summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2018-09-05 16:42:14 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2018-09-05 18:05:43 +0200
commitd70bf1c4caf37f38166b5f1facc08264cd203f92 (patch)
tree41deb2dfcf215e59248bcda925500938fa213cbb
parenta91dfea300a379c2f754dbb1d5a002d093b73032 (diff)
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 <vmiklos@collabora.co.uk> Tested-by: Jenkins
-rw-r--r--include/vcl/outdev.hxx9
-rw-r--r--vcl/source/outdev/text.cxx17
-rw-r--r--vcl/source/window/menu.cxx14
-rw-r--r--vcl/source/window/menuitemlist.cxx23
-rw-r--r--vcl/source/window/menuitemlist.hxx6
5 files changed, 57 insertions, 12 deletions
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 ) );