diff options
author | Justin Luth <jluth@mail.com> | 2024-08-21 08:36:00 -0400 |
---|---|---|
committer | Justin Luth <jluth@mail.com> | 2024-08-24 14:29:47 +0200 |
commit | c63cce999629ef1aedfa688d1ef8753e13020c36 (patch) | |
tree | 2386cd47a3d8938c72c817391d95e2a0b87f15b5 /sw | |
parent | c2337ff12896b2ae09437d2cbc726971c9fb170f (diff) |
tdf#157637 ODT->DOC: use layoutInCell for para-oriented fly
This is a very sticky business.
LO and Word implement aspects of FollowTextFlow so differently.
But for native LO documents, it is clear that at least
the image placement of paragraph-oriented flies
is based on the cell paragraph, which in MSO layout
means the layoutInCell paragraph.
Prior to 7.4, we never wrote anything related to layoutInCell,
and since the default is true, layoutInCell was always true,
so writing layoutInCell = false less often can't cause a regression.
But of course there are implications.
The main side effect is that the cell will expand to contain the fly,
or the UI might, on an "OK", move or squish the image into the cell.
But we already had that prior to 7.4 anyway.
WrapThrough shouldn't come into play here
(although they tend to look better, with less side effects).
make CppunitTest_sw_ww8export3 \
CPPUNIT_TEST_NAME=testTdf79186_noLayoutInCell
----
This cannot fix LO inserting images into a doc-formatted file though.
That can only be handled by "fixing" the layout to orient the newly
inserted image relative to the table-paragraph
instead of the cell-paragraph.
LO currently does not properly reflect the layout
when layoutInCell=false for DOC/DOCX<=compat14 flies,
so simply looking at LO results is very deceiving.
Make sure you also check how the end result looks in MS Word.
Change-Id: Ia631c56a25ad103ac448f1f46a8553ab1478330b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157662
Reviewed-by: Justin Luth <jluth@mail.com>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/ww8export/ww8export3.cxx | 26 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8esh.cxx | 32 |
2 files changed, 49 insertions, 9 deletions
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx index c639f46ea51d..a4ba58d4c37a 100644 --- a/sw/qa/extras/ww8export/ww8export3.cxx +++ b/sw/qa/extras/ww8export/ww8export3.cxx @@ -1069,11 +1069,33 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf136814) CPPUNIT_TEST_FIXTURE(Test, testTdf79186_noLayoutInCell) { + // given a native ODT file with a paragraph-oriented textbox anchored/located in cell B2 + + // Note: there is no direct equivalent layout for this in MSO format, + // so there has to be some give and take as the most suitable choice is selected. + loadAndReload("tdf79186_noLayoutInCell.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); - CPPUNIT_ASSERT_EQUAL(1, getPages()); + // CPPUNIT_ASSERT_EQUAL(1, getPages()); + + // Although setting "Follow Text Flow" significantly changes this doc's layout during ODF->DOC + // it preserves orienting the frame in the proper column. + // (While this example looked perfect in a LO round-trip without FTF, + // in MS Word the textbox was contained in column A instead of the original column B.) + // Thus the "perfect look" simply proves that LO is doing the layout wrong. + CPPUNIT_ASSERT(getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr)); // tdf#157637 + CPPUNIT_ASSERT_EQUAL(isExported(), getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr)); + xmlDocUniquePtr pDump = parseLayoutDump(); + sal_Int32 nShapeLeft + = getXPath(pDump, "//anchored/SwAnchoredDrawObject/bounds"_ostr, + "left"_ostr) + .toInt32(); + sal_Int32 nColumnBLeft + = getXPath(pDump, "//page[1]/body/tab/row[1]/cell[2]/infos/bounds"_ostr, + "left"_ostr).toInt32(); + // The textbox's horizontal placement is of primary concern. It must remain in cell B2 + CPPUNIT_ASSERT(nShapeLeft > nColumnBLeft); - CPPUNIT_ASSERT(!getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr)); CPPUNIT_ASSERT(getProperty<bool>(getShape(1), u"SurroundContour"_ustr)); // tdf#140508 } diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx index 37b36ccaafdf..9513c42d4d01 100644 --- a/sw/source/filter/ww8/wrtw8esh.cxx +++ b/sw/source/filter/ww8/wrtw8esh.cxx @@ -2566,13 +2566,6 @@ void WinwordAnchoring::SetAnchoring(const SwFrameFormat& rFormat) const RndStdIds eAnchor = rFormat.GetAnchor().GetAnchorId(); mbInline = (eAnchor == RndStdIds::FLY_AS_CHAR); - mnGroupShapeBooleanProperties = 0; - if (!rFormat.GetFollowTextFlow().GetValue()) - { - // bit32: fUseLayoutInCell, bit16: fLayoutInCell - mnGroupShapeBooleanProperties |= 0x80000000; - } - SwFormatHoriOrient rHoriOri = rFormat.GetHoriOrient(); SwFormatVertOrient rVertOri = rFormat.GetVertOrient(); @@ -2701,6 +2694,31 @@ void WinwordAnchoring::SetAnchoring(const SwFrameFormat& rFormat) mnYRelTo = 3; break; } + + mnGroupShapeBooleanProperties = 0; + // LayoutInCell is hugely problematic if the value is false, + // so much so that Microsoft, since DOCX compat15, ignores it and always does a layoutInCell. + + // LO (currently) does the obvious thing of always orienting a fly from the cell paragraph, + // while MSO orients a non-layoutInCell-fly from the paragraph that contains the entire table. + // Thus, during ODF->MSO, ONLY a non-paragraph-oriented-fly can be marked as layoutInCell=false. + + // FOR DOCX and DOC, the absence of the fLayoutInCell property means true - layout in cell, + // so do nothing unless "Follow text flow" is disabled (which is the default in native LO). + bool bLayoutInCell = rFormat.GetFollowTextFlow().GetValue(); + + // If this is already MSO format, then we need to round-trip a false FollowingTextFlow value + const bool bIsMSOLayout = rFormat.getIDocumentSettingAccess().get( + DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION); + + // For native LO: if !FollowingTextFlow and the fly is oriented to the pageMargin(0) or page(1), + // we must write layoutInCell(false), but paragraph-oriented flies match layoutInCell placement. + if (!bLayoutInCell && (bIsMSOLayout || mnYRelTo != 2 || mnXRelTo != 2)) + { + // indicate layoutInCell = false + // bit32: fUseLayoutInCell, bit16: fLayoutInCell + mnGroupShapeBooleanProperties |= 0x80000000; + } } void SwEscherEx::WriteFrameExtraData( const SwFrameFormat& rFormat ) |