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

📄 qopentype.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // reset    kerning_feature_selected = false;    if (gpos) {        HB_GPOS_Clear_Features(gpos);        FT_UShort script_index;        FT_Error error = HB_GPOS_Select_Script(gpos, tag, &script_index);        if (!error) {#ifdef OT_DEBUG            {                HB_FeatureList featurelist = gpos->FeatureList;                int numfeatures = featurelist.FeatureCount;                DEBUG("gpos table has %d features", numfeatures);                for(int i = 0; i < numfeatures; i++) {                    HB_FeatureRecord *r = featurelist.FeatureRecord + i;                    FT_UShort feature_index;                    HB_GPOS_Select_Feature(gpos, r->FeatureTag, script_index, 0xffff, &feature_index);                    DEBUG("   feature '%s'", tag_to_string(r->FeatureTag));                }            }#endif            FT_ULong *feature_tag_list_buffer;            error = HB_GPOS_Query_Features(gpos, script_index, 0xffff, &feature_tag_list_buffer);            if (!error) {                FT_ULong *feature_tag_list = feature_tag_list_buffer;                while (*feature_tag_list) {                    FT_UShort feature_index;                    if (*feature_tag_list == FT_MAKE_TAG('k', 'e', 'r', 'n')) {                        if (!item->kerning_enabled) {                            ++feature_tag_list;                            continue;                        }                        kerning_feature_selected = true;                    }                    error = HB_GPOS_Select_Feature(gpos, *feature_tag_list, script_index, 0xffff, &feature_index);                    if (!error) {                        HB_GPOS_Add_Feature(gpos, feature_index, PositioningProperties);                        has_features = true;                    }                    ++feature_tag_list;                }                FT_Memory memory = gpos->memory;                FREE(feature_tag_list_buffer);            }        }    }    current_script = script;}extern void qt_heuristicPosition(QShaperItem *item);bool QOpenType::shape(QShaperItem *item, const unsigned int *properties){    if (!has_features)        return true;    length = item->num_glyphs;    hb_buffer_clear(hb_buffer);    if (allocated < length) {        tmpAttributes = (QGlyphLayout::Attributes *) realloc(tmpAttributes, length*sizeof(QGlyphLayout::Attributes));        tmpLogClusters = (unsigned int *) realloc(tmpLogClusters, length*sizeof(unsigned int));        allocated = length;    }    for (int i = 0; i < length; ++i) {        hb_buffer_add_glyph(hb_buffer, item->glyphs[i].glyph, properties ? properties[i] : 0, i);        tmpAttributes[i] = item->glyphs[i].attributes;        tmpLogClusters[i] = item->log_clusters[i];    }#ifdef OT_DEBUG    DEBUG("-----------------------------------------");//     DEBUG("log clusters before shaping:");//     for (int j = 0; j < length; j++)//         DEBUG("    log[%d] = %d", j, item->log_clusters[j]);    DEBUG("original glyphs: %p", item->glyphs);    for (int i = 0; i < length; ++i)        DEBUG("   glyph=%4x", hb_buffer->in_string[i].gindex);//     dump_string(hb_buffer);#endif    // ### FT_LOAD_NO_HINTING might give problems here, see comment about MingLiu in qfontengine_ft.cpp    loadFlags = item->flags & QTextEngine::DesignMetrics ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;    glyphs_substituted = false;    if (gsub) {        uint error = HB_GSUB_Apply_String(gsub, hb_buffer);        if (error && error != HB_Err_Not_Covered)            return false;        glyphs_substituted = (error != HB_Err_Not_Covered);    }#ifdef OT_DEBUG//     DEBUG("log clusters before shaping:");//     for (int j = 0; j < length; j++)//         DEBUG("    log[%d] = %d", j, item->log_clusters[j]);    DEBUG("shaped glyphs:");    for (int i = 0; i < length; ++i)        DEBUG("   glyph=%4x", hb_buffer->in_string[i].gindex);    DEBUG("-----------------------------------------");//     dump_string(hb_buffer);#endif    return true;}bool QOpenType::positionAndAdd(QShaperItem *item, int availableGlyphs, bool doLogClusters){    if (!has_features)        return true;    bool glyphs_positioned = false;    if (gpos) {        switch (fontEngine->type()) {#ifndef QT_NO_FREETYPE        case QFontEngine::Freetype:            face = static_cast<QFontEngineFT *>(fontEngine)->lockFace();            break;#endif#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2) && !defined(QT_NO_FREETYPE)        case QFontEngine::QPF2:            face = static_cast<QFontEngineQPF *>(fontEngine)->lockFace();            break;#endif        default:            Q_ASSERT(false);        }        memset(hb_buffer->positions, 0, hb_buffer->in_length*sizeof(HB_PositionRec));        // #### check that passing "false,false" is correct        glyphs_positioned = HB_GPOS_Apply_String(face, gpos, loadFlags, hb_buffer, false, false) != HB_Err_Not_Covered;        switch (fontEngine->type()) {        case QFontEngine::Freetype:#ifndef QT_NO_FREETYPE            static_cast<QFontEngineFT *>(fontEngine)->unlockFace();            break;#endif#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2) && !defined(QT_NO_FREETYPE)        case QFontEngine::QPF2:            static_cast<QFontEngineQPF *>(fontEngine)->unlockFace();            break;#endif        default:            break;        }    }    if (!glyphs_substituted && !glyphs_positioned)        return true; // nothing to do for us    // make sure we have enough space to write everything back    if (availableGlyphs < (int)hb_buffer->in_length) {        item->num_glyphs = hb_buffer->in_length;        return false;    }    QGlyphLayout *glyphs = item->glyphs;    for (unsigned int i = 0; i < hb_buffer->in_length; ++i) {        glyphs[i].glyph = hb_buffer->in_string[i].gindex;        glyphs[i].attributes = tmpAttributes[hb_buffer->in_string[i].cluster];        if (i && hb_buffer->in_string[i].cluster == hb_buffer->in_string[i-1].cluster)            glyphs[i].attributes.clusterStart = false;    }    item->num_glyphs = hb_buffer->in_length;    if (doLogClusters) {        // we can't do this for indic, as we pass the stuf in syllables and it's easier to do it in the shaper.        unsigned short *logClusters = item->log_clusters;        int clusterStart = 0;        int oldCi = 0;        for (unsigned int i = 0; i < hb_buffer->in_length; ++i) {            int ci = hb_buffer->in_string[i].cluster;            //         DEBUG("   ci[%d] = %d mark=%d, cmb=%d, cs=%d",            //                i, ci, glyphAttributes[i].mark, glyphAttributes[i].combiningClass, glyphAttributes[i].clusterStart);            if (!glyphs[i].attributes.mark && glyphs[i].attributes.clusterStart && ci != oldCi) {                for (int j = oldCi; j < ci; j++)                    logClusters[j] = clusterStart;                clusterStart = i;                oldCi = ci;            }        }        for (int j = oldCi; j < length; j++)            logClusters[j] = clusterStart;    }    // calulate the advances for the shaped glyphs//     DEBUG("unpositioned: ");    if (glyphs_substituted)        item->font->recalcAdvances(item->num_glyphs, glyphs, QFlag(item->flags));    // positioning code:    if (gpos && glyphs_positioned) {        HB_Position positions = hb_buffer->positions;//         DEBUG("positioned glyphs:");        for (unsigned int i = 0; i < hb_buffer->in_length; i++) {//             DEBUG("    %d:\t orig advance: (%d/%d)\tadv=(%d/%d)\tpos=(%d/%d)\tback=%d\tnew_advance=%d", i,//                    glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(),//                    (int)(positions[i].x_advance >> 6), (int)(positions[i].y_advance >> 6),//                    (int)(positions[i].x_pos >> 6), (int)(positions[i].y_pos >> 6),//                    positions[i].back, positions[i].new_advance);            // ###### fix the case where we have y advances. How do we handle this in Uniscribe?????            QFixed xValue = QFixed::fromFixed(item->flags & QTextEngine::RightToLeft                                              ? -positions[i].x_advance : positions[i].x_advance);            QFixed yValue = QFixed::fromFixed(-positions[i].y_advance);            if (!(item->flags & QTextEngine::DesignMetrics)) {                xValue = xValue.round();                yValue = yValue.round();            }            if (positions[i].new_advance) {                glyphs[i].advance.x = xValue;                glyphs[i].advance.y = yValue;            } else {                glyphs[i].advance.x += xValue;                glyphs[i].advance.y += yValue;            }            int back = 0;            glyphs[i].offset.x = QFixed::fromFixed(positions[i].x_pos);            glyphs[i].offset.y = QFixed::fromFixed(positions[i].y_pos);            while (positions[i - back].back) {                back += positions[i - back].back;                glyphs[i].offset.x += QFixed::fromFixed(positions[i - back].x_pos);                glyphs[i].offset.y += QFixed::fromFixed(positions[i - back].y_pos);            }            glyphs[i].offset.y = -glyphs[i].offset.y;            if (item->flags & QTextEngine::RightToLeft) {                // ### may need to go back multiple glyphs like in ltr                back = positions[i].back;                while (back--) {                    glyphs[i].offset.x -= glyphs[i-back].advance.x;                    glyphs[i].offset.y -= -glyphs[i-back].advance.y;                }            } else {                back = 0;                while (positions[i - back].back) {                    back += positions[i - back].back;                    glyphs[i].offset.x -= glyphs[i-back].advance.x;                    glyphs[i].offset.y -= -glyphs[i-back].advance.y;                }            }//             DEBUG("   ->\tadv=%d\tpos=(%d/%d)",//                    glyphs[i].advance.x.toInt(), glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt());        }        item->kerning_applied = kerning_feature_selected;    } else {        qt_heuristicPosition(item);    }#ifdef OT_DEBUG    if (doLogClusters) {        DEBUG("log clusters after shaping:");        for (int j = 0; j < length; j++)            DEBUG("    log[%d] = %d", j, item->log_clusters[j]);    }    DEBUG("final glyphs:");    for (int i = 0; i < (int)hb_buffer->in_length; ++i)        DEBUG("   glyph=%4x char_index=%d mark: %d cmp: %d, clusterStart: %d advance=%d/%d offset=%d/%d",               glyphs[i].glyph, hb_buffer->in_string[i].cluster, glyphs[i].attributes.mark,               glyphs[i].attributes.combiningClass, glyphs[i].attributes.clusterStart,               glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(),               glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt());    DEBUG("-----------------------------------------");#endif    return true;}#endif // QT_NO_FREETYPE

⌨️ 快捷键说明

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