[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - vcl/inc vcl/source vcl/win

Khaled Hosny khaledhosny at eglug.org
Fri Dec 16 05:57:20 UTC 2016


 vcl/inc/CommonSalLayout.hxx        |    3 +
 vcl/inc/win/salgdi.h               |    3 +
 vcl/inc/win/winlayout.hxx          |    2 
 vcl/source/gdi/CommonSalLayout.cxx |    1 
 vcl/win/gdi/winlayout.cxx          |   95 +++++++++++++++++++++++++++++++------
 5 files changed, 90 insertions(+), 14 deletions(-)

New commits:
commit d85003a8af8b454b34eea0ac67c8dd9184a0b6d3
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Dec 15 02:47:13 2016 +0200

    tdf#104159: Re-enable OpenGL glyph caching on Windows
    
    Reviewed-on: https://gerrit.libreoffice.org/32026
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>
    (cherry picked from commit 9cf20b5f0473db0b4dd2dcf607b7884f40762995)
    
    Change-Id: Icafec05a8cf4428d806efcb286addf3042fcf021
    Reviewed-on: https://gerrit.libreoffice.org/32066
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index e5345d7..e2f3a11 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -45,6 +45,7 @@ class CommonSalLayout : public GenericSalLayout
 #ifdef _WIN32
     HDC                     mhDC;
     HFONT                   mhFont;
+    WinFontInstance&        mrWinFontInstance;
     double                  mnAveWidthFactor;
 #elif defined(MACOSX) || defined(IOS)
     const CoreTextStyle&    mrCoreTextStyle;
@@ -65,6 +66,8 @@ public:
 #if defined(_WIN32)
     explicit                CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&);
     const FontSelectPattern& getFontSelData() const { return mrFontSelData; };
+    HFONT                   getHFONT() const { return mhFont; }
+    WinFontInstance&        getWinFontInstance() const { return mrWinFontInstance; }
 #elif defined(MACOSX) || defined(IOS)
     explicit                CommonSalLayout(const CoreTextStyle&);
     const CoreTextStyle&    getFontData() const { return mrCoreTextStyle; };
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 3050055..14310f9 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -236,6 +236,9 @@ private:
 
     LogicalFontInstance* GetWinFontEntry(int nFallbackLevel);
 
+    bool CacheGlyphs(const CommonSalLayout& rLayout);
+    bool DrawCachedGlyphs(const CommonSalLayout& rLayout);
+
 public:
     HDC getHDC() const { return mhLocalDC; }
     void setHDC(HDC aNew) { mhLocalDC = aNew; }
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 7b15e7e..8ceebea 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -193,7 +193,7 @@ public:
 private:
     GlyphCache maGlyphCache;
 public:
-    bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics);
+    bool CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics);
 
     GlyphCache& GetGlyphCache()
     {
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index dbc3fa8..8ab8eb3 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -181,6 +181,7 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con
 :   mrFontSelData(rWinFontInstance.maFontSelData)
 ,   mhDC(hDC)
 ,   mhFont(static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)))
+,   mrWinFontInstance(rWinFontInstance)
 ,   mnAveWidthFactor(1.0f)
 ,   mpVertGlyphs(nullptr)
 {
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index c693b31..2d35175 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -66,7 +66,7 @@ inline int WinFontInstance::GetCachedGlyphWidth( int nCharCode ) const
     return it->second;
 }
 
-bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics)
+bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics)
 {
     if (nGlyphIndex == DROPPED_OUTGLYPH)
         return true;
@@ -77,17 +77,17 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex,
     std::vector<uint32_t> aCodePointsOrGlyphIndices(1);
     aCodePointsOrGlyphIndices[0] = nGlyphIndex;
 
-    HDC hDC = CreateCompatibleDC(rLayout.mhDC);
-    if (hDC == nullptr)
+    HDC hNewDC = CreateCompatibleDC(hDC);
+    if (hNewDC == nullptr)
     {
         SAL_WARN("vcl.gdi", "CreateCompatibleDC failed: " << WindowsErrorString(GetLastError()));
         return false;
     }
-    HFONT hOrigFont = static_cast<HFONT>(SelectObject(hDC, rLayout.mhFont));
+    HFONT hOrigFont = static_cast<HFONT>(SelectObject(hNewDC, hFont));
     if (hOrigFont == nullptr)
     {
         SAL_WARN("vcl.gdi", "SelectObject failed: " << WindowsErrorString(GetLastError()));
-        DeleteDC(hDC);
+        DeleteDC(hNewDC);
         return false;
     }
 
@@ -96,26 +96,26 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex,
     if (!pTxt)
         return false;
 
-    if (!pTxt->BindFont(hDC))
+    if (!pTxt->BindFont(hNewDC))
     {
         SAL_WARN("vcl.gdi", "Binding of font failed. The font might not be supported by Direct Write.");
-        DeleteDC(hDC);
+        DeleteDC(hNewDC);
         return false;
     }
 
     // Bail for non-horizontal text.
     {
         wchar_t sFaceName[200];
-        int nFaceNameLen = GetTextFaceW(hDC, SAL_N_ELEMENTS(sFaceName), sFaceName);
+        int nFaceNameLen = GetTextFaceW(hNewDC, SAL_N_ELEMENTS(sFaceName), sFaceName);
 
         if (!nFaceNameLen)
             SAL_WARN("vcl.gdi", "GetTextFace failed: " << WindowsErrorString(GetLastError()));
 
         LOGFONTW aLogFont;
-        GetObjectW(rLayout.mhFont, sizeof(LOGFONTW), &aLogFont);
+        GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont);
 
-        SelectObject(hDC, hOrigFont);
-        DeleteDC(hDC);
+        SelectObject(hNewDC, hOrigFont);
+        DeleteDC(hNewDC);
 
         if (sFaceName[0] == '@' || aLogFont.lfOrientation != 0 || aLogFont.lfEscapement != 0)
         {
@@ -1160,7 +1160,7 @@ bool SimpleWinLayout::CacheGlyphs(SalGraphics& rGraphics) const
 
         if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint))
         {
-            if (!mrWinFontEntry.CacheGlyphToAtlas(false, nCodePoint, *this, rGraphics))
+            if (!mrWinFontEntry.CacheGlyphToAtlas(false, mhDC, mhFont, nCodePoint, rGraphics))
                 return false;
         }
     }
@@ -2409,7 +2409,7 @@ bool UniscribeLayout::CacheGlyphs(SalGraphics& rGraphics) const
         int nCodePoint = mpOutGlyphs[i];
         if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint))
         {
-            if (!mrWinFontEntry.CacheGlyphToAtlas(true, nCodePoint, *this, rGraphics))
+            if (!mrWinFontEntry.CacheGlyphToAtlas(true, mhDC, mhFont, nCodePoint, rGraphics))
                 return false;
         }
     }
@@ -3778,6 +3778,70 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
     return pFontInstance;
 }
 
+bool WinSalGraphics::CacheGlyphs(const CommonSalLayout& rLayout)
+{
+    static bool bDoGlyphCaching = (std::getenv("SAL_DISABLE_GLYPH_CACHING") == nullptr);
+    if (!bDoGlyphCaching)
+        return false;
+
+    HDC hDC = getHDC();
+    HFONT hFONT = rLayout.getHFONT();
+    WinFontInstance& rFont = rLayout.getWinFontInstance();
+
+    int nStart = 0;
+    Point aPos(0, 0);
+    sal_GlyphId nGlyph;
+    while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart))
+    {
+        if (!rFont.GetGlyphCache().IsGlyphCached(nGlyph))
+        {
+            if (!rFont.CacheGlyphToAtlas(true, hDC, hFONT, nGlyph, *this))
+                return false;
+        }
+    }
+
+    return true;
+}
+
+bool WinSalGraphics::DrawCachedGlyphs(const CommonSalLayout& rLayout)
+{
+    HDC hDC = getHDC();
+
+    Rectangle aRect;
+    rLayout.GetBoundRect(*this, aRect);
+
+    COLORREF color = GetTextColor(hDC);
+    SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color));
+
+    WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get());
+    if (!pImpl)
+        return false;
+
+    WinFontInstance& rFont = rLayout.getWinFontInstance();
+
+    int nStart = 0;
+    Point aPos(0, 0);
+    sal_GlyphId nGlyph;
+    while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart))
+    {
+        OpenGLGlyphDrawElement& rElement(rFont.GetGlyphCache().GetDrawElement(nGlyph));
+        OpenGLTexture& rTexture = rElement.maTexture;
+
+        if (!rTexture)
+            return false;
+
+        SalTwoRect a2Rects(0, 0,
+                           rTexture.GetWidth(), rTexture.GetHeight(),
+                           aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs,
+                           aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(),
+                           rTexture.GetWidth(), rTexture.GetHeight());
+
+        pImpl->DeferredTextDraw(rTexture, salColor, a2Rects);
+    }
+
+    return true;
+}
+
 void WinSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout, HDC hDC, bool bUseDWrite)
 {
     Point aPos(0, 0);
@@ -3796,6 +3860,11 @@ void WinSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
         // no OpenGL, just classic rendering
         DrawTextLayout(rLayout, hDC, false);
     }
+    else if (CacheGlyphs(rLayout) &&
+             DrawCachedGlyphs(rLayout))
+    {
+        // Nothing
+    }
     else
     {
         // We have to render the text to a hidden texture, and draw it.


More information about the Libreoffice-commits mailing list