diff options
author | Attila Szűcs <attila.szucs@collabora.com> | 2023-01-13 04:49:33 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-01-20 07:56:29 +0000 |
commit | f9d6dd788e82a1964dab9cc0d0436c8c54b775c0 (patch) | |
tree | ed2d99c3771c43530f5883c2fa4e4102bd187854 /svx/source | |
parent | 14da39fcfffe8006a79971ac0b670e12d0d7a0ea (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>
Diffstat (limited to 'svx/source')
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShapeFontWork.cxx | 57 | ||||
-rw-r--r-- | svx/source/svdraw/svdmodel.cxx | 42 |
2 files changed, 87 insertions, 12 deletions
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()); |