summaryrefslogtreecommitdiffstats
path: root/src/kernel/tqfontengine_x11.cpp
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2025-01-12 13:09:40 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2025-01-12 13:25:56 +0900
commite0a38072cf48a6819a5cd788588267f3441d9d6a (patch)
tree5875e89df7d84f3c72f19496961694ab6009e5a1 /src/kernel/tqfontengine_x11.cpp
parentccd304b2a6415d8b747d04b3a47736d1e6f45717 (diff)
downloadtqt-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.cpp83
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;
}