[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - vcl/source vcl/win

Akash Jain akash96j at gmail.com
Wed Jul 13 13:00:23 UTC 2016


Rebased ref, commits from common ancestor:
commit d5b568b5ecd998e06519e0d807ab69a1eab0e3d2
Author: Akash Jain <akash96j at gmail.com>
Date:   Wed Jul 6 17:56:15 2016 +0530

    GSoC: Integrate new CommonSalLayout in win/ code
    
    Change-Id: Ifeb2fa7ca9e2cd0da1c504d4e770aa0bb1b0b0de

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 725a254..3d0b38f 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -62,7 +62,12 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
 
     hb_blob_t* pBlob = nullptr;
     if (pBuffer != nullptr)
+#if defined(_WIN32)
+        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
+                               const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
+#else
         pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+#endif
 
     return pBlob;
 }
@@ -79,6 +84,7 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
 #if defined(_WIN32)
 CommonSalLayout::CommonSalLayout(HDC hDC, const WinFontFace& rWinFontFace, WinFontInstance& rWinFontInstance)
 :   mhDC(hDC),
+    mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)),
     mpHBFace(nullptr),
     maFontSelData(rWinFontInstance.maFontSelData)
 {
@@ -86,6 +92,11 @@ CommonSalLayout::CommonSalLayout(HDC hDC, const WinFontFace& rWinFontFace, WinFo
     mpHBFace = hb_face_create_for_tables(getFontTable, &rWinFontFaceWithHDC, nullptr);
 }
 
+void CommonSalLayout::InitFont() const
+{
+    SelectObject( mhDC, mhFont );
+}
+
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(CoreTextStyle* pCoreTextStyle)
 :   mpHBFace(nullptr),
@@ -200,6 +211,7 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const
 {
     //call platform dependent DrawText functions
 #if defined(_WIN32)
+    rSalGraphics.DrawSalLayout( *this );
 #elif defined(MACOSX) || defined(IOS)
 #else
     rSalGraphics.DrawSalLayout( *this, mrServerFont );
@@ -211,6 +223,12 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
     //XXX WinLayout object DOESN'T derive from GSL
     GenericSalLayout& rLayout = *this;
 
+// HACK. TODO: Get rid of HACK
+#if defined(_WIN32)
+    if(maFontSelData.mnWidth)
+        maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812;
+#endif
+
     hb_font_t* pHBFont = hb_font_create(mpHBFace);
     hb_font_set_ppem(pHBFont, maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight , maFontSelData.mnHeight);
     hb_font_set_scale(pHBFont, (uint64_t)(maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight) << 6
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index e740835..845333f 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2606,7 +2606,4 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
     }
 }
 
-void WinSalGraphics::DrawSalLayout( const GenericSalLayout& )
-{}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 4e0c0eb..0db5286 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -34,6 +34,7 @@
 
 #include "sft.hxx"
 #include "sallayout.hxx"
+#include "CommonSalLayout.hxx"
 
 #include <cstdio>
 #include <cstdlib>
@@ -3967,66 +3968,74 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
     const WinFontFace& rFontFace = *mpWinFontData[ nFallbackLevel ];
     WinFontInstance& rFontInstance = *mpWinFontEntry[ nFallbackLevel ];
 
-    bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
-
-    if (!bUspInited)
-        InitUSP();
-
-    if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) )
+    if( getenv("SAL_USE_COMMON_LAYOUT") )
     {
-#if ENABLE_GRAPHITE
-        if (rFontFace.SupportsGraphite())
-        {
-            pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
-        }
-        else
-#endif // ENABLE_GRAPHITE
-        {
-            // script complexity is determined in upper layers
-            pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
-            // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
-            // the created UniscribeLayout, otherwise the data passed into the
-            // constructor might become invalid too early
-        }
+        CommonSalLayout* pCommonSalLayout = new CommonSalLayout( getHDC(), rFontFace, rFontInstance );
+        return pCommonSalLayout;
     }
     else
     {
-#if ENABLE_GRAPHITE
-        if (rFontFace.SupportsGraphite())
-        {
-            pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
-        }
-        else
-#endif // ENABLE_GRAPHITE
-        {
-            static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+        bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
 
-            if (!bAvoidSimpleWinLayout)
-            {
-                if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
-                {
-                    // TODO: directly cache kerning info in the rFontInstance
-                    // TODO: get rid of kerning methods+data in WinSalGraphics object
-                    GetKernPairs();
-                    rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
-                }
+        if (!bUspInited)
+            InitUSP();
 
-                pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+        if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) )
+        {
+#if ENABLE_GRAPHITE
+            if (rFontFace.SupportsGraphite())
+            {
+                pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
             }
             else
+#endif // ENABLE_GRAPHITE
             {
+                // script complexity is determined in upper layers
                 pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
                 // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
                 // the created UniscribeLayout, otherwise the data passed into the
                 // constructor might become invalid too early
             }
         }
-    }
+        else
+        {
+#if ENABLE_GRAPHITE
+            if (rFontFace.SupportsGraphite())
+            {
+                pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+            }
+            else
+#endif // ENABLE_GRAPHITE
+            {
+                static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+
+                if (!bAvoidSimpleWinLayout)
+                {
+                    if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
+                    {
+                        // TODO: directly cache kerning info in the rFontInstance
+                        // TODO: get rid of kerning methods+data in WinSalGraphics object
+                        GetKernPairs();
+                        rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
+                    }
+
+                    pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+                }
+                else
+                {
+                    pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+                    // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
+                    // the created UniscribeLayout, otherwise the data passed into the
+                    // constructor might become invalid too early
+                }
+            }
+        }
 
-    if( mfFontScale[nFallbackLevel] != 1.0 )
-        pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
+        if( mfFontScale[nFallbackLevel] != 1.0 )
+            pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
 
-    return pWinLayout;
+        return pWinLayout;
+    }
 }
 
 int    WinSalGraphics::GetMinKashidaWidth()
@@ -4135,4 +4144,39 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
     return pFontInstance;
 }
 
+void WinSalGraphics::DrawSalLayout( const GenericSalLayout& rLayout )
+{
+    HDC hDC = getHDC();
+
+    Point aStartPos;
+    sal_GlyphId aGlyphId;
+    int nFetchedGlyphs = 0 ;
+
+    UINT oldTa = GetTextAlign( hDC );
+    SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) );
+
+    while( rLayout.GetNextGlyphs( 1, &aGlyphId, aStartPos, nFetchedGlyphs ) )
+    {
+        std::vector<uint16_t> aGlyphIds;
+        std::vector<const int> aGlyphDx;
+        Point aCurPos, aNextPos;
+        int nGlyphCount;
+
+        aGlyphIds.push_back( aGlyphId & GF_IDXMASK );
+        aCurPos = aStartPos;
+        nGlyphCount = 1;
+
+        for( ; nGlyphCount < 8192 && rLayout.GetNextGlyphs( 1, &aGlyphId, aNextPos, nFetchedGlyphs ); nGlyphCount++ )
+        {
+            aGlyphIds.push_back( aGlyphId & GF_IDXMASK );
+            aGlyphDx.push_back( (aNextPos.X() - aCurPos.X()) );
+            aCurPos = aNextPos;
+        }
+
+        ExtTextOutW( hDC, aStartPos.X(), aStartPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( aGlyphIds.data() ),
+                     nGlyphCount, aGlyphDx.data() );
+    }
+    SetTextAlign(hDC, oldTa);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list