45 #include <com/sun/star/i18n/BreakIterator.hpp>
46 #include <com/sun/star/i18n/ScriptType.hpp>
50 #include <rtl/math.hxx>
57 struct FWCharacterData
59 std::vector< tools::PolyPolygon > vOutlines;
62 struct FWParagraphData
65 std::vector< FWCharacterData > vCharacters;
71 std::vector< FWParagraphData > vParagraphs;
76 std::vector< FWTextArea > vTextAreas;
77 double fHorizontalTextScaling;
78 double fVerticalTextScaling;
79 sal_uInt32 nMaxParagraphsPerTextArea;
80 sal_Int32 nSingleLineHeight;
89 const sal_uInt16 nOutlinesCount2d,
93 bool bSingleLineMode =
false;
94 sal_uInt16 nTextAreaCount = nOutlinesCount2d;
95 if ( nOutlinesCount2d & 1 )
96 bSingleLineMode =
true;
103 *pAny >>= rFWData.bScaleX;
105 rFWData.bScaleX =
false;
107 if ( nTextAreaCount )
109 rFWData.bSingleLineMode = bSingleLineMode;
119 rFWData.nMaxParagraphsPerTextArea = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
121 while( nParagraphsLeft && nTextAreaCount )
123 FWTextArea aTextArea;
124 sal_Int32
i, nParagraphs = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
125 for ( i = 0; i < nParagraphs; ++i, ++j )
127 FWParagraphData aParagraphData;
128 aParagraphData.aString = rTextObj.
GetText( j );
132 aTextArea.vParagraphs.push_back( aParagraphData );
134 rFWData.vTextAreas.push_back( aTextArea );
135 nParagraphsLeft -= nParagraphs;
157 bool bSingleLineMode,
161 bool bScalingFactorDefined =
false;
162 for(
const auto& rTextArea : rFWData.vTextAreas )
166 if ( !bSingleLineMode )
172 for(
const auto& rParagraph : rTextArea.vParagraphs )
174 double fTextWidth = pVirDev->
GetTextWidth( rParagraph.aString );
175 if ( fTextWidth > 0.0 )
177 double fScale = fWidth / fTextWidth;
178 if ( !bScalingFactorDefined )
180 rScalingFactor = fScale;
181 bScalingFactorDefined =
true;
183 else if (fScale < rScalingFactor)
185 rScalingFactor = fScale;
199 double fScalingFactor = 1.0;
200 rFWData.fVerticalTextScaling = 1.0;
202 bool bSingleLineMode =
false;
203 sal_uInt16 nOutlinesCount2d = rOutline2d.
Count();
208 sal_Int32 nFontSize = rFontHeight.
GetHeight();
210 SAL_WARN_IF(nFontSize >
SAL_MAX_INT16,
"svx",
"CalculateHorizontalScalingFactor suspiciously large font height: " << nFontSize);
219 aFont.
SetFamily( rFontItem.GetFamily() );
230 pVirDev->SetMapMode(
MapMode(MapUnit::Map100thMM));
231 pVirDev->SetFont( aFont );
233 if ( nOutlinesCount2d & 1 )
234 bSingleLineMode =
true;
242 UpdateScalingMode(rFWData, rOutline2d, bSingleLineMode, pVirDev, fScalingFactor);
244 if (fScalingFactor < 1.0)
250 sal_Int32 nOrigFontSize = nFontSize;
251 double fOrigScalingFactor = fScalingFactor;
256 pVirDev->SetFont(aFont);
257 UpdateScalingMode(rFWData, rOutline2d, bSingleLineMode, pVirDev, fScalingFactor);
260 const bool bHopeLess = fScalingFactor < 1.0;
265 nFontSize = nOrigFontSize;
266 fScalingFactor = fOrigScalingFactor;
269 double nEstimatedFinalFontSize = nFontSize * fScalingFactor;
270 double nOnePercentFontSize = nFontSize / 100.0;
271 if (nEstimatedFinalFontSize < nOnePercentFontSize)
273 nFontSize = std::max<int>(16, std::ceil(5 * nEstimatedFinalFontSize));
274 SAL_WARN(
"svx",
"CalculateHorizontalScalingFactor skipping direct to: " << nFontSize <<
" from " << rFontHeight.GetHeight());
280 pVirDev->SetFont( aFont );
283 while (rFWData.bScaleX && fScalingFactor < 1.0 && nFontSize > 1 );
286 rFWData.fVerticalTextScaling =
static_cast<double>(nFontSize) / rFontHeight.GetHeight();
288 rFWData.fHorizontalTextScaling = fScalingFactor;
292 const FWData& rFWData,
294 FWTextArea& rTextArea,
295 bool bSameLetterHeights)
298 sal_Int32 nVerticalOffset = rFWData.nMaxParagraphsPerTextArea > rTextArea.vParagraphs.size()
299 ? rFWData.nSingleLineHeight / 2 : 0;
301 for(
auto& rParagraph : rTextArea.vParagraphs )
303 const OUString& rText = rParagraph.aString;
304 if ( !rText.isEmpty() )
307 sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
311 nScriptType = xBI->getScriptType( rText, 0 );
312 if( i18n::ScriptType::WEAK == nScriptType )
314 sal_Int32 nChg = xBI->endOfScript( rText, 0, nScriptType );
315 if (nChg < rText.getLength() && nChg >= 0)
316 nScriptType = xBI->getScriptType( rText, nChg );
318 nScriptType = i18n::ScriptType::LATIN;
322 if ( nScriptType == i18n::ScriptType::COMPLEX )
324 else if ( nScriptType == i18n::ScriptType::ASIAN )
346 pVirDev->SetMapMode(
MapMode(MapUnit::Map100thMM));
347 pVirDev->SetFont( aFont );
348 pVirDev->EnableRTL();
349 if ( rParagraph.nFrameDirection == SvxFrameDirection::Horizontal_RL_TB )
353 sal_uInt16 nCharScaleWidth = rCharScaleWidthItem.GetValue();
354 sal_Int32 nWidth = 0;
361 sal_Int32 nHeight = 0;
363 for ( i = 0; i < rText.getLength(); i++ )
365 FWCharacterData aCharacterData;
366 OUString aCharText( rText[ i ] );
367 if ( pVirDev->GetTextOutlines( aCharacterData.vOutlines, aCharText, 0, 0, -1, nWidth, {} ) )
369 sal_Int32 nTextWidth = pVirDev->GetTextWidth( aCharText);
370 if ( aCharacterData.vOutlines.empty() )
372 nHeight += rFWData.nSingleLineHeight;
376 for (
auto& rOutline : aCharacterData.vOutlines )
379 rOutline.Rotate(
Point( nTextWidth / 2, rFWData.nSingleLineHeight / 2 ), 900_deg10 );
380 aCharacterData.aBoundRect.Union( rOutline.GetBoundRect() );
382 for (
auto& rOutline : aCharacterData.vOutlines )
384 sal_Int32 nM = - aCharacterData.aBoundRect.Left() + nHeight;
385 rOutline.Move( nM, 0 );
386 aCharacterData.aBoundRect.Move( nM, 0 );
388 nHeight += aCharacterData.aBoundRect.GetWidth() + ( rFWData.nSingleLineHeight / 5 );
389 aSingleCharacterUnion.
Union( aCharacterData.aBoundRect );
392 rParagraph.vCharacters.push_back( aCharacterData );
394 for (
auto& rCharacter : rParagraph.vCharacters )
396 for (
auto& rOutline : rCharacter.vOutlines )
398 rOutline.
Move( ( aSingleCharacterUnion.
GetWidth() - rCharacter.aBoundRect.GetWidth() ) / 2, 0 );
404 std::vector<sal_Int32> aDXArry;
405 if ( ( nCharScaleWidth != 100 ) && nCharScaleWidth )
407 pVirDev->GetTextArray( rText, &aDXArry);
408 FontMetric aFontMetric( pVirDev->GetFontMetric() );
409 aFont.
SetAverageFontWidth( static_cast<sal_Int32>( static_cast<double>(aFontMetric.GetAverageFontWidth()) * (
double(100) /
static_cast<double>(nCharScaleWidth) ) ) );
410 pVirDev->SetFont( aFont );
412 FWCharacterData aCharacterData;
413 if ( pVirDev->GetTextOutlines( aCharacterData.vOutlines, rText, 0, 0, -1, nWidth, aDXArry ) )
415 rParagraph.vCharacters.push_back( aCharacterData );
423 pVirDev->GetTextArray( rText, &aDXArry);
424 aCharacterData.vOutlines.clear();
428 for(
size_t a(0);
a < aDXArry.size();
a++)
433 0 ==
a ? 0 : aDXArry[
a - 1],
448 aDXArry.empty() ? 10 : aDXArry.back(),
455 rParagraph.vCharacters.push_back( aCharacterData );
460 for (
auto& rCharacter : rParagraph.vCharacters )
464 if ( nVerticalOffset )
465 rPolyPoly.
Move( 0, nVerticalOffset );
469 rParagraph.aBoundRect.
Union( aBoundRect );
474 if ( rParagraph.aBoundRect.IsEmpty() )
476 if ( rTextArea.aBoundRect.IsEmpty() )
479 rTextArea.aBoundRect.AdjustBottom(rFWData.nSingleLineHeight );
484 rTextArea.aBoundRect.Union( rParagraphBoundRect );
486 if ( bSameLetterHeights )
488 for (
auto& rCharacter : rParagraph.vCharacters )
490 for(
auto& rOutline : rCharacter.vOutlines )
493 if (aPolyPolyBoundRect.GetHeight() != rParagraphBoundRect.
GetHeight() && aPolyPolyBoundRect.GetHeight())
494 rOutline.Scale( 1.0, static_cast<double>(rParagraphBoundRect.
GetHeight()) / aPolyPolyBoundRect.GetHeight() );
495 aPolyPolyBoundRect = rOutline.GetBoundRect();
496 sal_Int32 nMove = aPolyPolyBoundRect.
Top() - rParagraphBoundRect.
Top();
498 rOutline.Move( 0, -nMove );
504 nVerticalOffset -= rFWData.nSingleLineHeight;
506 nVerticalOffset += rFWData.nSingleLineHeight;
517 bool bSameLetterHeights =
false;
521 *pAny >>= bSameLetterHeights;
525 rFWData.nSingleLineHeight = rFWData.fVerticalTextScaling * rFontHeight.GetHeight();
527 rFWData.nSingleLineHeight =
static_cast<sal_Int32
>( (
static_cast<double>( rSdrObjCustomShape.
GetLogicRect().
GetHeight() )
528 / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
533 for (
auto& rTextArea : rFWData.vTextAreas )
541 if (eFTS == drawing::TextFitToSizeType_ALLLINES ||
544 eFTS == drawing::TextFitToSizeType_PROPORTIONAL)
546 for (
auto& rParagraph : rTextArea.vParagraphs )
548 sal_Int32 nParaWidth = rParagraph.aBoundRect.GetWidth();
551 double fScale =
static_cast<double>(rTextArea.aBoundRect.GetWidth()) / nParaWidth;
553 for (
auto& rCharacter : rParagraph.vCharacters )
555 for(
auto& rOutline : rCharacter.vOutlines )
557 rOutline.Scale( fScale, 1.0 );
563 else if (rFWData.bScaleX)
568 for (
auto& rParagraph : rTextArea.vParagraphs )
570 sal_Int32 nHorzDiff = 0;
571 sal_Int32 nVertDiff =
static_cast<double>( rFWData.nSingleLineHeight ) * fFactor * ( rTextArea.vParagraphs.size() - 1 );
574 nHorzDiff = ( rFWData.fHorizontalTextScaling * rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() ) / 2;
576 nHorzDiff = ( rFWData.fHorizontalTextScaling * rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() );
578 if (nHorzDiff || nVertDiff)
580 for (
auto& rCharacter : rParagraph.vCharacters )
582 for(
auto& rOutline : rCharacter.vOutlines )
584 rOutline.Move( nHorzDiff, nVertDiff );
592 switch( eHorzAdjust )
597 for (
auto& rParagraph : rTextArea.vParagraphs )
599 sal_Int32 nHorzDiff = 0;
601 nHorzDiff = ( rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() ) / 2;
603 nHorzDiff = ( rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() );
606 for (
auto& rCharacter : rParagraph.vCharacters )
608 for(
auto& rOutline : rCharacter.vOutlines )
610 rOutline.Move( nHorzDiff, 0 );
632 while( aObjListIter.
IsMore() )
635 if (
auto pPathObj = dynamic_cast<const SdrPathObj*>( pPartObj))
638 if(aCandidate.areControlPointsUsed())
642 aOutlines2d.
append(aCandidate);
655 for ( i = 0; i < nCount; i++ )
657 double fDistance = i ? rPoly.
CalcDistance( i, i - 1 ) : 0.0;
658 rDistances.push_back( fDistance );
660 std::partial_sum( rDistances.begin(), rDistances.end(), rDistances.begin() );
661 double fLength = rDistances[ rDistances.size() - 1 ];
664 for (
auto& rDistance : rDistances )
665 rDistance /= fLength;
672 sal_uInt16 nSize = rPoly.
GetSize();
681 double fLastDistance = 0.0;
682 for (sal_uInt16
i = 0;
i < nSize; ++
i)
684 Point& rPoint = rPoly[
i ];
685 double fDistance =
static_cast<double>( rPoint.X() - rTextAreaBoundRect.
Left() ) / static_cast<double>(nTextWidth);
688 if ( fDistance > fLastDistance )
690 std::vector< double >::const_iterator aIter = std::upper_bound( rDistances.begin(), rDistances.end(), fLastDistance );
691 if ( aIter != rDistances.end() && ( *aIter > fLastDistance ) && ( *aIter < fDistance ) )
693 Point& rPt0 = rPoly[
i - 1 ];
694 sal_Int32 fX = rPoint.X() - rPt0.X();
695 sal_Int32 fY = rPoint.Y() - rPt0.Y();
696 double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
697 rPoly.
Insert(
i,
Point( static_cast<sal_Int32>( rPt0.X() + fX * fd ), static_cast<sal_Int32>( rPt0.Y() + fY * fd ) ) );
701 else if ( fDistance < fLastDistance )
703 std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fLastDistance );
704 if ( aIter != rDistances.begin() )
707 if ( ( *aIter > fDistance ) && ( *aIter < fLastDistance ) )
709 Point& rPt0 = rPoly[
i - 1 ];
710 sal_Int32 fX = rPoint.X() - rPt0.X();
711 sal_Int32 fY = rPoint.Y() - rPt0.Y();
712 double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
713 rPoly.
Insert(
i,
Point( static_cast<sal_Int32>( rPt0.X() + fX * fd ), static_cast<sal_Int32>( rPt0.Y() + fY * fd ) ) );
719 fLastDistance = fDistance;
723 static void GetPoint(
const tools::Polygon& rPoly,
const std::vector< double >& rDistances,
const double& fX,
double& fx1,
double& fy1 )
729 std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fX );
730 sal_uInt16 nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
731 if ( aIter == rDistances.end() )
733 const Point& rPt = rPoly[ nIdx ];
736 if ( !nIdx || ( aIter == rDistances.end() ) || rtl::math::approxEqual( *aIter, fX ) )
739 nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
740 double fDist0 = *( aIter - 1 );
741 double fd = ( 1.0 / ( *aIter - fDist0 ) ) * ( fX - fDist0 );
742 const Point& rPt2 = rPoly[ nIdx - 1 ];
743 double fWidth = rPt.X() - rPt2.X();
744 double fHeight= rPt.Y() - rPt2.Y();
747 fx1 = rPt2.X() + fWidth;
748 fy1 = rPt2.Y() + fHeight;
753 sal_uInt16 nOutline2dIdx = 0;
754 for(
auto& rTextArea : rFWData.vTextAreas )
757 sal_Int32 nLeft = rTextAreaBoundRect.
Left();
758 sal_Int32 nTop = rTextAreaBoundRect.
Top();
759 sal_Int32 nWidth = rTextAreaBoundRect.
GetWidth();
760 sal_Int32 nHeight= rTextAreaBoundRect.
GetHeight();
764 nWidth *= rFWData.fHorizontalTextScaling;
767 if ( rFWData.bSingleLineMode && nHeight && nWidth )
769 if ( nOutline2dIdx >= aOutlines2d.
Count() )
771 const tools::Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
772 const sal_uInt16 nPointCount = rOutlinePoly.
GetSize();
773 if ( nPointCount > 1 )
775 std::vector< double > vDistances;
776 vDistances.reserve( nPointCount );
778 if ( !vDistances.empty() )
780 for(
auto& rParagraph : rTextArea.vParagraphs )
782 for (
auto& rCharacter : rParagraph.vCharacters )
787 double fx1 = aBoundRect.
Left() - nLeft;
788 double fx2 = aBoundRect.Right() - nLeft;
790 double fM1 = fx1 /
static_cast<double>(nWidth);
791 double fM2 = fx2 /
static_cast<double>(nWidth);
793 GetPoint( rOutlinePoly, vDistances, fM1, fx1, fy1 );
794 GetPoint( rOutlinePoly, vDistances, fM2, fx2, fy2 );
796 double fvx = fy2 - fy1;
797 double fvy = - ( fx2 - fx1 );
798 fx1 = fx1 + ( ( fx2 - fx1 ) * 0.5 );
799 fy1 = fy1 + ( ( fy2 - fy1 ) * 0.5 );
801 double fAngle = atan2( -fvx, -fvy );
802 double fL = hypot( fvx, fvy );
805 SAL_WARN(
"svx",
"FitTextOutlinesToShapeOutlines div-by-zero, abandon fit");
810 fL = rTextArea.aBoundRect.GetHeight() / 2.0 + rTextArea.aBoundRect.Top() - rParagraph.aBoundRect.Center().Y();
813 rPolyPoly.
Rotate(
Point( aBoundRect.Center().X(), rParagraph.aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
814 rPolyPoly.
Move( static_cast<sal_Int32>( ( fx1 + fvx )- aBoundRect.Center().X() ), static_cast<sal_Int32>( ( fy1 + fvy ) - rParagraph.aBoundRect.Center().Y() ) );
823 if ( ( nOutline2dIdx + 1 ) >= aOutlines2d.
Count() )
825 const tools::Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
826 const tools::Polygon& rOutlinePoly2( aOutlines2d[ nOutline2dIdx++ ] );
827 const sal_uInt16 nPointCount = rOutlinePoly.
GetSize();
828 const sal_uInt16 nPointCount2 = rOutlinePoly2.
GetSize();
829 if ( ( nPointCount > 1 ) && ( nPointCount2 > 1 ) )
831 std::vector< double > vDistances;
832 vDistances.reserve( nPointCount );
833 std::vector< double > vDistances2;
834 vDistances2.reserve( nPointCount2 );
837 for(
auto& rParagraph : rTextArea.vParagraphs )
839 for (
auto& rCharacter : rParagraph.vCharacters )
843 sal_uInt16
i, nPolyCount = rPolyPoly.
Count();
844 for ( i = 0; i < nPolyCount; i++ )
860 sal_uInt16 _nPointCount = aLocalPoly.
GetSize();
863 if (!nWidth || !nHeight)
865 for (sal_uInt16 j = 0; j < _nPointCount; ++j)
867 Point& rPoint = aLocalPoly[ j ];
868 rPoint.AdjustX( -nLeft );
869 rPoint.AdjustY( -nTop );
870 double fX =
static_cast<double>(rPoint.X()) / static_cast<double>(nWidth);
871 double fY =
static_cast<double>(rPoint.Y()) / static_cast<double>(nHeight);
873 double fx1, fy1, fx2, fy2;
874 GetPoint( rOutlinePoly, vDistances, fX, fx1, fy1 );
875 GetPoint( rOutlinePoly2, vDistances2, fX, fx2, fy2 );
876 double fWidth = fx2 - fx1;
877 double fHeight= fy2 - fy1;
878 rPoint.setX( static_cast<sal_Int32>( fx1 + fWidth * fY ) );
879 rPoint.setY( static_cast<sal_Int32>( fy1 + fHeight* fY ) );
884 rPolyPoly[ i ] = aLocalPoly;
895 const FWData& rFWData,
900 if ( !rFWData.vTextAreas.empty() )
902 for (
const auto& rTextArea : rFWData.vTextAreas )
904 for (
const auto& rParagraph : rTextArea.vParagraphs )
906 for (
const auto& rCharacter : rParagraph.vCharacters )
908 for(
const auto& rOutline : rCharacter.vOutlines )
910 aPolyPoly.
append( rOutline.getB2DPolyPolygon() );
934 if ( !mxBreakIterator.is() )
937 mxBreakIterator = i18n::BreakIterator::create(xContext);
939 return mxBreakIterator;
949 sal_uInt16 nOutlinesCount2d = aOutlines2d.
Count();
950 if ( nOutlinesCount2d )
void SetFamily(FontFamily)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CJK(EE_CHAR_START+17)
constexpr TypedWhichId< SdrTextHorzAdjustItem > SDRATTR_TEXT_HORZADJUST(SDRATTR_MISC_FIRST+13)
static void CalculateHorizontalScalingFactor(const SdrObjCustomShape &rSdrObjCustomShape, FWData &rFWData, const tools::PolyPolygon &rOutline2d)
void SetAverageFontWidth(tools::Long nWidth)
static void GetTextAreaOutline(const FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape, FWTextArea &rTextArea, bool bSameLetterHeights)
static bool InitializeFontWorkData(const SdrObjCustomShape &rSdrObjCustomShape, const sal_uInt16 nOutlinesCount2d, FWData &rFWData)
static css::uno::Reference< css::i18n::XBreakIterator > mxBreakIterator
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC(EE_CHAR_START+7)
void SetWeight(FontWeight)
bool areControlPointsUsed() const
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
FontFamily GetFamily() const
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
FontItalic GetPosture() const
tools::Long GetFontHeight() const
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CTL(EE_CHAR_START+18)
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
virtual const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const =0
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
static void GetPoint(const tools::Polygon &rPoly, const std::vector< double > &rDistances, const double &fX, double &fx1, double &fy1)
const OUString & GetStyleName() const
static double GetLength(const tools::Polygon &rPolygon)
constexpr TypedWhichId< SvxWritingModeItem > SDRATTR_TEXTDIRECTION(SDRATTR_NOTPERSIST_FIRST+34)
constexpr TypedWhichId< SdrTextFitToSizeTypeItem > SDRATTR_TEXT_FITTOSIZE(SDRATTR_MISC_FIRST+3)
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
void SetFamilyName(const OUString &rFamilyName)
constexpr TypedWhichId< SdrCustomShapeGeometryItem > SDRATTR_CUSTOMSHAPE_GEOMETRY(SDRATTR_CUSTOMSHAPE_FIRST+2)
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
FontWeight GetWeight() const
static void CalcDistances(const tools::Polygon &rPoly, std::vector< double > &rDistances)
static bool GetFontWorkOutline(FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape)
constexpr TypedWhichId< SvxCharScaleWidthItem > EE_CHAR_FONTWIDTH(EE_CHAR_START+3)
void SetOrientation(Degree10 nLineOrientation)
constexpr TypedWhichId< SdrTextVertAdjustItem > SDRATTR_TEXT_VERTADJUST(SDRATTR_MISC_FIRST+8)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
virtual OUString GetText(sal_Int32 nPara) const =0
static void FitTextOutlinesToShapeOutlines(const tools::PolyPolygon &aOutlines2d, FWData &rFWData)
SdrModel & getSdrModelFromSdrObject() const
static void UpdateScalingMode(FWData &rFWData, const tools::PolyPolygon &rOutline2d, bool bSingleLineMode, VirtualDevice *pVirDev, double &rScalingFactor)
static SdrObject * CreateSdrObjectFromParagraphOutlines(const FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape)
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
void SetAlignment(TextAlign)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
const OUString & GetFamilyName() const
void SetStyleName(const OUString &rStyleName)
virtual bool IsVerticalWriting() const
sal_uInt32 GetHeight() const
B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon &rCandidate, double fAngleBound)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
#define SAL_WARN_IF(condition, area, stream)
virtual OutlinerParaObject * GetOutlinerParaObject() const override
virtual sal_Int32 GetParagraphCount() const =0
static SdrObject * CreateFontWork(const SdrObject *pShape2d, const SdrObjCustomShape &rSdrObjCustomShape)
const SfxItemSet & GetMergedItemSet() const
SdrOnOffItem makeSdrShadowItem(bool bShadow)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
static basegfx::B2DPolyPolygon GetOutlinesFromShape2d(const SdrObject *pShape2d)
css::uno::Any * GetPropertyValueByName(const OUString &rPropName)
static css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIterator()
void SetFontHeight(tools::Long nHeight)
void SetItalic(FontItalic)
#define SAL_WARN(area, stream)
static void InsertMissingOutlinePoints(const std::vector< double > &rDistances, const tools::Rectangle &rTextAreaBoundRect, tools::Polygon &rPoly)
virtual const tools::Rectangle & GetLogicRect() const override