summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2018-08-07 10:44:21 +0200
committerAndras Timar <andras.timar@collabora.com>2018-08-20 10:14:41 +0200
commit40b396ef207213ebd07981206674a2260256cb3c (patch)
treeaed1e5334a28cfa67dbe709fd4ac4ad8edb2f358
parent406280c62843e9ed167e7adaa005fba92a39608f (diff)
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@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/58840 Reviewed-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--oox/source/drawingml/shape.cxx11
-rw-r--r--sd/qa/unit/export-tests-ooxml2.cxx42
-rw-r--r--svx/source/customshapes/EnhancedCustomShapeFontWork.cxx148
3 files changed, 167 insertions, 34 deletions
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index f13fa4a2f56f..5483dcc06ff1 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -547,13 +547,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 1f246fec7a90..80cd202c533c 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -1717,6 +1717,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 );
@@ -1726,16 +1759,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 9bfed5d53ab4..0419038f0fda 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>
@@ -79,9 +80,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;
};
@@ -98,6 +101,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;
@@ -157,18 +167,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
@@ -179,40 +202,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;
}
@@ -255,7 +293,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() );
@@ -433,18 +473,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(
@@ -484,6 +528,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 )
@@ -670,6 +746,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() )