📄 qopentype.cpp
字号:
while (features->tag) { FT_UShort feature_index; error = TT_GSUB_Select_Feature(gsub, features->tag, script_index, 0xffff, &feature_index); if (!error) {#ifdef OT_DEBUG qDebug(" adding feature %s", tag_to_string(features->tag));#endif TT_GSUB_Add_Feature(gsub, feature_index, features->property); } ++features; } } } if (gpos) { TT_GPOS_Clear_Features(gpos); FT_UShort script_index; FT_Error error = TT_GPOS_Select_Script(gpos, tag, &script_index); if (!error) {#ifdef OT_DEBUG { TTO_FeatureList featurelist = gpos->FeatureList; int numfeatures = featurelist.FeatureCount; qDebug("gpos table has %d features", numfeatures); for(int i = 0; i < numfeatures; i++) { TTO_FeatureRecord *r = featurelist.FeatureRecord + i; FT_UShort feature_index; TT_GPOS_Select_Feature(gpos, r->FeatureTag, script_index, 0xffff, &feature_index); qDebug(" feature '%s'", tag_to_string(r->FeatureTag)); } }#endif FT_ULong *feature_tag_list; error = TT_GPOS_Query_Features(gpos, script_index, 0xffff, &feature_tag_list); if (!error) { while (*feature_tag_list) { FT_UShort feature_index; error = TT_GPOS_Select_Feature(gpos, *feature_tag_list, script_index, 0xffff, &feature_index); if (!error) TT_GPOS_Add_Feature(gpos, feature_index, PositioningProperties); ++feature_tag_list; } } } } current_script = script;}#ifdef OT_DEBUGstatic void dump_string(OTL_Buffer buffer){ for (uint i = 0; i < buffer->in_length; ++i) { qDebug(" %x: cluster=%d", buffer->in_string[i].gindex, buffer->in_string[i].cluster); }}#endifextern void qt_heuristicPosition(QShaperItem *item);bool QOpenType::shape(QShaperItem *item, const unsigned int *properties){ length = item->num_glyphs; otl_buffer_clear(otl_buffer); tmpAttributes = (QGlyphLayout::Attributes *) realloc(tmpAttributes, length*sizeof(QGlyphLayout::Attributes)); tmpLogClusters = (unsigned int *) realloc(tmpLogClusters, length*sizeof(unsigned int)); for (int i = 0; i < length; ++i) { otl_buffer_add_glyph(otl_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 qDebug("-----------------------------------------");// qDebug("log clusters before shaping:");// for (int j = 0; j < length; j++)// qDebug(" log[%d] = %d", j, item->log_clusters[j]); qDebug("original glyphs: %p", item->glyphs); for (int i = 0; i < length; ++i) qDebug(" glyph=%4x", otl_buffer->in_string[i].gindex);// dump_string(otl_buffer);#endif loadFlags = item->flags & QTextEngine::DesignMetrics ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT; if (gsub) { uint error = TT_GSUB_Apply_String(gsub, otl_buffer); if (error && error != TTO_Err_Not_Covered) return false; }#ifdef OT_DEBUG// qDebug("log clusters before shaping:");// for (int j = 0; j < length; j++)// qDebug(" log[%d] = %d", j, item->log_clusters[j]); qDebug("shaped glyphs:"); for (int i = 0; i < length; ++i) qDebug(" glyph=%4x", otl_buffer->in_string[i].gindex); qDebug("-----------------------------------------");// dump_string(otl_buffer);#endif return true;}bool QOpenType::positionAndAdd(QShaperItem *item, int availableGlyphs, bool doLogClusters){ if (gpos) {#ifdef Q_WS_X11 Q_ASSERT(fontEngine->type() == QFontEngine::Freetype); face = static_cast<QFontEngineFT *>(fontEngine)->lockFace();#endif memset(otl_buffer->positions, 0, otl_buffer->in_length*sizeof(OTL_PositionRec)); // #### check that passing "false,false" is correct TT_GPOS_Apply_String(face, gpos, loadFlags, otl_buffer, false, false);#ifdef Q_WS_X11 static_cast<QFontEngineFT *>(fontEngine)->unlockFace();#endif } // make sure we have enough space to write everything back if (availableGlyphs < (int)otl_buffer->in_length) { item->num_glyphs = otl_buffer->in_length; return false; } QGlyphLayout *glyphs = item->glyphs; for (unsigned int i = 0; i < otl_buffer->in_length; ++i) { glyphs[i].glyph = otl_buffer->in_string[i].gindex; glyphs[i].attributes = tmpAttributes[otl_buffer->in_string[i].cluster]; if (i && otl_buffer->in_string[i].cluster == otl_buffer->in_string[i-1].cluster) glyphs[i].attributes.clusterStart = false; } item->num_glyphs = otl_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 < otl_buffer->in_length; ++i) { int ci = otl_buffer->in_string[i].cluster; // qDebug(" 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// qDebug("unpositioned: "); item->font->recalcAdvances(item->num_glyphs, glyphs, QFlag(item->flags)); // positioning code: if (gpos) { OTL_Position positions = otl_buffer->positions;// qDebug("positioned glyphs:"); for (unsigned int i = 0; i < otl_buffer->in_length; i++) {// qDebug(" %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????? if (positions[i].new_advance) { glyphs[i].advance.x = QFixed::fromFixed(item->flags & QTextEngine::RightToLeft ? -positions[i].x_advance : positions[i].x_advance); glyphs[i].advance.y = QFixed::fromFixed(-positions[i].y_advance); } else { glyphs[i].advance.x += QFixed::fromFixed(item->flags & QTextEngine::RightToLeft ? -positions[i].x_advance : positions[i].x_advance); glyphs[i].advance.y -= QFixed::fromFixed(positions[i].y_advance); } glyphs[i].offset.x = QFixed::fromFixed(positions[i].x_pos); glyphs[i].offset.y = QFixed::fromFixed(-positions[i].y_pos); int back = positions[i].back; if (item->flags & QTextEngine::RightToLeft) { while (back--) { glyphs[i].offset.x -= glyphs[i-back].advance.x; glyphs[i].offset.y -= -glyphs[i-back].advance.y; } } else { while (back) { glyphs[i].offset.x -= glyphs[i-back].advance.x; glyphs[i].offset.y -= -glyphs[i-back].advance.y; --back; } }// qDebug(" ->\tadv=%d\tpos=(%d/%d)",// glyphs[i].advance.x.toInt(), glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt()); } } else { qt_heuristicPosition(item); }#ifdef OT_DEBUG if (doLogClusters) { qDebug("log clusters after shaping:"); for (int j = 0; j < length; j++) qDebug(" log[%d] = %d", j, item->log_clusters[j]); } qDebug("final glyphs:"); for (int i = 0; i < (int)otl_buffer->in_length; ++i) qDebug(" glyph=%4x char_index=%d mark: %d cmp: %d, clusterStart: %d advance=%d/%d offset=%d/%d", glyphs[i].glyph, otl_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()); qDebug("-----------------------------------------");#endif return true;}#endif // QT_NO_FREETYPE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -