include/vcl/outdev.hxx | 9 ++++++--- vcl/source/outdev/text.cxx | 17 ++++++++++------- vcl/source/window/menu.cxx | 14 ++++++++++++-- vcl/source/window/menuitemlist.cxx | 23 +++++++++++++++++++++++ vcl/source/window/menuitemlist.hxx | 6 ++++++ 5 files changed, 57 insertions(+), 12 deletions(-)
New commits: commit d70bf1c4caf37f38166b5f1facc08264cd203f92 Author: Miklos Vajna <vmik...@collabora.co.uk> AuthorDate: Wed Sep 5 16:42:14 2018 +0200 Commit: Miklos Vajna <vmik...@collabora.co.uk> CommitDate: Wed Sep 5 18:05:43 2018 +0200 vcl: less text layout calls in Menu Number of GenericSalLayout::LayoutText() calls for each & every menu item till a Writer document is opened: 3 (before) -> 1 (after). Change-Id: I08a3d174bf15bafbcbce612712f2ab773cd5e085 Reviewed-on: https://gerrit.libreoffice.org/60045 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 693a905b342e..ba15a974f78d 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -995,7 +995,8 @@ public: void DrawCtrlText( const Point& rPos, const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1, - DrawTextFlags nStyle = DrawTextFlags::Mnemonic, MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr ); + DrawTextFlags nStyle = DrawTextFlags::Mnemonic, MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr, + const SalLayoutGlyphs* pGlyphs = nullptr); void DrawTextLine( const Point& rPos, long nWidth, FontStrikeout eStrikeout, @@ -1093,7 +1094,8 @@ public: OUString GetEllipsisString( const OUString& rStr, long nMaxWidth, DrawTextFlags nStyle = DrawTextFlags::EndEllipsis ) const; - long GetCtrlTextWidth( const OUString& rStr ) const; + long GetCtrlTextWidth( const OUString& rStr, + const SalLayoutGlyphs* pLayoutCache = nullptr ) const; static OUString GetNonMnemonicString( const OUString& rStr, sal_Int32& rMnemonicPos ); @@ -1163,7 +1165,8 @@ public: SalLayoutGlyphs const*const pLayoutCache = nullptr) const; void GetCaretPositions( const OUString&, long* pCaretXArray, - sal_Int32 nIndex, sal_Int32 nLen ) const; + sal_Int32 nIndex, sal_Int32 nLen, + const SalLayoutGlyphs* pGlyphs = nullptr ) const; void DrawStretchText( const Point& rStartPt, sal_uLong nWidth, const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1); diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index 5112814a35ec..e6b63a0a4286 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -1069,7 +1069,8 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry, } void OutputDevice::GetCaretPositions( const OUString& rStr, long* pCaretXArray, - sal_Int32 nIndex, sal_Int32 nLen ) const + sal_Int32 nIndex, sal_Int32 nLen, + const SalLayoutGlyphs* pGlyphs ) const { if( nIndex >= rStr.getLength() ) @@ -1078,7 +1079,8 @@ void OutputDevice::GetCaretPositions( const OUString& rStr, long* pCaretXArray, nLen = rStr.getLength() - nIndex; // layout complex text - std::unique_ptr<SalLayout> pSalLayout = ImplLayout( rStr, nIndex, nLen, Point(0,0) ); + std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, Point(0, 0), 0, nullptr, + SalLayoutFlags::NONE, nullptr, pGlyphs); if( !pSalLayout ) return; @@ -2082,7 +2084,8 @@ OUString OutputDevice::ImplGetEllipsisString( const OutputDevice& rTargetDevice, void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen, - DrawTextFlags nStyle, MetricVector* pVector, OUString* pDisplayText ) + DrawTextFlags nStyle, MetricVector* pVector, OUString* pDisplayText, + const SalLayoutGlyphs* pGlyphs ) { assert(!is_double_buffered_window()); @@ -2143,7 +2146,7 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr, } std::unique_ptr<long[]> const pCaretXArray(new long[2 * nLen]); - /*sal_Bool bRet =*/ GetCaretPositions( aStr, pCaretXArray.get(), nIndex, nLen ); + /*sal_Bool bRet =*/ GetCaretPositions( aStr, pCaretXArray.get(), nIndex, nLen, pGlyphs ); long lc_x1 = pCaretXArray[ 2*(nMnemonicPos - nIndex) ]; long lc_x2 = pCaretXArray[ 2*(nMnemonicPos - nIndex)+1 ]; nMnemonicWidth = ::abs(static_cast<int>(lc_x1 - lc_x2)); @@ -2210,7 +2213,7 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr, } else { - DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText ); + DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText, pGlyphs ); if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector && accel && (!autoacc || !(nStyle & DrawTextFlags::HideMnemonic)) ) { @@ -2223,7 +2226,7 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr, mpAlphaVDev->DrawCtrlText( rPos, rStr, nIndex, nLen, nStyle, pVector, pDisplayText ); } -long OutputDevice::GetCtrlTextWidth( const OUString& rStr ) const +long OutputDevice::GetCtrlTextWidth( const OUString& rStr, const SalLayoutGlyphs* pGlyphs ) const { sal_Int32 nLen = rStr.getLength(); sal_Int32 nIndex = 0; @@ -2237,7 +2240,7 @@ long OutputDevice::GetCtrlTextWidth( const OUString& rStr ) const else if ( (nMnemonicPos >= nIndex) && (static_cast<sal_uLong>(nMnemonicPos) < static_cast<sal_uLong>(nIndex+nLen)) ) nLen--; } - return GetTextWidth( aStr, nIndex, nLen ); + return GetTextWidth( aStr, nIndex, nLen, nullptr, pGlyphs ); } OUString OutputDevice::GetNonMnemonicString( const OUString& rStr, sal_Int32& rMnemonicPos ) diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 8cfeba05f33b..255a315f3755 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -65,6 +65,7 @@ #include <vcl/configsettings.hxx> #include <vcl/lazydelete.hxx> +#include <vcl/vcllayout.hxx> #include <map> #include <vector> @@ -1002,6 +1003,8 @@ void Menu::SetItemText( sal_uInt16 nItemId, const OUString& rStr ) if ( rStr != pData->aText ) { pData->aText = rStr; + // Clear layout for aText. + pData->aTextGlyphs.clear(); ImplSetMenuItemData( pData ); // update native menu if( ImplGetSalMenu() && pData->pSalMenuItem ) @@ -1513,7 +1516,8 @@ Size Menu::ImplCalcSize( vcl::Window* pWin ) // Text: if ( (pData->eType == MenuItemType::STRING) || (pData->eType == MenuItemType::STRINGIMAGE) ) { - long nTextWidth = pWin->GetCtrlTextWidth( pData->aText ); + const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(pWin); + long nTextWidth = pWin->GetCtrlTextWidth(pData->aText, pGlyphs); long nTextHeight = pWin->GetTextHeight(); if (IsMenuBar()) @@ -2009,7 +2013,13 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize, pData->bHiddenOnGUI = false; } - rRenderContext.DrawCtrlText(aTmpPos, aItemText, 0, aItemText.getLength(), nStyle, pVector, pDisplayText); + const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(&rRenderContext); + if (aItemText != pData->aText) + // Can't use pre-computed glyphs, item text was + // changed. + pGlyphs = nullptr; + rRenderContext.DrawCtrlText(aTmpPos, aItemText, 0, aItemText.getLength(), + nStyle, pVector, pDisplayText, pGlyphs); if (bSetTmpBackground) rRenderContext.SetBackground(); } diff --git a/vcl/source/window/menuitemlist.cxx b/vcl/source/window/menuitemlist.cxx index 1d63118af096..7be1f22f917e 100644 --- a/vcl/source/window/menuitemlist.cxx +++ b/vcl/source/window/menuitemlist.cxx @@ -38,6 +38,29 @@ MenuItemData::~MenuItemData() pSubMenu.disposeAndClear(); } +SalLayoutGlyphs* MenuItemData::GetTextGlyphs(OutputDevice* pOutputDevice) +{ + if (!aTextGlyphs.empty()) + // Use pre-calculated result. + return &aTextGlyphs; + + OUString aNonMnemonicString = OutputDevice::GetNonMnemonicString(aText); + std::unique_ptr<SalLayout> pLayout + = pOutputDevice->ImplLayout(aNonMnemonicString, 0, aNonMnemonicString.getLength(), + Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly); + if (!pLayout) + return nullptr; + + const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); + if (!pGlyphs) + return nullptr; + + // Remember the calculation result. + aTextGlyphs = *pGlyphs; + + return &aTextGlyphs; +} + MenuItemList::~MenuItemList() { } diff --git a/vcl/source/window/menuitemlist.hxx b/vcl/source/window/menuitemlist.hxx index bb7ef90dc026..5b9c3bb4ea6c 100644 --- a/vcl/source/window/menuitemlist.hxx +++ b/vcl/source/window/menuitemlist.hxx @@ -21,6 +21,7 @@ #include <vcl/image.hxx> #include <vcl/keycod.hxx> #include <vcl/menu.hxx> +#include <vcl/vcllayout.hxx> #include <com/sun/star/i18n/XCharacterClassification.hpp> @@ -36,6 +37,7 @@ struct MenuItemData MenuItemBits nBits; // MenuItem-Bits VclPtr<Menu> pSubMenu; // Pointer to SubMenu OUString aText; // Menu-Text + SalLayoutGlyphs aTextGlyphs; ///< Text layout of aText. OUString aHelpText; // Help-String OUString aTipHelpText; // TipHelp-String (eg, expanded filenames) OUString aCommandStr; // CommandString @@ -87,6 +89,10 @@ struct MenuItemData { } ~MenuItemData(); + + /// Computes aText's text layout (glyphs), cached in aTextGlyphs. + SalLayoutGlyphs* GetTextGlyphs(OutputDevice* pOutputDevice); + bool HasCheck() const { return bChecked || ( nBits & ( MenuItemBits::RADIOCHECK | MenuItemBits::CHECKABLE | MenuItemBits::AUTOCHECK ) ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits