void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { return; } if (chars == NULL || offset < 0 || count < 0) { success = LE_ILLEGAL_ARGUMENT_ERROR; return; } LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); CanonMarkFilter filter(gdefTable, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); KernTable kt(kernTable, success); kt.process(glyphStorage, success); } // default is no adjustments return; }
// This is the same as LayoutEngline::adjustGlyphPositions() except that it doesn't call adjustMarkGlyphs void ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { return; } if (chars == NULL || offset < 0 || count < 0) { success = LE_ILLEGAL_ARGUMENT_ERROR; return; } if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); KernTable kt(kernTable, success); kt.process(glyphStorage, success); } // default is no adjustments return; }
// apply GPOS table, if any void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { return; } if (chars == NULL || offset < 0 || count < 0) { success = LE_ILLEGAL_ARGUMENT_ERROR; return; } le_int32 glyphCount = glyphStorage.getGlyphCount(); if (glyphCount == 0) { return; } if (!fGPOSTable.isEmpty()) { GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount); le_int32 i; if (adjustments == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; return; } #if 0 // Don't need to do this if we allocate // the adjustments array w/ new... for (i = 0; i < glyphCount; i += 1) { adjustments->setXPlacement(i, 0); adjustments->setYPlacement(i, 0); adjustments->setXAdvance(i, 0); adjustments->setYAdvance(i, 0); adjustments->setBaseOffset(i, -1); } #endif if (!fGPOSTable.isEmpty()) { if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) { fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); } else { fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); } } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); KernTable kt(kernTable, success); kt.process(glyphStorage, success); } float xAdjust = 0, yAdjust = 0; for (i = 0; i < glyphCount; i += 1) { float xAdvance = adjustments->getXAdvance(i); float yAdvance = adjustments->getYAdvance(i); float xPlacement = 0; float yPlacement = 0; #if 0 // This is where separate kerning adjustments // should get applied. xAdjust += xKerning; yAdjust += yKerning; #endif for (le_int32 base = i; base >= 0; base = adjustments->getBaseOffset(base)) { xPlacement += adjustments->getXPlacement(base); yPlacement += adjustments->getYPlacement(base); } xPlacement = fFontInstance->xUnitsToPoints(xPlacement); yPlacement = fFontInstance->yUnitsToPoints(yPlacement); glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success); xAdjust += fFontInstance->xUnitsToPoints(xAdvance); yAdjust += fFontInstance->yUnitsToPoints(yAdvance); } glyphStorage.adjustPosition(glyphCount, xAdjust, -yAdjust, success); delete adjustments; } else { // if there was no GPOS table, maybe there's non-OpenType kerning we can use LayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success); } LEGlyphID zwnj = fFontInstance->mapCharToGlyph(0x200C); if (zwnj != 0x0000) { for (le_int32 g = 0; g < glyphCount; g += 1) { LEGlyphID glyph = glyphStorage[g]; if (glyph == zwnj) { glyphStorage[g] = LE_SET_GLYPH(glyph, 0xFFFF); } } } #if 0 // Don't know why this is here... LE_DELETE_ARRAY(fFeatureTags); fFeatureTags = NULL; #endif }