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 13:25:56 +0900 |
| commit | e0a38072cf48a6819a5cd788588267f3441d9d6a (patch) | |
| tree | 5875e89df7d84f3c72f19496961694ab6009e5a1 /src/kernel/tqfontengine_x11.cpp | |
| parent | ccd304b2a6415d8b747d04b3a47736d1e6f45717 (diff) | |
| download | tqt-e0a38072cf48a6819a5cd788588267f3441d9d6a.tar.gz tqt-e0a38072cf48a6819a5cd788588267f3441d9d6a.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>
Diffstat (limited to 'src/kernel/tqfontengine_x11.cpp')
| -rw-r--r-- | src/kernel/tqfontengine_x11.cpp | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/src/kernel/tqfontengine_x11.cpp b/src/kernel/tqfontengine_x11.cpp index f39304c21..b3461a6ff 100644 --- a/src/kernel/tqfontengine_x11.cpp +++ b/src/kernel/tqfontengine_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; } |
