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 void MeasureString(char[] str, int startAt, int len, out int w, out int h) { //measure string //check if we use cache feature or not if (str.Length < 1) { w = h = 0; } _reusableMeasureBoxList.Clear(); //reset float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_fontSizeInPts); //NOET:at this moment, simple operation //may not be simple... //------------------- //input string may contain more than 1 script lang //user can parse it by other parser //but in this code, we use our Typography' parser //------------------- //user must setup the CustomBreakerBuilder before use int cur_startAt = startAt; float accumW = 0; float accumH = 0; foreach (BreakSpan breakSpan in BreakToLineSegments(str, startAt, len)) { _glyphLayout.Layout(str, breakSpan.startAt, breakSpan.len); // _reusableGlyphPlanList.Clear(); GlyphLayoutExtensions.GenerateGlyphPlans( _glyphLayout.ResultUnscaledGlyphPositions, pxscale, true, _reusableGlyphPlanList); //measure string size var result = new MeasuredStringBox( _reusableGlyphPlanList.AccumAdvanceX * pxscale, _currentTypeface.Ascender * pxscale, _currentTypeface.Descender * pxscale, _currentTypeface.LineGap * pxscale, Typography.OpenFont.Extensions.TypefaceExtensions.CalculateRecommendLineSpacing(_currentTypeface) * pxscale); // ConcatMeasureBox(ref accumW, ref accumH, ref result); } w = (int)System.Math.Round(accumW); h = (int)System.Math.Round(accumH); }
private void cmdMeasureTextSpan_Click(object sender, System.EventArgs e) { //set some Gdi+ props... g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.Clear(Color.White); //credit: //http://stackoverflow.com/questions/1485745/flip-coordinates-when-drawing-to-control g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -(float)300); // Translate the drawing area accordingly //-------------------------------- //textspan measurement sample //-------------------------------- _currentTextPrinter.HintTechnique = (HintTechnique)lstHintList.SelectedItem; _currentTextPrinter.PositionTechnique = (PositionTechnique)cmbPositionTech.SelectedItem; //render at specific pos float x_pos = 0, y_pos = 100; char[] textBuffer = txtInputChar.Text.ToCharArray(); //Example 1: this is a basic draw sample _currentTextPrinter.FillColor = Color.Black; _currentTextPrinter.TargetGraphics = g; _currentTextPrinter.DrawString( textBuffer, 0, textBuffer.Length, x_pos, y_pos ); // //-------------------------------------------------- //Example 2: print glyph plan to 'user' list-> then draw it (or hold it/ not draw) //you can create you own class to hold userGlyphPlans.*** //2.1 _reusableUnscaledGlyphPlan.Clear(); _currentTextPrinter.GenerateGlyphPlan(textBuffer, 0, textBuffer.Length, _reusableUnscaledGlyphPlan); //2.2 //and we can print the formatted glyph plan later. y_pos -= _currentTextPrinter.FontLineSpacingPx; _currentTextPrinter.FillColor = Color.Red; _currentTextPrinter.DrawFromGlyphPlans( new GlyphPlanSequence(_reusableUnscaledGlyphPlan), x_pos, y_pos ); //Example 3: MeasureString //TODO: review here again MeasuredStringBox strBox = _currentTextPrinter.GlyphLayoutMan.LayoutAndMeasureString( textBuffer, 0, textBuffer.Length, _currentTextPrinter.FontSizeInPoints); //draw line mark float x_pos2 = x_pos + strBox.width + 10; g.DrawRectangle(Pens.Red, x_pos, y_pos, strBox.width, strBox.LineSpaceInPx); g.DrawLine(Pens.Blue, x_pos, y_pos, x_pos2, y_pos); //baseline g.DrawLine(Pens.Green, x_pos, y_pos + strBox.DescendingInPx, x_pos2, y_pos + strBox.DescendingInPx); //descending g.DrawLine(Pens.Magenta, x_pos, y_pos + strBox.AscendingInPx, x_pos2, y_pos + strBox.AscendingInPx); //ascending _currentTextPrinter.FillColor = Color.Black; //transform back g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -(float)300); // Translate the drawing area accordingly }
public static float CalculateLineHeight(this MeasuredStringBox box, float scale = 1) { return(box.btbd); //return box.ascending - box.descending + box.lineGap; }
void RenderAndShowMeasureBox() { bool flipY = chkFlipY.Checked; //set some Gdi+ props... g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.Clear(Color.White); Typography.OpenFont.Typeface typeface = _currentTextPrinter.Typeface; Typography.OpenFont.TypefaceExtension2.UpdateAllCffGlyphBounds(typeface); float pxscale = typeface.CalculateScaleToPixelFromPointSize(_currentTextPrinter.FontSizeInPoints); int lineSpacing = (int)System.Math.Ceiling((double)typeface.CalculateLineSpacing(LineSpacingChoice.TypoMetric) * pxscale); if (flipY) { //credit: //http://stackoverflow.com/questions/1485745/flip-coordinates-when-drawing-to-control g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -500); // Translate the drawing area accordingly } //-------------------------------- //textspan measurement sample //-------------------------------- _currentTextPrinter.HintTechnique = (HintTechnique)lstHintList.SelectedItem; _currentTextPrinter.PositionTechnique = (PositionTechnique)cmbPositionTech.SelectedItem; _currentTextPrinter.UpdateGlyphLayoutSettings(); //render at specific pos float x_pos = 0, y_pos = lineSpacing * 2; char[] textBuffer = txtInputChar.Text.ToCharArray(); //Example 1: this is a basic draw sample _currentTextPrinter.FillColor = Color.Black; _currentTextPrinter.TargetGraphics = g; _currentTextPrinter.DrawString( textBuffer, 0, textBuffer.Length, x_pos, y_pos ); // //-------------------------------------------------- //Example 2: print glyph plan to 'user' list-> then draw it (or hold it/ not draw) //you can create you own class to hold userGlyphPlans.*** //2.1 _reusableUnscaledGlyphPlanList.Clear(); _currentTextPrinter.GenerateGlyphPlan(textBuffer, 0, textBuffer.Length, _reusableUnscaledGlyphPlanList); //2.2 //and we can print the formatted glyph plan later. y_pos -= lineSpacing;//next line _currentTextPrinter.FillColor = Color.Red; _currentTextPrinter.DrawFromGlyphPlans( new GlyphPlanSequence(_reusableUnscaledGlyphPlanList), x_pos, y_pos ); //Example 3: MeasureString UnscaledGlyphPlanList glyphPlans = new UnscaledGlyphPlanList(); _currentTextPrinter.GlyphLayoutMan.GenerateUnscaledGlyphPlans(glyphPlans); MeasuredStringBox strBox = _currentTextPrinter.GlyphLayoutMan.LayoutAndMeasureString( textBuffer, 0, textBuffer.Length, _currentTextPrinter.FontSizeInPoints); int j = glyphPlans.Count; float backup_xpos = x_pos; for (int i = 0; i < j; ++i) { UnscaledGlyphPlan glyphPlan = glyphPlans[i]; Typography.OpenFont.Glyph glyph = typeface.GetGlyphByIndex(glyphPlan.glyphIndex); // Typography.OpenFont.Bounds b = glyph.Bounds; // float xmin = b.XMin * pxscale; float ymin = b.YMin * pxscale; // float xmax = b.XMax * pxscale; float ymax = b.YMax * pxscale; // float glyph_x = x_pos + glyphPlan.OffsetX; g.DrawRectangle(Pens.Red, glyph_x + xmin, y_pos + ymin, xmax - xmin, ymax - ymin); x_pos += glyphPlan.AdvanceX * pxscale; } x_pos = backup_xpos; g.FillRectangle(Brushes.Red, new RectangleF(0, 0, 5, 5));//reference point(0,0) g.FillRectangle(Brushes.Green, new RectangleF(x_pos, y_pos, 3, 3)); float x_pos2 = x_pos + strBox.width + 10; g.DrawRectangle(Pens.Black, x_pos, y_pos + strBox.DescendingInPx, strBox.width, strBox.ClipHeightInPx); g.DrawRectangle(Pens.Red, x_pos, y_pos + strBox.DescendingInPx, strBox.width, strBox.LineSpaceInPx); g.DrawLine(Pens.Blue, x_pos, y_pos, x_pos2, y_pos); //baseline g.DrawLine(Pens.Green, x_pos, y_pos + strBox.DescendingInPx, x_pos2, y_pos + strBox.DescendingInPx); //descending g.DrawLine(Pens.Magenta, x_pos, y_pos + strBox.AscendingInPx, x_pos2, y_pos + strBox.AscendingInPx); //ascending ////------------ ////draw another line (for reference) y_pos -= lineSpacing;//next line _currentTextPrinter.FillColor = Color.Black; _currentTextPrinter.DrawFromGlyphPlans( new GlyphPlanSequence(_reusableUnscaledGlyphPlanList), x_pos, y_pos ); //transform back if (flipY) { g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -500); // Translate the drawing area accordingly } //--------- //txtMsgInfo.Text = "choice:" + choice.ToString() + "=" + lineSpacing.ToString(); }
private void cmdMeasureTextSpan_Click(object sender, System.EventArgs e) { //set some Gdi+ props... g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.Clear(Color.White); //credit: //http://stackoverflow.com/questions/1485745/flip-coordinates-when-drawing-to-control g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -(float)300); // Translate the drawing area accordingly //-------------------------------- //textspan measurement sample //-------------------------------- _currentTextPrinter.HintTechnique = (HintTechnique)lstHintList.SelectedItem; _currentTextPrinter.PositionTechnique = (PositionTechnique)cmbPositionTech.SelectedItem; //render at specific pos float x_pos = 0, y_pos = 100; char[] textBuffer = txtInputChar.Text.ToCharArray(); //Example 1: this is a basic draw sample _currentTextPrinter.FillColor = Color.Black; _currentTextPrinter.TargetGraphics = g; _currentTextPrinter.DrawString( textBuffer, 0, textBuffer.Length, x_pos, y_pos ); // //-------------------------------------------------- //Example 2: print glyph plan to 'user' list-> then draw it (or hold it/ not draw) //you can create you own class to hold userGlyphPlans.*** //2.1 _reusableUnscaledGlyphPlanList.Clear(); _currentTextPrinter.GenerateGlyphPlan(textBuffer, 0, textBuffer.Length, _reusableUnscaledGlyphPlanList); //2.2 //and we can print the formatted glyph plan later. y_pos -= _currentTextPrinter.FontLineSpacingPx; _currentTextPrinter.FillColor = Color.Red; _currentTextPrinter.DrawFromGlyphPlans( new GlyphPlanSequence(_reusableUnscaledGlyphPlanList), x_pos, y_pos ); //Example 3: MeasureString Typography.OpenFont.Typeface typeface = _currentTextPrinter.Typeface; UnscaledGlyphPlanList userGlyphPlans = new UnscaledGlyphPlanList(); _currentTextPrinter.GlyphLayoutMan.GenerateUnscaledGlyphPlans(userGlyphPlans); MeasuredStringBox strBox = new MeasuredStringBox(); throw new System.NotSupportedException(); //_currentTextPrinter.GlyphLayoutMan.LayoutAndMeasureString( // textBuffer, 0, textBuffer.Length, // _currentTextPrinter.FontSizeInPoints, // true, // userGlyphPlans); float x_pos2 = x_pos + strBox.width + 10; g.DrawRectangle(Pens.Red, x_pos, y_pos + strBox.descending, strBox.width, strBox.CalculateLineHeight()); g.DrawLine(Pens.Blue, x_pos, y_pos, x_pos2, y_pos); //baseline g.DrawLine(Pens.Green, x_pos, y_pos + strBox.descending, x_pos2, y_pos + strBox.descending); //descending g.DrawLine(Pens.Magenta, x_pos, y_pos + strBox.ascending, x_pos2, y_pos + strBox.ascending); //ascending Typography.OpenFont.TypefaceExtension2.UpdateAllCffGlyphBounds(typeface); float pxscale = typeface.CalculateScaleToPixelFromPointSize(_currentTextPrinter.FontSizeInPoints); int j = userGlyphPlans.Count; for (int i = 0; i < j; ++i) { UnscaledGlyphPlan glyphPlan = userGlyphPlans[i]; Typography.OpenFont.Glyph glyph = typeface.GetGlyphByIndex(glyphPlan.glyphIndex); // Typography.OpenFont.Bounds b = glyph.Bounds; // float xmin = b.XMin * pxscale; float ymin = b.YMin * pxscale; // float xmax = b.XMax * pxscale; float ymax = b.YMax * pxscale; // float glyph_x = x_pos + glyphPlan.OffsetX; g.DrawRectangle(Pens.Red, glyph_x + xmin, y_pos + ymin, xmax - xmin, ymax - ymin); } //------------ _currentTextPrinter.FillColor = Color.Black; //transform back g.ScaleTransform(1.0F, -1.0F); // Flip the Y-Axis g.TranslateTransform(0.0F, -(float)300); // Translate the drawing area accordingly }