[Libreoffice-commits] core.git: oox/source sw/qa sw/source writerfilter/source

Michael Stahl mstahl at redhat.com
Thu Nov 2 21:37:55 UTC 2017


 oox/source/vml/vmlshape.cxx                           |   61 +++++++++---------
 sw/qa/extras/odfimport/data/Word2010AsCharShape.odt   |binary
 sw/qa/extras/odfimport/odfimport.cxx                  |    9 ++
 sw/qa/extras/ooxmlexport/ooxmlexport6.cxx             |    6 +
 sw/source/core/unocore/unodraw.cxx                    |   10 ++
 writerfilter/source/rtftok/rtfdispatchdestination.cxx |    3 
 6 files changed, 57 insertions(+), 32 deletions(-)

New commits:
commit c79467ba954987f1d239c594c1e1b3af3f5515f6
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Nov 2 22:13:32 2017 +0100

    sw: ODF import: default as-char shapes to vertical-pos="top"
    
    The problem is that we don't render ShapesWithWrapping.odt
    the same as Word does:
    
    https://beta.opendocumentformat.org/rendercompare/upload/223/86/191/1
    
    The first shape in the file is anchored "as-char" and has no
    style:vertical-rel or style:vertical-pos attribute affecting it.
    
    If Word would write either style:vertical-rel="baseline" or
    style:vertical-pos="top" explicitly, the rendering in LO would
    be the same.
    
    So the problem is that, for drawing shapes (note, text frames are
    images, embedded objects handled differently), LO's default
    vertical alignment is different, it is hard-coded in
    SwShapeDescriptor_Impl::GetVOrient() as
    SwFormatVertOrient(0, text::VertOrientation::NONE, text::RelOrientation::FRAME)
    
    This effectively positions as-char shapes *below* the baseline,
    which, while technically allowed, isn't really a good default.
    
    So fix this by making the default alignment dependent on the anchor
    type, so that as-char shapes sit on top of the baseline.
    
    The ODF filter sets the anchor type before inserting the shape in
    XMLTextShapeImportHelper::addShape(), however as it turns out the
    various MSO filters insert the shape before setting the anchor,
    which means the new default in SwXShape has an unwanted effect
    on them, as inserting the shape causes the default to be created.
    
    This requires changes to VML import to always set the VertOrient
    property, and to RTF import to set the anchor type before inserting.
    
    The DrawingML import is unaffected as it already sets VertOrient
    for every non-as-char shape.
    
    The testDmlTextshape "dml-textshape.docx" test still fails, but it
    turns out that the change in alignment for this test document is
    a bugfix, as it now has the same vertical alignment as in Word,
    so adapt the test.
    
    Change-Id: Ifcabd96a037515f7803f5474ec995f968b3b4de1

diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 2c1acb029916..74ae15f848f3 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -564,6 +564,39 @@ void lcl_setSurround(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel, co
 
 void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel, const GraphicHelper& rGraphicHelper)
 {
+    if ( rTypeModel.maPosition == "absolute" )
+    {
+        // Word supports as-character (inline) and at-character only, absolute can't be inline.
+        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
+        // anchor is set after insertion, so reset to NONE
+        rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::NONE));
+
+        if ( rTypeModel.maPositionVerticalRelative == "page" )
+        {
+            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
+        }
+        else if ( rTypeModel.maPositionVerticalRelative == "margin" )
+        {
+            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
+        }
+        else
+        {
+            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
+        }
+    }
+    else if( rTypeModel.maPosition == "relative" )
+    {   // I'm not very sure this is correct either.
+        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
+        // anchor is set after insertion, so reset to NONE
+        rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::NONE));
+    }
+    else // static (is the default) means anchored inline
+    {
+        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
+        // Use top orientation, this one seems similar to what MSO uses as inline
+        rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::TOP));
+    }
+
     if ( rTypeModel.maPositionHorizontal == "center" )
         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
     else if ( rTypeModel.maPositionHorizontal == "left" )
@@ -599,34 +632,6 @@ void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel,
     else if ( rTypeModel.maPositionVertical == "outside" )
         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::LINE_BOTTOM));
 
-    if ( rTypeModel.maPosition == "absolute" )
-    {
-        // Word supports as-character (inline) and at-character only, absolute can't be inline.
-        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
-
-        if ( rTypeModel.maPositionVerticalRelative == "page" )
-        {
-            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
-        }
-        else if ( rTypeModel.maPositionVerticalRelative == "margin" )
-        {
-            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
-        }
-        else
-        {
-            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
-        }
-    }
-    else if( rTypeModel.maPosition == "relative" )
-    {   // I'm not very sure this is correct either.
-        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
-    }
-    else // static (is the default) means anchored inline
-    {
-        rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
-        // Use top orientation, this one seems similar to what MSO uses as inline
-        rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::TOP));
-    }
     lcl_setSurround( rPropSet, rTypeModel, rGraphicHelper );
 }
 
diff --git a/sw/qa/extras/odfimport/data/Word2010AsCharShape.odt b/sw/qa/extras/odfimport/data/Word2010AsCharShape.odt
new file mode 100644
index 000000000000..06c917f6a825
Binary files /dev/null and b/sw/qa/extras/odfimport/data/Word2010AsCharShape.odt differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index 67a6873f5617..365c01c21949 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -20,6 +20,7 @@
 #include <com/sun/star/text/XTextSection.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/PageNumberType.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
 
 #include <wrtsh.hxx>
 #include <ndtxt.hxx>
@@ -791,6 +792,14 @@ DECLARE_ODFIMPORT_TEST(testTdf100033_1, "tdf100033_1.odt")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
 }
 
+DECLARE_ODFIMPORT_TEST(testWordAsCharShape, "Word2010AsCharShape.odt")
+{
+    // As-char shape had VertOrient "from-top"/NONE default from GetVOrient()
+    uno::Reference<drawing::XShape> const xShape(getShape(1));
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, getProperty<text::TextContentAnchorType>(xShape, "AnchorType"));
+    CPPUNIT_ASSERT_EQUAL(text::VertOrientation::TOP, getProperty<sal_Int16>(xShape, "VertOrient"));
+}
+
 DECLARE_ODFIMPORT_TEST(testTdf100033_2, "tdf100033_2.odt")
 {
     // Test document have three different frames anchored to different paragraphs -> import all frames
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index 66ac2feaa876..880d05aafbb6 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/style/LineSpacingMode.hpp>
 #include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
 
 #include <comphelper/sequenceashashmap.hxx>
 
@@ -88,6 +89,7 @@ DECLARE_OOXMLEXPORT_TEST(testDmlGroupshapeRelsize, "dml-groupshape-relsize.docx"
 DECLARE_OOXMLEXPORT_TEST(testDmlTextshape, "dml-textshape.docx")
 {
     uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(text::VertOrientation::TOP, getProperty<sal_Int16>(xGroup, "VertOrient"));
     uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(1), uno::UNO_QUERY);
     // This was drawing::FillStyle_NONE.
     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xShape, "FillStyle"));
@@ -105,11 +107,11 @@ DECLARE_OOXMLEXPORT_TEST(testDmlTextshape, "dml-textshape.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("ooxml-bentConnector3"), aType);
     // Connector was incorrectly shifted towards the top left corner, X was 552, Y was 0.
     CPPUNIT_ASSERT_EQUAL(sal_Int32(4018), xShape->getPosition().X);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(1256), xShape->getPosition().Y);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-4487), xShape->getPosition().Y);
 
     xShape.set(xGroup->getByIndex(5), uno::UNO_QUERY);
     // This was incorrectly shifted towards the top of the page, Y was 106.
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(1016), xShape->getPosition().Y);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-4727), xShape->getPosition().Y);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testDMLSolidfillAlpha, "dml-solidfill-alpha.docx")
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
index 2dc746ca6f7f..d6732961b804 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -149,8 +149,14 @@ public:
         {
             if(bCreate && !pVOrient)
             {
-                // #i26791#
-                pVOrient = new SwFormatVertOrient( 0, text::VertOrientation::NONE, text::RelOrientation::FRAME );
+                if (!GetAnchor(true) || pAnchor->GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+                {   // for as-char, NONE ("from-top") is not a good default
+                    pVOrient = new SwFormatVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME);
+                }
+                else
+                {   // #i26791#
+                    pVOrient = new SwFormatVertOrient(0, text::VertOrientation::NONE, text::RelOrientation::FRAME);
+                }
             }
             return pVOrient;
         }
diff --git a/writerfilter/source/rtftok/rtfdispatchdestination.cxx b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
index ed5748ab0c85..d6c1d1f5dc15 100644
--- a/writerfilter/source/rtftok/rtfdispatchdestination.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
@@ -11,6 +11,7 @@
 
 #include <com/sun/star/document/DocumentProperties.hpp>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
 
 #include <filter/msfilter/escherex.hxx>
 #include <rtl/character.hxx>
@@ -590,6 +591,8 @@ RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
                 if (xDrawSupplier.is())
                 {
                     uno::Reference<drawing::XShape> xShape(xGroupShape, uno::UNO_QUERY);
+                    // set AnchorType before inserting
+                    uno::Reference<beans::XPropertySet>(xShape, uno::UNO_QUERY)->setPropertyValue("AnchorType", uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
                     xDrawSupplier->getDrawPage()->add(xShape);
                 }
                 m_pSdrImport->pushParent(xGroupShape);


More information about the Libreoffice-commits mailing list