summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/compatflags.hxx2
-rw-r--r--include/tools/poly.hxx1
-rw-r--r--oox/qa/unit/shape.cxx4
-rw-r--r--sc/source/ui/docshell/docsh.cxx2
-rw-r--r--sd/qa/unit/export-tests-ooxml3.cxx2
-rw-r--r--sd/source/ui/docshell/docshel4.cxx2
-rw-r--r--svx/qa/unit/data/tdf148000_CurvedTextWidth.pptxbin0 -> 28435 bytes
-rw-r--r--svx/qa/unit/data/tdf148000_CurvedTextWidth_Legacy.odpbin0 -> 17039 bytes
-rw-r--r--svx/qa/unit/data/tdf148000_CurvedTextWidth_New.odpbin0 -> 16791 bytes
-rw-r--r--svx/qa/unit/svdraw.cxx39
-rw-r--r--svx/source/customshapes/EnhancedCustomShapeFontWork.cxx275
-rw-r--r--svx/source/svdraw/svdmodel.cxx18
-rw-r--r--sw/source/uibase/app/docshini.cxx2
13 files changed, 296 insertions, 51 deletions
diff --git a/include/svx/compatflags.hxx b/include/svx/compatflags.hxx
index f7d021f17bf7..9a64bd2bab80 100644
--- a/include/svx/compatflags.hxx
+++ b/include/svx/compatflags.hxx
@@ -11,7 +11,7 @@
enum class SdrCompatibilityFlag
{
AnchoredTextOverflowLegacy, ///< for tdf#99729
- LegacySingleLineFontwork, ///< for tdf#148000
+ LegacyFontwork, ///< for tdf#148000 false == Fontwork works in PowerPoint compat mode
ConnectorUseSnapRect, ///< for tdf#149756
IgnoreBreakAfterMultilineField, ///< for tdf#148966
};
diff --git a/include/tools/poly.hxx b/include/tools/poly.hxx
index 77653d23bda7..24705f6c9e3c 100644
--- a/include/tools/poly.hxx
+++ b/include/tools/poly.hxx
@@ -114,6 +114,7 @@ public:
void SetSize( sal_uInt16 nNewSize );
sal_uInt16 GetSize() const;
+ sal_uInt16 size() const { return GetSize(); } //for vector compability
void Clear();
diff --git a/oox/qa/unit/shape.cxx b/oox/qa/unit/shape.cxx
index 54ea52cce19c..d3a971cd58db 100644
--- a/oox/qa/unit/shape.cxx
+++ b/oox/qa/unit/shape.cxx
@@ -178,9 +178,9 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, testTdf125582_TextOnCircle)
{
SdrObjCustomShape& rSdrCustomShape(
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape)));
- // Without the fix in place width was 3639, but should be 4824 for 96dpi.
+ // Without the fix in place width was 3639, but should be 4784 for 96dpi.
tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
- CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(4824), aBoundRect.GetWidth(), 5);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(4784), aBoundRect.GetWidth(), 5);
}
drawing::TextVerticalAdjust eAdjust;
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index c951814ce77f..77cf975166de 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -612,7 +612,7 @@ bool ScDocShell::Load( SfxMedium& rMedium )
{
pDrawLayer->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy,
true); // for tdf#99729
- pDrawLayer->SetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork,
+ pDrawLayer->SetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork,
true); // for tdf#148000
}
}
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx b/sd/qa/unit/export-tests-ooxml3.cxx
index dbe68d2fcd7e..106073c47816 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -582,7 +582,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf125573_FontWorkScaleX)
// BoundRect is DPI dependent, thus allow some range.
// Expected width is 13139 in 96dpi and is 13106 in 120 dpi, for example
// (Without fix Expected less than: 85 Actual : 10432)
- CPPUNIT_ASSERT_LESS(sal_Int32(85), std::abs(aBoundRectArch.Width - 13139));
+ CPPUNIT_ASSERT_LESS(sal_Int32(85), std::abs(aBoundRectArch.Width - 13145));
// Error was, that text in shapes of category "Warp" was not scaled to the path.
uno::Reference<beans::XPropertySet> xShapeWaveProps(getShapeFromPage(0, 1));
diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx
index 6b9d8993ada9..742614d101c1 100644
--- a/sd/source/ui/docshell/docshel4.cxx
+++ b/sd/source/ui/docshell/docshel4.cxx
@@ -270,7 +270,7 @@ bool DrawDocShell::Load( SfxMedium& rMedium )
if (IsOwnStorageFormat(rMedium))
{
mpDoc->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy, true); // for tdf#99729
- mpDoc->SetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork, true); // for tdf#148000
+ mpDoc->SetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork, true); // for tdf#148000
}
bool bRet = false;
diff --git a/svx/qa/unit/data/tdf148000_CurvedTextWidth.pptx b/svx/qa/unit/data/tdf148000_CurvedTextWidth.pptx
new file mode 100644
index 000000000000..be286cb1cea6
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_CurvedTextWidth.pptx
Binary files differ
diff --git a/svx/qa/unit/data/tdf148000_CurvedTextWidth_Legacy.odp b/svx/qa/unit/data/tdf148000_CurvedTextWidth_Legacy.odp
new file mode 100644
index 000000000000..24cf1593f133
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_CurvedTextWidth_Legacy.odp
Binary files differ
diff --git a/svx/qa/unit/data/tdf148000_CurvedTextWidth_New.odp b/svx/qa/unit/data/tdf148000_CurvedTextWidth_New.odp
new file mode 100644
index 000000000000..45b6ed0e1f16
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_CurvedTextWidth_New.odp
Binary files differ
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index 8a6a39892b9d..2a7b7950c998 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -427,6 +427,45 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_EOLinCurvedText)
}
}
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_CurvedTextEidth)
+{
+ std::vector<OUString> aFilenames
+ = { u"tdf148000_CurvedTextWidth.pptx"_ustr, u"tdf148000_CurvedTextWidth_New.odp"_ustr,
+ u"tdf148000_CurvedTextWidth_Legacy.odp"_ustr };
+
+ for (int i = 0; i < 3; i++)
+ {
+ loadFromURL(aFilenames[i]);
+
+ SdrPage* pSdrPage = getFirstDrawPageWithAssert();
+
+ xmlDocUniquePtr pXmlDoc = lcl_dumpAndParseFirstObjectWithAssert(pSdrPage);
+
+ OString aBasePath = "/primitive2D/objectinfo[4]/objectinfo/unhandled/unhandled/"
+ "polypolygoncolor/polypolygon/"_ostr;
+
+ // The text is: 7 line od "OOOOOOO"
+ // Take the x coord of the 4 "O" on the corners
+ sal_Int32 nX1 = getXPath(pXmlDoc, aBasePath + "polygon[1]/point[1]", "x"_ostr).toInt32();
+ sal_Int32 nX2 = getXPath(pXmlDoc, aBasePath + "polygon[13]/point[1]", "x"_ostr).toInt32();
+ sal_Int32 nX3 = getXPath(pXmlDoc, aBasePath + "polygon[85]/point[1]", "x"_ostr).toInt32();
+ sal_Int32 nX4 = getXPath(pXmlDoc, aBasePath + "polygon[97]/point[1]", "x"_ostr).toInt32();
+
+ if (i < 2)
+ {
+ // All the lines should be positioned similar (start/end is similar)
+ CPPUNIT_ASSERT_LESS(sal_Int32(150), abs(nX3 - nX1));
+ CPPUNIT_ASSERT_LESS(sal_Int32(150), abs(nX4 - nX2));
+ }
+ else
+ {
+ // In legacy mode, the outer lines become much wider
+ CPPUNIT_ASSERT_GREATER(sal_Int32(1500), nX3 - nX1);
+ CPPUNIT_ASSERT_GREATER(sal_Int32(1500), nX2 - nX4);
+ }
+ }
+}
+
CPPUNIT_TEST_FIXTURE(SvdrawTest, testSurfaceMetal)
{
loadFromURL(u"tdf140321_metal.odp");
diff --git a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
index 7d7ee4fdbc81..8f2896109e9e 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
@@ -75,6 +75,7 @@ struct FWTextArea // representing multiple concluding para
{
std::vector< FWParagraphData > vParagraphs;
tools::Rectangle aBoundRect;
+ sal_Int32 nHAlignMove = 0;
};
struct FWData // representing the whole text
{
@@ -135,7 +136,7 @@ static bool InitializeFontWorkData(
{
// search line break.
if (!rSdrObjCustomShape.getSdrModelFromSdrObject().GetCompatibilityFlag(
- SdrCompatibilityFlag::LegacySingleLineFontwork))
+ SdrCompatibilityFlag::LegacyFontwork))
nPos = aParaText[nPara].indexOf(sal_Unicode(u'\1'), nPrevPos);
else
nPos = -1; // tdf#148000: ignore line breaks in legacy fontworks
@@ -570,6 +571,7 @@ static bool GetFontWorkOutline(
{
sal_Int32 nHorzDiff = 0;
sal_Int32 nVertDiff = static_cast<double>( rFWData.nSingleLineHeight ) * fFactor * ( rTextArea.vParagraphs.size() - 1 );
+ rTextArea.nHAlignMove = nVertDiff;
if ( eHorzAdjust == SDRTEXTHORZADJUST_CENTER )
nHorzDiff = ( rFWData.fHorizontalTextScaling * rTextArea.aBoundRect.GetWidth() - rParagraph.aBoundRect.GetWidth() ) / 2;
@@ -721,10 +723,12 @@ static void InsertMissingOutlinePoints( const std::vector< double >& rDistances,
}
}
-static void GetPoint( const tools::Polygon& rPoly, const std::vector< double >& rDistances, const double& fX, double& fx1, double& fy1 )
+//only 2 types used: 'const tools::Polygon&' and 'const std::vector<Point>&'
+template <class T>
+static void GetPoint( T rPoly, const std::vector< double >& rDistances, const double& fX, double& fx1, double& fy1 )
{
fy1 = fx1 = 0.0;
- if ( rPoly.GetSize() <= 1 )
+ if (rPoly.size() <= 1)
return;
std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fX );
@@ -749,7 +753,8 @@ static void GetPoint( const tools::Polygon& rPoly, const std::vector< double >&
fy1 = rPt2.Y() + fHeight;
}
-static void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2d, FWData& rFWData )
+static void FitTextOutlinesToShapeOutlines(const tools::PolyPolygon& aOutlines2d, FWData& rFWData,
+ SdrTextHorzAdjust eHorzAdjust, bool bPPFontwork)
{
sal_uInt16 nOutline2dIdx = 0;
for( auto& rTextArea : rFWData.vTextAreas )
@@ -776,46 +781,242 @@ static void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2
std::vector< double > vDistances;
vDistances.reserve( nPointCount );
CalcDistances( rOutlinePoly, vDistances );
+
if ( !vDistances.empty() )
{
- for( auto& rParagraph : rTextArea.vParagraphs )
+ // horizontal aligment: how much we have to move text to the right.
+ int nAdjust = -1;
+ switch (eHorzAdjust)
+ {
+ case SDRTEXTHORZADJUST_RIGHT:
+ nAdjust = 2; // 2 half of the possible
+ break;
+ case SDRTEXTHORZADJUST_CENTER:
+ nAdjust = 1; // 1 half of the possible
+ break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ nAdjust = -1; // don't know what it is, so dont even align
+ break;
+ case SDRTEXTHORZADJUST_LEFT:
+ nAdjust = 0; // no need to move
+ break;
+ }
+
+ if (bPPFontwork && rTextArea.vParagraphs.size() > 1 && nAdjust >= 0)
+ {
+ // If we have multiple lines of text to fit to the outline (curve)
+ // then we have to be able to calculate outer versions of the outline
+ // where we can fit the next lines of texts
+ // those outer lines will be wider (or shorter) as the original outline
+ // and probably will looks different as the original outline.
+ //
+ // for example if we have an outline like this:
+ // <____>
+ // then the middle part will have the same normals, so distances there,
+ // will not change for an outer outline
+ // while the points near the edge will have different normals,
+ // distances around there will increase for an outer (wider) outline
+
+ //Normal vectors for every rOutlinePoly point. 1024 long
+ std::vector<Point> vNorm;
+ //wider curve path points, for current paragraph (rOutlinePoly + vNorm*line)
+ std::vector<Point> vCurOutline;
+ //distances between points of this wider curve
+ std::vector<double> vCurDistances;
+
+ vCurDistances.reserve(nPointCount);
+ vCurOutline.reserve(nPointCount);
+ vNorm.reserve(nPointCount);
+
+ // Calculate Normal vectors, and allocate curve datas
+ sal_uInt16 i;
+ for (i = 0; i < nPointCount; i++)
+ {
+ //Normal vector for a point will be calculated from its neightbour points
+ //except if is in the start/end of the vector
+ sal_uInt16 nPointIdx1 = i == 0 ? i : i - 1;
+ sal_uInt16 nPointIdx2 = i == nPointCount - 1 ? i : i + 1;
+
+ Point aPoint = rOutlinePoly.GetPoint(nPointIdx2)
+ - rOutlinePoly.GetPoint(nPointIdx1);
+
+ double fLen = sqrt(aPoint.X() * aPoint.X() + aPoint.Y() * aPoint.Y());
+
+ if (fLen > 0)
+ {
+ //Rotate by 90 degree, and divide by length, to get normal vector
+ vNorm.emplace_back(aPoint.getY() * 1024 / fLen,
+ -aPoint.getX() * 1024 / fLen);
+ }
+ else
+ {
+ vNorm.emplace_back(0, 0);
+ }
+ vCurOutline.emplace_back(Point());
+ vCurDistances.push_back(0);
+
+ }
+
+ for( auto& rParagraph : rTextArea.vParagraphs )
+ {
+ //calculate the actual outline length, and its align adjustments
+ double fAdjust;
+ double fCurWidth;
+
+ // distance between the original an the current curve
+ double fCurvesDist = rTextArea.aBoundRect.GetHeight() / 2.0
+ + rTextArea.aBoundRect.Top()
+ - rParagraph.aBoundRect.Center().Y();
+ // verical alignment adjust
+ fCurvesDist -= rTextArea.nHAlignMove;
+
+ for (i = 0; i < nPointCount; i++)
+ {
+ vCurOutline[i]
+ = rOutlinePoly.GetPoint(i) + vNorm[i] * fCurvesDist / 1024.0;
+ if (i > 0)
+ {
+ //calculate distances between points on the outer outline
+ const double fDx = vCurOutline[i].X() - vCurOutline[i - 1].X();
+ const double fDy = vCurOutline[i].Y() - vCurOutline[i - 1].Y();
+ vCurDistances[i] = sqrt(fDx * fDx + fDy * fDy);
+ }
+ else
+ vCurDistances[i] = 0;
+ }
+ std::partial_sum(vCurDistances.begin(), vCurDistances.end(),
+ vCurDistances.begin());
+ fCurWidth = vCurDistances[vCurDistances.size() - 1];
+ if (fCurWidth > 0.0)
+ {
+ for (auto& rDistance : vCurDistances)
+ rDistance /= fCurWidth;
+ }
+
+ // if the current outline is longer then the text to fit in,
+ // then we have to divide the bonus space betweeen the
+ // before-/after- text area.
+ // fAdjust means how much space we put before the text.
+ if (fCurWidth > rParagraph.aBoundRect.GetWidth())
+ {
+ fAdjust
+ = nAdjust * (fCurWidth - rParagraph.aBoundRect.GetWidth()) / 2;
+ }
+ else
+ fAdjust = -1; // we neet tho shrink the text to fit the curve
+
+ for ( auto& rCharacter : rParagraph.vCharacters )
+ {
+ for (tools::PolyPolygon& rPolyPoly : rCharacter.vOutlines)
+ {
+ tools::Rectangle aBoundRect(rPolyPoly.GetBoundRect());
+ double fx1 = aBoundRect.Left() - nLeft;
+ double fx2 = aBoundRect.Right() - nLeft;
+
+ double fParaRectWidth = rParagraph.aBoundRect.GetWidth();
+ // Undo Horizontal alignment, hacked into poly coords,
+ // so we can calculate it the right way
+ double fHA = (rFWData.fHorizontalTextScaling
+ * rTextArea.aBoundRect.GetWidth()
+ - rParagraph.aBoundRect.GetWidth())
+ * nAdjust / 2;
+
+ fx1 -= fHA;
+ fx2 -= fHA;
+
+ double fy1, fy2;
+ double fM1 = fx1 / fParaRectWidth;
+ double fM2 = fx2 / fParaRectWidth;
+
+ // if fAdjust<0, then it means, the text was longer, as
+ // the current outline, so we will skip the text scaling, and
+ // the text horizontal alignment ajustment
+ // so the text will be rendered just as long as the cureve is.
+ if (fAdjust >= 0)
+ {
+ fM1 = (fM1 * fParaRectWidth + fAdjust) / fCurWidth;
+ fM2 = (fM2 * fParaRectWidth + fAdjust) / fCurWidth;
+ }
+ // 0 <= fM1,fM2 <= 1 should be true, but rounding errors can
+ // make a small mistake.
+ // make sure they are >0 becuase GetPoint() need that
+ if (fM1 < 0) fM1 = 0;
+ if (fM2 < 0) fM2 = 0;
+
+ GetPoint(vCurOutline, vCurDistances, fM1, fx1, fy1);
+ GetPoint(vCurOutline, vCurDistances, fM2, fx2, fy2);
+
+ double fvx = fy2 - fy1;
+ double fvy = - ( fx2 - fx1 );
+ fx1 = fx1 + ( ( fx2 - fx1 ) * 0.5 );
+ fy1 = fy1 + ( ( fy2 - fy1 ) * 0.5 );
+
+ double fAngle = atan2( -fvx, -fvy );
+ double fL = hypot( fvx, fvy );
+ if (fL == 0.0)
+ {
+ SAL_WARN("svx", "FitTextOutlinesToShapeOutlines div-by-zero, abandon fit");
+ break;
+ }
+ fvx = fvx / fL;
+ fvy = fvy / fL;
+ // Undo Vertical alignment hacked into poly coords
+ // We already calculated the right alignment into the curve
+ fL = rTextArea.nHAlignMove;
+ fvx *= fL;
+ fvy *= fL;
+ rPolyPoly.Rotate( Point( aBoundRect.Center().X(), rParagraph.aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
+ rPolyPoly.Move( static_cast<sal_Int32>( ( fx1 + fvx )- aBoundRect.Center().X() ), static_cast<sal_Int32>( ( fy1 + fvy ) - rParagraph.aBoundRect.Center().Y() ) );
+ }
+ }
+ }
+ }
+ else
{
- for ( auto& rCharacter : rParagraph.vCharacters )
+ // Fallback / old way to handle multiple lines:
+ // Every text lines use the same original outline (curve),
+ // it just scale character coordinates to fit to the right text line
+ // (curve), resulting wider/thinner space between characters
+ for (auto& rParagraph : rTextArea.vParagraphs)
{
- for( tools::PolyPolygon& rPolyPoly : rCharacter.vOutlines )
+ for (auto& rCharacter : rParagraph.vCharacters)
{
- tools::Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
- double fx1 = aBoundRect.Left() - nLeft;
- double fx2 = aBoundRect.Right() - nLeft;
- double fy1, fy2;
- double fM1 = fx1 / static_cast<double>(nWidth);
- double fM2 = fx2 / static_cast<double>(nWidth);
-
- GetPoint( rOutlinePoly, vDistances, fM1, fx1, fy1 );
- GetPoint( rOutlinePoly, vDistances, fM2, fx2, fy2 );
-
- double fvx = fy2 - fy1;
- double fvy = - ( fx2 - fx1 );
- fx1 = fx1 + ( ( fx2 - fx1 ) * 0.5 );
- fy1 = fy1 + ( ( fy2 - fy1 ) * 0.5 );
-
- double fAngle = atan2( -fvx, -fvy );
- double fL = hypot( fvx, fvy );
- if (fL == 0.0)
+ for (tools::PolyPolygon& rPolyPoly : rCharacter.vOutlines)
{
- SAL_WARN("svx", "FitTextOutlinesToShapeOutlines div-by-zero, abandon fit");
- break;
+ tools::Rectangle aBoundRect(rPolyPoly.GetBoundRect());
+ double fx1 = aBoundRect.Left() - nLeft;
+ double fx2 = aBoundRect.Right() - nLeft;
+ double fy1, fy2;
+ double fM1 = fx1 / static_cast<double>(nWidth);
+ double fM2 = fx2 / static_cast<double>(nWidth);
+
+ GetPoint(rOutlinePoly, vDistances, fM1, fx1, fy1);
+ GetPoint(rOutlinePoly, vDistances, fM2, fx2, fy2);
+
+ double fvx = fy2 - fy1;
+ double fvy = -(fx2 - fx1);
+ fx1 = fx1 + ((fx2 - fx1) * 0.5);
+ fy1 = fy1 + ((fy2 - fy1) * 0.5);
+
+ double fAngle = atan2(-fvx, -fvy);
+ double fL = hypot(fvx, fvy);
+ if (fL == 0.0)
+ {
+ SAL_WARN("svx", "FitTextOutlinesToShapeOutlines div-by-zero, abandon fit");
+ break;
+ }
+ fvx = fvx / fL;
+ fvy = fvy / fL;
+ fL = rTextArea.aBoundRect.GetHeight() / 2.0 + rTextArea.aBoundRect.Top() - rParagraph.aBoundRect.Center().Y();
+ fvx *= fL;
+ fvy *= fL;
+ rPolyPoly.Rotate( Point( aBoundRect.Center().X(), rParagraph.aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
+ rPolyPoly.Move( static_cast<sal_Int32>( ( fx1 + fvx )- aBoundRect.Center().X() ), static_cast<sal_Int32>( ( fy1 + fvy ) - rParagraph.aBoundRect.Center().Y() ) );
}
- fvx = fvx / fL;
- fvy = fvy / fL;
- fL = rTextArea.aBoundRect.GetHeight() / 2.0 + rTextArea.aBoundRect.Top() - rParagraph.aBoundRect.Center().Y();
- fvx *= fL;
- fvy *= fL;
- rPolyPoly.Rotate( Point( aBoundRect.Center().X(), rParagraph.aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
- rPolyPoly.Move( static_cast<sal_Int32>( ( fx1 + fvx )- aBoundRect.Center().X() ), static_cast<sal_Int32>( ( fy1 + fvy ) - rParagraph.aBoundRect.Center().Y() ) );
}
}
}
+
}
}
}
@@ -973,7 +1174,11 @@ rtl::Reference<SdrObject> EnhancedCustomShapeFontWork::CreateFontWork(
return nullptr;
}
- FitTextOutlinesToShapeOutlines( aOutlines2d, aFWData );
+ SdrTextHorzAdjust eHorzAdjust(
+ rSdrObjCustomShape.GetMergedItem(SDRATTR_TEXT_HORZADJUST).GetValue());
+ bool bPPFontwork = !rSdrObjCustomShape.getSdrModelFromSdrObject().GetCompatibilityFlag(
+ SdrCompatibilityFlag::LegacyFontwork);
+ FitTextOutlinesToShapeOutlines( aOutlines2d, aFWData, eHorzAdjust, bPPFontwork );
pRet = CreateSdrObjectFromParagraphOutlines(
aFWData,
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index ba57b71c685b..90fc769e20b7 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -86,7 +86,7 @@ struct SdrModelImpl
SfxUndoManager* mpUndoManager;
SdrUndoFactory* mpUndoFactory;
bool mbAnchoredTextOverflowLegacy; // tdf#99729 compatibility flag
- bool mbLegacySingleLineFontwork; // tdf#148000 compatibility flag
+ bool mbLegacyFontwork; // tdf#148000 compatibility flag
bool mbConnectorUseSnapRect; // tdf#149756 compatibility flag
bool mbIgnoreBreakAfterMultilineField; ///< tdf#148966 compatibility flag
std::shared_ptr<model::Theme> mpTheme;
@@ -96,7 +96,7 @@ struct SdrModelImpl
: mpUndoManager(nullptr)
, mpUndoFactory(nullptr)
, mbAnchoredTextOverflowLegacy(false)
- , mbLegacySingleLineFontwork(false)
+ , mbLegacyFontwork(false)
, mbConnectorUseSnapRect(false)
, mbIgnoreBreakAfterMultilineField(false)
, mpTheme(new model::Theme("Office"))
@@ -1724,8 +1724,8 @@ void SdrModel::SetCompatibilityFlag(SdrCompatibilityFlag eFlag, bool bEnabled)
case SdrCompatibilityFlag::AnchoredTextOverflowLegacy:
mpImpl->mbAnchoredTextOverflowLegacy = bEnabled;
break;
- case SdrCompatibilityFlag::LegacySingleLineFontwork:
- mpImpl->mbLegacySingleLineFontwork = bEnabled;
+ case SdrCompatibilityFlag::LegacyFontwork:
+ mpImpl->mbLegacyFontwork = bEnabled;
break;
case SdrCompatibilityFlag::ConnectorUseSnapRect:
mpImpl->mbConnectorUseSnapRect = bEnabled;
@@ -1742,8 +1742,8 @@ bool SdrModel::GetCompatibilityFlag(SdrCompatibilityFlag eFlag) const
{
case SdrCompatibilityFlag::AnchoredTextOverflowLegacy:
return mpImpl->mbAnchoredTextOverflowLegacy;
- case SdrCompatibilityFlag::LegacySingleLineFontwork:
- return mpImpl->mbLegacySingleLineFontwork;
+ case SdrCompatibilityFlag::LegacyFontwork:
+ return mpImpl->mbLegacyFontwork;
case SdrCompatibilityFlag::ConnectorUseSnapRect:
return mpImpl->mbConnectorUseSnapRect;
case SdrCompatibilityFlag::IgnoreBreakAfterMultilineField:
@@ -1807,9 +1807,9 @@ void SdrModel::ReadUserDataSequenceValue(const beans::PropertyValue* pValue)
else if (pValue->Name == "LegacySingleLineFontwork")
{
bool bBool = false;
- if (pValue->Value >>= bBool)
+ if ((pValue->Value >>= bBool) && mpImpl->mbLegacyFontwork != bBool)
{
- mpImpl->mbLegacySingleLineFontwork = bBool;
+ mpImpl->mbLegacyFontwork = bBool;
// tdf#148000 hack: reset all CustomShape geometry as they may depend on this property
// Ideally this ReadUserDataSequenceValue should be called before geometry creation
// Once the calling order will be fixed, this hack will not be needed.
@@ -1845,7 +1845,7 @@ void SdrModel::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rValu
std::vector< std::pair< OUString, uno::Any > > aUserData
{
{ "AnchoredTextOverflowLegacy", uno::Any(GetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy)) },
- { "LegacySingleLineFontwork", uno::Any(GetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork)) },
+ { "LegacySingleLineFontwork", uno::Any(GetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork)) },
{ "ConnectorUseSnapRect", uno::Any(GetCompatibilityFlag(SdrCompatibilityFlag::ConnectorUseSnapRect)) },
{ "IgnoreBreakAfterMultilineField", uno::Any(GetCompatibilityFlag(SdrCompatibilityFlag::IgnoreBreakAfterMultilineField)) }
};
diff --git a/sw/source/uibase/app/docshini.cxx b/sw/source/uibase/app/docshini.cxx
index 6d3cf42a7858..5acee759dba2 100644
--- a/sw/source/uibase/app/docshini.cxx
+++ b/sw/source/uibase/app/docshini.cxx
@@ -482,7 +482,7 @@ bool SwDocShell::Load( SfxMedium& rMedium )
{
pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy,
true); // legacy processing for tdf#99729
- pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork,
+ pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork,
true); // legacy processing for tdf#148000
}
}