[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - sw/CppunitTest_sw_rtfexport4.mk sw/qa sw/source

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Wed Nov 20 08:31:42 UTC 2019


 sw/CppunitTest_sw_rtfexport4.mk             |    1 
 sw/qa/extras/rtfexport/data/anchor.fodt     |  101 ++++++++++++++++++++++++++++
 sw/qa/extras/rtfexport/rtfexport4.cxx       |   33 +++++++++
 sw/source/filter/ww8/rtfattributeoutput.cxx |   41 ++++++++++-
 sw/source/filter/ww8/rtfattributeoutput.hxx |    1 
 5 files changed, 173 insertions(+), 4 deletions(-)

New commits:
commit 88dced2fb7575a16c409c17fa14473542ad3d8c8
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Nov 18 17:17:29 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Nov 20 09:30:54 2019 +0100

    sw: RTF export: fix invalid RTF for shapes and text frames again
    
    It turns out that commit 4652b911c4376048a452709c953197e1a879a921 wasn't
    quite right: writing out the m_aRunText doesn't necessarily put it in
    the right place, it just happened to work on that bugdoc but in other
    cases the shape may be written before the paragraph properties of the
    paragraph it's in...
    
    So instead change the text frame case to save and restore the run
    related buffers and members, so that the text frame itself can do
    whatever it wants, and the result is appended to m_aRunText.
    
    The members saved are a superset of those saved in
    WriteHeaderFooter_Impl(), writeTextFrame(), TextFootnote_Impl().
    
    Also another thing was missing is that OLE objects would trigger the
    assert because they are also buffered into m_aRunText, e.g.
    ooo46760-1.odt.
    
    Change-Id: Icc6988f8ed19724c593760df46e0254792cd1735
    Reviewed-on: https://gerrit.libreoffice.org/83105
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit da967d5f8f450fbcbe1f595dbfc357eb7c8b3c50)
    Reviewed-on: https://gerrit.libreoffice.org/83181
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/CppunitTest_sw_rtfexport4.mk b/sw/CppunitTest_sw_rtfexport4.mk
index c18f4a769f49..c4ea085ee886 100644
--- a/sw/CppunitTest_sw_rtfexport4.mk
+++ b/sw/CppunitTest_sw_rtfexport4.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_rtfexport4, \
     cppu \
 	cppuhelper \
     sal \
+	svl \
     sfx \
 	sw \
     test \
diff --git a/sw/qa/extras/rtfexport/data/anchor.fodt b/sw/qa/extras/rtfexport/data/anchor.fodt
new file mode 100644
index 000000000000..8b152806e0e2
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/anchor.fodt
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ooo="http://openoffice.org/2004/office" xmlns:loext="urn:org:documentfoundation:names:experimenta
 l:office:xmlns:loext:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns
 :tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2019-11-18T14:16:40.561315956</meta:creation-date><dc:date>2019-11-18T14:20:04.545186431</dc:date><meta:editing-duration>PT3M25S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="2" meta:word-count="2" meta:character-count="12" meta:non-whitespace-character-count="12"/><meta:generator>LibreOfficeDev/6.4.0.0.alpha1$Linux_X86_64 LibreOffice_project/6af445f3ce2c754785c61ac2e74f8f16e3a6a13d</meta:generator></office:meta>
+
+ <office:font-face-decls>
+  <style:font-face style:name="Lohit Devanagari1" svg:font-family="'Lohit Devanagari'"/>
+  <style:font-face style:name="Calibri" svg:font-family="Calibri" style:font-family-generic="swiss"/>
+  <style:font-face style:name="Liberation Sans" svg:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/>
+  <style:font-face style:name="Lohit Devanagari" svg:font-family="'Lohit Devanagari'" style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Source Han Sans CN" svg:font-family="'Source Han Sans CN'" style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Source Han Serif CN" svg:font-family="'Source Han Serif CN'" 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" style:font-name="Calibri" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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" style:font-name="Calibri" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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"/>
+  </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"/>
+  <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
+   <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.247cm" loext:contextual-spacing="false" fo:line-height="115%"/>
+  </style:style>
+  <style:style style:name="Frame_20_contents" style:display-name="Frame contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"/>
+  <style:style style:name="Frame" style:family="graphic">
+   <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" fo:margin-top="0.201cm" fo:margin-bottom="0.201cm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:padding="0.15cm" fo:border="0.06pt solid #000000"/>
+  </style:style>
+
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Frame_20_contents">
+   <style:text-properties officeooo:rsid="000e19a7" officeooo:paragraph-rsid="000e19a7"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard">
+   <style:text-properties officeooo:rsid="000e19a7" officeooo:paragraph-rsid="000e19a7"/>
+  </style:style>
+  <style:style style:name="P3" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="start"/>
+  </style:style>
+  <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame">
+   <style:graphic-properties style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph"/>
+  </style:style>
+  <style:style style:name="gr1" style:family="graphic">
+   <style:graphic-properties draw:textarea-vertical-align="middle" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph"/>
+  </style:style>
+  <style:style style:name="gr2" style:family="graphic">
+   <style:graphic-properties draw:textarea-horizontal-align="justify" draw:textarea-vertical-align="middle" draw:auto-grow-height="false" fo:min-height="1.244cm" fo:min-width="2.461cm" style:run-through="foreground" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph"/>
+  </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: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>
+   <office:forms form:automatic-focus="false" form:apply-design-mode="false">
+    <form:form form:name="Form" form:apply-filter="true" form:command-type="table" form:control-implementation="ooo:com.sun.star.form.component.Form" office:target-frame="">
+     <form:properties>
+      <form:property form:property-name="PropertyChangeNotificationEnabled" office:value-type="boolean" office:boolean-value="true"/>
+      <form:property form:property-name="TargetURL" office:value-type="string" office:string-value=""/>
+     </form:properties>
+     <form:checkbox form:name="Check Box 1" form:control-implementation="ooo:com.sun.star.form.component.CheckBox" xml:id="control1" form:id="control1" form:label="Check Box" form:input-required="false" form:image-position="center">
+      <form:properties>
+       <form:property form:property-name="ControlTypeinMSO" office:value-type="float" office:value="0"/>
+       <form:property form:property-name="DefaultControl" office:value-type="string" office:string-value="com.sun.star.form.control.CheckBox"/>
+       <form:property form:property-name="ObjIDinMSO" office:value-type="float" office:value="65535"/>
+       <form:property form:property-name="SecondaryRefValue" office:value-type="string" office:string-value=""/>
+      </form:properties>
+     </form:checkbox>
+    </form:form>
+   </office:forms>
+
+   <text:p text:style-name="P2">foo<draw:frame draw:style-name="fr1" draw:name="Frame1" text:anchor-type="char" svg:x="12.786cm" svg:y="0.33cm" svg:width="3.625cm" draw:z-index="0">
+     <draw:text-box fo:min-height="1.323cm">
+      <text:p text:style-name="P1">Frame!</text:p>
+     </draw:text-box>
+    </draw:frame><draw:custom-shape text:anchor-type="char" draw:z-index="1" draw:name="Shape1" draw:style-name="gr2" svg:width="2.461cm" svg:height="1.244cm" svg:x="5.907cm" svg:y="0.409cm">
+     <text:p/>
+     <draw:enhanced-geometry svg:viewBox="0 0 21600 21600" draw:type="rectangle" draw:enhanced-path="M 0 0 L 21600 0 21600 21600 0 21600 0 0 Z N"/>
+    </draw:custom-shape><draw:control text:anchor-type="char" draw:z-index="2" draw:name="Shape2" draw:style-name="gr1" draw:text-style-name="P3" svg:width="2.435cm" svg:height="0.927cm" svg:x="2.653cm" svg:y="0.7cm" draw:control="control1"/>bar</text:p>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/rtfexport/rtfexport4.cxx b/sw/qa/extras/rtfexport/rtfexport4.cxx
index 65b1ffbdce9a..270797e2f923 100644
--- a/sw/qa/extras/rtfexport/rtfexport4.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport4.cxx
@@ -12,6 +12,13 @@
 #include <com/sun/star/text/WritingMode2.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
 
+#include <svx/swframetypes.hxx>
+
+#include <doc.hxx>
+#include <unotxdoc.hxx>
+#include <pam.hxx>
+#include <fmtanchr.hxx>
+
 /**
   Split these tests into their own file because they are really really slow
 */
@@ -79,6 +86,32 @@ DECLARE_RTFEXPORT_TEST(testCjklist31, "cjklist31.rtf")
     CPPUNIT_ASSERT_EQUAL(style::NumberingType::DI_ZI_ZH, numFormat);
 }
 
+DECLARE_RTFEXPORT_TEST(testAnchoredAtSamePosition, "anchor.fodt")
+{
+    SwXTextDocument* const pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDoc* const pDoc = pTextDoc->GetDocShell()->GetDoc();
+
+    CPPUNIT_ASSERT_EQUAL(OUString("foobar"), getParagraph(1)->getString());
+
+    SwFrameFormats& rFlys(*pDoc->GetSpzFrameFormats());
+    if (mbExported)
+    { // 2, not 3: the form control becomes a field on export...
+        CPPUNIT_ASSERT_EQUAL(size_t(2), rFlys.size());
+    }
+    else
+    {
+        CPPUNIT_ASSERT_EQUAL(size_t(3), rFlys.size());
+    }
+
+    sal_Int32 const nIndex(mbExported ? 4 : 3);
+    CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_CHAR, rFlys[0]->GetAnchor().GetAnchorId());
+    CPPUNIT_ASSERT_EQUAL(sal_uLong(12), rFlys[0]->GetAnchor().GetContentAnchor()->nNode.GetIndex());
+    CPPUNIT_ASSERT_EQUAL(nIndex, rFlys[0]->GetAnchor().GetContentAnchor()->nContent.GetIndex());
+    CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_CHAR, rFlys[1]->GetAnchor().GetAnchorId());
+    CPPUNIT_ASSERT_EQUAL(sal_uLong(12), rFlys[1]->GetAnchor().GetContentAnchor()->nNode.GetIndex());
+    CPPUNIT_ASSERT_EQUAL(nIndex, rFlys[1]->GetAnchor().GetContentAnchor()->nContent.GetIndex());
+}
+
 DECLARE_RTFEXPORT_TEST(testParaAdjustDistribute, "para-adjust-distribute.rtf")
 {
     // Without the accompanying fix in place, this test would have failed with
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index b9fe1aa50902..d49dba1e57a8 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1874,6 +1874,41 @@ void RtfAttributeOutput::writeTextFrame(const ww8::Frame& rFrame, bool bTextBox)
     }
 }
 
+/** save the current run state around exporting things that contain paragraphs
+    themselves like text frames.
+    TODO: probably more things need to be saved?
+ */
+class SaveRunState
+{
+private:
+    RtfAttributeOutput& m_rRtf;
+    RtfStringBuffer const m_Run;
+    RtfStringBuffer const m_RunText;
+    bool const m_bSingleEmptyRun;
+    bool const m_bInRun;
+
+public:
+    explicit SaveRunState(RtfAttributeOutput& rRtf)
+        : m_rRtf(rRtf)
+        , m_Run(std::move(rRtf.m_aRun))
+        , m_RunText(std::move(rRtf.m_aRunText))
+        , m_bSingleEmptyRun(rRtf.m_bSingleEmptyRun)
+        , m_bInRun(rRtf.m_bInRun)
+    {
+        m_rRtf.m_rExport.setStream();
+    }
+    ~SaveRunState()
+    {
+        m_rRtf.m_aRun = std::move(m_Run);
+        m_rRtf.m_aRunText = std::move(m_RunText);
+        m_rRtf.m_bSingleEmptyRun = m_bSingleEmptyRun;
+        m_rRtf.m_bInRun = m_bInRun;
+
+        m_rRtf.m_aRunText->append(m_rRtf.m_rExport.getStream());
+        m_rRtf.m_rExport.resetStream();
+    }
+};
+
 void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Point& /*rNdTopLeft*/)
 {
     const SwNode* pNode = rFrame.GetContent();
@@ -1887,7 +1922,8 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Poi
             if (RtfSdrExport::isTextBox(rFrame.GetFrameFormat()))
                 break;
 
-            assert(m_aRunText.getLength() == 0 && "this will corrupt the document");
+            SaveRunState const saved(*this);
+
             m_rExport.m_pParentFrame = &rFrame;
 
             m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP);
@@ -1954,14 +1990,12 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Poi
                 m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
                 m_aRunText->append('}');
                 m_rExport.m_pParentFrame = nullptr;
-                m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
             }
 
             if (pGrfNode)
             {
                 m_aRunText.append(dynamic_cast<const SwFlyFrameFormat*>(&rFrame.GetFrameFormat()),
                                   pGrfNode);
-                m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
             }
             break;
         case ww8::Frame::eDrawing:
@@ -1980,7 +2014,6 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Poi
 
                 m_aRunText->append('}');
                 m_aRunText->append('}');
-                m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
             }
         }
         break;
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 4a6b90607af5..1b4799d5978f 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -39,6 +39,7 @@ class RtfExport;
 class RtfAttributeOutput : public AttributeOutputBase
 {
     friend class RtfStringBufferValue;
+    friend class SaveRunState;
 
 public:
     /// Export the state of RTL/CJK.


More information about the Libreoffice-commits mailing list