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 + -
显示快捷键?