public static void MeasureString( this GlyphLayout glyphLayout, char[] textBuffer, int startAt, int len, out MeasuredStringBox strBox, float scale = 1) { //TODO: consider extension method List <GlyphPlan> outputGlyphPlans = glyphLayout._myGlyphPlans; outputGlyphPlans.Clear(); glyphLayout.Layout(textBuffer, startAt, len, outputGlyphPlans); // int j = outputGlyphPlans.Count; Typeface currentTypeface = glyphLayout.Typeface; if (j == 0) { //not scale strBox = new MeasuredStringBox(0, currentTypeface.Ascender * scale, currentTypeface.Descender * scale, currentTypeface.LineGap * scale); } //get last one GlyphPlan lastOne = outputGlyphPlans[j - 1]; strBox = new MeasuredStringBox((lastOne.x + lastOne.advX) * scale, currentTypeface.Ascender * scale, currentTypeface.Descender * scale, currentTypeface.LineGap * scale); }
public static MeasuredStringBox LayoutAndMeasureString( this GlyphLayout glyphLayout, char[] textBuffer, int startAt, int len, float fontSizeInPoints, bool snapToGrid = true) { //1. unscale layout, in design unit glyphLayout.Layout(textBuffer, startAt, len); //2. scale to specific font size Typeface typeface = glyphLayout.Typeface; float pxscale = typeface.CalculateScaleToPixelFromPointSize(fontSizeInPoints); //.... GenerateScaledGlyphPlans( glyphLayout, pxscale, snapToGrid, out float scaled_accumX); return(new MeasuredStringBox( scaled_accumX, typeface.Ascender * pxscale, typeface.Descender * pxscale, typeface.LineGap * pxscale, Typography.OpenFont.Extensions.TypefaceExtensions.CalculateRecommendLineSpacing(typeface) * pxscale)); }
public void DoLayout() { //user can use other native methods //to do the layout *** //the following code is how-to-layout with //our Typography lib // //then at this step //we calculate span size //resolve each font style _glyphLayout.FontSizeInPoints = FontSizeInPts; // _glyphLayout.EnableComposition = true; _glyphLayout.EnableLigature = true; int lineCount = _lines.Count; List <GlyphPlan> outputGlyphPlan = new List <GlyphPlan>(); GlyphPlanBuffer glyphPlanBuffer = new GlyphPlanBuffer(outputGlyphPlan); Typeface selectedTypeface = this.DefaultTypeface; for (int i = 0; i < lineCount; ++i) { EditableTextLine line = _lines[i]; List <IRun> runList = line.UnsageGetTextRunList(); int runCount = runList.Count; for (int r = 0; r < runCount; ++r) { TextRun tt = runList[r] as TextRun; if (tt == null) { continue; } //this is text run if (tt.IsMeasured) { continue; } // TextRunFontStyle fontStyle = tt.FontStyle; //resolve to actual font face TextBuffer buffer = tt.TextBuffer; char[] rawBuffer = buffer.UnsafeGetInternalBuffer(); int preCount = outputGlyphPlan.Count; _glyphLayout.Layout(selectedTypeface, rawBuffer, tt.StartAt, tt.Len, outputGlyphPlan); int postCount = outputGlyphPlan.Count; // tt.SetGlyphPlanSeq(new GlyphPlanSequence(glyphPlanBuffer, preCount, postCount - preCount)); tt.IsMeasured = true; // } } }
public static void GenerateGlyphPlans(this GlyphLayout glyphLayout, char[] textBuffer, int startAt, int len, List <GlyphPlan> userGlyphPlanList, List <UserCharToGlyphIndexMap> charToGlyphMapList) { //generate glyph plan based on its current setting glyphLayout.Layout(textBuffer, startAt, len, userGlyphPlanList); //note that we print to userGlyphPlanList //---------------- //3. user char to glyph index map if (charToGlyphMapList != null) { glyphLayout.ReadOutput(charToGlyphMapList); } }
//static void ConcatMeasureBox(ref float accumW, ref float accumH, ref MeasuredStringBox measureBox) //{ // accumW += measureBox.width; // float h = measureBox.CalculateLineHeight(); // if (h > accumH) // { // accumH = h; // } //} public static MeasuredStringBox LayoutAndMeasureString( this GlyphLayout glyphLayout, char[] textBuffer, int startAt, int len, float fontSizeInPoints, float limitW = -1,//-1 unlimit scaled width (px) bool snapToGrid = true) { //1. unscale layout, in design unit glyphLayout.Layout(textBuffer, startAt, len); //2. scale to specific font size Typeface typeface = glyphLayout.Typeface; float pxscale = typeface.CalculateScaleToPixelFromPointSize(fontSizeInPoints); //.... float scaled_accumX = 0; if (limitW < 0) { //no limit scaled_accumX = MeasureGlyphPlans( glyphLayout, pxscale, snapToGrid); return(new MeasuredStringBox( scaled_accumX, typeface.Ascender, typeface.Descender, typeface.LineGap, typeface.ClipedAscender, typeface.ClipedDescender, pxscale)); } else if (limitW > 0) { scaled_accumX = MeasureGlyphPlanWithLimitWidth( glyphLayout, pxscale, limitW, snapToGrid, out int stopAtChar); var mstrbox = new MeasuredStringBox( scaled_accumX, typeface.Ascender, typeface.Descender, typeface.LineGap, typeface.ClipedAscender, typeface.ClipedDescender, pxscale); mstrbox.StopAt = (ushort)stopAtChar; return(mstrbox); } else { return(new MeasuredStringBox( 0, typeface.Ascender, typeface.Descender, typeface.LineGap, typeface.ClipedAscender, typeface.ClipedDescender, pxscale)); } }
public void DoLayout() { //---------------- //TODO: use typography text service //it should be faster since it has glyph-plan cache //---------------- //user can use other native methods //to do the layout *** //the following code is how-to-layout with //our Typography lib // //then at this step //we calculate span size //resolve each font style _glyphLayout.EnableComposition = true; _glyphLayout.EnableLigature = true; int lineCount = _lines.Count; Typeface selectedTypeface = this.DefaultTypeface; float pxscale = selectedTypeface.CalculateScaleToPixelFromPointSize(this.FontSizeInPts); for (int i = 0; i < lineCount; ++i) { EditableTextLine line = _lines[i]; List <IRun> runList = line.UnsageGetTextRunList(); int runCount = runList.Count; for (int r = 0; r < runCount; ++r) { TextRun tt = runList[r] as TextRun; if (tt == null) { continue; } //this is text run if (tt.IsMeasured) { continue; } // TextRunFontStyle fontStyle = tt.FontStyle; //resolve to actual font face TextBuffer buffer = tt.TextBuffer; char[] rawBuffer = buffer.UnsafeGetInternalBuffer(); //TODO: review here again int preCount = _outputGlyphPlan.Count; _glyphLayout.Typeface = selectedTypeface; _glyphLayout.Layout(rawBuffer, tt.StartAt, tt.Len); _glyphLayout.GenerateUnscaledGlyphPlans(_outputGlyphPlan); //use pixel-scale-layout-engine to scale to specific font size //or scale it manually int postCount = _outputGlyphPlan.Count; // tt.SetGlyphPlanSeq(new GlyphPlanSequence(_outputGlyphPlan, preCount, postCount - preCount)); tt.IsMeasured = true; // } } }
public static void Layout(this GlyphLayout glyphLayout, char[] str, int startAt, int len, GlyphReadOutputDelegate readDel) { glyphLayout.Layout(str, startAt, len); glyphLayout.ReadOutput(readDel); }
public static void Layout(this GlyphLayout glyphLayout, char[] str, int startAt, int len, List <GlyphPlan> outputGlyphList) { glyphLayout.Layout(str, startAt, len); glyphLayout.ReadOutput(outputGlyphList); }