void UpdateLayoutPlan() { GlyphLayoutPlanContext context = _layoutPlanCollection.GetPlanOrCreate(this._typeface, this._scriptLang); this._gpos = context._glyphPos; this._gsub = context._glyphSub; _needPlanUpdate = false; }
public GlyphLayoutPlanContext(GlyphSubstitution glyphSub, GlyphSetPosition glyphPos) { _glyphSub = glyphSub; _glyphPos = glyphPos; }
public GlyphLayoutPlanContext(GlyphSubstitution _glyphSub, GlyphSetPosition glyphPos) { this._glyphSub = _glyphSub; this._glyphPos = glyphPos; }
List <ushort> inputGlyphs = new List <ushort>(); //not thread safe*** public void Layout(Typeface typeface, float size, char[] str, List <GlyphPlan> glyphPlanBuffer) { //---------------------------------------------- //1. convert char[] to glyph[] //2. send to shaping engine //3. layout position of each glyph //---------------------------------------------- //check if we have created a glyph cache for the typeface GlyphsCache glyphCache; if (!_glyphCaches.TryGetValue(typeface, out glyphCache)) { //create new glyphCache = new GlyphsCache(typeface); _glyphCaches.Add(typeface, glyphCache); } //---------------------------------------------- int j = str.Length; inputGlyphs.Clear(); for (int i = 0; i < j; ++i) { //1. convert char[] to glyphIndex[] inputGlyphs.Add((ushort)typeface.LookupIndex(str[i])); } //---------------------------------------------- //glyph substitution if (j > 1) { GlyphSubStitution glyphSubstitution = new GlyphSubStitution(typeface, this.ScriptLang.shortname); glyphSubstitution.EnableLigation = this.EnableLigature; glyphSubstitution.DoSubstitution(inputGlyphs); } //---------------------------------------------- //glyph position j = inputGlyphs.Count; List <GlyphPos> glyphPositions = new List <GlyphPos>(j); for (int i = 0; i < j; ++i) { ushort glyIndex = inputGlyphs[i]; glyphPositions.Add(new GlyphPos( glyIndex, typeface.GetGlyphByIndex(glyIndex).GlyphClass, typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex)) ); } PositionTecnhique posTech = this.PositionTechnique; if (j > 1 && posTech == PositionTecnhique.OpenFont) { GlyphSetPosition glyphSetPos = new GlyphSetPosition(typeface, ScriptLang.shortname); glyphSetPos.DoGlyphPosition(glyphPositions); } //-------------- float scale = typeface.CalculateFromPointToPixelScale(size); float cx = 0; float cy = 0; j = inputGlyphs.Count; for (int i = 0; i < j; ++i) { ushort glyIndex = inputGlyphs[i]; GlyphPlan glyphPlan = new GlyphPlan(glyIndex); glyphPlanBuffer.Add(glyphPlan); //this advWidth in font design unit float advWidth = typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex) * scale; //---------------------------------- switch (posTech) { case PositionTecnhique.None: { glyphPlan.x = cx; glyphPlan.y = cy; glyphPlan.advX = advWidth; } break; case PositionTecnhique.OpenFont: { GlyphPos gpos_offset = glyphPositions[i]; glyphPlan.x = cx + (scale * gpos_offset.xoffset); glyphPlan.y = cy + (scale * gpos_offset.yoffset); glyphPlan.advX = advWidth; } break; case PositionTecnhique.Kerning: { glyphPlan.x = cx; glyphPlan.y = cy; glyphPlan.advX = advWidth; if (i > 0) { advWidth += typeface.GetKernDistance(glyphPlanBuffer[i - 1].glyphIndex, glyphPlanBuffer[i].glyphIndex) * scale; } } break; } cx += advWidth; } }