[Libreoffice-commits] core.git: include/vcl vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Sep 5 16:06:07 UTC 2018


 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 <vmiklos at collabora.co.uk>
AuthorDate: Wed Sep 5 16:42:14 2018 +0200
Commit:     Miklos Vajna <vmiklos at 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 <vmiklos at 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 ) );


More information about the Libreoffice-commits mailing list