From d57c02ebc09bfd1a0cac44140ec7a80dbe43877e Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Sun, 16 May 2004 20:13:21 +0000 Subject: Import of Xpdf 2.03 --- diff --git a/pdf/aconf2.h b/pdf/aconf2.h index 59a1740..b51de1e 100644 --- a/pdf/aconf2.h +++ b/pdf/aconf2.h @@ -28,4 +28,11 @@ # endif #endif +/* + * Make sure WIN32 is defined if appropriate. + */ +#if defined(_WIN32) && !defined(WIN32) +# define WIN32 +#endif + #endif diff --git a/pdf/xpdf/JBIG2Stream.cc b/pdf/xpdf/JBIG2Stream.cc index 8363362..f852d26 100644 --- a/pdf/xpdf/JBIG2Stream.cc +++ b/pdf/xpdf/JBIG2Stream.cc @@ -2324,7 +2324,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, } else { arithDecoder->decodeInt(&t, iadtStats); } - t *= -strips; + t *= -(int)strips; inst = 0; sFirst = 0; @@ -2497,10 +2497,10 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) { } // read the bitmap - atx[0] = -patternW; aty[0] = 0; - atx[1] = -3; aty[1] = -1; - atx[2] = 2; aty[2] = -2; - atx[3] = -2; aty[3] = -2; + atx[0] = -(int)patternW; aty[0] = 0; + atx[1] = -3; aty[1] = -1; + atx[2] = 2; aty[2] = -2; + atx[3] = -2; aty[3] = -2; bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH, templ, gFalse, gFalse, NULL, atx, aty, length - 7); @@ -2816,10 +2816,12 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, code2 += code3 = mmrDecoder->getBlackCode(); } while (code3 >= 64); } - a0 = codingLine[codingI++] = a0 + code1; - a0 = codingLine[codingI++] = a0 + code2; - while (refLine[refI] <= a0 && refLine[refI] < w) { - refI += 2; + if (code1 > 0 || code2 > 0) { + a0 = codingLine[codingI++] = a0 + code1; + a0 = codingLine[codingI++] = a0 + code2; + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } } break; case twoDimVert0: @@ -3027,9 +3029,9 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, } // update the context - cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f; cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; - cx2 = ((cx2 << 1) | pix) & 0x0f; + cx2 = ((cx2 << 1) | pix) & 0x07; } break; @@ -3049,7 +3051,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, for (x = 0; x < w; ++x) { // build the context - cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) | bitmap->nextPixel(&atPtr0); // check for a skipped pixel @@ -3062,9 +3064,9 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, } // update the context - cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f; - cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; - cx2 = ((cx2 << 1) | pix) & 0x07; + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f; + cx2 = ((cx2 << 1) | pix) & 0x03; } break; @@ -3081,7 +3083,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, for (x = 0; x < w; ++x) { // build the context - cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + cx = (cx1 << 5) | (cx2 << 1) | bitmap->nextPixel(&atPtr0); // check for a skipped pixel @@ -3519,7 +3521,7 @@ void JBIG2Stream::discardSegment(Guint segNum) { for (i = 0; i < segments->getLength(); ++i) { seg = (JBIG2Segment *)segments->get(i); if (seg->getSegNum() == segNum) { - globalSegments->del(i); + segments->del(i); return; } } diff --git a/pdf/xpdf/XPDFApp.cc b/pdf/xpdf/XPDFApp.cc index d93f2a0..5125f5f 100644 --- a/pdf/xpdf/XPDFApp.cc +++ b/pdf/xpdf/XPDFApp.cc @@ -35,6 +35,7 @@ //------------------------------------------------------------------------ static String fallbackResources[] = { + "*.zoomComboBox*fontList: -*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1", "*XmTextField.fontList: -*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1", "*.fontList: -*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1", "*XmTextField.translations: #override\\n" @@ -271,9 +272,9 @@ void XPDFApp::quit() { delete (XPDFViewer *)viewers->del(0); } #if HAVE_XTAPPSETEXITFLAG - exit(0); -#else XtAppSetExitFlag(appContext); +#else + exit(0); #endif } @@ -378,7 +379,6 @@ void XPDFApp::remoteMsgCbk(Widget widget, XtPointer ptr, app->remoteViewer->open(fileName, page, destName); delete fileName; } - XFree((XPointer)cmd); if (destName) { delete destName; } @@ -397,4 +397,6 @@ void XPDFApp::remoteMsgCbk(Widget widget, XtPointer ptr, XMapRaised(app->display, XtWindow(app->remoteWin)); XFlush(app->display); } + + XFree((XPointer)cmd); } diff --git a/pdf/xpdf/XPDFCore.cc b/pdf/xpdf/XPDFCore.cc index 9e359da..d4d8fa6 100644 --- a/pdf/xpdf/XPDFCore.cc +++ b/pdf/xpdf/XPDFCore.cc @@ -14,6 +14,7 @@ #include #include +#include #include "gmem.h" #include "GString.h" #include "GList.h" @@ -91,14 +92,6 @@ //------------------------------------------------------------------------ -static int zoomDPI[maxZoom - minZoom + 1] = { - 29, 35, 42, 50, 60, - 72, - 86, 104, 124, 149, 179 -}; - -//------------------------------------------------------------------------ - GString *XPDFCore::currentSelection = NULL; XPDFCore *XPDFCore::currentSelectionOwner = NULL; Atom XPDFCore::targetsAtom; @@ -146,10 +139,8 @@ XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA, zoom = zoomWidth; } else { zoom = atoi(initialZoom->getCString()); - if (zoom < minZoom) { - zoom = minZoom; - } else if (zoom > maxZoom) { - zoom = maxZoom; + if (zoom <= 0) { + zoom = defZoom; } } delete initialZoom; @@ -397,11 +388,11 @@ void XPDFCore::resizeToPage(int pg) { height1 = doc->getPageHeight(pg); } if (zoom == zoomPage || zoom == zoomWidth) { - width = (Dimension)((width1 * zoomDPI[defZoom - minZoom]) / 72 + 0.5); - height = (Dimension)((height1 * zoomDPI[defZoom - minZoom]) / 72 + 0.5); + width = (Dimension)(width1 * 0.01 * defZoom + 0.5); + height = (Dimension)(height1 * 0.01 * defZoom + 0.5); } else { - width = (Dimension)((width1 * zoomDPI[zoom - minZoom]) / 72 + 0.5); - height = (Dimension)((height1 * zoomDPI[zoom - minZoom]) / 72 + 0.5); + width = (Dimension)(width1 * 0.01 * zoom + 0.5); + height = (Dimension)(height1 * 0.01 * zoom + 0.5); } if (width > displayW - 100) { width = displayW - 100; @@ -441,7 +432,7 @@ void XPDFCore::clear() { redrawRectangle(scrollX, scrollY, drawAreaWidth, drawAreaHeight); } -void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, +void XPDFCore::displayPage(int pageA, double zoomA, int rotateA, GBool scrollToTop, GBool addToHist) { double hDPI, vDPI; int rot; @@ -525,10 +516,10 @@ void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, dpi = (drawAreaWidth / doc->getPageWidth(page)) * 72; } } else { - dpi = zoomDPI[zoom - minZoom]; + dpi = 0.01 * zoom * 72; } out->setWindow(XtWindow(drawArea)); - doc->displayPage(out, page, dpi, rotate, gTrue); + doc->displayPage(out, page, dpi, dpi, rotate, gTrue); oldScrollX = scrollX; oldScrollY = scrollY; updateScrollBars(); @@ -576,7 +567,7 @@ void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, setCursor(None); } -void XPDFCore::displayDest(LinkDest *dest, int zoomA, int rotateA, +void XPDFCore::displayDest(LinkDest *dest, double zoomA, int rotateA, GBool addToHist) { Ref pageRef; int pg; @@ -685,7 +676,7 @@ void XPDFCore::goForward() { } --historyFLen; ++historyBLen; - if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) { + if (!doc || history[historyCur].fileName->cmp(doc->getFileName()) != 0) { if (loadFile(history[historyCur].fileName) != errNone) { XBell(display, 0); return; @@ -704,7 +695,7 @@ void XPDFCore::goBackward() { } --historyBLen; ++historyFLen; - if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) { + if (!doc || history[historyCur].fileName->cmp(doc->getFileName()) != 0) { if (loadFile(history[historyCur].fileName) != errNone) { XBell(display, 0); return; @@ -1045,7 +1036,7 @@ GString *XPDFCore::extractText(int pageNum, delete textOut; return NULL; } - doc->displayPage(textOut, pageNum, dpi, rotate, gFalse); + doc->displayPage(textOut, pageNum, dpi, dpi, rotate, gFalse); s = textOut->getText(xMin, yMin, xMax, yMax); delete textOut; return s; @@ -1055,7 +1046,7 @@ GString *XPDFCore::extractText(int pageNum, // hyperlinks //------------------------------------------------------------------------ -void XPDFCore::doLink(int mx, int my) { +GBool XPDFCore::doLink(int mx, int my) { double x, y; LinkAction *action; @@ -1063,7 +1054,9 @@ void XPDFCore::doLink(int mx, int my) { out->cvtDevToUser(mx, my, &x, &y); if ((action = doc->findLink(x, y))) { doAction(action); + return gTrue; } + return gFalse; } void XPDFCore::doAction(LinkAction *action) { @@ -1271,26 +1264,9 @@ void XPDFCore::doAction(LinkAction *action) { void XPDFCore::runCommand(GString *cmdFmt, GString *arg) { GString *cmd; char *s; - int i; if ((s = strstr(cmdFmt->getCString(), "%s"))) { - cmd = arg->copy(); - // filter out any quote marks (' or ") to avoid a potential - // security hole - i = 0; - while (i < cmd->getLength()) { - if (cmd->getChar(i) == '"') { - cmd->del(i); - cmd->insert(i, "%22"); - i += 3; - } else if (cmd->getChar(i) == '\'') { - cmd->del(i); - cmd->insert(i, "%27"); - i += 3; - } else { - ++i; - } - } + cmd = mungeURL(arg); cmd->insert(0, cmdFmt->getCString(), s - cmdFmt->getCString()); cmd->append(s + 2); @@ -1308,18 +1284,43 @@ void XPDFCore::runCommand(GString *cmdFmt, GString *arg) { delete cmd; } +// Escape any characters in a URL which might cause problems when +// calling system(). +GString *XPDFCore::mungeURL(GString *url) { + static char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "-_.~/?:@&=+,#%"; + GString *newURL; + char c; + char buf[4]; + int i; + + newURL = new GString(); + for (i = 0; i < url->getLength(); ++i) { + c = url->getChar(i); + if (strchr(allowed, c)) { + newURL->append(c); + } else { + sprintf(buf, "%%%02x", c & 0xff); + newURL->append(buf); + } + } + return newURL; +} + //------------------------------------------------------------------------ // find //------------------------------------------------------------------------ -void XPDFCore::find(char *s) { +void XPDFCore::find(char *s, GBool next) { Unicode *u; TextOutputDev *textOut; int xMin, yMin, xMax, yMax; double xMin1, yMin1, xMax1, yMax1; int pg; - GBool top; + GBool startAtTop; int len, i; // check for zero-length string @@ -1341,15 +1342,12 @@ void XPDFCore::find(char *s) { #endif // search current page starting at current selection or top of page - xMin = yMin = xMax = yMax = 0; - if (selectXMin < selectXMax && selectYMin < selectYMax) { - xMin = selectXMax; - yMin = (selectYMin + selectYMax) / 2; - top = gFalse; - } else { - top = gTrue; - } - if (out->findText(u, len, top, gTrue, &xMin, &yMin, &xMax, &yMax)) { + startAtTop = !next && !(selectXMin < selectXMax && selectYMin < selectYMax); + xMin = selectXMin + 1; + yMin = selectYMin + 1; + xMax = yMax = 0; + if (out->findText(u, len, startAtTop, gTrue, next, gFalse, + &xMin, &yMin, &xMax, &yMax)) { goto found; } @@ -1360,8 +1358,8 @@ void XPDFCore::find(char *s) { goto done; } for (pg = page+1; pg <= doc->getNumPages(); ++pg) { - doc->displayPage(textOut, pg, 72, 0, gFalse); - if (textOut->findText(u, len, gTrue, gTrue, + doc->displayPage(textOut, pg, 72, 72, 0, gFalse); + if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse, &xMin1, &yMin1, &xMax1, &yMax1)) { goto foundPage; } @@ -1369,8 +1367,8 @@ void XPDFCore::find(char *s) { // search previous pages for (pg = 1; pg < page; ++pg) { - doc->displayPage(textOut, pg, 72, 0, gFalse); - if (textOut->findText(u, len, gTrue, gTrue, + doc->displayPage(textOut, pg, 72, 72, 0, gFalse); + if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse, &xMin1, &yMin1, &xMax1, &yMax1)) { goto foundPage; } @@ -1378,10 +1376,12 @@ void XPDFCore::find(char *s) { delete textOut; // search current page ending at current selection - if (selectXMin < selectXMax && selectYMin < selectYMax) { + if (!startAtTop) { + xMin = yMin = 0; xMax = selectXMin; - yMax = (selectYMin + selectYMax) / 2; - if (out->findText(u, len, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax)) { + yMax = selectYMin; + if (out->findText(u, len, gTrue, gFalse, gFalse, next, + &xMin, &yMin, &xMax, &yMax)) { goto found; } } @@ -1394,7 +1394,8 @@ void XPDFCore::find(char *s) { foundPage: delete textOut; displayPage(pg, zoom, rotate, gTrue, gTrue); - if (!out->findText(u, len, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax)) { + if (!out->findText(u, len, gTrue, gTrue, gFalse, gFalse, + &xMin, &yMin, &xMax, &yMax)) { // this can happen if coalescing is bad goto done; } @@ -1942,7 +1943,7 @@ void XPDFCore::doErrorDialog(char *title, GString *msg) { GBool XPDFCore::doDialog(int type, GBool hasCancel, char *title, GString *msg) { - Widget dialog; + Widget dialog, scroll, text; XtAppContext appContext; Arg args[20]; int n; @@ -1954,11 +1955,31 @@ GBool XPDFCore::doDialog(int type, GBool hasCancel, XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n; s1 = XmStringCreateLocalized(title); XtSetArg(args[n], XmNdialogTitle, s1); ++n; - s2 = XmStringCreateLocalized(msg->getCString()); - XtSetArg(args[n], XmNmessageString, s2); ++n; + s2 = NULL; // make gcc happy + if (msg->getLength() <= 80) { + s2 = XmStringCreateLocalized(msg->getCString()); + XtSetArg(args[n], XmNmessageString, s2); ++n; + } dialog = XmCreateMessageDialog(drawArea, "questionDialog", args, n); XmStringFree(s1); - XmStringFree(s2); + if (msg->getLength() <= 80) { + XmStringFree(s2); + } else { + n = 0; + XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n; + if (drawAreaWidth > 300) { + XtSetArg(args[n], XmNwidth, drawAreaWidth - 100); ++n; + } + scroll = XmCreateScrolledWindow(dialog, "scroll", args, n); + XtManageChild(scroll); + n = 0; + XtSetArg(args[n], XmNeditable, False); ++n; + XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); ++n; + XtSetArg(args[n], XmNvalue, msg->getCString()); ++n; + XtSetArg(args[n], XmNshadowThickness, 0); ++n; + text = XmCreateText(scroll, "text", args, n); + XtManageChild(text); + } XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); XtAddCallback(dialog, XmNokCallback, &dialogOkCbk, (XtPointer)this); diff --git a/pdf/xpdf/XPDFCore.h b/pdf/xpdf/XPDFCore.h index 6435736..4878c4f 100644 --- a/pdf/xpdf/XPDFCore.h +++ b/pdf/xpdf/XPDFCore.h @@ -34,11 +34,9 @@ class XPixmapOutputDev; // zoom factor //------------------------------------------------------------------------ -#define minZoom -5 -#define maxZoom 5 -#define zoomPage 100 -#define zoomWidth 101 -#define defZoom 1 +#define zoomPage -1 +#define zoomWidth -2 +#define defZoom 125 //------------------------------------------------------------------------ // XPDFHistory @@ -114,11 +112,11 @@ public: // set, the window is vertically scrolled to the top; otherwise, no // scrolling is done. If is set, this page change is // added to the history list. - void displayPage(int pageA, int zoomA, int rotateA, + void displayPage(int pageA, double zoomA, int rotateA, GBool scrollToTop, GBool addToHist); // Display a link destination. - void displayDest(LinkDest *dest, int zoomA, int rotateA, + void displayDest(LinkDest *dest, double zoomA, int rotateA, GBool addToHist); //----- page/position changes @@ -151,7 +149,7 @@ public: //----- find - void find(char *s); + void find(char *s, GBool next = gFalse); //----- simple modal dialogs @@ -166,7 +164,7 @@ public: PDFDoc *getDoc() { return doc; } XPixmapOutputDev *getOutputDev() { return out; } int getPageNum() { return page; } - int getZoom() { return zoom; } + double getZoom() { return zoom; } double getZoomDPI() { return dpi; } int getRotate() { return rotate; } GBool canGoBack() { return historyBLen > 1; } @@ -194,8 +192,9 @@ public: private: //----- hyperlinks - void doLink(int mx, int my); + GBool doLink(int mx, int my); void runCommand(GString *cmdFmt, GString *arg); + GString *mungeURL(GString *url); //----- selection static Boolean convertSelectionCbk(Widget widget, Atom *selection, @@ -275,7 +274,7 @@ private: PDFDoc *doc; // current PDF file int page; // current page number - int zoom; // current zoom level + double zoom; // current zoom level, in percent of 72 dpi double dpi; // current zoom level, in DPI int rotate; // current page rotation time_t modTime; // last modification time of PDF file diff --git a/pdf/xpdf/XPDFViewer.cc b/pdf/xpdf/XPDFViewer.cc index f8f030b..56fb7b5 100644 --- a/pdf/xpdf/XPDFViewer.cc +++ b/pdf/xpdf/XPDFViewer.cc @@ -85,11 +85,38 @@ //------------------------------------------------------------------------ +struct ZoomMenuInfo { + char *label; + double zoom; +}; + +static ZoomMenuInfo zoomMenuInfo[nZoomMenuItems] = { + { "400%", 400 }, + { "200%", 200 }, + { "150%", 150 }, + { "125%", 125 }, + { "100%", 100 }, + { "50%", 50 }, + { "25%", 25 }, + { "12.5%", 12.5 }, + { "fit page", zoomPage }, + { "fit width", zoomWidth } +}; + +#define maxZoomIdx 0 +#define defZoomIdx 3 +#define minZoomIdx 7 +#define zoomPageIdx 8 +#define zoomWidthIdx 9 + +//------------------------------------------------------------------------ + XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName, int pageA, GString *destName, GString *ownerPassword, GString *userPassword) { LinkDest *dest; - int pg, z; + int pg; + double z; GString *dir; app = appA; @@ -118,6 +145,13 @@ XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName, if (fileName) { if (loadFile(fileName, ownerPassword, userPassword)) { getPageAndDest(pageA, destName, &pg, &dest); +#ifndef DISABLE_OUTLINE + if (!app->getFullScreen() && + core->getDoc()->getOutline()->getItems() && + core->getDoc()->getOutline()->getItems()->getLength() > 0) { + XtVaSetValues(outlineScroll, XmNwidth, 175, NULL); + } +#endif if (pg > 0) { core->resizeToPage(pg); } @@ -164,7 +198,8 @@ XPDFViewer::~XPDFViewer() { void XPDFViewer::open(GString *fileName, int pageA, GString *destName) { LinkDest *dest; - int pg, z; + int pg; + double z; if (!core->getDoc() || fileName->cmp(core->getDoc()->getFileName())) { if (!loadFile(fileName, NULL, NULL)) { @@ -233,12 +268,12 @@ void XPDFViewer::reloadFile() { displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse); } -void XPDFViewer::displayPage(int pageA, int zoomA, int rotateA, +void XPDFViewer::displayPage(int pageA, double zoomA, int rotateA, GBool scrollToTop, GBool addToHist) { core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist); } -void XPDFViewer::displayDest(LinkDest *dest, int zoomA, int rotateA, +void XPDFViewer::displayDest(LinkDest *dest, double zoomA, int rotateA, GBool addToHist) { core->displayDest(dest, zoomA, rotateA, addToHist); } @@ -318,7 +353,7 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key, break; case '\007': // ctrl-G if (viewer->core->getDoc()) { - XPDFViewer::findFindCbk(None, viewer, NULL); + viewer->doFind(gTrue); } break; case '\020': // ctrl-P @@ -387,43 +422,39 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key, case '0': if (!viewer->app->getFullScreen() && viewer->core->getZoom() != defZoom) { - XtVaSetValues(viewer->zoomMenu, - XmNmenuHistory, viewer->getZoomMenuBtn(defZoom), - NULL); + viewer->setZoomIdx(defZoomIdx); viewer->displayPage(viewer->core->getPageNum(), defZoom, viewer->core->getRotate(), gTrue, gFalse); } break; case '+': - if (!viewer->app->getFullScreen() && - viewer->core->getZoom() >= minZoom && - viewer->core->getZoom() < maxZoom) { - z = viewer->core->getZoom() + 1; - XtVaSetValues(viewer->zoomMenu, - XmNmenuHistory, viewer->getZoomMenuBtn(z), - NULL); - viewer->displayPage(viewer->core->getPageNum(), z, - viewer->core->getRotate(), gTrue, gFalse); + if (!viewer->app->getFullScreen()) { + z = viewer->getZoomIdx(); + if (z <= minZoomIdx && z > maxZoomIdx) { + --z; + viewer->setZoomIdx(z); + viewer->displayPage(viewer->core->getPageNum(), + zoomMenuInfo[z].zoom, + viewer->core->getRotate(), gTrue, gFalse); + } } break; case '-': - if (!viewer->app->getFullScreen() && - viewer->core->getZoom() > minZoom && - viewer->core->getZoom() <= maxZoom) { - z = viewer->core->getZoom() - 1; - XtVaSetValues(viewer->zoomMenu, - XmNmenuHistory, viewer->getZoomMenuBtn(z), - NULL); - viewer->displayPage(viewer->core->getPageNum(), z, - viewer->core->getRotate(), gTrue, gFalse); + if (!viewer->app->getFullScreen()) { + z = viewer->getZoomIdx(); + if (z < minZoomIdx && z >= maxZoomIdx) { + ++z; + viewer->setZoomIdx(z); + viewer->displayPage(viewer->core->getPageNum(), + zoomMenuInfo[z].zoom, + viewer->core->getRotate(), gTrue, gFalse); + } } break; case 'z': if (!viewer->app->getFullScreen() && viewer->core->getZoom() != zoomPage) { - XtVaSetValues(viewer->zoomMenu, - XmNmenuHistory, viewer->getZoomMenuBtn(zoomPage), - NULL); + viewer->setZoomIdx(zoomPageIdx); viewer->displayPage(viewer->core->getPageNum(), zoomPage, viewer->core->getRotate(), gTrue, gFalse); } @@ -431,9 +462,7 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key, case 'w': if (!viewer->app->getFullScreen() && viewer->core->getZoom() != zoomWidth) { - XtVaSetValues(viewer->zoomMenu, - XmNmenuHistory, viewer->getZoomMenuBtn(zoomWidth), - NULL); + viewer->setZoomIdx(zoomWidthIdx); viewer->displayPage(viewer->core->getPageNum(), zoomWidth, viewer->core->getRotate(), gTrue, gFalse); } @@ -475,7 +504,7 @@ void XPDFViewer::mouseCbk(void *data, XEvent *event) { //------------------------------------------------------------------------ void XPDFViewer::initWindow() { - Widget btn, label, menuPane, lastBtn; + Widget btn, label, lastBtn, zoomWidget; #ifndef DISABLE_OUTLINE Widget clipWin; #endif @@ -485,7 +514,6 @@ void XPDFViewer::initWindow() { int n; char *title; XmString s, s2, emptyString; - char buf[16]; int i; display = XtDisplay(app->getAppShell()); @@ -658,43 +686,50 @@ void XPDFViewer::initWindow() { XmStringFree(s); // zoom menu +#if USE_COMBO_BOX + XmString st[nZoomMenuItems]; + n = 0; + XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n; + XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n; + XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n; + XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n; + XtSetArg(args[n], XmNmarginWidth, 0); ++n; + XtSetArg(args[n], XmNmarginHeight, 0); ++n; + XtSetArg(args[n], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ++n; + XtSetArg(args[n], XmNpositionMode, XmONE_BASED); ++n; + XtSetArg(args[n], XmNcolumns, 7); ++n; + for (i = 0; i < nZoomMenuItems; ++i) { + st[i] = XmStringCreateLocalized(zoomMenuInfo[i].label); + } + XtSetArg(args[n], XmNitems, st); ++n; + XtSetArg(args[n], XmNitemCount, nZoomMenuItems); ++n; + zoomComboBox = XmCreateComboBox(toolBar, "zoomComboBox", args, n); + for (i = 0; i < nZoomMenuItems; ++i) { + XmStringFree(st[i]); + } + XtAddCallback(zoomComboBox, XmNselectionCallback, + &zoomComboBoxCbk, (XtPointer)this); + XtManageChild(zoomComboBox); + zoomWidget = zoomComboBox; +#else + Widget menuPane; + char buf[16]; n = 0; menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n); - for (i = minZoom; i <= maxZoom; ++i) { + for (i = 0; i < nZoomMenuItems; ++i) { n = 0; - sprintf(buf, "%s%d", i > 0 ? "+" : "", i); - s = XmStringCreateLocalized(buf); + s = XmStringCreateLocalized(zoomMenuInfo[i].label); XtSetArg(args[n], XmNlabelString, s); ++n; XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n; - sprintf(buf, "zoom%s%d", i < 0 ? "M" : "", i < 0 ? -i : i); + sprintf(buf, "zoom%d", i); btn = XmCreatePushButton(menuPane, buf, args, n); XmStringFree(s); XtManageChild(btn); XtAddCallback(btn, XmNactivateCallback, &zoomMenuCbk, (XtPointer)this); - zoomMenuBtns[i - minZoom] = btn; + zoomMenuBtns[i] = btn; } n = 0; - s = XmStringCreateLocalized("fit page"); - XtSetArg(args[n], XmNlabelString, s); ++n; - XtSetArg(args[n], XmNuserData, (XtPointer)zoomPage); ++n; - btn = XmCreatePushButton(menuPane, "zoomPage", args, n); - XmStringFree(s); - XtManageChild(btn); - XtAddCallback(btn, XmNactivateCallback, - &zoomMenuCbk, (XtPointer)this); - zoomMenuBtns[maxZoom - minZoom + 1] = btn; - n = 0; - s = XmStringCreateLocalized("fit width"); - XtSetArg(args[n], XmNlabelString, s); ++n; - XtSetArg(args[n], XmNuserData, (XtPointer)zoomWidth); ++n; - btn = XmCreatePushButton(menuPane, "zoomWidth", args, n); - XmStringFree(s); - XtManageChild(btn); - XtAddCallback(btn, XmNactivateCallback, - &zoomMenuCbk, (XtPointer)this); - zoomMenuBtns[maxZoom - minZoom + 2] = btn; - n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n; XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n; @@ -704,11 +739,13 @@ void XPDFViewer::initWindow() { XtSetArg(args[n], XmNsubMenuId, menuPane); ++n; zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n); XtManageChild(zoomMenu); + zoomWidget = zoomMenu; +#endif // find/print/about buttons n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n; - XtSetArg(args[n], XmNleftWidget, zoomMenu); ++n; + XtSetArg(args[n], XmNleftWidget, zoomWidget); ++n; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNmarginWidth, 6); ++n; @@ -760,7 +797,7 @@ void XPDFViewer::initWindow() { XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n; XtSetArg(args[n], XmNleftWidget, lastBtn); ++n; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n; - XtSetArg(args[n], XmNrightWidget, btn); ++n; + XtSetArg(args[n], XmNrightWidget, quitBtn); ++n; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n; s = XmStringCreateLocalized(""); @@ -852,8 +889,7 @@ void XPDFViewer::initWindow() { #endif // set the zoom menu to match the initial zoom setting - XtVaSetValues(zoomMenu, XmNmenuHistory, - getZoomMenuBtn(core->getZoom()), NULL); + setZoomVal(core->getZoom()); // set traversal order XtVaSetValues(core->getDrawAreaWidget(), @@ -872,7 +908,7 @@ void XPDFViewer::initWindow() { NULL); XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL); - XtVaSetValues(zoomMenu, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, + XtVaSetValues(zoomWidget, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL); XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL); @@ -885,7 +921,12 @@ void XPDFViewer::initWindow() { // popup menu n = 0; +#if XmVersion < 1002 + // older versions of Motif need this, newer ones choke on it, + // sometimes not displaying the menu at all, maybe depending on the + // state of the NumLock key (taken from DDD) XtSetArg(args[n], XmNmenuPost, ""); ++n; +#endif popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu", args, n); n = 0; @@ -1182,17 +1223,67 @@ void XPDFViewer::closeWindow() { XtDestroyWidget(win); } -Widget XPDFViewer::getZoomMenuBtn(int z) { - if (z >= minZoom && z <= maxZoom) { - return zoomMenuBtns[z - minZoom]; +int XPDFViewer::getZoomIdx() { +#if USE_COMBO_BOX + int z; + + XtVaGetValues(zoomComboBox, XmNselectedPosition, &z, NULL); + return z - 1; +#else + Widget w; + int i; + + XtVaGetValues(zoomMenu, XmNmenuHistory, &w, NULL); + for (i = 0; i < nZoomMenuItems; ++i) { + if (w == zoomMenuBtns[i]) { + return i; + } + } + // this should never happen + return 0; +#endif +} + +void XPDFViewer::setZoomIdx(int idx) { +#if USE_COMBO_BOX + XtVaSetValues(zoomComboBox, XmNselectedPosition, idx + 1, NULL); +#else + XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[idx], NULL); +#endif +} + +void XPDFViewer::setZoomVal(double z) { +#if USE_COMBO_BOX + char buf[32]; + XmString s; + int i; + + for (i = 0; i < nZoomMenuItems; ++i) { + if (z == zoomMenuInfo[i].zoom) { + XtVaSetValues(zoomComboBox, XmNselectedPosition, i + 1, NULL); + return; + } } - if (z == zoomPage) { - return zoomMenuBtns[maxZoom - minZoom + 1]; + sprintf(buf, "%d", (int)z); + s = XmStringCreateLocalized(buf); + XtVaSetValues(zoomComboBox, XmNselectedItem, s, NULL); + XmStringFree(s); +#else + int i; + + for (i = 0; i < nZoomMenuItems; ++i) { + if (z == zoomMenuInfo[i].zoom) { + XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL); + return; + } } - if (z == zoomWidth) { - return zoomMenuBtns[maxZoom - minZoom + 2]; + for (i = maxZoomIdx; i < minZoomIdx; ++i) { + if (z > zoomMenuInfo[i].zoom) { + break; + } } - return zoomMenuBtns[0]; + XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL); +#endif } void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr, @@ -1243,19 +1334,65 @@ void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr, viewer->core->takeFocus(); } +#if USE_COMBO_BOX + +void XPDFViewer::zoomComboBoxCbk(Widget widget, XtPointer ptr, + XtPointer callData) { + XPDFViewer *viewer = (XPDFViewer *)ptr; + XmComboBoxCallbackStruct *data = (XmComboBoxCallbackStruct *)callData; + double z; + char *s; + XmStringContext context; + XmStringCharSet charSet; + XmStringDirection dir; + Boolean sep; + + z = viewer->core->getZoom(); + if (data->item_position == 0) { + XmStringInitContext(&context, data->item_or_text); + if (XmStringGetNextSegment(context, &s, &charSet, &dir, &sep)) { + z = atof(s); + if (z <= 1) { + z = defZoom; + } + XtFree(charSet); + XtFree(s); + } + XmStringFreeContext(context); + } else { + z = zoomMenuInfo[data->item_position - 1].zoom; + } + // only redraw if this was triggered by an event; otherwise + // the caller is responsible for doing the redraw + if (z != viewer->core->getZoom() && data->event) { + viewer->displayPage(viewer->core->getPageNum(), z, + viewer->core->getRotate(), gTrue, gFalse); + } + viewer->core->takeFocus(); +} + +#else // USE_COMBO_BOX + void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr, XtPointer callData) { XPDFViewer *viewer = (XPDFViewer *)ptr; + XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData; XtPointer userData; + double z; XtVaGetValues(widget, XmNuserData, &userData, NULL); - if ((int)userData != viewer->core->getZoom()) { - viewer->displayPage(viewer->core->getPageNum(), (int)userData, + z = zoomMenuInfo[(int)userData].zoom; + // only redraw if this was triggered by an event; otherwise + // the caller is responsible for doing the redraw + if (z != viewer->core->getZoom() && data->event) { + viewer->displayPage(viewer->core->getPageNum(), z, viewer->core->getRotate(), gTrue, gFalse); } viewer->core->takeFocus(); } +#endif // USE_COMBO_BOX + void XPDFViewer::findCbk(Widget widget, XtPointer ptr, XtPointer callData) { XPDFViewer *viewer = (XPDFViewer *)ptr; @@ -1389,7 +1526,7 @@ void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr, } void XPDFViewer::updateCbk(void *data, GString *fileName, - int pageNum, int numPages, char *linkLabel) { + int pageNum, int numPages, char *linkString) { XPDFViewer *viewer = (XPDFViewer *)data; GString *title; char buf[20]; @@ -1439,8 +1576,8 @@ void XPDFViewer::updateCbk(void *data, GString *fileName, XmStringFree(s); } - if (linkLabel) { - s = XmStringCreateLocalized(linkLabel); + if (linkString) { + s = XmStringCreateLocalized(linkString); XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL); XmStringFree(s); } @@ -1815,13 +1952,16 @@ void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr, XtPointer callData) { XPDFViewer *viewer = (XPDFViewer *)ptr; - if (XtWindow(viewer->findDialog)) { - XDefineCursor(viewer->display, XtWindow(viewer->findDialog), - viewer->core->getBusyCursor()); + viewer->doFind(gFalse); +} + +void XPDFViewer::doFind(GBool next) { + if (XtWindow(findDialog)) { + XDefineCursor(display, XtWindow(findDialog), core->getBusyCursor()); } - viewer->core->find(XmTextFieldGetString(viewer->findText)); - if (XtWindow(viewer->findDialog)) { - XUndefineCursor(viewer->display, XtWindow(viewer->findDialog)); + core->find(XmTextFieldGetString(findText), next); + if (XtWindow(findDialog)) { + XUndefineCursor(display, XtWindow(findDialog)); } } @@ -1905,6 +2045,7 @@ void XPDFViewer::initPrintDialog() { Arg args[20]; int n; XmString s; + GString *psFileName; //----- dialog n = 0; @@ -2053,6 +2194,17 @@ void XPDFViewer::initPrintDialog() { XtSetArg(args[n], XmNdefaultButton, okBtn); ++n; XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n; XtSetValues(printDialog, args, n); + + //----- initial values + if ((psFileName = globalParams->getPSFile())) { + if (psFileName->getChar(0) == '|') { + XmTextFieldSetString(printCmdText, + psFileName->getCString() + 1); + } else { + XmTextFieldSetString(printFileText, psFileName->getCString()); + } + delete psFileName; + } } void XPDFViewer::setupPrintDialog() { @@ -2063,10 +2215,7 @@ void XPDFViewer::setupPrintDialog() { doc = core->getDoc(); psFileName = globalParams->getPSFile(); - - if (psFileName && psFileName->getChar(0) != '|') { - XmTextFieldSetString(printFileText, psFileName->getCString()); - } else { + if (!psFileName || psFileName->getChar(0) == '|') { pdfFileName = doc->getFileName(); p = pdfFileName->getCString() + pdfFileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { @@ -2079,12 +2228,6 @@ void XPDFViewer::setupPrintDialog() { XmTextFieldSetString(printFileText, psFileName2->getCString()); delete psFileName2; } - - if (psFileName && psFileName->getChar(0) == '|') { - XmTextFieldSetString(printCmdText, - psFileName->getCString() + 1); - } - if (psFileName) { delete psFileName; } @@ -2164,7 +2307,7 @@ void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr, doc->getCatalog(), firstPage, lastPage, psModePS); if (psOut->isOk()) { - doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse); + doc->displayPages(psOut, firstPage, lastPage, 72, 72, 0, gFalse); } delete psOut; delete psFileName; diff --git a/pdf/xpdf/XPDFViewer.h b/pdf/xpdf/XPDFViewer.h index 924042f..b48af27 100644 --- a/pdf/xpdf/XPDFViewer.h +++ b/pdf/xpdf/XPDFViewer.h @@ -25,6 +25,12 @@ #define DISABLE_OUTLINE #endif +#if (XmVERSION >= 2 && !defined(LESSTIF_VERSION)) +# define USE_COMBO_BOX 1 +#else +# undef USE_COMBO_BOX +#endif + class GString; class GList; class UnicodeMap; @@ -32,6 +38,11 @@ class LinkDest; class XPDFApp; //------------------------------------------------------------------------ + +// NB: this must match the defn of zoomMenuBtnInfo in XPDFViewer.cc +#define nZoomMenuItems 10 + +//------------------------------------------------------------------------ // XPDFViewer //------------------------------------------------------------------------ @@ -55,9 +66,9 @@ private: //----- load / display GBool loadFile(GString *fileName, GString *ownerPassword = NULL, GString *userPassword = NULL); - void displayPage(int pageA, int zoomA, int rotateA, + void displayPage(int pageA, double zoomA, int rotateA, GBool scrollToTop, GBool addToHist); - void displayDest(LinkDest *dest, int zoomA, int rotateA, + void displayDest(LinkDest *dest, double zoomA, int rotateA, GBool addToHist); void getPageAndDest(int pageA, GString *destName, int *pageOut, LinkDest **destOut); @@ -77,7 +88,9 @@ private: void initWindow(); void mapWindow(); void closeWindow(); - Widget getZoomMenuBtn(int z); + int getZoomIdx(); + void setZoomIdx(int idx); + void setZoomVal(double z); static void prevPageCbk(Widget widget, XtPointer ptr, XtPointer callData); static void prevTenPageCbk(Widget widget, XtPointer ptr, @@ -90,8 +103,13 @@ private: XtPointer callData); static void forwardCbk(Widget widget, XtPointer ptr, XtPointer callData); +#if USE_COMBO_BOX + static void zoomComboBoxCbk(Widget widget, XtPointer ptr, + XtPointer callData); +#else static void zoomMenuCbk(Widget widget, XtPointer ptr, XtPointer callData); +#endif static void findCbk(Widget widget, XtPointer ptr, XtPointer callData); static void printCbk(Widget widget, XtPointer ptr, @@ -119,7 +137,7 @@ private: static void pageNumCbk(Widget widget, XtPointer ptr, XtPointer callData); static void updateCbk(void *data, GString *fileName, - int pageNum, int numPages, char *linkLabel); + int pageNum, int numPages, char *linkString); //----- GUI code: outline #ifndef DISABLE_OUTLINE @@ -143,6 +161,7 @@ private: void initFindDialog(); static void findFindCbk(Widget widget, XtPointer ptr, XtPointer callData); + void doFind(GBool next); static void findCloseCbk(Widget widget, XtPointer ptr, XtPointer callData); @@ -201,8 +220,12 @@ private: Widget forwardBtn; Widget pageNumText; Widget pageCountLabel; +#if USE_COMBO_BOX + Widget zoomComboBox; +#else Widget zoomMenu; - Widget zoomMenuBtns[maxZoom - minZoom + 1 + 2]; + Widget zoomMenuBtns[nZoomMenuItems]; +#endif Widget findBtn; Widget printBtn; Widget aboutBtn; diff --git a/pdf/xpdf/about-text.h b/pdf/xpdf/about-text.h index 3b03f46..172e39f 100644 --- a/pdf/xpdf/about-text.h +++ b/pdf/xpdf/about-text.h @@ -27,7 +27,7 @@ static char *aboutWinText[] = { " o = open file", " r = reload", " f / ctrl-F = find text", - " ctrl-G = find next" + " ctrl-G = find next", " ctrl-P = print", " n = next page", " p = previous page", -- cgit v0.9.1