From 3b309f44aa13103c8317af2160991207e5d96d78 Mon Sep 17 00:00:00 2001 From: Claudius Korzen Date: Wed, 4 Oct 2023 15:39:26 +0200 Subject: [PATCH] Round the coordinates of elements on creating the elements, and nowhere else. --- src/PdfParsing.cpp | 137 +++++++++++++------- src/TextBlocksDetection.cpp | 5 +- src/TextLinesDetection.cpp | 3 +- src/Types.cpp | 16 +-- src/WordsStatisticsCalculation.cpp | 8 +- src/serializers/JsonlSerializer.cpp | 44 +++---- src/utils/TextBlocksDetectionUtils.cpp | 10 +- test/utils/TextBlocksDetectionUtilsTest.cpp | 93 +++++++------ test/utils/TextLinesDetectionUtilsTest.cpp | 9 +- test/utils/WordsDetectionUtilsTest.cpp | 51 ++++---- 10 files changed, 198 insertions(+), 178 deletions(-) diff --git a/src/PdfParsing.cpp b/src/PdfParsing.cpp index 338227f..a2d8cd5 100755 --- a/src/PdfParsing.cpp +++ b/src/PdfParsing.cpp @@ -88,7 +88,15 @@ void PdfParsing::startPage(int pageNum, GfxState* state, XRef* xref) { _page = new PdfPage(); _page->pageNum = _p = pageNum; + state->getClipBBox(&_page->clipLeftX, &_page->clipUpperY, &_page->clipRightX, &_page->clipLowerY); + + // Round the coordinates of the page's clip box. + _page->clipLeftX = round(_page->clipLeftX, _config.coordinatePrecision); + _page->clipUpperY = round(_page->clipUpperY, _config.coordinatePrecision); + _page->clipRightX = round(_page->clipRightX, _config.coordinatePrecision); + _page->clipLowerY = round(_page->clipLowerY, _config.coordinatePrecision); + _doc->pages.push_back(_page); _xref = xref; @@ -349,10 +357,11 @@ void PdfParsing::drawChar(GfxState* state, double x, double y, double dx, double double descent = _fontInfo ? _fontInfo->descent * transformedFontSize : 0; // Compute leftX, upperY, rightX, lowerY dependent on the writing mode and rotation. - ch->pos->leftX = x0 - transformedFontSize; - ch->pos->upperY = y0 - transformedFontSize; - ch->pos->rightX = x0; - ch->pos->lowerY = y0; + double posLeftX = x0 - transformedFontSize; + double posUpperY = y0 - transformedFontSize; + double posRightX = x0; + double posLowerY = y0; + double base = 0; int wMode = gfxFont->getWMode(); if (wMode) { // vertical writing mode @@ -360,53 +369,53 @@ void PdfParsing::drawChar(GfxState* state, double x, double y, double dx, double case 0: break; case 1: - ch->pos->leftX = x0; - ch->pos->upperY = y0 - transformedFontSize; - ch->pos->rightX = x0 + transformedFontSize; - ch->pos->lowerY = y0; + posLeftX = x0; + posUpperY = y0 - transformedFontSize; + posRightX = x0 + transformedFontSize; + posLowerY = y0; break; case 2: - ch->pos->leftX = x0; - ch->pos->upperY = y0; - ch->pos->rightX = x0 + transformedFontSize; - ch->pos->lowerY = y0 + transformedFontSize; + posLeftX = x0; + posUpperY = y0; + posRightX = x0 + transformedFontSize; + posLowerY = y0 + transformedFontSize; break; case 3: - ch->pos->leftX = x0 - transformedFontSize; - ch->pos->upperY = y0; - ch->pos->rightX = x0; - ch->pos->lowerY = y0 + transformedFontSize; + posLeftX = x0 - transformedFontSize; + posUpperY = y0; + posRightX = x0; + posLowerY = y0 + transformedFontSize; break; } } else { // horizontal writing mode switch (ch->pos->rotation) { case 0: - ch->pos->leftX = x0; - ch->pos->upperY = y0 - ascent; - ch->pos->rightX = x0 + (x1 - x0); - ch->pos->lowerY = y0 - descent; - ch->base = y0; + posLeftX = x0; + posUpperY = y0 - ascent; + posRightX = x0 + (x1 - x0); + posLowerY = y0 - descent; + base = y0; break; case 1: - ch->pos->leftX = x0 + descent; - ch->pos->upperY = y0; - ch->pos->rightX = x0 + ascent; - ch->pos->lowerY = y0 + (y1 - y0); - ch->base = x0; + posLeftX = x0 + descent; + posUpperY = y0; + posRightX = x0 + ascent; + posLowerY = y0 + (y1 - y0); + base = x0; break; case 2: - ch->pos->leftX = x0; - ch->pos->upperY = y0 + descent; - ch->pos->rightX = x0 + (x1 - x0); - ch->pos->lowerY = y0 + ascent; - ch->base = y0; + posLeftX = x0; + posUpperY = y0 + descent; + posRightX = x0 + (x1 - x0); + posLowerY = y0 + ascent; + base = y0; break; case 3: - ch->pos->leftX = x0 - ascent; - ch->pos->upperY = y0 + (y1 - y0); - ch->pos->rightX = x0 - descent; - ch->pos->lowerY = y0; - ch->base = x0; + posLeftX = x0 - ascent; + posUpperY = y0 + (y1 - y0); + posRightX = x0 - descent; + posLowerY = y0; + base = x0; break; } } @@ -437,20 +446,28 @@ void PdfParsing::drawChar(GfxState* state, double x, double y, double dx, double // Update the bounding box when the alternative bounding box has a larger vertical extent. double tolerance = _config.coordsEqualTolerance; - if (smaller(upperY, ch->pos->upperY, tolerance) || larger(lowerY, ch->pos->lowerY, tolerance)) { - ch->pos->leftX = leftX; - ch->pos->upperY = upperY; - ch->pos->rightX = rightX; - ch->pos->lowerY = lowerY; - ch->base = lowerY; + if (smaller(upperY, posUpperY, tolerance) || larger(lowerY, posLowerY, tolerance)) { + posLeftX = leftX; + posUpperY = upperY; + posRightX = rightX; + posLowerY = lowerY; + base = lowerY; } } + // Round the coordinates of the character's bounding box. + ch->pos->leftX = round(posLeftX, _config.coordinatePrecision); + ch->pos->upperY = round(posUpperY, _config.coordinatePrecision); + ch->pos->rightX = round(posRightX, _config.coordinatePrecision); + ch->pos->lowerY = round(posLowerY, _config.coordinatePrecision); + ch->base = round(base, _config.coordinatePrecision); + _log->debug(_p) << " • char.leftX: " << ch->pos->leftX << endl; _log->debug(_p) << " • char.upperY: " << ch->pos->upperY << endl; _log->debug(_p) << " • char.rightX: " << ch->pos->rightX << endl; _log->debug(_p) << " • char.lowerY: " << ch->pos->lowerY << endl; _log->debug(_p) << " • char.base: " << ch->base << endl; + if (ch->pos->rotation > 0) { _log->debug(_p) << " • char.rotLeftX: " << ch->pos->getRotLeftX() << endl; _log->debug(_p) << " • char.rotUpperY: " << ch->pos->getRotUpperY() << endl; @@ -506,6 +523,12 @@ void PdfParsing::drawChar(GfxState* state, double x, double y, double dx, double double clipLeftX, clipUpperY, clipRightX, clipLowerY; state->getClipBBox(&clipLeftX, &clipUpperY, &clipRightX, &clipLowerY); + // Round the coordinates of the clip box. + clipLeftX = round(clipLeftX, _config.coordinatePrecision); + clipUpperY = round(clipUpperY, _config.coordinatePrecision); + clipRightX = round(clipRightX, _config.coordinatePrecision); + clipLowerY = round(clipLowerY, _config.coordinatePrecision); + _log->debug(_p) << " • clipbox: leftX: " << clipLeftX << "; upperY: " << clipUpperY << "; rightX: " << clipRightX << "; lowerY: " << clipLowerY << endl; @@ -579,6 +602,12 @@ void PdfParsing::stroke(GfxState* state) { double clipLeftX, clipUpperY, clipRightX, clipLowerY; state->getClipBBox(&clipLeftX, &clipUpperY, &clipRightX, &clipLowerY); + // Round the coordinates of the clip box. + clipLeftX = round(clipLeftX, _config.coordinatePrecision); + clipUpperY = round(clipUpperY, _config.coordinatePrecision); + clipRightX = round(clipRightX, _config.coordinatePrecision); + clipLowerY = round(clipLowerY, _config.coordinatePrecision); + // Iterate through each subpath and each point, for compute the bounding box of the path. double x, y; double leftX = numeric_limits::max(); @@ -591,6 +620,8 @@ void PdfParsing::stroke(GfxState* state) { for (int j = 0; j < subpath->getNumPoints(); j++) { state->transform(subpath->getX(j), subpath->getY(j), &x, &y); + x = round(x, _config.coordinatePrecision); + y = round(y, _config.coordinatePrecision); // Ignore points that lies outside the clip box (points outside the clip box are not visible). // TODO(korzen): This is dangerous, since we may ignore a path that is actually visible, for @@ -616,10 +647,10 @@ void PdfParsing::stroke(GfxState* state) { shape->id = createRandomString(_config.idLength, "shape-"); shape->doc = _doc; shape->pos->pageNum = _page->pageNum; - shape->pos->leftX = leftX; - shape->pos->upperY = upperY; - shape->pos->rightX = rightX; - shape->pos->lowerY = lowerY; + shape->pos->leftX = round(leftX, _config.coordinatePrecision); + shape->pos->upperY = round(upperY, _config.coordinatePrecision); + shape->pos->rightX = round(rightX, _config.coordinatePrecision); + shape->pos->lowerY = round(lowerY, _config.coordinatePrecision); shape->rank = _numElements++; _log->debug(_p) << " • shape.id: " << shape->id << endl; @@ -743,12 +774,18 @@ void PdfParsing::drawGraphic(GfxState* state) { double clipLeftX, clipUpperY, clipRightX, clipLowerY; state->getClipBBox(&clipLeftX, &clipUpperY, &clipRightX, &clipLowerY); + // Round the coordinates of the clip box. + clipLeftX = round(clipLeftX, _config.coordinatePrecision); + clipUpperY = round(clipUpperY, _config.coordinatePrecision); + clipRightX = round(clipRightX, _config.coordinatePrecision); + clipLowerY = round(clipLowerY, _config.coordinatePrecision); + // Compute the bounding box of the graphic from the current transformation matrix. const double* ctm = state->getCTM(); - double leftX = ctm[4]; // ctm[4] = translateX - double upperY = ctm[5]; // ctm[5] = translateY - double rightX = leftX + ctm[0]; // ctm[0] = scaleX - double lowerY = upperY + ctm[3]; // ctm[3] = scaleY + double leftX = round(ctm[4], _config.coordinatePrecision); // ctm[4] = translateX + double upperY = round(ctm[5], _config.coordinatePrecision); // ctm[5] = translateY + double rightX = round(leftX + ctm[0], _config.coordinatePrecision); // ctm[0] = scaleX + double lowerY = round(upperY + ctm[3], _config.coordinatePrecision); // ctm[3] = scaleY // Ignore the graphic if it lies outside the clip box (since graphics outside the clip box are // not visible). Example PDF where a graphic lies outside the clip box: 1001.5159. diff --git a/src/TextBlocksDetection.cpp b/src/TextBlocksDetection.cpp index 0d517e5..50e40ce 100755 --- a/src/TextBlocksDetection.cpp +++ b/src/TextBlocksDetection.cpp @@ -434,10 +434,9 @@ Trool TextBlocksDetection::startsBlock_lineDistance(const PdfTextLine* line) con const PdfTextLine* prevLine = line->prevLine; // Compute the expected line distance. - double fontSize = round(line->fontSize, _config->fontSizePrecision); double expectedLineDistance = 0; - if (_doc->mostFreqLineDistancePerFontSize.count(fontSize) > 0) { - double eld = _doc->mostFreqLineDistancePerFontSize.at(fontSize); + if (_doc->mostFreqLineDistancePerFontSize.count(line->fontSize) > 0) { + double eld = _doc->mostFreqLineDistancePerFontSize.at(line->fontSize); expectedLineDistance = maximum(expectedLineDistance, eld); } expectedLineDistance = maximum(expectedLineDistance, _doc->mostFreqLineDistance); diff --git a/src/TextLinesDetection.cpp b/src/TextLinesDetection.cpp index eb6ad18..8e56ad5 100755 --- a/src/TextLinesDetection.cpp +++ b/src/TextLinesDetection.cpp @@ -56,7 +56,6 @@ using ppp::utils::log::Logger; using ppp::utils::math::equalOrLarger; using ppp::utils::math::maximum; using ppp::utils::math::minimum; -using ppp::utils::math::round; using ppp::utils::text::createRandomString; // ================================================================================================= @@ -146,7 +145,7 @@ void TextLinesDetection::process() { } double rotation = word->pos->rotation; - double lowerY = round(word->pos->getRotLowerY(), _config->coordinatePrecision); + double lowerY = word->pos->getRotLowerY(); clusters[rotation][lowerY].push_back(word); _log->debug(p) << q << "cluster: (" << rotation << ", " << lowerY << ")" << endl; diff --git a/src/Types.cpp b/src/Types.cpp index e093069..3a82720 100644 --- a/src/Types.cpp +++ b/src/Types.cpp @@ -132,10 +132,10 @@ string PdfPosition::toString() const { stringstream ss; ss << "PdfPosition(" << "page=" << pageNum << "; " - << "leftX=" << round(leftX, 1) << "; " - << "upperY=" << round(upperY, 1) << "; " - << "rightX=" << round(rightX, 1) << "; " - << "lowerY=" << round(lowerY, 1) << "; " + << "leftX=" << leftX << "; " + << "upperY=" << upperY << "; " + << "rightX=" << rightX << "; " + << "lowerY=" << lowerY << "; " << "rotation=" << rotation << "; " << "wMode=" << wMode << ")"; return ss.str(); @@ -145,10 +145,10 @@ string PdfPosition::toString() const { string PdfPosition::toShortString() const { stringstream ss; ss << "p=" << pageNum - << "; leftX=" << round(leftX, 1) - << "; upperY=" << round(upperY, 1) - << "; rightX=" << round(rightX, 1) - << "; lowerY=" << round(lowerY, 1); + << "; leftX=" << leftX + << "; upperY=" << upperY + << "; rightX=" << rightX + << "; lowerY=" << lowerY; return ss.str(); } diff --git a/src/WordsStatisticsCalculation.cpp b/src/WordsStatisticsCalculation.cpp index 6f8e611..4259054 100755 --- a/src/WordsStatisticsCalculation.cpp +++ b/src/WordsStatisticsCalculation.cpp @@ -31,7 +31,6 @@ using ppp::utils::log::Logger; using ppp::utils::math::equal; using ppp::utils::math::equalOrLarger; using ppp::utils::math::equalOrSmaller; -using ppp::utils::math::round; using ppp::utils::math::smaller; // ================================================================================================= @@ -84,10 +83,7 @@ void WordsStatisticsCalculation::process() const { } // Count the word height. - // TODO(korzen): The height should not be rounded here, but on creating the word. Remove - // _coordinatePrecision if not necessary anymore. - double height = round(word->pos->getHeight(), _config->coordinatePrecision); - wordHeightCounter[height]++; + wordHeightCounter[word->pos->getHeight()]++; // Skip to the next word if there is no previous word. if (!prevWord) { @@ -116,7 +112,6 @@ void WordsStatisticsCalculation::process() const { // when one word vertically overlaps at least the half of the height of the other word. if (equalOrLarger(maxYOverlapRatio, minYOverlapRatioSameLine)) { double gap = computeHorizontalGap(prevWord, word); - gap = round(gap, _config->coordinatePrecision); horizontalGapCounter[gap]++; } @@ -124,7 +119,6 @@ void WordsStatisticsCalculation::process() const { // they do *not* vertically overlap. if (equalOrSmaller(maxYOverlapRatio, maxYOverlapRatioDiffLine)) { double gap = computeVerticalGap(prevWord, word); - gap = round(gap, _config->coordinatePrecision); verticalGapCounter[gap]++; } } diff --git a/src/serializers/JsonlSerializer.cpp b/src/serializers/JsonlSerializer.cpp index fe08fdc..f5431c3 100755 --- a/src/serializers/JsonlSerializer.cpp +++ b/src/serializers/JsonlSerializer.cpp @@ -89,8 +89,8 @@ void JsonlSerializer::serializePages(const PdfDocument* doc, out << "{" << "\"type\": \"page\", " << "\"num\": " << page->pageNum << ", " - << "\"width\": " << round(page->getWidth(), _coordsPrecision) << ", " - << "\"height\": " << round(page->getHeight(), _coordsPrecision) << ", " + << "\"width\": " << page->getWidth() << ", " + << "\"height\": " << page->getHeight() << ", " << "\"origin\": \"pdftotext++\"" << "}" << endl; @@ -129,10 +129,10 @@ void JsonlSerializer::serializeCharacters(const PdfDocument* doc, << "\"id\": \"" << c->id << "\", " << "\"rank\": " << c->rank << ", " << "\"page\": " << c->pos->pageNum << ", " - << "\"minX\": " << round(c->pos->leftX, _coordsPrecision) << ", " - << "\"minY\": " << round(c->pos->upperY, _coordsPrecision) << ", " - << "\"maxX\": " << round(c->pos->rightX, _coordsPrecision) << ", " - << "\"maxY\": " << round(c->pos->lowerY, _coordsPrecision) << ", " + << "\"minX\": " << c->pos->leftX << ", " + << "\"minY\": " << c->pos->upperY << ", " + << "\"maxX\": " << c->pos->rightX << ", " + << "\"maxY\": " << c->pos->lowerY << ", " << "\"wMode\": " << c->pos->wMode << ", " << "\"rotation\": " << c->pos->rotation << ", " << "\"font\": \"" << c->fontName << "\", " @@ -167,10 +167,10 @@ void JsonlSerializer::serializeFigures(const PdfDocument* doc, << "\"rank\": " << f->rank << ", " << "\"id\": \"" << f->id << "\", " << "\"page\": " << f->pos->pageNum << ", " - << "\"minX\": " << round(f->pos->leftX, _coordsPrecision) << ", " - << "\"minY\": " << round(f->pos->upperY, _coordsPrecision) << ", " - << "\"maxX\": " << round(f->pos->rightX, _coordsPrecision) << ", " - << "\"maxY\": " << round(f->pos->lowerY, _coordsPrecision) << ", " + << "\"minX\": " << f->pos->leftX << ", " + << "\"minY\": " << f->pos->upperY << ", " + << "\"maxX\": " << f->pos->rightX << ", " + << "\"maxY\": " << f->pos->lowerY << ", " << "\"origin\": \"pdftotext++\"" << "}" << endl; @@ -190,10 +190,10 @@ void JsonlSerializer::serializeShapes(const PdfDocument* doc, << "\"rank\": " << s->rank << ", " << "\"id\": \"" << s->id << "\", " << "\"page\": " << s->pos->pageNum << ", " - << "\"minX\": " << round(s->pos->leftX, _coordsPrecision) << ", " - << "\"minY\": " << round(s->pos->upperY, _coordsPrecision) << ", " - << "\"maxX\": " << round(s->pos->rightX, _coordsPrecision) << ", " - << "\"maxY\": " << round(s->pos->lowerY, _coordsPrecision) << ", " + << "\"minX\": " << s->pos->leftX << ", " + << "\"minY\": " << s->pos->upperY << ", " + << "\"maxX\": " << s->pos->rightX << ", " + << "\"maxY\": " << s->pos->lowerY << ", " << "\"origin\": \"pdftotext++\"" << "}" << endl; @@ -220,10 +220,10 @@ void JsonlSerializer::serializeWords(const PdfDocument* doc, << "\"id\": \"" << word->id << "\", " << "\"rank\": " << word->rank << ", " << "\"page\": " << word->pos->pageNum << ", " - << "\"minX\": " << round(word->pos->leftX, _coordsPrecision) << ", " - << "\"minY\": " << round(word->pos->upperY, _coordsPrecision) << ", " - << "\"maxX\": " << round(word->pos->rightX, _coordsPrecision) << ", " - << "\"maxY\": " << round(word->pos->lowerY, _coordsPrecision) << ", " + << "\"minX\": " << word->pos->leftX << ", " + << "\"minY\": " << word->pos->upperY << ", " + << "\"maxX\": " << word->pos->rightX << ", " + << "\"maxY\": " << word->pos->lowerY << ", " << "\"font\": \"" << word->fontName << "\", " << "\"fontSize\": " << word->fontSize << ", " << "\"text\": \"" << escapeJson(word->text) << "\", " @@ -254,10 +254,10 @@ void JsonlSerializer::serializeTextBlocks(const PdfDocument* doc, << "\"id\": \"" << block->id << "\", " << "\"rank\": " << block->rank << ", " << "\"page\": " << block->pos->pageNum << ", " - << "\"minX\": " << round(block->pos->leftX, _coordsPrecision) << ", " - << "\"minY\": " << round(block->pos->upperY, _coordsPrecision) << ", " - << "\"maxX\": " << round(block->pos->rightX, _coordsPrecision) << ", " - << "\"maxY\": " << round(block->pos->lowerY, _coordsPrecision) << ", " + << "\"minX\": " << block->pos->leftX << ", " + << "\"minY\": " << block->pos->upperY << ", " + << "\"maxX\": " << block->pos->rightX << ", " + << "\"maxY\": " << block->pos->lowerY << ", " << "\"font\": \"" << block->fontName << "\", " << "\"fontSize\": " << block->fontSize << ", " << "\"text\": \"" << escapeJson(block->text) << "\", " diff --git a/src/utils/TextBlocksDetectionUtils.cpp b/src/utils/TextBlocksDetectionUtils.cpp index 3be2fd2..0d7d15a 100755 --- a/src/utils/TextBlocksDetectionUtils.cpp +++ b/src/utils/TextBlocksDetectionUtils.cpp @@ -279,9 +279,8 @@ double TextBlocksDetectionUtils::computeHangingIndent(const PdfTextBlock* block) } // Count the number of lines with a left margin >= the given threshold. - double leftMargin = round(line->leftMargin); - if (equalOrLarger(leftMargin, marginThreshold)) { - largeLeftMarginCounter[leftMargin]++; + if (equalOrLarger(line->leftMargin, marginThreshold)) { + largeLeftMarginCounter[line->leftMargin]++; numLargeLeftMarginLines++; } } @@ -414,9 +413,8 @@ void TextBlocksDetectionUtils::computeTextLineMargins(const PdfTextBlock* block) } for (auto* line : block->lines) { - // TODO(korzen): Should this really be rounded? - line->leftMargin = round(line->pos->leftX - block->trimLeftX); - line->rightMargin = round(blockTrimRightX - line->pos->rightX); + line->leftMargin = line->pos->leftX - block->trimLeftX; + line->rightMargin = blockTrimRightX - line->pos->rightX; } } diff --git a/test/utils/TextBlocksDetectionUtilsTest.cpp b/test/utils/TextBlocksDetectionUtilsTest.cpp index 07b2000..361f42d 100755 --- a/test/utils/TextBlocksDetectionUtilsTest.cpp +++ b/test/utils/TextBlocksDetectionUtilsTest.cpp @@ -323,7 +323,7 @@ TEST_F(TextBlocksDetectionUtilsTest, computeHangingIndent) { ASSERT_NEAR(utils.computeHangingIndent(block2), 0.0, TOL); // Input: A text block in hanging indent format. - ASSERT_NEAR(utils.computeHangingIndent(block3), 11.0, TOL); + ASSERT_NEAR(utils.computeHangingIndent(block3), 10.9, TOL); // Input: Text blocks with indented first lines (but not in hanging indent format). ASSERT_NEAR(utils.computeHangingIndent(block4), 0.0, TOL); @@ -332,9 +332,9 @@ TEST_F(TextBlocksDetectionUtilsTest, computeHangingIndent) { ASSERT_NEAR(utils.computeHangingIndent(block7), 0.0, TOL); // Input: Three references, each in hanging indent format. - ASSERT_NEAR(utils.computeHangingIndent(block9), 12.0, TOL); - ASSERT_NEAR(utils.computeHangingIndent(block10), 12.0, TOL); - ASSERT_NEAR(utils.computeHangingIndent(block11), 12.0, TOL); + ASSERT_NEAR(utils.computeHangingIndent(block9), 11.5, TOL); + ASSERT_NEAR(utils.computeHangingIndent(block10), 11.5, TOL); + ASSERT_NEAR(utils.computeHangingIndent(block11), 11.5, TOL); } // _________________________________________________________________________________________________ @@ -360,38 +360,38 @@ TEST_F(TextBlocksDetectionUtilsTest, computeTextLineMargins) { ASSERT_DEATH(utils.computeTextLineMargins(nullptr), ""); utils.computeTextLineMargins(block1); - ASSERT_NEAR(block1->lines[0]->leftMargin, 11.0, TOL); + ASSERT_NEAR(block1->lines[0]->leftMargin, 10.9, TOL); ASSERT_NEAR(block1->lines[0]->rightMargin, 0.0, TOL); ASSERT_NEAR(block1->lines[1]->leftMargin, 0.0, TOL); ASSERT_NEAR(block1->lines[1]->rightMargin, 0.0, TOL); ASSERT_NEAR(block1->lines[2]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block1->lines[2]->rightMargin, 84.0, TOL); + ASSERT_NEAR(block1->lines[2]->rightMargin, 84.3, TOL); utils.computeTextLineMargins(block2); - ASSERT_NEAR(block2->lines[0]->leftMargin, 4.0, TOL); - ASSERT_NEAR(block2->lines[0]->rightMargin, 4.0, TOL); - ASSERT_NEAR(block2->lines[1]->leftMargin, 3.0, TOL); - ASSERT_NEAR(block2->lines[1]->rightMargin, 3.0, TOL); - ASSERT_NEAR(block2->lines[2]->leftMargin, 42.0, TOL); - ASSERT_NEAR(block2->lines[2]->rightMargin, 42.0, TOL); + ASSERT_NEAR(block2->lines[0]->leftMargin, 3.7, TOL); + ASSERT_NEAR(block2->lines[0]->rightMargin, 3.7, TOL); + ASSERT_NEAR(block2->lines[1]->leftMargin, 2.8, TOL); + ASSERT_NEAR(block2->lines[1]->rightMargin, 2.8, TOL); + ASSERT_NEAR(block2->lines[2]->leftMargin, 41.6, TOL); + ASSERT_NEAR(block2->lines[2]->rightMargin, 41.6, TOL); ASSERT_NEAR(block2->lines[3]->leftMargin, 0.0, TOL); ASSERT_NEAR(block2->lines[3]->rightMargin, 0.0, TOL); - ASSERT_NEAR(block2->lines[4]->leftMargin, 228.0, TOL); - ASSERT_NEAR(block2->lines[4]->rightMargin, 228.0, TOL); + ASSERT_NEAR(block2->lines[4]->leftMargin, 228.4, TOL); + ASSERT_NEAR(block2->lines[4]->rightMargin, 228.5, TOL); utils.computeTextLineMargins(block3); - ASSERT_NEAR(block3->lines[0]->leftMargin, 11.0, TOL); - ASSERT_NEAR(block3->lines[0]->rightMargin, 0.0, TOL); + ASSERT_NEAR(block3->lines[0]->leftMargin, 10.9, TOL); + ASSERT_NEAR(block3->lines[0]->rightMargin, 0.4, TOL); ASSERT_NEAR(block3->lines[1]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block3->lines[1]->rightMargin, -22.0, TOL); + ASSERT_NEAR(block3->lines[1]->rightMargin, -22.2, TOL); ASSERT_NEAR(block3->lines[2]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block3->lines[2]->rightMargin, 0.0, TOL); + ASSERT_NEAR(block3->lines[2]->rightMargin, 0.4, TOL); ASSERT_NEAR(block3->lines[3]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block3->lines[3]->rightMargin, 0.0, TOL); + ASSERT_NEAR(block3->lines[3]->rightMargin, 0.4, TOL); ASSERT_NEAR(block3->lines[4]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block3->lines[4]->rightMargin, 0.0, TOL); + ASSERT_NEAR(block3->lines[4]->rightMargin, 0.4, TOL); ASSERT_NEAR(block3->lines[5]->leftMargin, 0.0, TOL); - ASSERT_NEAR(block3->lines[5]->rightMargin, 365.0, TOL); + ASSERT_NEAR(block3->lines[5]->rightMargin, 364.7, TOL); } // _________________________________________________________________________________________________ @@ -843,15 +843,14 @@ TEST_F(TextBlocksDetectionUtilsTest, createTextBlock) { ASSERT_EQ(blocks[0]->pos->pageNum, 12); ASSERT_EQ(blocks[0]->pos->wMode, 0); ASSERT_EQ(blocks[0]->pos->rotation, 0); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(blocks[0]->pos->leftX, 1), 56.7, TOL); - ASSERT_NEAR(round(blocks[0]->pos->rightX, 1), 538.6, TOL); - ASSERT_NEAR(round(blocks[0]->pos->upperY, 1), 90.8, TOL); - ASSERT_NEAR(round(blocks[0]->pos->lowerY, 1), 132.0, TOL); - ASSERT_NEAR(round(blocks[0]->trimLeftX, 1), 56.7, TOL); - ASSERT_NEAR(round(blocks[0]->trimRightX, 1), 538.6, TOL); - ASSERT_NEAR(round(blocks[0]->trimUpperY, 1), 90.8, TOL); - ASSERT_NEAR(round(blocks[0]->trimLowerY, 1), 132.0, TOL); + ASSERT_NEAR(blocks[0]->pos->leftX, 56.7, TOL); + ASSERT_NEAR(blocks[0]->pos->rightX, 538.6, TOL); + ASSERT_NEAR(blocks[0]->pos->upperY, 90.8, TOL); + ASSERT_NEAR(blocks[0]->pos->lowerY, 132.0, TOL); + ASSERT_NEAR(blocks[0]->trimLeftX, 56.7, TOL); + ASSERT_NEAR(blocks[0]->trimRightX, 538.6, TOL); + ASSERT_NEAR(blocks[0]->trimUpperY, 90.8, TOL); + ASSERT_NEAR(blocks[0]->trimLowerY, 132.0, TOL); ASSERT_EQ(blocks[0]->rank, 0); ASSERT_EQ(blocks[0]->fontName, "KAGVWM+CMR10"); ASSERT_NEAR(blocks[0]->fontSize, 10.9, TOL); @@ -872,15 +871,14 @@ TEST_F(TextBlocksDetectionUtilsTest, createTextBlock) { ASSERT_EQ(blocks[1]->pos->pageNum, 12); ASSERT_EQ(blocks[1]->pos->wMode, 0); ASSERT_EQ(blocks[1]->pos->rotation, 0); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(blocks[1]->pos->leftX, 1), 67.5, TOL); - ASSERT_NEAR(round(blocks[1]->pos->rightX, 1), 527.8, TOL); - ASSERT_NEAR(round(blocks[1]->pos->upperY, 1), 142.7, TOL); - ASSERT_NEAR(round(blocks[1]->pos->lowerY, 1), 191.5, TOL); - ASSERT_NEAR(round(blocks[1]->trimLeftX, 1), 67.5, TOL); - ASSERT_NEAR(round(blocks[1]->trimRightX, 1), 527.8, TOL); - ASSERT_NEAR(round(blocks[1]->trimUpperY, 1), 142.7, TOL); - ASSERT_NEAR(round(blocks[1]->trimLowerY, 1), 191.5, TOL); + ASSERT_NEAR(blocks[1]->pos->leftX, 67.5, TOL); + ASSERT_NEAR(blocks[1]->pos->rightX, 527.8, TOL); + ASSERT_NEAR(blocks[1]->pos->upperY, 142.7, TOL); + ASSERT_NEAR(blocks[1]->pos->lowerY, 191.5, TOL); + ASSERT_NEAR(blocks[1]->trimLeftX, 67.5, TOL); + ASSERT_NEAR(blocks[1]->trimRightX, 527.8, TOL); + ASSERT_NEAR(blocks[1]->trimUpperY, 142.7, TOL); + ASSERT_NEAR(blocks[1]->trimLowerY, 191.5, TOL); ASSERT_EQ(blocks[1]->rank, 1); ASSERT_EQ(blocks[1]->fontName, "KAGVWM+CMR10"); ASSERT_NEAR(blocks[1]->fontSize, 10.0, TOL); @@ -901,15 +899,14 @@ TEST_F(TextBlocksDetectionUtilsTest, createTextBlock) { ASSERT_EQ(blocks[2]->pos->pageNum, 12); ASSERT_EQ(blocks[2]->pos->wMode, 0); ASSERT_EQ(blocks[2]->pos->rotation, 0); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(blocks[2]->pos->leftX, 1), 56.7, TOL); - ASSERT_NEAR(round(blocks[2]->pos->rightX, 1), 580.2, TOL); - ASSERT_NEAR(round(blocks[2]->pos->upperY, 1), 203.1, TOL); - ASSERT_NEAR(round(blocks[2]->pos->lowerY, 1), 285.1, TOL); - ASSERT_NEAR(round(blocks[2]->trimLeftX, 1), 56.7, TOL); - ASSERT_NEAR(round(blocks[2]->trimRightX, 1), 539.0, TOL); - ASSERT_NEAR(round(blocks[2]->trimUpperY, 1), 203.1, TOL); - ASSERT_NEAR(round(blocks[2]->trimLowerY, 1), 285.1, TOL); + ASSERT_NEAR(blocks[2]->pos->leftX, 56.7, TOL); + ASSERT_NEAR(blocks[2]->pos->rightX, 580.2, TOL); + ASSERT_NEAR(blocks[2]->pos->upperY, 203.1, TOL); + ASSERT_NEAR(blocks[2]->pos->lowerY, 285.1, TOL); + ASSERT_NEAR(blocks[2]->trimLeftX, 56.7, TOL); + ASSERT_NEAR(blocks[2]->trimRightX, 539.0, TOL); + ASSERT_NEAR(blocks[2]->trimUpperY, 203.1, TOL); + ASSERT_NEAR(blocks[2]->trimLowerY, 285.1, TOL); ASSERT_EQ(blocks[2]->rank, 2); ASSERT_EQ(blocks[2]->fontName, "ADABFR+CMSSBX10"); ASSERT_NEAR(blocks[2]->fontSize, 10.9, TOL); diff --git a/test/utils/TextLinesDetectionUtilsTest.cpp b/test/utils/TextLinesDetectionUtilsTest.cpp index fa11865..272d146 100644 --- a/test/utils/TextLinesDetectionUtilsTest.cpp +++ b/test/utils/TextLinesDetectionUtilsTest.cpp @@ -167,9 +167,8 @@ TEST_F(TextLinesDetectionUtilsTest, computeTrimBox) { ASSERT_DEATH(utils.computeTrimBox(nullptr), ""); tuple trimBox = utils.computeTrimBox(segment); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(std::get<0>(trimBox), 1), 56.7, TOL); - ASSERT_NEAR(round(std::get<1>(trimBox), 1), 59.1, TOL); - ASSERT_NEAR(round(std::get<2>(trimBox), 1), 539.0, TOL); - ASSERT_NEAR(round(std::get<3>(trimBox), 1), 500.4, TOL); + ASSERT_NEAR(std::get<0>(trimBox), 56.7, TOL); + ASSERT_NEAR(std::get<1>(trimBox), 59.1, TOL); + ASSERT_NEAR(std::get<2>(trimBox), 539.0, TOL); + ASSERT_NEAR(std::get<3>(trimBox), 500.4, TOL); } diff --git a/test/utils/WordsDetectionUtilsTest.cpp b/test/utils/WordsDetectionUtilsTest.cpp index 78c598b..ce712d7 100644 --- a/test/utils/WordsDetectionUtilsTest.cpp +++ b/test/utils/WordsDetectionUtilsTest.cpp @@ -113,15 +113,14 @@ TEST_F(WordsDetectionUtilsTest, createWord) { PdfWord* word = utils.createWord(characters); ASSERT_TRUE(word->id.size() > static_cast(0)); ASSERT_EQ(word->pos->pageNum, 1); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(word->pos->leftX, 1), 56.7, TOL); - ASSERT_NEAR(round(word->pos->upperY, 1), 90.8, TOL); - ASSERT_NEAR(round(word->pos->rightX, 1), 90.7, TOL); - ASSERT_NEAR(round(word->pos->lowerY, 1), 104.9, TOL); - ASSERT_NEAR(round(word->pos->getRotLeftX(), 1), 56.7, TOL); - ASSERT_NEAR(round(word->pos->getRotUpperY(), 1), 90.8, TOL); - ASSERT_NEAR(round(word->pos->getRotRightX(), 1), 90.7, TOL); - ASSERT_NEAR(round(word->pos->getRotLowerY(), 1), 104.9, TOL); + ASSERT_NEAR(word->pos->leftX, 56.7, TOL); + ASSERT_NEAR(word->pos->upperY, 90.8, TOL); + ASSERT_NEAR(word->pos->rightX, 90.7, TOL); + ASSERT_NEAR(word->pos->lowerY, 104.9, TOL); + ASSERT_NEAR(word->pos->getRotLeftX(), 56.7, TOL); + ASSERT_NEAR(word->pos->getRotUpperY(), 90.8, TOL); + ASSERT_NEAR(word->pos->getRotRightX(), 90.7, TOL); + ASSERT_NEAR(word->pos->getRotLowerY(), 104.9, TOL); ASSERT_EQ(word->pos->wMode, 0); ASSERT_EQ(word->pos->rotation, 0); ASSERT_EQ(word->text, "Ashton"); @@ -134,15 +133,14 @@ TEST_F(WordsDetectionUtilsTest, createWord) { word = utils.createWord(characters); ASSERT_TRUE(word->id.size() > static_cast(0)); ASSERT_EQ(word->pos->pageNum, 1); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(word->pos->leftX, 1), 53.8, TOL); - ASSERT_NEAR(round(word->pos->upperY, 1), 114.1, TOL); - ASSERT_NEAR(round(word->pos->rightX, 1), 68, TOL); - ASSERT_NEAR(round(word->pos->lowerY, 1), 143.6, TOL); - ASSERT_NEAR(round(word->pos->getRotLeftX(), 1), 143.6, TOL); - ASSERT_NEAR(round(word->pos->getRotUpperY(), 1), 53.8, TOL); - ASSERT_NEAR(round(word->pos->getRotRightX(), 1), 114.1, TOL); - ASSERT_NEAR(round(word->pos->getRotLowerY(), 1), 68, TOL); + ASSERT_NEAR(word->pos->leftX, 53.8, TOL); + ASSERT_NEAR(word->pos->upperY, 114.1, TOL); + ASSERT_NEAR(word->pos->rightX, 68, TOL); + ASSERT_NEAR(word->pos->lowerY, 143.6, TOL); + ASSERT_NEAR(word->pos->getRotLeftX(), 143.6, TOL); + ASSERT_NEAR(word->pos->getRotUpperY(), 53.8, TOL); + ASSERT_NEAR(word->pos->getRotRightX(), 114.1, TOL); + ASSERT_NEAR(word->pos->getRotLowerY(), 68, TOL); ASSERT_EQ(word->pos->wMode, 0); ASSERT_EQ(word->pos->rotation, 3); ASSERT_EQ(word->text, "Travis"); @@ -155,15 +153,14 @@ TEST_F(WordsDetectionUtilsTest, createWord) { word = utils.createWord(characters); ASSERT_TRUE(word->id.size() > static_cast(0)); ASSERT_EQ(word->pos->pageNum, 1); - // TODO(korzen): The coordinates should not be rounded here. - ASSERT_NEAR(round(word->pos->leftX, 1), 61.9, TOL); - ASSERT_NEAR(round(word->pos->upperY, 1), 158.3, TOL); - ASSERT_NEAR(round(word->pos->rightX, 1), 71.8, TOL); - ASSERT_NEAR(round(word->pos->lowerY, 1), 172.5, TOL); - ASSERT_NEAR(round(word->pos->getRotLeftX(), 1), 71.8, TOL); - ASSERT_NEAR(round(word->pos->getRotUpperY(), 1), 172.5, TOL); - ASSERT_NEAR(round(word->pos->getRotRightX(), 1), 61.9, TOL); - ASSERT_NEAR(round(word->pos->getRotLowerY(), 1), 158.3, TOL); + ASSERT_NEAR(word->pos->leftX, 61.9, TOL); + ASSERT_NEAR(word->pos->upperY, 158.3, TOL); + ASSERT_NEAR(word->pos->rightX, 71.8, TOL); + ASSERT_NEAR(word->pos->lowerY, 172.5, TOL); + ASSERT_NEAR(word->pos->getRotLeftX(), 71.8, TOL); + ASSERT_NEAR(word->pos->getRotUpperY(), 172.5, TOL); + ASSERT_NEAR(word->pos->getRotRightX(), 61.9, TOL); + ASSERT_NEAR(word->pos->getRotLowerY(), 158.3, TOL); ASSERT_EQ(word->pos->wMode, 0); ASSERT_EQ(word->pos->rotation, 2); ASSERT_EQ(word->text, "Levy");