diff options
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 9 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 22 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 124 |
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()) { |