summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
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())
{