📄 pdfcore.cc
字号:
} if (yi + hi > tile->bitmap->getHeight()) { hi = tile->bitmap->getHeight() - yi; } updateTileData(tile, xi, yi, wi, hi, gTrue); } } } delete pattern;}GBool PDFCore::getSelection(int *pg, double *ulx, double *uly, double *lrx, double *lry) { if (selectULX == selectLRX || selectULY == selectLRY) { return gFalse; } *pg = selectPage; cvtDevToUser(selectPage, selectULX, selectULY, ulx, uly); cvtDevToUser(selectPage, selectLRX, selectLRY, lrx, lry); return gTrue;}GString *PDFCore::extractText(int pg, double xMin, double yMin, double xMax, double yMax) { PDFCorePage *page; TextOutputDev *textOut; int x0, y0, x1, y1, t; GString *s; if (!doc->okToCopy()) { return NULL; } if ((page = findPage(pg))) { cvtUserToDev(pg, xMin, yMin, &x0, &y0); cvtUserToDev(pg, xMax, yMax, &x1, &y1); if (x0 > x1) { t = x0; x0 = x1; x1 = t; } if (y0 > y1) { t = y0; y0 = y1; y1 = t; } s = page->text->getText(x0, y0, x1, y1); } else { textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); if (textOut->isOk()) { doc->displayPage(textOut, pg, dpi, dpi, rotate, gFalse, gTrue, gFalse); textOut->cvtUserToDev(xMin, yMin, &x0, &y0); textOut->cvtUserToDev(xMax, yMax, &x1, &y1); if (x0 > x1) { t = x0; x0 = x1; x1 = t; } if (y0 > y1) { t = y0; y0 = y1; y1 = t; } s = textOut->getText(x0, y0, x1, y1); } else { s = new GString(); } delete textOut; } return s;}GBool PDFCore::find(char *s, GBool caseSensitive, GBool next, GBool backward, GBool onePageOnly) { Unicode *u; int len, i; GBool ret; // convert to Unicode len = strlen(s); u = (Unicode *)gmallocn(len, sizeof(Unicode)); for (i = 0; i < len; ++i) { u[i] = (Unicode)(s[i] & 0xff); } ret = findU(u, len, caseSensitive, next, backward, onePageOnly); gfree(u); return ret;}GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive, GBool next, GBool backward, GBool onePageOnly) { TextOutputDev *textOut; double xMin, yMin, xMax, yMax; PDFCorePage *page; PDFCoreTile *tile; int pg; GBool startAtTop, startAtLast, stopAtLast; // check for zero-length string if (len == 0) { return gFalse; } setBusyCursor(gTrue); // search current page starting at previous result, current // selection, or top/bottom of page startAtTop = startAtLast = gFalse; xMin = yMin = xMax = yMax = 0; pg = topPage; if (next) { startAtLast = gTrue; } else if (selectULX != selectLRX && selectULY != selectLRY) { pg = selectPage; if (backward) { xMin = selectULX - 1; yMin = selectULY - 1; } else { xMin = selectULX + 1; yMin = selectULY + 1; } } else { startAtTop = gTrue; } if (!(page = findPage(pg))) { displayPage(pg, zoom, rotate, gTrue, gFalse); page = findPage(pg); } if (page->text->findText(u, len, startAtTop, gTrue, startAtLast, gFalse, caseSensitive, backward, &xMin, &yMin, &xMax, &yMax)) { goto found; } if (!onePageOnly) { // search following/previous pages textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); if (!textOut->isOk()) { delete textOut; goto notFound; } for (pg = backward ? pg - 1 : pg + 1; backward ? pg >= 1 : pg <= doc->getNumPages(); pg += backward ? -1 : 1) { doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse); if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse, caseSensitive, backward, &xMin, &yMin, &xMax, &yMax)) { delete textOut; goto foundPage; } } // search previous/following pages for (pg = backward ? doc->getNumPages() : 1; backward ? pg > topPage : pg < topPage; pg += backward ? -1 : 1) { doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse); if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse, caseSensitive, backward, &xMin, &yMin, &xMax, &yMax)) { delete textOut; goto foundPage; } } delete textOut; } // search current page ending at previous result, current selection, // or bottom/top of page if (!startAtTop) { xMin = yMin = xMax = yMax = 0; if (next) { stopAtLast = gTrue; } else { stopAtLast = gFalse; xMax = selectLRX; yMax = selectLRY; } if (page->text->findText(u, len, gTrue, gFalse, gFalse, stopAtLast, caseSensitive, backward, &xMin, &yMin, &xMax, &yMax)) { goto found; } } // not found notFound: setBusyCursor(gFalse); return gFalse; // found on a different page foundPage: update(pg, scrollX, continuousMode ? -1 : 0, zoom, rotate, gFalse, gTrue); page = findPage(pg); if (!page->text->findText(u, len, gTrue, gTrue, gFalse, gFalse, caseSensitive, backward, &xMin, &yMin, &xMax, &yMax)) { // this can happen if coalescing is bad goto notFound; } // found: change the selection found: tile = (PDFCoreTile *)page->tiles->get(0); setSelection(pg, (int)floor(xMin), (int)floor(yMin), (int)ceil(xMax), (int)ceil(yMax)); setBusyCursor(gFalse); return gTrue;}GBool PDFCore::cvtWindowToUser(int xw, int yw, int *pg, double *xu, double *yu) { PDFCorePage *page; PDFCoreTile *tile; int i; for (i = 0; i < pages->getLength(); ++i) { page = (PDFCorePage *)pages->get(i); if (xw >= page->xDest && xw < page->xDest + page->w && yw >= page->yDest && yw < page->yDest + page->h) { tile = (PDFCoreTile *)page->tiles->get(0); *pg = page->page; xw -= tile->xDest; yw -= tile->yDest; *xu = tile->ictm[0] * xw + tile->ictm[2] * yw + tile->ictm[4]; *yu = tile->ictm[1] * xw + tile->ictm[3] * yw + tile->ictm[5]; return gTrue; } } *pg = 0; *xu = *yu = 0; return gFalse;}GBool PDFCore::cvtWindowToDev(int xw, int yw, int *pg, int *xd, int *yd) { PDFCorePage *page; int i; for (i = 0; i < pages->getLength(); ++i) { page = (PDFCorePage *)pages->get(i); if (xw >= page->xDest && xw < page->xDest + page->w && yw >= page->yDest && yw < page->yDest + page->h) { *pg = page->page; *xd = xw - page->xDest; *yd = yw - page->yDest; return gTrue; } } *pg = 0; *xd = *yd = 0; return gFalse;}void PDFCore::cvtUserToWindow(int pg, double xu, double yu, int *xw, int *yw) { PDFCorePage *page; PDFCoreTile *tile; if ((page = findPage(pg)) && page->tiles->getLength() > 0) { tile = (PDFCoreTile *)page->tiles->get(0); } else if (curTile && curPage->page == pg) { tile = curTile; } else { tile = NULL; } if (tile) { *xw = tile->xDest + (int)(tile->ctm[0] * xu + tile->ctm[2] * yu + tile->ctm[4] + 0.5); *yw = tile->yDest + (int)(tile->ctm[1] * xu + tile->ctm[3] * yu + tile->ctm[5] + 0.5); } else { // this should never happen *xw = *yw = 0; }}void PDFCore::cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd) { PDFCorePage *page; PDFCoreTile *tile; double ctm[6]; if ((page = findPage(pg)) && page->tiles->getLength() > 0) { tile = (PDFCoreTile *)page->tiles->get(0); } else if (curTile && curPage->page == pg) { tile = curTile; } else { tile = NULL; } if (tile) { *xd = (int)(tile->xMin + tile->ctm[0] * xu + tile->ctm[2] * yu + tile->ctm[4] + 0.5); *yd = (int)(tile->yMin + tile->ctm[1] * xu + tile->ctm[3] * yu + tile->ctm[5] + 0.5); } else { doc->getCatalog()->getPage(pg)->getDefaultCTM(ctm, dpi, dpi, rotate, gFalse, out->upsideDown()); *xd = (int)(ctm[0] * xu + ctm[2] * yu + ctm[4] + 0.5); *yd = (int)(ctm[1] * xu + ctm[3] * yu + ctm[5] + 0.5); }}void PDFCore::cvtDevToWindow(int pg, int xd, int yd, int *xw, int *yw) { PDFCorePage *page; if ((page = findPage(pg))) { *xw = page->xDest + xd; *yw = page->yDest + yd; } else { // this should never happen *xw = *yw = 0; }}void PDFCore::cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu) { PDFCorePage *page; PDFCoreTile *tile; if ((page = findPage(pg)) && page->tiles->getLength() > 0) { tile = (PDFCoreTile *)page->tiles->get(0); } else if (curTile && curPage->page == pg) { tile = curTile; } else { tile = NULL; } if (tile) { xd -= tile->xMin; yd -= tile->yMin; *xu = tile->ictm[0] * xd + tile->ictm[2] * yd + tile->ictm[4]; *yu = tile->ictm[1] * xd + tile->ictm[3] * yd + tile->ictm[5]; } else { // this should never happen *xu = *yu = 0; }}void PDFCore::setReverseVideo(GBool reverseVideoA) { out->setReverseVideo(reverseVideoA); update(topPage, scrollX, scrollY, zoom, rotate, gTrue, gFalse);}LinkAction *PDFCore::findLink(int pg, double x, double y) { PDFCorePage *page; if ((page = findPage(pg))) { return page->links ? page->links->find(x, y) : (LinkAction *)NULL; } return NULL;}PDFCorePage *PDFCore::findPage(int pg) { PDFCorePage *page; int i; for (i = 0; i < pages->getLength(); ++i) { page = (PDFCorePage *)pages->get(i); if (page->page == pg) { return page; } } return NULL;}void PDFCore::redrawCbk(void *data, int x0, int y0, int x1, int y1, GBool composited) { PDFCore *core = (PDFCore *)data; core->curTile->bitmap = core->out->getBitmap(); // the default CTM is set by the Gfx constructor; tile->ctm is // needed by the coordinate conversion functions (which may be // called during redraw) memcpy(core->curTile->ctm, core->out->getDefCTM(), 6 * sizeof(double)); memcpy(core->curTile->ictm, core->out->getDefICTM(), 6 * sizeof(double)); // the bitmap created by Gfx and SplashOutputDev can be a slightly // different size due to rounding errors if (x1 >= core->curTile->xMax) { x1 = core->curTile->xMax - 1; } if (y1 >= core->curTile->yMax) { y1 = core->curTile->yMax - 1; } core->clippedRedrawRect(core->curTile, x0, y0, core->curTile->xDest + x0, core->curTile->yDest + y0, x1 - x0 + 1, y1 - y0 + 1, 0, 0, core->drawAreaWidth, core->drawAreaHeight, gTrue, composited);}void PDFCore::redrawWindow(int x, int y, int width, int height, GBool needUpdate) { PDFCorePage *page; PDFCoreTile *tile; int xDest, yDest, w, i, j; if (pages->getLength() == 0) { redrawRect(NULL, 0, 0, x, y, width, height, gTrue); return; } for (i = 0; i < pages->getLength(); ++i) { page = (PDFCorePage *)pages->get(i); for (j = 0; j < page->tiles->getLength(); ++j) { tile = (PDFCoreTile *)page->tiles->get(j); if (tile->edges & pdfCoreTileTopEdge) { if (tile->edges & pdfCoreTileLeftEdge) { xDest = 0; } else { xDest = tile->xDest; } if (tile->edges & pdfCoreTileRightEdge) { w = drawAreaWidth - xDest; } else { w = tile->xDest + (tile->xMax - tile->xMin) - xDest; } clippedRedrawRect(NULL, 0, 0, xDest, 0, w, tile->yDest, x, y, width, height, gFalse); } if (tile->edges & pdfCoreTileBottomEdge) { if (tile->edges & pdfCoreTileLeftEdge) { xDest = 0; } else { xDest = tile->xDest; } if (tile->edges & pdfCoreTileRightEdge) { w = drawAreaWidth - xDest; } else { w = tile->xDest + (tile->xMax - tile->xMin) - xDest; } yDest = tile->yDest + (tile->yMax - tile->yMin); clippedRedrawRect(NULL, 0, 0, xDest, yDest, w, drawAreaHeight - yDest, x, y, width, height, gFalse); } else if ((tile->edges & pdfCoreTileBottomSpace) && i+1 < pages->getLength()) { if (tile->edges & pdfCoreTileLeftEdge) { xDest = 0; } else { xDest = tile->xDest; } if (tile->edges & pdfCoreTileRightEdge) { w = drawAreaWidth - xDest; } else { w = tile->xDest + (tile->xMax - tile->xMin) - xDest; } yDest = tile->yDest + (tile->yMax - tile->yMin); clippedRedrawRect(NULL, 0, 0, xDest, yDest, w, ((PDFCorePage *)pages->get(i+1))->yDest - yDest, x, y, width, height, gFalse); } if (tile->edges & pdfCoreTileLeftEdge) { clippedRedrawRect(NULL, 0, 0, 0, tile->yDest, tile->xDest, tile->yMax - tile->yMin, x, y, width, height, gFalse); } if (tile->edges & pdfCoreTileRightEdge) { xDest = tile->xDest + (tile->xMax - tile->xMin); clippedRedrawRect(NULL, 0, 0, xDest, tile->yDest, drawAreaWidth - xDest, tile->yMax - tile->yMin, x, y, width, height, gFalse); } clippedRedrawRect(tile, 0, 0, tile->xDest, tile->yDest, tile->bitmap->getWidth(), tile->bitmap->getHeight(), x, y, width, height, needUpdate); } }}PDFCoreTile *PDFCore::newTile(int xDestA, int yDestA) { return new PDFCoreTile(xDestA, yDestA);}void PDFCore::updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc, int width, int height, GBool composited) {}void PDFCore::clippedRedrawRect(PDFCoreTile *tile, int xSrc, int ySrc, int xDest, int yDest, int width, int height, int xClip, int yClip, int wClip, int hClip, GBool needUpdate, GBool composited) { if (tile && needUpdate) { updateTileData(tile, xSrc, ySrc, width, height, composited); } if (xDest < xClip) { xSrc += xClip - xDest; width -= xClip - xDest; xDest = xClip; } if (xDest + width > xClip + wClip) { width = xClip + wClip - xDest; } if (yDest < yClip) { ySrc += yClip - yDest; height -= yClip - yDest; yDest = yClip; } if (yDest + height > yClip + hClip) { height = yClip + hClip - yDest; } if (width > 0 && height > 0) { redrawRect(tile, xSrc, ySrc, xDest, yDest, width, height, composited); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -