[Kde-cygwin-cvs] CVS: qt-3/src/kernel qeventloop.cpp,1.1.1.7,1.2 qeventloop.h,1.1.1.8,1.2 qeventloop
Status: Inactive
Brought to you by:
habacker
Update of /cvsroot/kde-cygwin/qt-3/src/kernel In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26950/src/kernel Modified Files: qeventloop.cpp qeventloop.h qeventloop_p.h qeventloop_unix.cpp qeventloop_x11.cpp qfontengine_p.h qfontengine_x11.cpp qgplugin.cpp qgplugin.h qimageformatinterface_p.h qimageformatplugin.h qinputcontext_p.h qlock.cpp qlock_p.h qobjectcleanuphandler.h qprinter_p.h qscriptengine.cpp qscriptengine_p.h qscriptengine_x11.cpp qsharedmemory_p.cpp qsharedmemory_p.h qt_kernel.pri qt_x11_p.h qtextengine.cpp qtextengine_p.h qtextengine_unix.cpp qtextlayout.cpp qtextlayout_p.h qthread.cpp qvfbhdr.h Log Message: st qt3.3.5 patch - I made the smae mistake like 3.3.4 but don't know what is going wrong there. Seems like our cvs is messed up :( ttt: ---------------------------------------------------------------------- Index: qeventloop.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qeventloop.cpp,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qeventloop.cpp 22 Sep 2005 12:55:17 -0000 1.1.1.7 +++ qeventloop.cpp 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Implementation of QEventLoop class ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qeventloop.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qeventloop.h,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qeventloop.h 22 Sep 2005 12:55:13 -0000 1.1.1.8 +++ qeventloop.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Declaration of QEventLoop class ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qeventloop_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qeventloop_p.h,v retrieving revision 1.1.1.12 retrieving revision 1.2 diff -u -r1.1.1.12 -r1.2 --- qeventloop_p.h 22 Sep 2005 12:55:17 -0000 1.1.1.12 +++ qeventloop_p.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of QEventLoop class ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** @@ -85,7 +85,7 @@ }; #endif // Q_OS_UNIX -#if defined(Q_WS_WIN) +#if defined(Q_WS_WIN) && !defined(Q_CYGWIN_WIN) struct QSockNot { QSocketNotifier *obj; int fd; @@ -134,7 +134,7 @@ QSockNotType sn_vec[3]; #endif -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) && !defined(Q_CYGWIN_WIN) // pending socket notifiers list QPtrList<QSockNot> sn_pending_list; #endif // Q_WS_WIN Index: qeventloop_unix.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qeventloop_unix.cpp,v retrieving revision 1.1.1.12 retrieving revision 1.2 diff -u -r1.1.1.12 -r1.2 --- qeventloop_unix.cpp 22 Sep 2005 12:55:17 -0000 1.1.1.12 +++ qeventloop_unix.cpp 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Implementation of QEventLoop class ** -** Copyright (C) 2000-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qeventloop_x11.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qeventloop_x11.cpp,v retrieving revision 1.1.1.12 retrieving revision 1.2 diff -u -r1.1.1.12 -r1.2 --- qeventloop_x11.cpp 22 Sep 2005 12:55:12 -0000 1.1.1.12 +++ qeventloop_x11.cpp 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Implementation of QEventLoop class ** -** Copyright (C) 2000-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2004 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** @@ -316,7 +316,7 @@ FD_ZERO(&fdset); FD_SET(sn->fd, &fdset); - int ret = -1; + int ret; do { switch (type) { case 0: // read Index: qfontengine_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qfontengine_p.h,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qfontengine_p.h 22 Sep 2005 12:55:09 -0000 1.1.1.8 +++ qfontengine_p.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ??? ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qfontengine_x11.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qfontengine_x11.cpp,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qfontengine_x11.cpp 22 Sep 2005 12:55:32 -0000 1.1.1.8 +++ qfontengine_x11.cpp 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ??? ** -** Copyright (C) 2003-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2003-2004 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** @@ -37,16 +37,13 @@ // #define FONTENGINE_DEBUG -#include <qwidget.h> #include <qcstring.h> #include <qtextcodec.h> #include "qbitmap.h" #include "qfontdatabase.h" #include "qpaintdevice.h" -#include "qpaintdevicemetrics.h" #include "qpainter.h" -#include "qimage.h" #include "qt_x11_p.h" @@ -82,115 +79,6 @@ } } - -inline static void qSafeXDestroyImage( XImage *x ) -{ - if ( x->data ) { - free( x->data ); - x->data = 0; - } - XDestroyImage( x ); -} - -extern bool qt_xForm_helper( const QWMatrix &trueMat, int xoffset, - int type, int depth, - uchar *dptr, int dbpl, int p_inc, int dHeight, - uchar *sptr, int sbpl, int sWidth, int sHeight - ); - -static QBitmap transform(Display *dpy, const QBitmap &source, int xoff, int yoff, int w, int h, const QWMatrix &matrix) -{ - int ws = source.width(); - int hs = source.height(); - - bool invertible; - QWMatrix mat = matrix.invert( &invertible ); // invert matrix - - if (!invertible ) - return QBitmap(); - mat.translate(xoff, yoff); - - XImage *xi = XGetImage(dpy, source.handle(), 0, 0, ws, hs, AllPlanes, XYPixmap); - - if ( !xi ) - return QBitmap(); - - int sbpl = xi->bytes_per_line; - uchar *sptr = (uchar *)xi->data; - - int dbpl = (w+7)/8; - int dbytes = dbpl*h; - - uchar *dptr = (uchar *)malloc( dbytes ); // create buffer for bits - memset( dptr, 0, dbytes ); - - int type = xi->bitmap_bit_order == MSBFirst ? QT_XFORM_TYPE_MSBFIRST : QT_XFORM_TYPE_LSBFIRST; - int xbpl, p_inc; - xbpl = (w+7)/8; - p_inc = dbpl - xbpl; - - bool ok = qt_xForm_helper( mat, xi->xoffset, type, 1, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs ); - qSafeXDestroyImage(xi); - QBitmap bm; - if (ok) { - bm = QBitmap( w, h, dptr, QImage::systemBitOrder() != QImage::BigEndian ); - } else { -#if defined(QT_CHECK_RANGE) - qWarning( "QFontEngineXft::tranform: xform failed"); -#endif - } - - free( dptr ); - return bm; -} - - -static void drawScaled(int x, int y, const QTextEngine *engine, const QScriptItem *si, int textFlags, - Display *dpy, GC gc, QPaintDevice *pdev, QFontEngine *fe, const QWMatrix &xmat) -{ - // font doesn't support transformations, need to do it by hand - int w = si->width, h = si->ascent + si->descent + 1; - if ( w == 0 || h == 0 ) - return; - - w += h; // add some pixels to width because of italic correction - QBitmap bm( w, h, TRUE ); // create bitmap - QPainter paint; - paint.begin( &bm ); // draw text in bitmap - fe->draw( &paint, 0, si->ascent, engine, si, textFlags ); - paint.end(); - - QRect pdevRect; - if (pdev->devType() == QInternal::Widget) - pdevRect = ((QWidget *)pdev)->rect(); - else if (pdev->devType() == QInternal::Pixmap) - pdevRect = ((QPixmap *)pdev)->rect(); - else - return; - - - QRect br = xmat.mapRect(QRect(x, y - si->ascent, w, h)); - QRect br2 = br & pdevRect; - if (br2.width() <= 0 || br2.height() <= 0) - return; - QWMatrix mat = QPixmap::trueMatrix( xmat, w, h ); - QBitmap wx_bm = ::transform(dpy, bm, br2.x() - br.x(), br2.y() - br.y(), br2.width(), br2.height(), mat); - if ( wx_bm.isNull() ) - return; - - x = br2.x(); - y = br2.y(); - - Qt::HANDLE hd = pdev->handle(); - XSetFillStyle( dpy, gc, FillStippled ); - XSetStipple( dpy, gc, wx_bm.handle() ); - XSetTSOrigin( dpy, gc, x, y ); - XFillRectangle( dpy, hd, gc, x, y, wx_bm.width(), wx_bm.height() ); - XSetTSOrigin( dpy, gc, 0, 0 ); - XSetFillStyle( dpy, gc, FillSolid ); -} - - QFontEngine::~QFontEngine() { } @@ -645,8 +533,38 @@ } if ( degenerate || xlfd_transformations == XlfdTrUnsupported ) { // XServer or font don't support server side transformations, need to do it by hand - drawScaled(x, y, engine, si, textFlags, dpy, p->gc, p->device(), this, p->xmat); - return; + int w = qRound(si->width/_scale), h = qRound((si->ascent + si->descent + 1)/_scale); + QWMatrix mat1 = p->xmat; + mat1.scale(_scale, _scale); + if (w == 0 || h == 0) + return; + float tmp = _scale; + _scale = 1; + QWMatrix mat2 = QPixmap::trueMatrix(mat1, w, h); + QBitmap bm(w, h, TRUE); // create bitmap + QPainter paint; + paint.begin( &bm ); // draw text in bitmap + draw( &paint, 0, qRound(si->ascent/tmp), engine, si, textFlags ); + paint.end(); + _scale = tmp; + QBitmap wx_bm( bm.xForm(mat2) ); // transform bitmap + if ( wx_bm.isNull() ) + return; + + double fx=x, fy=y - si->ascent, nfx, nfy; + p->xmat.map( fx,fy, &nfx,&nfy ); + double tfx=0, tfy=0, dx, dy; + mat2.map( tfx, tfy, &dx, &dy ); // compute position of bitmap + x = qRound(nfx-dx); + y = qRound(nfy-dy); + + XSetFillStyle( dpy, gc, FillStippled ); + XSetStipple( dpy, gc, wx_bm.handle() ); + XSetTSOrigin( dpy, gc, x, y ); + XFillRectangle( dpy, hd, gc, x, y, wx_bm.width(), wx_bm.height() ); + XSetTSOrigin( dpy, gc, 0, 0 ); + XSetFillStyle( dpy, gc, FillSolid ); + return; } transform = TRUE; } else if ( p->txop == QPainter::TxTranslate ) { @@ -1059,7 +977,7 @@ // merge member data with the above for ( i = 0; i < 0x200; ++i ) { if ( glyphIndices[i] != 0 || glyphs[i] == 0 ) continue; - glyphIndices[i] = glyphs[i] >= 0x2100 ? glyphs[i] : hi | glyphs[i]; + glyphIndices[i] = hi | glyphs[i]; glyphAdvances[i] = advances[i]; } if (!euroIndex && glyphs[0x200]) { @@ -1158,6 +1076,7 @@ } } + *nglyphs = len; return NoError; } @@ -1170,22 +1089,16 @@ glyph_t *glyphs = engine->glyphs( si ); advance_t *advances = engine->advances( si ); int which = glyphs[0] >> 8; - if (which > 0x20) - which = 0; int start = 0; int end, i; for ( end = 0; end < si->num_glyphs; ++end ) { - int e = glyphs[end] >> 8; - if (e > 0x20) - e = 0; + const int e = glyphs[end] >> 8; if ( e == which ) continue; // set the high byte to zero - if (which != 0) { - for ( i = start; i < end; ++i ) - glyphs[i] = glyphs[i] & 0xff; - } + for ( i = start; i < end; ++i ) + glyphs[i] = glyphs[i] & 0xff; // draw the text QScriptItem si2 = *si; @@ -1194,11 +1107,11 @@ _engines[which]->draw( p, x, y, engine, &si2, textFlags ); // reset the high byte for all glyphs and advance to the next sub-string - const int hi = which << 8; - for ( i = start; i < end; ++i ) { - glyphs[i] = hi | glyphs[i]; - x += advances[i]; - } + const int hi = which << 8; + for ( i = start; i < end; ++i ) { + glyphs[i] = hi | glyphs[i]; + x += advances[i]; + } // change engine start = end; @@ -1206,10 +1119,9 @@ } // set the high byte to zero - if (which != 0) { - for ( i = start; i < end; ++i ) - glyphs[i] = glyphs[i] & 0xff; - } + for ( i = start; i < end; ++i ) + glyphs[i] = glyphs[i] & 0xff; + // draw the text QScriptItem si2 = *si; si2.glyph_data_offset = si->glyph_data_offset + start; @@ -1217,11 +1129,9 @@ _engines[which]->draw( p, x, y, engine, &si2, textFlags ); // reset the high byte for all glyphs - if (which != 0) { - const int hi = which << 8; - for ( i = start; i < end; ++i ) - glyphs[i] = hi | glyphs[i]; - } + const int hi = which << 8; + for ( i = start; i < end; ++i ) + glyphs[i] = hi | glyphs[i]; } glyph_metrics_t QFontEngineLatinXLFD::boundingBox( const glyph_t *glyphs_const, @@ -1235,22 +1145,16 @@ glyph_t *glyphs = (glyph_t *) glyphs_const; int which = glyphs[0] >> 8; - if (which > 0x20) - which = 0; int start = 0; int end, i; for ( end = 0; end < numGlyphs; ++end ) { - int e = glyphs[end] >> 8; - if (e > 0x20) - e = 0; + const int e = glyphs[end] >> 8; if ( e == which ) continue; // set the high byte to zero - if (which != 0) { - for ( i = start; i < end; ++i ) - glyphs[i] = glyphs[i] & 0xff; - } + for ( i = start; i < end; ++i ) + glyphs[i] = glyphs[i] & 0xff; // merge the bounding box for this run const glyph_metrics_t gm = @@ -1268,11 +1172,9 @@ overall.yoff += gm.yoff; // reset the high byte for all glyphs - if (which != 0) { - const int hi = which << 8; - for ( i = start; i < end; ++i ) - glyphs[i] = hi | glyphs[i]; - } + const int hi = which << 8; + for ( i = start; i < end; ++i ) + glyphs[i] = hi | glyphs[i]; // change engine start = end; @@ -1280,10 +1182,8 @@ } // set the high byte to zero - if (which != 0) { - for ( i = start; i < end; ++i ) - glyphs[i] = glyphs[i] & 0xff; - } + for ( i = start; i < end; ++i ) + glyphs[i] = glyphs[i] & 0xff; // merge the bounding box for this run const glyph_metrics_t gm = @@ -1301,22 +1201,18 @@ overall.yoff += gm.yoff; // reset the high byte for all glyphs - if (which != 0) { - const int hi = which << 8; - for ( i = start; i < end; ++i ) - glyphs[i] = hi | glyphs[i]; - } + const int hi = which << 8; + for ( i = start; i < end; ++i ) + glyphs[i] = hi | glyphs[i]; return overall; } glyph_metrics_t QFontEngineLatinXLFD::boundingBox( glyph_t glyph ) { - int engine = glyph >> 8; - if (engine > 0x20) - engine = 0; + const int engine = glyph >> 8; Q_ASSERT( engine < _count ); - return _engines[engine]->boundingBox( engine > 0 ? glyph & 0xff : glyph ); + return _engines[engine]->boundingBox( glyph & 0xff ); } int QFontEngineLatinXLFD::ascent() const @@ -1722,6 +1618,7 @@ #endif // QT_XFT2 } + //#define FONTENGINE_DEBUG void QFontEngineXft::draw( QPainter *p, int x, int y, const QTextEngine *engine, const QScriptItem *si, int textFlags ) { @@ -1736,13 +1633,47 @@ XftFont *fnt = _font; bool transform = FALSE; if ( p->txop >= QPainter::TxScale || p->rop != Qt::CopyROP) { - bool can_scale = (_face->face_flags & FT_FACE_FLAG_SCALABLE) && p->rop == Qt::CopyROP; - double size = (p->m11()*p->m22() - p->m12()*p->m21())*_scale*_scale*fontDef.pixelSize*fontDef.pixelSize; - if (size > 256*256) - can_scale = FALSE; - if (!can_scale) { + if (!(_face->face_flags & FT_FACE_FLAG_SCALABLE) || p->rop != Qt::CopyROP) { + Qt::HANDLE hd = p->device()->handle(); + GC gc = p->gc; + // font doesn't support transformations, need to do it by hand - drawScaled(x, y, engine, si, textFlags, dpy, p->gc, p->device(), this, p->xmat); + QRect bbox( 0, 0, si->width, si->ascent + si->descent + 1 ); + int w=bbox.width(), h=bbox.height(); + int aw = w, ah = h; + int tx=-bbox.x(), ty=-bbox.y(); // text position + QWMatrix mat1 = p->xmat; + if ( aw == 0 || ah == 0 ) + return; + double rx = (double)w / (double)aw; + double ry = (double)h / (double)ah; + QWMatrix mat2 = QPixmap::trueMatrix( QWMatrix( rx, 0, 0, ry, 0, 0 )*mat1, aw, ah ); + QBitmap *wx_bm; + { // no such cached bitmap + QBitmap bm( aw, ah, TRUE ); // create bitmap + QPainter paint; + paint.begin( &bm ); // draw text in bitmap + draw( &paint, 0, si->ascent, engine, si, textFlags ); + paint.end(); + wx_bm = new QBitmap( bm.xForm(mat2) ); // transform bitmap + if ( wx_bm->isNull() ) { + delete wx_bm; // nothing to draw + return; + } + } + double fx=x, fy=y - si->ascent, nfx, nfy; + mat1.map( fx,fy, &nfx,&nfy ); + double tfx=tx, tfy=ty, dx, dy; + mat2.map( tfx, tfy, &dx, &dy ); // compute position of bitmap + x = qRound(nfx-dx); + y = qRound(nfy-dy); + XSetFillStyle( dpy, gc, FillStippled ); + XSetStipple( dpy, gc, wx_bm->handle() ); + XSetTSOrigin( dpy, gc, x, y ); + XFillRectangle( dpy, hd, gc, x, y, wx_bm->width(), wx_bm->height() ); + XSetTSOrigin( dpy, gc, 0, 0 ); + XSetFillStyle( dpy, gc, FillSolid ); + delete wx_bm; return; } Index: qgplugin.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qgplugin.cpp,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qgplugin.cpp 22 Sep 2005 12:55:25 -0000 1.1.1.7 +++ qgplugin.cpp 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ... ** -** Copyright (C) 2001-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2001-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qgplugin.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qgplugin.h,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qgplugin.h 22 Sep 2005 12:55:35 -0000 1.1.1.7 +++ qgplugin.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ... ** -** Copyright (C) 2001-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2001-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qimageformatinterface_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qimageformatinterface_p.h,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qimageformatinterface_p.h 22 Sep 2005 12:55:33 -0000 1.1.1.7 +++ qimageformatinterface_p.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ... ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qimageformatplugin.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qimageformatplugin.h,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qimageformatplugin.h 22 Sep 2005 12:54:59 -0000 1.1.1.7 +++ qimageformatplugin.h 23 Sep 2005 09:40:29 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of ??? ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qinputcontext_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qinputcontext_p.h,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qinputcontext_p.h 22 Sep 2005 12:55:18 -0000 1.1.1.8 +++ qinputcontext_p.h 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of ??? ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qlock.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qlock.cpp,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qlock.cpp 22 Sep 2005 12:55:30 -0000 1.1.1.7 +++ qlock.cpp 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,11 +1,11 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of QLock class. This manages interprocess locking ** ** Created : 20000406 ** -** Copyright (C) 2000-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qlock_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qlock_p.h,v retrieving revision 1.1.1.7 retrieving revision 1.2 diff -u -r1.1.1.7 -r1.2 --- qlock_p.h 22 Sep 2005 12:55:30 -0000 1.1.1.7 +++ qlock_p.h 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,11 +1,11 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of QLock class. This manages interprocess locking ** ** Created : 20000406 ** -** Copyright (C) 2000-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qobjectcleanuphandler.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qobjectcleanuphandler.h,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qobjectcleanuphandler.h 22 Sep 2005 12:55:19 -0000 1.1.1.8 +++ qobjectcleanuphandler.h 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of ??? ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qprinter_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qprinter_p.h,v retrieving revision 1.1.1.5 retrieving revision 1.2 diff -u -r1.1.1.5 -r1.2 --- qprinter_p.h 22 Sep 2005 12:55:18 -0000 1.1.1.5 +++ qprinter_p.h 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,11 +1,11 @@ /********************************************************************** -** $Id$ +** ** ** Definition of QPrinter class ** ** Created : 940927 ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qscriptengine.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qscriptengine.cpp,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qscriptengine.cpp 22 Sep 2005 12:55:05 -0000 1.1.1.8 +++ qscriptengine.cpp 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,7 +1,7 @@ /**************************************************************************** -** $Id$ +** ** -** Copyright (C) 2003-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2003-2004 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** @@ -222,7 +222,7 @@ // set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars ang glyphs // and no reordering. // also computes logClusters heuristically -static void heuristicSetGlyphAttributes( const QChar *uc, int len, +static void heuristicSetGlyphAttributes( const QString &string, int from, int len, QTextEngine *engine, QScriptItem *si ) { // ### zeroWidth and justification are missing here!!!!! @@ -236,6 +236,8 @@ advance_t *advances = engine->advances( si ); // honour the logClusters array if it exists. + const QChar *uc = string.unicode() + from; + for ( int i = 0; i < si->num_glyphs; i++ ) logClusters[i] = i; @@ -297,13 +299,6 @@ } } -static void heuristicSetGlyphAttributes( const QString &string, int from, int len, - QTextEngine *engine, QScriptItem *si ) -{ - heuristicSetGlyphAttributes(string.unicode() + from, len, engine, si); -} - - static void convertToCMap( const QChar *chars, int len, QTextEngine *engine, QScriptItem *si ) { glyph_t *glyphs = engine->glyphs( si ); @@ -380,171 +375,12 @@ } #endif - - // -------------------------------------------------------------------------------------------------------------------------------------------- // // Middle eastern languages // // -------------------------------------------------------------------------------------------------------------------------------------------- -/* Hebrew shaping. In the non opentype case we try to use the - presentation forms specified for Hebrew. Especially for the - ligatures with Dagesh this gives much better results than we could - achieve manually. -*/ -static void hebrew_shape(int script, const QString &string, int from, int len, - QTextEngine *engine, QScriptItem *si) -{ - assert(script == QFont::Hebrew); - - if (len == 0) - return; - -#if defined( Q_WS_X11) && !defined( QT_NO_XFTFREETYPE ) - QOpenType *openType = si->fontEngine->openType(); - - if ( openType && openType->supportsScript( script ) ) { - convertToCMap( string.unicode() + from, len, engine, si ); - heuristicSetGlyphAttributes( string, from, len, engine, si ); - openType->init(engine->glyphs(si), engine->glyphAttributes(si), si->num_glyphs, - engine->logClusters(si), len); - - openType->applyGSUBFeature(FT_MAKE_TAG( 'c', 'c', 'm', 'p' )); - // Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly - // ligatures one does not want in modern Hebrew (as lam-alef ligatures). - - openType->applyGPOSFeatures(); - si->num_glyphs = 0; - openType->appendTo(engine, si); - - return; - } -#endif - - enum { - Dagesh = 0x5bc, - ShinDot = 0x5c1, - SinDot = 0x5c2, - Patah = 0x5b7, - Qamats = 0x5b8, - Holam = 0x5b9, - Rafe = 0x5bf - }; - unsigned short chars[512]; - QChar *shapedChars = len > 256 ? (QChar *)::malloc(2*len * sizeof(QChar)) : (QChar *)chars; - - GlyphAttributes *glyphAttributes = engine->glyphAttributes( si ); - unsigned short *logClusters = engine->logClusters( si ); - - const QChar *uc = string.unicode() + from; - - *shapedChars = *uc; - logClusters[0] = 0; - int slen = 1; - int cluster_start = 0; - for (int i = 1; i < len; ++i) { - ushort base = shapedChars[slen-1].unicode(); - ushort shaped = 0; - bool invalid = FALSE; - if (uc[i].unicode() == Dagesh) { - if (base >= 0x5d0 - && base <= 0x5ea - && base != 0x5d7 - && base != 0x5dd - && base != 0x5df - && base != 0x5e2 - && base != 0x5e5) { - shaped = base - 0x5d0 + 0xfb30; - } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) { - shaped = base + 2; - } else { - invalid = TRUE; - } - } else if (uc[i].unicode() == ShinDot) { - if (base == 0x05e9) - shaped = 0xfb2a; - else if (base == 0xfb49) - shaped = 0xfb2c; - else - invalid = TRUE; - } else if (uc[i].unicode() == SinDot) { - if (base == 0x05e9) - shaped = 0xfb2b; - else if (base == 0xfb49) - shaped = 0xfb2d; - else - invalid = TRUE; - } else if (uc[i].unicode() == Patah) { - if (base == 0x5d0) - shaped = 0xfb2e; - } else if (uc[i].unicode() == Qamats) { - if (base == 0x5d0) - shaped = 0xfb2f; - } else if (uc[i].unicode() == Holam) { - if (base == 0x5d5) - shaped = 0xfb4b; - } else if (uc[i].unicode() == Rafe) { - if (base == 0x5d1) - shaped = 0xfb4c; - else if (base == 0x5db) - shaped = 0xfb4d; - else if (base == 0x5e4) - shaped = 0xfb4e; - } - - if (invalid) { - shapedChars[slen] = 0x25cc; - glyphAttributes[slen].clusterStart = TRUE; - glyphAttributes[slen].mark = FALSE; - glyphAttributes[slen].combiningClass = 0; - cluster_start = slen; - ++slen; - } - if (shaped) { - if (si->fontEngine->canRender((QChar *)&shaped, 1)) { - shapedChars[slen-1] = QChar(shaped); - } else - shaped = 0; - } - if (!shaped) { - shapedChars[slen] = uc[i]; - if (::category(uc[i]) != QChar::Mark_NonSpacing) { - glyphAttributes[slen].clusterStart = TRUE; - glyphAttributes[slen].mark = FALSE; - glyphAttributes[slen].combiningClass = 0; - cluster_start = slen; - } else { - glyphAttributes[slen].clusterStart = FALSE; - glyphAttributes[slen].mark = TRUE; - glyphAttributes[slen].combiningClass = ::combiningClass(uc[i]); - } - ++slen; - } - logClusters[i] = cluster_start; - si->hasPositioning = TRUE; - } - - convertToCMap(shapedChars, slen, engine, si); - - glyphAttributes = engine->glyphAttributes( si ); - advance_t *advances = engine->advances( si ); - { - for (int i = 0; i < slen; ++i) { - if (glyphAttributes[i].mark) - advances[i] = 0; - } - } - - if ( !engine->widthOnly ) { - q_heuristicPosition( engine, si ); - } - - if (len > 256) - ::free(shapedChars); -} - - /* Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on arabic). Index: qscriptengine_p.h =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qscriptengine_p.h,v retrieving revision 1.1.1.5 retrieving revision 1.2 diff -u -r1.1.1.5 -r1.2 --- qscriptengine_p.h 22 Sep 2005 12:55:08 -0000 1.1.1.5 +++ qscriptengine_p.h 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** ??? ** -** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** Index: qscriptengine_x11.cpp =================================================================== RCS file: /cvsroot/kde-cygwin/qt-3/src/kernel/qscriptengine_x11.cpp,v retrieving revision 1.1.1.8 retrieving revision 1.2 diff -u -r1.1.1.8 -r1.2 --- qscriptengine_x11.cpp 22 Sep 2005 12:55:20 -0000 1.1.1.8 +++ qscriptengine_x11.cpp 23 Sep 2005 09:40:30 -0000 1.2 @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** ** Continuation of middle eastern languages ** -** Copyright (C) 2003-2005 Trolltech AS. All rights reserved. +** Copyright (C) 2003-2004 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** @@ -39,6 +39,34 @@ // // ------------------------------------------------------------------------------------------------------------------ +// #### stil missing: identify invalid character combinations +static void hebrew_shape(int script, const QString &string, int from, int len, + QTextEngine *engine, QScriptItem *si) +{ + assert(script == QFont::Hebrew); + +#ifndef QT_NO_XFTFREETYPE + QOpenType *openType = si->fontEngine->openType(); + + if ( openType && openType->supportsScript( script ) ) { + convertToCMap( string.unicode() + from, len, engine, si ); + heuristicSetGlyphAttributes( string, from, len, engine, si ); + openType->init(engine->glyphs(si), engine->glyphAttributes(si), si->num_glyphs, + engine->logClusters(si), len); + + openType->applyGSUBFeature(FT_MAKE_TAG( 'c', 'c', 'm', 'p' )); + // Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly + // ligatures one does not want in modern Hebrew (as lam-alef ligatures). + + openType->applyGPOSFeatures(); + si->num_glyphs = 0; + openType->appendTo(engine, si); + + return; + } +#endif + basic_shape( script, string, from, len, engine, si ); +} // #### stil missing: identify invalid character combinations static void syriac_shape( int script, const QString &string, int from, int len, @@ -628,7 +656,7 @@ Below, None, None, None, None, Below, None, None, - None, Below, None, None, + None, None, None, None, Below, None, Post, Pre, Post, Below, Below, None, @@ -1299,8 +1327,7 @@ // If the base consonant is not the last one, Uniscribe // moves the halant from the base consonant to the last // one. - if ( lastConsonant > base && uc[base+1] == halant - && (script != QFont::Telugu || lastConsonant == len - 1 || uc[lastConsonant+1] != halant)) { + if ( lastConsonant > base && uc[base+1] == halant ) { IDEBUG(" moving halant from %d to %d!", base+1, lastConsonant); for (i = base+1; i < lastConsonant; i++) uc[i] = uc[i+1]; @@ -2179,321 +2206,215 @@ // // -------------------------------------------------------------------------------------------------------------------------------------------- -// Vocabulary -// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the -// center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels, -// split vowels, signs... but there is only one base in a syllable, it has to be coded as -// the first character of the syllable. -// split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant). -// Khmer language has five of them. Khmer split vowels either have one part before the -// base and one after the base or they have a part before the base and a part above the base. -// The first part of all Khmer split vowels is the same character, identical to -// the glyph of Khmer dependent vowel SRA EI -// coeng --> modifier used in Khmer to construct coeng (subscript) consonants -// Differently than indian languages, the coeng modifies the consonant that follows it, -// not the one preceding it Each consonant has two forms, the base form and the subscript form -// the base form is the normal one (using the consonants code-point), the subscript form is -// displayed when the combination coeng + consonant is encountered. -// Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant -// Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO) -// Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA) -// Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds -// if it is attached to a consonant of the first series or a consonant of the second series -// Most consonants have an equivalent in the other series, but some of theme exist only in -// one series (for example SA). If we want to use the consonant SA with a vowel sound that -// can only be done with a vowel sound that corresponds to a vowel accompanying a consonant -// of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN -// x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and -// MUSIKATOAN a second series consonant to have a first series vowel sound. -// Consonant shifter are both normally supercript marks, but, when they are followed by a -// superscript, they change shape and take the form of subscript dependent vowel SRA U. -// If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they -// should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should -// be placed after the coeng consonant. -// Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base -// Each vowel has its own position. Only one vowel per syllable is allowed. -// Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are -// Allowed in a syllable. -// -// -// order is important here! This order must be the same that is found in each horizontal -// line in the statetable for Khmer (see khmerStateTable) . -// -enum KhmerCharClassValues { - CC_RESERVED = 0, - CC_CONSONANT = 1, // Consonant of type 1 or independent vowel - CC_CONSONANT2 = 2, // Consonant of type 2 - CC_CONSONANT3 = 3, // Consonant of type 3 - CC_ZERO_WIDTH_NJ_MARK = 4, // Zero Width non joiner character (0x200C) - CC_CONSONANT_SHIFTER = 5, - CC_ROBAT = 6, // Khmer special diacritic accent -treated differently in state table - CC_COENG = 7, // Subscript consonant combining character - CC_DEPENDENT_VOWEL = 8, - CC_SIGN_ABOVE = 9, - CC_SIGN_AFTER = 10, - CC_ZERO_WIDTH_J_MARK = 11, // Zero width joiner character - CC_COUNT = 12 // This is the number of character classes -}; - - -enum KhmerCharClassFlags { - CF_CLASS_MASK = 0x0000FFFF, - - CF_CONSONANT = 0x01000000, // flag to speed up comparing - CF_SPLIT_VOWEL = 0x02000000, // flag for a split vowel -> the first part is added in front of the syllable - CF_DOTTED_CIRCLE = 0x04000000, // add a dotted circle if a character with this flag is the first in a syllable - CF_COENG = 0x08000000, // flag to speed up comparing - CF_SHIFTER = 0x10000000, // flag to speed up comparing - CF_ABOVE_VOWEL = 0x20000000, // flag to speed up comparing - - // position flags - CF_POS_BEFORE = 0x00080000, - CF_POS_BELOW = 0x00040000, - CF_POS_ABOVE = 0x00020000, - CF_POS_AFTER = 0x00010000, - CF_POS_MASK = 0x000f0000 -}; - +enum KhmerForm { + Khmer_Cons, // Consonant + Khmer_IndV, // Independent Vowel + Khmer_Coeng, // COENG + Khmer_PreV, // Pre dependent Vowel + Khmer_BlwV, // Below dependent Vowel + Khmer_Shift, // Regshift + Khmer_AbvV, // Above dependent Vowel + Khmer_AbvS, // Above Sign + Khmer_PstV, // Post dependent Vowel + Khmer_PstS, // Post sign + Khmer_Other +}; + + +static const unsigned char khmerForm[0x54] = { + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_Cons, + + Khmer_Cons, Khmer_Cons, Khmer_Cons, Khmer_IndV, + Khmer_IndV, Khmer_IndV, Khmer_IndV, Khmer_IndV, + Khmer_IndV, Khmer_IndV, Khmer_IndV, Khmer_IndV, + Khmer_IndV, Khmer_IndV, Khmer_IndV, Khmer_IndV, + + Khmer_IndV, Khmer_IndV, Khmer_IndV, Khmer_IndV, + // #### the following two might not be independent vowels. + Khmer_IndV, Khmer_IndV, Khmer_PstV, Khmer_AbvV, + Khmer_AbvV, Khmer_AbvV, Khmer_AbvV, Khmer_BlwV, + Khmer_BlwV, Khmer_BlwV, Khmer_AbvV, Khmer_PstV, + + Khmer_PstV, Khmer_PreV, Khmer_PreV, Khmer_PreV, + Khmer_PstV, Khmer_PstV, Khmer_AbvS, Khmer_PstS, + Khmer_PstS, Khmer_Shift, Khmer_Shift, Khmer_AbvS, + Khmer_AbvS, Khmer_AbvS, Khmer_AbvS, Khmer_AbvS, + + Khmer_AbvS, Khmer_AbvS, Khmer_Coeng, Khmer_AbvS, +}; + +// see Uniscribe specs for details. A lot of the needed information can be found +// in the 3.2 annex, see http://www.unicode.org/reports/tr28/ +// +// syllable analysis needs to respect these: type one has to come before type 2 +// which has to come before type 3. type 2 can appear only once. +// +// We use 0xff to encode that this is a split vowel. +static const unsigned char khmerSubscriptType[0x54] = { + 1, 1, 1, 3, + 1, 1, 1, 1, + 3, 1, 1, 1, + 1, 3, 1, 1, + + 1, 1, 1, 1, + 3, 1, 1, 1, + 1, 3, 2, 1, + 1, 1, 3, 3, + + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 0xff, 0xff, + + 0xff, 1, 1, 1, + 0xff, 0xff, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + + 1, 1, 1, 1 +}; + +static inline KhmerForm khmer_form(const QChar &uc) { + if (uc.unicode() < 0x1780 || uc.unicode() > 0x17d3) + return Khmer_Other; + return (KhmerForm) khmerForm[uc.unicode()-0x1780]; +} -// Characters that get refered to by name -enum KhmerChar { - C_SIGN_ZWNJ = 0x200C, - C_SIGN_ZWJ = 0x200D, - C_DOTTED_CIRCLE = 0x25CC, - C_RO = 0x179A, - C_VOWEL_AA = 0x17B6, - C_SIGN_NIKAHIT = 0x17C6, - C_VOWEL_E = 0x17C1, - C_COENG = 0x17D2 -}; +static inline unsigned char khmer_subscript_type(const QChar &uc) { + return khmerSubscriptType[uc.unicode()-0x1780]; +} +// #define KHMER_DEBUG +#ifdef KHMER_DEBUG +#define KHDEBUG qDebug +#else +#define KHDEBUG if(0) qDebug +#endif -// simple classes, they are used in the statetable (in this file) to control the length of a syllable -// they are also used to know where a character should be placed (location in reference to the base character) -// and also to know if a character, when independently displayed, should be displayed with a dotted-circle to -// indicate error in syllable construction +// Khmer syllables are of the form: +// Cons + {COENG + (Cons | IndV)} + [PreV | BlwV] + [Shift] + [AbvV] + {AbvS} + [PstV] + [PstS] +// IndV +// Number // -enum { - _xx = CC_RESERVED, - _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER, - _c1 = CC_CONSONANT | CF_CONSONANT, - _c2 = CC_CONSONANT2 | CF_CONSONANT, - _c3 = CC_CONSONANT3 | CF_CONSONANT, - _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE, - _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER, - _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE, - _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE, - _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL, - _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE, - _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE, - - // split vowel - _va = _da | CF_SPLIT_VOWEL, - _vr = _dr | CF_SPLIT_VOWEL -}; - +// {...} == 0-2 occurences -// Character class: a character class value -// ORed with character class flags. -// -typedef unsigned long KhmerCharClass; +// According to the Unicode 3.0 standard, the syllable is as follows: +// Cons ( Coeng (Cons|IndV) )* Shift? DepV? +// The above definitions disagree to a certain degree. Most probably the form mentioned by Uniscribe is the shaped form. -// Character class tables -// _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs... -// _sa Sign placed above the base -// _sp Sign placed after the base -// _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants) -// _c2 Consonant of type 2 (only RO) -// _c3 Consonant of type 3 -// _rb Khmer sign robat u17CC. combining mark for subscript consonants -// _cd Consonant-shifter -// _dl Dependent vowel placed before the base (left of the base) -// _db Dependent vowel placed below the base -// _da Dependent vowel placed above the base -// _dr Dependent vowel placed behind the base (right of the base) -// _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following -// it to create a subscript consonant or independent vowel -// _va Khmer split vowel in wich the first part is before the base and the second one above the base -// _vr Khmer split vowel in wich the first part is before the base and the second one behind (right of) the base -// -static const KhmerCharClass khmerCharClasses[] = { - _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, // 1780 - 178F - _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, // 1790 - 179F - _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, // 17A0 - 17AF - _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, // 17B0 - 17BF - _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, // 17C0 - 17CF - _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx // 17D0 - 17DF -}; - -// this enum must reflect the range of khmerCharClasses -enum KhmerCharClassesRange { - KhmerFirstChar = 0x1780, - KhmerLastChar = 0x17df -}; - -// Below we define how a character in the input string is either in the khmerCharClasses table -// (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear -// within the syllable, but are not in the table) we also get their type back, or an unknown object -// in which case we get _xx (CC_RESERVED) back -// -static inline KhmerCharClass getKhmerCharClass(const QChar &uc) +static int khmer_nextSyllableBoundary(const QString &s, int start, int end, bool *invalid) { - if (uc.unicode() == C_SIGN_ZWJ) { - return CC_ZERO_WIDTH_J_MARK; - } - - if (uc.unicode() == C_SIGN_ZWNJ) { - return CC_ZERO_WIDTH_NJ_MARK; - } + const QChar *uc = s.unicode() + start; - if (uc.unicode() < KhmerFirstChar || uc.unicode() > KhmerLastChar) { - return CC_RESERVED; - } + int pos = 0; + unsigned int coengCount = 0; + unsigned int abvSCount = 0; + unsigned int subscriptType = 1; - return khmerCharClasses[uc.unicode() - KhmerFirstChar]; -} + KhmerForm state = khmer_form(*uc); + KHDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos].unicode() ); + pos++; -// The stateTable is used to calculate the end (the length) of a well -// formed Khmer Syllable. -// -// Each horizontal line is ordered exactly the same way as the values in KhmerClassTable -// CharClassValues. This coincidence of values allows the follow up of the table. -// -// Each line corresponds to a state, which does not necessarily need to be a type -// of component... for example, state 2 is a base, with is always a first character -// in the syllable, but the state could be produced a consonant of any type when -// it is the first character that is analysed (in ground state). -// -// Differentiating 3 types of consonants is necessary in order to -// forbid the use of certain combinations, such as having a second -// coeng after a coeng RO, -// The inexistent possibility of having a type 3 after another type 3 is permitted, -// eliminating it would very much complicate the table, and it does not create typing -// problems, as the case above. -// -// The table is quite complex, in order to limit the number of coeng consonants -// to 2 (by means of the table). -// -// There a peculiarity, as far as Unicode is concerned: -// - The consonant-shifter is considered in two possible different -// locations, the one considered in Unicode 3.0 and the one considered in -// Unicode 4.0. (there is a backwards compatibility problem in this standard). -// -// -// xx independent character, such as a number, punctuation sign or non-khmer char -// -// c1 Khmer consonant of type 1 or an independent vowel -// that is, a letter in which the subscript for is only under the -// base, not taking any space to the right or to the left -// -// c2 Khmer consonant of type 2, the coeng form takes space under -// and to the left of the base (only RO is of this type) -// -// c3 Khmer consonant of type 3. Its subscript form takes space under -// and to the right of the base. -// -// cs Khmer consonant shifter -// -// rb Khmer robat -// -// co coeng character (u17D2) -// -// dv dependent vowel (including split vowels, they are treated in the same way). -// even if dv is not defined above, the component that is really tested for is -// KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels -// -// zwj Zero Width joiner -// -// zwnj Zero width non joiner -// -// sa above sign -// -// sp post sign -// -// there are lines with equal content but for an easier understanding -// (and maybe change in the future) we did not join them -// -static const signed char khmerStateTable[][CC_COUNT] = -{ - // xx c1 c2 c3 zwnj cs rb co dv sa sp zwj - { 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, // 0 - ground state - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state (or sign to the right of the syllable) - {-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, // 2 - Base consonant - {-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, // 3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel - {-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, // 4 - First register shifter - {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, // 5 - Robat - {-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - First Coeng - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 7 - First consonant of type 1 after coeng - {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, // 8 - First consonant of type 2 after coeng - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 9 - First consonant or type 3 after ceong - {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, // 10 - Second Coeng (no register shifter before) - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 11 - Second coeng consonant (or ind. vowel) no register shifter before - {-1, -1, 1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 13 - Second register shifter - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 14 - ZWJ before vowel - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 15 - ZWNJ before vowel - {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, // 16 - dependent vowel - {-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above - {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, // 18 - ZWJ after vowel - {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, // 19 - Third coeng - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat -}; + if (state != Khmer_Cons && state != Khmer_IndV) { + if (state != Khmer_Other) + *invalid = TRUE; + goto finish; + } + while ( pos < end - start ) { + KhmerForm newState = khmer_form(uc[pos]); + switch( newState ) { + case Khmer_Coeng: + if (coengCount > 1 || (state != Khmer_Cons && state != Khmer_IndV)) + goto finish; + ++coengCount; + break; + case Khmer_Cons: + case Khmer_IndV: { + unsigned int t = khmer_subscript_type(uc[pos]); + if (state != Khmer_Coeng || t < subscriptType) + goto finish; + subscriptType = t; + // only one consonant of type 2 can be present + if (t == 2) + t = 3; + break; + } + case Khmer_PstS: + if (state == Khmer_PstV) + break; + case Khmer_PstV: + case Khmer_AbvS: + if (newState == Khmer_AbvS) { + if (abvSCount > 1) + goto finish; + ++abvSCount; + } + if (state == Khmer_AbvS || state == Khmer_AbvV) + break; + // fall through + case Khmer_AbvV: + if (state == Khmer_Shift) + break; + // fall through + case Khmer_Shift: + if (state == Khmer_PreV || state == Khmer_BlwV) + break; + // fall through + case Khmer_PreV: + case Khmer_BlwV: + if (state != Khmer_Cons && state != Khmer_IndV) + goto finish; + break; + case Khmer_Other: + goto finish; + } + state = newState; + pos++; + } -// #define KHMER_DEBUG -#ifdef KHMER_DEBUG -#define KHDEBUG qDebug -#else -#define KHDEBUG if(0) qDebug -#endif +finish: + // makse sure we don't have an invalid Coeng at the end + if (state == Khmer_Coeng && pos > 1) + --pos; -// Given an input string of characters and a location in which to start looking -// calculate, using the state table, which one is the last character of the syllable -// that starts in the starting position. -// -static inline int khmer_nextSyllableBoundary(const QString &s, int start, int end, bool *invalid) -{ *invalid = FALSE; - const QChar *uc = s.unicode() + start; - int state = 0; - int pos = start; - - while (pos < end) { - KhmerCharClass charClass = getKhmerCharClass(*uc); - if (pos == start) { - *invalid = (charClass > 0) && ! (charClass & CF_CONSONANT); - } - state = khmerStateTable[state][charClass & CF_CLASS_MASK]; - - KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state, - charClass, uc->unicode() ); - - if (state < 0) { - break; - } - ++uc; - ++pos; - } - return pos; + return start+pos; } - static void khmer_shape_syllable( const QString &string, int from, int syllableLength, - QTextEngine *engine, QScriptItem *si, QOpenType *openType ) + QTextEngine *engine, QScriptItem *si, QOpenType *openType, bool invalid ) { + enum { + Coeng = 0x17d2, + VowelSignE = 0x17c1 + }; + // according to the specs this is the max length one can get // ### the real value should be smaller assert(syllableLength < 13); KHDEBUG("syllable from %d len %d, str='%s'", from, syllableLength, string.mid(from,syllableLength).utf8().data()); + int len = syllableLength; - int len = 0; - int syllableEnd = from + syllableLength; + int i; unsigned short reordered[16]; GlyphAttributes glyphAttributes[16]; unsigned char properties[16]; @@ -2505,163 +2426,86 @@ }; memset(properties, 0, 16*sizeof(unsigned char)); - int i; + if ( invalid ) { + *reordered = 0x25cc; + memcpy( reordered+1, string.unicode() + from, len*sizeof(unsigned short) ); + len++; + } else { + memcpy( reordered, string.unicode() + from, len*sizeof(unsigned short) ); + } + #ifdef KHMER_DEBUG qDebug("original:"); - for (i = from; i < syllableEnd; i++) { - qDebug(" %d: %4x", i, string[i].unicode()); + for (i = 0; i < len; i++) { + qDebug(" %d: %4x", i, reordered[i]); } #endif - // write a pre vowel or the pre part of a split vowel first - // and look out for coeng + ro. RO is the only vowel of type 2, and - // therefore the only one that requires saving space before the base. - // - int coengRo = -1; // There is no Coeng Ro, if found this value will change - for (i = from; i < syllableEnd; i += 1) { - KhmerCharClass charClass = getKhmerCharClass(string[i]); - - // if a split vowel, write the pre part. In Khmer the pre part - // is the same for all split vowels, same glyph as pre vowel C_VOWEL_E - if (charClass & CF_SPLIT_VOWEL) { - reordered[len] = C_VOWEL_E; - properties[len] = PreForm; - ++len; - break; // there can be only one vowel - } - // if a vowel with pos before write it out - if (charClass & CF_POS_BEFORE) { - reordered[len] = string[i].unicode(); - properties[len] = PreForm; - ++len; - break; // there can be only one vowel - } - // look for coeng + ro and remember position - // works because coeng + ro is always in front of a vowel (if there is a vowel) - // and because CC_CONSONANT2 is enough to identify it, as it is the only consonant - // with this flag - if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) && - ( (getKhmerCharClass(string[i + 1]) & CF_CLASS_MASK) == CC_CONSONANT2) ) { - coengRo = i; - } - } - - // write coeng + ro if found - if (coengRo > -1) { - reordered[len] = C_COENG; - properties[len] = PreForm; - ++len; - reordered[len] = C_RO; - properties[len] = PreForm; - ++len; - } - - // shall we add a dotted circle? - // If in the position in which the base should be (first char in the string) there is - // a character that has the Dotted circle flag (a character that cannot be a base) - // then write a dotted circle - if (getKhmerCharClass(string[from]) & CF_DOTTED_CIRCLE) { - reordered[len] = C_DOTTED_CIRCLE; - ++len; - } - - // copy what is left to the output, skipping before vowels and - // coeng Ro if they are present - for (i = from; i < syllableEnd; i += 1) { - QChar uc = string[i]; - KhmerCharClass charClass = getKhmerCharClass(uc); - - // skip a before vowel, it was already processed - if (charClass & CF_POS_BEFORE) { - ... [truncated message content] |