public void GetOffset(int index, out short offsetX, out short offsetY) { GlyphPos pos = _glyphPosList[index]; offsetX = pos.xoffset; offsetY = pos.yoffset; }
public void AppendGlyphAdvance(int index, short appendAdvX, short appendAdvY) { GlyphPos pos = _glyphPosList[index]; pos.advanceW += appendAdvX;//TODO: review for appendY _glyphPosList[index] = pos; }
public ushort GetGlyph(int index, out ushort advW) { GlyphPos pos = _glyphPosList[index]; advW = (ushort)pos.advanceW; return(pos.glyphIndex); }
public void AppendGlyphOffset(int index, short appendOffsetX, short appendOffsetY) { GlyphPos existing = _glyphPosList[index]; existing.xoffset += appendOffsetX; existing.yoffset += appendOffsetY; _glyphPosList[index] = existing; }
public ushort GetGlyph(int index, out short offsetX, out short offsetY, out short advW) { GlyphPos pos = _glyphs[index]; offsetX = pos.xoffset; offsetY = pos.yoffset; advW = pos.advanceW; return(pos.glyphIndex); }
public ushort GetGlyph(int index, out short inputOffset, out short offsetX, out short offsetY, out short advW) { GlyphPos pos = _glyphPosList[index]; offsetX = pos.xoffset; offsetY = pos.yoffset; advW = pos.advanceW; inputOffset = pos.o_offset; return(pos.glyphIndex); }
/// <summary> /// read latest layout output /// </summary> /// <param name="glyphLayout"></param> /// <param name="readDel"></param> public static void ReadOutput(this GlyphLayout glyphLayout, GlyphReadOutputDelegate readDel) { Typeface typeface = glyphLayout.Typeface; List <GlyphPos> glyphPositions = glyphLayout._glyphPositions; //3.read back int finalGlyphCount = glyphPositions.Count; int cx = 0; short cy = 0; PositionTechnique posTech = glyphLayout.PositionTechnique; ushort prev_index = 0; for (int i = 0; i < finalGlyphCount; ++i) { GlyphPos glyphPos = glyphPositions[i]; //---------------------------------- switch (posTech) { default: throw new NotSupportedException(); case PositionTechnique.None: readDel(i, new GlyphPlan(glyphPos.glyphIndex, cx, cy, glyphPos.advWidth)); break; case PositionTechnique.OpenFont: readDel(i, new GlyphPlan( glyphPos.glyphIndex, cx + glyphPos.xoffset, (short)(cy + glyphPos.yoffset), glyphPos.advWidth)); break; case PositionTechnique.Kerning: if (i > 0) { cx += typeface.GetKernDistance(prev_index, glyphPos.glyphIndex); } readDel(i, new GlyphPlan( prev_index = glyphPos.glyphIndex, cx, cy, glyphPos.advWidth)); break; } cx += glyphPos.advWidth; } }
/// <summary> /// read latest layout output into outputGlyphPlanList /// </summary> public static void ReadOutput(this GlyphLayout glyphLayout, List <GlyphPlan> outputGlyphPlanList) { GlyphPosStream glyphPositions = glyphLayout._glyphPositions; //from opentype's layout result, int finalGlyphCount = glyphPositions.Count; //------------------------ IPixelScaleLayout pxscaleLayout = glyphLayout.PxScaleLayout; if (pxscaleLayout != null) { //use custom pixel scale layout engine pxscaleLayout.SetFont(glyphLayout.Typeface, glyphLayout.FontSizeInPoints); pxscaleLayout.Layout(glyphPositions, outputGlyphPlanList); } else { //default scale float pxscale = glyphLayout.PixelScale; double cx = 0; short cy = 0; for (int i = 0; i < finalGlyphCount; ++i) { GlyphPos glyph_pos = glyphPositions[i]; float advW = glyph_pos.advanceW * pxscale; float exact_x = (float)(cx + glyph_pos.OffsetX * pxscale); float exact_y = (float)(cy + glyph_pos.OffsetY * pxscale); outputGlyphPlanList.Add(new GlyphPlan( glyph_pos.glyphIndex, exact_x, exact_y, advW)); cx += advW; } } }
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; } }