static gboolean seed_cairo_surface_set_fallback_resolution(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException *exception) { cairo_surface_t *surf; gdouble x, y; SeedValue jsx, jsy; CHECK_THIS_BOOL(); if (!seed_value_is_object (ctx, value)) { seed_make_exception(ctx, exception, "ArgumentError", "Cairo.Surface.fallback_resolution must be an array [x,y]"); return FALSE; } jsx = seed_object_get_property_at_index (ctx, (SeedObject) value, 0, exception); jsy = seed_object_get_property_at_index (ctx, (SeedObject) value, 1, exception); surf = seed_object_to_cairo_surface (ctx, this_object, exception); x = seed_value_to_double (ctx, jsx, exception); y = seed_value_to_double (ctx, jsy, exception); cairo_surface_set_fallback_resolution (surf, x, y); return TRUE; }
void gfxPDFSurface::SetDPI(double xDPI, double yDPI) { mXDPI = xDPI; mYDPI = yDPI; cairo_surface_set_fallback_resolution(CairoSurface(), xDPI, yDPI); }
static int surface_set_fallback_resolution (lua_State *L) { cairo_surface_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_SURFACE); cairo_surface_set_fallback_resolution(*obj, luaL_checknumber(L, 2), luaL_checknumber(L, 3)); return 0; }
cairo_surface_t * _cairo_boilerplate_pdf_create_surface (const char *name, cairo_content_t content, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { pdf_target_closure_t *ptc; cairo_surface_t *surface; cairo_status_t status; /* Sanitize back to a real cairo_content_t value. */ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) content = CAIRO_CONTENT_COLOR_ALPHA; *closure = ptc = xmalloc (sizeof (pdf_target_closure_t)); ptc->width = width; ptc->height = height; xasprintf (&ptc->filename, "%s-out.pdf", name); xunlink (ptc->filename); surface = cairo_pdf_surface_create (ptc->filename, width, height); if (cairo_surface_status (surface)) goto CLEANUP_FILENAME; cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); if (cairo_surface_status (surface)) goto CLEANUP_TARGET; } else { ptc->target = NULL; } status = cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); CLEANUP_TARGET: cairo_surface_destroy (ptc->target); CLEANUP_FILENAME: free (ptc->filename); free (ptc); return surface; }
IoObject *IoCairoSurface_setFallbackResolution(IoCairoSurface *self, IoObject *locals, IoMessage *m) { double x = IoMessage_locals_doubleArgAt_(m, locals, 0); double y = IoMessage_locals_doubleArgAt_(m, locals, 1); cairo_surface_set_fallback_resolution(SURFACE(self), x, y); CHECK_STATUS(self); return self; }
static cairo_surface_t * create_source_surface (int size) { cairo_surface_t *surface; surface = cairo_pdf_surface_create ("pdf-surface-source.out.pdf", size, size); cairo_surface_set_fallback_resolution (surface, 72., 72.); return surface; }
static cairo_surface_t * _cairo_boilerplate_svg_create_surface (const char *name, cairo_content_t content, cairo_svg_version_t version, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { svg_target_closure_t *ptc; cairo_surface_t *surface; cairo_status_t status; *closure = ptc = xmalloc (sizeof (svg_target_closure_t)); ptc->width = width; ptc->height = height; xasprintf (&ptc->filename, "%s-out.svg", name); xunlink (ptc->filename); surface = cairo_svg_surface_create (ptc->filename, width, height); if (cairo_surface_status (surface)) goto CLEANUP_FILENAME; cairo_svg_surface_restrict_to_version (surface, version); cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); if (cairo_surface_status (surface)) goto CLEANUP_TARGET; } else ptc->target = NULL; status = cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); CLEANUP_TARGET: cairo_surface_destroy (ptc->target); CLEANUP_FILENAME: free (ptc->filename); free (ptc); return surface; }
static PyObject * surface_set_fallback_resolution (PycairoSurface *o, PyObject *args) { double x_ppi, y_ppi; if (!PyArg_ParseTuple(args, "dd:Surface.set_fallback_resolution", &x_ppi, &y_ppi)) return NULL; cairo_surface_set_fallback_resolution (o->surface, x_ppi, y_ppi); Py_RETURN_NONE; }
static VALUE cr_surface_set_fallback_resolution (VALUE self, VALUE x_pixels_per_inch, VALUE y_pixels_per_inch) { cairo_surface_set_fallback_resolution (_SELF, NUM2DBL (x_pixels_per_inch), NUM2DBL (y_pixels_per_inch)); cr_surface_check_status (_SELF); return self; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_set_fallback_resolution (cairo_get_target (cr), FALLBACK_RES_X, FALLBACK_RES_Y); rectangles (cr); cairo_translate (cr, 3*SIZE, 0); cairo_push_group (cr); rectangles (cr); cairo_pop_group_to_source (cr); cairo_paint (cr); return CAIRO_TEST_SUCCESS; }
static cairo_test_status_t preamble (cairo_test_context_t *ctx) { cairo_surface_t *surface; /* get the error surface */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, INT_MAX, INT_MAX); #if CAIRO_HAS_GL_SURFACE cairo_gl_surface_set_size (surface, 0, 0); cairo_gl_surface_swapbuffers (surface); #endif #if CAIRO_HAS_OS2_SURFACE cairo_os2_surface_set_hwnd (surface, 0); cairo_os2_surface_set_size (surface, 0, 0); cairo_os2_surface_set_manual_window_refresh (surface, FALSE); #endif #if CAIRO_HAS_PDF_SURFACE cairo_pdf_surface_restrict_to_version (surface, CAIRO_PDF_VERSION_1_4); cairo_pdf_surface_set_size (surface, 0, 0); #endif #if CAIRO_HAS_PS_SURFACE cairo_ps_surface_set_eps (surface, FALSE); cairo_ps_surface_set_size (surface, 0, 0); cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_2); cairo_ps_surface_dsc_comment (surface, NULL); cairo_ps_surface_dsc_begin_setup (surface); cairo_ps_surface_dsc_begin_page_setup (surface); #endif #if CAIRO_HAS_XCB_SURFACE cairo_xcb_surface_set_size (surface, 0, 0); #endif #if CAIRO_HAS_XLIB_SURFACE cairo_xlib_surface_set_size (surface, 0, 0); cairo_xlib_surface_set_drawable (surface, 0, 0, 0); #endif cairo_surface_set_mime_data (surface, NULL, NULL, 0, NULL, 0); cairo_surface_set_device_offset (surface, 0, 0); cairo_surface_set_fallback_resolution (surface, 0, 0); cairo_surface_destroy (surface); return CAIRO_TEST_SUCCESS; }
static void _fo_doc_cairo_create_cr (FoDocCairo *fo_doc_cairo, gdouble width, gdouble height, GError **error) { g_return_if_fail (error == NULL || *error == NULL); cairo_surface_t *surface = fo_doc_cairo->surface_create (fo_doc_cairo->current_filename, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { g_set_error (error, FO_DOC_ERROR, FO_DOC_ERROR_FAILED, "%s", N_(fo_doc_error_messages[FO_DOC_ERROR_FAILED])); return; } cairo_surface_set_fallback_resolution (surface, PIXELS_PER_INCH, PIXELS_PER_INCH); fo_doc_cairo->cr = cairo_create (surface); cairo_surface_destroy (surface); if (cairo_status (fo_doc_cairo->cr) != CAIRO_STATUS_SUCCESS) { g_set_error (error, FO_DOC_ERROR, FO_DOC_ERROR_FAILED, "%s", N_(fo_doc_error_messages[FO_DOC_ERROR_FAILED])); return; } pango_cairo_update_context (fo_doc_cairo->cr, FO_DOC (fo_doc_cairo)->pango_context); fo_doc_cairo->page_width = width; fo_doc_cairo->page_height = height; }
static void _cairo_boilerplate_ps_force_fallbacks (cairo_surface_t *abstract_surface, double x_pixels_per_inch, double y_pixels_per_inch) { ps_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface, &ps_closure_key); cairo_paginated_surface_t *paginated; cairo_ps_surface_t *surface; if (ptc->target) abstract_surface = ptc->target; paginated = (cairo_paginated_surface_t*) abstract_surface; surface = (cairo_ps_surface_t*) paginated->target; surface->force_fallbacks = TRUE; cairo_surface_set_fallback_resolution (&paginated->base, x_pixels_per_inch, y_pixels_per_inch); }
static cairo_test_status_t test_cairo_surface_set_fallback_resolution (cairo_surface_t *surface) { cairo_surface_set_fallback_resolution (surface, 42, 42); return CAIRO_TEST_SUCCESS; }
static cairo_test_status_t preamble (cairo_test_context_t *ctx) { cairo_t *cr; cairo_test_status_t ret = CAIRO_TEST_UNTESTED; struct { double x, y; } ppi[] = { { 600, 600 }, { 600, 72 }, { 300, 300 }, { 300, 72 }, { 150, 150 }, { 150, 72 }, { 75, 75 }, { 75, 72 }, { 72, 600 }, { 72, 300 }, { 72, 150 }, { 72, 75 }, { 72, 72 }, { 72, 37.5 }, { 37.5, 72 }, { 37.5, 37.5 }, }; unsigned int i; int n, num_ppi; num_ppi = sizeof (ppi) / sizeof (ppi[0]); #if GENERATE_REFERENCE for (n = 0; n < num_ppi; n++) { char *ref_name; xasprintf (&ref_name, "fallback-resolution.ppi%gx%g.ref.png", ppi[n].x, ppi[n].y); generate_reference (ppi[n].x, ppi[n].y, ref_name); free (ref_name); } #endif for (i = 0; i < ctx->num_targets; i++) { const cairo_boilerplate_target_t *target = ctx->targets_to_test[i]; cairo_surface_t *surface = NULL; char *base_name; void *closure; const char *format; cairo_status_t status; if (! target->is_vector) continue; if (! cairo_test_is_target_enabled (ctx, target->name)) continue; format = cairo_boilerplate_content_name (target->content); xasprintf (&base_name, "fallback-resolution.%s.%s", target->name, format); surface = (target->create_surface) (base_name, target->content, SIZE, SIZE, SIZE, SIZE, CAIRO_BOILERPLATE_MODE_TEST, 0, &closure); if (surface == NULL) { free (base_name); continue; } if (ret == CAIRO_TEST_UNTESTED) ret = CAIRO_TEST_SUCCESS; cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); free (base_name); /* we need to recreate the surface for each resolution as we include * SVG in testing which does not support the paginated interface. */ for (n = 0; n < num_ppi; n++) { char *test_name; cairo_bool_t pass; xasprintf (&test_name, "fallback-resolution.ppi%gx%g", ppi[n].x, ppi[n].y); xasprintf (&base_name, "%s.%s.%s", test_name, target->name, format); surface = (target->create_surface) (base_name, target->content, SIZE + 25, SIZE + 25, SIZE + 25, SIZE + 25, CAIRO_BOILERPLATE_MODE_TEST, 0, &closure); if (surface == NULL || cairo_surface_status (surface)) { cairo_test_log (ctx, "Failed to generate surface: %s.%s\n", target->name, format); free (base_name); free (test_name); ret = CAIRO_TEST_FAILURE; continue; } cairo_test_log (ctx, "Testing fallback-resolution %gx%g with %s target\n", ppi[n].x, ppi[n].y, target->name); printf ("%s:\t", base_name); fflush (stdout); if (target->force_fallbacks != NULL) target->force_fallbacks (surface, ~0U); cr = cairo_create (surface); #if SET_TOLERANCE cairo_set_tolerance (cr, 3.0); #endif cairo_surface_set_device_offset (surface, 25, 25); cairo_surface_set_fallback_resolution (surface, ppi[n].x, ppi[n].y); cairo_save (cr); { cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); } cairo_restore (cr); /* First draw the top half in a conventional way. */ cairo_save (cr); { cairo_rectangle (cr, 0, 0, SIZE, SIZE / 2.0); cairo_clip (cr); draw (cr, SIZE, SIZE); } cairo_restore (cr); /* Then draw the bottom half in a separate group, * (exposing a bug in 1.6.4 with the group not being * rendered with the correct fallback resolution). */ cairo_save (cr); { cairo_rectangle (cr, 0, SIZE / 2.0, SIZE, SIZE / 2.0); cairo_clip (cr); cairo_push_group (cr); { draw (cr, SIZE, SIZE); } cairo_pop_group_to_source (cr); cairo_paint (cr); } cairo_restore (cr); status = cairo_status (cr); cairo_destroy (cr); pass = FALSE; if (status) { cairo_test_log (ctx, "Error: Failed to create target surface: %s\n", cairo_status_to_string (status)); ret = CAIRO_TEST_FAILURE; } else { /* extract the image and compare it to our reference */ if (! check_result (ctx, target, test_name, base_name, surface)) ret = CAIRO_TEST_FAILURE; else pass = TRUE; } cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); free (base_name); free (test_name); if (pass) { printf ("PASS\n"); } else { printf ("FAIL\n"); } fflush (stdout); } } return ret; }
static void BM_NewPage(const pGEcontext gc, pDevDesc dd) { pX11Desc xd = (pX11Desc) dd->deviceSpecific; char buf[PATH_MAX]; cairo_status_t res; xd->npages++; if (xd->type == PNG || xd->type == JPEG || xd->type == BMP) { if (xd->npages > 1) { /* try to preserve the page we do have */ BM_Close_bitmap(xd); if (xd->fp) fclose(xd->fp); } snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->fp = R_fopen(R_ExpandFileName(buf), "wb"); if (!xd->fp) error(_("could not open file '%s'"), buf); } else if(xd->type == PNGdirect || xd->type == TIFF) { if (xd->npages > 1) { xd->npages--; BM_Close_bitmap(xd); xd->npages++; } } #ifdef HAVE_CAIRO_SVG else if(xd->type == SVG) { if (xd->npages > 1 && xd->cs) { cairo_show_page(xd->cc); if(!xd->onefile) { cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_svg_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { xd->cs = NULL; error("cairo error '%s'", cairo_status_to_string(res)); } if(xd->onefile) cairo_svg_surface_restrict_to_version(xd->cs, CAIRO_SVG_VERSION_1_2); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } } #endif #ifdef HAVE_CAIRO_PDF else if(xd->type == PDF) { if (xd->npages > 1) { cairo_show_page(xd->cc); if(!xd->onefile) { cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_pdf_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_surface_set_fallback_resolution(xd->cs, xd->fallback_dpi, xd->fallback_dpi); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } } #endif #ifdef HAVE_CAIRO_PS else if(xd->type == PS) { if (xd->npages > 1) { cairo_show_page(xd->cc); if(!xd->onefile) { cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_ps_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } // We already require >= 1.2 #if CAIRO_VERSION_MAJOR > 2 || CAIRO_VERSION_MINOR >= 6 if(!xd->onefile) cairo_ps_surface_set_eps(xd->cs, TRUE); #endif cairo_surface_set_fallback_resolution(xd->cs, xd->fallback_dpi, xd->fallback_dpi); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } } #endif else error(_("unimplemented cairo-based device")); cairo_reset_clip(xd->cc); if (xd->type == PNG || xd->type == TIFF|| xd->type == PNGdirect) { /* First clear it */ cairo_set_operator (xd->cc, CAIRO_OPERATOR_CLEAR); cairo_paint (xd->cc); cairo_set_operator (xd->cc, CAIRO_OPERATOR_OVER); xd->fill = gc->fill; } else xd->fill = R_OPAQUE(gc->fill) ? gc->fill: xd->canvas; CairoColor(xd->fill, xd); cairo_new_path(xd->cc); cairo_paint(xd->cc); }
static Rboolean BM_Open(pDevDesc dd, pX11Desc xd, int width, int height) { char buf[PATH_MAX]; cairo_status_t res; if (xd->type == PNG || xd->type == JPEG || xd->type == TIFF || xd->type == BMP || xd->type == PNGdirect) { xd->cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, xd->windowWidth, xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } cairo_set_operator(xd->cc, CAIRO_OPERATOR_OVER); cairo_reset_clip(xd->cc); cairo_set_antialias(xd->cc, xd->antialias); } #ifdef HAVE_CAIRO_SVG else if(xd->type == SVG) { snprintf(buf, PATH_MAX, xd->filename, xd->npages + 1); xd->cs = cairo_svg_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { xd->cs = NULL; warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } if(xd->onefile) cairo_svg_surface_restrict_to_version(xd->cs, CAIRO_SVG_VERSION_1_2); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } cairo_set_antialias(xd->cc, xd->antialias); } #endif #ifdef HAVE_CAIRO_PDF else if(xd->type == PDF) { snprintf(buf, PATH_MAX, xd->filename, xd->npages + 1); xd->cs = cairo_pdf_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } cairo_surface_set_fallback_resolution(xd->cs, xd->fallback_dpi, xd->fallback_dpi); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } cairo_set_antialias(xd->cc, xd->antialias); } #endif #ifdef HAVE_CAIRO_PS else if(xd->type == PS) { snprintf(buf, PATH_MAX, xd->filename, xd->npages + 1); xd->cs = cairo_ps_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } // We already require >= 1.2 #if CAIRO_VERSION_MAJOR > 2 || CAIRO_VERSION_MINOR >= 6 if(!xd->onefile) cairo_ps_surface_set_eps(xd->cs, TRUE); #endif cairo_surface_set_fallback_resolution(xd->cs, xd->fallback_dpi, xd->fallback_dpi); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { warning("cairo error '%s'", cairo_status_to_string(res)); return FALSE; } cairo_set_antialias(xd->cc, xd->antialias); } #endif else error(_("unimplemented cairo-based device")); return TRUE; }
static cairo_surface_t * _cairo_boilerplate_win32_printing_create_surface (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, void **closure) { win32_target_closure_t *ptc; cairo_surface_t *surface; DOCINFO di; if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) content = CAIRO_CONTENT_COLOR_ALPHA; *closure = ptc = xmalloc (sizeof (win32_target_closure_t)); xasprintf (&ptc->filename, "%s.out.ps", name); xunlink (ptc->filename); memset (&di, 0, sizeof (DOCINFO)); di.cbSize = sizeof (DOCINFO); di.lpszDocName = ptc->filename; di.lpszOutput = ptc->filename; ptc->width = width; ptc->height = height; create_printer_dc (ptc); if (ptc->dc == NULL) { printf("\nFailed to create printer\n"); free (ptc->filename); free (ptc); return NULL; } StartDoc (ptc->dc, &di); StartPage (ptc->dc); surface = cairo_win32_printing_surface_create (ptc->dc); if (cairo_surface_status (surface)) { free (ptc->filename); free (ptc); return NULL; } cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); } else { ptc->target = NULL; } if (cairo_surface_set_user_data (surface, &win32_closure_key, ptc, NULL) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); if (ptc->target != NULL) cairo_surface_destroy (ptc->target); free (ptc->filename); free (ptc); return NULL; } return surface; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpRunMode run_mode; /* Plug-in variables */ gboolean single_image; gboolean defaults_proc; /* Plug-In variables */ cairo_surface_t *pdf_file; cairo_t *cr; GimpExportCapabilities capabilities; guint32 i = 0; gint32 j = 0; gdouble x_res, y_res; gdouble x_scale, y_scale; gint32 image_id; gboolean exported; GimpImageBaseType type; gint32 temp; gint *layers; gint32 num_of_layers; GimpDrawable *layer; cairo_surface_t *layer_image; gdouble opacity; gint x, y; GimpRGB layer_color; gboolean single_color; gint32 mask_id = -1; GimpDrawable *mask = NULL; cairo_surface_t *mask_image = NULL; FILE *fp; INIT_I18N (); /* Setting mandatory output values */ *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; /* Initializing all the settings */ multi_page.image_count = 0; if (! init_vals (name, nparams, param, &single_image, &defaults_proc, &run_mode)) { values[0].data.d_status = GIMP_PDB_CALLING_ERROR; return; } /* Starting the executions */ if (run_mode == GIMP_RUN_INTERACTIVE) { if (single_image) { if (! gui_single ()) { values[0].data.d_status = GIMP_PDB_CANCEL; return; } } else if (! gui_multi ()) { values[0].data.d_status = GIMP_PDB_CANCEL; return; } if (file_name == NULL) { values[0].data.d_status = GIMP_PDB_CALLING_ERROR; gimp_message (_("You must select a file to save!")); return; } } fp = g_fopen (file_name, "wb"); pdf_file = cairo_pdf_surface_create_for_stream (write_func, fp, 1, 1); if (cairo_surface_status (pdf_file) != CAIRO_STATUS_SUCCESS) { char *str = g_strdup_printf (_("An error occured while creating the PDF file:\n" "%s\n" "Make sure you entered a valid filename and that the selected location isn't read only!"), cairo_status_to_string (cairo_surface_status (pdf_file))); gimp_message (str); g_free (str); values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; return; } cr = cairo_create (pdf_file); capabilities = GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_ALPHA | GIMP_EXPORT_CAN_HANDLE_GRAY | GIMP_EXPORT_CAN_HANDLE_LAYERS | GIMP_EXPORT_CAN_HANDLE_INDEXED; if (optimize.apply_masks) capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS; for (i = 0; i < multi_page.image_count; i++) { /* Save the state of the surface before any changes, so that settings * from one page won't affect all the others */ cairo_save (cr); image_id = multi_page.images[i]; /* We need the active layer in order to use gimp_image_export */ temp = gimp_image_get_active_drawable (image_id); if (temp == -1) exported = gimp_export_image (&image_id, &temp, NULL, capabilities) == GIMP_EXPORT_EXPORT; else exported = FALSE; type = gimp_image_base_type (image_id); gimp_image_get_resolution (image_id, &x_res, &y_res); x_scale = 72.0 / x_res; y_scale = 72.0 / y_res; cairo_pdf_surface_set_size (pdf_file, gimp_image_width (image_id) * x_scale, gimp_image_height (image_id) * y_scale); /* This way we set how many pixels are there in every inch. * It's very important for PangoCairo */ cairo_surface_set_fallback_resolution (pdf_file, x_res, y_res); /* PDF is usually 72 points per inch. If we have a different resolution, * we will need this to fit our drawings */ cairo_scale (cr, x_scale, y_scale); /* Now, we should loop over the layers of each image */ layers = gimp_image_get_layers (image_id, &num_of_layers); for (j = 0; j < num_of_layers; j++) { layer = gimp_drawable_get (layers [num_of_layers-j-1]); opacity = gimp_layer_get_opacity (layer->drawable_id)/100.0; /* Gimp doesn't display indexed layers with opacity below 50% * And if it's above 50%, it will be rounded to 100% */ if (type == GIMP_INDEXED) { if (opacity <= 0.5) opacity = 0.0; else opacity = 1.0; } if (gimp_item_get_visible (layer->drawable_id) && (! optimize.ignore_hidden || (optimize.ignore_hidden && opacity > 0.0))) { mask_id = gimp_layer_get_mask (layer->drawable_id); if (mask_id != -1) { mask = gimp_drawable_get (mask_id); mask_image = get_drawable_image (mask); } gimp_drawable_offsets (layer->drawable_id, &x, &y); /* For raster layers */ if (!gimp_item_is_text_layer (layer->drawable_id)) { layer_color = get_layer_color (layer, &single_color); cairo_rectangle (cr, x, y, layer->width, layer->height); if (optimize.vectorize && single_color) { cairo_set_source_rgba (cr, layer_color.r, layer_color.g, layer_color.b, layer_color.a * opacity); if (mask_id != -1) cairo_mask_surface (cr, mask_image, x, y); else cairo_fill (cr); } else { cairo_clip (cr); layer_image = get_drawable_image (layer); cairo_set_source_surface (cr, layer_image, x, y); cairo_push_group (cr); cairo_paint_with_alpha (cr, opacity); cairo_pop_group_to_source (cr); if (mask_id != -1) cairo_mask_surface (cr, mask_image, x, y); else cairo_paint (cr); cairo_reset_clip (cr); cairo_surface_destroy (layer_image); } } /* For text layers */ else { drawText (layer, opacity, cr, x_res, y_res); } } /* We are done with the layer - time to free some resources */ gimp_drawable_detach (layer); if (mask_id != -1) { gimp_drawable_detach (mask); cairo_surface_destroy (mask_image); } } /* We are done with this image - Show it! */ cairo_show_page (cr); cairo_restore (cr); if (exported) gimp_image_delete (image_id); } /* We are done with all the images - time to free the resources */ cairo_surface_destroy (pdf_file); cairo_destroy (cr); fclose (fp); /* Finally done, let's save the parameters */ gimp_set_data (DATA_OPTIMIZE, &optimize, sizeof (optimize)); if (!single_image) { g_strlcpy (multi_page.file_name, file_name, MAX_FILE_NAME_LENGTH); gimp_set_data (DATA_IMAGE_LIST, &multi_page, sizeof (multi_page)); } }
/** * fo_doc_cairo_place_image: * @fo_doc: * @fo_image: * @x: * @y: * @xscale: * @yscale: * * **/ static void fo_doc_cairo_place_image (FoDoc *fo_doc, FoImage *fo_image, gdouble x G_GNUC_UNUSED, gdouble y G_GNUC_UNUSED, gdouble xscale G_GNUC_UNUSED, gdouble yscale G_GNUC_UNUSED) { GdkPixbuf *pixbuf = g_object_ref (fo_pixbuf_get_pixbuf (fo_image)); gint width = gdk_pixbuf_get_width (pixbuf); gint height = gdk_pixbuf_get_height (pixbuf); guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); int n_channels = gdk_pixbuf_get_n_channels (pixbuf); guchar *cairo_pixels; cairo_format_t format; cairo_surface_t *surface; static const cairo_user_data_key_t key; int j; cairo_translate (FO_DOC_CAIRO (fo_doc)->cr, 0, FO_DOC_CAIRO(fo_doc)->page_height); cairo_save (FO_DOC_CAIRO(fo_doc)->cr); cairo_scale (FO_DOC_CAIRO (fo_doc)->cr, xscale * 72.0 / PIXELS_PER_INCH, yscale * 72.0 / PIXELS_PER_INCH); #if HAVE_LIBRSVG if (g_str_has_suffix( fo_image_get_uri(fo_image), ".svg")) { RsvgHandle *rsvg; GError *error = NULL; g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "rendering %s as SVG\n", fo_image_get_uri(fo_image)); rsvg_init(); rsvg_set_default_dpi_x_y (PIXELS_PER_INCH, PIXELS_PER_INCH); rsvg = rsvg_handle_new_from_file (fo_image_get_uri(fo_image), &error); rsvg_handle_render_cairo (rsvg, FO_DOC_CAIRO(fo_doc)->cr); rsvg_term(); cairo_restore (FO_DOC_CAIRO(fo_doc)->cr); if (error) { g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, error->message); g_error_free (error); } return; } #endif if (n_channels == 3) { format = CAIRO_FORMAT_RGB24; } else { format = CAIRO_FORMAT_ARGB32; } cairo_pixels = g_malloc (4 * width * height); surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, format, width, height, 4 * width); cairo_surface_set_user_data (surface, &key, cairo_pixels, (cairo_destroy_func_t)g_free); for (j = height; j; j--) { guchar *p = gdk_pixels; guchar *q = cairo_pixels; if (n_channels == 3) { guchar *end = p + 3 * width; while (p < end) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN q[0] = p[2]; q[1] = p[1]; q[2] = p[0]; #else q[1] = p[0]; q[2] = p[1]; q[3] = p[2]; #endif p += 3; q += 4; } } else { guchar *end = p + 4 * width; guint t1,t2,t3; #define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END while (p < end) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN MULT(q[0], p[2], p[3], t1); MULT(q[1], p[1], p[3], t2); MULT(q[2], p[0], p[3], t3); q[3] = p[3]; #else q[0] = p[3]; MULT(q[1], p[0], p[3], t1); MULT(q[2], p[1], p[3], t2); MULT(q[3], p[2], p[3], t3); #endif p += 4; q += 4; } #undef MULT } gdk_pixels += gdk_rowstride; cairo_pixels += 4 * width; } cairo_surface_set_fallback_resolution (surface, PIXELS_PER_INCH, PIXELS_PER_INCH); cairo_set_source_surface (FO_DOC_CAIRO (fo_doc)->cr, surface, 0, 0); cairo_pattern_t *pattern = cairo_get_source (FO_DOC_CAIRO (fo_doc)->cr); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE); cairo_paint (FO_DOC_CAIRO (fo_doc)->cr); cairo_surface_destroy (surface); g_object_unref (pixbuf); cairo_restore (FO_DOC_CAIRO(fo_doc)->cr); }