📄 xpdfcore.cc
字号:
//========================================================================//// XPDFCore.cc//// Copyright 2002-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <X11/keysym.h>#include <X11/cursorfont.h>#include <string.h>#include "gmem.h"#include "GString.h"#include "GList.h"#include "Error.h"#include "GlobalParams.h"#include "PDFDoc.h"#include "Link.h"#include "ErrorCodes.h"#include "GfxState.h"#include "CoreOutputDev.h"#include "PSOutputDev.h"#include "TextOutputDev.h"#include "SplashBitmap.h"#include "SplashPattern.h"#include "XPDFApp.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//------------------------------------------------------------------------// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.static inline Guchar div255(int x) { return (Guchar)((x + (x >> 8) + 0x80) >> 8);}//------------------------------------------------------------------------GString *XPDFCore::currentSelection = NULL;XPDFCore *XPDFCore::currentSelectionOwner = NULL;Atom XPDFCore::targetsAtom;//------------------------------------------------------------------------// XPDFCoreTile//------------------------------------------------------------------------class XPDFCoreTile: public PDFCoreTile {public: XPDFCoreTile(int xDestA, int yDestA); virtual ~XPDFCoreTile(); XImage *image;};XPDFCoreTile::XPDFCoreTile(int xDestA, int yDestA): PDFCoreTile(xDestA, yDestA){ image = NULL;}XPDFCoreTile::~XPDFCoreTile() { if (image) { gfree(image->data); image->data = NULL; XDestroyImage(image); }}//------------------------------------------------------------------------// XPDFCore//------------------------------------------------------------------------XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA, SplashColorPtr paperColorA, Gulong paperPixelA, Gulong mattePixelA, GBool fullScreenA, GBool reverseVideoA, GBool installCmap, int rgbCubeSizeA): PDFCore(splashModeRGB8, 4, reverseVideoA, paperColorA, !fullScreenA){ GString *initialZoom; shell = shellA; parentWidget = parentWidgetA; display = XtDisplay(parentWidget); screenNum = XScreenNumberOfScreen(XtScreen(parentWidget)); targetsAtom = XInternAtom(display, "TARGETS", False); paperPixel = paperPixelA; mattePixel = mattePixelA; fullScreen = fullScreenA; setupX(installCmap, rgbCubeSizeA); scrolledWin = NULL; hScrollBar = NULL; vScrollBar = NULL; drawAreaFrame = NULL; drawArea = NULL; // get the initial zoom value if (fullScreen) { zoom = zoomPage; } else { initialZoom = globalParams->getInitialZoom(); if (!initialZoom->cmp("page")) { zoom = zoomPage; } else if (!initialZoom->cmp("width")) { zoom = zoomWidth; } else { zoom = atoi(initialZoom->getCString()); if (zoom <= 0) { zoom = defZoom; } } delete initialZoom; } linkAction = NULL; panning = gFalse; updateCbk = NULL; actionCbk = NULL; keyPressCbk = NULL; mouseCbk = NULL; // optional features default to on hyperlinksEnabled = gTrue; selectEnabled = gTrue; // do X-specific initialization and create the widgets initWindow(); initPasswordDialog();}XPDFCore::~XPDFCore() { if (currentSelectionOwner == this && currentSelection) { delete currentSelection; currentSelection = NULL; currentSelectionOwner = NULL; } if (drawAreaGC) { XFreeGC(display, drawAreaGC); } 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) { int err; err = PDFCore::loadFile(fileName, ownerPassword, userPassword); if (err == errNone) { // save the modification time modTime = getModTime(doc->getFileName()->getCString()); // update the parent window if (updateCbk) { (*updateCbk)(updateCbkData, doc->getFileName(), -1, doc->getNumPages(), NULL); } } return err;}int XPDFCore::loadFile(BaseStream *stream, GString *ownerPassword, GString *userPassword) { int err; err = PDFCore::loadFile(stream, ownerPassword, userPassword); if (err == errNone) { // no file modTime = 0; // update the parent window if (updateCbk) { (*updateCbk)(updateCbkData, doc->getFileName(), -1, doc->getNumPages(), NULL); } } return err;}void XPDFCore::loadDoc(PDFDoc *docA) { PDFCore::loadDoc(docA); // save the modification time if (doc->getFileName()) { modTime = getModTime(doc->getFileName()->getCString()); } // update the parent window if (updateCbk) { (*updateCbk)(updateCbkData, doc->getFileName(), -1, doc->getNumPages(), NULL); }}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 (!doc || pg <= 0 || pg > doc->getNumPages()) { width1 = 612; height1 = 792; } else if (doc->getPageRotate(pg) == 90 || doc->getPageRotate(pg) == 270) { width1 = doc->getPageCropHeight(pg); height1 = doc->getPageCropWidth(pg); } else { width1 = doc->getPageCropWidth(pg); height1 = doc->getPageCropHeight(pg); } if (zoom == zoomPage || zoom == zoomWidth) { width = (Dimension)(width1 * 0.01 * defZoom + 0.5); height = (Dimension)(height1 * 0.01 * defZoom + 0.5); } else { width = (Dimension)(width1 * 0.01 * zoom + 0.5); height = (Dimension)(height1 * 0.01 * zoom + 0.5); } if (continuousMode) { height += continuousModePageSpacing; } if (width > displayW - 100) { width = displayW - 100; } if (height > displayH - 100) { height = displayH - 100; } } 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::update(int topPageA, int scrollXA, int scrollYA, double zoomA, int rotateA, GBool force, GBool addToHist) { int oldPage; oldPage = topPage; PDFCore::update(topPageA, scrollXA, scrollYA, zoomA, rotateA, force, addToHist); linkAction = NULL; if (doc && topPage != oldPage) { if (updateCbk) { (*updateCbk)(updateCbkData, NULL, topPage, -1, ""); } }}GBool XPDFCore::checkForNewFile() { time_t newModTime; if (doc->getFileName()) { newModTime = getModTime(doc->getFileName()->getCString()); if (newModTime != modTime) { modTime = newModTime; return gTrue; } } return gFalse;}//------------------------------------------------------------------------// page/position changes//------------------------------------------------------------------------GBool XPDFCore::gotoNextPage(int inc, GBool top) { if (!PDFCore::gotoNextPage(inc, top)) { XBell(display, 0); return gFalse; } return gTrue;}GBool XPDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) { if (!PDFCore::gotoPrevPage(dec, top, bottom)) { XBell(display, 0); return gFalse; } return gTrue;}GBool XPDFCore::goForward() { if (!PDFCore::goForward()) { XBell(display, 0); return gFalse; } return gTrue;}GBool XPDFCore::goBackward() { if (!PDFCore::goBackward()) { XBell(display, 0); return gFalse; } return gTrue;}void XPDFCore::startPan(int wx, int wy) { panning = gTrue; panMX = wx; panMY = wy;}void XPDFCore::endPan(int wx, int wy) { panning = gFalse;}//------------------------------------------------------------------------// selection//------------------------------------------------------------------------void XPDFCore::startSelection(int wx, int wy) { int pg, x, y; takeFocus(); if (doc && doc->getNumPages() > 0) { if (selectEnabled) { if (cvtWindowToDev(wx, wy, &pg, &x, &y)) { setSelection(pg, x, y, x, y); setCursor(selectCursor); dragging = gTrue; } } }}void XPDFCore::endSelection(int wx, int wy) { int pg, x, y; GBool ok; if (doc && doc->getNumPages() > 0) { ok = cvtWindowToDev(wx, wy, &pg, &x, &y); if (dragging) { dragging = gFalse; setCursor(None); if (ok) { moveSelection(pg, x, y); }#ifndef NO_TEXT_SELECT if (selectULX != selectLRX && selectULY != selectLRY) { if (doc->okToCopy()) { copySelection(); } else { error(-1, "Copying of text from this document is not allowed."); } }#endif } }}// X's copy-and-paste mechanism is brain damaged. Xt doesn't help// any, but doesn't make it too much worse, either. Motif, on the// other hand, adds significant complexity to the mess. So here we// blow off the Motif junk and stick to plain old Xt. The next two// functions (copySelection and convertSelectionCbk) implement the// magic needed to deal with Xt's mechanism. Note that this requires// global variables (currentSelection and currentSelectionOwner).void XPDFCore::copySelection() { int pg; double ulx, uly, lrx, lry; if (!doc->okToCopy()) { return; } if (getSelection(&pg, &ulx, &uly, &lrx, &lry)) { //~ for multithreading: need a mutex here
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -