Changeset 169

Show
Ignore:
Timestamp:
03/31/07 18:22:28 (18 months ago)
Author:
dmik
Message:

Kernel: Added initial DBCS input/output support (thanks to Ko Myung-Hun for patches).

Location:
trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/include/qstring.h

    r8 r169  
    11081108extern Q_EXPORT QCString qt_os2QString2MB( const QString& s, int len=-1 ); 
    11091109extern Q_EXPORT QString qt_os2MB2QString( const char* mb, int len=-1 ); 
     1110extern Q_EXPORT const char *qt_os2UconvFirstByteTable(); 
    11101111#endif 
    11111112 
  • trunk/src/kernel/qapplication_pm.cpp

    r154 r169  
    10151015    // some undocumented system values 
    10161016     
    1017     SV_WORKAREA_YTOP = 51,             
    1018     SV_WORKAREA_YBOTTOM = 52,             
    1019     SV_WORKAREA_XRIGHT = 53,             
     1017    SV_WORKAREA_YTOP = 51, 
     1018    SV_WORKAREA_YBOTTOM = 52, 
     1019    SV_WORKAREA_XRIGHT = 53, 
    10201020    SV_WORKAREA_XLEFT = 54, 
    10211021}; 
     
    12521252#if 0 
    12531253            qDebug( "WM_CHAR:  [%s]", widget->name() ); 
    1254 #endif             
     1254#endif 
    12551255            QWidget *g = QWidget::keyboardGrabber(); 
    12561256            if ( g ) 
     
    12761276            } 
    12771277            break; 
     1278        } 
     1279 
     1280        case WM_QUERYCONVERTPOS : 
     1281        { 
     1282            // Ooops, how to get caret pos ? 
     1283            /// @todo (r=dmik) we should make usage of the QIMEvent 
     1284            //  to query widgets about IME data (see how/where this event 
     1285            //  is used across the sources) 
     1286 
     1287            PRECTL pcp = ( PRECTL )mp1; 
     1288            CURSORINFO ci; 
     1289 
     1290            WinQueryCursorInfo( HWND_DESKTOP, &ci ); 
     1291 
     1292            memset( pcp, 0xFF, sizeof( RECTL )); 
     1293 
     1294            pcp->xLeft = ci.x; 
     1295            pcp->yBottom = ci.y; 
     1296            WinMapWindowPoints( ci.hwnd, hwnd, ( PPOINTL )pcp, 2 ); 
     1297 
     1298            RETURN( QCP_CONVERT ); 
    12781299        } 
    12791300 
     
    17871808                    USHORT w = r.width(); 
    17881809                    USHORT h = r.height(); 
    1789                     // flip y coordinate  
     1810                    // flip y coordinate 
    17901811                    y = QApplication::desktop()->height() - (y + h); 
    17911812                    WinSetWindowUShort( hwnd, QWS_XRESTORE, x ); 
     
    18671888            // WM_MINMAXFRAME, because WM_MINMAXFRAME is a pre-process message 
    18681889            // (i.e. no actual changes have been made) We need actual changes 
    1869             // in order to update the frame strut and send WindowStateChange.  
     1890            // in order to update the frame strut and send WindowStateChange. 
    18701891            result = TRUE; 
    18711892            rc = QtOldFrameProc( hwnd, msg, mp1, mp2 ); 
     
    29542975    ascii = ch; 
    29552976    if ( ascii > 0x7F ) ascii = 0; 
    2956     if ( ch ) 
    2957         text = QString::fromLocal8Bit( (char*)&ch, 1 ); 
     2977    if ( ch ) { 
     2978        // Note: Ignore the KC_CHAR flag when generating text for a key to get 
     2979        // correct (non-null) text even for Alt+Letter combinations (that 
     2980        // don't have KC_CHAR set) because processing Alt+Letter shortcuts 
     2981        // for non-ASCII letters in widgets (e.g. QPushButton) depends on that. 
     2982        if ( !(chm.fs & KC_KEYUP) && (chm.chr & 0xFF) && (chm.chr & 0xFF00) && 
     2983             qt_os2UconvFirstByteTable()[ (chm.chr & 0xFF) ] == 2 ) { 
     2984            // We assime we get a DBCS char if both hi and lo bytes of chr are 
     2985            // non-zero. Note that this check is performed only for key press 
     2986            // events, because key release events (at least for SBCS) often 
     2987            // contain a scancode in the hi byte of chr, which is of course 
     2988            // doesn't mean DBCS. We also perform a DBCS lead byte check to 
     2989            // ensure keys like ESC (that always gives chm=0x011B) are not  
     2990            // mistakenly recognized as DBCS. 
     2991            text = QString::fromLocal8Bit( (char *) &chm.chr, 2 ); 
     2992        } 
     2993        else 
     2994            text = QString::fromLocal8Bit( (char*) &ch, 1 ); 
     2995    } 
    29582996} 
    29592997 
     
    30223060    if ( nrecs == maxrecs ) { 
    30233061#if defined(QT_CHECK_RANGE) 
    3024         qWarning( "Qt: Internal keyboard buffer overflow" ); 
     3062        qWarning( "Qt: Internal keyboard buffer overflow" ); 
    30253063#endif 
    3026         return; 
     3064        return; 
    30273065    } 
    30283066 
     
    30443082 
    30453083    if ( sm_blockUserInput ) // block user interaction during session management 
    3046         return TRUE; 
     3084        return TRUE; 
    30473085 
    30483086    translateKeyCode( chm, code, ascii, state, text ); 
    3049 /// @todo (dmik) currently WM_CHARs chars with zero virtual code or zero 
    3050 //  scancode are totally ignored. -- are they? 
    3051 //    if ( !code || !chm.scancode ) return FALSE; 
     3087 
     3088    // code will be zero for all non-ASCII letters, but I'm not sure when 
     3089    // scancode is oficially allowed to be zero and what it means. Anyway, 
     3090    // ignore key events when both are zero, because it will not make sense 
     3091    // (we will not be able to properly report key releases for such events 
     3092    // since all of them will be indexed by the same zero number in key_rec). 
     3093    if ( !code && !chm.scancode ) return FALSE; 
    30523094 
    30533095    // Invert state logic 
     
    30723114                        // "Alt depressed" event, that must preceed it, will be 
    30733115                        // eaten by the system) 
    3074                         find_key_rec( Qt::Key_Alt, TRUE );  
     3116                        find_key_rec( Qt::Key_Alt, TRUE ); 
    30753117/// @todo (dmik) do the same for other global keys (ALT+TAB, ALT+ESC, CTRL+ESC) 
    30763118//  by handling this situation when we obtain/loose focus) 
     
    30803122//  that find_key_rec() above should also be removed to get identical behavior for 
    30813123//  all stolen keys. This will allow to solve the problem on the Qt application 
    3082 //  level if needed (and even in a platform-independent manner).  
     3124//  level if needed (and even in a platform-independent manner). 
    30833125                    } 
    30843126                    return TRUE; 
     
    31273169    } 
    31283170 
    3129 #if 0     
     3171#if 0 
    31303172    qDebug("WM_CHAR: RESULT = %d", (k0 || k1)); 
    3131 #endif     
     3173#endif 
    31323174    return k0 || k1; 
    31333175} 
  • trunk/src/kernel/qfontengine_pm.cpp

    r60 r169  
    4343#include <qpaintdevice.h> 
    4444#include <qpainter.h> 
    45 //@@TODO (dmik): need? 
    46 //#include <limits.h> 
    47 //#include <math.h> 
    4845 
    4946#include <private/qunicodetables_p.h> 
     
    5249#include <qthreadstorage.h> 
    5350 
    54 //@@TODO (dmik): need? 
     51/// @todo need? 
    5552//#ifndef M_PI 
    5653//#define M_PI 3.14159265358979 
     
    5956// per-thread unique screen ps to perform font operations 
    6057 
    61 //@@TODO (dmik): optimize: use small mem hps'es 1x1 px instead of screen ps? 
     58/// @todo (r=dmik) optimize: use small mem hps'es 1x1 px instead of screen ps? 
    6259class QDisplayPS 
    6360{ 
     
    7067 
    7168 
    72 //@@TODO (dmik): remove? 
    73 //// defined in qtextengine_win.cpp 
    74 //typedef void *SCRIPT_CACHE; 
    75 //typedef HRESULT (WINAPI *fScriptFreeCache)( SCRIPT_CACHE *); 
    76 //extern fScriptFreeCache ScriptFreeCache; 
    77  
    78  
    79 //@@TODO (dmik): remove? 
    80 //static unsigned char *getCMap( HDC hdc, bool & ); 
    81 //static Q_UINT16 getGlyphIndex( unsigned char *table, unsigned short unicode ); 
    82  
    83  
    84 //@@TODO (dmik): remove? 
    85 //HDC   shared_dc           = 0;                // common dc for all fonts 
    86 //static HFONT shared_dc_font = 0;              // used by Windows 95/98 
    87 //static HFONT stock_sysfont  = 0; 
    88 // 
    89 //static inline HFONT systemFont() 
    90 //{ 
    91 //    if ( stock_sysfont == 0 ) 
    92 //      stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); 
    93 //    return stock_sysfont; 
    94 //} 
    95  
    9669// general font engine 
    9770 
     
    10073    hps = 0; 
    10174    delete pfm; 
    102 //@@TODO (dmik): remove... 
    103 //    QT_WA( { 
    104 //      if ( hdc ) {                            // one DC per font (Win NT) 
    105 //          //SelectObject( hdc, systemFont() ); 
    106 //          if ( !stockFont ) 
    107 //              DeleteObject( hfont ); 
    108 //          if ( !paintDevice ) 
    109 //              ReleaseDC( 0, hdc ); 
    110 //          hdc = 0; 
    111 //          hfont = 0; 
    112 //      } 
    113 //    } , { 
    114 //      if ( hfont ) {                          // shared DC (Windows 95/98) 
    115 //          if ( shared_dc_font == hfont ) {    // this is the current font 
    116 //              Q_ASSERT( shared_dc != 0 ); 
    117 //              SelectObject( shared_dc, systemFont() ); 
    118 //              shared_dc_font = 0; 
    119 //          } 
    120 //          if ( !stockFont ) 
    121 //              DeleteObject( hfont ); 
    122 //          hfont = 0; 
    123 //      } 
    124 //    } ); 
    125 //    delete [] cmap; 
    126 // 
    127 //    // for Uniscribe 
    128 //    if ( ScriptFreeCache ) 
    129 //      ScriptFreeCache( &script_cache ); 
    13075} 
    13176 
    13277int QFontEngine::lineThickness() const 
    13378{ 
    134 //@@TODO (dmik): values from FONTMETRICS are not always good (line is too 
     79/// @todo (r=dmik) values from FONTMETRICS are not always good (line is too 
    13580//  thick or too close to glyphs). The algorithm below is not always perfect 
    13681//  either. Which one to leave? 
     
    14994int QFontEngine::underlinePosition() const 
    15095{ 
    151 //@@TODO (dmik): values from FONTMETRICS are not always good (line is too 
     96/// @todo (r=dmik) values from FONTMETRICS are not always good (line is too 
    15297//  thick or too close to glyphs). The algorithm below is not always perfect 
    15398//  either. Which one to leave? 
     
    228173} 
    229174 
    230 //@@TODO (dmik): remove? 
    231 //HDC QFontEngine::dc() const 
    232 //{ 
    233 //    if ( hdc || (qt_winver & Qt::WV_NT_based) ) // either NT_based or Printer 
    234 //      return hdc; 
    235 //    Q_ASSERT( shared_dc != 0 && hfont != 0 ); 
    236 //    if ( shared_dc_font != hfont ) { 
    237 //      SelectObject( shared_dc, hfont ); 
    238 //      shared_dc_font = hfont; 
    239 //    } 
    240 //    return shared_dc; 
    241 //} 
    242  
    243 //@@TODO (dmik): remove? 
    244 //void QFontEngine::getCMap() 
    245 //{ 
    246 //    QT_WA( { 
    247 //      ttf = (bool)(tm.w.tmPitchAndFamily & TMPF_TRUETYPE); 
    248 //    } , { 
    249 //      ttf = (bool)(tm.a.tmPitchAndFamily & TMPF_TRUETYPE); 
    250 //    } ); 
    251 //    HDC hdc = dc(); 
    252 //    SelectObject( hdc, hfont ); 
    253 //    bool symb = false; 
    254 //    cmap = ttf ? ::getCMap( hdc, symb ) : 0; 
    255 //    if ( !cmap ) { 
    256 //      ttf = false; 
    257 //      symb = false; 
    258 //    } 
    259 //    symbol = symb; 
    260 //    script_cache = 0; 
    261 //} 
    262  
    263 //@@TODO (dmik): remove 
    264 //void QFontEngine::getGlyphIndexes( const QChar *ch, int numChars, glyph_t *glyphs, bool mirrored ) const 
    265 //{ 
    266 //    if ( mirrored ) { 
    267 //      if ( symbol ) { 
    268 //          while( numChars-- ) { 
    269 //              *glyphs = getGlyphIndex(cmap, ch->unicode() ); 
    270 //              if(!*glyphs && ch->unicode() < 0x100) 
    271 //                  *glyphs = getGlyphIndex(cmap, ch->unicode()+0xf000 ); 
    272 //              glyphs++; 
    273 //              ch++; 
    274 //          } 
    275 //      } else if ( ttf ) { 
    276 //          while( numChars-- ) { 
    277 //              *glyphs = getGlyphIndex(cmap, ::mirroredChar(*ch).unicode() ); 
    278 //              glyphs++; 
    279 //              ch++; 
    280 //          } 
    281 //      } else { 
    282 //          while( numChars-- ) { 
    283 //              *glyphs = ::mirroredChar(*ch).unicode(); 
    284 //              glyphs++; 
    285 //              ch++; 
    286 //          } 
    287 //      } 
    288 //    } else { 
    289 //      if ( symbol ) { 
    290 //          while( numChars-- ) { 
    291 //              *glyphs = getGlyphIndex(cmap, ch->unicode() ); 
    292 //              if(!*glyphs && ch->unicode() < 0x100) 
    293 //                  *glyphs = getGlyphIndex(cmap, ch->unicode()+0xf000 ); 
    294 //              glyphs++; 
    295 //              ch++; 
    296 //          } 
    297 //      } else if ( ttf ) { 
    298 //          while( numChars-- ) { 
    299 //              *glyphs = getGlyphIndex(cmap, ch->unicode() ); 
    300 //              glyphs++; 
    301 //              ch++; 
    302 //          } 
    303 //      } else { 
    304 //          while( numChars-- ) { 
    305 //              *glyphs = ch->unicode(); 
    306 //              glyphs++; 
    307 //              ch++; 
    308 //          } 
    309 //      } 
    310 //    } 
    311 //} 
    312  
    313175QFontEnginePM::QFontEnginePM( HPS ps, PFATTRS pfa, int pixelSize, int pointSize ) 
    314176{ 
     
    325187    // cache cost here should be in bytes. it is converted to 
    326188    // kbytes by QFontCache::increaseCost() 
    327 //@@TODO (dmik): is this formula for cost ok? 
     189    /// @todo is this formula for cost ok? 
    328190    cache_cost = pfm->lMaxBaselineExt * pfm->lAveCharWidth * 2000; 
    329191 
     
    332194} 
    333195 
    334 //@@TODO (dmik): remove 
    335 //QFontEngineWin::QFontEngineWin( const char * name, HDC _hdc, HFONT _hfont, bool stockFont, LOGFONT lf ) 
    336 //{ 
    337 //    paintDevice = FALSE; 
    338 //    //qDebug("regular windows font engine created: font='%s', size=%d", name, lf.lfHeight); 
    339 // 
    340 //    _name = name; 
    341 // 
    342 //    hdc = _hdc; 
    343 //    hfont = _hfont; 
    344 //    logfont = lf; 
    345 //    SelectObject( dc(), hfont ); 
    346 //    this->stockFont = stockFont; 
    347 // 
    348 //    lbearing = SHRT_MIN; 
    349 //    rbearing = SHRT_MIN; 
    350 // 
    351 //    BOOL res; 
    352 //    QT_WA( { 
    353 //      res = GetTextMetricsW( dc(), &tm.w ); 
    354 //    } , { 
    355 //      res = GetTextMetricsA( dc(), &tm.a ); 
    356 //    } ); 
    357 //#ifndef QT_NO_DEBUG 
    358 //    if ( !res ) 
    359 //      qSystemWarning( "QFontPrivate: GetTextMetrics failed" ); 
    360 //#endif 
    361 //    cache_cost = tm.w.tmHeight * tm.w.tmAveCharWidth * 2000; 
    362 //    getCMap(); 
    363 // 
    364 //    useTextOutA = FALSE; 
    365 //#ifndef Q_OS_TEMP 
    366 //    // TextOutW doesn't work for symbol fonts on Windows 95! 
    367 //    // since we're using glyph indices we don't care for ttfs about this! 
    368 //    if ( qt_winver == Qt::WV_95 && !ttf && 
    369 //       ( _name == "Marlett" || _name == "Symbol" || _name == "Webdings" || _name == "Wingdings" ) ) 
    370 //          useTextOutA = TRUE; 
    371 //#endif 
    372 //    memset( widthCache, 0, sizeof(widthCache) ); 
    373 //} 
    374  
    375 //@@TODO (dmik): current implementation of this fn uses the local8bit QChar 
     196#define isDBCSGlyph(g) ( (g) & 0xFF00 ) 
     197 
     198#define queryGlyphSize(g) ( isDBCSGlyph( g ) ? 2 : 1 ) 
     199 
     200/// @todo (r=dmik) current implementation of this fn uses the local8bit QChar 
    376201//  code as the glyph index, i.e. glyphs are just unicode chars converted to 
    377202//  8 bit chars according to the current (system) code page. This will be 
    378 //  changed when all font-related code will be rewritten to support true unicode 
     203//  changed when all font-related code is rewritten to support true unicode 
    379204//  (for example, by using innotek ft2lib, since native OS/2 unicode support 
    380205//  relative to text output using GPI is pretty buggy). 
    381 QFontEngine::Error QFontEnginePM::stringToCMap( const QChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const 
    382 { 
    383     if ( *nglyphs < len ) { 
    384         *nglyphs = len; 
    385         return OutOfMemory; 
    386     } 
    387  
    388 //@@TODO (dmik): mirrored is currently ignored. 
    389     Q_UNUSED(mirrored); 
    390  
    391     // convert chars to glyphs 
     206QFontEngine::Error QFontEnginePM::stringToCMap( const QChar *str, int len, 
     207                                                glyph_t *glyphs, advance_t *advances, 
     208                                                int *nglyphs, bool mirrored ) const 
     209{ 
     210    /// @todo mirrored is currently ignored. 
     211    Q_UNUSED( mirrored ); 
     212 
     213    const char *uconvFirstByteTable = qt_os2UconvFirstByteTable(); 
     214 
     215    // convert multibyte chars to "wide char" glyphs 
    392216    QCString s = QConstString( str, len ).string().local8Bit(); 
    393     for ( int i = 0; i < len; i++ ) { 
    394         glyphs[i] = (uchar) s[i]; 
     217    // sanity check (uint value must fit into positive int) 
     218    Q_ASSERT( (int) s.size() >= 1 ); 
     219    if ( (int) s.size() < 1 ) { 
     220        *nglyphs = 0; 
     221        return OutOfMemory; 
     222    } 
     223    // we use QCString::size() instead of length() because the str array may 
     224    // contain embedded zero chars that must be also processed 
     225    int slen = (int) s.size() - 1; // exclude terminating zero 
     226    if ( slen == 0 ) { 
     227        // null string or no valid conversion, nothing to do 
     228        *nglyphs = 0; 
     229        return NoError; 
     230    } 
     231    int givenLen = *nglyphs; 
     232    int realLen = 0; 
     233    for( int i = 0; i < slen; i++ ) { 
     234        bool isDBCSLeadByte = uconvFirstByteTable[ s[ i ] ] == 2; 
     235        if ( realLen < givenLen ) { 
     236            // enough space, store the glyph 
     237            glyphs[ realLen ] = s[ i ] & 0xFF; 
     238            if( isDBCSLeadByte ) 
     239                glyphs[ realLen ] |= ( s[ ++i ] << 8 ) & 0xFF00; 
     240        } else { 
     241            // not enough space, keep calulating the length 
     242            if( isDBCSLeadByte ) 
     243                ++i; 
     244        } 
     245        realLen++; 
     246    } 
     247 
     248    if ( givenLen < realLen ) { 
     249        *nglyphs = realLen; 
     250        return OutOfMemory; 
    395251    } 
    396252 
    397253    if ( advances ) { 
    398         HPS ps = 0; 
    399         glyph_t glyph; 
    400         for( register int i = 0; i < len; i++ ) { 
    401             glyph = *(glyphs + i); 
    402             advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0; 
    403             // font-width cache failed 
    404             if ( !advances[i] ) { 
     254        HPS ps = 0; 
     255        glyph_t glyph; 
     256        for( register int i = 0; i < realLen; i++ ) { 
     257            glyph = *(glyphs + i); 
     258            advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0; 
     259            // font-width cache failed 
     260            if ( !advances[i] ) { 
    405261                if ( !ps ) ps = this->ps(); 
    406262                POINTL ptls [TXTBOX_COUNT]; 
    407                 GpiQueryTextBox( ps, 1, &s[i], TXTBOX_COUNT, ptls); 
     263                GpiQueryTextBox( ps, queryGlyphSize( glyph ), 
     264                                 (PCH) &glyph, TXTBOX_COUNT, ptls ); 
    408265                advances[i] = ptls[4].x; 
    409                 // if glyph's within cache range, store it for later 
    410                 if ( glyph < widthCacheSize && advances[i] < 0x100 ) 
    411                     ((QFontEnginePM *)this)->widthCache[glyph] = advances[i]; 
    412             } 
    413         } 
    414     } 
    415  
    416     *nglyphs = len; 
     266                // if glyph's within cache range, store it for later 
     267                if ( glyph < widthCacheSize && advances[i] < 0x100 ) 
     268                    ((QFontEnginePM *)this)->widthCache[glyph] = advances[i]; 
     269            } 
     270        } 
     271    } 
     272 
     273    *nglyphs = realLen; 
    417274    return NoError; 
    418  
    419 //@@TODO (dmik): remove 
    420 //    if ( *nglyphs < len ) { 
    421 //      *nglyphs = len; 
    422 //      return OutOfMemory; 
    423 //    } 
    424 // 
    425 //    getGlyphIndexes( str, len, glyphs, mirrored ); 
    426 // 
    427 //    if ( advances ) { 
    428 //      HDC hdc = dc(); 
    429 //      unsigned int glyph; 
    430 //      int overhang = (qt_winver & Qt::WV_DOS_based) ? tm.a.tmOverhang : 0; 
    431 //      for( register int i = 0; i < len; i++ ) { 
    432 //          glyph = *(glyphs + i); 
    433 //          advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0; 
    434 //          // font-width cache failed 
    435 //          if ( !advances[i] ) { 
    436 //              SIZE size; 
    437 //              GetTextExtentPoint32W( hdc, (wchar_t *)str, 1, &size ); 
    438 //              advances[i] = size.cx - overhang; 
    439 //              // if glyph's within cache range, store it for later 
    440 //              if ( glyph < widthCacheSize && (size.cx - overhang) < 0x100 ) 
    441 //                  ((QFontEngineWin *)this)->widthCache[glyph] = size.cx - overhang; 
    442 //          } 
    443 //          str++; 
    444 //      } 
    445 //    } 
    446 // 
    447 //    *nglyphs = len; 
    448 //    return NoError; 
    449275} 
    450276 
     
    456282extern const LONG qt_ropCodes_2ROP[]; 
    457283 
    458 void QFontEnginePM::draw( QPainter *p, int x, int y, const QTextEngine *engine, const QScriptItem *si, int textFlags ) 
     284void QFontEnginePM::draw( QPainter *p, int x, int y, const QTextEngine 
     285                          *engine, const QScriptItem *si, int textFlags ) 
    459286{ 
    460287    HPS ps = p->handle(); 
     
    463290    advance_t *advances = engine->advances( si ); 
    464291    qoffset_t *offsets = engine->offsets( si ); 
    465  
    466     /// @todo (dmik) 
    467     //      glyphs here are just 8 bit chars (see stringToCMap()), 
    468     //      and glyph_t is temporarly defined as unsigned char. 
    469     //      it should be changed later. 
    470     PSZ cglyphs = (PSZ) glyphs; 
    471     /* 
    472     QConstString str( (QChar *)glyphs, si->num_glyphs ); 
    473     QCString cglyphs = str.string().latin1(); 
    474     */ 
    475292 
    476293    // GPI version of the opaque rectangle below the text is rather strange, 
     
    480297        GpiSetMix( ps, FM_LEAVEALONE ); 
    481298        // use drawRect to have the rectangle properly transformed 
    482         /// @todo (dmik) 
     299        /// @todo (r=dmik) 
    483300        //      we don't add 1 to si->ascent + si->descent to exactly match 
    484301        //      QFontMetrics::boundingRect(). This stuff needs to be reviewed 
     
    563380 
    564381    if ( p->txop == QPainter::TxTranslate ) { 
    565         p->map( x, y, &x, &y ); 
     382        p->map( x, y, &x, &y ); 
    566383    } else if ( p->txop > QPainter::TxTranslate ) { 
    567384        y = -y; 
    568385        ySign = -1; 
    569386        nativexform = p->setNativeXForm( TRUE /* assumeYNegation */ ); 
    570         if( !nativexform ) 
    571             return; 
     387        if( !nativexform ) 
     388            return; 
    572389    } 
    573390 
     
    598415        if ( haveOffsets ) { 
    599416            for( int i = 0; i < si->num_glyphs; i++ ) { 
    600                 char chr = *glyphs; 
    601417                ptl.x = x + offsets->x; 
    602418                ptl.y = y + ySign * offsets->y; 
     
    604420                if ( !nativexform && p->devh ) 
    605421                    ptl.y = p->devh - (ptl.y + 1); 
    606                 GpiCharStringPosAt( ps, &ptl, NULL, options, 1, &chr, NULL ); 
     422                GpiCharStringPosAt( ps, &ptl, NULL, options, 
     423                                    queryGlyphSize( *glyphs ), (PCH) glyphs, NULL ); 
    607424                x += *advances; 
    608425                glyphs++; 
     
    617434            if ( !nativexform && p->devh ) 
    618435                ptl.y = p->devh - (ptl.y + 1); 
     436            GpiMove( ps, &ptl ); 
    619437            // draw glyphs in 512 char chunks: it's a GpiCharString* limitation 
    620             GpiMove( ps, &ptl ); 
    621             for ( int i = 0; i < si->num_glyphs; i += 512 ) {   
    622                 GpiCharStringPos( ps, NULL, options | CHS_VECTOR, 
    623                     QMIN( si->num_glyphs - i, 512 ),  cglyphs, (PLONG) advances ); 
    624                 cglyphs += 512; 
    625                 advances += 512; 
     438            advance_t adv[ 512 ]; 
     439            char str[ 512 ]; 
     440            int len = 0; 
     441            // convert "wide char" glyphs to a multi byte string 
     442            glyph_t *pg = glyphs; 
     443            advance_t *pa = advances; 
     444            for( int i = 0; i < si->num_glyphs; i++, pg++, pa++ ) { 
     445                str[ len ] = *pg & 0xFF; 
     446                adv[ len++ ] = *pa; 
     447 
     448                if( isDBCSGlyph( *pg ) ) { 
     449                    str[ len ] = ( *pg & 0xFF00 ) >> 8; 
     450                    adv[ len++ ] = 0; 
     451                } 
     452 
     453                if( len > 510 ) { 
     454                    GpiCharStringPos( ps, NULL, options | CHS_VECTOR, len, str, (PLONG) adv ); 
     455                    len = 0; 
     456                } 
    626457            } 
     458 
     459            if( len > 0 ) 
     460                GpiCharStringPos( ps, NULL, options | CHS_VECTOR, len, str, (PLONG) adv ); 
     461 
    627462            x += w; 
    628463        } 
    629464    } else { 
    630         offsets += si->num_glyphs; 
    631         advances += si->num_glyphs; 
    632         glyphs += si->num_glyphs; 
    633         for( int i = 0; i < si->num_glyphs; i++ ) { 
    634             glyphs--; 
    635             offsets--; 
    636             advances--; 
    637             char chr = *glyphs; 
    638             ptl.x = x + offsets->x; 
    639             ptl.y = y + ySign * offsets->y; 
     465        offsets += si->num_glyphs; 
     466        advances += si->num_glyphs; 
     467        glyphs += si->num_glyphs; 
     468        for( int i = 0; i < si->num_glyphs; i++ ) { 
     469            glyphs--; 
     470            offsets--; 
     471            advances--; 
     472            ptl.x = x + offsets->x; 
     473            ptl.y = y + ySign * offsets->y;