⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qscriptengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qscriptengine_p.h"#include "qdebug.h"#include "qstring.h"#include "qrect.h"#include "qfont.h"#include <private/qunicodetables_p.h>#include "qtextengine_p.h"#include "qfontengine_p.h"#include <stdlib.h>#include <qvarlengtharray.h>#ifndef QT_NO_OPENTYPE#include "qopentype_p.h"#endif#undef None#undef Pre#undef Above#undef Below// --------------------------------------------------------------------------------------------------------------------------------------------//// Basic processing//// --------------------------------------------------------------------------------------------------------------------------------------------static inline void positionCluster(QShaperItem *item, int gfrom,  int glast){    int nmarks = glast - gfrom;    if (nmarks <= 0) {        qWarning("Qt: No marks to position in positionCluster()");        return;    }    QGlyphLayout *glyphs = item->glyphs;    QFontEngine *f = item->font;    glyph_metrics_t baseInfo = f->boundingBox(glyphs[gfrom].glyph);    if (item->script == QUnicodeTables::Hebrew)        // we need to attach below the baseline, because of the hebrew iud.        baseInfo.height = qMax(baseInfo.height, -baseInfo.y);    QRectF baseRect(baseInfo.x.toReal(), baseInfo.y.toReal(), baseInfo.width.toReal(), baseInfo.height.toReal());//     qDebug("---> positionCluster: cluster from %d to %d", gfrom, glast);//     qDebug("baseInfo: %f/%f (%f/%f) off=%f/%f", baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height, baseInfo.xoff, baseInfo.yoff);    qreal size = (f->ascent()/10).toReal();    qreal offsetBase = (size - 4) / 4 + qMin<qreal>(size, 4) + 1;//     qDebug("offset = %f", offsetBase);    bool rightToLeft = item->flags & QTextEngine::RightToLeft;    int i;    unsigned char lastCmb = 0;    QRectF attachmentRect;    for(i = 1; i <= nmarks; i++) {        glyph_t mark = glyphs[gfrom+i].glyph;        QPointF p;        glyph_metrics_t markInfo = f->boundingBox(mark);        QRectF markRect(markInfo.x.toReal(), markInfo.y.toReal(), markInfo.width.toReal(), markInfo.height.toReal());//          qDebug("markInfo: %f/%f (%f/%f) off=%f/%f", markInfo.x, markInfo.y, markInfo.width, markInfo.height, markInfo.xoff, markInfo.yoff);        qreal offset = offsetBase;        unsigned char cmb = glyphs[gfrom+i].attributes.combiningClass;        // ### maybe the whole position determination should move down to heuristicSetGlyphAttributes. Would save some        // bits  in the glyphAttributes structure.        if (cmb < 200) {            // fixed position classes. We approximate by mapping to one of the others.            // currently I added only the ones for arabic, hebrew, lao and thai.            // for Lao and Thai marks with class 0, see below (heuristicSetGlyphAttributes)            // add a bit more offset to arabic, a bit hacky            if (cmb >= 27 && cmb <= 36 && offset < 3)                offset +=1;            // below            if ((cmb >= 10 && cmb <= 18) ||                 cmb == 20 || cmb == 22 ||                 cmb == 29 || cmb == 32)                cmb = QChar::Combining_Below;            // above            else if (cmb == 23 || cmb == 27 || cmb == 28 ||                      cmb == 30 || cmb == 31 || (cmb >= 33 && cmb <= 36))                cmb = QChar::Combining_Above;            //below-right            else if (cmb == 9 || cmb == 103 || cmb == 118)                cmb = QChar::Combining_BelowRight;            // above-right            else if (cmb == 24 || cmb == 107 || cmb == 122)                cmb = QChar::Combining_AboveRight;            else if (cmb == 25)                cmb = QChar::Combining_AboveLeft;            // fixed:            //  19 21        }        // combining marks of different class don't interact. Reset the rectangle.        if (cmb != lastCmb) {            //qDebug("resetting rect");            attachmentRect = baseRect;        }        switch(cmb) {        case QChar::Combining_DoubleBelow:                // ### wrong in rtl context!        case QChar::Combining_BelowLeft:            p += QPointF(0, offset);        case QChar::Combining_BelowLeftAttached:            p += attachmentRect.bottomLeft() - markRect.topLeft();            break;        case QChar::Combining_Below:            p += QPointF(0, offset);        case QChar::Combining_BelowAttached:            p += attachmentRect.bottomLeft() - markRect.topLeft();            p += QPointF((attachmentRect.width() - markRect.width())/2 , 0);            break;            case QChar::Combining_BelowRight:            p += QPointF(0, offset);        case QChar::Combining_BelowRightAttached:            p += attachmentRect.bottomRight() - markRect.topRight();            break;            case QChar::Combining_Left:            p += QPointF(-offset, 0);        case QChar::Combining_LeftAttached:            break;            case QChar::Combining_Right:            p += QPointF(offset, 0);        case QChar::Combining_RightAttached:            break;        case QChar::Combining_DoubleAbove:            // ### wrong in RTL context!        case QChar::Combining_AboveLeft:            p += QPointF(0, -offset);        case QChar::Combining_AboveLeftAttached:            p += attachmentRect.topLeft() - markRect.bottomLeft();            break;        case QChar::Combining_Above:            p += QPointF(0, -offset);        case QChar::Combining_AboveAttached:            p += attachmentRect.topLeft() - markRect.bottomLeft();            p += QPointF((attachmentRect.width() - markRect.width())/2 , 0);            break;        case QChar::Combining_AboveRight:            p += QPointF(0, -offset);        case QChar::Combining_AboveRightAttached:            p += attachmentRect.topRight() - markRect.bottomRight();            break;        case QChar::Combining_IotaSubscript:            default:                break;        }//          qDebug("char=%x combiningClass = %d offset=%f/%f", mark, cmb, p.x(), p.y());        markRect.translate(p.x(), p.y());        attachmentRect |= markRect;        lastCmb = cmb;        if (rightToLeft) {            glyphs[gfrom+i].offset.x = QFixed::fromReal(p.x());            glyphs[gfrom+i].offset.y = QFixed::fromReal(p.y());        } else {            glyphs[gfrom+i].offset.x = QFixed::fromReal(p.x()) - baseInfo.xoff;            glyphs[gfrom+i].offset.y = QFixed::fromReal(p.y()) - baseInfo.yoff;        }        glyphs[gfrom+i].advance = QFixedPoint();    }}void qt_heuristicPosition(QShaperItem *item){    QGlyphLayout *glyphs = item->glyphs;    int cEnd = -1;    int i = item->num_glyphs;    while (i--) {        if (cEnd == -1 && glyphs[i].attributes.mark) {            cEnd = i;        } else if (cEnd != -1 && !glyphs[i].attributes.mark) {            positionCluster(item, i, cEnd);            cEnd = -1;        }    }}// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs// and no reordering.// also computes logClusters heuristicallystatic void heuristicSetGlyphAttributes(QShaperItem *item, const QChar *uc, int length){    // ### zeroWidth and justification are missing here!!!!!    Q_ASSERT(item->num_glyphs <= length);//     qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);    QGlyphLayout *glyphs = item->glyphs;    unsigned short *logClusters = item->log_clusters;    // the mac font engine does the setup already in stringToCMap#ifndef Q_WS_MAC    int glyph_pos = 0;    for (int i = 0; i < length; i++) {        if (uc[i].unicode() >= 0xd800 && uc[i].unicode() < 0xdc00 && i < length-1            && uc[i+1].unicode() >= 0xdc00 && uc[i+1].unicode() < 0xe000) {            logClusters[i] = glyph_pos;            logClusters[++i] = glyph_pos;        } else {            logClusters[i] = glyph_pos;        }        ++glyph_pos;    }    Q_ASSERT(glyph_pos == item->num_glyphs);#endif    // first char in a run is never (treated as) a mark#if !defined(Q_WS_MAC)    int cStart = 0;#endif    const bool symbolFont = item->font->symbol;    glyphs[0].attributes.mark = false;    glyphs[0].attributes.clusterStart = true;    glyphs[0].attributes.dontPrint = (!symbolFont && uc[0].unicode() == 0x00ad) || qIsControlChar(uc[0].unicode());    int pos = 0;    int lastCat = QChar::category(uc[0].unicode());    for (int i = 1; i < length; ++i) {        if (logClusters[i] == pos)            // same glyph            continue;        ++pos;        while (pos < logClusters[i]) {            // the mac engine already has attributes setup properly#if !defined(Q_WS_MAC)            glyphs[pos].attributes = glyphs[pos-1].attributes;#endif            ++pos;        }        // hide soft-hyphens by default        if ((!symbolFont && uc[i].unicode() == 0x00ad) || qIsControlChar(uc[i].unicode()))            glyphs[pos].attributes.dontPrint = true;        const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc[i].unicode());        int cat = prop->category;#if !defined(Q_WS_MAC)        if (cat != QChar::Mark_NonSpacing) {            glyphs[pos].attributes.mark = false;            glyphs[pos].attributes.clusterStart = true;            glyphs[pos].attributes.combiningClass = 0;            cStart = logClusters[i];        } else {            int cmb = prop->combiningClass;            if (cmb == 0) {                // Fix 0 combining classes                if ((uc[pos].unicode() & 0xff00) == 0x0e00) {                    // thai or lao                    unsigned char col = uc[pos].cell();                    if (col == 0x31 ||                         col == 0x34 ||                         col == 0x35 ||                         col == 0x36 ||                         col == 0x37 ||                         col == 0x47 ||                         col == 0x4c ||                         col == 0x4d ||                         col == 0x4e) {                        cmb = QChar::Combining_AboveRight;                    } else if (col == 0xb1 ||                                col == 0xb4 ||                                col == 0xb5 ||                                col == 0xb6 ||                                col == 0xb7 ||                                col == 0xbb ||                                col == 0xcc ||                                col == 0xcd) {                        cmb = QChar::Combining_Above;                    } else if (col == 0xbc) {                        cmb = QChar::Combining_Below;                    }                }            }            glyphs[pos].attributes.mark = true;            glyphs[pos].attributes.clusterStart = false;            glyphs[pos].attributes.combiningClass = cmb;            logClusters[i] = cStart;            glyphs[pos].advance = QFixedPoint();        }#endif        // one gets an inter character justification point if the current char is not a non spacing mark.        // as then the current char belongs to the last one and one gets a space justification point        // after the space char.        if (lastCat == QChar::Separator_Space)            glyphs[pos-1].attributes.justification = QGlyphLayout::Space;        else if (cat != QChar::Mark_NonSpacing)            glyphs[pos-1].attributes.justification = QGlyphLayout::Character;        else            glyphs[pos-1].attributes.justification = QGlyphLayout::NoJustification;        lastCat = cat;    }    pos = logClusters[length-1];    if (lastCat == QChar::Separator_Space)        glyphs[pos].attributes.justification = QGlyphLayout::Space;    else        glyphs[pos].attributes.justification = QGlyphLayout::Character;}static void heuristicSetGlyphAttributes(QShaperItem *item){    heuristicSetGlyphAttributes(item, item->string->unicode() + item->from, item->length);}enum {    CcmpProperty = 0x1};#ifndef QT_NO_OPENTYPEstatic const QOpenType::Features basic_features[] = {    { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },    { FT_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },    { FT_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },    {0, 0}};#endifstatic bool basic_shape(QShaperItem *item){#if !defined(QT_NO_OPENTYPE) && !defined(Q_WS_QWS)    const int availableGlyphs = item->num_glyphs;#endif    if (!item->font->stringToCMap(item->string->unicode()+item->from, item->length,                                  item->glyphs, &item->num_glyphs, QFlag(item->flags)))        return false;    heuristicSetGlyphAttributes(item);    // disable open type shaping for simple scripts on embedded, as it's computationally rahter expensive

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -