summaryrefslogtreecommitdiff
path: root/apps/w32pdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/w32pdf.c')
-rw-r--r--apps/w32pdf.c231
1 files changed, 199 insertions, 32 deletions
diff --git a/apps/w32pdf.c b/apps/w32pdf.c
index 33fb589c..69f8a483 100644
--- a/apps/w32pdf.c
+++ b/apps/w32pdf.c
@@ -3,13 +3,14 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <commdlg.h>
-static HWND hwnd;
+static HWND hwnd = NULL;
static HDC hdc;
static BITMAPINFO *dibinf;
static TCHAR szAppName[] = TEXT("mupdf");
static HCURSOR arrowcurs, handcurs, waitcurs;
-static LRESULT CALLBACK winproc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT CALLBACK windproc(HWND, UINT, WPARAM, LPARAM);
static char *doctitle = "<untitled>";
static float zoom = 1.0;
@@ -17,6 +18,9 @@ static int rotate = 0;
static int pageno = 1;
static int count = 0;
+static char *password = "";
+static char *filename = "";
+
static pdf_page *page = nil;
static fz_obj *pageobj = nil;
@@ -33,16 +37,123 @@ static pdf_outline *outline;
static fz_renderer *rast;
static fz_pixmap *image;
+#define fz_abort(eo) winabort(eo->msg)
+
+int getfilename(char *buf, int len)
+{
+ OPENFILENAME ofn;
+ strcpy(buf, "");
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwnd;
+ ofn.lpstrFile = buf;
+ ofn.nMaxFile = len;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = "MuPDF: Open PDF file";
+ ofn.lpstrFilter = "PDF Files (*.pdf)\0*.pdf\0All Files\0*\0\0";
+ ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
+ return GetOpenFileName(&ofn);
+}
+
+static char pd_filename[256] = "The file is encrypted.";
+static char pd_password[256] = "";
+static int pd_okay = 0;
+
+INT CALLBACK
+dlogproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwnd, 4, pd_filename);
+ return TRUE;
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case 1:
+ pd_okay = 1;
+ GetDlgItemText(hwnd, 3, pd_password, sizeof pd_password);
+ EndDialog(hwnd, 0);
+ return TRUE;
+ case 2:
+ pd_okay = 0;
+ EndDialog(hwnd, 0);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+char *getpassword(void)
+{
+ char buf[124], *s;
+ strcpy(buf, filename);
+ s = buf;
+ if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1;
+ if (strrchr(s, '/')) s = strrchr(s, '/') + 1;
+ if (strlen(s) > 32)
+ strcpy(s + 30, "...");
+ sprintf(pd_filename, "The file \"%s\" is encrypted.", s);
+ DialogBox(NULL, "IDD_DLOGPASS", hwnd, dlogproc);
+ if (pd_okay)
+ return pd_password;
+ return NULL;
+}
+
+void help()
+{
+ char *msg = \
+ "w32pdf [-b] [-pzr page/zoom/rotate] [-u password] file.pdf\n\n"
+ "key commands:\n"
+ " h\tdisplay this help\n"
+ " <\trotate left\n"
+ " >\trotate right\n"
+ " +\tzoom in\n"
+ " -\tzoom out\n"
+ " b\tgo back one page\n"
+ " B\tgo back ten pages\n"
+ " f\tgo forward one page\n"
+ " F\tgo forward ten pages\n"
+ " G\tgo to last page\n"
+ " m\tmark page for pop-back\n"
+ " t\tpop back to last mark\n"
+ " 123g\tgo to page 123\n"
+ "\nMuPDF is Copyright (C) 2005 artofcode\n"
+ ;
+ MessageBoxA(hwnd, msg, "MuPDF: Usage", MB_ICONINFORMATION);
+}
+
void usage()
{
- fprintf(stderr, "usage: w32pdf [-b] [-pzr page/zoom/rotate] [-u password] file.pdf\n");
+ help();
+ exit(1);
+}
+
+void winwarn(const char *fmt, ...)
+{
+ char buf[1024];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+ MessageBoxA(hwnd, buf, "MuPDF: Warning", MB_ICONWARNING);
+}
+
+void winerror(const char *fmt, ...)
+{
+ char buf[1024];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+ MessageBoxA(hwnd, buf, "MuPDF: Error", MB_ICONERROR);
exit(1);
}
void winabort(const char *msg)
{
- MessageBoxA(NULL, msg, "Fatal error", MB_ICONERROR);
- abort();
+ winerror("There was a problem with file \"%s\":\n\n%s\n", filename, msg);
}
void winopen()
@@ -51,11 +162,11 @@ void winopen()
/* Create and register window class */
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wc.lpfnWndProc = winproc;
+ wc.lpfnWndProc = windproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
- wc.hInstance = 0; //hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(wc.hInstance, "IDI_ICONGHOST");
wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;//(HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
@@ -220,7 +331,7 @@ Lskipload:
winrepaint();
}
-static void pdfopen(char *filename, char *password)
+static void pdfopen(void)
{
fz_error *error;
fz_obj *obj;
@@ -232,8 +343,13 @@ static void pdfopen(char *filename, char *password)
error = pdf_loadxref(xref, filename);
if (error)
{
- fz_warn(error->msg);
- printf("trying to repair...\n");
+ if (!strncmp(error->msg, "ioerror", 7))
+ fz_abort(error);
+ winwarn(
+ "There was a problem with file \"%s\".\n"
+ "It may be corrupted, or generated by broken software.\n\n"
+ "%s\n\nTrying to continue anyway...",
+ filename, error->msg);
error = pdf_repairxref(xref, filename);
if (error)
fz_abort(error);
@@ -246,7 +362,16 @@ static void pdfopen(char *filename, char *password)
if (xref->crypt)
{
error = pdf_setpassword(xref->crypt, password);
- if (error) fz_abort(error);
+ while (error)
+ {
+ fz_droperror(error);
+ password = getpassword();
+ if (!password)
+ exit(1);
+ error = pdf_setpassword(xref->crypt, password);
+ if (error)
+ winwarn("Invalid password.");
+ }
}
obj = fz_dictgets(xref->trailer, "Root");
@@ -269,6 +394,8 @@ static void pdfopen(char *filename, char *password)
if (error) fz_abort(error);
doctitle = filename;
+ if (strrchr(doctitle, '\\')) doctitle = strrchr(doctitle, '\\') + 1;
+ if (strrchr(doctitle, '/')) doctitle = strrchr(doctitle, '/') + 1;
if (xref->info)
{
obj = fz_dictgets(xref->info, "Title");
@@ -293,15 +420,25 @@ static void pdfopen(char *filename, char *password)
image = nil;
}
+static void dumptext()
+{
+ fz_error *error;
+ pdf_textline *line;
+
+ error = pdf_loadtextfromtree(&line, page->tree);
+ if (error)
+ fz_abort(error);
+
+ pdf_debugtextline(line);
+
+ pdf_droptextline(line);
+}
+
static void gotouri(fz_obj *uri)
{
char cmd[2048];
char buf[2048];
- printf("goto uri: ");
- fz_debugobj(uri);
- printf("\n");
-
memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri));
buf[fz_tostrlen(uri)] = 0;
@@ -315,11 +452,8 @@ static void gotouri(fz_obj *uri)
static void gotopage(fz_obj *obj)
{
int oid = fz_tonum(obj);
- int gen = fz_togen(obj);
int i;
- printf("goto page: %d %d R\n", oid, gen);
-
for (i = 0; i < count; i++)
{
if (fz_tonum(pages->pref[i]) == oid)
@@ -351,12 +485,20 @@ static void handlekey(int c)
switch (c)
{
+ case VK_F1:
+ case 'h':
+ help();
+ break;
+
case 'd': fz_debugglyphcache(rast->cache); break;
case 'a': rotate -= 5; break;
case 's': rotate += 5; break;
// case 'x': dumptext(); break;
// case 'o': drawlinks(); break;
+ case VK_LEFT:
+ case VK_UP:
+ case VK_PRIOR:
case '\b':
case 'b':
pageno--;
@@ -368,6 +510,9 @@ static void handlekey(int c)
if (pageno < 1)
pageno = 1;
break;
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_NEXT:
case ' ':
case 'f':
pageno++;
@@ -408,6 +553,7 @@ static void handlekey(int c)
case '>':
rotate += 90;
break;
+ case VK_ESCAPE:
case 'q':
exit(0);
case 'g':
@@ -478,11 +624,10 @@ static void handlemouse(int x, int y, int btn)
}
LRESULT CALLBACK
-winproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+windproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int x = (signed short) LOWORD(lParam);
int y = (signed short) HIWORD(lParam);
- int key;
switch (message)
{
@@ -583,13 +728,26 @@ winproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_KEYDOWN:
//printf("WM_KEYDOWN: %d '%c'\n", wParam, wParam);
- return 0;
+ /* only handle special keys */
+ switch (wParam)
+ {
+ case VK_F1:
+ case VK_LEFT:
+ case VK_UP:
+ case VK_PRIOR:
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_NEXT:
+ case VK_ESCAPE:
+ handlekey(wParam);
+ return 0;
+ }
+ return 1;
/* unicode encoded chars, including escape, backspace etc... */
case WM_CHAR:
//printf("WM_CHAR: %d '%c'\n", wParam, wParam);
- key = wParam;
- handlekey(key);
+ handlekey(wParam);
return 0;
}
@@ -601,13 +759,12 @@ winproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
int main(int argc, char **argv)
{
- char *filename;
+ char buf[1024];
int c;
int benchmark = 0;
- char *password = "";
- while ((c = getopt(argc, argv, "bz:r:p:u:")) != -1)
+ while ((c = getopt(argc, argv, "hbz:r:p:u:")) != -1)
{
switch (c)
{
@@ -616,20 +773,30 @@ int main(int argc, char **argv)
case 'p': pageno = atoi(optarg); break;
case 'z': zoom = atof(optarg); break;
case 'r': rotate = atoi(optarg); break;
- default: usage();
+ case 'h': help(); break;
+ default: help(); exit(1); break;
}
}
+ winopen();
+
if (argc - optind == 0)
- usage();
+ {
+ if (!getfilename(buf, sizeof buf))
+ {
+ help();
+ exit(0);
+ }
+ filename = buf;
+ }
+ else
+ filename = argv[optind++];
fz_cpudetect();
fz_accelerate();
- filename = argv[optind++];
+ pdfopen();
- winopen();
- pdfopen(filename, password);
showpage();
if (benchmark)