diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2017-11-02 19:53:53 +0100 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2017-11-14 16:49:30 +0100 |
commit | a3a917748892a6a3194ebfc4db64cfd764cc054a (patch) | |
tree | 5c314606ace2b7d2712f4ffe3ef342657aeeac52 | |
parent | e128d83b5e7fd2ceb8d5ec9a346a3b7351be79cc (diff) |
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@libreoffice.org>
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
-rw-r--r-- | oox/source/export/vmlexport.cxx | 18 | ||||
-rw-r--r-- | oox/source/vml/vmlshape.cxx | 68 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/watermark.docx | bin | 14766 -> 19473 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport10.cxx | 18 |
4 files changed, 102 insertions, 2 deletions
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 Binary files differindex 8e279e3e857f..98c305af8cab 100644 --- a/sw/qa/extras/ooxmlexport/data/watermark.docx +++ b/sw/qa/extras/ooxmlexport/data/watermark.docx 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: */ |