private void InitGlyphPointsAndContourEnds(char c) { try { using (FileStream fs = File.OpenRead(ttfPath)) { OpenFontReader reader = new OpenFontReader(); Typeface typeface = reader.Read(fs); var builder = new GlyphPathBuilder(typeface); builder.BuildFromGlyphIndex(typeface.LookupIndex(c), 300); var txToPath = new GlyphTranslatorToPath(); var writablePath = new WritablePath(); txToPath.SetOutput(writablePath); builder.ReadShapes(txToPath); var curveFlattener = new SimpleCurveFlattener(); float[] flattenPoints = curveFlattener.Flatten( writablePath._points, out _contourEnds); _glyphPoints2 = flattenPoints; } } catch (Exception) { ClearGlyphData(); pnlGlyph.Invalidate(); } }
/// <summary> /// generate glyph run into a given textRun /// </summary> /// <param name="outputTextRun"></param> /// <param name="charBuffer"></param> /// <param name="start"></param> /// <param name="len"></param> public void GenerateGlyphRuns(TextRun outputTextRun, char[] charBuffer, int start, int len) { // layout glyphs with selected layout technique float sizeInPoints = this.FontSizeInPoints; outputTextRun.typeface = this.CurrentTypeFace; outputTextRun.sizeInPoints = sizeInPoints; //in this version we store original glyph into the mesh collection //and then we scale it later, so I just specific font size=0 (you can use any value) _glyphMeshCollection.SetCacheInfo(this.CurrentTypeFace, 0, this.HintTechnique); outputGlyphPlans.Clear(); glyphLayout.Typeface = this.CurrentTypeFace; glyphLayout.GenerateGlyphPlans(charBuffer, start, len, outputGlyphPlans, null); // render each glyph int planCount = outputGlyphPlans.Count; for (var i = 0; i < planCount; ++i) { pathTranslator.Reset(); //---- //glyph path //---- GlyphPlan glyphPlan = outputGlyphPlans[i]; // //1. check if we have this glyph in cache? //if yes, not need to build it again ProcessedGlyph processGlyph; float[] tessData = null; if (!_glyphMeshCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out processGlyph)) { //if not found the create a new one and register it var writablePath = new WritablePath(); pathTranslator.SetOutput(writablePath); currentGlyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, sizeInPoints); currentGlyphPathBuilder.ReadShapes(pathTranslator); //------- //do tess int[] endContours; float[] flattenPoints = _curveFlattener.Flatten(writablePath._points, out endContours); int nTessElems; tessData = _tessTool.TessPolygon(flattenPoints, endContours, out nTessElems); //------- processGlyph = new ProcessedGlyph(tessData, (ushort)nTessElems); _glyphMeshCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, processGlyph); } outputTextRun.AddGlyph( new GlyphRun(glyphPlan, processGlyph.tessData, processGlyph.tessNElements)); } }
private void FormTess_Load(object sender, EventArgs e) { g = this.pnlGlyph.CreateGraphics(); pnlGlyph.MouseDown += PnlGlyph_MouseDown; //string testFont = "d:\\WImageTest\\DroidSans.ttf"; string testFont = "c:\\Windows\\Fonts\\Tahoma.ttf"; using (FileStream fs = new FileStream(testFont, FileMode.Open, FileAccess.Read)) { OpenFontReader reader = new OpenFontReader(); Typeface typeface = reader.Read(fs); //-- var builder = new Typography.Rendering.GlyphPathBuilder(typeface); builder.BuildFromGlyphIndex(typeface.LookupIndex('a'), 256); var txToPath = new GlyphTranslatorToPath(); var writablePath = new WritablePath(); txToPath.SetOutput(writablePath); builder.ReadShapes(txToPath); //from contour to var curveFlattener = new SimpleCurveFlattener(); float[] flattenPoints = curveFlattener.Flatten(writablePath._points, out contourEnds); glyphPoints2 = flattenPoints; ////-------------------------------------- ////raw glyph points //int j = glyphPoints.Length; //float scale = typeface.CalculateToPixelScaleFromPointSize(256); //glyphPoints2 = new float[j * 2]; //int n = 0; //for (int i = 0; i < j; ++i) //{ // GlyphPointF pp = glyphPoints[i]; // glyphPoints2[n] = pp.X * scale; // n++; // glyphPoints2[n] = pp.Y * scale; // n++; //} ////-------------------------------------- } }
/// <summary> /// generate glyph run into a given textRun /// </summary> /// <param name="outputTextRun"></param> /// <param name="charBuffer"></param> /// <param name="start"></param> /// <param name="len"></param> public void GenerateGlyphRuns(TextRun outputTextRun, char[] charBuffer, int start, int len) { // layout glyphs with selected layout technique float sizeInPoints = this.FontSizeInPoints; outputTextRun.typeface = this.Typeface; outputTextRun.sizeInPoints = sizeInPoints; //in this version we store original glyph into the mesh collection //and then we scale it later, so I just specific font size=0 (you can use any value) _glyphMeshCollection.SetCacheInfo(this.Typeface, 0, this.HintTechnique); GlyphLayoutMan.Typeface = this.Typeface; GlyphLayoutMan.Layout(charBuffer, start, len); float pxscale = this.Typeface.CalculateScaleToPixelFromPointSize(sizeInPoints); _resuableGlyphPlanList.Clear(); GenerateGlyphPlan(charBuffer, 0, charBuffer.Length, _resuableGlyphPlanList); // render each glyph int planCount = _resuableGlyphPlanList.Count; for (var i = 0; i < planCount; ++i) { _pathTranslator.Reset(); //---- //glyph path //---- UnscaledGlyphPlan glyphPlan = _resuableGlyphPlanList[i]; // //1. check if we have this glyph in cache? //if yes, not need to build it again ProcessedGlyph processGlyph; float[] tessData = null; if (!_glyphMeshCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out processGlyph)) { //if not found the create a new one and register it var writablePath = new WritablePath(); _pathTranslator.SetOutput(writablePath); _currentGlyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, sizeInPoints); _currentGlyphPathBuilder.ReadShapes(_pathTranslator); //------- //do tess int[] endContours; float[] flattenPoints = _curveFlattener.Flatten(writablePath._points, out endContours); tessData = _tessTool.TessAsTriVertexArray(flattenPoints, endContours, out int vertexCount); processGlyph = new ProcessedGlyph(tessData, (ushort)vertexCount); _glyphMeshCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, processGlyph); } outputTextRun.AddGlyph( new GlyphRun(glyphPlan, processGlyph.tessData, processGlyph.vertextCount)); } }
private void TextBox1_KeyUp(object sender, KeyEventArgs e) { string oneChar = this.textBox1.Text.Trim(); if (string.IsNullOrEmpty(oneChar)) { return; } // char selectedChar = oneChar[0]; // // //selectedChar = 'e'; if (_g == null) { _g = this.pnlGlyph.CreateGraphics(); } _g.Clear(Color.White); //string testFont = "d:\\WImageTest\\DroidSans.ttf"; //string testFont = "c:\\Windows\\Fonts\\Tahoma.ttf"; string testFont = "d:\\WImageTest\\Alfa_Slab.ttf"; using (FileStream fs = new FileStream(testFont, FileMode.Open, FileAccess.Read)) { OpenFontReader reader = new OpenFontReader(); Typeface typeface = reader.Read(fs); //-- var builder = new Typography.Contours.GlyphPathBuilder(typeface); builder.BuildFromGlyphIndex(typeface.LookupIndex(selectedChar), 300); var txToPath = new GlyphTranslatorToPath(); var writablePath = new WritablePath(); txToPath.SetOutput(writablePath); builder.ReadShapes(txToPath); //from contour to var curveFlattener = new SimpleCurveFlattener(); float[] flattenPoints = curveFlattener.Flatten(writablePath._points, out _contourEnds); _glyphPoints2 = flattenPoints; ////-------------------------------------- ////raw glyph points //int j = glyphPoints.Length; //float scale = typeface.CalculateToPixelScaleFromPointSize(256); //glyphPoints2 = new float[j * 2]; //int n = 0; //for (int i = 0; i < j; ++i) //{ // GlyphPointF pp = glyphPoints[i]; // glyphPoints2[n] = pp.X * scale; // n++; // glyphPoints2[n] = pp.Y * scale; // n++; //} ////-------------------------------------- } DrawOutput(); }
void UpdateOutput() { string oneChar = this.textBox1.Text.Trim(); if (string.IsNullOrEmpty(oneChar)) { return; } // char selectedChar = oneChar[0]; // // //selectedChar = 'e'; if (_g == null) { _g = this.panel1.CreateGraphics(); } _g.Clear(Color.White); //------- //string testFont = "c:\\Windows\\Fonts\\Tahoma.ttf"; //string testFont = @"D:\projects\Typography\Demo\Windows\TestFonts\SourceSerifPro-Regular.otf"; string testFont = @"D:\projects\Typography\Demo\Windows\TestFonts\SourceSansPro-Light.ttf"; //string testFont = @"D:\projects\Typography\Demo\Windows\TestFonts\Sarabun-Regular.ttf"; using (FileStream fs = new FileStream(testFont, FileMode.Open, FileAccess.Read)) { OpenFontReader reader = new OpenFontReader(); Typeface typeface = reader.Read(fs); //-- var builder = new Typography.Contours.GlyphPathBuilder(typeface); builder.BuildFromGlyphIndex(typeface.LookupIndex(selectedChar), 300); var txToPath = new GlyphTranslatorToPath(); var writablePath = new WritablePath(); txToPath.SetOutput(writablePath); builder.ReadShapes(txToPath); //------ // //**flatten contour before send to Tess*** var curveFlattener = new SimpleCurveFlattener(); if (rdoSimpleIncCurveFlattener.Checked) { if (int.TryParse(txtIncrementalTessStep.Text, out int incSteps)) { curveFlattener.IncrementalStep = incSteps; } curveFlattener.FlattenMethod = CurveFlattenMethod.Inc; } else { if (double.TryParse(txtDivAngleTolerenceEpsilon.Text, out double angleTolerenceEpsilon)) { //convert degree to rad curveFlattener.DivCurveAngleTolerenceEpsilon = DegToRad(angleTolerenceEpsilon); } if (int.TryParse(txtDivCurveRecursiveLimit.Text, out int recuvesiveLim)) { curveFlattener.DivCurveRecursiveLimit = recuvesiveLim; } curveFlattener.FlattenMethod = CurveFlattenMethod.Div; } _glyphPoints2 = curveFlattener.Flatten(writablePath._points, out _contourEnds); ////-------------------------------------- ////raw glyph points //int j = glyphPoints.Length; //float scale = typeface.CalculateToPixelScaleFromPointSize(256); //glyphPoints2 = new float[j * 2]; //int n = 0; //for (int i = 0; i < j; ++i) //{ // GlyphPointF pp = glyphPoints[i]; // glyphPoints2[n] = pp.X * scale; // n++; // glyphPoints2[n] = pp.Y * scale; // n++; //} ////-------------------------------------- } DrawOutput(); }