diff options
-rw-r--r-- | apps/win_main.c | 84 | ||||
-rw-r--r-- | apps/win_res.rc | 36 | ||||
-rw-r--r-- | cbz/mucbz.c | 17 | ||||
-rw-r--r-- | fitz/doc_document.c | 8 | ||||
-rw-r--r-- | fitz/fitz-internal.h | 1 | ||||
-rw-r--r-- | fitz/fitz.h | 70 | ||||
-rw-r--r-- | pdf/pdf_xref.c | 76 | ||||
-rw-r--r-- | xps/xps_zip.c | 17 |
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; } |