From 2a393c134fe3fe8eb85bf818cb7ad6ae4396322a Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Wed, 18 Sep 2002 22:20:42 +0000 Subject: Synched with Xpdf 1.01 --- (limited to 'pdf/xpdf/xpdf.cc') diff --git a/pdf/xpdf/xpdf.cc b/pdf/xpdf/xpdf.cc index 90a16f9..ff54550 100644 --- a/pdf/xpdf/xpdf.cc +++ b/pdf/xpdf/xpdf.cc @@ -2,10 +2,11 @@ // // xpdf.cc // -// Copyright 1996 Derek B. Noonburg +// Copyright 1996-2002 Glyph & Cog, LLC // //======================================================================== +#include #include #include #include @@ -19,6 +20,7 @@ #include "parseargs.h" #include "gfile.h" #include "gmem.h" +#include "GlobalParams.h" #include "LTKAll.h" #include "Object.h" #include "Stream.h" @@ -33,7 +35,6 @@ #include "LTKOutputDev.h" #include "PSOutputDev.h" #include "TextOutputDev.h" -#include "Params.h" #include "Error.h" #include "config.h" @@ -96,14 +97,14 @@ typedef char *XPointer; // misc constants / enums //------------------------------------------------------------------------ -#define remoteCmdLength 256 +#define remoteCmdLength 512 enum XpdfMenuItem { menuOpen, menuReload, menuSavePDF, - menuRotateLeft, - menuRotateRight, + menuRotateCCW, + menuRotateCW, menuQuit }; @@ -113,7 +114,9 @@ enum XpdfMenuItem { // loadFile / displayPage static GBool loadFile(GString *fileName); -static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist); +static void displayPage(int page1, int zoomA, int rotateA, GBool addToHist); +static void displayDest(LinkDest *dest, int zoomA, int rotateA, + GBool addToHist); // key press and menu callbacks static void keyPressCbk(LTKWindow *win1, KeySym key, Guint modifiers, @@ -177,6 +180,9 @@ static void psButtonCbk(LTKWidget *button, int n, GBool on); // "About" window static void mapAboutWin(); static void closeAboutCbk(LTKWidget *button, int n, GBool on); +static void aboutLayoutCbk(LTKWindow *winA); +static void aboutScrollVertCbk(LTKWidget *scrollbar, int n, int val); +static void aboutScrollHorizCbk(LTKWidget *scrollbar, int n, int val); // "Find" window static void findCbk(LTKWidget *button, int n, GBool on); @@ -188,104 +194,172 @@ static void doFind(char *s); static void killCbk(LTKWindow *win1); //------------------------------------------------------------------------ -// command line options +// "About" window text //------------------------------------------------------------------------ -static XrmOptionDescRec opts[] = { - {"-display", ".display", XrmoptionSepArg, NULL}, - {"-foreground", ".foreground", XrmoptionSepArg, NULL}, - {"-fg", ".foreground", XrmoptionSepArg, NULL}, - {"-background", ".background", XrmoptionSepArg, NULL}, - {"-bg", ".background", XrmoptionSepArg, NULL}, - {"-geometry", ".geometry", XrmoptionSepArg, NULL}, - {"-g", ".geometry", XrmoptionSepArg, NULL}, - {"-font", ".font", XrmoptionSepArg, NULL}, - {"-fn", ".font", XrmoptionSepArg, NULL}, - {"-title", ".title", XrmoptionSepArg, NULL}, - {"-cmap", ".installCmap", XrmoptionNoArg, (XPointer)"on"}, - {"-rgb", ".rgbCubeSize", XrmoptionSepArg, NULL}, - {"-papercolor", ".paperColor", XrmoptionSepArg, NULL}, -#if JAPANESE_SUPPORT - {"-eucjp", ".eucjp", XrmoptionNoArg, (XPointer)"off"}, -#endif -#if HAVE_T1LIB_H - {"-t1lib", ".t1libControl", XrmoptionSepArg, NULL}, -#endif -#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H - {"-freetype", ".freeTypeControl", XrmoptionSepArg, NULL}, -#endif - {"-z", ".initialZoom", XrmoptionSepArg, NULL}, - {"-ps", ".psFile", XrmoptionSepArg, NULL}, - {"-paperw", ".psPaperWidth", XrmoptionSepArg, NULL}, - {"-paperh", ".psPaperHeight", XrmoptionSepArg, NULL}, - {"-level1", ".psLevel1", XrmoptionNoArg, (XPointer)"false"}, - {NULL} +static char *aboutWinText[] = { + "X X d fff", + " X X d f f", + " X X d f", + " X pppp dddd ffff", + " X X p p d d f", + " X X p p d d f", + "X X pppp dddd f Version " xpdfVersion, + " p", + " p", + " p", + "", + xpdfCopyright, + "", + "http://www.foolabs.com/xpdf/", + "derekn@foolabs.com", + "", + "Licensed under the GNU General Public License (GPL).", + "See the 'COPYING' file for details.", + "", + "Supports PDF version " supportedPDFVersionStr ".", + "", + "The PDF data structures, operators, and specification", + "are copyright 1985-2001 Adobe Systems Inc.", + "", + "Mouse bindings:", + " button 1: select text / follow link", + " button 2: pan window", + " button 3: menu", + "", + "Key bindings:", + " o = open file", + " r = reload", + " f = find text", + " n = = next page", + " p = = previous page", + " = scroll down", + " = = scroll up", + " v = forward (history path)", + " b = backward (history path)", + " 0 / + / - = zoom zero / in / out", + " z / w = zoom page / page width", + " ctrl-L = redraw", + " q = quit", + " / = top / bottom of page", + " = scroll", + "", + "For more information, please read the xpdf(1) man page.", + NULL }; -static GBool printVersion = gFalse; -static GBool printHelp = gFalse; +//------------------------------------------------------------------------ +// command line options +//------------------------------------------------------------------------ + +static char initialZoomStr[32] = ""; +static char t1libControlStr[16] = ""; +static char freetypeControlStr[16] = ""; +static char psFileArg[256]; +static char paperSize[15] = ""; +static int paperWidth = 0; +static int paperHeight = 0; +static GBool level1 = gFalse; +static char textEncName[128] = ""; +static char textEOL[16] = ""; +static char ownerPassword[33] = ""; +static char userPassword[33] = ""; +static GBool fullScreen = gFalse; static char remoteName[100] = "xpdf_"; static GBool doRemoteRaise = gFalse; static GBool doRemoteQuit = gFalse; +static GBool printCommands = gFalse; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; static GBool viKeys = gFalse; -static char userPassword[33] = ""; -static GBool fullScreen = gFalse; static ArgDesc argDesc[] = { - {"-z", argStringDummy, NULL, 0, - "initial zoom level (-5..5, page, width)"}, {"-g", argStringDummy, NULL, 0, "initial window geometry"}, {"-geometry", argStringDummy, NULL, 0, "initial window geometry"}, {"-title", argStringDummy, NULL, 0, "window title"}, - {"-remote", argString, remoteName + 5, sizeof(remoteName) - 5, - "start/contact xpdf remote server with specified name"}, - {"-raise", argFlag, &doRemoteRaise, 0, - "raise xpdf remote server window (with -remote only)"}, - {"-quit", argFlag, &doRemoteQuit, 0, - "kill xpdf remote server (with -remote only)"}, {"-cmap", argFlagDummy, NULL, 0, "install a private colormap"}, {"-rgb", argIntDummy, NULL, 0, "biggest RGB cube to allocate (default is 5)"}, + {"-rv", argFlagDummy, NULL, 0, + "reverse video"}, {"-papercolor", argStringDummy, NULL, 0, "color of paper background"}, -#if JAPANESE_SUPPORT - {"-eucjp", argStringDummy, NULL, 0, - "convert Japanese text to EUC-JP"}, -#endif + {"-z", argString, initialZoomStr, sizeof(initialZoomStr), + "initial zoom level (-5..5, page, width)"}, #if HAVE_T1LIB_H - {"-t1lib", argStringDummy, NULL, 0, - "t1lib font control: none, plain, low, high"}, + {"-t1lib", argString, t1libControlStr, sizeof(t1libControlStr), + "t1lib font rasterizer control: none, plain, low, high"}, #endif #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H - {"-freetype", argStringDummy, NULL, 0, - "FreeType font control: none, plain, aa"}, + {"-freetype", argString, freetypeControlStr, sizeof(freetypeControlStr), + "FreeType font rasterizer control: none, plain, low, high"}, #endif - {"-ps", argStringDummy, NULL, 0, - "default PostScript file/command name"}, - {"-paperw", argIntDummy, NULL, 0, + {"-ps", argString, psFileArg, sizeof(psFileArg), + "default PostScript file name or command"}, + {"-paper", argString, paperSize, sizeof(paperSize), + "paper size (letter, legal, A4, A3)"}, + {"-paperw", argInt, &paperWidth, 0, "paper width, in points"}, - {"-paperh", argIntDummy, NULL, 0, + {"-paperh", argInt, &paperHeight, 0, "paper height, in points"}, - {"-level1", argFlagDummy, NULL, 0, + {"-level1", argFlag, &level1, 0, "generate Level 1 PostScript"}, + {"-enc", argString, textEncName, sizeof(textEncName), + "output text encoding name"}, + {"-eol", argString, textEOL, sizeof(textEOL), + "output end-of-line convention (unix, dos, or mac)"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, {"-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)"}, {"-fullscreen", argFlag, &fullScreen, 0, "run in full-screen (presentation) mode"}, + {"-remote", argString, remoteName + 5, sizeof(remoteName) - 5, + "start/contact xpdf remote server with specified name"}, + {"-raise", argFlag, &doRemoteRaise, 0, + "raise xpdf remote server window (with -remote only)"}, + {"-quit", argFlag, &doRemoteQuit, 0, + "kill xpdf remote server (with -remote only)"}, {"-cmd", argFlag, &printCommands, 0, "print commands as they're executed"}, - {"-q", argFlag, &errQuiet, 0, + {"-q", argFlag, &quiet, 0, "don't print any messages or errors"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, {"-v", argFlag, &printVersion, 0, "print copyright and version info"}, {"-h", argFlag, &printHelp, 0, "print usage information"}, {"-help", argFlag, &printHelp, 0, "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +static XrmOptionDescRec opts[] = { + {"-display", ".display", XrmoptionSepArg, NULL}, + {"-foreground", ".foreground", XrmoptionSepArg, NULL}, + {"-fg", ".foreground", XrmoptionSepArg, NULL}, + {"-background", ".background", XrmoptionSepArg, NULL}, + {"-bg", ".background", XrmoptionSepArg, NULL}, + {"-geometry", ".geometry", XrmoptionSepArg, NULL}, + {"-g", ".geometry", XrmoptionSepArg, NULL}, + {"-font", ".font", XrmoptionSepArg, NULL}, + {"-fn", ".font", XrmoptionSepArg, NULL}, + {"-title", ".title", XrmoptionSepArg, NULL}, + {"-cmap", ".installCmap", XrmoptionNoArg, (XPointer)"on"}, + {"-rgb", ".rgbCubeSize", XrmoptionSepArg, NULL}, + {"-rv", ".reverseVideo", XrmoptionNoArg, (XPointer)"true"}, + {"-papercolor", ".paperColor", XrmoptionSepArg, NULL}, {NULL} }; @@ -298,13 +372,12 @@ static ArgDesc argDesc[] = { #define maxZoom 5 #define zoomPage 100 #define zoomWidth 101 +#define defZoom 1 static int zoomDPI[maxZoom - minZoom + 1] = { 29, 35, 42, 50, 60, 72, 86, 104, 124, 149, 179 }; -#define defZoom 1 -#define defZoomStr "1" static PDFDoc *doc; @@ -338,7 +411,6 @@ static int historyBLen; // number of valid entries backward from static int historyFLen; // number of valid entries forward from // current entry -static GString *defPSFileName; static GString *psFileName; static int psFirstPage, psLastPage; @@ -359,10 +431,13 @@ static LTKLabel *numPagesLabel; static LTKLabel *linkLabel; static LTKMenuButton *zoomMenuBtn; static LTKWindow *aboutWin; +static LTKList *aboutList; +static LTKScrollbar *aboutHScrollbar, *aboutVScrollbar; static LTKWindow *psDialog; static LTKWindow *openDialog; static LTKWindow *saveDialog; static LTKWindow *findWin; +static LTKTextIn *findTextIn; static Atom remoteAtom; static GC selectGC; @@ -393,12 +468,17 @@ int main(int argc, char *argv[]) { LTKMenu *menu; GString *name; GString *title; + GString *initialZoom; + GBool reverseVideo; unsigned long paperColor; + GBool installCmap; + int rgbCubeSize; int pg; + GString *destName; + LinkDest *dest; int x, y; Guint width, height; double width1, height1; - GString *zoomStr; GBool ok; char s[20]; int i; @@ -410,23 +490,60 @@ int main(int argc, char *argv[]) { out = NULL; remoteAtom = None; doc = NULL; - xref = NULL; psFileName = NULL; fileReqDir = getCurrentDir(); ret = 0; // parse args - paperWidth = paperHeight = -1; ok = parseArgs(argDesc, &argc, argv); - // init error file - errorInit(); - // read config file - initParams(xpdfConfigFile); + globalParams = new GlobalParams(cfgFileName); + if (psFileArg[0]) { + globalParams->setPSFile(psFileArg); + } + if (paperSize[0]) { + if (!globalParams->setPSPaperSize(paperSize)) { + fprintf(stderr, "Invalid paper size\n"); + } + } else { + if (paperWidth) { + globalParams->setPSPaperWidth(paperWidth); + } + if (paperHeight) { + globalParams->setPSPaperHeight(paperHeight); + } + } + if (level1) { + globalParams->setPSLevel(psLevel1); + } + if (textEncName[0]) { + globalParams->setTextEncoding(textEncName); + } + if (textEOL[0]) { + if (!globalParams->setTextEOL(textEOL)) { + fprintf(stderr, "Bad '-eol' value on command line\n"); + } + } + if (initialZoomStr[0]) { + globalParams->setInitialZoom(initialZoomStr); + } + if (t1libControlStr[0]) { + if (!globalParams->setT1libControl(t1libControlStr)) { + fprintf(stderr, "Bad '-t1lib' value on command line\n"); + } + } + if (freetypeControlStr[0]) { + if (!globalParams->setFreeTypeControl(freetypeControlStr)) { + fprintf(stderr, "Bad '-freetype' value on command line\n"); + } + } + if (quiet) { + globalParams->setErrQuiet(quiet); + } // create LTKApp (and parse X-related args) - app = new LTKApp("xpdf", opts, &argc, argv); + app = new LTKApp("xpdf", "Xpdf", opts, &argc, argv); app->setKillCbk(&killCbk); display = app->getDisplay(); @@ -441,19 +558,25 @@ int main(int argc, char *argv[]) { fprintf(stderr, "xpdf version %s\n", xpdfVersion); fprintf(stderr, "%s\n", xpdfCopyright); if (!printVersion) { - printUsage("xpdf", "[ []]", argDesc); + printUsage("xpdf", "[ [ | +]]", argDesc); } ret = 1; goto done2; } - if (argc >= 2) + if (argc >= 2) { name = new GString(argv[1]); - else + } else { name = NULL; - if (argc == 3) - pg = atoi(argv[2]); - else - pg = 1; + } + pg = 1; + destName = NULL; + if (argc == 3) { + if (argv[2][0] == '+') { + destName = new GString(&argv[2][1]); + } else { + pg = atoi(argv[2]); + } + } // look for already-running remote server if (remoteName[5]) { @@ -461,8 +584,14 @@ int main(int argc, char *argv[]) { xwin = XGetSelectionOwner(display, remoteAtom); if (xwin != None) { if (name) { - sprintf(cmd, "%c %d %.200s", doRemoteRaise ? 'D' : 'd', - pg, name->getCString()); + if (destName) { + sprintf(cmd, "%c +%.256s %.200s", doRemoteRaise ? 'D' : 'd', + destName->getCString(), name->getCString()); + delete destName; + } else { + sprintf(cmd, "%c %d %.200s", doRemoteRaise ? 'D' : 'd', + pg, name->getCString()); + } XChangeProperty(display, xwin, remoteAtom, remoteAtom, 8, PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1); delete name; @@ -475,8 +604,12 @@ int main(int argc, char *argv[]) { } goto done2; } - if (doRemoteQuit) + if (doRemoteQuit) { + if (destName) { + delete destName; + } goto done2; + } } // no history yet @@ -486,7 +619,6 @@ int main(int argc, char *argv[]) { history[i].fileName = NULL; // open PDF file - defPSFileName = app->getStringResource("psFile", NULL); if (name) { if (!loadFile(name)) { ret = 1; @@ -497,8 +629,9 @@ int main(int argc, char *argv[]) { } // check for legal page number - if (doc && (pg < 1 || pg > doc->getNumPages())) + if (doc && (pg < 1 || pg > doc->getNumPages())) { pg = 1; + } // create window menu = makeMenu(); @@ -529,73 +662,42 @@ int main(int argc, char *argv[]) { vScrollbar->setRepeatPeriod(0); } + // get parameters + urlCommand = globalParams->getURLCommand(); + // get X resources - paperWidth = app->getIntResource("psPaperWidth", defPaperWidth); - paperHeight = app->getIntResource("psPaperHeight", defPaperHeight); - psOutLevel1 = app->getBoolResource("psLevel1", gFalse); - urlCommand = app->getStringResource("urlCommand", NULL); windowTitle = app->getStringResource("title", NULL); installCmap = app->getBoolResource("installCmap", gFalse); - if (installCmap) + if (installCmap) { win->setInstallCmap(gTrue); + } rgbCubeSize = app->getIntResource("rgbCubeSize", defaultRGBCube); - paperColor = app->getColorResource("paperColor", "white", - WhitePixel(display, app->getScreenNum()), - NULL); -#if JAPANESE_SUPPORT - useEUCJP = app->getBoolResource("eucjp", gFalse); -#else - useEUCJP = gFalse; -#endif -#if HAVE_T1LIB_H - t1libControl = app->getStringResource("t1libControl", "low"); -#endif -#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H - freeTypeControl = app->getStringResource("freeTypeControl", "aa"); -#endif - t1Courier = app->getStringResource("t1Courier", NULL); - t1CourierBold = app->getStringResource("t1CourierBold", NULL); - t1CourierBoldOblique = app->getStringResource("t1CourierBoldOblique", NULL); - t1CourierOblique = app->getStringResource("t1CourierOblique", NULL); - t1Helvetica = app->getStringResource("t1Helvetica", NULL); - t1HelveticaBold = app->getStringResource("t1HelveticaBold", NULL); - t1HelveticaBoldOblique = - app->getStringResource("t1HelveticaBoldOblique", NULL); - t1HelveticaOblique = app->getStringResource("t1HelveticaOblique", NULL); - t1Symbol = app->getStringResource("t1Symbol", NULL); - t1TimesBold = app->getStringResource("t1TimesBold", NULL); - t1TimesBoldItalic = app->getStringResource("t1TimesBoldItalic", NULL); - t1TimesItalic = app->getStringResource("t1TimesItalic", NULL); - t1TimesRoman = app->getStringResource("t1TimesRoman", NULL); - t1ZapfDingbats = app->getStringResource("t1ZapfDingbats", NULL); -#if JAPANESE_SUPPORT - japan12Font = app->getStringResource("japaneseFont", NULL); -#endif -#if CHINESE_GB_SUPPORT - gb12Font = app->getStringResource("chineseGBFont", NULL); -#endif -#if CHINESE_CNS_SUPPORT - cns13Font = app->getStringResource("chineseCNSFont", NULL); -#endif + reverseVideo = app->getBoolResource("reverseVideo", gFalse); + paperColor = app->getColorResource( + "paperColor", + reverseVideo ? (char *)"black" : (char *)"white", + reverseVideo ? BlackPixel(display, app->getScreenNum()) + : WhitePixel(display, app->getScreenNum()), + NULL); if (fullScreen) { zoom = zoomPage; } else { - zoomStr = app->getStringResource("initialZoom", defZoomStr); - if (!zoomStr->cmp("page")) { + initialZoom = globalParams->getInitialZoom(); + if (!initialZoom->cmp("page")) { zoom = zoomPage; i = maxZoom - minZoom + 2; - } else if (!zoomStr->cmp("width")) { + } else if (!initialZoom->cmp("width")) { zoom = zoomWidth; i = maxZoom - minZoom + 3; } else { - zoom = atoi(zoomStr->getCString()); - if (zoom < minZoom) + zoom = atoi(initialZoom->getCString()); + if (zoom < minZoom) { zoom = minZoom; - else if (zoom > maxZoom) + } else if (zoom > maxZoom) { zoom = maxZoom; + } i = zoom - minZoom; } - delete zoomStr; zoomMenuBtn->setInitialMenuItem(zoomMenu->getItem(i)); } viKeys = app->getBoolResource("viKeys", gFalse); @@ -674,11 +776,25 @@ int main(int argc, char *argv[]) { } // create output device - out = new LTKOutputDev(win, paperColor); - out->startDoc(); + out = new LTKOutputDev(win, reverseVideo, paperColor, + installCmap, rgbCubeSize, !fullScreen); + out->startDoc(doc ? doc->getXRef() : (XRef *)NULL); // display first page - displayPage(pg, zoom, 0, gTrue); + if (destName) { + if (doc) { + if ((dest = doc->findDest(destName))) { + displayDest(dest, zoom, 0, gTrue); + delete dest; + } else { + error(-1, "Unknown named destination '%s'", destName->getCString()); + displayPage(1, zoom, 0, gTrue); + } + } + delete destName; + } else { + displayPage(pg, zoom, 0, gTrue); + } // event loop quit = gFalse; @@ -714,107 +830,34 @@ int main(int argc, char *argv[]) { if (psFileName) { delete psFileName; } - if (defPSFileName) { - delete defPSFileName; - } if (fileReqDir) { delete fileReqDir; } - if (urlCommand) { - delete urlCommand; - } if (windowTitle) { delete windowTitle; } -#if HAVE_T1LIB_H - if (t1libControl) { - delete t1libControl; - } -#endif -#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H - if (freeTypeControl) { - delete freeTypeControl; - } -#endif - if (t1Courier) { - delete t1Courier; - } - if (t1CourierBold) { - delete t1CourierBold; - } - if (t1CourierBoldOblique) { - delete t1CourierBoldOblique; - } - if (t1CourierOblique) { - delete t1CourierOblique; - } - if (t1Helvetica) { - delete t1Helvetica; - } - if (t1HelveticaBold) { - delete t1HelveticaBold; - } - if (t1HelveticaBoldOblique) { - delete t1HelveticaBoldOblique; - } - if (t1HelveticaOblique) { - delete t1HelveticaOblique; - } - if (t1Symbol) { - delete t1Symbol; - } - if (t1TimesBold) { - delete t1TimesBold; - } - if (t1TimesBoldItalic) { - delete t1TimesBoldItalic; - } - if (t1TimesItalic) { - delete t1TimesItalic; - } - if (t1TimesRoman) { - delete t1TimesRoman; - } - if (t1ZapfDingbats) { - delete t1ZapfDingbats; - } -#if JAPANESE_SUPPORT - if (japan12Font) { - delete japan12Font; - } -#endif -#if CHINESE_GB_SUPPORT - if (gb12Font) { - delete gb12Font; - } -#endif -#if CHINESE_CNS_SUPPORT - if (cns13Font) { - delete cns13Font; - } -#endif for (i = 0; i < historySize; ++i) { if (history[i].fileName) { delete history[i].fileName; } } - freeParams(); + delete globalParams; // check for memory leaks - Object::memCheck(errFile ? errFile : stderr); - gMemReport(errFile ? errFile : stderr); + Object::memCheck(stderr); + gMemReport(stderr); return ret; } //------------------------------------------------------------------------ -// loadFile / displayPage +// loadFile / displayPage / displayDest //------------------------------------------------------------------------ static GBool loadFile(GString *fileName) { GString *title; PDFDoc *newDoc; - GString *userPW; + GString *ownerPW, *userPW; char s[20]; char *p; @@ -823,15 +866,23 @@ static GBool loadFile(GString *fileName) { win->setBusyCursor(gTrue); // open PDF file + if (ownerPassword[0]) { + ownerPW = new GString(ownerPassword); + } else { + ownerPW = NULL; + } if (userPassword[0]) { userPW = new GString(userPassword); } else { userPW = NULL; } - newDoc = new PDFDoc(fileName, userPW); + newDoc = new PDFDoc(fileName, ownerPW, userPW, printCommands); if (userPW) { delete userPW; } + if (ownerPW) { + delete ownerPW; + } if (!newDoc->isOk()) { delete newDoc; if (win) @@ -843,8 +894,9 @@ static GBool loadFile(GString *fileName) { if (doc) delete doc; doc = newDoc; - if (out) - out->startDoc(); + if (out) { + out->startDoc(doc->getXRef()); + } // nothing displayed yet page = -99; @@ -855,8 +907,8 @@ static GBool loadFile(GString *fileName) { // init PostScript output params if (psFileName) delete psFileName; - if (defPSFileName) { - psFileName = defPSFileName->copy(); + if (globalParams->getPSFile()) { + psFileName = globalParams->getPSFile()->copy(); } else { p = fileName->getCString() + fileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) @@ -887,7 +939,7 @@ static GBool loadFile(GString *fileName) { return gTrue; } -static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) { +static void displayPage(int pageA, int zoomA, int rotateA, GBool addToHist) { time_t modTime1; double hDPI, vDPI, dpi; int rot; @@ -902,8 +954,8 @@ static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) { modTime1 = getModTime(doc->getFileName()->getCString()); if (modTime1 != modTime) { if (loadFile(doc->getFileName()->copy())) { - if (page1 > doc->getNumPages()) { - page1 = doc->getNumPages(); + if (pageA > doc->getNumPages()) { + pageA = doc->getNumPages(); } } modTime = modTime1; @@ -914,9 +966,9 @@ static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) { win->setBusyCursor(gTrue); // new page/zoom/rotate values - page = page1; - zoom = zoom1; - rotate = rotate1; + page = pageA; + zoom = zoomA; + rotate = rotateA; // initialize mouse-related stuff linkAction = NULL; @@ -945,18 +997,18 @@ static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) { dpi = (hDPI < vDPI) ? hDPI : vDPI; } else if (zoom == zoomPage) { if (rot == 90 || rot == 270) { - hDPI = ((win->getWidth() - 28) / doc->getPageHeight(page)) * 72; - vDPI = ((win->getHeight() - 56) / doc->getPageWidth(page)) * 72; + hDPI = (canvas->getWidth() / doc->getPageHeight(page)) * 72; + vDPI = (canvas->getHeight() / doc->getPageWidth(page)) * 72; } else { - hDPI = ((win->getWidth() - 28) / doc->getPageWidth(page)) * 72; - vDPI = ((win->getHeight() - 56) / doc->getPageHeight(page)) * 72; + hDPI = (canvas->getWidth() / doc->getPageWidth(page)) * 72; + vDPI = (canvas->getHeight() / doc->getPageHeight(page)) * 72; } dpi = (hDPI < vDPI) ? hDPI : vDPI; } else if (zoom == zoomWidth) { if (rot == 90 || rot == 270) { - dpi = ((win->getWidth() - 28) / doc->getPageHeight(page)) * 72; + dpi = (canvas->getWidth() / doc->getPageHeight(page)) * 72; } else { - dpi = ((win->getWidth() - 28) / doc->getPageWidth(page)) * 72; + dpi = (canvas->getWidth() / doc->getPageWidth(page)) * 72; } } else { dpi = zoomDPI[zoom - minZoom]; @@ -988,6 +1040,75 @@ static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) { win->setBusyCursor(gFalse); } +static void displayDest(LinkDest *dest, int zoomA, int rotateA, + GBool addToHist) { + Ref pageRef; + int pg; + int dx, dy; + + if (dest->isPageRef()) { + pageRef = dest->getPageRef(); + pg = doc->findPage(pageRef.num, pageRef.gen); + } else { + pg = dest->getPageNum(); + } + if (pg <= 0 || pg > doc->getNumPages()) { + pg = 1; + } + if (pg != page) { + displayPage(pg, zoomA, rotateA, addToHist); + } + + if (fullScreen) { + return; + } + switch (dest->getKind()) { + case destXYZ: + out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); + if (dest->getChangeLeft() || dest->getChangeTop()) { + if (dest->getChangeLeft()) { + hScrollbar->setPos(dx, canvas->getWidth()); + } + if (dest->getChangeTop()) { + vScrollbar->setPos(dy, canvas->getHeight()); + } + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + } + //~ what is the zoom parameter? + break; + case destFit: + case destFitB: + //~ do fit + hScrollbar->setPos(0, canvas->getWidth()); + vScrollbar->setPos(0, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; + case destFitH: + case destFitBH: + //~ do fit + out->cvtUserToDev(0, dest->getTop(), &dx, &dy); + hScrollbar->setPos(0, canvas->getWidth()); + vScrollbar->setPos(dy, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; + case destFitV: + case destFitBV: + //~ do fit + out->cvtUserToDev(dest->getLeft(), 0, &dx, &dy); + hScrollbar->setPos(dx, canvas->getWidth()); + vScrollbar->setPos(0, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; + case destFitR: + //~ do fit + out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); + hScrollbar->setPos(dx, canvas->getWidth()); + vScrollbar->setPos(dy, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; + } +} + //------------------------------------------------------------------------ // key press and menu callbacks //------------------------------------------------------------------------ @@ -1039,6 +1160,19 @@ static void keyPressCbk(LTKWindow *win1, KeySym key, Guint modifiers, canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); } break; + case 'v': + forwardCbk(NULL, 0, gTrue); + break; + case 'b': + backCbk(NULL, 0, gTrue); + break; + case 'g': + if (fullScreen) { + break; + } + pageNumText->selectAll(); + pageNumText->activate(gTrue); + break; case 'h': // vi-style left if (fullScreen) { break; @@ -1075,6 +1209,42 @@ static void keyPressCbk(LTKWindow *win1, KeySym key, Guint modifiers, canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); } break; + case '0': + if (fullScreen) { + break; + } + if (zoom != defZoom) { + zoomMenuBtn->setMenuItem(zoomMenu->getItem(defZoom - minZoom)); + } + break; + case '+': + if (fullScreen) { + break; + } + if (zoom >= minZoom && zoom < maxZoom) { + zoomMenuBtn->setMenuItem(zoomMenu->getItem(zoom + 1 - minZoom)); + } + break; + case '-': + if (fullScreen) { + break; + } + if (zoom > minZoom && zoom <= maxZoom) { + zoomMenuBtn->setMenuItem(zoomMenu->getItem(zoom - 1 - minZoom)); + } + break; + case 'z': + if (fullScreen) { + break; + } + zoomMenuBtn->setMenuItem(zoomMenu->getItem(maxZoom - minZoom + 2)); + break; + case 'w': + if (fullScreen) { + break; + } + zoomMenuBtn->setMenuItem(zoomMenu->getItem(maxZoom - minZoom + 3)); + break; case '\014': // ^L win->redraw(); displayPage(page, zoom, rotate, gFalse); @@ -1180,13 +1350,13 @@ static void menuCbk(LTKMenuItem *item) { if (doc) mapSaveDialog(); break; - case menuRotateLeft: + case menuRotateCCW: if (doc) { r = (rotate == 0) ? 270 : rotate - 90; displayPage(page, zoom, r, gFalse); } break; - case menuRotateRight: + case menuRotateCW: if (doc) { r = (rotate == 270) ? 0 : rotate + 90; displayPage(page, zoom, r, gFalse); @@ -1204,13 +1374,53 @@ static void menuCbk(LTKMenuItem *item) { static void buttonPressCbk(LTKWidget *canvas1, int n, int mx, int my, int button, GBool dblClick) { - if (!doc || doc->getNumPages() == 0) + if (!doc || doc->getNumPages() == 0) { return; - if (button == 1) { + } + switch (button) { + case 1: setSelection(mx, my, mx, my); - } else if (!fullScreen && button == 2) { - panMX = mx - hScrollbar->getPos(); - panMY = my - vScrollbar->getPos(); + break; + case 2: + if (!fullScreen) { + panMX = mx - hScrollbar->getPos(); + panMY = my - vScrollbar->getPos(); + } + break; + case 4: // mouse wheel up + if (fullScreen) { + gotoPrevPage(1, gTrue, gFalse); + } else if (vScrollbar->getPos() == 0) { + gotoPrevPage(1, gFalse, gTrue); + } else { + vScrollbar->setPos(vScrollbar->getPos() - 16, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + } + break; + case 5: // mouse wheel down + if (fullScreen || + vScrollbar->getPos() >= + canvas->getRealHeight() - canvas->getHeight()) { + gotoNextPage(1, gTrue); + } else { + vScrollbar->setPos(vScrollbar->getPos() + 16, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + } + break; + case 6: // second mouse wheel right + if (fullScreen) { + return; + } + hScrollbar->setPos(hScrollbar->getPos() + 16, canvas->getWidth()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; + case 7: // second mouse wheel left + if (fullScreen) { + return; + } + hScrollbar->setPos(hScrollbar->getPos() - 16, canvas->getWidth()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + break; } } @@ -1249,10 +1459,7 @@ static void doLink(int mx, int my) { char *s; GString *fileName; GString *actionName; - Ref pageRef; - int pg; double x, y; - int dx, dy; LTKButtonDialog *dialog; int i; @@ -1297,68 +1504,13 @@ static void doLink(int mx, int my) { dest = doc->findDest(namedDest); delete namedDest; } - if (!dest) { - if (kind == actionGoToR) - displayPage(1, zoom, 0, gTrue); + if (dest) { + displayDest(dest, zoom, rotate, gTrue); + delete dest; } else { - if (dest->isPageRef()) { - pageRef = dest->getPageRef(); - pg = doc->findPage(pageRef.num, pageRef.gen); - } else { - pg = dest->getPageNum(); - } - if (pg > 0 && pg != page) - displayPage(pg, zoom, rotate, gTrue); - else if (pg <= 0) - displayPage(1, zoom, rotate, gTrue); - if (fullScreen) { - delete dest; - break; - } - switch (dest->getKind()) { - case destXYZ: - out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); - if (dest->getChangeLeft() || dest->getChangeTop()) { - if (dest->getChangeLeft()) - hScrollbar->setPos(dx, canvas->getWidth()); - if (dest->getChangeTop()) - vScrollbar->setPos(dy, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); - } - //~ what is the zoom parameter? - break; - case destFit: - case destFitB: - //~ do fit - hScrollbar->setPos(0, canvas->getWidth()); - vScrollbar->setPos(0, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); - break; - case destFitH: - case destFitBH: - //~ do fit - out->cvtUserToDev(0, dest->getTop(), &dx, &dy); - hScrollbar->setPos(0, canvas->getWidth()); - vScrollbar->setPos(dy, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); - break; - case destFitV: - case destFitBV: - //~ do fit - out->cvtUserToDev(dest->getLeft(), 0, &dx, &dy); - hScrollbar->setPos(dx, canvas->getWidth()); - vScrollbar->setPos(0, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); - break; - case destFitR: - //~ do fit - out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); - hScrollbar->setPos(dx, canvas->getWidth()); - vScrollbar->setPos(dy, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); - break; + if (kind == actionGoToR) { + displayPage(1, zoom, 0, gTrue); } - delete dest; } break; @@ -1443,8 +1595,7 @@ static void doLink(int mx, int my) { system(fileName->getCString()); delete fileName; } else { - fprintf(errFile, "URI: %s\n", - ((LinkURI *)action)->getURI()->getCString()); + printf("URI: %s\n", ((LinkURI *)action)->getURI()->getCString()); } break; @@ -1631,7 +1782,7 @@ static void gotoNextPage(int inc, GBool top) { if (page < doc->getNumPages()) { if (top && !fullScreen) { vScrollbar->setPos(0, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + canvas->setScrollPos(hScrollbar->getPos(), vScrollbar->getPos()); } if ((pg = page + inc) > doc->getNumPages()) { pg = doc->getNumPages(); @@ -1659,7 +1810,7 @@ static void gotoPrevPage(int dec, GBool top, GBool bottom) { if (page > 1) { if (top && !fullScreen) { vScrollbar->setPos(0, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + canvas->setScrollPos(hScrollbar->getPos(), vScrollbar->getPos()); } else if (bottom && !fullScreen) { vScrollbar->setPos(canvas->getRealHeight() - canvas->getHeight(), canvas->getHeight()); @@ -1798,19 +1949,23 @@ static void propChangeCbk(LTKWindow *win1, Atom atom) { Atom type; int format; Gulong size, remain; - char *p; + char *p, *q; GString *newFileName; int newPage; + GString *destName; + LinkDest *dest; // get command xwin = win1->getXWindow(); if (XGetWindowProperty(display, xwin, remoteAtom, 0, remoteCmdLength/4, True, remoteAtom, &type, &format, &size, &remain, - (Guchar **)&cmd) != Success) + (Guchar **)&cmd) != Success) { return; - if (size == 0) + } + if (size == 0) { return; + } // raise window if (cmd[0] == 'D' || cmd[0] == 'r'){ @@ -1821,10 +1976,22 @@ static void propChangeCbk(LTKWindow *win1, Atom atom) { // display file / page if (cmd[0] == 'd' || cmd[0] == 'D') { p = cmd + 2; - newPage = atoi(p); - if (!(p = strchr(p, ' '))) + q = strchr(p, ' '); + if (!q) { + return; + } + *q++ = '\0'; + newPage = 1; + destName = NULL; + if (*p == '+') { + destName = new GString(p + 1); + } else { + newPage = atoi(p); + } + if (!q) { return; - newFileName = new GString(p + 1); + } + newFileName = new GString(q); XFree((XPointer)cmd); if (!doc || newFileName->cmp(doc->getFileName())) { if (!loadFile(newFileName)) @@ -1832,8 +1999,16 @@ static void propChangeCbk(LTKWindow *win1, Atom atom) { } else { delete newFileName; } - if (newPage != page && newPage >= 1 && newPage <= doc->getNumPages()) + if (destName) { + if ((dest = doc->findDest(destName))) { + displayDest(dest, zoom, rotate, gTrue); + delete dest; + } + delete destName; + } else if (newPage != page && + newPage >= 1 && newPage <= doc->getNumPages()) { displayPage(newPage, zoom, rotate, gTrue); + } // quit } else if (cmd[0] == 'q') { @@ -1993,8 +2168,10 @@ static void openSelectCbk(LTKWidget *widget, int n, GString *name) { openDialog = NULL; } if (loadFile(name1)) { - vScrollbar->setPos(0, canvas->getHeight()); - canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + if (!fullScreen) { + vScrollbar->setPos(0, canvas->getHeight()); + canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos()); + } displayPage(1, zoom, rotate, gTrue); } } @@ -2122,8 +2299,9 @@ static void psButtonCbk(LTKWidget *button, int n, GBool on) { psDialog->setBusyCursor(gTrue); win->setBusyCursor(gTrue); if (doc->okToPrint()) { - psOut = new PSOutputDev(psFileName->getCString(), doc->getCatalog(), - psFirstPage, psLastPage, gTrue, gFalse); + psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + doc->getCatalog(), psFirstPage, psLastPage, + psModePS); if (psOut->isOk()) { doc->displayPages(psOut, psFirstPage, psLastPage, 72, 0, gFalse); } @@ -2146,10 +2324,19 @@ static void psButtonCbk(LTKWidget *button, int n, GBool on) { //------------------------------------------------------------------------ static void mapAboutWin() { + int i; + if (aboutWin) { aboutWin->raise(); } else { aboutWin = makeAboutWindow(app); + aboutWin->setLayoutCbk(&aboutLayoutCbk); + aboutList = (LTKList *)aboutWin->findWidget("list"); + aboutHScrollbar = (LTKScrollbar *)aboutWin->findWidget("hScrollbar"); + aboutVScrollbar = (LTKScrollbar *)aboutWin->findWidget("vScrollbar"); + for (i = 0; aboutWinText[i]; ++i) { + aboutList->addLine(aboutWinText[i]); + } aboutWin->layout(-1, -1, -1, -1); aboutWin->map(); } @@ -2160,6 +2347,24 @@ static void closeAboutCbk(LTKWidget *button, int n, GBool on) { aboutWin = NULL; } +static void aboutLayoutCbk(LTKWindow *winA) { + aboutHScrollbar->setLimits(0, aboutList->getMaxWidth() - 1); + aboutHScrollbar->setPos(aboutHScrollbar->getPos(), aboutList->getWidth()); + aboutVScrollbar->setLimits(0, aboutList->getNumLines() - 1); + aboutVScrollbar->setPos(aboutVScrollbar->getPos(), + aboutList->getDisplayedLines()); +} + +static void aboutScrollVertCbk(LTKWidget *scrollbar, int n, int val) { + aboutList->scrollTo(val, aboutHScrollbar->getPos()); + XSync(display, False); +} + +static void aboutScrollHorizCbk(LTKWidget *scrollbar, int n, int val) { + aboutList->scrollTo(aboutVScrollbar->getPos(), val); + XSync(display, False); +} + //------------------------------------------------------------------------ // "Find" window //------------------------------------------------------------------------ @@ -2177,17 +2382,16 @@ static void mapFindWin() { findWin = makeFindWindow(app); findWin->layout(-1, -1, -1, -1); findWin->map(); + findTextIn = (LTKTextIn *)findWin->findWidget("text"); } + findTextIn->activate(gTrue); } static void findButtonCbk(LTKWidget *button, int n, GBool on) { - LTKTextIn *textIn; - if (!doc || doc->getNumPages() == 0) return; if (n == 1) { - textIn = (LTKTextIn *)findWin->findWidget("text"); - doFind(textIn->getText()->getCString()); + doFind(findTextIn->getText()->getCString()); } else { delete findWin; findWin = NULL; @@ -2195,12 +2399,14 @@ static void findButtonCbk(LTKWidget *button, int n, GBool on) { } static void doFind(char *s) { + Unicode *u; TextOutputDev *textOut; int xMin, yMin, xMax, yMax; double xMin1, yMin1, xMax1, yMax1; int pg; GBool top; GString *s1; + int len, i; // check for zero-length string if (!s[0]) { @@ -2212,6 +2418,15 @@ static void doFind(char *s) { win->setBusyCursor(gTrue); findWin->setBusyCursor(gTrue); + // convert to Unicode +#if 1 //~ should do something more intelligent here + len = strlen(s); + u = (Unicode *)gmalloc(len * sizeof(Unicode)); + for (i = 0; i < len; ++i) { + u[i] = (Unicode)(s[i] & 0xff); + } +#endif + // search current page starting at current selection or top of page xMin = yMin = xMax = yMax = 0; if (selectXMin < selectXMax && selectYMin < selectYMax) { @@ -2221,28 +2436,31 @@ static void doFind(char *s) { } else { top = gTrue; } - if (out->findText(s, top, gTrue, &xMin, &yMin, &xMax, &yMax)) + if (out->findText(u, len, top, gTrue, &xMin, &yMin, &xMax, &yMax)) { goto found; + } // search following pages - textOut = new TextOutputDev(NULL, - useEUCJP ? textOutASCII7 : textOutLatin1, - gFalse); + textOut = new TextOutputDev(NULL, gFalse, gFalse); if (!textOut->isOk()) { delete textOut; goto done; } for (pg = page+1; pg <= doc->getNumPages(); ++pg) { doc->displayPage(textOut, pg, 72, 0, gFalse); - if (textOut->findText(s, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1)) + if (textOut->findText(u, len, gTrue, gTrue, + &xMin1, &yMin1, &xMax1, &yMax1)) { goto foundPage; + } } // search previous pages for (pg = 1; pg < page; ++pg) { doc->displayPage(textOut, pg, 72, 0, gFalse); - if (textOut->findText(s, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1)) + if (textOut->findText(u, len, gTrue, gTrue, + &xMin1, &yMin1, &xMax1, &yMax1)) { goto foundPage; + } } delete textOut; @@ -2250,8 +2468,9 @@ static void doFind(char *s) { if (selectXMin < selectXMax && selectYMin < selectYMax) { xMax = selectXMin; yMax = (selectYMin + selectYMax) / 2; - if (out->findText(s, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax)) + if (out->findText(u, len, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax)) { goto found; + } } // not found @@ -2262,8 +2481,10 @@ static void doFind(char *s) { foundPage: delete textOut; displayPage(pg, zoom, rotate, gTrue); - if (!out->findText(s, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax)) - goto done; // this can happen if coalescing is bad + if (!out->findText(u, len, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax)) { + // this can happen if coalescing is bad + goto done; + } // found: change the selection found: @@ -2276,6 +2497,8 @@ static void doFind(char *s) { #endif done: + gfree(u); + // reset cursors to normal win->setBusyCursor(gFalse); findWin->setBusyCursor(gFalse); -- cgit v0.9.1