📄 pdfcore.cc
字号:
//========================================================================//// PDFCore.cc//// Copyright 2004 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <math.h>#include "GString.h"#include "GList.h"#include "GlobalParams.h"#include "Splash.h"#include "SplashBitmap.h"#include "SplashPattern.h"#include "SplashPath.h"#include "Error.h"#include "ErrorCodes.h"#include "PDFDoc.h"#include "Link.h"#include "TextOutputDev.h"#include "CoreOutputDev.h"#include "PDFCore.h"//------------------------------------------------------------------------// PDFCorePage//------------------------------------------------------------------------PDFCorePage::PDFCorePage(int pageA, int wA, int hA, int tileWA, int tileHA) { page = pageA; tiles = new GList(); w = wA; h = hA; tileW = tileWA; tileH = tileHA; links = NULL; text = NULL;}PDFCorePage::~PDFCorePage() { deleteGList(tiles, PDFCoreTile); if (links) { delete links; } if (text) { delete text; }}//------------------------------------------------------------------------// PDFCoreTile//------------------------------------------------------------------------PDFCoreTile::PDFCoreTile(int xDestA, int yDestA) { xMin = 0; yMin = 0; xMax = 0; yMax = 0; xDest = xDestA; yDest = yDestA; bitmap = NULL;}PDFCoreTile::~PDFCoreTile() { if (bitmap) { delete bitmap; }}//------------------------------------------------------------------------// PDFCore//------------------------------------------------------------------------PDFCore::PDFCore(SplashColorMode colorModeA, int bitmapRowPadA, GBool reverseVideoA, SplashColorPtr paperColorA, GBool incrementalUpdate) { int i; doc = NULL; continuousMode = globalParams->getContinuousView(); drawAreaWidth = drawAreaHeight = 0; maxPageW = totalDocH = 0; pageY = NULL; topPage = 0; scrollX = scrollY = 0; zoom = defZoom; dpi = 0; rotate = 0; selectPage = 0; selectULX = selectLRX = 0; selectULY = selectLRY = 0; dragging = gFalse; lastDragLeft = lastDragTop = gTrue; historyCur = pdfHistorySize - 1; historyBLen = historyFLen = 0; for (i = 0; i < pdfHistorySize; ++i) { history[i].fileName = NULL; } pages = new GList(); curTile = NULL; splashColorCopy(paperColor, paperColorA); out = new CoreOutputDev(colorModeA, bitmapRowPadA, reverseVideoA, paperColorA, incrementalUpdate, &redrawCbk, this); out->startDoc(NULL);}PDFCore::~PDFCore() { int i; if (doc) { delete doc; } for (i = 0; i < pdfHistorySize; ++i) { if (history[i].fileName) { delete history[i].fileName; } } gfree(pageY); deleteGList(pages, PDFCorePage); delete out;}int PDFCore::loadFile(GString *fileName, GString *ownerPassword, GString *userPassword) { int err; setBusyCursor(gTrue); err = loadFile2(new PDFDoc(fileName->copy(), ownerPassword, userPassword, this)); setBusyCursor(gFalse); return err;}#ifdef WIN32int PDFCore::loadFile(wchar_t *fileName, int fileNameLen, GString *ownerPassword, GString *userPassword) { int err; setBusyCursor(gTrue); err = loadFile2(new PDFDoc(fileName, fileNameLen, ownerPassword, userPassword, this)); setBusyCursor(gFalse); return err;}#endifint PDFCore::loadFile(BaseStream *stream, GString *ownerPassword, GString *userPassword) { int err; setBusyCursor(gTrue); err = loadFile2(new PDFDoc(stream, ownerPassword, userPassword, this)); setBusyCursor(gFalse); return err;}void PDFCore::loadDoc(PDFDoc *docA) { setBusyCursor(gTrue); loadFile2(docA); setBusyCursor(gFalse);}int PDFCore::loadFile2(PDFDoc *newDoc) { int err; double w, h, t; int i; // open the PDF file if (!newDoc->isOk()) { err = newDoc->getErrorCode(); delete newDoc; return err; } // replace old document if (doc) { delete doc; } doc = newDoc; if (out) { out->startDoc(doc->getXRef()); } // nothing displayed yet topPage = -99; while (pages->getLength() > 0) { delete (PDFCorePage *)pages->del(0); } // compute the max unscaled page size maxUnscaledPageW = maxUnscaledPageH = 0; for (i = 1; i <= doc->getNumPages(); ++i) { w = doc->getPageCropWidth(i); h = doc->getPageCropHeight(i); if (doc->getPageRotate(i) == 90 || doc->getPageRotate(i) == 270) { t = w; w = h; h = t; } if (w > maxUnscaledPageW) { maxUnscaledPageW = w; } if (h > maxUnscaledPageH) { maxUnscaledPageH = h; } } return errNone;}void PDFCore::clear() { if (!doc) { return; } // no document delete doc; doc = NULL; out->clear(); // no page displayed topPage = -99; while (pages->getLength() > 0) { delete (PDFCorePage *)pages->del(0); } // redraw scrollX = scrollY = 0; redrawWindow(0, 0, drawAreaWidth, drawAreaHeight, gTrue); updateScrollbars();}PDFDoc *PDFCore::takeDoc(GBool redraw) { PDFDoc *docA; if (!doc) { return NULL; } // no document docA = doc; doc = NULL; out->clear(); // no page displayed topPage = -99; while (pages->getLength() > 0) { delete (PDFCorePage *)pages->del(0); } // redraw scrollX = scrollY = 0; if (redraw) { redrawWindow(0, 0, drawAreaWidth, drawAreaHeight, gTrue); updateScrollbars(); } return docA;}void PDFCore::displayPage(int topPageA, double zoomA, int rotateA, GBool scrollToTop, GBool addToHist) { int scrollXA, scrollYA; scrollXA = scrollX; if (continuousMode) { scrollYA = -1; } else if (scrollToTop) { scrollYA = 0; } else { scrollYA = scrollY; } if (zoomA != zoom) { scrollXA = 0; scrollYA = continuousMode ? -1 : 0; } dragging = gFalse; lastDragLeft = lastDragTop = gTrue; update(topPageA, scrollXA, scrollYA, zoomA, rotateA, gTrue, addToHist);}void PDFCore::displayDest(LinkDest *dest, double zoomA, int rotateA, GBool addToHist) { Ref pageRef; int topPageA; int dx, dy, scrollXA, scrollYA; if (dest->isPageRef()) { pageRef = dest->getPageRef(); topPageA = doc->findPage(pageRef.num, pageRef.gen); } else { topPageA = dest->getPageNum(); } if (topPageA <= 0 || topPageA > doc->getNumPages()) { topPageA = 1; } scrollXA = scrollX; scrollYA = continuousMode ? -1 : scrollY; switch (dest->getKind()) { case destXYZ: cvtUserToDev(topPageA, dest->getLeft(), dest->getTop(), &dx, &dy); scrollXA = dest->getChangeLeft() ? dx : scrollX; if (dest->getChangeTop()) { scrollYA = dy; } else { if (topPage <= 0) { scrollYA = 0; } else if (continuousMode) { scrollYA = scrollY - pageY[topPage - 1]; } else { scrollYA = scrollY; } } if (continuousMode && topPage > 0) { scrollYA += pageY[topPageA - 1]; } //~ what is the zoom parameter? break; case destFit: case destFitB: //~ do fit scrollXA = 0; scrollYA = continuousMode ? -1 : 0; break; case destFitH: case destFitBH: //~ do fit cvtUserToDev(topPageA, 0, dest->getTop(), &dx, &dy); if (continuousMode && topPage > 0) { dy += pageY[topPageA - 1]; } scrollXA = 0; scrollYA = dy; break; case destFitV: case destFitBV: //~ do fit cvtUserToDev(topPageA, dest->getLeft(), 0, &dx, &dy); scrollXA = dx; scrollYA = continuousMode ? -1 : 0; break; case destFitR: //~ do fit cvtUserToDev(topPageA, dest->getLeft(), dest->getTop(), &dx, &dy); if (continuousMode && topPage > 0) { dy += pageY[topPageA - 1]; } scrollXA = dx; scrollYA = dy; break; } update(topPageA, scrollXA, scrollYA, zoom, rotate, gFalse, addToHist && topPageA != topPage);}void PDFCore::update(int topPageA, int scrollXA, int scrollYA, double zoomA, int rotateA, GBool force, GBool addToHist) { double hDPI, vDPI, dpiA, uw, uh, ut; int w, h, t, x0, x1, y0, y1, x, y; int rot; int pg0, pg1; PDFCoreTile *tile; PDFCorePage *page; PDFHistory *hist; SplashColor xorColor; GBool needUpdate; int i, j; // check for document and valid page number if (!doc) { // save the new settings zoom = zoomA; rotate = rotateA; return; } if (topPageA <= 0 || topPageA > doc->getNumPages()) { return; } needUpdate = gFalse; // check for changes to the PDF file if ((force || (!continuousMode && topPage != topPageA)) && checkForNewFile()) { if (loadFile(doc->getFileName()) == errNone) { if (topPageA > doc->getNumPages()) { topPageA = doc->getNumPages(); } needUpdate = gTrue; } } // compute the DPI if (continuousMode) { uw = maxUnscaledPageW; uh = maxUnscaledPageH; rot = rotateA; } else { uw = doc->getPageCropWidth(topPageA); uh = doc->getPageCropHeight(topPageA); rot = rotateA + doc->getPageRotate(topPageA); if (rot >= 360) { rot -= 360; } else if (rot < 0) { rot += 360; } } if (rot == 90 || rot == 270) { ut = uw; uw = uh; uh = ut; } if (zoomA == zoomPage) { hDPI = (drawAreaWidth / uw) * 72; if (continuousMode) { vDPI = ((drawAreaHeight - continuousModePageSpacing) / uh) * 72; } else { vDPI = (drawAreaHeight / uh) * 72; } dpiA = (hDPI < vDPI) ? hDPI : vDPI; } else if (zoomA == zoomWidth) { dpiA = (drawAreaWidth / uw) * 72; } else { dpiA = 0.01 * zoomA * 72; } // this can happen if the window hasn't been sized yet if (dpiA <= 0) { dpiA = 1; } // if the display properties have changed, create a new PDFCorePage // object if (force || pages->getLength() == 0 || (!continuousMode && topPageA != topPage) || zoomA != zoom || dpiA != dpi || rotateA != rotate) { needUpdate = gTrue; setSelection(0, 0, 0, 0, 0); while (pages->getLength() > 0) { delete (PDFCorePage *)pages->del(0); } zoom = zoomA; rotate = rotateA; dpi = dpiA; if (continuousMode) { maxPageW = totalDocH = 0; pageY = (int *)greallocn(pageY, doc->getNumPages(), sizeof(int)); for (i = 1; i <= doc->getNumPages(); ++i) { pageY[i-1] = totalDocH; w = (int)((doc->getPageCropWidth(i) * dpi) / 72 + 0.5); h = (int)((doc->getPageCropHeight(i) * dpi) / 72 + 0.5); rot = rotate + doc->getPageRotate(i); if (rot >= 360) { rot -= 360; } else if (rot < 0) { rot += 360; } if (rot == 90 || rot == 270) { t = w; w = h; h = t; } if (w > maxPageW) { maxPageW = w; } totalDocH += h; if (i < doc->getNumPages()) { totalDocH += continuousModePageSpacing; } } } else { rot = rotate + doc->getPageRotate(topPageA); if (rot >= 360) { rot -= 360; } else if (rot < 0) { rot += 360; } addPage(topPageA, rot); } } else { // erase the selection if (selectULX != selectLRX && selectULY != selectLRY) { xorColor[0] = xorColor[1] = xorColor[2] = 0xff; xorRectangle(selectPage, selectULX, selectULY, selectLRX, selectLRY, new SplashSolidColor(xorColor)); } } if (continuousMode) { page = NULL; // make gcc happy } else { page = (PDFCorePage *)pages->get(0); } topPage = topPageA; // adjust the scroll position scrollX = scrollXA; if (continuousMode && scrollYA < 0) { scrollY = pageY[topPage - 1]; } else { scrollY = scrollYA; } w = continuousMode ? maxPageW : page->w; if (scrollX > w - drawAreaWidth) { scrollX = w - drawAreaWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -