xpdfcore.cc
来自「将pdf文档转换为高质量的html文档」· CC 代码 · 共 1,725 行 · 第 1/4 页
CC
1,725 行
//========================================================================//// 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// 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//------------------------------------------------------------------------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){ 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 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::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->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, !fullScreen && 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;}//------------------------------------------------------------------------// selection//------------------------------------------------------------------------// 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 if (currentSelection) { delete currentSelection; } currentSelection = extractText(pg, ulx, uly, lrx, lry); currentSelectionOwner = this; XtOwnSelection(drawArea, XA_PRIMARY, XtLastTimestampProcessed(display), &convertSelectionCbk, NULL, NULL); }}Boolean XPDFCore::convertSelectionCbk(Widget widget, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) { Atom *array; // send back a list of supported conversion targets if (*target == targetsAtom) { if (!(array = (Atom *)XtMalloc(sizeof(Atom)))) { return False; } array[0] = XA_STRING; *value = (XtPointer)array; *type = XA_ATOM; *format = 32; *length = 1; return True; // send the selected text } else if (*target == XA_STRING) { //~ for multithreading: need a mutex here *value = XtNewString(currentSelection->getCString()); *length = currentSelection->getLength(); *type = XA_STRING; *format = 8; // 8-bit elements return True; } return False;}//------------------------------------------------------------------------// hyperlinks//------------------------------------------------------------------------GBool XPDFCore::doLink(int pg, int x, int y) { LinkAction *action; double xu, yu;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?