glib/poppler-page.cc | 227 ++++++++++++++++++++------------------------------- 1 file changed, 93 insertions(+), 134 deletions(-)
New commits: commit 55c76069c52f9f51c6b8c60fe1aa8de499012ea8 Author: Carlos Garcia Campos <[email protected]> Date: Mon Apr 12 19:32:46 2010 +0200 [glib] Use existing cairo api when rendering to a pixbuf I should fix bug #5589 for the GDK api too. diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc index 747ee0c..39645bd 100644 --- a/glib/poppler-page.cc +++ b/glib/poppler-page.cc @@ -256,59 +256,8 @@ poppler_page_get_text_page (PopplerPage *page) } #ifdef POPPLER_WITH_GDK -typedef struct { - unsigned char *cairo_data; - cairo_surface_t *surface; - cairo_t *cairo; -} OutputDevData; - -static void -poppler_page_prepare_output_dev (PopplerPage *page, - double scale, - int rotation, - gboolean transparent, - OutputDevData *output_dev_data) -{ - CairoOutputDev *output_dev; - cairo_surface_t *surface; - double width, height; - int cairo_width, cairo_height, cairo_rowstride, rotate; - unsigned char *cairo_data; - - rotate = rotation + page->page->getRotate (); - if (rotate == 90 || rotate == 270) { - height = page->page->getCropWidth (); - width = page->page->getCropHeight (); - } else { - width = page->page->getCropWidth (); - height = page->page->getCropHeight (); - } - - cairo_width = (int) ceil(width * scale); - cairo_height = (int) ceil(height * scale); - - output_dev = page->document->output_dev; - cairo_rowstride = cairo_width * 4; - cairo_data = (guchar *) gmallocn (cairo_height, cairo_rowstride); - if (transparent) - memset (cairo_data, 0x00, cairo_height * cairo_rowstride); - else - memset (cairo_data, 0xff, cairo_height * cairo_rowstride); - - surface = cairo_image_surface_create_for_data(cairo_data, - CAIRO_FORMAT_ARGB32, - cairo_width, cairo_height, - cairo_rowstride); - - output_dev_data->cairo_data = cairo_data; - output_dev_data->surface = surface; - output_dev_data->cairo = cairo_create (surface); - output_dev->setCairo (output_dev_data->cairo); -} - static void copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, - unsigned char *data, GdkPixbuf *pixbuf) { int cairo_width, cairo_height, cairo_rowstride; @@ -319,8 +268,8 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, cairo_width = cairo_image_surface_get_width (surface); cairo_height = cairo_image_surface_get_height (surface); - cairo_rowstride = cairo_width * 4; - cairo_data = data; + cairo_rowstride = cairo_image_surface_get_stride (surface); + cairo_data = cairo_image_surface_get_data (surface); pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); @@ -346,31 +295,6 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, } } } - -static void -poppler_page_copy_to_pixbuf (PopplerPage *page, - GdkPixbuf *pixbuf, - OutputDevData *output_dev_data) -{ - copy_cairo_surface_to_pixbuf (output_dev_data->surface, - output_dev_data->cairo_data, - pixbuf); - - page->document->output_dev->setCairo (NULL); - cairo_surface_destroy (output_dev_data->surface); - cairo_destroy (output_dev_data->cairo); - gfree (output_dev_data->cairo_data); -} - -static void -poppler_page_set_selection_alpha (PopplerPage *page, - double scale, - GdkPixbuf *pixbuf, - PopplerSelectionStyle style, - PopplerRectangle *selection) -{ - /* Cairo doesn't need this, since cairo generates an alpha channel. */ -} #endif /* POPPLER_WITH_GDK */ static GBool @@ -611,23 +535,47 @@ _poppler_page_render_to_pixbuf (PopplerPage *page, GBool printing, GdkPixbuf *pixbuf) { - OutputDevData data; - - poppler_page_prepare_output_dev (page, scale, rotation, FALSE, &data); + cairo_t *cr; + cairo_surface_t *surface; - page->page->displaySlice(page->document->output_dev, - 72.0 * scale, 72.0 * scale, - rotation, - gFalse, /* useMediaBox */ - gTrue, /* Crop */ - src_x, src_y, - src_width, src_height, - printing, - page->document->doc->getCatalog (), - NULL, NULL, - printing ? poppler_print_annot_cb : NULL, NULL); - - poppler_page_copy_to_pixbuf (page, pixbuf, &data); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + src_width, src_height); + cr = cairo_create (surface); + cairo_save (cr); + switch (rotation) { + case 90: + cairo_translate (cr, src_x + src_width, -src_y); + break; + case 180: + cairo_translate (cr, src_x + src_width, src_y + src_height); + break; + case 270: + cairo_translate (cr, -src_x, src_y + src_height); + break; + default: + cairo_translate (cr, -src_x, -src_y); + } + + if (scale != 1.0) + cairo_scale (cr, scale, scale); + + if (rotation != 0) + cairo_rotate (cr, rotation * G_PI / 180.0); + + if (printing) + poppler_page_render_for_printing (page, cr); + else + poppler_page_render (page, cr); + cairo_restore (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER); + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_paint (cr); + + cairo_destroy (cr); + + copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); } /** @@ -761,53 +709,64 @@ poppler_page_render_selection_to_pixbuf (PopplerPage *page, GdkColor *glyph_color, GdkColor *background_color) { - OutputDev *output_dev; - OutputDevData data; - TextPage *text; - SelectionStyle selection_style = selectionStyleGlyph; - PDFRectangle pdf_selection(selection->x1, selection->y1, - selection->x2, selection->y2); + cairo_t *cr; + cairo_surface_t *surface; + double width, height; + int cairo_width, cairo_height, rotate; + PopplerColor poppler_background_color; + PopplerColor poppler_glyph_color; - GfxColor gfx_background_color = { - { - background_color->red, - background_color->green, - background_color->blue - } - }; - GfxColor gfx_glyph_color = { - { - glyph_color->red, - glyph_color->green, - glyph_color->blue - } - }; + poppler_background_color.red = background_color->red; + poppler_background_color.green = background_color->green; + poppler_background_color.blue = background_color->blue; + poppler_glyph_color.red = glyph_color->red; + poppler_glyph_color.green = glyph_color->green; + poppler_glyph_color.blue = glyph_color->blue; - switch (style) - { - case POPPLER_SELECTION_GLYPH: - selection_style = selectionStyleGlyph; - break; - case POPPLER_SELECTION_WORD: - selection_style = selectionStyleWord; - break; - case POPPLER_SELECTION_LINE: - selection_style = selectionStyleLine; - break; - } + rotate = rotation + page->page->getRotate (); + if (rotate == 90 || rotate == 270) { + height = page->page->getCropWidth (); + width = page->page->getCropHeight (); + } else { + width = page->page->getCropWidth (); + height = page->page->getCropHeight (); + } - output_dev = page->document->output_dev; + cairo_width = (int) ceil(width * scale); + cairo_height = (int) ceil(height * scale); - poppler_page_prepare_output_dev (page, scale, rotation, TRUE, &data); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + cairo_width, cairo_height); + cr = cairo_create (surface); + cairo_set_source_rgba (cr, 0, 0, 0, 0); + cairo_paint (cr); - text = poppler_page_get_text_page (page); - text->drawSelection (output_dev, scale, rotation, - &pdf_selection, selection_style, - &gfx_glyph_color, &gfx_background_color); + switch (rotate) { + case 90: + cairo_translate (cr, cairo_width, 0); + break; + case 180: + cairo_translate (cr, cairo_width, cairo_height); + break; + case 270: + cairo_translate (cr, 0, cairo_height); + break; + default: + cairo_translate (cr, 0, 0); + } + if (scale != 1.0) + cairo_scale (cr, scale, scale); + + if (rotate != 0) + cairo_rotate (cr, rotation * G_PI / 180.0); + + poppler_page_render_selection (page, cr, selection, old_selection, style, + &poppler_glyph_color, &poppler_background_color); - poppler_page_copy_to_pixbuf (page, pixbuf, &data); + cairo_destroy (cr); - poppler_page_set_selection_alpha (page, scale, pixbuf, style, selection); + copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); } #endif /* POPPLER_WITH_GDK */ _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
