summaryrefslogtreecommitdiffstats
path: root/src/kernel/tqfontengine_x11.cpp
diff options
context:
space:
mode:
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;
}