diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-01-12 13:09:40 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-01-12 23:34:08 +0900 |
| commit | b559abe7220b3d86edc427bcbf7db26f9f6f62d6 (patch) | |
| tree | 83c6a8a483f629d23d12d93f210379f5c51281f4 /src/kernel/qfontengine_x11.cpp | |
| parent | 1c9111b3795a3b87254cbac172dcc565c7f76a57 (diff) | |
| download | tqt-b559abe7.tar.gz tqt-b559abe7.zip | |
Add support for Unicode surrogate characters and planes above zero.
If the selected font supports the required characters, the text will be displayed correctly.
If the selected font does not support such characters, empty boxes will be displayed in place of the expected text.
Part of the code changes comes from Qt4 code.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit e0a38072cf48a6819a5cd788588267f3441d9d6a)
Diffstat (limited to 'src/kernel/qfontengine_x11.cpp')
| -rw-r--r-- | src/kernel/qfontengine_x11.cpp | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/src/kernel/qfontengine_x11.cpp b/src/kernel/qfontengine_x11.cpp index 47ddb9367..539b14aed 100644 --- a/src/kernel/qfontengine_x11.cpp +++ b/src/kernel/qfontengine_x11.cpp @@ -488,7 +488,15 @@ TQFontEngine::Error TQFontEngineXLFD::stringToCMap( const TQChar *str, int len, chars[i] = (str[i].unicode() == 0xa0 ? 0x20 : (mirrored ? ::mirroredChar(str[i]).unicode() : str[i].unicode())); } - _codec->fromUnicodeInternal( chars, glyphs, len ); + // XLFD does not support unicode characters above 0xFFFF, so casting to ushort + // does not cause real loss + ushort *us_glyphs = new ushort[len]; + _codec->fromUnicodeInternal( chars, us_glyphs, len ); + for ( int i = 0; i < len; ++i ) { + glyphs[i] = us_glyphs[i]; + } + delete[] us_glyphs; + if (chars != str) free( chars ); } else { @@ -1523,6 +1531,18 @@ static glyph_t getAdobeCharIndex(XftFont *font, int cmap, uint ucs4) return g; } +static uint getChar(const TQChar *str, int &i, const int len) +{ + uint uc = str[i].unicode(); + if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { + uint low = str[++i].unicode(); + if (low >= 0xdc00 && low < 0xe000) { + uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; + } + } + return uc; +} + TQFontEngine::Error TQFontEngineXft::stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const { if ( *nglyphs < len ) { @@ -1530,52 +1550,35 @@ TQFontEngine::Error TQFontEngineXft::stringToCMap( const TQChar *str, int len, g return OutOfMemory; } - if (_cmap != -1) { - for ( int i = 0; i < len; ++i ) { - unsigned short uc = str[i].unicode(); - if (mirrored) - uc = ::mirroredChar(str[i]).unicode(); - glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0; - if ( !glyphs[i] ) { - glyph_t glyph = XftCharIndex(0, _font, uc); - if (!glyph) - glyph = getAdobeCharIndex(_font, _cmap, uc); - glyphs[i] = glyph; - if ( uc < cmapCacheSize ) - ((TQFontEngineXft *)this)->cmapCache[uc] = glyph; + int glyph_pos = 0; + for ( int i = 0; i < len; ++i ) { + uint uc = getChar(str, i, len); + if ( uc == 0xa0 ) + uc = 0x20; + if ( mirrored ) + uc = ::mirroredChar(uc).unicode(); + glyphs[glyph_pos] = uc < cmapCacheSize ? cmapCache[uc] : 0; + if ( !glyphs[glyph_pos] ) { + glyph_t glyph = 0; + if (XftCharExists(0, _font, uc)) { + glyph = XftCharIndex(0, _font, uc); } - } - } else if ( mirrored ) { - for ( int i = 0; i < len; ++i ) { - unsigned short uc = ::mirroredChar(str[i]).unicode(); - glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0; - if ( !glyphs[i] ) { - if (uc == 0xa0) - uc = 0x20; - glyph_t glyph = XftCharIndex(0, _font, uc); - glyphs[i] = glyph; - if ( uc < cmapCacheSize ) - ((TQFontEngineXft *)this)->cmapCache[uc] = glyph; + if ( !glyph && _cmap != -1 ) { + glyph = getAdobeCharIndex(_font, _cmap, uc); } - } - } else { - for ( int i = 0; i < len; ++i ) { - unsigned short uc = str[i].unicode(); - glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0; - if ( !glyphs[i] ) { - if (uc == 0xa0) - uc = 0x20; - glyph_t glyph = XftCharIndex(0, _font, uc); - glyphs[i] = glyph; - if ( uc < cmapCacheSize ) + if ( glyph ) { + glyphs[glyph_pos] = glyph; + if ( uc < cmapCacheSize ) { ((TQFontEngineXft *)this)->cmapCache[uc] = glyph; + } } } + ++glyph_pos; } if ( advances ) { - for ( int i = 0; i < len; i++ ) { - FT_UInt glyph = *(glyphs + i); + for ( int i = 0; i < glyph_pos; i++ ) { + glyph_t glyph = *(glyphs + i); advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0; if ( !advances[i] ) { XGlyphInfo gi; @@ -1591,7 +1594,7 @@ TQFontEngine::Error TQFontEngineXft::stringToCMap( const TQChar *str, int len, g } } - *nglyphs = len; + *nglyphs = glyph_pos; return NoError; } |
