示例#1
0
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;
}
示例#3
0
文件: doc.c 项目: arsane/vipdf
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;
}
示例#4
0
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;
}
示例#5
0
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;
}