📄 xpdfcore.cc
字号:
// add to history if (addToHist) { if (++historyCur == xpdfHistorySize) { historyCur = 0; } h = &history[historyCur]; if (h->fileName) { delete h->fileName; } h->fileName = doc->getFileName()->copy(); h->page = page; if (historyBLen < xpdfHistorySize) { ++historyBLen; } historyFLen = 0; } // update the parent window if (updateCbk) { (*updateCbk)(updateCbkData, NULL, page, -1, ""); } // allocate new GCs gcValues.foreground = BlackPixel(display, screenNum) ^ WhitePixel(display, screenNum); gcValues.function = GXxor; selectGC = XCreateGC(display, out->getPixmap(), GCForeground | GCFunction, &gcValues); highlightGC = XCreateGC(display, out->getPixmap(), GCForeground | GCFunction, &gcValues); // back to regular cursor setCursor(None);}void XPDFCore::displayDest(LinkDest *dest, int zoomA, int rotateA, GBool addToHist) { Ref pageRef; int pg; int dx, dy; if (dest->isPageRef()) { pageRef = dest->getPageRef(); pg = doc->findPage(pageRef.num, pageRef.gen); } else { pg = dest->getPageNum(); } if (pg <= 0 || pg > doc->getNumPages()) { pg = 1; } if (pg != page) { displayPage(pg, zoomA, rotateA, gTrue, addToHist); } if (fullScreen) { return; } switch (dest->getKind()) { case destXYZ: out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); if (dest->getChangeLeft() || dest->getChangeTop()) { scrollTo(dest->getChangeLeft() ? dx : scrollX, dest->getChangeTop() ? dy : scrollY); } //~ what is the zoom parameter? break; case destFit: case destFitB: //~ do fit scrollTo(0, 0); break; case destFitH: case destFitBH: //~ do fit out->cvtUserToDev(0, dest->getTop(), &dx, &dy); scrollTo(0, dy); break; case destFitV: case destFitBV: //~ do fit out->cvtUserToDev(dest->getLeft(), 0, &dx, &dy); scrollTo(dx, 0); break; case destFitR: //~ do fit out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy); scrollTo(dx, dy); break; }}//------------------------------------------------------------------------// page/position changes//------------------------------------------------------------------------void XPDFCore::gotoNextPage(int inc, GBool top) { int pg; if (!doc || doc->getNumPages() == 0) { return; } if (page < doc->getNumPages()) { if ((pg = page + inc) > doc->getNumPages()) { pg = doc->getNumPages(); } displayPage(pg, zoom, rotate, top, gTrue); } else { XBell(display, 0); }}void XPDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) { int pg; if (!doc || doc->getNumPages() == 0) { return; } if (page > 1) { if (!fullScreen && bottom) { scrollY = out->getPixmapHeight() - drawAreaHeight; if (scrollY < 0) { scrollY = 0; } // displayPage will call updateScrollBars() } if ((pg = page - dec) < 1) { pg = 1; } displayPage(pg, zoom, rotate, top, gTrue); } else { XBell(display, 0); }}void XPDFCore::goForward() { if (historyFLen == 0) { XBell(display, 0); return; } if (++historyCur == xpdfHistorySize) { historyCur = 0; } --historyFLen; ++historyBLen; if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) { if (loadFile(history[historyCur].fileName) != errNone) { XBell(display, 0); return; } } displayPage(history[historyCur].page, zoom, rotate, gFalse, gFalse);}void XPDFCore::goBackward() { if (historyBLen <= 1) { XBell(display, 0); return; } if (--historyCur < 0) { historyCur = xpdfHistorySize - 1; } --historyBLen; ++historyFLen; if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) { if (loadFile(history[historyCur].fileName) != errNone) { XBell(display, 0); return; } } displayPage(history[historyCur].page, zoom, rotate, gFalse, gFalse);}void XPDFCore::scrollLeft(int nCols) { scrollTo(scrollX - nCols * 16, scrollY);}void XPDFCore::scrollRight(int nCols) { scrollTo(scrollX + nCols * 16, scrollY);}void XPDFCore::scrollUp(int nLines) { scrollTo(scrollX, scrollY - nLines * 16);}void XPDFCore::scrollDown(int nLines) { scrollTo(scrollX, scrollY + nLines * 16);}void XPDFCore::scrollPageUp() { if (scrollY == 0) { gotoPrevPage(1, gFalse, gTrue); } else { scrollTo(scrollX, scrollY - drawAreaHeight); }}void XPDFCore::scrollPageDown() { if (scrollY >= out->getPixmapHeight() - drawAreaHeight) { gotoNextPage(1, gTrue); } else { scrollTo(scrollX, scrollY + drawAreaHeight); }}void XPDFCore::scrollTo(int x, int y) { GBool needRedraw; int maxPos, pos; needRedraw = gFalse; maxPos = out ? out->getPixmapWidth() : 1; if (maxPos < drawAreaWidth) { maxPos = drawAreaWidth; } if (x < 0) { pos = 0; } else if (x > maxPos - drawAreaWidth) { pos = maxPos - drawAreaWidth; } else { pos = x; } if (scrollX != pos) { scrollX = pos; XmScrollBarSetValues(hScrollBar, scrollX, drawAreaWidth, 16, drawAreaWidth, False); needRedraw = gTrue; } maxPos = out ? out->getPixmapHeight() : 1; if (maxPos < drawAreaHeight) { maxPos = drawAreaHeight; } if (y < 0) { pos = 0; } else if (y > maxPos - drawAreaHeight) { pos = maxPos - drawAreaHeight; } else { pos = y; } if (scrollY != pos) { scrollY = pos; XmScrollBarSetValues(vScrollBar, scrollY, drawAreaHeight, 16, drawAreaHeight, False); needRedraw = gTrue; } if (needRedraw) { redrawRectangle(scrollX, scrollY, drawAreaWidth, drawAreaHeight); }}//------------------------------------------------------------------------// selection//------------------------------------------------------------------------void XPDFCore::setSelection(int newXMin, int newYMin, int newXMax, int newYMax) { Pixmap pixmap; int x, y; GBool needRedraw, needScroll; GBool moveLeft, moveRight, moveTop, moveBottom; pixmap = out->getPixmap(); // erase old selection on off-screen bitmap needRedraw = gFalse; if (selectXMin < selectXMax && selectYMin < selectYMax) { XFillRectangle(display, pixmap, selectGC, selectXMin, selectYMin, selectXMax - selectXMin, selectYMax - selectYMin); needRedraw = gTrue; } // draw new selection on off-screen bitmap if (newXMin < newXMax && newYMin < newYMax) { XFillRectangle(display, pixmap, selectGC, newXMin, newYMin, newXMax - newXMin, newYMax - newYMin); needRedraw = gTrue; } // check which edges moved moveLeft = newXMin != selectXMin; moveTop = newYMin != selectYMin; moveRight = newXMax != selectXMax; moveBottom = newYMax != selectYMax; // redraw currently visible part of bitmap if (needRedraw) { if (moveLeft) { redrawRectangle((newXMin < selectXMin) ? newXMin : selectXMin, (newYMin < selectYMin) ? newYMin : selectYMin, (newXMin > selectXMin) ? newXMin : selectXMin, (newYMax > selectYMax) ? newYMax : selectYMax); } if (moveRight) { redrawRectangle((newXMax < selectXMax) ? newXMax : selectXMax, (newYMin < selectYMin) ? newYMin : selectYMin, (newXMax > selectXMax) ? newXMax : selectXMax, (newYMax > selectYMax) ? newYMax : selectYMax); } if (moveTop) { redrawRectangle((newXMin < selectXMin) ? newXMin : selectXMin, (newYMin < selectYMin) ? newYMin : selectYMin, (newXMax > selectXMax) ? newXMax : selectXMax, (newYMin > selectYMin) ? newYMin : selectYMin); } if (moveBottom) { redrawRectangle((newXMin < selectXMin) ? newXMin : selectXMin, (newYMax < selectYMax) ? newYMax : selectYMax, (newXMax > selectXMax) ? newXMax : selectXMax, (newYMax > selectYMax) ? newYMax : selectYMax); } } // switch to new selection coords selectXMin = newXMin; selectXMax = newXMax; selectYMin = newYMin; selectYMax = newYMax; // scroll if necessary if (fullScreen) { return; } needScroll = gFalse; x = scrollX; y = scrollY; if (moveLeft && selectXMin < x) { x = selectXMin; needScroll = gTrue; } else if (moveRight && selectXMax >= x + drawAreaWidth) { x = selectXMax - drawAreaWidth; needScroll = gTrue; } else if (moveLeft && selectXMin >= x + drawAreaWidth) { x = selectXMin - drawAreaWidth; needScroll = gTrue; } else if (moveRight && selectXMax < x) { x = selectXMax; needScroll = gTrue; } if (moveTop && selectYMin < y) { y = selectYMin; needScroll = gTrue; } else if (moveBottom && selectYMax >= y + drawAreaHeight) { y = selectYMax - drawAreaHeight; needScroll = gTrue; } else if (moveTop && selectYMin >= y + drawAreaHeight) { y = selectYMin - drawAreaHeight; needScroll = gTrue; } else if (moveBottom && selectYMax < y) { y = selectYMax; needScroll = gTrue; } if (needScroll) { scrollTo(x, y); }}void XPDFCore::moveSelection(int mx, int my) { int xMin, yMin, xMax, yMax; // clip mouse coords if (mx < 0) { mx = 0; } else if (mx >= out->getPixmapWidth()) { mx = out->getPixmapWidth() - 1; } if (my < 0) { my = 0; } else if (my >= out->getPixmapHeight()) { my = out->getPixmapHeight() - 1; } // move appropriate edges of selection if (lastDragLeft) { if (mx < selectXMax) { xMin = mx; xMax = selectXMax; } else { xMin = selectXMax; xMax = mx; lastDragLeft = gFalse; } } else { if (mx > selectXMin) { xMin = selectXMin; xMax = mx; } else { xMin = mx; xMax = selectXMin; lastDragLeft = gTrue; } } if (lastDragTop) { if (my < selectYMax) { yMin = my; yMax = selectYMax; } else { yMin = selectYMax; yMax = my; lastDragTop = gFalse; } } else { if (my > selectYMin) { yMin = selectYMin; yMax = my; } else { yMin = my; yMax = selectYMin; lastDragTop = gTrue; } } // redraw the selection setSelection(xMin, yMin, xMax, yMax);}// 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() { if (!doc->okToCopy()) { return; } if (currentSelection) { delete currentSelection; } //~ for multithreading: need a mutex here currentSelection = out->getText(selectXMin, selectYMin, selectXMax, selectYMax); 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) { if (*target != XA_STRING) { return False; } //~ for multithreading: need a mutex here *value = XtNewString(currentSelection->getCString()); *length = currentSelection->getLength(); *type = XA_STRING; *format = 8; // 8-bit elements return True;}GBool XPDFCore::getSelection(int *xMin, int *yMin, int *xMax, int *yMax) { if (selectXMin >= selectXMax || selectYMin >= selectYMax) { return gFalse; } *xMin = selectXMin; *yMin = selectYMin; *xMax = selectXMax; *yMax = selectYMax; return gTrue;}GString *XPDFCore::extractText(int xMin, int yMin, int xMax, int yMax) { if (!doc->okToCopy()) { return NULL; } return out->getText(xMin, yMin, xMax, yMax);}GString *XPDFCore::extractText(int pageNum, int xMin, int yMin, int xMax, int yMax) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -