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

Szymon Kłos szymon.klos at collabora.com
Tue Nov 14 15:50:07 UTC 2017


 oox/source/export/vmlexport.cxx              |   18 ++++++-
 oox/source/vml/vmlshape.cxx                  |   68 ++++++++++++++++++++++++++-
 sw/qa/extras/ooxmlexport/data/watermark.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport10.cxx   |   18 +++++++
 4 files changed, 102 insertions(+), 2 deletions(-)

New commits:
commit a3a917748892a6a3194ebfc4db64cfd764cc054a
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Thu Nov 2 19:53:53 2017 +0100

    tdf#113037 DOCX Watermark correct ratio
    
    Import and export Watermark with padding like MSO does.
    Shape is scaled to save correct ratio.
    
    Change-Id: Iebd8eb5f168e0030320406d4fd6b287e451267bd
    Reviewed-on: https://gerrit.libreoffice.org/44319
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 363dd363cffb..a290db597df7 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -19,6 +19,7 @@
 
 #include <config_folders.h>
 #include <rtl/bootstrap.hxx>
+#include <svl/itemset.hxx>
 #include <oox/export/drawingml.hxx>
 #include <oox/export/vmlexport.hxx>
 
@@ -382,7 +383,22 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
     if ( m_nShapeType == ESCHER_ShpInst_Line )
         AddLineDimensions( rRect );
     else
-        AddRectangleDimensions( m_ShapeStyle, rRect );
+    {
+        if ( IsWaterMarkShape( m_pSdrObject->GetName() ) )
+        {
+            // Watermark need some padding to be compatible with MSO
+            long nPaddingY = 0;
+            const SfxItemSet& rSet = m_pSdrObject->GetMergedItemSet();
+            if ( const SdrMetricItem* pItem = static_cast<const SdrMetricItem*>( rSet.GetItem( SDRATTR_TEXT_UPPERDIST ) ) )
+                nPaddingY += pItem->GetValue();
+
+            tools::Rectangle aRect( rRect );
+            aRect.setHeight( aRect.getHeight() + nPaddingY );
+            AddRectangleDimensions( m_ShapeStyle, aRect );
+        }
+        else
+            AddRectangleDimensions( m_ShapeStyle, rRect );
+    }
 
     // properties
     bool bAlreadyWritten[ 0xFFF ];
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 7679ca838f67..f9fa58669c35 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -72,6 +72,7 @@
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/storagehelper.hxx>
+#include <vcl/svapp.hxx>
 
 using ::com::sun::star::beans::XPropertySet;
 using ::com::sun::star::uno::Any;
@@ -1139,12 +1140,77 @@ CustomShape::CustomShape( Drawing& rDrawing ) :
 {
 }
 
+static OUString lcl_getFontFamily( const oox::OptValue<OUString>& rStyle )
+{
+    OUString sFont = "";
+
+    if( rStyle.has() )
+    {
+        OUString aStyle = rStyle.get( OUString() );
+
+        sal_Int32 nIndex = 0;
+        while( nIndex >= 0 )
+        {
+            OUString aName;
+            if( ConversionHelper::separatePair( aName, sFont, aStyle.getToken( 0, ';', nIndex ), ':' ) )
+            {
+                if( aName == "font-family" )
+                {
+                    // remove " (first, and last character)
+                    if( sFont.getLength() > 2 )
+                        sFont = sFont.copy( 1, sFont.getLength() - 2 );
+                }
+            }
+        }
+    }
+
+    return sFont;
+}
+
+/// modifies rShapeRect's height and returns difference
+sal_Int32 lcl_correctWatermarkRect( awt::Rectangle& rShapeRect, const OUString& sFont, const OUString& sText )
+{
+    sal_Int32 nPaddingY = 0;
+    double fRatio = 0;
+    OutputDevice* pOut = Application::GetDefaultDevice();
+    vcl::Font aFont( pOut->GetFont() );
+    aFont.SetFamilyName( sFont );
+
+    tools::Rectangle aBoundingRect;
+    pOut->GetTextBoundRect( aBoundingRect, sText );
+    if( aBoundingRect.GetWidth() )
+    {
+        fRatio = (double)aBoundingRect.GetHeight() / aBoundingRect.GetWidth();
+
+        sal_Int32 nNewHeight = fRatio * rShapeRect.Width;
+        nPaddingY = rShapeRect.Height - nNewHeight;
+        rShapeRect.Height = nNewHeight;
+    }
+
+    return nPaddingY;
+}
+
 Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
 {
+    awt::Rectangle aShapeRect( rShapeRect );
+
+    // Add padding for Watermark like Word does
+    sal_Int32 nPaddingY = 0;
+    if( getShapeName().match( "PowerPlusWaterMarkObject" ) && maTypeModel.maTextpathModel.moString.has() )
+    {
+        OUString sText = maTypeModel.maTextpathModel.moString.get();
+        OUString sFont = lcl_getFontFamily( maTypeModel.maTextpathModel.moStyle );
+        nPaddingY = lcl_correctWatermarkRect( aShapeRect, sFont, sText );
+    }
+
     // try to create a custom shape
-    Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
+    Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, aShapeRect );
     if( xShape.is() ) try
     {
+        // Remember padding for Watermark
+        if( nPaddingY )
+            PropertySet( xShape ).setAnyProperty( PROP_TextUpperDistance, makeAny( nPaddingY ) );
+
         // create the custom shape geometry
         Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
         xDefaulter->createCustomShapeDefaults( OUString::number( getShapeType() ) );
diff --git a/sw/qa/extras/ooxmlexport/data/watermark.docx b/sw/qa/extras/ooxmlexport/data/watermark.docx
index 8e279e3e857f..98c305af8cab 100644
Binary files a/sw/qa/extras/ooxmlexport/data/watermark.docx and b/sw/qa/extras/ooxmlexport/data/watermark.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 5498eb4f1a02..725209aab686 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <memory>
+#include <sstream>
 #include <config_test.h>
 
 #include <swmodeltestbase.hxx>
@@ -61,6 +62,7 @@
 #include <unotools/streamwrap.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <svx/svdpage.hxx>
+#include <editeng/unoprnms.hxx>
 
 #include <bordertest.hxx>
 
@@ -1714,6 +1716,22 @@ DECLARE_OOXMLEXPORT_TEST( testObjectCrossReference, "object_cross_reference.odt"
     CPPUNIT_ASSERT_EQUAL(sal_uInt16(21), nIndex);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark.docx")
+{
+    uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
+
+    sal_Int32 nTotalHeight = 0;
+    xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST) >>= nTotalHeight;
+    nTotalHeight += xShape->getSize().Height;
+
+    // Rounding errors
+    sal_Int32 nDifference = 5198 - nTotalHeight;
+    std::stringstream ss;
+    ss << "Difference: " << nDifference;
+    CPPUNIT_ASSERT_MESSAGE(ss.str(), nDifference <= 4);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list