diff -r -u glib.orig/poppler-document.cc glib/poppler-document.cc --- glib.orig/poppler-document.cc 2005-05-18 10:39:59.000000000 -0700 +++ glib/poppler-document.cc 2005-05-21 12:49:10.764077377 -0700 @@ -38,6 +38,11 @@ PROP_AUTHOR, PROP_SUBJECT, PROP_KEYWORDS, + PROP_CREATOR, + PROP_PRODUCER, + PROP_CREATION_DATE, + PROP_MOD_DATE, + PROP_LINEARIZED, PROP_PAGE_LAYOUT, PROP_PAGE_MODE, PROP_VIEWER_PREFERENCES, @@ -222,6 +227,81 @@ g_free (result); } +static void +info_dict_get_date (Dict *info_dict, const gchar *key, GValue *value) +{ + Object obj; + GooString *goo_value; + int year, mon, day, hour, min, sec; + int scanned_items; + struct tm *time; + gchar *date_string; + GTime result; + + if (!info_dict->lookup ((gchar *)key, &obj)->isString ()) { + obj.free (); + return; + } + + goo_value = obj.getString (); + + if (has_unicode_marker (goo_value)) { + date_string = g_convert (goo_value->getCString () + 2, + goo_value->getLength () - 2, + "UTF-8", "UTF-16BE", NULL, NULL, NULL); + } else { + date_string = g_strndup (goo_value->getCString (), goo_value->getLength ()); + } + + /* See PDF Reference 1.3, Section 3.8.2 for PDF Date representation */ + + if (date_string [0] == 'D' && date_string [1] == ':') + date_string += 2; + + /* FIXME only year is mandatory; parse optional timezone offset */ + scanned_items = sscanf (date_string, "%4d%2d%2d%2d%2d%2d", + &year, &mon, &day, &hour, &min, &sec); + + if (scanned_items != 6) + return; + + /* Workaround for y2k bug in Distiller 3, hoping that it won't + * be used after y2.2k */ + if (year < 1930 && strlen (date_string) > 14) { + int century, years_since_1900; + scanned_items = sscanf (date_string, "%2d%3d%2d%2d%2d%2d%2d", + ¢ury, &years_since_1900, &mon, &day, &hour, &min, &sec); + + if (scanned_items != 7) + return; + + year = century * 100 + years_since_1900; + } + + time = g_new0 (struct tm, 1); + + time->tm_year = year - 1900; + time->tm_mon = mon - 1; + time->tm_mday = day; + time->tm_hour = hour; + time->tm_min = min; + time->tm_sec = sec; + time->tm_wday = -1; + time->tm_yday = -1; + time->tm_isdst = -1; /* 0 = DST off, 1 = DST on, -1 = don't know */ + + /* compute tm_wday and tm_yday and check date */ + if (mktime (time) == (time_t) - 1) { + return; + } else { + result = mktime (time); + } + + obj.free (); + + g_value_set_int (value, result); +} + static PopplerPageLayout convert_page_layout (Catalog::PageLayout pageLayout) { @@ -274,6 +354,7 @@ Object obj; Catalog *catalog; gchar *str; + GValue *tmp_value = g_new0 (GValue, 1); switch (prop_id) { @@ -303,6 +384,33 @@ if (obj.isDict ()) info_dict_get_string (obj.getDict(), "Keywords", value); break; + case PROP_CREATOR: + document->doc->getDocInfo (&obj); + if (obj.isDict ()) + info_dict_get_string (obj.getDict(), "Creator", value); + break; + case PROP_PRODUCER: + document->doc->getDocInfo (&obj); + if (obj.isDict ()) + info_dict_get_string (obj.getDict(), "Producer", value); + break; + case PROP_CREATION_DATE: + document->doc->getDocInfo (&obj); + if (obj.isDict ()) + info_dict_get_date (obj.getDict(), "CreationDate", value); + break; + case PROP_MOD_DATE: + document->doc->getDocInfo (&obj); + if (obj.isDict ()) + info_dict_get_date (obj.getDict(), "ModDate", value); + break; + case PROP_LINEARIZED: + if (document->doc->isLinearized ()) { + g_value_set_string (value, "Yes"); + } else { + g_value_set_string (value, "No"); + } + break; case PROP_PAGE_LAYOUT: catalog = document->doc->getCatalog (); if (catalog && catalog->isOk ()) @@ -383,6 +491,51 @@ g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_CREATOR, + g_param_spec_string ("creator", + "Creator", + "The software that created the document", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (G_OBJECT_CLASS (klass), + PROP_PRODUCER, + g_param_spec_string ("producer", + "Producer", + "The software that converted the document", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (G_OBJECT_CLASS (klass), + PROP_CREATION_DATE, + g_param_spec_int ("creation-date", + "Creation Date", + "The date and time the document was created", + 0, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (G_OBJECT_CLASS (klass), + PROP_MOD_DATE, + g_param_spec_int ("mod-date", + "Modification Date", + "The date and time the document was modified", + 0, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (G_OBJECT_CLASS (klass), + PROP_LINEARIZED, + g_param_spec_string ("linearized", + "Fast Web View Enabled", + "Is the document optimized for web viewing?", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (G_OBJECT_CLASS (klass), PROP_PAGE_LAYOUT, g_param_spec_enum ("page-layout", "Page Layout", @@ -417,7 +570,6 @@ { } - /* PopplerIndexIter: For determining the index of a tree */ struct _PopplerIndexIter { @@ -499,8 +651,6 @@ return child; } - - static gchar * unicode_to_char (Unicode *unicode, int len) diff -r -u glib.orig/test-poppler-glib.c glib/test-poppler-glib.c --- glib.orig/test-poppler-glib.c 2005-05-11 13:01:43.000000000 -0700 +++ glib/test-poppler-glib.c 2005-05-21 12:49:10.765077133 -0700 @@ -10,7 +10,8 @@ static void print_document_info (PopplerDocument *document) { - gchar *title, *format, *author, *subject, *keywords; + gchar *title, *format, *author, *subject, *keywords, *creator, *producer, *linearized; + GTime creation_date, mod_date; PopplerPageLayout layout; PopplerPageMode mode; PopplerViewerPreferences view_prefs; @@ -22,23 +23,36 @@ "author", &author, "subject", &subject, "keywords", &keywords, + "creation-date", &creation_date, + "mod-date", &mod_date, + "creator", &creator, + "producer", &producer, + "linearized", &linearized, "page-mode", &mode, "page-layout", &layout, "viewer-preferences", &view_prefs, NULL); - printf ("document metadata\n"); - if (title) printf ("\ttitle:\t%s\n", title); - if (format) printf ("\tformat:\t%s\n", format); - if (author) printf ("\tauthor:\t%s\n", author); + printf ("\t---------------------------------------------------------\n"); + printf ("\tDocument Metadata\n"); + printf ("\t---------------------------------------------------------\n"); + if (title) printf ("\ttitle:\t\t%s\n", title); + if (format) printf ("\tformat:\t\t%s\n", format); + if (author) printf ("\tauthor:\t\t%s\n", author); if (subject) printf ("\tsubject:\t%s\n", subject); - if (keywords) printf ("\tdkeywords:\t%s\n", keywords); - + if (keywords) printf ("\tkeywords:\t%s\n", keywords); + if (creator) printf ("\tcreator:\t%s\n", creator); + if (producer) printf ("\tproducer:\t%s\n", producer); + if (linearized) printf ("\tlinearized:\t%s\n", linearized); + enum_value = g_enum_get_value ((GEnumClass *) g_type_class_peek (POPPLER_TYPE_PAGE_MODE), mode); g_print ("\tpage mode:\t%s\n", enum_value->value_name); enum_value = g_enum_get_value ((GEnumClass *) g_type_class_peek (POPPLER_TYPE_PAGE_LAYOUT), layout); g_print ("\tpage layout:\t%s\n", enum_value->value_name); + g_print ("\tcreation date:\t%d\n", creation_date); + g_print ("\tmodified date:\t%d\n", mod_date); + /* FIXME: print out the view prefs when we support it */ g_free (title); @@ -46,6 +60,9 @@ g_free (author); g_free (subject); g_free (keywords); + g_free (creator); + g_free (producer); + g_free (linearized); } int main (int argc, char *argv[]) @@ -63,7 +80,7 @@ PopplerRectangle area; if (argc != 3) - FAIL ("usage: test-poppler-glib FILE PAGE"); + FAIL ("usage: test-poppler-glib file://FILE PAGE"); g_type_init (); @@ -84,7 +101,7 @@ FAIL ("page not found"); poppler_page_get_size (page, &width, &height); - printf ("page size: %f inches by %f inches\n", width / 72, height / 72); + printf ("\tpage size:\t%f inches by %f inches\n", width / 72, height / 72); thumb = poppler_page_get_thumbnail (page); if (thumb != NULL) { @@ -92,14 +109,14 @@ if (error != NULL) FAIL (error->message); else - printf ("saved thumbnail as thumb.png\n"); + printf ("\tthumbnail:\tsaved as thumb.png\n"); g_object_unref (G_OBJECT (thumb)); } else - printf ("no thumbnail for page\n"); + printf ("\tthumbnail:\tno thumbnail for page\n"); g_object_get (page, "label", &label, NULL); - printf ("page label: %s\n", label); + printf ("\tpage label:\t%s\n", label); g_free (label); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 220, 220); @@ -107,7 +124,7 @@ poppler_page_render_to_pixbuf (page, 100, 100, 200, 200, 1, pixbuf, 10, 10); gdk_pixbuf_save (pixbuf, "slice.png", "png", &error, NULL); - printf ("saved 200x200 slice at (100, 100) as slice.png\n"); + printf ("\tslice:\t\tsaved 200x200 slice at (100, 100) as slice.png\n"); if (error != NULL) FAIL (error->message); @@ -129,7 +146,8 @@ } list = poppler_page_find_text (page, "Bitwise"); - printf ("Found text \"Bitwise\" at positions:\n"); + printf ("\n"); + printf ("\tFound text \"Bitwise\" at positions:\n"); for (l = list; l != NULL; l = l->next) { PopplerRectangle *rect = l->data;