summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Dürr <hdu@apache.org>2014-03-27 16:07:37 +0000
committerAndras Timar <andras.timar@collabora.com>2014-04-02 15:29:23 +0200
commit9c340d46b457cb54700cd2e8ccaab7001ee42b27 (patch)
tree08b5563de43bb44ec5eaffa9d2ab66f5368810a9
parent6ea4789e99c92994d083b13fd8efee8c35987561 (diff)
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)
-rw-r--r--vcl/win/source/gdi/winlayout.cxx17
1 files changed, 12 insertions, 5 deletions
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 5a5538745035..e7bdc111a8cc 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -385,12 +385,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 )
{
@@ -408,7 +415,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;