PageInfo *analyse_page (PopplerDocument *doc, guint page_num) { PopplerPage *page; PageInfo *info; GdkPixbuf *image; double width_points, height_points; int width, height; gboolean *white_rows, *white_cols; page = poppler_document_get_page (doc, page_num); if (!page) { g_error ("Couldn't open page %d of document", page_num); } /* There are 72 points in an inch. So width and height should be * multiplied by settings.dpi / 72.0 */ poppler_page_get_size (page, &width_points, &height_points); width = (int) ((width_points * settings.dpi / 72.0) + 0.5); height = (int) ((height_points * settings.dpi / 72.0) + 0.5); image = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); if (!image) { g_error ("Couldn't create an image (size %d x %d) for page %d", width, height, page_num); } poppler_page_render_to_pixbuf (page, 0, 0, width, height, settings.dpi / 72.0, 0, image); g_object_unref (page); find_white (image, &white_rows, &white_cols); g_object_unref (image); guint firstrow, lastrow, hunkscount; HunkData* hunks = find_hunks (white_rows, height, &firstrow, &lastrow, &hunkscount); info = g_new (PageInfo, 1); info->bbox.x = first_zero (white_cols, width); info->bbox.width = last_zero (white_cols, width) - info->bbox.x; if (info->bbox.width <= 0) { g_error ("Empty page (%d)? Couldn't find a nonwhite column.", page_num); } info->bbox.y = firstrow; info->bbox.height = lastrow - firstrow; info->num_hunks = hunkscount; info->hunks = hunks; g_free (white_rows); g_free (white_cols); return info; }
static GdkPixbuf * get_thumbnail (PopplerDocument *doc, gint page_num, gint preferred_size) { PopplerPage *page; GdkPixbuf *pixbuf; page = poppler_document_get_page (doc, page_num); if (! page) return NULL; /* XXX: Remove conditional when we depend on poppler 0.8.0, but also * add configure check to make sure POPPLER_WITH_GDK is enabled! */ #ifdef POPPLER_WITH_GDK pixbuf = poppler_page_get_thumbnail_pixbuf (page); #else pixbuf = poppler_page_get_thumbnail (page); #endif if (! pixbuf) { gdouble width; gdouble height; gdouble scale; poppler_page_get_size (page, &width, &height); scale = (gdouble) preferred_size / MAX (width, height); width *= scale; height *= scale; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, pixbuf); } g_object_unref (page); return pixbuf; }
static GdkPixbuf * xv_doc_get_gdkbuf(struct xv_page_t *page, PgdRenderMode mode, double scale) { if (mode != page->mode || page->scale != scale) { if (page->pixbuf) { xv_page_paint_free (page); } page->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, page->width * scale, page->height * scale); gdk_pixbuf_fill (page->pixbuf, 0xffffff); poppler_page_render_to_pixbuf (page->page, 0, 0, page->width * scale, page->height *scale, scale, /* scale */ 0, /* rotate */ page->pixbuf); page->scale = scale; page->mode = mode; } return page->pixbuf; }
static GdkPixbuf * getRenderedPixbuf(struct viewport *pp, int mypage_i) { int myfitmode = -1; double pw = 0, ph = 0; double w = 0, h = 0; double page_ratio = 1, screen_ratio = 1, scale = 1; GdkPixbuf *targetBuf = NULL; PopplerPage *page = NULL; GList *it = NULL; struct cacheItem *ci = NULL; gboolean found = FALSE; /* Limit boundaries of mypage_i -- just to be sure. */ if (mypage_i < 0 || mypage_i >= doc_n_pages) return NULL; /* Get this page and its ratio. That function should never return * NULL because we already took care of it. Catch it nontheless. */ page = poppler_document_get_page(doc, mypage_i); if (page == NULL) return NULL; poppler_page_get_size(page, &pw, &ph); page_ratio = pw / ph; screen_ratio = (double)pp->width / (double)pp->height; /* select fit mode */ if (runpref.fit_mode == FIT_PAGE) { /* that's it: compare screen and page ratio. this * will cover all 4 cases that could happen. */ if (screen_ratio > page_ratio) myfitmode = FIT_HEIGHT; else myfitmode = FIT_WIDTH; } else myfitmode = runpref.fit_mode; switch (myfitmode) { case FIT_HEIGHT: h = pp->height; w = h * page_ratio; scale = h / ph; break; case FIT_WIDTH: w = pp->width; h = w / page_ratio; scale = w / pw; break; } /* check if already in cache. */ it = cache; found = FALSE; while (it) { ci = (struct cacheItem *)(it->data); if (ci->slidenum == mypage_i && ci->w == w && ci->h == h && ci->scale == scale) { /* cache hit. */ found = TRUE; targetBuf = ci->pixbuf; /* we need to increase this item's "score", that is marking * it as a "recent" item. we do so by placing it at the end * of the list. */ cache = g_list_remove(cache, ci); cache = g_list_append(cache, ci); /* now quit the loop. */ break; } it = g_list_next(it); } if (!found) { /* cache miss, render to a pixbuf. */ targetBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h); g_assert(targetBuf); poppler_page_render_to_pixbuf(page, 0, 0, w, h, scale, 0, targetBuf); /* check if cache full. if so, kill the oldest item. */ if (g_list_length(cache) + 1 > runpref.cache_max) { it = g_list_first(cache); if (it == NULL) { fprintf(stderr, "[Cache] No first item in list." " cache_max too small?\n"); } else { /* unref pixbuf. */ ci = (struct cacheItem *)(it->data); if (ci->pixbuf != NULL) g_object_unref(ci->pixbuf); /* free memory alloc'd for the struct. */ free(ci); /* remove the pointer which is now invalid from the * list. */ cache = g_list_remove(cache, ci); } } /* add new item to cache. */ ci = (struct cacheItem *)malloc(sizeof(struct cacheItem)); ci->slidenum = mypage_i; ci->w = w; ci->h = h; ci->scale = scale; ci->pixbuf = targetBuf; cache = g_list_append(cache, ci); } /* cleanup */ g_object_unref(G_OBJECT(page)); return targetBuf; }
static void pgd_render_start (GtkButton *button, PgdRenderDemo *demo) { PopplerPage *page; gdouble page_width, page_height; gdouble width, height; gint x, y; gchar *str; GTimer *timer; page = poppler_document_get_page (demo->doc, demo->page); if (!page) return; if (demo->surface) cairo_surface_destroy (demo->surface); demo->surface = NULL; if (demo->pixbuf) g_object_unref (demo->pixbuf); demo->pixbuf = NULL; poppler_page_get_size (page, &page_width, &page_height); if (demo->rotate == 0 || demo->rotate == 180) { width = demo->slice.width * demo->scale; height = demo->slice.height * demo->scale; x = demo->slice.x * demo->scale; y = demo->slice.y * demo->scale; } else { width = demo->slice.height * demo->scale; height = demo->slice.width * demo->scale; x = demo->slice.y * demo->scale; y = demo->slice.x * demo->scale; } if (demo->mode == PGD_RENDER_CAIRO) { cairo_t *cr; timer = g_timer_new (); demo->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (demo->surface); cairo_save (cr); switch (demo->rotate) { case 90: cairo_translate (cr, x + width, -y); break; case 180: cairo_translate (cr, x + width, y + height); break; case 270: cairo_translate (cr, -x, y + height); break; default: cairo_translate (cr, -x, -y); } if (demo->scale != 1.0) cairo_scale (cr, demo->scale, demo->scale); if (demo->rotate != 0) cairo_rotate (cr, demo->rotate * G_PI / 180.0); if (demo->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); g_timer_stop (timer); cairo_destroy (cr); } else if (demo->mode == PGD_RENDER_PIXBUF) { #ifdef POPPLER_WITH_GDK timer = g_timer_new (); demo->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); gdk_pixbuf_fill (demo->pixbuf, 0xffffff); if (demo->printing) { poppler_page_render_to_pixbuf_for_printing (page, x, y, width, height, demo->scale, demo->rotate, demo->pixbuf); } else { poppler_page_render_to_pixbuf (page, x, y, width, height, demo->scale, demo->rotate, demo->pixbuf); } g_timer_stop (timer); #endif /* POPPLER_WITH_GDK */ } else { g_assert_not_reached (); } g_object_unref (page); str = g_strdup_printf ("<i>Page rendered in %.4f seconds</i>", g_timer_elapsed (timer, NULL)); gtk_label_set_markup (GTK_LABEL (demo->timer_label), str); g_free (str); g_timer_destroy (timer); gtk_widget_set_size_request (demo->darea, width, height); gtk_widget_queue_draw (demo->darea); }
static gint32 load_image (PopplerDocument *doc, const gchar *filename, GimpRunMode run_mode, GimpPageSelectorTarget target, guint32 resolution, PdfSelectedPages *pages) { gint32 image_ID = 0; gint32 *images = NULL; gint i; gdouble scale; gdouble doc_progress = 0; if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) images = g_new0 (gint32, pages->n_pages); gimp_progress_init_printf (_("Opening '%s'"), gimp_filename_to_utf8 (filename)); scale = resolution / gimp_unit_get_factor (GIMP_UNIT_POINT); /* read the file */ for (i = 0; i < pages->n_pages; i++) { PopplerPage *page; gchar *page_label; gdouble page_width; gdouble page_height; GdkPixbuf *buf; gint width; gint height; page = poppler_document_get_page (doc, pages->pages[i]); poppler_page_get_size (page, &page_width, &page_height); width = page_width * scale; height = page_height * scale; g_object_get (G_OBJECT (page), "label", &page_label, NULL); if (! image_ID) { gchar *name; image_ID = gimp_image_new (width, height, GIMP_RGB); gimp_image_undo_disable (image_ID); if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) name = g_strdup_printf (_("%s-%s"), filename, page_label); else name = g_strdup_printf (_("%s-pages"), filename); gimp_image_set_filename (image_ID, name); g_free (name); gimp_image_set_resolution (image_ID, resolution, resolution); } buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, buf); layer_from_pixbuf (image_ID, page_label, i, buf, doc_progress, 1.0 / pages->n_pages); g_free (page_label); g_object_unref (buf); doc_progress = (double) (i + 1) / pages->n_pages; gimp_progress_update (doc_progress); if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) { images[i] = image_ID; gimp_image_undo_enable (image_ID); gimp_image_clean_all (image_ID); image_ID = 0; } } if (image_ID) { gimp_image_undo_enable (image_ID); gimp_image_clean_all (image_ID); } if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) { if (run_mode != GIMP_RUN_NONINTERACTIVE) { /* Display images in reverse order. The last will be * displayed by GIMP itself */ for (i = pages->n_pages - 1; i > 0; i--) gimp_display_new (images[i]); } image_ID = images[0]; g_free (images); } return image_ID; }