summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-04-12 18:21:35 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-04-12 22:16:05 +0200
commite3830b06a9886620ed432a011d2de2abbb7a3a12 (patch)
tree7eb233e55e8c13df3f9186d839e3a4a946587e7e /editeng
parentefb60b6fb5e11c31fecddf1e0502c1fe4feb7b57 (diff)
don't FormatDoc() a whole long text if not necessary (tdf#144515)
The testcase has a very long text in a cell that is really high enough to hold only one line of text, yet EditEngine formats and wraps the entire string. Which can be expensive because of calling into text layout to find out width of a text portion, and this is done repeatedly for the yet-unformatted text, so pretty much O(N^2). For top-aligned text it's enough to format only as much as will fit and ignore the rest, so implement that and add EditEngine::EnableSkipOutsideFormat() to enable the optimization. Change-Id: Ida87a1843737a368798ba2b3e60eedc99ee0f611 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132932 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'editeng')
-rw-r--r--editeng/source/editeng/editeng.cxx5
-rw-r--r--editeng/source/editeng/impedit.hxx3
-rw-r--r--editeng/source/editeng/impedit2.cxx1
-rw-r--r--editeng/source/editeng/impedit3.cxx21
4 files changed, 29 insertions, 1 deletions
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index eb7d1ad5a6fa..237c78264e72 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -2856,6 +2856,11 @@ void EditEngine::DisableAttributeExpanding() {
pImpEditEngine->GetEditDoc().DisableAttributeExpanding();
}
+void EditEngine::EnableSkipOutsideFormat(bool set)
+{
+ pImpEditEngine->EnableSkipOutsideFormat(set);
+}
+
void EditEngine::SetLOKSpecialPaperSize(const Size& rSize)
{
pImpEditEngine->SetLOKSpecialPaperSize(rSize);
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 894bb822f676..e66988d60e0c 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -604,6 +604,7 @@ private:
bool bFirstWordCapitalization:1; // specifies if auto-correction should capitalize the first word or not
bool mbLastTryMerge:1;
bool mbReplaceLeadingSingleQuotationMark:1;
+ bool mbSkipOutsideFormat:1;
bool mbNbspRunNext; // can't be a bitfield as it is passed as bool&
@@ -1131,6 +1132,8 @@ public:
/** Whether last AutoCorrect inserted a NO-BREAK SPACE that may need to be removed again. */
bool IsNbspRunNext() const { return mbNbspRunNext; }
+ void EnableSkipOutsideFormat(bool set) { mbSkipOutsideFormat = set; }
+
void Dispose();
void SetLOKSpecialPaperSize(const Size& rSize) { aLOKSpecialPaperSize = rSize; }
const Size& GetLOKSpecialPaperSize() const { return aLOKSpecialPaperSize; }
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 4b7b3490d138..94cc2d479b36 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -123,6 +123,7 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
bFirstWordCapitalization(true),
mbLastTryMerge(false),
mbReplaceLeadingSingleQuotationMark(true),
+ mbSkipOutsideFormat(false),
mbNbspRunNext(false)
{
aStatus.GetControlWord() = EEControlBits::USECHARATTRIBS | EEControlBits::DOIDLEFORMAT |
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index cdcc05100730..372237ff9c70 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -621,10 +621,18 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
return FinishCreateLines( &rParaPortion );
}
+ sal_Int64 nCurrentPosY = nStartPosY;
+ // If we're allowed to skip parts outside and this cannot possibly fit in the given height,
+ // bail out to avoid possibly formatting a lot of text that will not be used. For the first
+ // paragraph still format at least a bit.
+ if( mbSkipOutsideFormat && nPara != 0
+ && !aStatus.AutoPageHeight() && aPaperSize.Height() < nCurrentPosY )
+ {
+ return false;
+ }
// Initialization...
-
// Always format for 100%:
bool bMapChanged = ImpCheckRefMapMode();
@@ -1607,6 +1615,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
// as nEnd points to the last character!
sal_Int32 nEndPortion = pLine->GetEndPortion();
+ nCurrentPosY += pLine->GetHeight();
// Next line or maybe a new line...
pLine = nullptr;
@@ -1617,6 +1626,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
nDelFromLine = nLine;
break;
}
+ // Stop processing if allowed and this is outside of the paper size height.
+ // Format at least two lines though, in case something detects whether
+ // the text has been wrapped or something similar.
+ if( mbSkipOutsideFormat && nLine > 2
+ && !aStatus.AutoPageHeight() && aPaperSize.Height() < nCurrentPosY )
+ {
+ if ( pLine && ( nIndex >= pNode->Len()) )
+ nDelFromLine = nLine;
+ break;
+ }
if ( !pLine )
{
if ( nIndex < pNode->Len() )