diff options
author | Herbert Dürr <hdu@apache.org> | 2014-03-27 16:07:37 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-03-28 11:12:58 +0000 |
commit | 67688d3118b1a361d5dbdaa78e918815c163d75c (patch) | |
tree | 871f8fa43ea62a7946f6a666a088d688ef8715da /vcl | |
parent | f6bcdc5ae6da9cb9b13bdc3551bef917d8b0362d (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
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/win/source/gdi/winlayout.cxx | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index a3aca6d5c4e4..f47456bf286d 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; |