public PathRenderVx CreatePathRenderVx(VertexStore vxs) { double prevX = 0; double prevY = 0; double prevMoveToX = 0; double prevMoveToY = 0; _xylist.Clear(); _figs.Clear(); //TODO: reivew here //about how to reuse this list //result... int index = 0; VertexCmd cmd; double x, y; while ((cmd = vxs.GetVertex(index++, out x, out y)) != VertexCmd.NoMore) { switch (cmd) { case PixelFarm.CpuBlit.VertexCmd.MoveTo: prevMoveToX = prevX = x; prevMoveToY = prevY = y; _xylist.Add((float)x); _xylist.Add((float)y); break; case PixelFarm.CpuBlit.VertexCmd.LineTo: _xylist.Add((float)x); _xylist.Add((float)y); prevX = x; prevY = y; break; case PixelFarm.CpuBlit.VertexCmd.Close: { //from current point _xylist.Add((float)prevMoveToX); _xylist.Add((float)prevMoveToY); prevX = prevMoveToX; prevY = prevMoveToY; //----------- Figure newfig = new Figure(_xylist.ToArray()); newfig.IsClosedFigure = true; _figs.Add(newfig); //----------- _xylist.Clear(); //clear temp list } break; case VertexCmd.CloseAndEndFigure: { //from current point _xylist.Add((float)prevMoveToX); _xylist.Add((float)prevMoveToY); prevX = prevMoveToX; prevY = prevMoveToY; // Figure newfig = new Figure(_xylist.ToArray()); newfig.IsClosedFigure = true; _figs.Add(newfig); //----------- _xylist.Clear(); //clear temp list } break; case PixelFarm.CpuBlit.VertexCmd.NoMore: goto EXIT_LOOP; default: throw new System.NotSupportedException(); } } EXIT_LOOP: if (_figs.Count == 0) { Figure newfig = new Figure(_xylist.ToArray()); newfig.IsClosedFigure = false; return(new PathRenderVx(newfig)); } // if (_xylist.Count > 1) { _xylist.Add((float)prevMoveToX); _xylist.Add((float)prevMoveToY); prevX = prevMoveToX; prevY = prevMoveToY; // Figure newfig = new Figure(_xylist.ToArray()); newfig.IsClosedFigure = true; //? _figs.Add(newfig); } if (_figs.Count == 1) { Figure fig = _figs[0]; _figs.Clear(); return(new PathRenderVx(fig)); } else { MultiFigures multiFig = new MultiFigures(_figs.ToArray()); _figs.Clear(); return(new PathRenderVx(multiFig)); } }
void DrawOutput(Painter painter, Typeface typeface, char selectedChar) { painter.Clear(Color.White); //this is a demo. // float fontSizeInPts = 300; _glyphPathBuilder.BuildFromGlyphIndex(typeface.GetGlyphIndex(selectedChar), fontSizeInPts); var prevColor = painter.StrokeColor; painter.StrokeColor = Color.Black; using (Tools.BorrowVxs(out var v1)) using (Tools.BorrowCurveFlattener(out var flattener)) { _glyphPathBuilder.ReadShapes(_tovxs); //config if (rdoSimpleIncCurveFlattener.Checked) { flattener.ApproximationMethod = CurveApproximationMethod.Inc; if (int.TryParse(txtIncrementalTessStep.Text, out int stepCount)) { if (stepCount < 0) { //auto calculate inc step count flattener.IncUseFixedStep = false; } else { //fix manual inc step count flattener.IncUseFixedStep = true; flattener.IncStepCount = stepCount; } } } else { flattener.ApproximationMethod = CurveApproximationMethod.Div; if (double.TryParse(txtDivAngleTolerenceEpsilon.Text, out double angleTolerance)) { flattener.AngleTolerance = angleTolerance; } if (byte.TryParse(txtDivCurveRecursiveLimit.Text, out byte recursiveLim)) { flattener.RecursiveLimit = recursiveLim; } } _tovxs.WriteOutput(v1, flattener); //write content from GlyphTranslator to v1 painter.Fill(v1, PixelFarm.Drawing.KnownColors.Gray); _tovxs.Reset(); //tess the vxs FigureBuilder figBuilder = new FigureBuilder(); FigureContainer container = figBuilder.Build(v1); TessTriangleTechnique tessTechnique = TessTriangleTechnique.DrawElement; if (container.IsSingleFigure) { Figure figure = container._figure; if (rdoTessSGI.Checked) { //coords of tess triangles switch (tessTechnique) { case TessTriangleTechnique.DrawArray: { DrawTessTriangles(painter, figure.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawArray)); } break; case TessTriangleTechnique.DrawElement: { float[] tessArea = figure.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawElement); ushort[] index = figure.GetAreaIndexList(); DrawTessTriangles(painter, tessArea, index); } break; } } else { if (chkShowContourAnalysis.Checked) { ContourAnalyzer analyzer1 = new ContourAnalyzer(); IntermediateOutline outline = analyzer1.CreateIntermediateOutline(v1); var dbugVisualizer = new PixelFarm.GlyphDebugContourVisualizer(); dbugVisualizer.SetPainter(painter); dbugVisualizer.Scale = _typeface.CalculateScaleToPixelFromPointSize(fontSizeInPts); dbugVisualizer.WalkCentroidLine(outline); } else { //Poly2Tri List <Poly2Tri.Polygon> polygons = figure.GetTrianglulatedArea(false); //draw polygon painter.StrokeColor = Color.Red; DrawPoly2TriPolygon(painter, polygons); } } } else { MultiFigures multiFig = container._multiFig; if (rdoTessSGI.Checked) { switch (tessTechnique) { case TessTriangleTechnique.DrawArray: { DrawTessTriangles(painter, multiFig.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawArray)); } break; case TessTriangleTechnique.DrawElement: { float[] tessArea = multiFig.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawElement); ushort[] index = multiFig.GetAreaIndexList(); DrawTessTriangles(painter, tessArea, index); } break; } } else { if (chkShowContourAnalysis.Checked) { ContourAnalyzer analyzer1 = new ContourAnalyzer(); IntermediateOutline outline = analyzer1.CreateIntermediateOutline(v1); var dbugVisualizer = new PixelFarm.GlyphDebugContourVisualizer(); dbugVisualizer.SetPainter(painter); dbugVisualizer.Scale = _typeface.CalculateScaleToPixelFromPointSize(fontSizeInPts); dbugVisualizer.WalkCentroidLine(outline); } else { List <Poly2Tri.Polygon> polygons = multiFig.GetTrianglulatedArea(false); painter.StrokeColor = Color.Red; DrawPoly2TriPolygon(painter, polygons); } } } } painter.StrokeColor = prevColor; //------------- //tess //if (rdoTessSGI.Checked) //{ // //SGI Tess Lib // if (!_tessTool.TessPolygon(polygon1, _contourEnds)) // { // return; // } // //1. // List<ushort> indexList = _tessTool.TessIndexList; // //2. // List<TessVertex2d> tempVertexList = _tessTool.TempVertexList; // //3. // int vertexCount = indexList.Count; // //----------------------------- // int orgVertexCount = polygon1.Length / 2; // float[] vtx = new float[vertexCount * 2];//*** // int n = 0; // for (int p = 0; p < vertexCount; ++p) // { // ushort index = indexList[p]; // if (index >= orgVertexCount) // { // //extra coord (newly created) // TessVertex2d extraVertex = tempVertexList[index - orgVertexCount]; // vtx[n] = (float)extraVertex.x; // vtx[n + 1] = (float)extraVertex.y; // } // else // { // //original corrd // vtx[n] = (float)polygon1[index * 2]; // vtx[n + 1] = (float)polygon1[(index * 2) + 1]; // } // n += 2; // } // //----------------------------- // //draw tess result // int j = vtx.Length; // for (int i = 0; i < j;) // { // var p0 = new PointF(vtx[i], vtx[i + 1]); // var p1 = new PointF(vtx[i + 2], vtx[i + 3]); // var p2 = new PointF(vtx[i + 4], vtx[i + 5]); // _g.DrawLine(Pens.Red, p0, p1); // _g.DrawLine(Pens.Red, p1, p2); // _g.DrawLine(Pens.Red, p2, p0); // i += 6; // } //} //else //{ // List<Poly2Tri.Polygon> outputPolygons = new List<Poly2Tri.Polygon>(); // Poly2TriExampleHelper.Triangulate(polygon1, contourEndIndices, flipYAxis, outputPolygons); // foreach (Poly2Tri.Polygon polygon in outputPolygons) // { // foreach (Poly2Tri.DelaunayTriangle tri in polygon.Triangles) // { // Poly2Tri.TriangulationPoint p0 = tri.P0; // Poly2Tri.TriangulationPoint p1 = tri.P1; // Poly2Tri.TriangulationPoint p2 = tri.P2; // _g.DrawLine(Pens.Red, (float)p0.X, (float)p0.Y, (float)p1.X, (float)p1.Y); // _g.DrawLine(Pens.Red, (float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y); // _g.DrawLine(Pens.Red, (float)p2.X, (float)p2.Y, (float)p0.X, (float)p0.Y); // } // } //} }
void DrawOutput(Painter painter, Typeface typeface, char selectedChar) { #if DEBUG painter.Clear(Color.White); //this is a demo. // float fontSizeInPts = 300; _glyphPathBuilder.BuildFromGlyphIndex(typeface.GetGlyphIndex(selectedChar), fontSizeInPts); var prevColor = painter.StrokeColor; painter.StrokeColor = Color.Black; using (Tools.BorrowVxs(out var v1)) { _glyphPathBuilder.ReadShapes(_tovxs); _tovxs.WriteOutput(v1); //write content from GlyphTranslator to v1 painter.Fill(v1, KnownColors.Gray); _tovxs.Reset(); //tess the vxs FigureBuilder figBuilder = new FigureBuilder(); FigureContainer container = figBuilder.Build(v1); TessTriangleTechnique tessTechnique = TessTriangleTechnique.DrawElement; if (container.IsSingleFigure) { Figure figure = container._figure; if (Tess == GlyphDemo_TessTech.SgiTess) { //coords of tess triangles switch (tessTechnique) { case TessTriangleTechnique.DrawArray: { painter.dbugDrawTessTriangles(figure.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawArray)); } break; case TessTriangleTechnique.DrawElement: { float[] tessArea = figure.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawElement); ushort[] index = figure.GetAreaIndexList(); painter.dbugDrawTessTriangles(tessArea, index); } break; } } else { if (ContourAnalysis) { ContourAnalyzer analyzer1 = new ContourAnalyzer(); IntermediateOutline outline = analyzer1.CreateIntermediateOutline(v1); GlyphDebugContourVisualizer dbugVisualizer = new GlyphDebugContourVisualizer(); dbugVisualizer.SetPainter(painter); dbugVisualizer.Scale = _typeface.CalculateScaleToPixelFromPointSize(fontSizeInPts); dbugVisualizer.WalkCentroidLine(outline); } else { //Poly2Tri List <Poly2Tri.Polygon> polygons = figure.GetTrianglulatedArea(false); //draw polygon painter.StrokeColor = Color.Red; painter.dbugDrawPoly2TriPolygon(polygons); } } } else { MultiFigures multiFig = container._multiFig; if (Tess == GlyphDemo_TessTech.SgiTess) { switch (tessTechnique) { case TessTriangleTechnique.DrawArray: { painter.dbugDrawTessTriangles(multiFig.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawArray)); } break; case TessTriangleTechnique.DrawElement: { float[] tessArea = multiFig.GetAreaTess(_tessTool, _tessTool.WindingRuleType, TessTriangleTechnique.DrawElement); ushort[] index = multiFig.GetAreaIndexList(); painter.dbugDrawTessTriangles(tessArea, index); } break; } } else { if (ContourAnalysis) { ContourAnalyzer analyzer1 = new ContourAnalyzer(); IntermediateOutline outline = analyzer1.CreateIntermediateOutline(v1); GlyphDebugContourVisualizer dbugVisualizer = new GlyphDebugContourVisualizer(); dbugVisualizer.SetPainter(painter); dbugVisualizer.Scale = _typeface.CalculateScaleToPixelFromPointSize(fontSizeInPts); dbugVisualizer.WalkCentroidLine(outline); } else { List <Poly2Tri.Polygon> polygons = multiFig.GetTrianglulatedArea(false); painter.StrokeColor = Color.Red; painter.dbugDrawPoly2TriPolygon(polygons); } } } } painter.StrokeColor = prevColor; //------------- //tess //if (rdoTessSGI.Checked) //{ // //SGI Tess Lib // if (!_tessTool.TessPolygon(polygon1, _contourEnds)) // { // return; // } // //1. // List<ushort> indexList = _tessTool.TessIndexList; // //2. // List<TessVertex2d> tempVertexList = _tessTool.TempVertexList; // //3. // int vertexCount = indexList.Count; // //----------------------------- // int orgVertexCount = polygon1.Length / 2; // float[] vtx = new float[vertexCount * 2];//*** // int n = 0; // for (int p = 0; p < vertexCount; ++p) // { // ushort index = indexList[p]; // if (index >= orgVertexCount) // { // //extra coord (newly created) // TessVertex2d extraVertex = tempVertexList[index - orgVertexCount]; // vtx[n] = (float)extraVertex.x; // vtx[n + 1] = (float)extraVertex.y; // } // else // { // //original corrd // vtx[n] = (float)polygon1[index * 2]; // vtx[n + 1] = (float)polygon1[(index * 2) + 1]; // } // n += 2; // } // //----------------------------- // //draw tess result // int j = vtx.Length; // for (int i = 0; i < j;) // { // var p0 = new PointF(vtx[i], vtx[i + 1]); // var p1 = new PointF(vtx[i + 2], vtx[i + 3]); // var p2 = new PointF(vtx[i + 4], vtx[i + 5]); // _g.DrawLine(Pens.Red, p0, p1); // _g.DrawLine(Pens.Red, p1, p2); // _g.DrawLine(Pens.Red, p2, p0); // i += 6; // } //} //else //{ // List<Poly2Tri.Polygon> outputPolygons = new List<Poly2Tri.Polygon>(); // Poly2TriExampleHelper.Triangulate(polygon1, contourEndIndices, flipYAxis, outputPolygons); // foreach (Poly2Tri.Polygon polygon in outputPolygons) // { // foreach (Poly2Tri.DelaunayTriangle tri in polygon.Triangles) // { // Poly2Tri.TriangulationPoint p0 = tri.P0; // Poly2Tri.TriangulationPoint p1 = tri.P1; // Poly2Tri.TriangulationPoint p2 = tri.P2; // _g.DrawLine(Pens.Red, (float)p0.X, (float)p0.Y, (float)p1.X, (float)p1.Y); // _g.DrawLine(Pens.Red, (float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y); // _g.DrawLine(Pens.Red, (float)p2.X, (float)p2.Y, (float)p0.X, (float)p0.Y); // } // } //} #endif }