47#include <com/sun/star/i18n/BreakIterator.hpp>
48#include <com/sun/star/i18n/ScriptType.hpp>
52#include <rtl/math.hxx>
63 std::vector< tools::PolyPolygon > vOutlines;
69 std::vector< FWCharacterData > vCharacters;
75 std::vector< FWParagraphData > vParagraphs;
80 std::vector< FWTextArea > vTextAreas;
81 double fHorizontalTextScaling;
82 double fVerticalTextScaling;
83 sal_uInt32 nMaxParagraphsPerTextArea;
84 sal_Int32 nSingleLineHeight;
93 const sal_uInt16 nOutlinesCount2d,
97 bool bSingleLineMode =
false;
98 sal_uInt16 nTextAreaCount = nOutlinesCount2d;
99 if ( nOutlinesCount2d & 1 )
100 bSingleLineMode =
true;
102 nTextAreaCount >>= 1;
107 *pAny >>= rFWData.bScaleX;
109 rFWData.bScaleX =
false;
111 if ( nTextAreaCount )
113 rFWData.bSingleLineMode = bSingleLineMode;
124 std::vector<int> aLineParaID;
125 std::vector<int> aLineStart;
126 std::vector<int> aLineLength;
127 std::vector<OUString> aParaText;
128 for (sal_Int32 nPara = 0; nPara < nParagraphsCount; ++nPara)
130 aParaText.push_back(rTextObj.
GetText(nPara));
132 sal_Int32 nPrevPos = 0;
141 aLineParaID.push_back(nPara);
142 aLineStart.push_back(nPrevPos);
149 sal_Int32 nLinesLeft = aLineParaID.size();
151 rFWData.nMaxParagraphsPerTextArea = ((nLinesLeft - 1) / nTextAreaCount) + 1;
153 while (nLinesLeft && nTextAreaCount)
155 FWTextArea aTextArea;
156 sal_Int32 nLinesInPara = ((nLinesLeft - 1) / nTextAreaCount) + 1;
157 for (sal_Int32
i = 0;
i < nLinesInPara; ++
i, ++nLine)
159 FWParagraphData aParagraphData;
160 aParagraphData.aString = aParaText[aLineParaID[nLine]].subView(
161 aLineStart[nLine], aLineLength[nLine]);
166 aTextArea.vParagraphs.push_back(aParagraphData);
168 rFWData.vTextAreas.push_back(aTextArea);
169 nLinesLeft -= nLinesInPara;
199 double fScalingFactor = 1.0;
200 rFWData.fVerticalTextScaling = 1.0;
203 bool bSingleLineMode =
false;
204 sal_uInt16 nOutlinesCount2d = rOutline2d.
Count();
209 sal_Int32 nFontSize = rFontHeight.
GetHeight();
229 pVirDev->SetMapMode(
MapMode(MapUnit::Map100thMM));
230 pVirDev->SetFont( aFont );
232 if ( nOutlinesCount2d & 1 )
233 bSingleLineMode =
true;
242 bool bScalingFactorDefined =
false;
243 for(
const auto& rTextArea : rFWData.vTextAreas )
247 if ( !bSingleLineMode )
253 for(
const auto& rParagraph : rTextArea.vParagraphs )
255 double fTextWidth = pVirDev->GetTextWidth( rParagraph.aString );
256 if ( fTextWidth > 0.0 )
258 double fScale = fWidth / fTextWidth;
259 if ( !bScalingFactorDefined )
261 fScalingFactor = fScale;
262 bScalingFactorDefined =
true;
264 else if (fScale < fScalingFactor)
266 fScalingFactor = fScale;
272 if (fScalingFactor < 1.0)
276 pVirDev->SetFont( aFont );
279 while (rFWData.bScaleX && fScalingFactor < 1.0 && nFontSize > 1 );
282 rFWData.fVerticalTextScaling =
static_cast<double>(nFontSize) / rFontHeight.
GetHeight();
284 rFWData.fHorizontalTextScaling = fScalingFactor;
288 const FWData& rFWData,
290 FWTextArea& rTextArea,
291 bool bSameLetterHeights)
294 sal_Int32 nVerticalOffset = rFWData.nMaxParagraphsPerTextArea > rTextArea.vParagraphs.size()
295 ? rFWData.nSingleLineHeight / 2 : 0;
297 for(
auto& rParagraph : rTextArea.vParagraphs )
299 const OUString& rText = rParagraph.aString;
300 if ( !rText.isEmpty() )
303 sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
307 nScriptType = xBI->getScriptType( rText, 0 );
308 if( i18n::ScriptType::WEAK == nScriptType )
310 sal_Int32 nChg = xBI->endOfScript( rText, 0, nScriptType );
311 if (nChg < rText.getLength() && nChg >= 0)
312 nScriptType = xBI->getScriptType( rText, nChg );
314 nScriptType = i18n::ScriptType::LATIN;
318 if ( nScriptType == i18n::ScriptType::COMPLEX )
320 else if ( nScriptType == i18n::ScriptType::ASIAN )
342 pVirDev->SetMapMode(
MapMode(MapUnit::Map100thMM));
343 pVirDev->SetFont( aFont );
344 pVirDev->EnableRTL();
345 if ( rParagraph.nFrameDirection == SvxFrameDirection::Horizontal_RL_TB )
349 sal_uInt16 nCharScaleWidth = rCharScaleWidthItem.GetValue();
350 sal_Int32 nWidth = 0;
357 sal_Int32 nHeight = 0;
359 for (
i = 0;
i < rText.getLength();
i++ )
361 FWCharacterData aCharacterData;
362 OUString aCharText( rText[
i ] );
363 if ( pVirDev->GetTextOutlines( aCharacterData.vOutlines, aCharText, 0, 0, -1, nWidth, {} ) )
365 sal_Int32 nTextWidth = pVirDev->GetTextWidth( aCharText);
366 if ( aCharacterData.vOutlines.empty() )
368 nHeight += rFWData.nSingleLineHeight;
372 for (
auto& rOutline : aCharacterData.vOutlines )
375 rOutline.Rotate(
Point( nTextWidth / 2, rFWData.nSingleLineHeight / 2 ), 900_deg10 );
376 aCharacterData.aBoundRect.Union( rOutline.GetBoundRect() );
378 for (
auto& rOutline : aCharacterData.vOutlines )
380 sal_Int32 nM = - aCharacterData.aBoundRect.Left() + nHeight;
381 rOutline.Move( nM, 0 );
382 aCharacterData.aBoundRect.Move( nM, 0 );
384 nHeight += aCharacterData.aBoundRect.GetWidth() + ( rFWData.nSingleLineHeight / 5 );
385 aSingleCharacterUnion.
Union( aCharacterData.aBoundRect );
388 rParagraph.vCharacters.push_back( aCharacterData );
390 for (
auto& rCharacter : rParagraph.vCharacters )
392 for (
auto& rOutline : rCharacter.vOutlines )
394 rOutline.
Move( ( aSingleCharacterUnion.
GetWidth() - rCharacter.aBoundRect.GetWidth() ) / 2, 0 );
401 if ( ( nCharScaleWidth != 100 ) && nCharScaleWidth )
403 pVirDev->GetTextArray( rText, &aDXArry);
404 FontMetric aFontMetric( pVirDev->GetFontMetric() );
406 pVirDev->SetFont( aFont );
408 FWCharacterData aCharacterData;
409 if ( pVirDev->GetTextOutlines( aCharacterData.vOutlines, rText, 0, 0, -1, nWidth, aDXArry ) )
411 rParagraph.vCharacters.push_back( aCharacterData );
419 pVirDev->GetTextArray( rText, &aDXArry);
420 aCharacterData.vOutlines.
clear();
424 for(
size_t a(0);
a < aDXArry.
size();
a++)
429 0 ==
a ? 0 : aDXArry[
a - 1],
451 rParagraph.vCharacters.push_back( aCharacterData );
456 for (
auto& rCharacter : rParagraph.vCharacters )
460 if ( nVerticalOffset )
461 rPolyPoly.
Move( 0, nVerticalOffset );
465 rParagraph.aBoundRect.Union( aBoundRect );
470 if ( rParagraph.aBoundRect.IsEmpty() )
472 if ( rTextArea.aBoundRect.IsEmpty() )
475 rTextArea.aBoundRect.AdjustBottom(rFWData.nSingleLineHeight );
480 rTextArea.aBoundRect.
Union( rParagraphBoundRect );
482 if ( bSameLetterHeights )
484 for (
auto& rCharacter : rParagraph.vCharacters )
486 for(
auto& rOutline : rCharacter.vOutlines )
490 rOutline.Scale( 1.0,
static_cast<double>(rParagraphBoundRect.
GetHeight()) / aPolyPolyBoundRect.
GetHeight() );
491 aPolyPolyBoundRect = rOutline.GetBoundRect();
492 sal_Int32 nMove = aPolyPolyBoundRect.
Top() - rParagraphBoundRect.
Top();
494 rOutline.Move( 0, -nMove );
500 nVerticalOffset -= rFWData.nSingleLineHeight;
502 nVerticalOffset += rFWData.nSingleLineHeight;
513 bool bSameLetterHeights =
false;
517 *pAny >>= bSameLetterHeights;
521 rFWData.nSingleLineHeight = rFWData.fVerticalTextScaling * rFontHeight.
GetHeight();
523 rFWData.nSingleLineHeight =
static_cast<sal_Int32
>( (
static_cast<double>( rSdrObjCustomShape.
GetLogicRect().
GetHeight() )
524 / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
529 for (
auto& rTextArea : rFWData.vTextAreas )
537 if (eFTS == drawing::TextFitToSizeType_ALLLINES ||
540 eFTS == drawing::TextFitToSizeType_PROPORTIONAL)
542 for (
auto& rParagraph : rTextArea.vParagraphs )
544 sal_Int32 nParaWidth = rParagraph.aBoundRect.GetWidth();
547 double fScale =
static_cast<double>(rTextArea.aBoundRect.GetWidth()) / nParaWidth;
549 for (
auto& rCharacter : rParagraph.vCharacters )
551 for(
auto& rOutline : rCharacter.vOutlines )
553 rOutline.Scale( fScale, 1.0 );
559 else if (rFWData.bScaleX)
564 for (
auto& rParagraph : rTextArea.vParagraphs )
566 sal_Int32 nHorzDiff = 0;
567 sal_Int32 nVertDiff =
static_cast<double>( rFWData.nSingleLineHeight ) * fFactor * ( rTextArea.vParagraphs.size() - 1 );
570 nHorzDiff = ( rFWData.fHorizontalTextScaling * rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() ) / 2;
572 nHorzDiff = ( rFWData.fHorizontalTextScaling * rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() );
574 if (nHorzDiff || nVertDiff)
576 for (
auto& rCharacter : rParagraph.vCharacters )
578 for(
auto& rOutline : rCharacter.vOutlines )
580 rOutline.Move( nHorzDiff, nVertDiff );
588 switch( eHorzAdjust )
593 for (
auto& rParagraph : rTextArea.vParagraphs )
595 sal_Int32 nHorzDiff = 0;
597 nHorzDiff = ( rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() ) / 2;
599 nHorzDiff = ( rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() );
602 for (
auto& rCharacter : rParagraph.vCharacters )
604 for(
auto& rOutline : rCharacter.vOutlines )
606 rOutline.Move( nHorzDiff, 0 );
628 while( aObjListIter.
IsMore() )
631 if (
auto pPathObj =
dynamic_cast<const SdrPathObj*
>( pPartObj))
638 aOutlines2d.
append(aCandidate);
654 rDistances.push_back( fDistance );
656 std::partial_sum( rDistances.begin(), rDistances.end(), rDistances.begin() );
657 double fLength = rDistances[ rDistances.size() - 1 ];
660 for (
auto& rDistance : rDistances )
661 rDistance /= fLength;
668 sal_uInt16 nSize = rPoly.
GetSize();
677 double fLastDistance = 0.0;
678 for (sal_uInt16
i = 0;
i < nSize; ++
i)
680 Point& rPoint = rPoly[
i ];
681 double fDistance =
static_cast<double>( rPoint.X() - rTextAreaBoundRect.
Left() ) /
static_cast<double>(nTextWidth);
684 if ( fDistance > fLastDistance )
686 std::vector< double >::const_iterator aIter = std::upper_bound( rDistances.begin(), rDistances.end(), fLastDistance );
687 if ( aIter != rDistances.end() && ( *aIter > fLastDistance ) && ( *aIter < fDistance ) )
689 Point& rPt0 = rPoly[
i - 1 ];
690 sal_Int32 fX = rPoint.X() - rPt0.X();
691 sal_Int32 fY = rPoint.Y() - rPt0.Y();
692 double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
693 rPoly.
Insert(
i,
Point(
static_cast<sal_Int32
>( rPt0.X() + fX * fd ),
static_cast<sal_Int32
>( rPt0.Y() + fY * fd ) ) );
697 else if ( fDistance < fLastDistance )
699 std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fLastDistance );
700 if ( aIter != rDistances.begin() )
703 if ( ( *aIter > fDistance ) && ( *aIter < fLastDistance ) )
705 Point& rPt0 = rPoly[
i - 1 ];
706 sal_Int32 fX = rPoint.X() - rPt0.X();
707 sal_Int32 fY = rPoint.Y() - rPt0.Y();
708 double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
709 rPoly.
Insert(
i,
Point(
static_cast<sal_Int32
>( rPt0.X() + fX * fd ),
static_cast<sal_Int32
>( rPt0.Y() + fY * fd ) ) );
715 fLastDistance = fDistance;
719static void GetPoint(
const tools::Polygon& rPoly,
const std::vector< double >& rDistances,
const double& fX,
double& fx1,
double& fy1 )
725 std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fX );
726 sal_uInt16 nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
727 if ( aIter == rDistances.end() )
729 const Point& rPt = rPoly[ nIdx ];
732 if ( !nIdx || ( aIter == rDistances.end() ) || rtl::math::approxEqual( *aIter, fX ) )
735 nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
736 double fDist0 = *( aIter - 1 );
737 double fd = ( 1.0 / ( *aIter - fDist0 ) ) * ( fX - fDist0 );
738 const Point& rPt2 = rPoly[ nIdx - 1 ];
739 double fWidth = rPt.X() - rPt2.X();
740 double fHeight= rPt.Y() - rPt2.Y();
743 fx1 = rPt2.X() + fWidth;
744 fy1 = rPt2.Y() + fHeight;
749 sal_uInt16 nOutline2dIdx = 0;
750 for(
auto& rTextArea : rFWData.vTextAreas )
753 sal_Int32 nLeft = rTextAreaBoundRect.
Left();
754 sal_Int32 nTop = rTextAreaBoundRect.
Top();
755 sal_Int32 nWidth = rTextAreaBoundRect.
GetWidth();
756 sal_Int32 nHeight= rTextAreaBoundRect.
GetHeight();
760 nWidth *= rFWData.fHorizontalTextScaling;
763 if ( rFWData.bSingleLineMode && nHeight && nWidth )
765 if ( nOutline2dIdx >= aOutlines2d.
Count() )
767 const tools::Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
768 const sal_uInt16 nPointCount = rOutlinePoly.
GetSize();
769 if ( nPointCount > 1 )
771 std::vector< double > vDistances;
772 vDistances.reserve( nPointCount );
774 if ( !vDistances.empty() )
776 for(
auto& rParagraph : rTextArea.vParagraphs )
778 for (
auto& rCharacter : rParagraph.vCharacters )
783 double fx1 = aBoundRect.
Left() - nLeft;
784 double fx2 = aBoundRect.
Right() - nLeft;
786 double fM1 = fx1 /
static_cast<double>(nWidth);
787 double fM2 = fx2 /
static_cast<double>(nWidth);
789 GetPoint( rOutlinePoly, vDistances, fM1, fx1, fy1 );
790 GetPoint( rOutlinePoly, vDistances, fM2, fx2, fy2 );
792 double fvx = fy2 - fy1;
793 double fvy = - ( fx2 - fx1 );
794 fx1 = fx1 + ( ( fx2 - fx1 ) * 0.5 );
795 fy1 = fy1 + ( ( fy2 - fy1 ) * 0.5 );
797 double fAngle = atan2( -fvx, -fvy );
798 double fL = hypot( fvx, fvy );
801 SAL_WARN(
"svx",
"FitTextOutlinesToShapeOutlines div-by-zero, abandon fit");
806 fL = rTextArea.aBoundRect.GetHeight() / 2.0 + rTextArea.aBoundRect.Top() - rParagraph.aBoundRect.Center().Y();
809 rPolyPoly.
Rotate(
Point( aBoundRect.
Center().X(), rParagraph.aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
810 rPolyPoly.
Move(
static_cast<sal_Int32
>( ( fx1 + fvx )- aBoundRect.
Center().X() ),
static_cast<sal_Int32
>( ( fy1 + fvy ) - rParagraph.aBoundRect.Center().Y() ) );
819 if ( ( nOutline2dIdx + 1 ) >= aOutlines2d.
Count() )
821 const tools::Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
822 const tools::Polygon& rOutlinePoly2( aOutlines2d[ nOutline2dIdx++ ] );
823 const sal_uInt16 nPointCount = rOutlinePoly.
GetSize();
824 const sal_uInt16 nPointCount2 = rOutlinePoly2.
GetSize();
825 if ( ( nPointCount > 1 ) && ( nPointCount2 > 1 ) )
827 std::vector< double > vDistances;
828 vDistances.reserve( nPointCount );
829 std::vector< double > vDistances2;
830 vDistances2.reserve( nPointCount2 );
833 for(
auto& rParagraph : rTextArea.vParagraphs )
835 for (
auto& rCharacter : rParagraph.vCharacters )
839 sal_uInt16
i, nPolyCount = rPolyPoly.
Count();
840 for (
i = 0;
i < nPolyCount;
i++ )
856 sal_uInt16 _nPointCount = aLocalPoly.
GetSize();
859 if (!nWidth || !nHeight)
861 for (sal_uInt16 j = 0; j < _nPointCount; ++j)
863 Point& rPoint = aLocalPoly[ j ];
864 rPoint.AdjustX( -nLeft );
865 rPoint.AdjustY( -nTop );
866 double fX =
static_cast<double>(rPoint.X()) /
static_cast<double>(nWidth);
867 double fY =
static_cast<double>(rPoint.Y()) /
static_cast<double>(nHeight);
869 double fx1, fy1, fx2, fy2;
870 GetPoint( rOutlinePoly, vDistances, fX, fx1, fy1 );
871 GetPoint( rOutlinePoly2, vDistances2, fX, fx2, fy2 );
872 double fWidth = fx2 - fx1;
873 double fHeight= fy2 - fy1;
874 rPoint.setX(
static_cast<sal_Int32
>( fx1 + fWidth * fY ) );
875 rPoint.setY(
static_cast<sal_Int32
>( fy1 + fHeight* fY ) );
880 rPolyPoly[
i ] = aLocalPoly;
891 const FWData& rFWData,
896 if ( !rFWData.vTextAreas.empty() )
898 for (
const auto& rTextArea : rFWData.vTextAreas )
900 for (
const auto& rParagraph : rTextArea.vParagraphs )
902 for (
const auto& rCharacter : rParagraph.vCharacters )
904 for(
const auto& rOutline : rCharacter.vOutlines )
906 aPolyPoly.
append( rOutline.getB2DPolyPolygon() );
915 std::move(aPolyPoly));
920 pRet->SetMergedItemSet( aSet );
949 sal_uInt16 nOutlinesCount2d = aOutlines2d.
Count();
950 if ( nOutlinesCount2d )
static void CalcDistances(const tools::Polygon &rPoly, std::vector< double > &rDistances)
static void GetPoint(const tools::Polygon &rPoly, const std::vector< double > &rDistances, const double &fX, double &fx1, double &fy1)
static bool GetFontWorkOutline(FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape)
static void FitTextOutlinesToShapeOutlines(const tools::PolyPolygon &aOutlines2d, FWData &rFWData)
static rtl::Reference< SdrObject > CreateSdrObjectFromParagraphOutlines(const FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape)
static void InsertMissingOutlinePoints(const std::vector< double > &rDistances, const tools::Rectangle &rTextAreaBoundRect, tools::Polygon &rPoly)
static void CalculateHorizontalScalingFactor(const SdrObjCustomShape &rSdrObjCustomShape, FWData &rFWData, const tools::PolyPolygon &rOutline2d)
static bool InitializeFontWorkData(const SdrObjCustomShape &rSdrObjCustomShape, const sal_uInt16 nOutlinesCount2d, FWData &rFWData)
static void GetTextAreaOutline(const FWData &rFWData, const SdrObjCustomShape &rSdrObjCustomShape, FWTextArea &rTextArea, bool bSameLetterHeights)
static double GetLength(const tools::Polygon &rPolygon)
static basegfx::B2DPolyPolygon GetOutlinesFromShape2d(const SdrObject *pShape2d)
virtual sal_Int32 GetParagraphCount() const=0
virtual OUString GetText(sal_Int32 nPara) const=0
virtual const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const=0
static css::uno::Reference< css::i18n::XBreakIterator > mxBreakIterator
static css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIterator()
static rtl::Reference< SdrObject > CreateFontWork(const SdrObject *pShape2d, const SdrObjCustomShape &rSdrObjCustomShape)
const EditTextObject & GetTextObject() const
css::uno::Any * GetPropertyValueByName(const OUString &rPropName)
bool IsLegacySingleLineFontwork() const
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
SdrModel & getSdrModelFromSdrObject() const
const SfxItemSet & GetMergedItemSet() const
virtual OutlinerParaObject * GetOutlinerParaObject() const override
virtual const tools::Rectangle & GetLogicRect() const override
virtual bool IsVerticalWriting() const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt32 GetHeight() const
FontFamily GetFamily() const
const OUString & GetStyleName() const
const OUString & GetFamilyName() const
FontItalic GetPosture() const
FontWeight GetWeight() const
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
bool areControlPointsUsed() const
bool areControlPointsUsed() const
tools::Long GetFontHeight() const
void SetOrientation(Degree10 nLineOrientation)
void SetStyleName(const OUString &rStyleName)
void SetAverageFontWidth(tools::Long nWidth)
void SetItalic(FontItalic)
void SetWeight(FontWeight)
void SetFontHeight(tools::Long nHeight)
void SetFamily(FontFamily)
void SetAlignment(TextAlign)
void SetFamilyName(const OUString &rFamilyName)
tools::Long GetAverageFontWidth() const
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CJK(EE_CHAR_START+17)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC(EE_CHAR_START+7)
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CTL(EE_CHAR_START+18)
constexpr TypedWhichId< SvxCharScaleWidthItem > EE_CHAR_FONTWIDTH(EE_CHAR_START+3)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
#define SAL_WARN(area, stream)
double getLength(const B2DPolygon &rCandidate)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon &rCandidate, double fAngleBound)
SdrOnOffItem makeSdrShadowItem(bool bShadow)
@ SDRTEXTVERTADJUST_BOTTOM
@ SDRTEXTHORZADJUST_BLOCK
@ SDRTEXTHORZADJUST_CENTER
@ SDRTEXTHORZADJUST_RIGHT
constexpr TypedWhichId< SdrTextFitToSizeTypeItem > SDRATTR_TEXT_FITTOSIZE(SDRATTR_MISC_FIRST+3)
constexpr TypedWhichId< SdrTextHorzAdjustItem > SDRATTR_TEXT_HORZADJUST(SDRATTR_MISC_FIRST+13)
constexpr TypedWhichId< SdrTextVertAdjustItem > SDRATTR_TEXT_VERTADJUST(SDRATTR_MISC_FIRST+8)
constexpr TypedWhichId< SdrCustomShapeGeometryItem > SDRATTR_CUSTOMSHAPE_GEOMETRY(SDRATTR_CUSTOMSHAPE_FIRST+2)
constexpr TypedWhichId< SvxWritingModeItem > SDRATTR_TEXTDIRECTION(SDRATTR_NOTPERSIST_FIRST+34)