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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Aug 8 13:58:48 UTC 2018


 oox/source/drawingml/shape.cxx                          |   11 +
 sd/qa/unit/export-tests-ooxml2.cxx                      |   42 ++++
 svx/source/customshapes/EnhancedCustomShapeFontWork.cxx |  148 ++++++++++++----
 3 files changed, 167 insertions(+), 34 deletions(-)

New commits:
commit e1d6ed941590a771abfc73f9eef4a98346eca762
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Tue Aug 7 10:44:21 2018 +0200
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Aug 8 15:58:24 2018 +0200

    tdf#116350 Correctly display text on arc
    
    Change-Id: Ice8c141db20d43ccc8d6e2b56004a4a28d2b257a
    Reviewed-on: https://gerrit.libreoffice.org/58729
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index f49f506eda9d..4f11186254f0 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -548,13 +548,22 @@ static inline void lcl_createPresetShape( uno::Reference<drawing::XShape>& xShap
     lcl_resetPropertyValue( aGeomPropVec, sEquations );
     lcl_resetPropertyValue( aGeomPropVec, sPath );
 
+    // Some shapes don't need scaling
+    bool bScale = true;
+    if ( rPresetType == "textRingInside"
+        || rPresetType == "textRingOutside"
+        || rPresetType == "textCirclePour" )
+    {
+        bScale = false;
+    }
+
     // Apply geometry properties
     uno::Sequence<beans::PropertyValue> aPropertyValues(
         comphelper::InitPropertySequence(
             { { sTextPath, uno::makeAny( true ) },
                 { "TextPathMode",
                 uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) },
-                { "ScaleX", uno::Any( false ) } } ) );
+                { "ScaleX", uno::Any( bScale ) } } ) );
 
     lcl_setPropertyValue( aGeomPropVec, sTextPath,
         comphelper::makePropertyValue( sTextPath, aPropertyValues ) );
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 06a4c343b28e..fe2be051603e 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -1816,6 +1816,39 @@ static inline double getAdjustmentValue( uno::Reference<beans::XPropertySet>& xS
     return -1.0;
 }
 
+static inline bool getScaleXValue(uno::Reference<beans::XPropertySet>& xSet)
+{
+    bool bScaleX = false;
+
+    auto aGeomPropSeq = xSet->getPropertyValue("CustomShapeGeometry")
+        .get<uno::Sequence<beans::PropertyValue>>();
+    auto aGeomPropVec
+        = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(
+            aGeomPropSeq);
+
+    const OUString sName = "TextPath";
+    auto aIterator = std::find_if(
+        aGeomPropVec.begin(), aGeomPropVec.end(),
+        [sName](const beans::PropertyValue& rValue) { return rValue.Name == sName; });
+
+    if (aIterator != aGeomPropVec.end())
+    {
+        uno::Sequence<beans::PropertyValue> aTextPathProperties;
+        aIterator->Value >>= aTextPathProperties;
+        const OUString sScaleX = "ScaleX";
+        auto aIterator2 = std::find_if(
+            aTextPathProperties.begin(), aTextPathProperties.end(),
+            [sScaleX](const beans::PropertyValue& rValue) { return rValue.Name == sScaleX; });
+
+        if (aIterator2 != aTextPathProperties.end())
+        {
+            aIterator2->Value >>= bScaleX;
+        }
+    }
+
+    return bScaleX;
+}
+
 void SdOOXMLExportTest2::testTdf116350TextEffects()
 {
     ::sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "sd/qa/unit/data/pptx/tdf116350-texteffects.pptx" ), PPTX );
@@ -1825,16 +1858,25 @@ void SdOOXMLExportTest2::testTdf116350TextEffects()
     double fAdjust = getAdjustmentValue( xShape0 );
     CPPUNIT_ASSERT_EQUAL( 180.0, fAdjust );
 
+    bool bScaleX = getScaleXValue( xShape0 );
+    CPPUNIT_ASSERT_EQUAL( true, bScaleX );
+
     // Default angle for ArchDown
     uno::Reference<beans::XPropertySet> xShape14( getShapeFromPage( 14, 0, xDocShRef ) );
     fAdjust = getAdjustmentValue( xShape14 );
     CPPUNIT_ASSERT_EQUAL( 0.0, fAdjust );
 
+    bScaleX = getScaleXValue( xShape14 );
+    CPPUNIT_ASSERT_EQUAL( true, bScaleX );
+
     // Angle directly set
     uno::Reference<beans::XPropertySet> xShape1( getShapeFromPage( 1, 0, xDocShRef ) );
     fAdjust = getAdjustmentValue( xShape1 );
     CPPUNIT_ASSERT_EQUAL( 213.25, fAdjust );
 
+    bScaleX = getScaleXValue( xShape1 );
+    CPPUNIT_ASSERT_EQUAL( true, bScaleX );
+
     // Export
     utl::TempFile tempFile;
     xDocShRef = saveAndReload( xDocShRef.get(), PPTX, &tempFile );
diff --git a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
index 9c02499a7a9b..5ce861bc0407 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
@@ -33,6 +33,7 @@
 #include <editeng/fontitem.hxx>
 #include <editeng/postitem.hxx>
 #include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
 #include <editeng/charscaleitem.hxx>
 #include <svx/EnhancedCustomShapeTypeNames.hxx>
 #include <svx/svdorect.hxx>
@@ -80,9 +81,11 @@ struct FWData                           // representing the whole text
 {
     std::vector< FWTextArea >           vTextAreas;
     double                              fHorizontalTextScaling;
+    double                              fVerticalTextScaling;
     sal_uInt32                          nMaxParagraphsPerTextArea;
     sal_Int32                           nSingleLineHeight;
     bool                                bSingleLineMode;
+    bool                                bScaleX;
 };
 
 
@@ -99,6 +102,13 @@ static bool InitializeFontWorkData(
     else
         nTextAreaCount >>= 1;
 
+    const SdrCustomShapeGeometryItem& rGeometryItem( rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+    const css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "ScaleX" );
+    if (pAny)
+        *pAny >>= rFWData.bScaleX;
+    else
+        rFWData.bScaleX = false;
+
     if ( nTextAreaCount )
     {
         rFWData.bSingleLineMode = bSingleLineMode;
@@ -158,18 +168,31 @@ void CalculateHorizontalScalingFactor(
 {
     double fScalingFactor = 1.0;
     bool bScalingFactorDefined = false;
+    rFWData.fVerticalTextScaling = 1.0;
 
     sal_uInt16 i = 0;
     bool bSingleLineMode = false;
     sal_uInt16 nOutlinesCount2d = rOutline2d.Count();
 
     vcl::Font aFont;
-    const SvxFontItem& rFontItem(rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTINFO ));
-    aFont.SetFontHeight(rSdrObjCustomShape.GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea);
+    const SvxFontItem& rFontItem( rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTINFO ) );
+    const SvxFontHeightItem& rFontHeight( rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTHEIGHT ) );
+    sal_Int32 nFontSize = rFontHeight.GetHeight();
+
+    if (rFWData.bScaleX)
+        aFont.SetFontHeight( nFontSize );
+    else
+        aFont.SetFontHeight( rSdrObjCustomShape.GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea );
+
     aFont.SetAlignment( ALIGN_TOP );
     aFont.SetFamilyName( rFontItem.GetFamilyName() );
     aFont.SetFamily( rFontItem.GetFamily() );
     aFont.SetStyleName( rFontItem.GetStyleName() );
+    const SvxPostureItem& rPostureItem = rSdrObjCustomShape.GetMergedItem( EE_CHAR_ITALIC );
+    aFont.SetItalic( rPostureItem.GetPosture() );
+
+    const SvxWeightItem& rWeightItem = rSdrObjCustomShape.GetMergedItem( EE_CHAR_WEIGHT );
+    aFont.SetWeight( rWeightItem.GetWeight() );
     aFont.SetOrientation( 0 );
     // initializing virtual device
 
@@ -180,40 +203,55 @@ void CalculateHorizontalScalingFactor(
     if ( nOutlinesCount2d & 1 )
         bSingleLineMode = true;
 
-    std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
-    std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
-    while( aTextAreaIter != aTextAreaIEnd )
+    do
     {
-        // calculating the width of the corresponding 2d text area
-        double fWidth = GetLength( rOutline2d.GetObject( i++ ) );
-        if ( !bSingleLineMode )
-        {
-            fWidth += GetLength( rOutline2d.GetObject( i++ ) );
-            fWidth /= 2.0;
-        }
-        std::vector< FWParagraphData >::const_iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
-        std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
-        while( aParagraphIter != aParagraphIEnd )
+        i = 0;
+        std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
+        std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
+        while( aTextAreaIter != aTextAreaIEnd )
         {
-            double fTextWidth = pVirDev->GetTextWidth( aParagraphIter->aString );
-            if ( fTextWidth > 0.0 )
+            // calculating the width of the corresponding 2d text area
+            double fWidth = GetLength( rOutline2d.GetObject( i++ ) );
+            if ( !bSingleLineMode )
             {
-                double fScale = fWidth / fTextWidth;
-                if ( !bScalingFactorDefined )
-                {
-                    fScalingFactor = fScale;
-                    bScalingFactorDefined = true;
-                }
-                else
+                fWidth += GetLength( rOutline2d.GetObject( i++ ) );
+                fWidth /= 2.0;
+            }
+
+            std::vector< FWParagraphData >::const_iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
+            std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
+            while( aParagraphIter != aParagraphIEnd )
+            {
+                double fTextWidth = pVirDev->GetTextWidth( aParagraphIter->aString );
+                if ( fTextWidth > 0.0 )
                 {
-                    if ( fScale < fScalingFactor )
+                    double fScale = fWidth / fTextWidth;
+                    if ( !bScalingFactorDefined )
+                    {
                         fScalingFactor = fScale;
+                        bScalingFactorDefined = true;
+                    }
+                    else if ( fScale < fScalingFactor || ( rFWData.bScaleX && fScalingFactor < 1.0 ) )
+                    {
+                        fScalingFactor = fScale;
+                    }
                 }
+                ++aParagraphIter;
             }
-            ++aParagraphIter;
+            ++aTextAreaIter;
+        }
+
+        if (fScalingFactor < 1.0)
+        {
+            nFontSize--;
+            aFont.SetFontHeight( nFontSize );
+            pVirDev->SetFont( aFont );
         }
-        ++aTextAreaIter;
     }
+    while (rFWData.bScaleX && fScalingFactor < 1.0 && nFontSize > 1 );
+
+    if (nFontSize > 1)
+        rFWData.fVerticalTextScaling = static_cast<double>(nFontSize) / rFontHeight.GetHeight();
     rFWData.fHorizontalTextScaling = fScalingFactor;
 }
 
@@ -256,7 +294,9 @@ void GetTextAreaOutline(
                 nFntItm = EE_CHAR_FONTINFO_CJK;
             const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rSdrObjCustomShape.GetMergedItem( nFntItm ));
             vcl::Font aFont;
+
             aFont.SetFontHeight( rFWData.nSingleLineHeight );
+
             aFont.SetAlignment( ALIGN_TOP );
 
             aFont.SetFamilyName( rFontItem.GetFamilyName() );
@@ -434,18 +474,22 @@ bool GetFontWorkOutline(
     std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
     std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
 
-    rFWData.nSingleLineHeight = static_cast<sal_Int32>( ( static_cast<double>(rSdrObjCustomShape.GetLogicRect().GetHeight())
-                                                / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
-
-    if (rFWData.nSingleLineHeight == SAL_MIN_INT32)
-        return false;
-
     bool bSameLetterHeights = false;
     const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     const css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "SameLetterHeights" );
     if ( pAny )
         *pAny >>= bSameLetterHeights;
 
+    const SvxFontHeightItem& rFontHeight( rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTHEIGHT ) );
+    if (rFWData.bScaleX)
+        rFWData.nSingleLineHeight = rFWData.fVerticalTextScaling * rFontHeight.GetHeight();
+    else
+        rFWData.nSingleLineHeight = static_cast<sal_Int32>( ( static_cast<double>( rSdrObjCustomShape.GetLogicRect().GetHeight() )
+                                                    / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
+
+    if (rFWData.nSingleLineHeight == SAL_MIN_INT32)
+        return false;
+
     while ( aTextAreaIter != aTextAreaIEnd )
     {
         GetTextAreaOutline(
@@ -485,6 +529,38 @@ bool GetFontWorkOutline(
                 ++aParagraphIter;
             }
         }
+        else if (rFWData.bScaleX)
+        {
+            std::vector< FWParagraphData >::iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
+            std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
+            while ( aParagraphIter != aParagraphIEnd )
+            {
+                sal_Int32 nHorzDiff = 0;
+                if ( eHorzAdjust == SDRTEXTHORZADJUST_CENTER )
+                    nHorzDiff = ( rFWData.fHorizontalTextScaling * aTextAreaIter->aBoundRect.GetWidth() - aParagraphIter->aBoundRect.GetWidth() ) / 2;
+                else if ( eHorzAdjust == SDRTEXTHORZADJUST_RIGHT )
+                    nHorzDiff = ( rFWData.fHorizontalTextScaling * aTextAreaIter->aBoundRect.GetWidth() - aParagraphIter->aBoundRect.GetWidth() );
+
+                if (nHorzDiff)
+                {
+                    std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
+                    std::vector< FWCharacterData >::const_iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
+                    while ( aCharacterIter != aCharacterIEnd )
+                    {
+                        std::vector< tools::PolyPolygon >::iterator aOutlineIter = aCharacterIter->vOutlines.begin();
+                        std::vector< tools::PolyPolygon >::const_iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
+                        while( aOutlineIter != aOutlineIEnd )
+                        {
+                            aOutlineIter->Move( nHorzDiff, 0 );
+                            ++aOutlineIter;
+                        }
+                        ++aCharacterIter;
+                    }
+                }
+
+                ++aParagraphIter;
+            }
+        }
         else
         {
             switch( eHorzAdjust )
@@ -671,6 +747,12 @@ void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2d, FWDa
         sal_Int32 nTop = rTextAreaBoundRect.Top();
         sal_Int32 nWidth = rTextAreaBoundRect.GetWidth();
         sal_Int32 nHeight= rTextAreaBoundRect.GetHeight();
+
+        if (rFWData.bScaleX)
+        {
+            nWidth *= rFWData.fHorizontalTextScaling;
+        }
+
         if ( rFWData.bSingleLineMode && nHeight && nWidth )
         {
             if ( nOutline2dIdx >= aOutlines2d.Count() )


More information about the Libreoffice-commits mailing list