vcl/win/source/gdi/winlayout.cxx |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

New commits:
commit c4b1a736c2c5378f5f7c62e1e350377bcef8832b
Author: Herbert Dürr <h...@apache.org>
Date:   Thu Mar 27 16:07:37 2014 +0000

    Related: #i124516# handle bad surrogate pairs gracefully on Windows
    
    When running into invalid Unicode surrogate pairs the text layout code on
    Windows ran into massive problems like crashes. This change detects the
    situation of an invalid surrogate pair and falls back to treat it as
    a simple character instead of requesting a complex glyph fallback.
    
    (cherry picked from commit 913f1fc4b1362f6e91595af5ae10c4cba79fd355)
    
    Change-Id: I2988f4b64061d0a5df211f6f0f04b1f235fcd6a5
    (cherry picked from commit 67688d3118b1a361d5dbdaa78e918815c163d75c)

diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 3113b0a..6fdc5ba 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -386,12 +386,19 @@ bool SimpleWinLayout::LayoutText( ImplLayoutArgs& rArgs )
         bool bSurrogate = ((nCharCode >= 0xD800) && (nCharCode <= 0xDFFF));
         if( bSurrogate )
         {
-            if( nCharCode >= 0xDC00 ) // this part of a surrogate pair was 
already processed
+            // ignore high surrogates, they were already processed with their 
low surrogates
+            if( nCharCode >= 0xDC00 )
                 continue;
-            nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + (pCodes[1] - 
0xDC00);
-    }
+            // check the second half of the surrogate pair
+            bSurrogate &= (0xDC00 <= pCodes[1]) && (pCodes[1] <= 0xDFFF);
+            // calculate the UTF-32 code of valid surrogate pairs
+            if( bSurrogate )
+                nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + 
(pCodes[1] - 0xDC00);
+            else // or fall back to a replacement character
+                nCharCode = '?';
+        }
 
-        // get the advance width for the current UCS-4 code point
+        // get the advance width for the current UTF-32 code point
         int nGlyphWidth = mrWinFontEntry.GetCachedGlyphWidth( nCharCode );
         if( nGlyphWidth == -1 )
         {
@@ -409,7 +416,7 @@ bool SimpleWinLayout::LayoutText( ImplLayoutArgs& rArgs )
         mpGlyphAdvances[ i ] = nGlyphWidth;
         mnWidth += nGlyphWidth;
 
-        // remaining codes of surrogate pair get a zero width
+        // the second half of surrogate pair gets a zero width
         if( bSurrogate && ((i+1) < mnGlyphCount) )
             mpGlyphAdvances[ i+1 ] = 0;
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to