summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorAttila Szűcs <attila.szucs@collabora.com>2023-01-13 04:49:33 +0100
committerAndras Timar <andras.timar@collabora.com>2023-01-23 12:47:04 +0000
commit497298874961fb335caf4cc91e531667394588bc (patch)
tree07cac688a8d24145f21d67575f5eb98b321b4b13 /svx
parent4a26d67dced163d79617b05131d66a05dafebc86 (diff)
tdf#148000 impress: Handle linebreaks on fontwork.
Split text lines in a paragraph, right before polygons are created for rendering, so eol will brake line in fontwork just like eop. Change-Id: Ie9e6764f9f91c2e19afd43dc9a212bd18c41c99d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145425 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit f9d6dd788e82a1964dab9cc0d0436c8c54b775c0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145804 Reviewed-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'svx')
-rw-r--r--svx/qa/unit/data/tdf148000_EOLinCurvedText.pptxbin0 -> 29206 bytes
-rw-r--r--svx/qa/unit/data/tdf148000_EOLinCurvedText_Legacy.odpbin0 -> 13692 bytes
-rw-r--r--svx/qa/unit/data/tdf148000_EOLinCurvedText_New.odpbin0 -> 13750 bytes
-rw-r--r--svx/qa/unit/svdraw.cxx42
-rw-r--r--svx/source/customshapes/EnhancedCustomShapeFontWork.cxx57
-rw-r--r--svx/source/svdraw/svdmodel.cxx42
6 files changed, 129 insertions, 12 deletions
diff --git a/svx/qa/unit/data/tdf148000_EOLinCurvedText.pptx b/svx/qa/unit/data/tdf148000_EOLinCurvedText.pptx
new file mode 100644
index 000000000000..137fc816697a
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_EOLinCurvedText.pptx
Binary files differ
diff --git a/svx/qa/unit/data/tdf148000_EOLinCurvedText_Legacy.odp b/svx/qa/unit/data/tdf148000_EOLinCurvedText_Legacy.odp
new file mode 100644
index 000000000000..13e7cc4e5c8a
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_EOLinCurvedText_Legacy.odp
Binary files differ
diff --git a/svx/qa/unit/data/tdf148000_EOLinCurvedText_New.odp b/svx/qa/unit/data/tdf148000_EOLinCurvedText_New.odp
new file mode 100644
index 000000000000..7ebdb9431b72
--- /dev/null
+++ b/svx/qa/unit/data/tdf148000_EOLinCurvedText_New.odp
Binary files differ
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index c2a7f244b8ab..7bf1ceb9d4a1 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -382,6 +382,48 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testFontWorks)
"32");
}
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_EOLinCurvedText)
+{
+ std::vector<OUString> aFilenames
+ = { u"tdf148000_EOLinCurvedText.pptx", u"tdf148000_EOLinCurvedText_New.odp",
+ u"tdf148000_EOLinCurvedText_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: "O" + eop + "O" + eol + "O"
+ // It should be displayed as 3 line of text. (1 "O" letter in every line)
+ sal_Int32 nY1 = getXPath(pXmlDoc, aBasePath + "polygon[1]/point[1]", "y").toInt32();
+ sal_Int32 nY2 = getXPath(pXmlDoc, aBasePath + "polygon[3]/point[1]", "y").toInt32();
+ sal_Int32 nY3 = getXPath(pXmlDoc, aBasePath + "polygon[5]/point[1]", "y").toInt32();
+
+ sal_Int32 nDiff21 = nY2 - nY1;
+ sal_Int32 nDiff32 = nY3 - nY2;
+
+ // the 2. "O" must be positioned much lower as the 1. "O". (the eop break the line)
+ CPPUNIT_ASSERT_GREATER(sal_Int32(300), nDiff21);
+ if (i < 2)
+ {
+ // the 3. "O" must be positioned even lower with 1 line. (the eol must break the line as well)
+ CPPUNIT_ASSERT_LESS(sal_Int32(50), abs(nDiff32 - nDiff21));
+ }
+ else
+ {
+ // In legacy mode, the 3. "O" must be positioned about the same high as the 2. "O"
+ // the eol not break the line.
+ CPPUNIT_ASSERT_LESS(sal_Int32(50), nDiff32);
+ }
+ }
+}
+
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 e8e3bd026cd1..672cd28fbc8e 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
@@ -36,6 +36,7 @@
#include <editeng/charscaleitem.hxx>
#include <svx/svdoashp.hxx>
#include <svx/sdshitm.hxx>
+#include <svx/svdmodel.hxx>
#include <editeng/outlobj.hxx>
#include <editeng/editobj.hxx>
#include <o3tl/numeric.hxx>
@@ -50,6 +51,7 @@
#include <sal/log.hxx>
#include <rtl/math.hxx>
#include <unotools/configmgr.hxx>
+#include <comphelper/string.hxx>
using namespace com::sun::star;
using namespace com::sun::star::uno;
@@ -116,27 +118,58 @@ static bool InitializeFontWorkData(
if ( pParaObj )
{
const EditTextObject& rTextObj = pParaObj->GetTextObject();
- sal_Int32 nParagraphsLeft = rTextObj.GetParagraphCount();
+ sal_Int32 nParagraphsCount = rTextObj.GetParagraphCount();
+
+ // Collect all the lines from all paragraphs
+ std::vector<int> aLineParaID; // which para this line is in
+ std::vector<int> aLineStart; // where this line start in that para
+ std::vector<int> aLineLength;
+ std::vector<OUString> aParaText;
+ for (sal_Int32 nPara = 0; nPara < nParagraphsCount; ++nPara)
+ {
+ aParaText.push_back(rTextObj.GetText(nPara));
+ sal_Int32 nPos = 0;
+ sal_Int32 nPrevPos = 0;
+ do
+ {
+ // search line break.
+ if (!rSdrObjCustomShape.getSdrModelFromSdrObject().IsLegacySingleLineFontwork())
+ nPos = aParaText[nPara].indexOf(sal_Unicode(u'\1'), nPrevPos);
+ else
+ nPos = -1; // tdf#148000: ignore line breaks in legacy fontworks
+
+ aLineParaID.push_back(nPara);
+ aLineStart.push_back(nPrevPos);
+ aLineLength.push_back((nPos >= 0 ? nPos : aParaText[nPara].getLength())
+ - nPrevPos);
+ nPrevPos = nPos + 1;
+ } while (nPos >= 0);
+ }
+
+ sal_Int32 nLinesLeft = aLineParaID.size();
- rFWData.nMaxParagraphsPerTextArea = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
- sal_Int32 j = 0;
- while( nParagraphsLeft && nTextAreaCount )
+ rFWData.nMaxParagraphsPerTextArea = ((nLinesLeft - 1) / nTextAreaCount) + 1;
+ sal_Int32 nLine = 0;
+ while (nLinesLeft && nTextAreaCount)
{
FWTextArea aTextArea;
- sal_Int32 i, nParagraphs = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
- for ( i = 0; i < nParagraphs; ++i, ++j )
+ sal_Int32 nLinesInPara = ((nLinesLeft - 1) / nTextAreaCount) + 1;
+ for (sal_Int32 i = 0; i < nLinesInPara; ++i, ++nLine)
{
FWParagraphData aParagraphData;
- aParagraphData.aString = rTextObj.GetText( j );
+ aParagraphData.aString = aParaText[aLineParaID[nLine]].subView(
+ aLineStart[nLine], aLineLength[nLine]);
- const SfxItemSet& rParaSet = rTextObj.GetParaAttribs( j ); // retrieving some paragraph attributes
- aParagraphData.nFrameDirection = rParaSet.Get( EE_PARA_WRITINGDIR ).GetValue();
- aTextArea.vParagraphs.push_back( aParagraphData );
+ // retrieving some paragraph attributes
+ const SfxItemSet& rParaSet = rTextObj.GetParaAttribs(aLineParaID[nLine]);
+ aParagraphData.nFrameDirection = rParaSet.Get(EE_PARA_WRITINGDIR).GetValue();
+ aTextArea.vParagraphs.push_back(aParagraphData);
}
- rFWData.vTextAreas.push_back( aTextArea );
- nParagraphsLeft -= nParagraphs;
+ rFWData.vTextAreas.push_back(aTextArea);
+ nLinesLeft -= nLinesInPara;
nTextAreaCount--;
}
+
bNoErr = true;
}
}
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 3feb1ae0669b..bc86671c9437 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -72,6 +72,9 @@
#include <comphelper/diagnose_ex.hxx>
#include <tools/UnitConversion.hxx>
#include <svx/ColorSets.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoashp.hxx>
+
using namespace ::com::sun::star;
@@ -80,12 +83,14 @@ struct SdrModelImpl
SfxUndoManager* mpUndoManager;
SdrUndoFactory* mpUndoFactory;
bool mbAnchoredTextOverflowLegacy; // tdf#99729 compatibility flag
+ bool mbLegacySingleLineFontwork; // tdf#148000 compatibility flag
std::unique_ptr<svx::Theme> mpTheme;
SdrModelImpl()
: mpUndoManager(nullptr)
, mpUndoFactory(nullptr)
, mbAnchoredTextOverflowLegacy(false)
+ , mbLegacySingleLineFontwork(false)
{}
};
@@ -1718,6 +1723,16 @@ bool SdrModel::IsAnchoredTextOverflowLegacy() const
return mpImpl->mbAnchoredTextOverflowLegacy;
}
+void SdrModel::SetLegacySingleLineFontwork(bool bEnabled)
+{
+ mpImpl->mbLegacySingleLineFontwork = bEnabled;
+}
+
+bool SdrModel::IsLegacySingleLineFontwork() const
+{
+ return mpImpl->mbLegacySingleLineFontwork;
+}
+
void SdrModel::ReformatAllTextObjects()
{
ImpReformatAllTextObjects();
@@ -1761,6 +1776,32 @@ void SdrModel::ReadUserDataSequenceValue(const beans::PropertyValue* pValue)
mpImpl->mbAnchoredTextOverflowLegacy = bBool;
}
}
+ else if (pValue->Name == "LegacySingleLineFontwork")
+ {
+ bool bBool = false;
+ if (pValue->Value >>= bBool)
+ {
+ mpImpl->mbLegacySingleLineFontwork = 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.
+ for (size_t i = 0; i < maPages.size(); ++i)
+ {
+ if (const SdrPage* pPage = maPages[i].get())
+ {
+ SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups);
+ while (aIter.IsMore())
+ {
+ SdrObject* pTempObj = aIter.Next();
+ if (SdrObjCustomShape* pShape = dynamic_cast<SdrObjCustomShape*>(pTempObj))
+ {
+ pShape->InvalidateRenderGeometry();
+ }
+ }
+ }
+ }
+ }
+ }
}
template <typename T>
@@ -1773,6 +1814,7 @@ void SdrModel::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rValu
{
std::vector< std::pair< OUString, uno::Any > > aUserData;
addPair(aUserData, "AnchoredTextOverflowLegacy", IsAnchoredTextOverflowLegacy());
+ addPair(aUserData, "LegacySingleLineFontwork", IsLegacySingleLineFontwork());
const sal_Int32 nOldLength = rValues.getLength();
rValues.realloc(nOldLength + aUserData.size());