/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// If the size index exceeds the cache size, we just read the value with // hb_ot_math_get_glyph_variants.
hb_direction_t direction = aVertical ? HB_DIRECTION_BTT : HB_DIRECTION_LTR;
hb_ot_math_glyph_variant_t variant; unsignedint count = 1;
hb_ot_math_get_glyph_variants(mHBFont, aGlyphID, direction, aSize, &count,
&variant); return count > 0 ? variant.glyph : 0;
}
// Cache the first size variants.
hb_direction_t direction = aVertical ? HB_DIRECTION_BTT : HB_DIRECTION_LTR;
hb_ot_math_glyph_variant_t variant[kMaxCachedSizeCount]; unsignedint count = kMaxCachedSizeCount;
hb_ot_math_get_glyph_variants(mHBFont, aGlyphID, direction, 0, &count,
variant); for (unsignedint i = 0; i < count; i++) {
mMathVariantCache.sizes[i] = variant[i].glyph;
}
// Try and cache the parts of the glyph assembly. // XXXfredw The structure of the Open Type Math table is a bit more general // than the one currently used by the nsMathMLChar code, so we try to fallback // in reasonable way. We use the approach of the copyComponents function in // github.com/mathjax/MathJax-dev/blob/master/fonts/OpenTypeMath/fontUtil.py // // The nsMathMLChar code can use at most 3 non extender pieces (aGlyphs[0], // aGlyphs[1] and aGlyphs[2]) and the extenders between these pieces should // all be the same (aGlyphs[4]). Also, the parts of vertical assembly are // stored from bottom to top in the Open Type MATH table while they are // stored from top to bottom in nsMathMLChar.
hb_ot_math_glyph_part_t parts[5];
count = std::size(parts); unsignedint offset = 0; if (hb_ot_math_get_glyph_assembly(mHBFont, aGlyphID, direction, offset,
&count, parts, NULL) > std::size(parts)) return; // Not supported: Too many pieces. if (count <= 0) return; // Not supported: No pieces.
// Count the number of non extender pieces
uint16_t nonExtenderCount = 0; for (uint16_t i = 0; i < count; i++) { if (!(parts[i].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)) {
nonExtenderCount++;
}
} if (nonExtenderCount > 3) { // Not supported: too many pieces return;
}
// Now browse the list of pieces
// 0 = look for a left/bottom glyph // 1 = look for an extender between left/bottom and mid // 2 = look for a middle glyph // 3 = look for an extender between middle and right/top // 4 = look for a right/top glyph // 5 = no more piece expected
uint8_t state = 0;
// First extender char found.
uint32_t extenderChar = 0;
for (uint16_t i = 0; i < count; i++) { bool isExtender = parts[i].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER;
uint32_t glyph = parts[i].glyph;
if ((state == 1 || state == 2) && nonExtenderCount < 3) { // do not try to find a middle glyph
state += 2;
}
if (isExtender) { if (!extenderChar) {
extenderChar = glyph;
mMathVariantCache.parts[3] = extenderChar;
} elseif (extenderChar != glyph) { // Not supported: different extenders return;
}
if (state == 0) { // or state == 1 // ignore left/bottom piece and multiple successive extenders
state = 1;
} elseif (state == 2) { // or state == 3 // ignore middle piece and multiple successive extenders
state = 3;
} elseif (state >= 4) { // Not supported: unexpected extender return;
}
continue;
}
if (state == 0) { // copy left/bottom part
mMathVariantCache.parts[aVertical ? 2 : 0] = glyph;
state = 1; continue;
}
if (state == 1 || state == 2) { // copy middle part
mMathVariantCache.parts[1] = glyph;
state = 3; continue;
}
if (state == 3 || state == 4) { // copy right/top part
mMathVariantCache.parts[aVertical ? 0 : 2] = glyph;
state = 5;
}
}
mMathVariantCache.arePartsValid = true;
}
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.