📄 xpdfcore.cc
字号:
//========================================================================//// XPDFCore.cc//// Copyright 2002 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <X11/keysym.h>#include <X11/cursorfont.h>#include "gmem.h"#include "GString.h"#include "GList.h"#include "Error.h"#include "GlobalParams.h"#include "PDFDoc.h"#include "ErrorCodes.h"#include "GfxState.h"#include "PSOutputDev.h"#include "TextOutputDev.h"#include "XPixmapOutputDev.h"#include "XPDFCore.h"// these macro defns conflict with xpdf's Object class#ifdef LESSTIF_VERSION#undef XtDisplay#undef XtScreen#undef XtWindow#undef XtParent#undef XtIsRealized#endif// hack around old X includes which are missing these symbols#ifndef XK_Page_Up#define XK_Page_Up 0xFF55#endif#ifndef XK_Page_Down#define XK_Page_Down 0xFF56#endif#ifndef XK_KP_Home#define XK_KP_Home 0xFF95#endif#ifndef XK_KP_Left#define XK_KP_Left 0xFF96#endif#ifndef XK_KP_Up#define XK_KP_Up 0xFF97#endif#ifndef XK_KP_Right#define XK_KP_Right 0xFF98#endif#ifndef XK_KP_Down#define XK_KP_Down 0xFF99#endif#ifndef XK_KP_Prior#define XK_KP_Prior 0xFF9A#endif#ifndef XK_KP_Page_Up#define XK_KP_Page_Up 0xFF9A#endif#ifndef XK_KP_Next#define XK_KP_Next 0xFF9B#endif#ifndef XK_KP_Page_Down#define XK_KP_Page_Down 0xFF9B#endif#ifndef XK_KP_End#define XK_KP_End 0xFF9C#endif#ifndef XK_KP_Begin#define XK_KP_Begin 0xFF9D#endif#ifndef XK_KP_Insert#define XK_KP_Insert 0xFF9E#endif#ifndef XK_KP_Delete#define XK_KP_Delete 0xFF9F#endif//------------------------------------------------------------------------#define highlightNone 0#define highlightNormal 1#define highlightSelected 2//------------------------------------------------------------------------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;//------------------------------------------------------------------------// XPDFCore//------------------------------------------------------------------------XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA, Gulong paperColorA, GBool fullScreenA, GBool reverseVideo, GBool installCmap, int rgbCubeSize) { GString *initialZoom; int i; shell = shellA; parentWidget = parentWidgetA; display = XtDisplay(parentWidget); screenNum = XScreenNumberOfScreen(XtScreen(parentWidget)); paperColor = paperColorA; fullScreen = fullScreenA; // for some reason, querying XmNvisual doesn't work (even if done // after the window is mapped) visual = DefaultVisual(display, screenNum); XtVaGetValues(shell, XmNcolormap, &colormap, NULL); scrolledWin = NULL; hScrollBar = NULL; vScrollBar = NULL; drawAreaFrame = NULL; drawArea = NULL; out = NULL; doc = NULL; page = 0; rotate = 0; // get the initial zoom value initialZoom = globalParams->getInitialZoom(); if (!initialZoom->cmp("page")) { zoom = zoomPage; } else if (!initialZoom->cmp("width")) { zoom = zoomWidth; } else { zoom = atoi(initialZoom->getCString()); if (zoom < minZoom) { zoom = minZoom; } else if (zoom > maxZoom) { zoom = maxZoom; } } delete initialZoom; scrollX = 0; scrollY = 0; linkAction = NULL; selectXMin = selectXMax = 0; selectYMin = selectYMax = 0; dragging = gFalse; lastDragLeft = lastDragTop = gTrue; panning = gFalse; updateCbk = NULL; actionCbk = NULL; keyPressCbk = NULL; mouseCbk = NULL; reqPasswordCbk = NULL; // no history yet historyCur = xpdfHistorySize - 1; historyBLen = historyFLen = 0; for (i = 0; i < xpdfHistorySize; ++i) { history[i].fileName = NULL; } // optional features default to on hyperlinksEnabled = gTrue; selectEnabled = gTrue; // do X-specific initialization and create the widgets initWindow(); // create the OutputDev out = new XPixmapOutputDev(display, screenNum, visual, colormap, reverseVideo, paperColor, installCmap, rgbCubeSize, gTrue, &outputDevRedrawCbk, this); out->startDoc(NULL);}XPDFCore::~XPDFCore() { int i; if (out) { delete out; } if (doc) { delete doc; } if (currentSelectionOwner == this && currentSelection) { delete currentSelection; currentSelection = NULL; currentSelectionOwner = NULL; } for (i = 0; i < xpdfHistorySize; ++i) { if (history[i].fileName) { delete history[i].fileName; } } if (selectGC) { XFreeGC(display, selectGC); XFreeGC(display, highlightGC); } if (drawAreaGC) { XFreeGC(display, drawAreaGC); } if (drawArea) { XtDestroyWidget(drawArea); } if (drawAreaFrame) { XtDestroyWidget(drawAreaFrame); } if (vScrollBar) { XtDestroyWidget(vScrollBar); } if (hScrollBar) { XtDestroyWidget(hScrollBar); } if (scrolledWin) { XtDestroyWidget(scrolledWin); } if (busyCursor) { XFreeCursor(display, busyCursor); } if (linkCursor) { XFreeCursor(display, linkCursor); } if (selectCursor) { XFreeCursor(display, selectCursor); }}//------------------------------------------------------------------------// loadFile / displayPage / displayDest//------------------------------------------------------------------------int XPDFCore::loadFile(GString *fileName, GString *ownerPassword, GString *userPassword) { PDFDoc *newDoc; GString *password; GBool again; int err; // busy cursor setCursor(busyCursor); // open the PDF file newDoc = new PDFDoc(fileName->copy(), ownerPassword, userPassword); if (!newDoc->isOk()) { err = newDoc->getErrorCode(); delete newDoc; if (err != errEncrypted || !reqPasswordCbk) { setCursor(None); return err; } // try requesting a password again = ownerPassword != NULL || userPassword != NULL; while (1) { if (!(password = (*reqPasswordCbk)(reqPasswordCbkData, again))) { setCursor(None); return errEncrypted; } newDoc = new PDFDoc(fileName->copy(), password, password); if (newDoc->isOk()) { break; } err = newDoc->getErrorCode(); delete newDoc; if (err != errEncrypted) { setCursor(None); return err; } again = gTrue; } } // replace old document if (doc) { delete doc; } doc = newDoc; if (out) { out->startDoc(doc->getXRef()); } // nothing displayed yet page = -99; // save the modification time modTime = getModTime(doc->getFileName()->getCString()); // update the parent window if (updateCbk) { (*updateCbk)(updateCbkData, doc->getFileName(), -1, doc->getNumPages(), NULL); } // back to regular cursor setCursor(None); return errNone;}void XPDFCore::resizeToPage(int pg) { Dimension width, height; double width1, height1; Dimension topW, topH, topBorder, daW, daH; Dimension displayW, displayH; displayW = DisplayWidth(display, screenNum); displayH = DisplayHeight(display, screenNum); if (fullScreen) { width = displayW; height = displayH; } else { if (pg < 0 || pg > doc->getNumPages()) { width1 = 612; height1 = 792; } else if (doc->getPageRotate(pg) == 90 || doc->getPageRotate(pg) == 270) { width1 = doc->getPageHeight(pg); height1 = doc->getPageWidth(pg); } else { width1 = doc->getPageWidth(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); } else { width = (Dimension)((width1 * zoomDPI[zoom - minZoom]) / 72 + 0.5); height = (Dimension)((height1 * zoomDPI[zoom - minZoom]) / 72 + 0.5); } if (width > displayW - 100) { width = displayW - 100; } if (height > displayH - 150) { height = displayH - 150; } } if (XtIsRealized(shell)) { XtVaGetValues(shell, XmNwidth, &topW, XmNheight, &topH, XmNborderWidth, &topBorder, NULL); XtVaGetValues(drawArea, XmNwidth, &daW, XmNheight, &daH, NULL); XtVaSetValues(shell, XmNwidth, width + (topW - daW), XmNheight, height + (topH - daH), NULL); } else { XtVaSetValues(drawArea, XmNwidth, width, XmNheight, height, NULL); }}void XPDFCore::clear() { if (!doc) { return; } // no document delete doc; doc = NULL; out->clear(); // no page displayed page = -99; // redraw scrollX = scrollY = 0; updateScrollBars(); redrawRectangle(scrollX, scrollY, drawAreaWidth, drawAreaHeight);}void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, GBool scrollToTop, GBool addToHist) { double hDPI, vDPI; int rot; XPDFHistory *h; GBool newZoom; XGCValues gcValues; time_t newModTime; int oldScrollX, oldScrollY; // update the zoom and rotate values newZoom = zoomA != zoom; zoom = zoomA; rotate = rotateA; // check for document and valid page number if (!doc || pageA <= 0 || pageA > doc->getNumPages()) { return; } // busy cursor setCursor(busyCursor); // check for changes to the file newModTime = getModTime(doc->getFileName()->getCString()); if (newModTime != modTime) { if (loadFile(doc->getFileName()) == errNone) { if (pageA > doc->getNumPages()) { pageA = doc->getNumPages(); } } modTime = newModTime; } // free the old GCs if (selectGC) { XFreeGC(display, selectGC); XFreeGC(display, highlightGC); } // new page number page = pageA; // scroll to top if (scrollToTop) { scrollY = 0; } // if zoom level changed, scroll to the top-left corner if (newZoom) { scrollX = scrollY = 0; } // initialize mouse-related stuff linkAction = NULL; selectXMin = selectXMax = 0; selectYMin = selectYMax = 0; dragging = gFalse; lastDragLeft = lastDragTop = gTrue; // draw the page rot = rotate + doc->getPageRotate(page); if (rot >= 360) { rot -= 360; } else if (rotate < 0) { rot += 360; } if (zoom == zoomPage) { if (rot == 90 || rot == 270) { hDPI = (drawAreaWidth / doc->getPageHeight(page)) * 72; vDPI = (drawAreaHeight / doc->getPageWidth(page)) * 72; } else { hDPI = (drawAreaWidth / doc->getPageWidth(page)) * 72; vDPI = (drawAreaHeight / doc->getPageHeight(page)) * 72; } dpi = (hDPI < vDPI) ? hDPI : vDPI; } else if (zoom == zoomWidth) { if (rot == 90 || rot == 270) { dpi = (drawAreaWidth / doc->getPageHeight(page)) * 72; } else { dpi = (drawAreaWidth / doc->getPageWidth(page)) * 72; } } else { dpi = zoomDPI[zoom - minZoom]; } out->setWindow(XtWindow(drawArea)); doc->displayPage(out, page, dpi, rotate, gTrue); oldScrollX = scrollX; oldScrollY = scrollY; updateScrollBars(); if (scrollX != oldScrollX || scrollY != oldScrollY) { redrawRectangle(scrollX, scrollY, drawAreaWidth, drawAreaHeight); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -