summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-10-27 18:00:14 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-11-02 10:46:30 +0100
commit6593d680e21c24501a58bac216de4a7c71541959 (patch)
tree6b40e10943607ca2147a7f77a5c84ab34d660af2 /sw
parent468e5b8e0a7fefe1ca53faeb15f5f6527c37a268 (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.cxx38
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))
{