22#include <ghostscript/iapi.h>
23#include <ghostscript/ierrors.h>
24#include <cairo/cairo.h>
33#define e_VMerror gs_error_VMerror
37#define e_unregistered gs_error_unregistered
41#define e_invalidid gs_error_invalidid
45 FORMAT_PS_CAIRO, FORMAT_EPS_CAIRO,
50 cairo_surface_t* surface;
51 cairo_pattern_t* pattern;
58 if (gs->pattern) cairo_pattern_destroy(gs->pattern);
59 if (gs->surface) cairo_surface_destroy(gs->surface);
63static int gs_writer(
void *caller_handle,
const char *
str,
int len)
65 GVJ_t *job = caller_handle;
69 return (
int)fwrite(
str, 1, (
size_t)
len, stderr);
74static void gs_error(
GVJ_t * job,
const char *name,
const char *funstr,
int err)
81 errsrc =
"PostScript Level 1";
82 else if (
err >= e_unregistered)
83 errsrc =
"PostScript Level 2";
84 else if (
err >= e_invalidid)
87 errsrc =
"Ghostscript internal error";
90 name, funstr,
err, errsrc);
93static int gvloadimage_process_file(
GVJ_t *job,
usershape_t *us,
void *instance)
95 int rc = 0, exit_code;
101 rc = gsapi_run_file(instance, us->
name, -1, &exit_code);
103 gs_error(job, us->
name,
"gsapi_run_file", rc);
109static int gvloadimage_process_surface(
GVJ_t *job,
usershape_t *us, gs_t *gs,
void *instance)
113 char width_height[20], dpi[10], cairo_context[30];
123#define GS_ARGC sizeof(gs_args)/sizeof(gs_args[0])
125 gs->surface = cairo_surface_create_similar(
126 cairo_get_target(gs->cr),
127 CAIRO_CONTENT_COLOR_ALPHA,
128 (
int)(us->
x + us->
w),
129 (
int)(us->
y + us->
h));
131 cr = cairo_create(gs->surface);
133 snprintf(width_height,
sizeof(width_height),
"-g%0.fx%0.f", us->
x + us->
w,
135 snprintf(dpi,
sizeof(dpi),
"-r%d", us->
dpi);
136 snprintf(cairo_context,
sizeof(cairo_context),
"-sCairoContext=%p", cr);
138 rc = gsapi_init_with_args(instance, GS_ARGC, gs_args);
143 gs_error(job, us->
name,
"gsapi_init_with_args", rc);
145 rc = gvloadimage_process_file(job, us, instance);
148 cairo_surface_destroy(gs->surface);
152 rc2 = gsapi_exit(instance);
154 gs_error(job, us->
name,
"gsapi_exit", rc2);
159 gs->pattern = cairo_pattern_create_for_surface (gs->surface);
167 gsapi_revision_t gsapi_revision_info;
176 if (us->
datafree == gvloadimage_gs_free
185 gs =
malloc(
sizeof(gs_t));
198#define GSAPI_REVISION_REQUIRED 863
199 rc = gsapi_revision(&gsapi_revision_info,
sizeof(gsapi_revision_t));
200 if (rc && rc < (
int)
sizeof(gsapi_revision_t)) {
201 job->
common->
errorfn(
"gs revision - struct too short %d\n", rc);
204 if (gsapi_revision_info.revision < GSAPI_REVISION_REQUIRED) {
206 gsapi_revision_info.revision);
210 rc = gsapi_new_instance(&instance, job);
212 gs_error(job, us->
name,
"gsapi_new_instance", rc);
214 rc = gsapi_set_stdio(instance,
NULL, gs_writer, gs_writer);
216 gs_error(job, us->
name,
"gsapi_set_stdio", rc);
218 rc = gvloadimage_process_surface(job, us, gs, instance);
219 gsapi_delete_instance(instance);
230 cairo_pattern_t *pattern = gvloadimage_gs_load(job, us);
234 cairo_translate(cr, b.
LL.
x - us->
x, -b.
UR.
y);
235 cairo_scale(cr, (b.
UR.
x - b.
LL.
x) / us->
w, (b.
UR.
y - b.
LL.
y) / us->
h);
236 cairo_set_source(cr, pattern);
250#ifdef HAVE_PANGOCAIRO
static double len(glCompPoint p)
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
gvplugin_installed_t gvloadimage_gs_types[]
static gvloadimage_engine_t engine_cairo
textitem scanner parser str
void(* errorfn)(const char *fmt,...)
void(* datafree)(usershape_t *us)