summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/docxattributeoutput.cxx
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2023-04-11 11:19:56 -0400
committerJustin Luth <jluth@mail.com>2023-04-14 03:13:23 +0200
commit02c902bde09984a87f19ac0eb63942724056c982 (patch)
treec72c2522ffd8922b3bd154f2e3e6d7e9b31ed044 /sw/source/filter/ww8/docxattributeoutput.cxx
parent996d264dd4ca37c869e5109296de6ae306f740d9 (diff)
tdf#154703 docx export framePr: merge para/frame FormatBox
Now that export knows about both frame and para border spacing, we can remove an import hack. When exporting the paragraph properties, not only do the direct border settings and the paragraph styles settings apply, but also (uniquely for framePr) do the frame properties. The most significant property is the border spacing. On import only the paragraph keeps the spacing (with the purpose of keeping paragraph shading looking right) and the frames itself has no border spacing. [That is also good, because the frame size is specified as the size without border spacing, and LO does not expand the frame when borders spacing is added.] One exception of course is if the user adds spacing during editing. Another (theoretical) situation comes during an ODT->DOCX export. Fortunately, both of these situations should be handled by just adding the frame and paragraph properties together. It is emulation, but it seems to work pretty good. I modified the unit test from 7.1 commit 49e2bd6103669ca94d4e308fc08beed57f85c7e2 Author: Tibor Nagy on Mon Aug 10 10:51:20 2020 +0200 tdf#131420 DOCX export: fix missing border of frame because we should _not_ have two pBdr entries, just one, non-empty entry. Table import and export are already a mess. See ooxmpexort5's fdo 60957-2.docx for a great example, and tdf104394_lostTextbox.docx is also fascinatingly complex. Change-Id: I011100ee2790de6b8573d6a8bc99b9455f65e76d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150242 Tested-by: Jenkins Reviewed-by: Justin Luth <jluth@mail.com>
Diffstat (limited to 'sw/source/filter/ww8/docxattributeoutput.cxx')
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx59
1 files changed, 53 insertions, 6 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1d9bde3f2ba4..0f34bc7b645b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -575,16 +575,26 @@ OString DocxAttributeOutput::convertToOOXMLHoriOrientRel(sal_Int16 nOrientRel)
}
}
-void FramePrHelper::SetFrame(ww8::Frame* pFrame)
+void FramePrHelper::SetFrame(ww8::Frame* pFrame, sal_Int32 nTableDepth)
{
assert(!pFrame || !m_pFrame);
m_pFrame = pFrame;
+ m_nTableDepth = nTableDepth;
if (m_pFrame)
{
+ m_bUseFrameBorders = true;
m_bUseFrameBackground = true;
}
}
+bool FramePrHelper::UseFrameBorders(sal_Int32 nTableDepth)
+{
+ if (!m_pFrame || m_nTableDepth < nTableDepth)
+ return false;
+
+ return m_bUseFrameBorders;
+}
+
bool FramePrHelper::UseFrameBackground()
{
if (!m_pFrame)
@@ -1117,7 +1127,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
for ( const auto & pFrame : aFramePrTextbox )
{
DocxTableExportContext aTableExportContext(*this);
- m_aFramePr.SetFrame(pFrame.get());
+ m_aFramePr.SetFrame(pFrame.get(), !m_xTableWrt ? -1 : m_tableReference.m_nTableDepth);
m_rExport.SdrExporter().writeOnlyTextOfFrame(pFrame.get());
m_aFramePr.SetFrame(nullptr);
}
@@ -1503,7 +1513,10 @@ void DocxAttributeOutput::EndParagraphProperties(const SfxItemSet& rParagraphMar
const Size aSize = m_aFramePr.Frame()->GetSize();
PopulateFrameProperties(&rFrameFormat, aSize);
- FormatBox(rFrameFormat.GetBox());
+
+ // if the paragraph itself never called FormatBox, do so now
+ if (m_aFramePr.UseFrameBorders(!m_xTableWrt ? -1 : m_tableReference.m_nTableDepth))
+ FormatBox(rFrameFormat.GetBox());
if (m_aFramePr.UseFrameBackground())
{
@@ -1522,7 +1535,9 @@ void DocxAttributeOutput::EndParagraphProperties(const SfxItemSet& rParagraphMar
}
}
}
+
// reset to true in preparation for the next paragraph in the frame
+ m_aFramePr.SetUseFrameBorders(true);
m_aFramePr.SetUseFrameBackground(true);
}
@@ -4163,7 +4178,8 @@ static void impl_borders( FSHelperPtr const & pSerializer,
const SvxBoxItem& rBox,
const OutputBorderOptions& rOptions,
std::map<SvxBoxItemLine,
- css::table::BorderLine2> &rTableStyleConf )
+ css::table::BorderLine2> &rTableStyleConf,
+ ww8::Frame* pFramePr = nullptr)
{
static const SvxBoxItemLine aBorders[] =
{
@@ -4243,6 +4259,34 @@ static void impl_borders( FSHelperPtr const & pSerializer,
}
}
+ if (pFramePr)
+ {
+ assert(rOptions.bWriteDistance && !rOptions.pDistances);
+
+ // In addition to direct properties, and paragraph styles,
+ // for framePr-floated paragraphs the frame borders also affect the exported values.
+
+ // For border spacing, there is a special situation to consider
+ // because a compat setting ignores left/right paragraph spacing on layout.
+ const SwFrameFormat& rFormat = pFramePr->GetFrameFormat();
+ const SvxBoxItem& rFramePrBox = rFormat.GetBox();
+ const IDocumentSettingAccess& rIDSA = rFormat.GetDoc()->getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::INVERT_BORDER_SPACING)
+ && (*pBrd == SvxBoxItemLine::LEFT || *pBrd == SvxBoxItemLine::RIGHT))
+ {
+ // only the frame's border spacing affects layout - so use that value instead.
+ nDist = rFramePrBox.GetDistance(*pBrd);
+ }
+ else
+ {
+ nDist += rFramePrBox.GetDistance(*pBrd);
+ }
+
+ // Unless the user added a paragraph border, the border normally comes from the frame.
+ if (!pLn)
+ pLn = rFramePrBox.GetLine(*pBrd);
+ }
+
impl_borderLine( pSerializer, aXmlElements[i], pLn, nDist, bWriteShadow, aStyleProps );
}
if (tagWritten && rOptions.bWriteTag) {
@@ -9518,11 +9562,14 @@ void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
aStyleBorders[ SvxBoxItemLine::LEFT ] = SvxBoxItem::SvxLineToLine(pInherited->GetLeft(), false);
aStyleBorders[ SvxBoxItemLine::RIGHT ] = SvxBoxItem::SvxLineToLine(pInherited->GetRight(), false);
}
-
- impl_borders( m_pSerializer, rBox, aOutputBorderOptions, aStyleBorders );
+ bool bUseFrame = m_aFramePr.UseFrameBorders(!m_xTableWrt ? -1 : m_tableReference.m_nTableDepth);
+ impl_borders(m_pSerializer, rBox, aOutputBorderOptions, aStyleBorders,
+ bUseFrame ? m_aFramePr.Frame() : nullptr);
// Close the paragraph's borders tag
m_pSerializer->endElementNS( XML_w, XML_pBdr );
+
+ m_aFramePr.SetUseFrameBorders(false);
}
void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFormatCol& rCol, bool bEven, SwTwips nPageSize )