static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { ViewerCbInfo *info = (ViewerCbInfo *) user_data; cairo_t *cr; gdouble page_width, page_height; cr = gtk_print_context_get_cairo_context (context); page_width = gtk_print_context_get_width (context); page_height = gtk_print_context_get_height (context); { RsvgHandle *handle; RsvgDimensionData svg_dimensions; struct RsvgSizeCallbackData size_data; /* should not fail */ handle = rsvg_handle_new_from_data(info->svg_bytes->data, info->svg_bytes->len, NULL); rsvg_handle_set_base_uri (handle, info->base_uri); rsvg_handle_set_dpi_x_y (handle, gtk_print_context_get_dpi_x(context), gtk_print_context_get_dpi_y(context)); rsvg_handle_get_dimensions(handle, &svg_dimensions); if (svg_dimensions.width > page_width || svg_dimensions.height > page_height) { /* scale down the image to the page's size, while preserving the aspect ratio */ if ((double) svg_dimensions.height * (double) page_width > (double) svg_dimensions.width * (double) page_height) { svg_dimensions.width = 0.5 + (double) svg_dimensions.width *(double) page_height / (double) svg_dimensions.height; svg_dimensions.height = page_height; } else { svg_dimensions.height = 0.5 + (double) svg_dimensions.height *(double) page_width / (double) svg_dimensions.width; svg_dimensions.width = page_width; } } size_data.type = RSVG_SIZE_WH; size_data.width = svg_dimensions.width; size_data.height = svg_dimensions.height; size_data.keep_aspect_ratio = FALSE; rsvg_handle_set_size_callback (handle, _rsvg_size_callback, &size_data, NULL); rsvg_handle_render_cairo(handle, cr); g_object_unref (handle); } }
JNIEXPORT jdouble JNICALL Java_org_gnome_gtk_GtkPrintContext_gtk_1print_1context_1get_1dpi_1x ( JNIEnv* env, jclass cls, jlong _self ) { gdouble result; jdouble _result; GtkPrintContext* self; // convert parameter self self = (GtkPrintContext*) _self; // call function result = gtk_print_context_get_dpi_x(self); // cleanup parameter self // translate return value to JNI type _result = (jdouble) result; // and finally return _result; }
static void get_tab_array(PangoTabArray **tabs, GtkPrintContext *ctx, GtkTextView *text_view) { gint xft_dpi, loc; GtkSettings *settings = gtk_settings_get_default(); g_object_get(settings, "gtk-xft-dpi", &xft_dpi, NULL); if ((*tabs = gtk_text_view_get_tabs(text_view))) { pango_tab_array_get_tab(*tabs, 0, NULL, &loc); pango_tab_array_set_tab(*tabs, 0, PANGO_TAB_LEFT, loc * gtk_print_context_get_dpi_x(ctx) / (xft_dpi / PANGO_SCALE)); } }
static int create_cairo(struct objlist *obj, N_VALUE *inst, N_VALUE *rval, int argc, char **argv) { cairo_t *cairo; int dpi, id, r; struct gra2cairo_local *local; GtkPrintContext *gpc; gpc = GTK_PRINT_CONTEXT(argv[2]); if (gpc == NULL) { error(obj, CAIRO_STATUS_NULL_POINTER + 100); return 1; } cairo = gtk_print_context_get_cairo_context(gpc); r = cairo_status(cairo); if (r != CAIRO_STATUS_SUCCESS) { error(obj, r + 100); return 1; } _getobj(obj, "id", inst, &id); dpi = gtk_print_context_get_dpi_x(gpc); if (putobj(obj, "dpix", id, &dpi) < 0) { error(obj, ERRFIELD); return 1; } dpi = gtk_print_context_get_dpi_y(gpc); if (putobj(obj, "dpiy", id, &dpi) < 0) { error(obj, ERRFIELD); return 1; } _getobj(obj, "_local", inst, &local); local->cairo = cairo; return 0; }
gboolean print_draw_page (GtkPrintContext *context, PrintData *data, GError **error) { cairo_t *cr = gtk_print_context_get_cairo_context (context); cairo_surface_t *surface; gint width; gint height; gdouble scale_x; gdouble scale_y; surface = print_surface_from_drawable (data->drawable_id, error); if (surface) { width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); scale_x = gtk_print_context_get_dpi_x (context) / data->xres; scale_y = gtk_print_context_get_dpi_y (context) / data->yres; cairo_translate (cr, data->offset_x, data->offset_y); if (data->draw_crop_marks) print_draw_crop_marks (context, 0, 0, width * scale_x, height * scale_y); cairo_scale (cr, scale_x, scale_y); cairo_rectangle (cr, 0, 0, width, height); cairo_set_source_surface (cr, surface, 0, 0); cairo_fill (cr); cairo_surface_destroy (surface); return TRUE; } else { return FALSE; } }
static void contact_begin_print (GtkPrintOperation *operation, GtkPrintContext *context, EContactPrintContext *ctxt) { GtkPageSetup *setup; gdouble page_width; e_contact_build_style (ctxt->style); setup = gtk_print_context_get_page_setup (context); page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS); ctxt->context = context; ctxt->x = ctxt->y = .0; ctxt->column = 0; ctxt->first_contact = TRUE; ctxt->first_section = TRUE; ctxt->section = NULL; ctxt->column_spacing = gtk_print_context_get_dpi_x (context) / 4; ctxt->column_width = (page_width + ctxt->column_spacing) / ctxt->style->num_columns - ctxt->column_spacing; ctxt->letter_heading_font = pango_font_description_new (); pango_font_description_set_family ( ctxt->letter_heading_font, pango_font_description_get_family ( ctxt->style->headings_font)); pango_font_description_set_size ( ctxt->letter_heading_font, pango_font_description_get_size ( ctxt->style->headings_font) * 1.5); if (ctxt->contact_list != NULL) { ctxt->page_nr = -1; ctxt->pages = 1; g_slist_foreach (ctxt->contact_list, (GFunc) contact_draw, ctxt); gtk_print_operation_set_n_pages (operation, ctxt->pages); } }
static gboolean preview_draw (GtkWidget *widget, cairo_t *cr, gpointer data) { PreviewOp *pop = data; cairo_t *prev_cr; double dpi_x, dpi_y; prev_cr = gtk_print_context_get_cairo_context (pop->context); cairo_reference (prev_cr); dpi_x = gtk_print_context_get_dpi_x (pop->context); dpi_y = gtk_print_context_get_dpi_y (pop->context); gtk_print_context_set_cairo_context (pop->context, cr, dpi_x, dpi_y); gtk_print_operation_preview_render_page (pop->preview, pop->page - 1); gtk_print_context_set_cairo_context (pop->context, prev_cr, dpi_x, dpi_y); cairo_destroy (prev_cr); return TRUE; }
gboolean draw_page_cairo (GtkPrintContext *context, PrintData *data) { GimpDrawable *drawable = gimp_drawable_get (data->drawable_id); GimpPixelRgn region; cairo_t *cr; cairo_surface_t *surface; guchar *pixels; gdouble cr_width; gdouble cr_height; gdouble cr_dpi_x; gdouble cr_dpi_y; gint width; gint height; gint stride; gint y; gdouble scale_x; gdouble scale_y; width = drawable->width; height = drawable->height; gimp_tile_cache_ntiles (width / gimp_tile_width () + 1); cr = gtk_print_context_get_cairo_context (context); cr_width = gtk_print_context_get_width (context); cr_height = gtk_print_context_get_height (context); cr_dpi_x = gtk_print_context_get_dpi_x (context); cr_dpi_y = gtk_print_context_get_dpi_y (context); scale_x = cr_dpi_x / data->xres; scale_y = cr_dpi_y / data->yres; #if 0 /* print header if it is requested */ if (data->show_info_header) { draw_info_header (context, cr, data); /* In points */ #define HEADER_HEIGHT (20 * 72.0 / 25.4) cairo_translate (cr, 0, HEADER_HEIGHT); cr_height -= HEADER_HEIGHT; } #endif cairo_translate (cr, data->offset_x / cr_dpi_x * 72.0, data->offset_y / cr_dpi_y * 72.0); cairo_scale (cr, scale_x, scale_y); gimp_pixel_rgn_init (®ion, drawable, 0, 0, width, height, FALSE, FALSE); surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); pixels = cairo_image_surface_get_data (surface); stride = cairo_image_surface_get_stride (surface); for (y = 0; y < height; y++, pixels += stride) { gimp_pixel_rgn_get_row (®ion, pixels, 0, y, width); switch (drawable->bpp) { case 3: convert_from_rgb (pixels, width); break; case 4: convert_from_rgba (pixels, width); break; } if (y % 16 == 0) gimp_progress_update ((gdouble) y / (gdouble) height); } cairo_set_source_surface (cr, surface, 0, 0); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); cairo_surface_destroy (surface); gimp_progress_update (1.0); gimp_drawable_detach (drawable); return TRUE; }
static void xviewer_print_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { cairo_t *cr; gdouble dpi_x, dpi_y; gdouble x0, y0; gdouble scale_factor; gdouble p_width, p_height; gint width, height; XviewerPrintData *data; GtkPageSetup *page_setup; xviewer_debug (DEBUG_PRINTING); data = (XviewerPrintData *) user_data; scale_factor = data->scale_factor/100; dpi_x = gtk_print_context_get_dpi_x (context); dpi_y = gtk_print_context_get_dpi_y (context); switch (data->unit) { case GTK_UNIT_INCH: x0 = data->left_margin * dpi_x; y0 = data->top_margin * dpi_y; break; case GTK_UNIT_MM: x0 = data->left_margin * dpi_x/25.4; y0 = data->top_margin * dpi_y/25.4; break; default: g_assert_not_reached (); } cr = gtk_print_context_get_cairo_context (context); cairo_translate (cr, x0, y0); page_setup = gtk_print_context_get_page_setup (context); p_width = gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS); p_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS); xviewer_image_get_size (data->image, &width, &height); /* this is both a workaround for a bug in cairo's PDF backend, and a way to ensure we are not printing outside the page margins */ cairo_rectangle (cr, 0, 0, MIN (width*scale_factor, p_width), MIN (height*scale_factor, p_height)); cairo_clip (cr); cairo_scale (cr, scale_factor, scale_factor); #ifdef HAVE_RSVG if (xviewer_image_is_svg (data->image)) { RsvgHandle *svg = xviewer_image_get_svg (data->image); rsvg_handle_render_cairo (svg, cr); return; } else #endif /* JPEGs can be attached to the cairo surface which simply embeds the JPEG file into the * destination PDF skipping (PNG-)recompression. This should reduce PDF sizes enormously. */ if (xviewer_image_is_jpeg (data->image) && _cairo_ctx_supports_jpg_metadata (cr)) { GFile *file; char *img_data; gsize data_len; cairo_surface_t *surface = NULL; xviewer_debug_message (DEBUG_PRINTING, "Attaching image to cairo surface"); file = xviewer_image_get_file (data->image); if (g_file_load_contents (file, NULL, &img_data, &data_len, NULL, NULL)) { XviewerTransform *tf = xviewer_image_get_transform (data->image); XviewerTransform *auto_tf = xviewer_image_get_autorotate_transform (data->image); cairo_matrix_t mx, mx2; if (!tf && auto_tf) { /* If only autorotation data present, * make it the normal rotation. */ tf = auto_tf; auto_tf = NULL; } /* Care must be taken with height and width values. They are not the original * values but were affected by the transformation. As the surface needs to be * generated using the original dimensions they might need to be flipped. */ if (tf) { if (auto_tf) { /* If we have an autorotation apply * it before the others */ tf = xviewer_transform_compose (auto_tf, tf); } switch (xviewer_transform_get_transform_type (tf)) { case XVIEWER_TRANSFORM_ROT_90: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, height, width); cairo_rotate (cr, 90.0 * (G_PI/180.0)); cairo_translate (cr, 0.0, -width); break; case XVIEWER_TRANSFORM_ROT_180: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, width, height); cairo_rotate (cr, 180.0 * (G_PI/180.0)); cairo_translate (cr, -width, -height); break; case XVIEWER_TRANSFORM_ROT_270: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, height, width); cairo_rotate (cr, 270.0 * (G_PI/180.0)); cairo_translate (cr, -height, 0.0); break; case XVIEWER_TRANSFORM_FLIP_HORIZONTAL: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, width, height); cairo_matrix_init_identity (&mx); _xviewer_cairo_matrix_flip (&mx2, &mx, TRUE, FALSE); cairo_transform (cr, &mx2); cairo_translate (cr, -width, 0.0); break; case XVIEWER_TRANSFORM_FLIP_VERTICAL: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, width, height); cairo_matrix_init_identity (&mx); _xviewer_cairo_matrix_flip (&mx2, &mx, FALSE, TRUE); cairo_transform (cr, &mx2); cairo_translate (cr, 0.0, -height); break; case XVIEWER_TRANSFORM_TRANSPOSE: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, height, width); cairo_matrix_init_rotate (&mx, 90.0 * (G_PI/180.0)); cairo_matrix_init_identity (&mx2); _xviewer_cairo_matrix_flip (&mx2, &mx2, TRUE, FALSE); cairo_matrix_multiply (&mx2, &mx, &mx2); cairo_transform (cr, &mx2); break; case XVIEWER_TRANSFORM_TRANSVERSE: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, height, width); cairo_matrix_init_rotate (&mx, 90.0 * (G_PI/180.0)); cairo_matrix_init_identity (&mx2); _xviewer_cairo_matrix_flip (&mx2, &mx2, FALSE, TRUE); cairo_matrix_multiply (&mx2, &mx, &mx2); cairo_transform (cr, &mx2); cairo_translate (cr, -height , -width); break; case XVIEWER_TRANSFORM_NONE: default: surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, width, height); break; } } if (!surface) surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); cairo_surface_set_mime_data (surface, CAIRO_MIME_TYPE_JPEG, (unsigned char*)img_data, data_len, g_free, img_data); cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_surface_destroy (surface); g_object_unref (file); return; } g_object_unref (file); } { GdkPixbuf *pixbuf; pixbuf = xviewer_image_get_pixbuf (data->image); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); g_object_unref (pixbuf); } }
static void draw_page_cairo(GtkPrintContext *context, PrintData *data) { cairo_t *cr; GdkPixbuf *pixbuf_to_draw; cairo_surface_t *surface; guchar *surface_pixels; guchar *pixbuf_pixels; gint stride; gint pixbuf_stride; gint pixbuf_n_channels; gdouble cr_dpi_x; gdouble cr_dpi_y; gdouble scale_x; gdouble scale_y; gint y; cr = gtk_print_context_get_cairo_context(context); pixbuf_to_draw = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(vik_viewport_get_pixmap(data->vvp)), NULL, 0, 0, 0, 0, data->width, data->height); surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, data->width, data->height); cr_dpi_x = gtk_print_context_get_dpi_x (context); cr_dpi_y = gtk_print_context_get_dpi_y (context); scale_x = cr_dpi_x / data->xres; scale_y = cr_dpi_y / data->yres; cairo_translate (cr, data->offset_x / cr_dpi_x * 72.0, data->offset_y / cr_dpi_y * 72.0); cairo_scale (cr, scale_x, scale_y); surface_pixels = cairo_image_surface_get_data (surface); stride = cairo_image_surface_get_stride (surface); pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf_to_draw); pixbuf_stride = gdk_pixbuf_get_rowstride(pixbuf_to_draw); pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf_to_draw); // fprintf(stderr, "DEBUG: %s() surface_pixels=%p pixbuf_pixels=%p size=%d surface_width=%d surface_height=%d stride=%d data_height=%d pixmap_stride=%d pixmap_nchannels=%d pixmap_bit_per_Sample=%d\n", __PRETTY_FUNCTION__, surface_pixels, pixbuf_pixels, stride * data->height, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), stride, data->height, gdk_pixbuf_get_rowstride(pixbuf_to_draw), gdk_pixbuf_get_n_channels(pixbuf_to_draw), gdk_pixbuf_get_bits_per_sample(pixbuf_to_draw)); /* Assume the pixbuf has 8 bits per channel */ for (y = 0; y < data->height; y++, surface_pixels += stride, pixbuf_pixels += pixbuf_stride) { switch (pixbuf_n_channels) { case 3: copy_row_from_rgb (surface_pixels, pixbuf_pixels, data->width); break; case 4: copy_row_from_rgba (surface_pixels, pixbuf_pixels, data->width); break; } } g_object_unref(G_OBJECT(pixbuf_to_draw)); cairo_set_source_surface(cr, surface, 0, 0); cairo_rectangle(cr, 0, 0, data->width, data->height); cairo_fill(cr); cairo_surface_destroy(surface); }
static void photos_print_operation_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr) { PhotosPrintOperation *self = PHOTOS_PRINT_OPERATION (operation); GeglRectangle bbox; GdkPixbuf *pixbuf = NULL; GtkPageSetup *page_setup; cairo_t *cr; gdouble dpi_x; gdouble dpi_y; gdouble page_height; gdouble page_width; gdouble scale_factor_n; gdouble x0; gdouble y0; scale_factor_n = self->scale_factor / 100.0; bbox = gegl_node_get_bounding_box (self->node); dpi_x = gtk_print_context_get_dpi_x (context); dpi_y = gtk_print_context_get_dpi_x (context); switch (self->unit) { case GTK_UNIT_INCH: x0 = self->left_margin * dpi_x; y0 = self->top_margin * dpi_y; break; case GTK_UNIT_MM: x0 = self->left_margin * dpi_x / 25.4; y0 = self->top_margin * dpi_y / 25.4; break; case GTK_UNIT_NONE: case GTK_UNIT_POINTS: default: g_assert_not_reached (); } cr = gtk_print_context_get_cairo_context (context); cairo_translate (cr, x0, y0); page_setup = gtk_print_context_get_page_setup (context); page_width = gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS); page_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS); /* This is both a workaround for a bug in cairo's PDF backend, and * a way to ensure we are not printing outside the page margins. */ cairo_rectangle (cr, 0, 0, MIN (bbox.width * scale_factor_n, page_width), MIN (bbox.height * scale_factor_n, page_height)); cairo_clip (cr); cairo_scale (cr, scale_factor_n, scale_factor_n); pixbuf = photos_utils_create_pixbuf_from_node (self->node); if (pixbuf == NULL) goto out; gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, 0.0); cairo_paint (cr); out: g_clear_object (&pixbuf); }
static VALUE rg_dpi_x(VALUE self) { return rb_float_new(gtk_print_context_get_dpi_x(_SELF(self))); }