#include "ev-document-fonts.h"
#include "ev-document-security.h"
#include "ev-document-thumbnails.h"
+#include "ev-selection.h"
typedef struct {
PdfDocument *document;
gchar *password;
PopplerOrientation orientation;
+ gboolean orientation_set;
PopplerFontInfo *font_info;
PopplerFontsIter *fonts_iter;
static void pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface);
static void pdf_document_find_iface_init (EvDocumentFindIface *iface);
static void pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface);
+static void pdf_selection_iface_init (EvSelectionIface *iface);
static void pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails,
gint page,
gint size,
gint *width,
gint *height);
+static int pdf_document_get_n_pages (EvDocument *document);
+
static EvLink * ev_link_from_action (PopplerAction *action);
+static void pdf_document_search_free (PdfDocumentSearch *search);
G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
pdf_document_find_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_PS_EXPORTER,
pdf_document_ps_exporter_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_SELECTION,
+ pdf_selection_iface_init);
});
+static void
+pdf_document_search_free (PdfDocumentSearch *search)
+{
+ PdfDocument *pdf_document = search->document;
+ int n_pages;
+ int i;
+
+ if (search->idle != 0)
+ g_source_remove (search->idle);
+
+ n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
+ for (i = 0; i < n_pages; i++) {
+ g_list_foreach (search->pages[i], (GFunc) g_free, NULL);
+ g_list_free (search->pages[i]);
+ }
+
+ g_free (search->text);
+}
+
static void
pdf_document_dispose (GObject *object)
{
PdfDocument *pdf_document = PDF_DOCUMENT(object);
+ if (pdf_document->search) {
+ pdf_document_search_free (pdf_document->search);
+ pdf_document->search = NULL;
+ }
+
if (pdf_document->document) {
g_object_unref (pdf_document->document);
}
return retval;
}
+static PopplerOrientation
+get_document_orientation (PdfDocument *pdf_document)
+{
+ PopplerOrientation orientation;
+ PopplerPage *page;
+
+ /* Should prolly be smarter here and check more than first page */
+ page = poppler_document_get_page (pdf_document->document, 0);
+ if (page) {
+ orientation = poppler_page_get_orientation (page);
+ } else {
+ orientation = POPPLER_ORIENTATION_PORTRAIT;
+ }
+ g_object_unref (page);
+
+ return orientation;
+}
+
static gboolean
pdf_document_load (EvDocument *document,
const char *uri,
return poppler_document_get_n_pages (PDF_DOCUMENT (document)->document);
}
+/* FIXME This should not be necessary, poppler should rember it */
+static void
+set_page_orientation (PdfDocument *pdf_document, PopplerPage *page)
+{
+ if (pdf_document->orientation_set) {
+ poppler_page_set_orientation (page, pdf_document->orientation);
+ }
+}
+
static void
pdf_document_get_page_size (EvDocument *document,
int page,
PopplerPage *poppler_page;
poppler_page = poppler_document_get_page (pdf_document->document, page);
- poppler_page_set_orientation (poppler_page, pdf_document->orientation);
+ set_page_orientation (pdf_document, poppler_page);
poppler_page_get_size (poppler_page, width, height);
+ g_object_unref (poppler_page);
}
static char *
g_object_get (G_OBJECT (poppler_page),
"label", &label,
NULL);
+ g_object_unref (poppler_page);
return label;
}
}
poppler_page_free_link_mapping (mapping_list);
+ g_object_unref (poppler_page);
return g_list_reverse (retval);
}
static GdkPixbuf *
pdf_document_render_pixbuf (EvDocument *document,
- int page,
- double scale)
+ EvRenderContext *rc)
{
PdfDocument *pdf_document;
PopplerPage *poppler_page;
pdf_document = PDF_DOCUMENT (document);
poppler_page = poppler_document_get_page (pdf_document->document,
- page);
- poppler_page_set_orientation (poppler_page, pdf_document->orientation);
+ rc->page);
+ set_page_orientation (pdf_document, poppler_page);
poppler_page_get_size (poppler_page, &width_points, &height_points);
- width = (int) ((width_points * scale) + 0.5);
- height = (int) ((height_points * scale) + 0.5);
+ width = (int) ((width_points * rc->scale) + 0.5);
+ height = (int) ((height_points * rc->scale) + 0.5);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
FALSE, 8,
poppler_page_render_to_pixbuf (poppler_page,
0, 0,
width, height,
- scale,
- pixbuf,
- 0, 0);
-
+ rc->scale,
+ pixbuf);
+
+ g_object_unref (poppler_page);
+
return pixbuf;
}
PopplerPage *poppler_page;
PopplerRectangle r;
double height;
+ char *text;
poppler_page = poppler_document_get_page (pdf_document->document, page);
+ set_page_orientation (pdf_document, poppler_page);
g_return_val_if_fail (poppler_page != NULL, NULL);
poppler_page_get_size (poppler_page, NULL, &height);
r.x2 = rect->x2;
r.y2 = height - rect->y1;
- return poppler_page_get_text (poppler_page, &r);
+ text = poppler_page_get_text (poppler_page, &r);
+
+ g_object_unref (poppler_page);
+
+ return text;
+}
+
+static EvOrientation
+pdf_document_get_orientation (EvDocument *document)
+{
+ EvOrientation result;
+ PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+ if (!pdf_document->orientation_set) {
+ pdf_document->orientation = get_document_orientation (pdf_document);
+ }
+
+ switch (pdf_document->orientation) {
+ case POPPLER_ORIENTATION_PORTRAIT:
+ result = EV_ORIENTATION_PORTRAIT;
+ break;
+ case POPPLER_ORIENTATION_LANDSCAPE:
+ result = EV_ORIENTATION_LANDSCAPE;
+ break;
+ case POPPLER_ORIENTATION_UPSIDEDOWN:
+ result = EV_ORIENTATION_UPSIDEDOWN;
+ break;
+ case POPPLER_ORIENTATION_SEASCAPE:
+ result = EV_ORIENTATION_SEASCAPE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return result;
}
static void
PopplerOrientation poppler_orientation;
switch (orientation) {
- case EV_ORIENTATION_DOCUMENT:
- poppler_orientation = POPPLER_ORIENTATION_DOCUMENT;
- break;
- case EV_ORIENTATION_PORTRAIT:
- poppler_orientation = POPPLER_ORIENTATION_PORTRAIT;
- break;
- case EV_ORIENTATION_LANDSCAPE:
- poppler_orientation = POPPLER_ORIENTATION_LANDSCAPE;
- break;
- case EV_ORIENTATION_UPSIDEDOWN:
- poppler_orientation = POPPLER_ORIENTATION_UPSIDEDOWN;
- break;
- case EV_ORIENTATION_SEASCAPE:
- poppler_orientation = POPPLER_ORIENTATION_SEASCAPE;
- break;
+ case EV_ORIENTATION_PORTRAIT:
+ poppler_orientation = POPPLER_ORIENTATION_PORTRAIT;
+ break;
+ case EV_ORIENTATION_LANDSCAPE:
+ poppler_orientation = POPPLER_ORIENTATION_LANDSCAPE;
+ break;
+ case EV_ORIENTATION_UPSIDEDOWN:
+ poppler_orientation = POPPLER_ORIENTATION_UPSIDEDOWN;
+ break;
+ case EV_ORIENTATION_SEASCAPE:
+ poppler_orientation = POPPLER_ORIENTATION_SEASCAPE;
+ break;
+ default:
+ g_assert_not_reached ();
}
pdf_document->orientation = poppler_orientation;
+ pdf_document->orientation_set = TRUE;
}
static void
iface->can_get_text = pdf_document_can_get_text;
iface->get_info = pdf_document_get_info;
iface->set_orientation = pdf_document_set_orientation;
+ iface->get_orientation = pdf_document_get_orientation;
};
static void
return result;
}
+static const char *
+font_type_to_string (PopplerFontType type)
+{
+ switch (type)
+ {
+ case POPPLER_FONT_TYPE_TYPE1:
+ return _("Type 1");
+ case POPPLER_FONT_TYPE_TYPE1C:
+ return _("Type 1C");
+ case POPPLER_FONT_TYPE_TYPE3:
+ return _("Type 3");
+ case POPPLER_FONT_TYPE_TRUETYPE:
+ return _("TrueType");
+ case POPPLER_FONT_TYPE_CID_TYPE0:
+ return _("Type 1 (CID)");
+ case POPPLER_FONT_TYPE_CID_TYPE0C:
+ return _("Type 1C (CID)");
+ case POPPLER_FONT_TYPE_CID_TYPE2:
+ return _("TrueType (CID)");
+ default:
+ return _("Unknown font type ");
+ }
+}
+
static void
pdf_document_fonts_fill_model (EvDocumentFonts *document_fonts,
GtkTreeModel *model)
g_return_if_fail (PDF_IS_DOCUMENT (document_fonts));
- if (iter) {
- do {
- GtkTreeIter list_iter;
- PopplerIndexIter *child;
- const char *name;
+ if (!iter)
+ return;
+
+ do {
+ GtkTreeIter list_iter;
+ const char *name;
+ const char *type;
+ const char *embedded;
+ char *details;
- name = poppler_fonts_iter_get_name (iter);
- gtk_list_store_append (GTK_LIST_STORE (model), &list_iter);
- gtk_list_store_set (GTK_LIST_STORE (model), &list_iter,
- EV_DOCUMENT_FONTS_COLUMN_NAME, name,
- -1);
- } while (poppler_fonts_iter_next (iter));
- }
+ name = poppler_fonts_iter_get_name (iter);
+
+ if (name == NULL) {
+ name = _("No name");
+ }
+
+ type = font_type_to_string (
+ poppler_fonts_iter_get_font_type (iter));
+
+ if (poppler_fonts_iter_is_embedded (iter)) {
+ if (poppler_fonts_iter_is_subset (iter))
+ embedded = _("Embedded subset");
+ else
+ embedded = _("Embedded");
+ } else {
+ embedded = _("Not embedded");
+ }
+
+ details = g_markup_printf_escaped ("%s\n%s", type, embedded);
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &list_iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &list_iter,
+ EV_DOCUMENT_FONTS_COLUMN_NAME, name,
+ EV_DOCUMENT_FONTS_COLUMN_DETAILS, details,
+ -1);
+
+ g_free (details);
+ } while (poppler_fonts_iter_next (iter));
}
static void
gboolean expand;
action = poppler_index_iter_get_action (iter);
-#ifdef POPPLER_LINK_IS_OPEN
expand = poppler_index_iter_is_open (iter);
-#else
- expand = TRUE;
-#endif
if (action) {
gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
link = ev_link_from_action (action);
EV_DOCUMENT_LINKS_COLUMN_LINK, link,
EV_DOCUMENT_LINKS_COLUMN_EXPAND, expand,
-1);
+ g_object_unref (link);
child = poppler_index_iter_get_child (iter);
if (child)
build_tree (pdf_document, model, &tree_iter, child);
if (iter != NULL) {
model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
G_TYPE_STRING,
- G_TYPE_POINTER,
+ G_TYPE_OBJECT,
G_TYPE_BOOLEAN);
build_tree (pdf_document, model, NULL, iter);
poppler_index_iter_free (iter);
gboolean border)
{
PopplerPage *poppler_page;
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf, *sub_pixbuf;
int width, height;
- int x_offset, y_offset;
double scale;
gdouble unscaled_width, unscaled_height;
poppler_page = poppler_document_get_page (pdf_document->document, page);
-
+ set_page_orientation (pdf_document, poppler_page);
g_return_val_if_fail (poppler_page != NULL, NULL);
pdf_document_thumbnails_get_dimensions (EV_DOCUMENT_THUMBNAILS (pdf_document), page, size, &width, &height);
if (border) {
pixbuf = ev_document_misc_get_thumbnail_frame (width, height, NULL);
- x_offset = 1;
- y_offset = 1;
+
+ sub_pixbuf = gdk_pixbuf_new_subpixbuf (pixbuf,
+ 1, 1,
+ width - 1, height - 1);
} else {
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
width, height);
gdk_pixbuf_fill (pixbuf, 0xffffffff);
- x_offset = 0;
- y_offset = 0;
+ sub_pixbuf = gdk_pixbuf_new_subpixbuf (pixbuf,
+ 0, 0,
+ width, height);
}
poppler_page_render_to_pixbuf (poppler_page, 0, 0,
width, height,
- scale, pixbuf,
- x_offset, y_offset);
+ scale, sub_pixbuf);
+ g_object_unref (G_OBJECT (sub_pixbuf));
+
+ g_object_unref (poppler_page);
return pixbuf;
}
pdf_document = PDF_DOCUMENT (document_thumbnails);
poppler_page = poppler_document_get_page (pdf_document->document, page);
+ set_page_orientation (pdf_document, poppler_page);
g_return_val_if_fail (poppler_page != NULL, NULL);
pixbuf = poppler_page_get_thumbnail (poppler_page);
+
if (pixbuf != NULL) {
/* The document provides its own thumbnails. */
if (border) {
/* There is no provided thumbnail. We need to make one. */
pixbuf = make_thumbnail_for_size (pdf_document, page, size, border);
}
+
+ g_object_unref (poppler_page);
+
return pixbuf;
}
pdf_document = PDF_DOCUMENT (document_thumbnails);
poppler_page = poppler_document_get_page (pdf_document->document, page);
+ set_page_orientation (pdf_document, poppler_page);
g_return_if_fail (width != NULL);
g_return_if_fail (height != NULL);
*height = size;
}
}
+ g_object_unref (poppler_page);
}
static void
page = poppler_document_get_page (search->document->document,
search->search_page);
+ set_page_orientation (pdf_document, page);
ev_document_doc_mutex_lock ();
matches = poppler_page_find_text (page, search->text);
ev_document_doc_mutex_unlock ();
+ g_object_unref (page);
+
search->pages[search->search_page] = matches;
ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
search->search_page);
return search;
}
-static void
-pdf_document_search_free (PdfDocumentSearch *search)
-{
- PdfDocument *pdf_document = search->document;
- int n_pages;
- int i;
-
- if (search->idle != 0)
- g_source_remove (search->idle);
-
- n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
- for (i = 0; i < n_pages; i++) {
- g_list_foreach (search->pages[i], (GFunc) g_free, NULL);
- g_list_free (search->pages[i]);
- }
-
- g_free (search->text);
-}
-
static void
pdf_document_find_begin (EvDocumentFind *document,
int page,
return FALSE;
poppler_page = poppler_document_get_page (pdf_document->document, page);
+ set_page_orientation (pdf_document, poppler_page);
poppler_page_get_size (poppler_page, NULL, &height);
rectangle->x1 = r->x1;
rectangle->y1 = height - r->y2;
rectangle->x2 = r->x2;
rectangle->y2 = height - r->y1;
-
+ g_object_unref (poppler_page);
+
return TRUE;
}
g_return_if_fail (pdf_document->ps_file != NULL);
poppler_page = poppler_document_get_page (pdf_document->document, page);
+ set_page_orientation (pdf_document, poppler_page);
poppler_page_render_to_ps (poppler_page, pdf_document->ps_file);
+ g_object_unref (poppler_page);
}
static void
iface->end = pdf_document_ps_exporter_end;
}
+
+void
+pdf_selection_render_selection (EvSelection *selection,
+ EvRenderContext *rc,
+ GdkPixbuf **pixbuf,
+ EvRectangle *points,
+ EvRectangle *old_points)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ double width_points, height_points;
+ gint width, height;
+
+ pdf_document = PDF_DOCUMENT (selection);
+ poppler_page = poppler_document_get_page (pdf_document->document,
+ rc->page);
+ set_page_orientation (pdf_document, poppler_page);
+
+ poppler_page_get_size (poppler_page, &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->scale, *pixbuf,
+ (PopplerRectangle *)points,
+ (PopplerRectangle *)old_points);
+ g_object_unref (poppler_page);
+
+}
+
+
+GdkRegion *
+pdf_selection_get_selection_region (EvSelection *selection,
+ EvRenderContext *rc,
+ EvRectangle *points)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ GdkRegion *retval;
+
+ pdf_document = PDF_DOCUMENT (selection);
+ poppler_page = poppler_document_get_page (pdf_document->document,
+ rc->page);
+ set_page_orientation (pdf_document, poppler_page);
+
+ retval = poppler_page_get_selection_region (poppler_page, rc->scale, (PopplerRectangle *) points);
+ g_object_unref (poppler_page);
+
+ return retval;
+}
+
+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);
+ set_page_orientation (pdf_document, poppler_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;
+}
+
PdfDocument *
pdf_document_new (void)
{