summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2024-03-28 12:30:34 +0900
committerTomaž Vajngerl <quikee@gmail.com>2024-04-03 04:06:50 +0200
commitf61ea135430d7b4a1fac7de1e57a1314fbb1b49e (patch)
treeb90ac8f11051ff25dd7204e2bfebff6dc31d79f3 /editeng
parentdb64748f1ee771da9da857f95601b9e08b577166 (diff)
editeng: use text scaling that better mimics MSO text scaling
Implement text scaling algorithm that is similar to MSO text scaling for text boxes for the compatibility purpuse, so that the Impress slides better match how the PP slides are layed out. This also moves the implementation into EditEng, where it is possible to better control how searching for the best scaling factor is performed without doing additional irrelevant work or trigger invalidations that should not be triggered. An additional change is that the paragraph with no content at the end are ignored, and are not taken into account when determining the height of the content. This is done for compatibility reasons. Fix horizontal spacing of tabs - the spacing shouldn't be scaled and the tab shouldn't include the space at the beginning of the line. Change-Id: Ie37fa67f1cf300e915a4ebaef2a7f968bf6c5744 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165441 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'editeng')
-rw-r--r--editeng/source/editeng/impedit.hxx9
-rw-r--r--editeng/source/editeng/impedit2.cxx22
-rw-r--r--editeng/source/editeng/impedit3.cxx124
3 files changed, 120 insertions, 35 deletions
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index a694196dbade..e09712f74bad 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -571,6 +571,7 @@ private:
Color maBackgroundColor;
+ ScalingParameters maCustomScalingParameters;
ScalingParameters maScalingParameters;
bool mbRoundToNearestPt;
@@ -657,6 +658,7 @@ private:
void ParaAttribsChanged( ContentNode const * pNode, bool bIgnoreUndoCheck = false );
void TextModified();
void CalcHeight(ParaPortion& rParaPortion);
+ bool isInEmptyClusterAtTheEnd(ParaPortion& rParaPortion);
void InsertUndo( std::unique_ptr<EditUndo> pUndo, bool bTryMerge = false );
void ResetUndoManager();
@@ -977,8 +979,11 @@ public:
void SetMinColumnWrapHeight(tools::Long nVal) { mnMinColumnWrapHeight = nVal; }
- void FormatDoc();
- void FormatFullDoc();
+ tools::Long FormatParagraphs(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs);
+ void ScaleContentToFitWindow(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs);
+ void FormatDoc();
+ void FormatFullDoc();
+
void UpdateViews( EditView* pCurView = nullptr );
void Paint( ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* pTargetDevice );
void Paint(OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, bool bStripOnly = false, Degree10 nOrientation = 0_deg10);
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index d3f07cec65ed..da4d851b3315 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -4388,12 +4388,31 @@ tools::Long ImpEditEngine::GetXPos(ParaPortion const& rParaPortion, EditLine con
return nX;
}
+/** Is true if paragraph is in the empty cluster of paragraphs at the end */
+bool ImpEditEngine::isInEmptyClusterAtTheEnd(ParaPortion& rPortion)
+{
+ sal_Int32 nPortion = GetParaPortions().GetPos(&rPortion);
+
+ auto& rParagraphs = GetParaPortions();
+ if (rParagraphs.Count() <= 0)
+ return false;
+
+ sal_Int32 nCurrent = rParagraphs.lastIndex();
+ while (nCurrent > 0 && rParagraphs.getRef(nCurrent).IsEmpty())
+ {
+ if (nCurrent == nPortion)
+ return true;
+ nCurrent--;
+ }
+ return false;
+}
+
void ImpEditEngine::CalcHeight(ParaPortion& rPortion)
{
rPortion.mnHeight = 0;
rPortion.mnFirstLineOffset = 0;
- if (!rPortion.IsVisible())
+ if (!rPortion.IsVisible() || isInEmptyClusterAtTheEnd(rPortion))
return;
OSL_ENSURE(rPortion.GetLines().Count(), "Paragraph with no lines in ParaPortion::CalcHeight");
@@ -4428,7 +4447,6 @@ void ImpEditEngine::CalcHeight(ParaPortion& rPortion)
rPortion.mnHeight += scaleYSpacingValue(rULItem.GetLower()); // not in the last
}
-
if ( !nPortion || maStatus.ULSpaceSummation() )
return;
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 821e345a1b05..a2dee889aa63 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -398,47 +398,34 @@ void ImpEditEngine::FormatFullDoc()
FormatDoc();
}
-void ImpEditEngine::FormatDoc()
+tools::Long ImpEditEngine::FormatParagraphs(o3tl::sorted_vector<sal_Int32>& aRepaintParagraphList)
{
- if (!IsUpdateLayout() || IsFormatting())
- return;
-
- mbIsFormatting = true;
-
- // Then I can also start the spell-timer...
- if ( GetStatus().DoOnlineSpelling() )
- StartOnlineSpellTimer();
-
+ sal_Int32 nParaCount = GetParaPortions().Count();
tools::Long nY = 0;
bool bGrow = false;
- // Here already, so that not always in CreateLines...
- sal_Int32 nParaCount = GetParaPortions().Count();
- o3tl::sorted_vector<sal_Int32> aRepaintParas;
- aRepaintParas.reserve(nParaCount);
-
- for ( sal_Int32 nPara = 0; nPara < nParaCount; nPara++ )
+ for (sal_Int32 nParagraph = 0; nParagraph < nParaCount; nParagraph++)
{
- ParaPortion& rParaPortion = GetParaPortions().getRef(nPara);
+ ParaPortion& rParaPortion = GetParaPortions().getRef(nParagraph);
if (rParaPortion.MustRepaint() || (rParaPortion.IsInvalid() && rParaPortion.IsVisible()))
{
// No formatting should be necessary for MustRepaint()!
- if (!rParaPortion.IsInvalid() || CreateLines( nPara, nY ) )
+ if (CreateLines(nParagraph, nY))
{
- if ( !bGrow && GetTextRanger() )
+ if (!bGrow && GetTextRanger())
{
// For a change in height all below must be reformatted...
- for ( sal_Int32 n = nPara+1; n < GetParaPortions().Count(); n++ )
+ for (sal_Int32 n = nParagraph + 1; n < nParaCount; n++)
{
ParaPortion& rParaPortionToInvalidate = GetParaPortions().getRef(n);
- rParaPortionToInvalidate.MarkSelectionInvalid( 0 );
+ rParaPortionToInvalidate.MarkSelectionInvalid(0);
rParaPortionToInvalidate.GetLines().Reset();
}
}
bGrow = true;
- if ( IsCallParaInsertedOrDeleted() )
+ if (IsCallParaInsertedOrDeleted())
{
- GetEditEnginePtr()->ParagraphHeightChanged( nPara );
+ GetEditEnginePtr()->ParagraphHeightChanged(nParagraph);
for (EditView* pView : maEditViews)
{
@@ -446,13 +433,88 @@ void ImpEditEngine::FormatDoc()
}
}
- rParaPortion.SetMustRepaint( false );
+ rParaPortion.SetMustRepaint(false);
}
- aRepaintParas.insert(nPara);
+ aRepaintParagraphList.insert(nParagraph);
}
nY += rParaPortion.GetHeight();
}
+ return nY;
+}
+
+namespace
+{
+constexpr std::array<ScalingParameters, 13> constScaleLevels =
+{
+ ScalingParameters{100.0, 100.0, 100.0, 90.0 },
+ ScalingParameters{ 92.5, 92.5, 100.0, 90.0 },
+ ScalingParameters{ 92.5, 92.5, 100.0, 80.0 },
+ ScalingParameters{ 85.0, 85.0, 100.0, 90.0 },
+ ScalingParameters{ 85.0, 85.0, 100.0, 80.0 },
+ ScalingParameters{ 77.5, 77.5, 100.0, 80.0 },
+ ScalingParameters{ 70.0, 70.0, 100.0, 80.0 },
+ ScalingParameters{ 62.5, 62.5, 100.0, 80.0 },
+ ScalingParameters{ 55.0, 55.0, 100.0, 80.0 },
+ ScalingParameters{ 47.5, 47.5, 100.0, 80.0 },
+ ScalingParameters{ 40.0, 40.0, 100.0, 80.0 },
+ ScalingParameters{ 32.5, 32.5, 100.0, 80.0 },
+ ScalingParameters{ 25.0, 25.0, 100.0, 80.0 },
+};
+
+} // end anonymous ns
+
+void ImpEditEngine::ScaleContentToFitWindow(o3tl::sorted_vector<sal_Int32>& aRepaintParagraphList)
+{
+ if (!maCustomScalingParameters.areValuesDefault())
+ maScalingParameters = maCustomScalingParameters;
+
+ tools::Long nHeight = FormatParagraphs(aRepaintParagraphList);
+ bool bOverflow = nHeight > (maMaxAutoPaperSize.Height() * mnColumns);
+
+ size_t nCurrentScaleLevel = 0;
+ while (bOverflow && nCurrentScaleLevel < constScaleLevels.size())
+ {
+ // Clean-up and reset paragraphs
+ aRepaintParagraphList.clear();
+ for (auto& pParaPortionToInvalidate : GetParaPortions())
+ {
+ pParaPortionToInvalidate->GetLines().Reset();
+ pParaPortionToInvalidate->MarkSelectionInvalid(0);
+ pParaPortionToInvalidate->SetMustRepaint(true);
+ }
+
+ // Get new scaling parameters
+ maScalingParameters = constScaleLevels[nCurrentScaleLevel];
+
+ // Try again with different scaling factor
+ nHeight = FormatParagraphs(aRepaintParagraphList);
+ bOverflow = nHeight > (maMaxAutoPaperSize.Height() * mnColumns);
+
+ // Increase scale level
+ nCurrentScaleLevel++;
+ }
+}
+
+void ImpEditEngine::FormatDoc()
+{
+ if (!IsUpdateLayout() || IsFormatting())
+ return;
+
+ mbIsFormatting = true;
+
+ // Then I can also start the spell-timer...
+ if (GetStatus().DoOnlineSpelling())
+ StartOnlineSpellTimer();
+
+ // Reserve, as it should match the current number of paragraphs
+ o3tl::sorted_vector<sal_Int32> aRepaintParagraphList;
+ aRepaintParagraphList.reserve(GetParaPortions().Count());
+
+ if (maStatus.DoStretch())
+ ScaleContentToFitWindow(aRepaintParagraphList);
+ else
+ FormatParagraphs(aRepaintParagraphList);
maInvalidRect = tools::Rectangle(); // make empty
@@ -491,10 +553,10 @@ void ImpEditEngine::FormatDoc()
}
}
- if (!aRepaintParas.empty())
+ if (!aRepaintParagraphList.empty())
{
auto CombineRepaintParasAreas = [&](const LineAreaInfo& rInfo) {
- if (aRepaintParas.count(rInfo.nPortion))
+ if (aRepaintParagraphList.count(rInfo.nPortion))
maInvalidRect.Union(rInfo.aArea);
return CallbackResult::Continue;
};
@@ -1010,9 +1072,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
if (maStatus.DoStretch() && (fFontScalingX != 100.0))
nCurPos = basegfx::fround(double(nCurPos) * 100.0 / std::max(fFontScalingX, 1.0));
- short nAllSpaceBeforeText = static_cast< short >(rLRItem.GetTextLeft()/* + rLRItem.GetTextLeft()*/ + nSpaceBeforeAndMinLabelWidth);
- aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText /*rLRItem.GetTextLeft()*/, maEditDoc.GetDefTab() );
- aCurrentTab.nTabPos = scaleXFontValue(tools::Long(aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText/*rLRItem.GetTextLeft()*/));
+ short nAllSpaceBeforeText = short(rLRItem.GetTextLeft());
+ aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText , maEditDoc.GetDefTab() );
+ aCurrentTab.nTabPos = tools::Long(aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText);
aCurrentTab.bValid = false;
// Switch direction in R2L para...
@@ -4542,7 +4604,7 @@ void ImpEditEngine::setScalingParameters(ScalingParameters const& rScalingParame
}
bool bScalingChanged = maScalingParameters != aNewScalingParameters;
- maScalingParameters = aNewScalingParameters;
+ maCustomScalingParameters = maScalingParameters = aNewScalingParameters;
if (bScalingChanged && maStatus.DoStretch())
{