[Libreoffice-commits] core.git: 3 commits - vcl/win vcl/workben

Tor Lillqvist tml at collabora.com
Tue Mar 15 08:22:37 UTC 2016


 vcl/win/gdi/winlayout.cxx |   49 ++++++++++++++++++++++++++++++++++------------
 vcl/workben/vcldemo.cxx   |   20 +++++++++---------
 2 files changed, 47 insertions(+), 22 deletions(-)

New commits:
commit 73443fd278811837650160482c34c15e8830f0d3
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Mar 15 10:18:15 2016 +0200

    tdf#97319: Handle surrogate pairs in glyph caching for SimpleWinLayout
    
    (For UniscribeLayout we use glyph indices.)
    
    Change-Id: Id1907cb766b9285d32e484049bec1b99159c5768

diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 56df894..9aa23ac 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -76,7 +76,7 @@ const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2;
 
 struct OpenGLGlyphCacheChunk
 {
-    WORD mnFirstGlyph;
+    int mnFirstGlyph;           // Must be int to handle non-BMP code points when mbRealGlyphIndices is false
     int mnGlyphCount;
     std::vector<Rectangle> maLocation;
     std::vector<int> maLeftOverhangs;
@@ -383,9 +383,9 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
     aChunk.mnGlyphCount = nCount;
     aChunk.mbRealGlyphIndices = bRealGlyphIndices;
 
-    std::vector<WORD> aGlyphIndices(nCount);
+    std::vector<uint32_t> aCodePointsOrGlyphIndices(nCount);
     for (int i = 0; i < nCount; i++)
-        aGlyphIndices[i] = nGlyphIndex + i;
+        aCodePointsOrGlyphIndices[i] = nGlyphIndex + i;
 
     HDC hDC = CreateCompatibleDC(rLayout.mhDC);
     if (hDC == NULL)
@@ -424,18 +424,21 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
             return false;
         }
     }
+    std::vector<WORD> aGlyphIndices(nCount);
     // Fetch the ink boxes and calculate the size of the atlas.
     if (!bRealGlyphIndices)
     {
-        // FIXME First convert from UTF16 to utf32
-        std::vector<uint32_t> aCodePoints(aGlyphIndices.begin(), aGlyphIndices.end());
-        aGlyphIndices.resize(aCodePoints.size());
-            if (!SUCCEEDED(pTxt->GetFontFace()->GetGlyphIndices(aCodePoints.data(), aCodePoints.size(), aGlyphIndices.data())))
+        if (!SUCCEEDED(pTxt->GetFontFace()->GetGlyphIndices(aCodePointsOrGlyphIndices.data(), aCodePointsOrGlyphIndices.size(), aGlyphIndices.data())))
         {
             pTxt->ReleaseFont();
             return false;
         }
     }
+    else
+    {
+        for (int i = 0; i < nCount; i++)
+            aGlyphIndices[i] = aCodePointsOrGlyphIndices[i];
+    }
     Rectangle bounds(0, 0, 0, 0);
     auto aInkBoxes = pTxt->GetGlyphInkBoxes(aGlyphIndices.data(), aGlyphIndices.data() + nCount);
     for (auto &box : aInkBoxes)
@@ -1491,10 +1494,21 @@ bool SimpleWinLayout::CacheGlyphs(SalGraphics& rGraphics) const
 
     for (int i = 0; i < mnGlyphCount; i++)
     {
-        if (mrWinFontEntry.GlyphIsCached(mpOutGlyphs[i]))
+        int nCodePoint;
+        if (i < mnGlyphCount-1 && rtl::isHighSurrogate(mpOutGlyphs[i]) && rtl::isLowSurrogate(mpOutGlyphs[i+1]))
+        {
+            nCodePoint = rtl::combineSurrogates(mpOutGlyphs[i], mpOutGlyphs[i+1]);
+            i++;
+        }
+        else
+        {
+            nCodePoint = mpOutGlyphs[i];
+        }
+
+        if (mrWinFontEntry.GlyphIsCached(nCodePoint))
             continue;
 
-        if (!mrWinFontEntry.AddChunkOfGlyphs(false, mpOutGlyphs[i], *this, rGraphics))
+        if (!mrWinFontEntry.AddChunkOfGlyphs(false, nCodePoint, *this, rGraphics))
             return false;
     }
 
@@ -1528,10 +1542,21 @@ bool SimpleWinLayout::DrawCachedGlyphs(SalGraphics& rGraphics) const
         if (mpOutGlyphs[i] == DROPPED_OUTGLYPH)
             continue;
 
-        assert(mrWinFontEntry.GlyphIsCached(mpOutGlyphs[i]));
+        int nCodePoint;
+        if (i < mnGlyphCount-1 && rtl::isHighSurrogate(mpOutGlyphs[i]) && rtl::isLowSurrogate(mpOutGlyphs[i+1]))
+        {
+            nCodePoint = rtl::combineSurrogates(mpOutGlyphs[i], mpOutGlyphs[i+1]);
+            i++;
+        }
+        else
+        {
+            nCodePoint = mpOutGlyphs[i];
+        }
+
+        assert(mrWinFontEntry.GlyphIsCached(nCodePoint));
 
-        const OpenGLGlyphCacheChunk& rChunk = mrWinFontEntry.GetCachedGlyphChunkFor(mpOutGlyphs[i]);
-        const int n = mpOutGlyphs[i] - rChunk.mnFirstGlyph;
+        const OpenGLGlyphCacheChunk& rChunk = mrWinFontEntry.GetCachedGlyphChunkFor(nCodePoint);
+        const int n = nCodePoint - rChunk.mnFirstGlyph;
 
         SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(),
                            rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(),
commit e2e3d75364ec7906954383c4fa6c883e416a37cc
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Mar 15 10:03:35 2016 +0200

    s/SEP/SMP
    
    See https://bugs.documentfoundation.org/show_bug.cgi?id=97319#c8 .
    
    Change-Id: I66f5ea5ddd2a98de1d6445f3c6a91f1943dd7ca4

diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index c3cb732..507fdc4 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -533,7 +533,7 @@ public:
                 // - FIXME: replicate justification
                 SET("gentium basic", pJustification),
 
-                // tdf#97319 - Unicode beyond BMP; SEP & Plane 2
+                // tdf#97319 - Unicode beyond BMP; SMP & Plane 2
                 SET("symbola", pEmojis),
                 SET("symbola", pThreeBowlG),
                 SET("symbola", pWavesAndDomino),
commit 1edbb90c9e9296bec33f4c590f3133160b7f9702
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Mar 15 10:02:30 2016 +0200

    We use strlen() on these char arrays so better terminate them with 0
    
    Avoids an assertion failure for me.
    
    Change-Id: I811a3702baf76465acc580bc0e05db8a3c7f5364

diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 4a3ffe5..c3cb732 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -488,28 +488,28 @@ public:
 
         static void drawComplex (OutputDevice &rDev, Rectangle r)
         {
-            const unsigned char pInvalid[] = { 0xfe, 0x1f };
-            const unsigned char pDiacritic1[] = { 0x61, 0xcc, 0x8a, 0xcc, 0x8c };
-            const unsigned char pDiacritic2[] = { 0x61, 0xcc, 0x88, 0xcc, 0x86 };
-            const unsigned char pDiacritic3[] = { 0x61, 0xcc, 0x8b, 0xcc, 0x87 };
+            const unsigned char pInvalid[] = { 0xfe, 0x1f, 0 };
+            const unsigned char pDiacritic1[] = { 0x61, 0xcc, 0x8a, 0xcc, 0x8c, 0 };
+            const unsigned char pDiacritic2[] = { 0x61, 0xcc, 0x88, 0xcc, 0x86, 0 };
+            const unsigned char pDiacritic3[] = { 0x61, 0xcc, 0x8b, 0xcc, 0x87, 0 };
             const unsigned char pJustification[] = {
                 0x64, 0x20, 0xc3, 0xa1, 0xc3, 0xa9, 0x77, 0xc4, 0x8d,
-                0xc5, 0xa1, 0xc3, 0xbd, 0xc5, 0x99, 0x20, 0xc4, 0x9b
+                0xc5, 0xa1, 0xc3, 0xbd, 0xc5, 0x99, 0x20, 0xc4, 0x9b, 0
             };
             const unsigned char pEmojis[] = {
                 0xf0, 0x9f, 0x8d, 0x80, 0xf0, 0x9f, 0x91, 0x98,
                 0xf0, 0x9f, 0x92, 0x8a, 0xf0, 0x9f, 0x92, 0x99,
-                0xf0, 0x9f, 0x92, 0xa4, 0xf0, 0x9f, 0x94, 0x90
+                0xf0, 0x9f, 0x92, 0xa4, 0xf0, 0x9f, 0x94, 0x90, 0
             };
             const unsigned char pThreeBowlG[] = {
-                0xe2, 0x9a, 0x82, 0xe2, 0x99, 0xa8, 0xc4, 0x9e
+                0xe2, 0x9a, 0x82, 0xe2, 0x99, 0xa8, 0xc4, 0x9e, 0
             };
             const unsigned char pWavesAndDomino[] = {
                 0xe2, 0x99, 0x92, 0xf0, 0x9f, 0x81, 0xa0,
-                0xf0, 0x9f, 0x82, 0x93
+                0xf0, 0x9f, 0x82, 0x93, 0
             };
             const unsigned char pSpadesAndBits[] = {
-                0xf0, 0x9f, 0x82, 0xa1, 0xc2, 0xa2, 0xc2, 0xa2
+                0xf0, 0x9f, 0x82, 0xa1, 0xc2, 0xa2, 0xc2, 0xa2, 0
             };
 
             struct {


More information about the Libreoffice-commits mailing list