summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/win_main.c84
-rw-r--r--apps/win_res.rc36
-rw-r--r--cbz/mucbz.c17
-rw-r--r--fitz/doc_document.c8
-rw-r--r--fitz/fitz-internal.h1
-rw-r--r--fitz/fitz.h70
-rw-r--r--pdf/pdf_xref.c76
-rw-r--r--xps/xps_zip.c17
8 files changed, 309 insertions, 0 deletions
diff --git a/apps/win_main.c b/apps/win_main.c
index 37864e19..cc71a120 100644
--- a/apps/win_main.c
+++ b/apps/win_main.c
@@ -20,6 +20,7 @@
#endif
#define ID_ABOUT 0x1000
+#define ID_DOCINFO 0x1001
static HWND hwndframe = NULL;
static HWND hwndview = NULL;
@@ -165,6 +166,83 @@ char *winpassword(pdfapp_t *app, char *filename)
}
INT CALLBACK
+dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ char buf[256];
+ fz_document *doc = gapp.doc;
+
+ switch(message)
+ {
+ case WM_INITDIALOG:
+
+ SetDlgItemTextW(hwnd, 0x10, wbuf);
+
+ if (fz_meta(doc, FZ_META_FORMAT_INFO, buf, 256) < 0)
+ {
+ SetDlgItemTextA(hwnd, 0x11, "Unknown");
+ SetDlgItemTextA(hwnd, 0x12, "None");
+ SetDlgItemTextA(hwnd, 0x13, "n/a");
+ return TRUE;
+ }
+
+ SetDlgItemTextA(hwnd, 0x11, buf);
+
+ if (fz_meta(doc, FZ_META_CRYPT_INFO, buf, 256) == 0)
+ {
+ SetDlgItemTextA(hwnd, 0x12, buf);
+ }
+ else
+ {
+ SetDlgItemTextA(hwnd, 0x12, "None");
+ }
+ buf[0] = 0;
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_PRINT) == 0)
+ strcat(buf, "print, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_CHANGE) == 0)
+ strcat(buf, "modify, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_COPY) == 0)
+ strcat(buf, "copy, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_NOTES) == 0)
+ strcat(buf, "annotate, ");
+ if (strlen(buf) > 2)
+ buf[strlen(buf)-2] = 0;
+ else
+ strcpy(buf, "None");
+ SetDlgItemTextA(hwnd, 0x13, buf);
+
+#define SETUTF8(ID, STRING) \
+ { \
+ *(char **)buf = STRING; \
+ if (fz_meta(doc, FZ_META_INFO, buf, 256) <= 0) \
+ buf[0] = 0; \
+ SetDlgItemTextA(hwnd, ID, buf); \
+ }
+
+ SETUTF8(0x20, "Title");
+ SETUTF8(0x21, "Author");
+ SETUTF8(0x22, "Subject");
+ SETUTF8(0x23, "Keywords");
+ SETUTF8(0x24, "Creator");
+ SETUTF8(0x25, "Producer");
+ SETUTF8(0x26, "CreationDate");
+ SETUTF8(0x27, "ModDate");
+ return TRUE;
+
+ case WM_COMMAND:
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void info()
+{
+ int code = DialogBoxW(NULL, L"IDD_DLOGINFO", hwndframe, dloginfoproc);
+ if (code <= 0)
+ winerror(&gapp, "cannot create info dialog");
+}
+
+INT CALLBACK
dlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
@@ -287,6 +365,7 @@ void winopen()
menu = GetSystemMenu(hwndframe, 0);
AppendMenuW(menu, MF_SEPARATOR, 0, NULL);
AppendMenuW(menu, MF_STRING, ID_ABOUT, L"About MuPDF...");
+ AppendMenuW(menu, MF_STRING, ID_DOCINFO, L"Document Properties...");
SetCursor(arrowcurs);
}
@@ -600,6 +679,11 @@ frameproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winhelp(&gapp);
return 0;
}
+ if (wParam == ID_DOCINFO)
+ {
+ info();
+ return 0;
+ }
if (wParam == SC_MAXIMIZE)
gapp.shrinkwrap = 0;
break;
diff --git a/apps/win_res.rc b/apps/win_res.rc
index 75b94ebe..f87de7d0 100644
--- a/apps/win_res.rc
+++ b/apps/win_res.rc
@@ -13,6 +13,42 @@ BEGIN
LTEXT "Password:", 5, 17, 22, 40, 10, 0x00000
END
+IDD_DLOGINFO DIALOG 50, 50, 300, 145
+STYLE 128 | 0x80000000
+CAPTION " Document Properties "
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "Okay", 1, 300-10-50, 145-7-14, 50, 14, 0x50010001
+
+ LTEXT "File:", -1, 10, 10, 50, 10, 0
+ LTEXT "Format:", -1, 10, 20, 50, 10, 0
+ LTEXT "Encryption:", -1, 10, 30, 50, 10, 0
+ LTEXT "Permissions:", -1, 10, 40, 50, 10, 0
+
+ LTEXT "<file", 0x10, 60, 10, 230, 10, 0
+ LTEXT "<version", 0x11, 60, 20, 230, 10, 0
+ LTEXT "<encryption", 0x12, 60, 30, 230, 10, 0
+ LTEXT "<permissions", 0x13, 60, 40, 230, 10, 0
+
+ LTEXT "Title:", -1, 10, 55, 50, 10, 0
+ LTEXT "Author:", -1, 10, 65, 50, 10, 0
+ LTEXT "Subject:", -1, 10, 75, 50, 10, 0
+ LTEXT "Keywords:", -1, 10, 85, 50, 10, 0
+ LTEXT "Creator:", -1, 10, 95, 50, 10, 0
+ LTEXT "Producer:", -1, 10, 105, 50, 10, 0
+ LTEXT "Created:", -1, 10, 115, 50, 10, 0
+ LTEXT "Modified:", -1, 10, 125, 50, 10, 0
+
+ LTEXT "", 0x20, 60, 55, 230, 10, 0
+ LTEXT "", 0x21, 60, 65, 230, 10, 0
+ LTEXT "", 0x22, 60, 75, 230, 10, 0
+ LTEXT "", 0x23, 60, 85, 230, 10, 0
+ LTEXT "", 0x24, 60, 95, 230, 10, 0
+ LTEXT "", 0x25, 60, 105, 230, 10, 0
+ LTEXT "", 0x26, 60, 115, 100, 10, 0
+ LTEXT "", 0x27, 60, 125, 100, 10, 0
+END
+
IDD_DLOGABOUT DIALOG 50, 50, 200, 220
STYLE 128 | 0x80000000
CAPTION " About MuPDF "
diff --git a/cbz/mucbz.c b/cbz/mucbz.c
index 1ab05799..e8e8faa3 100644
--- a/cbz/mucbz.c
+++ b/cbz/mucbz.c
@@ -490,6 +490,22 @@ static void cbz_free_page_shim(fz_document *doc, fz_page *page)
cbz_free_page((cbz_document*)doc, (cbz_page*)page);
}
+static int cbz_meta(fz_document *doc_, int key, void *ptr, int size)
+{
+ cbz_document *doc = (cbz_document *)doc_;
+
+ doc = doc;
+
+ switch(key)
+ {
+ case FZ_META_FORMAT_INFO:
+ sprintf((char *)ptr, "CBZ");
+ return FZ_META_OK;
+ default:
+ return FZ_META_UNKNOWN_KEY;
+ }
+}
+
static void
cbz_init_document(cbz_document *doc)
{
@@ -503,4 +519,5 @@ cbz_init_document(cbz_document *doc)
doc->super.bound_page = cbz_bound_page_shim;
doc->super.run_page = cbz_run_page_shim;
doc->super.free_page = cbz_free_page_shim;
+ doc->super.meta = cbz_meta;
}
diff --git a/fitz/doc_document.c b/fitz/doc_document.c
index 2da7a110..095a7fb5 100644
--- a/fitz/doc_document.c
+++ b/fitz/doc_document.c
@@ -113,3 +113,11 @@ fz_free_page(fz_document *doc, fz_page *page)
if (doc && doc->free_page && page)
doc->free_page(doc, page);
}
+
+int
+fz_meta(fz_document *doc, int key, void *ptr, int size)
+{
+ if (doc && doc->meta)
+ return doc->meta(doc, key, ptr, size);
+ return FZ_META_UNKNOWN_KEY;
+}
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index b47d984a..bd19886c 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -1079,6 +1079,7 @@ struct fz_document_s
fz_rect (*bound_page)(fz_document *doc, fz_page *page);
void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
void (*free_page)(fz_document *doc, fz_page *page);
+ int (*meta)(fz_document *doc, int key, void *ptr, int size);
};
#endif
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 1355c740..472b5ac9 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -2154,4 +2154,74 @@ void fz_run_page(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix tran
*/
void fz_free_page(fz_document *doc, fz_page *page);
+/*
+ fz_meta: Perform a meta operation on a document.
+
+ Meta operations provide a way to perform format specific
+ operations on a document. The meta operation scheme is
+ designed to be extensible so that new features can be
+ transparently added in later versions of the library.
+
+ doc: The document on which to perform the meta operation.
+
+ key: The meta operation to try. If a particular operation
+ is unsupported on a given document, the function will return
+ FZ_META_UNKNOWN_KEY.
+
+ ptr: An operation dependent (possibly NULL) pointer.
+
+ size: An operation dependent integer. Often this will
+ be the size of the block pointed to by ptr, but not always.
+
+ Returns an operation dependent value; FZ_META_UNKNOWN_KEY
+ always means "unknown operation for this document". In general
+ FZ_META_OK should be used to indicate successful operation.
+*/
+int fz_meta(fz_document *doc, int key, void *ptr, int size);
+
+enum
+{
+ FZ_META_UNKNOWN_KEY = -1,
+ FZ_META_OK = 0,
+
+ /*
+ ptr: Pointer to block (uninitialised on entry)
+ size: Size of block (at least 64 bytes)
+ Returns: Document format as a brief text string.
+ All formats should support this.
+ */
+ FZ_META_FORMAT_INFO = 1,
+
+ /*
+ ptr: Pointer to block (uninitialised on entry)
+ size: Size of block (at least 64 bytes)
+ Returns: Encryption info as a brief text string.
+ */
+ FZ_META_CRYPT_INFO = 2,
+
+ /*
+ ptr: NULL
+ size: Which permission to check
+ Returns: 1 if permitted, 0 otherwise.
+ */
+ FZ_META_HAS_PERMISSION = 3,
+
+ FZ_PERMISSION_PRINT = 0,
+ FZ_PERMISSION_CHANGE = 1,
+ FZ_PERMISSION_COPY = 2,
+ FZ_PERMISSION_NOTES = 3,
+
+ /*
+ ptr: Pointer to block. First entry in the block is
+ a pointer to a UCS string to lookup. The rest of the
+ block is uninitialised on entry.
+ size: size of the block in bytes.
+ Returns: 0 if not found. 1 if found. The string
+ result is copied into the block (truncated to size
+ and NULL terminated)
+
+ */
+ FZ_META_INFO = 4,
+};
+
#endif
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c
index ffdc435e..11cf4bf0 100644
--- a/pdf/pdf_xref.c
+++ b/pdf/pdf_xref.c
@@ -1182,6 +1182,81 @@ static void pdf_free_page_shim(fz_document *doc, fz_page *page)
pdf_free_page((pdf_document*)doc, (pdf_page*)page);
}
+static int pdf_meta(fz_document *doc_, int key, void *ptr, int size)
+{
+ pdf_document *doc = (pdf_document *)doc_;
+
+ switch(key)
+ {
+ /*
+ ptr: Pointer to block (uninitialised on entry)
+ size: Size of block (at least 64 bytes)
+ Returns: Document format as a brief text string.
+ */
+ case FZ_META_FORMAT_INFO:
+ sprintf((char *)ptr, "PDF %d.%d", doc->version/10, doc->version % 10);
+ return FZ_META_OK;
+ case FZ_META_CRYPT_INFO:
+ if (doc->crypt)
+ sprintf((char *)ptr, "Standard V%d %d-bit %s",
+ pdf_crypt_revision(doc),
+ pdf_crypt_length(doc),
+ pdf_crypt_method(doc));
+ else
+ sprintf((char *)ptr, "None");
+ return FZ_META_OK;
+ case FZ_META_HAS_PERMISSION:
+ {
+ int i;
+ switch (size)
+ {
+ case FZ_PERMISSION_PRINT:
+ i = PDF_PERM_PRINT;
+ break;
+ case FZ_PERMISSION_CHANGE:
+ i = PDF_PERM_CHANGE;
+ break;
+ case FZ_PERMISSION_COPY:
+ i = PDF_PERM_COPY;
+ break;
+ case FZ_PERMISSION_NOTES:
+ i = PDF_PERM_NOTES;
+ break;
+ default:
+ return 0;
+ }
+ return pdf_has_permission(doc, size);
+ }
+ case FZ_META_INFO:
+ {
+ pdf_obj *info = pdf_dict_gets(doc->trailer, "Info");
+ if (!info)
+ {
+ if (ptr)
+ *(char *)ptr = 0;
+ return 0;
+ }
+ info = pdf_dict_gets(info, *(char **)ptr);
+ if (!info)
+ {
+ if (ptr)
+ *(char *)ptr = 0;
+ return 0;
+ }
+ if (info && ptr && size)
+ {
+ char *utf8 = pdf_to_utf8(doc->ctx, info);
+ strncpy(ptr, utf8, size);
+ ((char *)ptr)[size-1] = 0;
+ fz_free(doc->ctx, utf8);
+ }
+ return 1;
+ }
+ default:
+ return FZ_META_UNKNOWN_KEY;
+ }
+}
+
static void
pdf_init_document(pdf_document *doc)
{
@@ -1195,4 +1270,5 @@ pdf_init_document(pdf_document *doc)
doc->super.bound_page = pdf_bound_page_shim;
doc->super.run_page = pdf_run_page_shim;
doc->super.free_page = pdf_free_page_shim;
+ doc->super.meta = pdf_meta;
}
diff --git a/xps/xps_zip.c b/xps/xps_zip.c
index 02c302c5..ff43abf2 100644
--- a/xps/xps_zip.c
+++ b/xps/xps_zip.c
@@ -720,6 +720,22 @@ static void xps_free_page_shim(fz_document *doc, fz_page *page)
xps_free_page((xps_document*)doc, (xps_page*)page);
}
+static int xps_meta(fz_document *doc_, int key, void *ptr, int size)
+{
+ xps_document *doc = (xps_document *)doc_;
+
+ doc = doc;
+
+ switch(key)
+ {
+ case FZ_META_FORMAT_INFO:
+ sprintf((char *)ptr, "XPS");
+ return FZ_META_OK;
+ default:
+ return FZ_META_UNKNOWN_KEY;
+ }
+}
+
static void
xps_init_document(xps_document *doc)
{
@@ -733,4 +749,5 @@ xps_init_document(xps_document *doc)
doc->super.bound_page = xps_bound_page_shim;
doc->super.run_page = xps_run_page_shim;
doc->super.free_page = xps_free_page_shim;
+ doc->super.meta = xps_meta;
}