diff --git a/Pdf4QtLib/sources/pdftextlayout.cpp b/Pdf4QtLib/sources/pdftextlayout.cpp index 7e277d5..648b7f0 100644 --- a/Pdf4QtLib/sources/pdftextlayout.cpp +++ b/Pdf4QtLib/sources/pdftextlayout.cpp @@ -314,7 +314,7 @@ bool PDFTextLayout::isHoveringOverTextBlock(const QPointF& point) const return false; } -PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor) +PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor, bool strictSelection) { PDFTextSelection selection; @@ -374,12 +374,12 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QRectF boundingBoxPathBBRect = boundingBoxPath.controlPointRect(); // If start point is above the text block, move start point to the left. - if (boundingBoxPathBBRect.bottom() < pointA.y()) + if (!strictSelection && boundingBoxPathBBRect.bottom() < pointA.y()) { pointA.setX(boundingBoxPathBBRect.left()); isTopPointAboveText = true; } - if (boundingBoxPathBBRect.top() > pointB.y()) + if (!strictSelection && boundingBoxPathBBRect.top() > pointB.y()) { pointB.setX(boundingBoxPathBBRect.right()); isBottomPointBelowText = true; @@ -399,6 +399,16 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const for (size_t lineId = 0, linesCount = lines.size(); lineId < linesCount; ++lineId) { const PDFTextLine& line = lines[lineId]; + QRectF lineBoundingRect = line.getBoundingBox().boundingRect(); + + // We skip lines, which are not in the range (pointB.y(), pointA.y), + // i.e. are above or below. + if (lineBoundingRect.bottom() < pointB.y() || + lineBoundingRect.top() > pointA.y()) + { + continue; + } + const TextCharacters& characters = line.getCharacters(); for (size_t characterId = 0, characterCount = characters.size(); characterId < characterCount; ++characterId) { diff --git a/Pdf4QtLib/sources/pdftextlayout.h b/Pdf4QtLib/sources/pdftextlayout.h index dd8d8d7..bff24df 100644 --- a/Pdf4QtLib/sources/pdftextlayout.h +++ b/Pdf4QtLib/sources/pdftextlayout.h @@ -368,7 +368,12 @@ public: /// \param point1 First point /// \param point2 Second point /// \param selectionColor Selection color - PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor = Qt::yellow); + /// \param strictSelection If true, does not adjust horizontal range when above/below text block + PDFTextSelection createTextSelection(PDFInteger pageIndex, + const QPointF& point1, + const QPointF& point2, + QColor selectionColor = Qt::yellow, + bool strictSelection = false); /// Returns string from text selection /// \param itBegin Iterator (begin range) diff --git a/Pdf4QtLib/sources/pdfwidgettool.cpp b/Pdf4QtLib/sources/pdfwidgettool.cpp index 5d15743..48c0643 100644 --- a/Pdf4QtLib/sources/pdfwidgettool.cpp +++ b/Pdf4QtLib/sources/pdfwidgettool.cpp @@ -1567,46 +1567,15 @@ void PDFSelectTableTool::keyPressEvent(QWidget* widget, QKeyEvent* event) cell.row = rowIndex; cell.column = columnIndex; cell.rectangle = QRectF(left, top, width, height); + + PDFTextSelection textSelection = m_textLayout.createTextSelection(m_pageIndex, cell.rectangle.topLeft(), cell.rectangle.bottomRight(), Qt::yellow, true); + cell.text = m_textLayout.getTextFromSelection(textSelection, m_pageIndex).trimmed(); + cell.text = cell.text.remove(QChar('\n')); + tableCells.push_back(cell); } } - const PDFTextBlocks& textBlocks = m_textLayout.getTextBlocks(); - for (size_t i = 0; i < textBlocks.size(); ++i) - { - // Detect, if whole block can be in some text cell - const PDFTextBlock& textBlock = textBlocks[i]; - QRectF textRect = textBlock.getBoundingBox().boundingRect(); - auto itBlockCell = std::find_if(tableCells.begin(), tableCells.end(), [textRect](const auto& cell) { return cell.rectangle.contains(textRect); }); - if (itBlockCell != tableCells.end()) - { - // Jakub Melka: whole block is contained in the cell - PDFTextSelection blockSelection = m_textLayout.selectBlock(i, m_pageIndex, QColor()); - QString text = m_textLayout.getTextFromSelection(blockSelection, m_pageIndex); - TableCell& cell = *itBlockCell; - cell.text = QString("%1 %2").arg(cell.text, text).trimmed(); - continue; - } - - const PDFTextLines& textLines = textBlock.getLines(); - for (size_t j = 0; j < textLines.size(); ++j) - { - const PDFTextLine& textLine = textLines[j]; - QRectF boundingRect = textLine.getBoundingBox().boundingRect(); - - auto itLineCell = std::find_if(tableCells.begin(), tableCells.end(), [boundingRect](const auto& cell) { return cell.rectangle.contains(boundingRect); }); - if (itLineCell != tableCells.end()) - { - // Jakub Melka: whole block is contained in the cell - PDFTextSelection blockSelection = m_textLayout.selectLineInBlock(i, j, m_pageIndex, QColor()); - QString text = m_textLayout.getTextFromSelection(blockSelection, m_pageIndex); - TableCell& cell = *itLineCell; - cell.text = QString("%1 %2").arg(cell.text, text).trimmed(); - continue; - } - } - } - if (m_isTransposed) { auto comparator = [](const TableCell& left, const TableCell right) diff --git a/RELEASES.txt b/RELEASES.txt index bd54437..47a957d 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,6 +1,7 @@ CURRENT: - Issue #21: Table selection tool - Issue #22: Solve compilation warnings + - Issue #24: Text selection and table selection algorithm improvement V: 1.2.1 30.6.2022 - Issue #17: Public key security handler