Kaydet (Commit) e1d6ed94 authored tarafından Szymon Kłos's avatar Szymon Kłos

tdf#116350 Correctly display text on arc

Change-Id: Ice8c141db20d43ccc8d6e2b56004a4a28d2b257a
Reviewed-on: https://gerrit.libreoffice.org/58729
Tested-by: Jenkins
Reviewed-by: 's avatarSzymon Kłos <szymon.klos@collabora.com>
üst 63c91b9c
...@@ -548,13 +548,22 @@ static inline void lcl_createPresetShape( uno::Reference<drawing::XShape>& xShap ...@@ -548,13 +548,22 @@ static inline void lcl_createPresetShape( uno::Reference<drawing::XShape>& xShap
lcl_resetPropertyValue( aGeomPropVec, sEquations ); lcl_resetPropertyValue( aGeomPropVec, sEquations );
lcl_resetPropertyValue( aGeomPropVec, sPath ); 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 // Apply geometry properties
uno::Sequence<beans::PropertyValue> aPropertyValues( uno::Sequence<beans::PropertyValue> aPropertyValues(
comphelper::InitPropertySequence( comphelper::InitPropertySequence(
{ { sTextPath, uno::makeAny( true ) }, { { sTextPath, uno::makeAny( true ) },
{ "TextPathMode", { "TextPathMode",
uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) }, uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) },
{ "ScaleX", uno::Any( false ) } } ) ); { "ScaleX", uno::Any( bScale ) } } ) );
lcl_setPropertyValue( aGeomPropVec, sTextPath, lcl_setPropertyValue( aGeomPropVec, sTextPath,
comphelper::makePropertyValue( sTextPath, aPropertyValues ) ); comphelper::makePropertyValue( sTextPath, aPropertyValues ) );
......
...@@ -1816,6 +1816,39 @@ static inline double getAdjustmentValue( uno::Reference<beans::XPropertySet>& xS ...@@ -1816,6 +1816,39 @@ static inline double getAdjustmentValue( uno::Reference<beans::XPropertySet>& xS
return -1.0; 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() void SdOOXMLExportTest2::testTdf116350TextEffects()
{ {
::sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "sd/qa/unit/data/pptx/tdf116350-texteffects.pptx" ), PPTX ); ::sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "sd/qa/unit/data/pptx/tdf116350-texteffects.pptx" ), PPTX );
...@@ -1825,16 +1858,25 @@ void SdOOXMLExportTest2::testTdf116350TextEffects() ...@@ -1825,16 +1858,25 @@ void SdOOXMLExportTest2::testTdf116350TextEffects()
double fAdjust = getAdjustmentValue( xShape0 ); double fAdjust = getAdjustmentValue( xShape0 );
CPPUNIT_ASSERT_EQUAL( 180.0, fAdjust ); CPPUNIT_ASSERT_EQUAL( 180.0, fAdjust );
bool bScaleX = getScaleXValue( xShape0 );
CPPUNIT_ASSERT_EQUAL( true, bScaleX );
// Default angle for ArchDown // Default angle for ArchDown
uno::Reference<beans::XPropertySet> xShape14( getShapeFromPage( 14, 0, xDocShRef ) ); uno::Reference<beans::XPropertySet> xShape14( getShapeFromPage( 14, 0, xDocShRef ) );
fAdjust = getAdjustmentValue( xShape14 ); fAdjust = getAdjustmentValue( xShape14 );
CPPUNIT_ASSERT_EQUAL( 0.0, fAdjust ); CPPUNIT_ASSERT_EQUAL( 0.0, fAdjust );
bScaleX = getScaleXValue( xShape14 );
CPPUNIT_ASSERT_EQUAL( true, bScaleX );
// Angle directly set // Angle directly set
uno::Reference<beans::XPropertySet> xShape1( getShapeFromPage( 1, 0, xDocShRef ) ); uno::Reference<beans::XPropertySet> xShape1( getShapeFromPage( 1, 0, xDocShRef ) );
fAdjust = getAdjustmentValue( xShape1 ); fAdjust = getAdjustmentValue( xShape1 );
CPPUNIT_ASSERT_EQUAL( 213.25, fAdjust ); CPPUNIT_ASSERT_EQUAL( 213.25, fAdjust );
bScaleX = getScaleXValue( xShape1 );
CPPUNIT_ASSERT_EQUAL( true, bScaleX );
// Export // Export
utl::TempFile tempFile; utl::TempFile tempFile;
xDocShRef = saveAndReload( xDocShRef.get(), PPTX, &tempFile ); xDocShRef = saveAndReload( xDocShRef.get(), PPTX, &tempFile );
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <editeng/fontitem.hxx> #include <editeng/fontitem.hxx>
#include <editeng/postitem.hxx> #include <editeng/postitem.hxx>
#include <editeng/wghtitem.hxx> #include <editeng/wghtitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/charscaleitem.hxx> #include <editeng/charscaleitem.hxx>
#include <svx/EnhancedCustomShapeTypeNames.hxx> #include <svx/EnhancedCustomShapeTypeNames.hxx>
#include <svx/svdorect.hxx> #include <svx/svdorect.hxx>
...@@ -80,9 +81,11 @@ struct FWData // representing the whole text ...@@ -80,9 +81,11 @@ struct FWData // representing the whole text
{ {
std::vector< FWTextArea > vTextAreas; std::vector< FWTextArea > vTextAreas;
double fHorizontalTextScaling; double fHorizontalTextScaling;
double fVerticalTextScaling;
sal_uInt32 nMaxParagraphsPerTextArea; sal_uInt32 nMaxParagraphsPerTextArea;
sal_Int32 nSingleLineHeight; sal_Int32 nSingleLineHeight;
bool bSingleLineMode; bool bSingleLineMode;
bool bScaleX;
}; };
...@@ -99,6 +102,13 @@ static bool InitializeFontWorkData( ...@@ -99,6 +102,13 @@ static bool InitializeFontWorkData(
else else
nTextAreaCount >>= 1; 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 ) if ( nTextAreaCount )
{ {
rFWData.bSingleLineMode = bSingleLineMode; rFWData.bSingleLineMode = bSingleLineMode;
...@@ -158,18 +168,31 @@ void CalculateHorizontalScalingFactor( ...@@ -158,18 +168,31 @@ void CalculateHorizontalScalingFactor(
{ {
double fScalingFactor = 1.0; double fScalingFactor = 1.0;
bool bScalingFactorDefined = false; bool bScalingFactorDefined = false;
rFWData.fVerticalTextScaling = 1.0;
sal_uInt16 i = 0; sal_uInt16 i = 0;
bool bSingleLineMode = false; bool bSingleLineMode = false;
sal_uInt16 nOutlinesCount2d = rOutline2d.Count(); sal_uInt16 nOutlinesCount2d = rOutline2d.Count();
vcl::Font aFont; vcl::Font aFont;
const SvxFontItem& rFontItem(rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTINFO )); const SvxFontItem& rFontItem( rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTINFO ) );
aFont.SetFontHeight(rSdrObjCustomShape.GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea); 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.SetAlignment( ALIGN_TOP );
aFont.SetFamilyName( rFontItem.GetFamilyName() ); aFont.SetFamilyName( rFontItem.GetFamilyName() );
aFont.SetFamily( rFontItem.GetFamily() ); aFont.SetFamily( rFontItem.GetFamily() );
aFont.SetStyleName( rFontItem.GetStyleName() ); 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 ); aFont.SetOrientation( 0 );
// initializing virtual device // initializing virtual device
...@@ -180,6 +203,9 @@ void CalculateHorizontalScalingFactor( ...@@ -180,6 +203,9 @@ void CalculateHorizontalScalingFactor(
if ( nOutlinesCount2d & 1 ) if ( nOutlinesCount2d & 1 )
bSingleLineMode = true; bSingleLineMode = true;
do
{
i = 0;
std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin(); std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end(); std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
while( aTextAreaIter != aTextAreaIEnd ) while( aTextAreaIter != aTextAreaIEnd )
...@@ -191,6 +217,7 @@ void CalculateHorizontalScalingFactor( ...@@ -191,6 +217,7 @@ void CalculateHorizontalScalingFactor(
fWidth += GetLength( rOutline2d.GetObject( i++ ) ); fWidth += GetLength( rOutline2d.GetObject( i++ ) );
fWidth /= 2.0; fWidth /= 2.0;
} }
std::vector< FWParagraphData >::const_iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() ); std::vector< FWParagraphData >::const_iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() ); std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
while( aParagraphIter != aParagraphIEnd ) while( aParagraphIter != aParagraphIEnd )
...@@ -204,9 +231,8 @@ void CalculateHorizontalScalingFactor( ...@@ -204,9 +231,8 @@ void CalculateHorizontalScalingFactor(
fScalingFactor = fScale; fScalingFactor = fScale;
bScalingFactorDefined = true; bScalingFactorDefined = true;
} }
else else if ( fScale < fScalingFactor || ( rFWData.bScaleX && fScalingFactor < 1.0 ) )
{ {
if ( fScale < fScalingFactor )
fScalingFactor = fScale; fScalingFactor = fScale;
} }
} }
...@@ -214,6 +240,18 @@ void CalculateHorizontalScalingFactor( ...@@ -214,6 +240,18 @@ void CalculateHorizontalScalingFactor(
} }
++aTextAreaIter; ++aTextAreaIter;
} }
if (fScalingFactor < 1.0)
{
nFontSize--;
aFont.SetFontHeight( nFontSize );
pVirDev->SetFont( aFont );
}
}
while (rFWData.bScaleX && fScalingFactor < 1.0 && nFontSize > 1 );
if (nFontSize > 1)
rFWData.fVerticalTextScaling = static_cast<double>(nFontSize) / rFontHeight.GetHeight();
rFWData.fHorizontalTextScaling = fScalingFactor; rFWData.fHorizontalTextScaling = fScalingFactor;
} }
...@@ -256,7 +294,9 @@ void GetTextAreaOutline( ...@@ -256,7 +294,9 @@ void GetTextAreaOutline(
nFntItm = EE_CHAR_FONTINFO_CJK; nFntItm = EE_CHAR_FONTINFO_CJK;
const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rSdrObjCustomShape.GetMergedItem( nFntItm )); const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rSdrObjCustomShape.GetMergedItem( nFntItm ));
vcl::Font aFont; vcl::Font aFont;
aFont.SetFontHeight( rFWData.nSingleLineHeight ); aFont.SetFontHeight( rFWData.nSingleLineHeight );
aFont.SetAlignment( ALIGN_TOP ); aFont.SetAlignment( ALIGN_TOP );
aFont.SetFamilyName( rFontItem.GetFamilyName() ); aFont.SetFamilyName( rFontItem.GetFamilyName() );
...@@ -434,18 +474,22 @@ bool GetFontWorkOutline( ...@@ -434,18 +474,22 @@ bool GetFontWorkOutline(
std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin(); std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end(); 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; bool bSameLetterHeights = false;
const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )); const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
const css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "SameLetterHeights" ); const css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "SameLetterHeights" );
if ( pAny ) if ( pAny )
*pAny >>= bSameLetterHeights; *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 ) while ( aTextAreaIter != aTextAreaIEnd )
{ {
GetTextAreaOutline( GetTextAreaOutline(
...@@ -485,6 +529,38 @@ bool GetFontWorkOutline( ...@@ -485,6 +529,38 @@ bool GetFontWorkOutline(
++aParagraphIter; ++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 else
{ {
switch( eHorzAdjust ) switch( eHorzAdjust )
...@@ -671,6 +747,12 @@ void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2d, FWDa ...@@ -671,6 +747,12 @@ void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2d, FWDa
sal_Int32 nTop = rTextAreaBoundRect.Top(); sal_Int32 nTop = rTextAreaBoundRect.Top();
sal_Int32 nWidth = rTextAreaBoundRect.GetWidth(); sal_Int32 nWidth = rTextAreaBoundRect.GetWidth();
sal_Int32 nHeight= rTextAreaBoundRect.GetHeight(); sal_Int32 nHeight= rTextAreaBoundRect.GetHeight();
if (rFWData.bScaleX)
{
nWidth *= rFWData.fHorizontalTextScaling;
}
if ( rFWData.bSingleLineMode && nHeight && nWidth ) if ( rFWData.bSingleLineMode && nHeight && nWidth )
{ {
if ( nOutline2dIdx >= aOutlines2d.Count() ) if ( nOutline2dIdx >= aOutlines2d.Count() )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment