sc/source/ui/inc/output.hxx | 9 +- sc/source/ui/view/output.cxx | 4 + sc/source/ui/view/output2.cxx | 148 ++++++++++++++++++++++++------------------ 3 files changed, 94 insertions(+), 67 deletions(-)
New commits: commit c546b33dde8760cdc8d9990e672cc8cb344e470e Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Oct 13 09:49:57 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed Oct 18 18:52:08 2023 +0200 cool#6893 cache the EditEngine for rendering to avoid re-allocating one constantly Change-Id: I7d6c97a7f68126979bd8a5c12cfd6e680a789d3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157906 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx index 1a445f9e14e4..e4763767b7f5 100644 --- a/sc/source/ui/inc/output.hxx +++ b/sc/source/ui/inc/output.hxx @@ -240,6 +240,7 @@ private: // #i74769# use SdrPaintWindow direct, remember it during BeginDrawLayers/EndDrawLayers SdrPaintWindow* mpTargetPaintWindow; const sc::SpellCheckContext* mpSpellCheckCxt; + std::unique_ptr<ScFieldEditEngine> mxOutputEditEngine; // private methods @@ -278,7 +279,7 @@ private: void DrawEditStacked(DrawEditParam& rParam); void DrawEditAsianVertical(DrawEditParam& rParam); - std::unique_ptr<ScFieldEditEngine> CreateOutputEditEngine(); + void InitOutputEditEngine(); void SetClipMarks( OutputAreaParam &aAreaParam, ScCellInfo* pClipMarkCell, SvxCellHorJustify eOutHorJust, tools::Long nLayoutSign ); @@ -318,14 +319,14 @@ public: void SetSpellCheckContext( const sc::SpellCheckContext* pCxt ); void SetContentDevice( OutputDevice* pContentDev ); - void SetRefDevice( OutputDevice* pRDev ) { mpRefDevice = pFmtDevice = pRDev; } - void SetFmtDevice( OutputDevice* pRDev ) { pFmtDevice = pRDev; } + void SetRefDevice( OutputDevice* pRDev ); + void SetFmtDevice( OutputDevice* pRDev ); void SetViewShell( ScTabViewShell* pSh ) { pViewShell = pSh; } void SetDrawView( FmFormView* pNew ) { pDrawView = pNew; } void SetSolidBackground( bool bSet ) { bSolidBackground = bSet; } - void SetUseStyleColor( bool bSet ) { mbUseStyleColor = bSet; } + void SetUseStyleColor( bool bSet ); void SetEditCell( SCCOL nCol, SCROW nRow ); void SetSyntaxMode( bool bNewMode ); diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index f3b4b3ca9be2..8461aaaac446 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -61,6 +61,7 @@ #include <postit.hxx> #include <validat.hxx> #include <detfunc.hxx> +#include <editutil.hxx> #include <SparklineRenderer.hxx> #include <colorscale.hxx> @@ -212,6 +213,7 @@ ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType, // always needed, so call at the end of the constructor SetCellRotations(); + InitOutputEditEngine(); } ScOutputData::~ScOutputData() @@ -262,6 +264,8 @@ void ScOutputData::SetShowFormulas( bool bSet ) void ScOutputData::SetShowSpellErrors( bool bSet ) { bShowSpellErrors = bSet; + // reset EditEngine because it depends on bShowSpellErrors + mxOutputEditEngine.reset(); } void ScOutputData::SetSnapPixel() diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 6dbd218caf61..c80c6483bc5e 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -2177,27 +2177,56 @@ void ScOutputData::LayoutStrings(bool bPixelToLogic) ScProgress::DeleteInterpretProgress(); } -std::unique_ptr<ScFieldEditEngine> ScOutputData::CreateOutputEditEngine() +void ScOutputData::SetRefDevice( OutputDevice* pRDev ) { - std::unique_ptr<ScFieldEditEngine> pEngine(new ScFieldEditEngine(mpDoc, mpDoc->GetEnginePool())); - pEngine->SetUpdateLayout( false ); - pEngine->EnableUndo( false ); // don't need undo for painting purposes - // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice - pEngine->SetRefDevice( pFmtDevice ); - EEControlBits nCtrl = pEngine->GetControlWord(); - if ( bShowSpellErrors ) - nCtrl |= EEControlBits::ONLINESPELLING; - if ( eType == OUTTYPE_PRINTER ) - nCtrl &= ~EEControlBits::MARKFIELDS; + mpRefDevice = pFmtDevice = pRDev; + // reset EditEngine because it depends on pFmtDevice and mpRefDevice + mxOutputEditEngine.reset(); +} + +void ScOutputData::SetFmtDevice( OutputDevice* pRDev ) +{ + pFmtDevice = pRDev; + // reset EditEngine because it depends on pFmtDevice + mxOutputEditEngine.reset(); +} + +void ScOutputData::SetUseStyleColor( bool bSet ) +{ + mbUseStyleColor = bSet; + // reset EditEngine because it depends on mbUseStyleColor + mxOutputEditEngine.reset(); +} + +void ScOutputData::InitOutputEditEngine() +{ + if (!mxOutputEditEngine) + { + mxOutputEditEngine = std::make_unique<ScFieldEditEngine>(mpDoc, mpDoc->GetEnginePool()); + mxOutputEditEngine->SetUpdateLayout( false ); + mxOutputEditEngine->EnableUndo( false ); // don't need undo for painting purposes + // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice + mxOutputEditEngine->SetRefDevice( pFmtDevice ); + EEControlBits nCtrl = mxOutputEditEngine->GetControlWord(); + if ( bShowSpellErrors ) + nCtrl |= EEControlBits::ONLINESPELLING; + if ( eType == OUTTYPE_PRINTER ) + nCtrl &= ~EEControlBits::MARKFIELDS; + else + nCtrl &= ~EEControlBits::MARKURLFIELDS; // URLs not shaded for output + if ( eType == OUTTYPE_WINDOW && mpRefDevice == pFmtDevice ) + nCtrl &= ~EEControlBits::FORMAT100; // use the actual MapMode + mxOutputEditEngine->SetControlWord( nCtrl ); + mxOutputEditEngine->EnableAutoColor( mbUseStyleColor ); + } else - nCtrl &= ~EEControlBits::MARKURLFIELDS; // URLs not shaded for output - if ( eType == OUTTYPE_WINDOW && mpRefDevice == pFmtDevice ) - nCtrl &= ~EEControlBits::FORMAT100; // use the actual MapMode - pEngine->SetControlWord( nCtrl ); - mpDoc->ApplyAsianEditSettings( *pEngine ); - pEngine->EnableAutoColor( mbUseStyleColor ); - pEngine->SetDefaultHorizontalTextDirection( mpDoc->GetEditTextDirection( nTab ) ); - return pEngine; + { + // just in case someone turned it on during the last paint cycle + mxOutputEditEngine->SetUpdateLayout( false ); + } + // we don't track changes to these settings, so we have to apply them every time + mpDoc->ApplyAsianEditSettings( *mxOutputEditEngine ); + mxOutputEditEngine->SetDefaultHorizontalTextDirection( mpDoc->GetEditTextDirection( nTab ) ); } static void lcl_ClearEdit( EditEngine& rEngine ) // text and attributes @@ -4350,7 +4379,8 @@ void ScOutputData::DrawEditAsianVertical(DrawEditParam& rParam) void ScOutputData::DrawEdit(bool bPixelToLogic) { - std::unique_ptr<ScFieldEditEngine> pEngine; + InitOutputEditEngine(); + bool bHyphenatorSet = false; const ScPatternAttr* pOldPattern = nullptr; const SfxItemSet* pOldCondSet = nullptr; @@ -4464,10 +4494,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic) } } SfxItemSet* pPreviewFontSet = mpDoc->GetPreviewFont( nCellX, nCellY, nTab ); - if (!pEngine) - pEngine = CreateOutputEditEngine(); - else - lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False) + lcl_ClearEdit( *mxOutputEditEngine ); // also calls SetUpdateMode(sal_False) // fdo#32530: Check if the first character is RTL. OUString aStr = mpDoc->GetString(nCellX, nCellY, nTab); @@ -4480,7 +4507,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic) SvxCellHorJustify::Block : aParam.meHorJustContext; aParam.mbPixelToLogic = bPixelToLogic; aParam.mbHyphenatorSet = bHyphenatorSet; - aParam.mpEngine = pEngine.get(); + aParam.mpEngine = mxOutputEditEngine.get(); aParam.maCell = aCell; aParam.mnArrY = nArrY; aParam.mnX = nX; @@ -4531,8 +4558,6 @@ void ScOutputData::DrawEdit(bool bPixelToLogic) nRowPosY += pRowInfo[nArrY].nHeight; } - pEngine.reset(); - if (mrTabInfo.maArray.HasCellRotation()) { DrawRotated(bPixelToLogic); //! call from outside ? @@ -4541,6 +4566,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic) void ScOutputData::DrawRotated(bool bPixelToLogic) { + InitOutputEditEngine(); //! store nRotMax SCCOL nRotMax = nX2; for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++) @@ -4552,7 +4578,6 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) bool bCellContrast = mbUseStyleColor && Application::GetSettings().GetStyleSettings().GetHighContrastMode(); - std::unique_ptr<ScFieldEditEngine> pEngine; bool bHyphenatorSet = false; const ScPatternAttr* pPattern; const SfxItemSet* pCondSet; @@ -4593,10 +4618,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) if (!bHidden) { - if (!pEngine) - pEngine = CreateOutputEditEngine(); - else - lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False) + lcl_ClearEdit( *mxOutputEditEngine ); // also calls SetUpdateMode(sal_False) tools::Long nPosY = nRowPosY; @@ -4677,7 +4699,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) // StringDiffer doesn't look at hyphenate, language items if ( pPattern != pOldPattern || pCondSet != pOldCondSet ) { - auto pSet = std::make_unique<SfxItemSet>( pEngine->GetEmptyItemSet() ); + auto pSet = std::make_unique<SfxItemSet>( mxOutputEditEngine->GetEmptyItemSet() ); pPattern->FillEditItemSet( pSet.get(), pCondSet ); // adjustment for EditEngine @@ -4688,22 +4710,22 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); bool bParaHyphenate = pSet->Get(EE_PARA_HYPHENATE).GetValue(); - pEngine->SetDefaults( std::move(pSet) ); + mxOutputEditEngine->SetDefaults( std::move(pSet) ); pOldPattern = pPattern; pOldCondSet = pCondSet; - EEControlBits nControl = pEngine->GetControlWord(); + EEControlBits nControl = mxOutputEditEngine->GetControlWord(); if (eOrient==SvxCellOrientation::Stacked) nControl |= EEControlBits::ONECHARPERLINE; else nControl &= ~EEControlBits::ONECHARPERLINE; - pEngine->SetControlWord( nControl ); + mxOutputEditEngine->SetControlWord( nControl ); if ( !bHyphenatorSet && bParaHyphenate ) { // set hyphenator the first time it is needed css::uno::Reference<css::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() ); - pEngine->SetHyphenator( xXHyphenator ); + mxOutputEditEngine->SetHyphenator( xXHyphenator ); bHyphenatorSet = true; } @@ -4711,7 +4733,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) pPattern->GetItem( ATTR_BACKGROUND, pCondSet ).GetColor(); if ( mbUseStyleColor && ( aBackCol.IsTransparent() || bCellContrast ) ) aBackCol = nConfBackColor; - pEngine->SetBackgroundColor( aBackCol ); + mxOutputEditEngine->SetBackgroundColor( aBackCol ); } // margins @@ -4821,16 +4843,16 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) aPaperSize.setWidth( nOutHeight - 1 ); } if (bPixelToLogic) - pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); + mxOutputEditEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); else - pEngine->SetPaperSize(aPaperSize); // scale is always 1 + mxOutputEditEngine->SetPaperSize(aPaperSize); // scale is always 1 // read data from cell if (aCell.getType() == CELLTYPE_EDIT) { if (aCell.getEditText()) - pEngine->SetTextCurrentDefaults(*aCell.getEditText()); + mxOutputEditEngine->SetTextCurrentDefaults(*aCell.getEditText()); else { OSL_FAIL("pData == 0"); @@ -4848,22 +4870,22 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) mbShowNullValues, mbShowFormulas); - pEngine->SetTextCurrentDefaults(aString); + mxOutputEditEngine->SetTextCurrentDefaults(aString); if ( pColor && !mbSyntaxMode && !( mbUseStyleColor && mbForceAutoColor ) ) - lcl_SetEditColor( *pEngine, *pColor ); + lcl_SetEditColor( *mxOutputEditEngine, *pColor ); } if ( mbSyntaxMode ) { - SetEditSyntaxColor(*pEngine, aCell); + SetEditSyntaxColor(*mxOutputEditEngine, aCell); } else if ( mbUseStyleColor && mbForceAutoColor ) - lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine + lcl_SetEditColor( *mxOutputEditEngine, COL_AUTO ); //! or have a flag at EditEngine - pEngine->SetUpdateLayout( true ); // after SetText, before CalcTextWidth/GetTextHeight + mxOutputEditEngine->SetUpdateLayout( true ); // after SetText, before CalcTextWidth/GetTextHeight - tools::Long nEngineWidth = static_cast<tools::Long>(pEngine->CalcTextWidth()); - tools::Long nEngineHeight = pEngine->GetTextHeight(); + tools::Long nEngineWidth = static_cast<tools::Long>(mxOutputEditEngine->CalcTextWidth()); + tools::Long nEngineHeight = mxOutputEditEngine->GetTextHeight(); if (nAttrRotate && bBreak) { @@ -4897,13 +4919,13 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) // set paper width and get new text height aPaperSize.setWidth( nNewWidth ); if (bPixelToLogic) - pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); + mxOutputEditEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); else - pEngine->SetPaperSize(aPaperSize); // Scale is always 1 - //pEngine->QuickFormatDoc( sal_True ); + mxOutputEditEngine->SetPaperSize(aPaperSize); // Scale is always 1 + //mxOutputEditEngine->QuickFormatDoc( sal_True ); - nEngineWidth = static_cast<tools::Long>(pEngine->CalcTextWidth()); - nEngineHeight = pEngine->GetTextHeight(); + nEngineWidth = static_cast<tools::Long>(mxOutputEditEngine->CalcTextWidth()); + nEngineHeight = mxOutputEditEngine->GetTextHeight(); } } } @@ -4982,22 +5004,22 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) aAreaParam.mbLeftClip = aAreaParam.mbRightClip = true; // always do height - ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *mxOutputEditEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, false, eOrient, nAttrRotate, bPixelToLogic, nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); if ( eRotMode == SVX_ROTATE_MODE_STANDARD ) { // do width only if rotating within the cell (standard mode) - ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *mxOutputEditEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, true, eOrient, nAttrRotate, bPixelToLogic, nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); } // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine // (but width is only valid for standard mode) - nRealWidth = static_cast<tools::Long>(pEngine->CalcTextWidth()); - nRealHeight = pEngine->GetTextHeight(); + nRealWidth = static_cast<tools::Long>(mxOutputEditEngine->CalcTextWidth()); + nRealHeight = mxOutputEditEngine->GetTextHeight(); if ( eRotMode != SVX_ROTATE_MODE_STANDARD ) nEngineWidth = static_cast<tools::Long>( nRealHeight / fabs( nSin ) ); @@ -5076,21 +5098,21 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) if (eHorJust==SvxCellHorJustify::Right || eHorJust==SvxCellHorJustify::Center) { - pEngine->SetUpdateLayout( false ); + mxOutputEditEngine->SetUpdateLayout( false ); SvxAdjust eSvxAdjust = (eHorJust==SvxCellHorJustify::Right) ? SvxAdjust::Right : SvxAdjust::Center; - pEngine->SetDefaultItem( + mxOutputEditEngine->SetDefaultItem( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); aPaperSize.setWidth( nOutWidth ); if (bPixelToLogic) - pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); + mxOutputEditEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize)); else - pEngine->SetPaperSize(aPaperSize); + mxOutputEditEngine->SetPaperSize(aPaperSize); - pEngine->SetUpdateLayout( true ); + mxOutputEditEngine->SetUpdateLayout( true ); } } else @@ -5200,7 +5222,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) // bSimClip is not used here (because nOriVal is set) - pEngine->Draw(*mpDev, aLogicStart, nOriVal); + mxOutputEditEngine->Draw(*mpDev, aLogicStart, nOriVal); if (bMetaFile) mpDev->Pop();