summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorAttila Szűcs <attila.szucs@collabora.com>2023-11-15 07:04:32 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-11-23 10:02:19 +0100
commit202f2d6f6529a8fe5a12dded879bafb546d9add3 (patch)
treeade7651041acd64d37f9e3282ef4385aaa888987 /svx
parent88639cdb35ff243263b04dacc794725b9e7e2703 (diff)
tdf#148000 impress: improve fontwork text placement.
Improved the calculation of positions of text characters for multi-line texts. The previous version only fitted the text to the basic outline (curve), and then scale them to the appropriate text line. This means that the text will be wider or shorter, depending on the shape of the curve, and which line it is on Now it calculates a curve for each paragraph and fits text on it. Text will be approximately the same width on each line. Except if the text is wider as the curve. Because then it shrinks the text to fit on the curve. (this can only happens on inner curves) Reused the same compat flag that was used in bug148000, now it serves as a Powerpoint compatible mode for FontWork, so no need to create new compat flag every time FontWork has improve. That means that the Fontwork in old documents has remains the same Refactored horizontal/vertical alignment, but had to keep the old hacks as well. Note: if there are too many lines of text, and the vertical alignment causes internal curves, then curves can shrink to 0 length (center point of a circle) or even to negative length, These cases are impossible to display normally, so it will be glitchy similar to how it was before this patch. MS PowerPoint avoid these cases by not allowing vertical alignments that would result internal (smaller) curves. Added unittest to check legacy-odb / new-odp / pptx file. It change the display of fontwork, so in some cases it may feel like a regression. Change-Id: Iac2d9bc751bbc2b6f747c33958f969cb3543fae5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159428 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'svx')
-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
6 files changed, 288 insertions, 44 deletions
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 7dbd96b04f67..bc73141d8107 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -424,6 +424,45 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_EOLinCurvedText)
}
}
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_CurvedTextEidth)
+{
+ std::vector<OUString> aFilenames
+ = { u"tdf148000_CurvedTextWidth.pptx", u"tdf148000_CurvedTextWidth_New.odp",
+ u"tdf148000_CurvedTextWidth_Legacy.odp" };
+
+ for (int i = 0; i < 3; i++)
+ {
+ loadFromURL(aFilenames[i]);
+
+ SdrPage* pSdrPage = getFirstDrawPageWithAssert();
+
+ xmlDocUniquePtr pXmlDoc = lcl_dumpAndParseFirstObjectWithAssert(pSdrPage);
+
+ OString aBasePath
+ = "/primitive2D/objectinfo[4]/unhandled/unhandled/polypolygoncolor/polypolygon/";
+
+ // 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").toInt32();
+ sal_Int32 nX2 = getXPath(pXmlDoc, aBasePath + "polygon[13]/point[1]", "x").toInt32();
+ sal_Int32 nX3 = getXPath(pXmlDoc, aBasePath + "polygon[6*14+1]/point[1]", "x").toInt32();
+ sal_Int32 nX4 = getXPath(pXmlDoc, aBasePath + "polygon[6*14+13]/point[1]", "x").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 648e5cfa56f3..4ca1bf17bd1e 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
@@ -567,6 +568,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;
@@ -718,10 +720,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 );
@@ -746,7 +750,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 )
@@ -773,46 +778,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() ) );
}
}
}
+
}
}
}
@@ -970,7 +1171,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 5c5d73d79a74..476594401021 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"))
@@ -1747,8 +1747,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;
@@ -1765,8 +1765,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:
@@ -1830,9 +1830,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.
@@ -1875,7 +1875,7 @@ void SdrModel::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rValu
addPair(aUserData, "AnchoredTextOverflowLegacy",
GetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy));
addPair(aUserData, "LegacySingleLineFontwork",
- GetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork));
+ GetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork));
addPair(aUserData, "ConnectorUseSnapRect",
GetCompatibilityFlag(SdrCompatibilityFlag::ConnectorUseSnapRect));
addPair(aUserData, "IgnoreBreakAfterMultilineField",