📄 textoutputdev.cc
字号:
fontSize1 > blkMaxFontSizeRatio * fontSize0) { return gFalse; } return gTrue;}// Returns true if <blk0> and <blk1> can be merged into a single// block. Assumes the y coordinates are within range.GBool TextPage::blockFit2(TextBlock *blk0, TextBlock *blk1) { double fontSize0, fontSize1; // check edges if (blk1->xMin < blk0->xSpaceL || blk1->xMax > blk0->xSpaceR || blk0->xMin < blk1->xSpaceL || blk0->xMax > blk1->xSpaceR) { return gFalse; } // check font sizes fontSize0 = blk0->lines->fontSize; fontSize1 = blk1->lines->fontSize; if (fontSize0 > blkMaxFontSizeRatio * fontSize1 || fontSize1 > blkMaxFontSizeRatio * fontSize0) { return gFalse; } return gTrue;}// Returns true if <blk> can be added to <flow>.GBool TextPage::flowFit(TextFlow *flow, TextBlock *blk) { double dy; // check whitespace above and below if (blk->yMin < flow->ySpaceT || blk->yMax > flow->ySpaceB || flow->yMin < blk->ySpaceT || flow->yMax > blk->ySpaceB) { return gFalse; } // check that block top edge is within +/- dy of flow top edge, // and that block bottom edge is above flow bottom edge + dy dy = flowMaxDeltaY * flow->blocks->maxFontSize; return blk->yMin > flow->yMin - dy && blk->yMin < flow->yMin + dy && blk->yMax < flow->yMax + dy;}GBool TextPage::findText(Unicode *s, int len, GBool top, GBool bottom, double *xMin, double *yMin, double *xMax, double *yMax) { TextLine *line; Unicode *p; Unicode u1, u2; int m, i, j; double x0, x1, x; // scan all text on the page for (line = lines; line; line = line->pageNext) { // check: above top limit? if (!top && (line->yMax < *yMin || (line->yMin < *yMin && line->xMax <= *xMin))) { continue; } // check: below bottom limit? if (!bottom && (line->yMin > *yMax || (line->yMax > *yMax && line->xMin >= *xMax))) { return gFalse; } // search each position in this line m = line->len; for (i = 0, p = line->text; i <= m - len; ++i, ++p) { x0 = (i == 0) ? line->xMin : line->xRight[i-1]; x1 = line->xRight[i]; x = 0.5 * (x0 + x1); // check: above top limit? if (!top && line->yMin < *yMin) { if (x < *xMin) { continue; } } // check: below bottom limit? if (!bottom && line->yMax > *yMax) { if (x > *xMax) { return gFalse; } } // compare the strings for (j = 0; j < len; ++j) {#if 1 //~ this lowercases Latin A-Z only -- this will eventually be //~ extended to handle other character sets if (p[j] >= 0x41 && p[j] <= 0x5a) { u1 = p[j] + 0x20; } else { u1 = p[j]; } if (s[j] >= 0x41 && s[j] <= 0x5a) { u2 = s[j] + 0x20; } else { u2 = s[j]; }#endif if (u1 != u2) { break; } } // found it if (j == len) { *xMin = x0; *xMax = line->xRight[i + len - 1]; *yMin = line->yMin; *yMax = line->yMax; return gTrue; } } } return gFalse;}GString *TextPage::getText(double xMin, double yMin, double xMax, double yMax) { GString *s; UnicodeMap *uMap; GBool isUnicode; char space[8], eol[16], buf[8]; int spaceLen, eolLen, len; TextLine *line, *prevLine; double x0, x1, y; int firstCol, col, i; GBool multiLine; s = new GString(); // get the output encoding if (!(uMap = globalParams->getTextEncoding())) { return s; } isUnicode = uMap->isUnicode(); spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); eolLen = 0; // make gcc happy switch (globalParams->getTextEOL()) { case eolUnix: eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); break; case eolDOS: eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); break; case eolMac: eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); break; } // find the leftmost column firstCol = -1; for (line = lines; line; line = line->pageNext) { if (line->yMin > yMax) { break; } if (line->yMax < yMin || line->xMax < xMin || line->xMin > xMax) { continue; } y = 0.5 * (line->yMin + line->yMax); if (y < yMin || y > yMax) { continue; } i = 0; while (1) { x0 = (i==0) ? line->xMin : line->xRight[i-1]; x1 = line->xRight[i]; if (0.5 * (x0 + x1) > xMin) { break; } ++i; } col = line->col[i]; if (firstCol < 0 || col < firstCol) { firstCol = col; } } // extract the text col = firstCol; multiLine = gFalse; for (prevLine = NULL, line = lines; line; prevLine = line, line = line->pageNext) { if (line->yMin > yMax) { break; } if (line->yMax < yMin || line->xMax < xMin || line->xMin > xMax) { continue; } y = 0.5 * (line->yMin + line->yMax); if (y < yMin || y > yMax) { continue; } i = 0; while (1) { x0 = (i==0) ? line->xMin : line->xRight[i-1]; x1 = line->xRight[i]; if (0.5 * (x0 + x1) > xMin) { break; } ++i; } // insert a return if (col > line->col[i] || (prevLine && line->yMin > prevLine->yMax - lineOverlapSlack * prevLine->fontSize)) { s->append(eol, eolLen); col = firstCol; multiLine = gTrue; } // line this block up with the correct column for (; col < line->col[i]; ++col) { s->append(space, spaceLen); } // print the portion of the line for (; i < line->len; ++i) { x0 = (i==0) ? line->xMin : line->xRight[i-1]; x1 = line->xRight[i]; if (0.5 * (x0 + x1) > xMax) { break; } len = uMap->mapUnicode(line->text[i], buf, sizeof(buf)); s->append(buf, len); col += isUnicode ? 1 : len; } } if (multiLine) { s->append(eol, eolLen); } uMap->decRefCnt(); return s;}void TextPage::dump(void *outputStream, TextOutputFunc outputFunc, GBool physLayout) { UnicodeMap *uMap; char space[8], eol[16], eop[8], buf[8]; int spaceLen, eolLen, eopLen, len; TextFlow *flow; TextLine *line; int col, d, n, i; // get the output encoding if (!(uMap = globalParams->getTextEncoding())) { return; } spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); eolLen = 0; // make gcc happy switch (globalParams->getTextEOL()) { case eolUnix: eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); break; case eolDOS: eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); break; case eolMac: eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); break; } eopLen = uMap->mapUnicode(0x0c, eop, sizeof(eop)); // output the page, maintaining the original physical layout if (physLayout || rawOrder) { col = 0; for (line = lines; line; line = line->pageNext) { // line this block up with the correct column if (!rawOrder) { for (; col < line->col[0]; ++col) { (*outputFunc)(outputStream, space, spaceLen); } } // print the line for (i = 0; i < line->len; ++i) { len = uMap->mapUnicode(line->text[i], buf, sizeof(buf)); (*outputFunc)(outputStream, buf, len); } col += line->convertedLen; // print one or more returns if necessary if (!line->pageNext || line->pageNext->col[0] < col || line->pageNext->yMin > line->yMax - lineOverlapSlack * line->fontSize) { // compute number of returns d = 1; if (line->pageNext) { d += (int)((line->pageNext->yMin - line->yMax) / line->fontSize + 0.5); } // various things (weird font matrices) can result in bogus // values here, so do a sanity check if (d < 1) { d = 1; } else if (d > 5) { d = 5; } for (; d > 0; --d) { (*outputFunc)(outputStream, eol, eolLen); } col = 0; } } // output the page, "undoing" the layout } else { for (flow = flows; flow; flow = flow->next) { for (line = flow->lines; line; line = line->flowNext) { n = line->len; if (line->flowNext && line->hyphenated) { --n; } for (i = 0; i < n; ++i) { len = uMap->mapUnicode(line->text[i], buf, sizeof(buf)); (*outputFunc)(outputStream, buf, len); } if (line->flowNext && !line->hyphenated) { (*outputFunc)(outputStream, space, spaceLen); } } (*outputFunc)(outputStream, eol, eolLen); (*outputFunc)(outputStream, eol, eolLen); } } // end of page (*outputFunc)(outputStream, eop, eopLen); (*outputFunc)(outputStream, eol, eolLen); uMap->decRefCnt();}void TextPage::startPage(GfxState *state) { clear(); pageWidth = state->getPageWidth(); pageHeight = state->getPageHeight();}void TextPage::clear() { TextWord *w1, *w2; TextFlow *f1, *f2; if (curWord) { delete curWord; curWord = NULL; } if (words) { for (w1 = words; w1; w1 = w2) { w2 = w1->next; delete w1; } } else if (flows) { for (f1 = flows; f1; f1 = f2) { f2 = f1->next; delete f1; } } deleteGList(fonts, TextFontInfo); curWord = NULL; font = NULL; fontSize = 0; nest = 0; nTinyChars = 0; words = wordPtr = NULL; lines = NULL; flows = NULL; fonts = new GList();}//------------------------------------------------------------------------// TextOutputDev//------------------------------------------------------------------------static void outputToFile(void *stream, char *text, int len) { fwrite(text, 1, len, (FILE *)stream);}TextOutputDev::TextOutputDev(char *fileName, GBool physLayoutA, GBool rawOrderA, GBool append) { text = NULL; physLayout = physLayoutA; rawOrder = rawOrderA; ok = gTrue; // open file needClose = gFalse; if (fileName) { if (!strcmp(fileName, "-")) { outputStream = stdout; } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { needClose = gTrue; } else { error(-1, "Couldn't open text file '%s'", fileName); ok = gFalse; return; } outputFunc = &outputToFile; } else { outputStream = NULL; } // set up text object text = new TextPage(rawOrderA);}TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream, GBool physLayoutA, GBool rawOrderA) { outputFunc = func; outputStream = stream; needClose = gFalse; physLayout = physLayoutA; rawOrder = rawOrderA; text = new TextPage(rawOrderA); ok = gTrue;}TextOutputDev::~TextOutputDev() { if (needClose) {#ifdef MACOS ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle);#endif fclose((FILE *)outputStream); } if (text) { delete text; }}void TextOutputDev::startPage(int pageNum, GfxState *state) { text->startPage(state);}void TextOutputDev::endPage() { text->coalesce(); if (outputStream) { text->dump(outputStream, outputFunc, physLayout); }}void TextOutputDev::updateFont(GfxState *state) { text->updateFont(state);}void TextOutputDev::beginString(GfxState *state, GString *s) { text->beginWord(state, state->getCurX(), state->getCurY());}void TextOutputDev::endString(GfxState *state) { text->endWord();}void TextOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode c, Unicode *u, int uLen) { text->addChar(state, x, y, dx, dy, c, u, uLen);}GBool TextOutputDev::findText(Unicode *s, int len, GBool top, GBool bottom, double *xMin, double *yMin, double *xMax, double *yMax) { return text->findText(s, len, top, bottom, xMin, yMin, xMax, yMax);}GString *TextOutputDev::getText(double xMin, double yMin, double xMax, double yMax) { return text->getText(xMin, yMin, xMax, yMax);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -