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-03 05:34:32 -0700
commit4939d0c337e5010ac7d10fa8097e741757cb7e08 (patch)
tree0b8e6b6f2a482ac3f4ba96f83a8aad304c655cec
parent01631edbe40c40c9146f9e165e852edcd96d41af (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;