+static const gboolean supported_formats[] = {
+ TRUE, /* EV_FILE_FORMAT_PS */
+#ifdef HAVE_POPPLER_PAGE_RENDER
+ TRUE, /* EV_FILE_FORMAT_PDF */
+#else
+ FALSE, /* EV_FILE_FORMAT_PDF */
+#endif
+};
+
+static void
+pdf_print_context_free (PdfPrintContext *ctx)
+{
+ if (!ctx)
+ return;
+
+ if (ctx->ps_file) {
+ poppler_ps_file_free (ctx->ps_file);
+ ctx->ps_file = NULL;
+ }
+
+ if (ctx->pdf_cairo) {
+ cairo_destroy (ctx->pdf_cairo);
+ ctx->pdf_cairo = NULL;
+ }
+
+ g_free (ctx);
+}
+
+static gboolean
+pdf_document_file_exporter_format_supported (EvFileExporter *exporter,
+ EvFileExporterFormat format)
+{
+ return supported_formats[format];
+}
+
+static void
+pdf_document_file_exporter_begin (EvFileExporter *exporter,
+ EvFileExporterFormat format,
+ const char *filename,
+ int first_page,
+ int last_page,
+ double width,
+ double height,
+ gboolean duplex)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+ PdfPrintContext *ctx;
+
+ if (pdf_document->print_ctx)
+ pdf_print_context_free (pdf_document->print_ctx);
+ pdf_document->print_ctx = g_new0 (PdfPrintContext, 1);
+ ctx = pdf_document->print_ctx;
+ ctx->format = format;
+
+ switch (format) {
+ case EV_FILE_FORMAT_PS:
+ ctx->ps_file = poppler_ps_file_new (pdf_document->document,
+ filename, first_page,
+ last_page - first_page + 1);
+ poppler_ps_file_set_paper_size (ctx->ps_file, width, height);
+ poppler_ps_file_set_duplex (ctx->ps_file, duplex);
+
+ break;
+ case EV_FILE_FORMAT_PDF: {
+ cairo_surface_t *surface;
+
+ surface = cairo_pdf_surface_create (filename, width, height);
+ ctx->pdf_cairo = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+pdf_document_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+ PdfPrintContext *ctx = pdf_document->print_ctx;
+ PopplerPage *poppler_page;
+
+ g_return_if_fail (pdf_document->print_ctx != NULL);
+
+ poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
+
+ switch (ctx->format) {
+ case EV_FILE_FORMAT_PS:
+ poppler_page_render_to_ps (poppler_page, ctx->ps_file);
+ break;
+ case EV_FILE_FORMAT_PDF:
+#ifdef HAVE_POPPLER_PAGE_RENDER
+ poppler_page_render (poppler_page, ctx->pdf_cairo);
+#endif
+ cairo_show_page (ctx->pdf_cairo);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_object_unref (poppler_page);
+}
+
+static void
+pdf_document_file_exporter_end (EvFileExporter *exporter)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+
+ pdf_print_context_free (pdf_document->print_ctx);
+ pdf_document->print_ctx = NULL;
+}
+
+static void
+pdf_document_file_exporter_iface_init (EvFileExporterIface *iface)
+{
+ iface->format_supported = pdf_document_file_exporter_format_supported;
+ iface->begin = pdf_document_file_exporter_begin;
+ iface->do_page = pdf_document_file_exporter_do_page;
+ iface->end = pdf_document_file_exporter_end;
+}
+
+static void
+pdf_selection_render_selection (EvSelection *selection,
+ EvRenderContext *rc,
+ GdkPixbuf **pixbuf,
+ EvRectangle *points,
+ EvRectangle *old_points,
+ GdkColor *text,
+ GdkColor *base)
+{
+ PdfDocument *pdf_document;
+ double width_points, height_points;
+ gint width, height;
+
+ pdf_document = PDF_DOCUMENT (selection);
+ set_rc_data (pdf_document, rc);
+
+ poppler_page_get_size (POPPLER_PAGE (rc->data), &width_points, &height_points);
+ width = (int) ((width_points * rc->scale) + 0.5);
+ height = (int) ((height_points * rc->scale) + 0.5);
+
+ if (*pixbuf == NULL) {
+ * pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ width, height);
+ }
+
+ poppler_page_render_selection (POPPLER_PAGE (rc->data),
+ rc->scale, rc->rotation, *pixbuf,
+ (PopplerRectangle *)points,
+ (PopplerRectangle *)old_points,
+ text,
+ base);
+}
+
+
+static GdkRegion *
+pdf_selection_get_selection_region (EvSelection *selection,
+ EvRenderContext *rc,
+ EvRectangle *points)
+{
+ PdfDocument *pdf_document;
+ GdkRegion *retval;
+
+ pdf_document = PDF_DOCUMENT (selection);
+
+ set_rc_data (pdf_document, rc);
+
+ retval = poppler_page_get_selection_region ((PopplerPage *)rc->data, rc->scale, (PopplerRectangle *) points);
+
+ return retval;
+}
+
+static GdkRegion *
+pdf_selection_get_selection_map (EvSelection *selection,
+ EvRenderContext *rc)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ PopplerRectangle points;
+ GdkRegion *retval;
+
+ pdf_document = PDF_DOCUMENT (selection);
+ poppler_page = poppler_document_get_page (pdf_document->document,
+ rc->page);
+
+ points.x1 = 0.0;
+ points.y1 = 0.0;
+ poppler_page_get_size (poppler_page, &(points.x2), &(points.y2));
+ retval = poppler_page_get_selection_region (poppler_page, 1.0, &points);
+ g_object_unref (poppler_page);
+
+ return retval;
+}
+
+static void
+pdf_selection_iface_init (EvSelectionIface *iface)
+{
+ iface->render_selection = pdf_selection_render_selection;
+ iface->get_selection_region = pdf_selection_get_selection_region;
+ iface->get_selection_map = pdf_selection_get_selection_map;
+}