diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2023-10-27 18:00:14 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2023-11-02 10:46:30 +0100 |
commit | 6593d680e21c24501a58bac216de4a7c71541959 (patch) | |
tree | 6b40e10943607ca2147a7f77a5c84ab34d660af2 /sw | |
parent | 468e5b8e0a7fefe1ca53faeb15f5f6527c37a268 (diff) |
tdf#157816 sw: PDF export: filter out links on empty space, fields
If there is a fly overlapping a paragraph, it may happen (depending on
wrap settings and position) that there's an empty space on one side of
the fly; the cursor selection region has the flys removed, and this
region is used here for the PDF export.
So there is a rectangle on the text on one side of the fly, turned into
the desired Link annotation, and another rectangle on the other side of
the fly, turned into another undesired Link annotation that isn't
connected to any SE because without text there is no SE.
This is a tricky problem, and the only idea to fix it is to try to see
if there is text in the rectangle by first GetModelPositionForViewPoint()
resulting in a SwPosition and a SwSpecialPos with an index inside the
field; then see if GetCharRect() for this position returns a cursor
rectangle that intersects the original selection rectangle.
Change-Id: I6918eac16690e7194208a828108bfa968d28d12a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158571
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/text/EnhancedPDFExportHelper.cxx | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index decdd4215f0b..946def82f719 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -345,6 +345,35 @@ bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, con return true; }; +// tdf#157816: try to check if the rectangle contains actual text +::std::vector<SwRect> GetCursorRectsContainingText(SwCursorShell const& rShell) +{ + ::std::vector<SwRect> ret; + for (SwRect const& rRect : *rShell.GetCursor_()) + { + Point center(rRect.Center()); + SwSpecialPos special; + SwCursorMoveState cms(CursorMoveState::NONE); + cms.m_pSpecialPos = &special; + cms.m_bFieldInfo = true; + SwPosition pos(rShell.GetDoc()->GetNodes()); + auto const [pStart, pEnd] = rShell.GetCursor_()->StartEnd(); + if (rShell.GetLayout()->GetModelPositionForViewPoint(&pos, center, &cms) + && *pStart <= pos && pos <= *pEnd) + { + SwRect charRect; + if (rShell.GetCurrFrame(false)->GetCharRect(charRect, pos, &cms, false) + && rRect.Overlaps(charRect)) + { + ret.push_back(rRect); + } + } + // reset stupid static var that may have gotten set now + SwTextCursor::SetRightMargin(false); // WTF is this crap + } + return ret; +} + } // end namespace SwTaggedPDFHelper::SwTaggedPDFHelper( const Num_Info* pNumInfo, @@ -2396,8 +2425,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport(LanguageType const eLanguageDe mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars ); // Link Rectangles - SwRects aTmp; - aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() ); + SwRects const aTmp(GetCursorRectsContainingText(mrSh)); OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" ); mrSh.SwCursorShell::ClearMark(); @@ -2819,7 +2847,8 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks() mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars); // Create the links. - for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_()) + SwRects const rects(GetCursorRectsContainingText(mrSh)); + for (const auto& rLinkRect : rects) { for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect)) { @@ -2869,7 +2898,8 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks() mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars); // Create the links. - for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_()) + SwRects const rects(GetCursorRectsContainingText(mrSh)); + for (const auto& rLinkRect : rects) { for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect)) { |