summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2020-08-04 18:56:08 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2020-08-07 00:41:38 +0200
commit56e1c88a7b2fc31682a239f59ec319f93ba61a25 (patch)
tree9ff1c0e4618bf8919f5c1ca5c83d8bb8de20bbf6
parent0de435962fc2ffbbcf3dc4a9bac13894372dfd5e (diff)
tdf#135464 sw: ODT->DOCX: fix positioning of at-page shapes and frames
Exporting at-page anchored flys to DOCX can result in wrong positions, because DocxSdrExport::startDMLAnchorInline() converts text::RelOrientation::FRAME to relativeFrom="column", i.e. the margin, but sw displays it as relative to the page. In fact at-page and FRAME is an invalid combination according to the table in ODF 1.3, 20.298 style:horizontal-pos, the paragraph and character relations are not valid for page-anchored flys. Since there are lots of ODT files with this invalid combination, try to fix it on import, in SwXFrame and SwXShape. Funnily, SwXShape is attached before the properties are set, while SwXFrame is attached after the properties are set. The anchor frame for at-page is always a SwPageFrame. Unfortunately there is a case where PRINT_AREA and PAGE_PRINT_AREA differ, namely the CalcClipRect() only handles PRINT_AREA so it will crop to the right margin with that but not with PAGE_PRINT_AREA, so don't map this value. Change-Id: I4d5f7f87d045ac4539b9170e55c34d4afe801f4d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100130 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de> (cherry picked from commit 12645900dece0a9aa0661fee796c27f672217977) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100237 Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r--sw/inc/fmtornt.hxx6
-rw-r--r--sw/qa/extras/ooxmlexport/data/rotated_shape.fodt81
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport15.cxx29
-rw-r--r--sw/source/core/layout/atrfrm.cxx33
-rw-r--r--sw/source/core/unocore/unodraw.cxx15
-rw-r--r--sw/source/core/unocore/unoframe.cxx13
6 files changed, 177 insertions, 0 deletions
diff --git a/sw/inc/fmtornt.hxx b/sw/inc/fmtornt.hxx
index 0a8ab6f1a619..59afdb46f26a 100644
--- a/sw/inc/fmtornt.hxx
+++ b/sw/inc/fmtornt.hxx
@@ -108,6 +108,12 @@ inline const SwFormatVertOrient &SwFormat::GetVertOrient(bool bInP) const
inline const SwFormatHoriOrient &SwFormat::GetHoriOrient(bool bInP) const
{ return m_aSet.GetHoriOrient(bInP); }
+namespace sw {
+
+ bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea);
+
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt b/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt
new file mode 100644
index 000000000000..fce84f93e945
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Times New Roman" svg:font-family="&apos;Times New Roman&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ <style:font-face style:name="Lucida Sans" svg:font-family="&apos;Lucida Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="NSimSun" svg:font-family="NSimSun" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Times New Roman" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Times New Roman" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph">
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ <style:text-properties fo:font-size="11pt"/>
+ </style:style>
+ <style:style style:name="T1" style:family="text">
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Arial" fo:font-size="7pt" fo:language="de" fo:country="DE" style:font-name-asian="Times New Roman" style:font-size-asian="7pt" style:font-name-complex="Arial" style:font-size-complex="12pt" style:language-complex="ar" style:country-complex="SA"/>
+ </style:style>
+ <style:style style:name="gr1" style:family="graphic">
+ <style:graphic-properties draw:stroke="none" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="justify" draw:textarea-vertical-align="middle" draw:auto-grow-height="false" draw:auto-grow-width="false" fo:padding-top="0.254cm" fo:padding-bottom="0.254cm" fo:padding-left="0.127cm" fo:padding-right="0.127cm" fo:wrap-option="wrap" draw:shadow="hidden" style:run-through="foreground" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="page" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true" style:flow-with-text="false"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics">
+ <style:graphic-properties style:horizontal-pos="from-left" style:horizontal-rel="paragraph" style:vertical-pos="from-top" style:vertical-rel="page" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <draw:frame text:anchor-type="page" text:anchor-page-number="1" draw:z-index="0" draw:name="Shape1" draw:style-name="gr1" draw:text-style-name="P2" svg:width="5.896cm" svg:height="0.957cm" draw:transform="rotate (1.5707963267949) translate (1.13418055555556cm 26.0579305555556cm)">
+ <draw:text-box>
+ <text:p text:style-name="P1"><text:span text:style-name="T1"><text:s/></text:span><text:span text:style-name="T1">Foo</text:span></text:p>
+ </draw:text-box>
+ </draw:frame><draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="page" text:anchor-page-number="1" svg:width="0.67cm" svg:height="0.67cm" draw:z-index="0"><draw:image draw:mime-type="image/png" svg:x="2cm" svg:y="3cm">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAAXNSR0IArs4c6QAAAAZiS0dE
+ AP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJBhI0A6HXrrIAAABl
+ SURBVDjLY/z//z8DtQATMYokl7D8p4phMIOIMZCJFBcRMpCJVK/hM5CJnDDCJc9EbmBjU8dE
+ jkG41DPhM+h5zB9GfHx0fTgjAJtGfOIMDAwMLMQoItZAJgYqglHDhpNhjNQsaQHF4y3hS/bS
+ HgAAAABJRU5ErkJggg==
+ </office:binary-data>
+ </draw:image>
+ </draw:frame>
+ <text:p text:style-name="Standard"/>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index a1f8971772c1..08136531b9df 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -52,6 +52,35 @@ DECLARE_OOXMLEXPORT_TEST(testTdf134063, "tdf134063.docx")
CPPUNIT_ASSERT_EQUAL(sal_Int32(720), getXPath(pDump, "//page[1]/body/txt[1]/Text[3]", "nWidth").toInt32());
}
+DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
+{
+ // invalid combination of at-page anchor and horizontal-rel="paragraph"
+ // caused relativeFrom="column" instead of relativeFrom="page"
+
+ xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml");
+ if (!pXmlDocument)
+ return;
+
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionH/wp:posOffset", "-480060");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionH", "relativeFrom", "page");
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionV/wp:posOffset", "8147685");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionV", "relativeFrom", "page");
+
+ // same for sw
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionH/wp:posOffset", "720090");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionH", "relativeFrom", "page");
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionV/wp:posOffset", "1080135");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionV", "relativeFrom", "page");
+}
+
DECLARE_OOXMLEXPORT_TEST(testRelativeAnchorHeightFromBottomMarginHasFooter,
"tdf133070_testRelativeAnchorHeightFromBottomMarginHasFooter.docx")
{
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index ae9311d2231d..d9f37a669787 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -96,6 +96,39 @@
using namespace ::com::sun::star;
+namespace sw {
+
+bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea)
+{
+ switch (rOrientation)
+ {
+ case text::RelOrientation::CHAR:
+ case text::RelOrientation::FRAME:
+ rOrientation = text::RelOrientation::PAGE_FRAME;
+ return true;
+ case text::RelOrientation::PRINT_AREA:
+ if (isIgnorePrintArea)
+ {
+ return false;
+ }
+ else
+ {
+ rOrientation = text::RelOrientation::PAGE_PRINT_AREA;
+ return true;
+ }
+ case text::RelOrientation::FRAME_LEFT:
+ rOrientation = text::RelOrientation::PAGE_LEFT;
+ return true;
+ case text::RelOrientation::FRAME_RIGHT:
+ rOrientation = text::RelOrientation::PAGE_RIGHT;
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace sw
+
SfxPoolItem* SwFormatLineNumber::CreateDefault() { return new SwFormatLineNumber; }
static sal_Int16 lcl_IntToRelation(const uno::Any& rVal)
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
index d21756c65720..ddbdf85769db 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -1226,6 +1226,21 @@ void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& a
}
}
}
+ else if (pEntry->nWID == RES_HORI_ORIENT
+ && pEntry->nMemberId == MID_HORIORIENT_RELATION
+ && aSet.Get(RES_ANCHOR).GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ uno::Any value(aValue);
+ sal_Int16 nRelOrient(text::RelOrientation::PAGE_FRAME);
+ aValue >>= nRelOrient;
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
+ value <<= nRelOrient;
+ }
+ m_pPropSet->setPropertyValue( *pEntry, value, aSet );
+ pFormat->SetFormatAttr(aSet);
+ }
else
{
m_pPropSet->setPropertyValue( *pEntry, aValue, aSet );
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index f827226d0be4..a04ac6908b92 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -2744,6 +2744,19 @@ void SwXFrame::attachToRange(uno::Reference<text::XTextRange> const& xTextRange,
aAnchor.SetAnchor( aPam.GetPoint() );
aFrameSet.Put(aAnchor);
}
+
+ if (eAnchorId == RndStdIds::FLY_AT_PAGE)
+ {
+ sal_Int16 nRelOrient(aFrameSet.Get(RES_HORI_ORIENT).GetRelationOrient());
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXFrame: fixing invalid horizontal RelOrientation for at-page anchor");
+
+ SwFormatHoriOrient item(aFrameSet.Get(RES_HORI_ORIENT));
+ item.SetRelationOrient(nRelOrient);
+ aFrameSet.Put(item);
+ }
+ }
}
const ::uno::Any* pStyle;