private void button1_Click(object sender, EventArgs e) { //1. MsdfGenParams msdfGenParams = new MsdfGenParams(); //GlyphImage glyphImg = MsdfGlyphGen.CreateMsdfImage(tx, msdfGenParams); Msdfgen.Shape shape1 = new Msdfgen.Shape(); // Msdfgen.Contour cnt = new Msdfgen.Contour(); //cnt.AddLine(0, 0, 50, 0); //cnt.AddLine(50, 0, 50, 50); //cnt.AddLine(50, 50, 0, 50); //cnt.AddLine(0, 50, 0, 0); //cnt.AddLine(10, 20, 50, 0); //cnt.AddLine(50, 0, 80, 20); //cnt.AddLine(80, 20, 50, 60); //cnt.AddLine(50, 60, 10, 20); //for msdf we draw shape clock-wise cnt.AddLine(10, 20, 50, 60); cnt.AddLine(50, 60, 80, 20); cnt.AddLine(80, 20, 50, 0); cnt.AddLine(50, 0, 10, 20); shape1.contours.Add(cnt); // // var genParams = new MsdfGenParams(); BitmapAtlasItemSource glyphImg = MsdfImageGen.CreateMsdfImageV1(shape1, genParams); using (Bitmap bmp = new Bitmap(glyphImg.Width, glyphImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { int[] buffer = glyphImg.GetImageBuffer(); var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg.Width, glyphImg.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpdata.Scan0, buffer.Length); bmp.UnlockBits(bmpdata); bmp.Save("msdf_shape.png"); // } }
static Shape CreateShape(VertexStore vxs, out EdgeBmpLut bmpLut) { List <EdgeSegment> flattenEdges = new List <EdgeSegment>(); Shape shape = new Shape(); //start with blank shape int i = 0; double x, y; VertexCmd cmd; Contour cnt = null; double latestMoveToX = 0; double latestMoveToY = 0; double latestX = 0; double latestY = 0; List <ContourCorner> corners = new List <ContourCorner>(); List <int> edgeOfNextContours = new List <int>(); List <int> cornerOfNextContours = new List <int>(); while ((cmd = vxs.GetVertex(i, out x, out y)) != VertexCmd.NoMore) { switch (cmd) { case VertexCmd.Close: { //close current cnt if ((latestMoveToX != latestX) || (latestMoveToY != latestY)) { //add line to close the shape if (cnt != null) { flattenEdges.Add(cnt.AddLine(latestX, latestY, latestMoveToX, latestMoveToY)); } } if (cnt != null) { //*** CreateCorners(cnt, corners); edgeOfNextContours.Add(flattenEdges.Count); cornerOfNextContours.Add(corners.Count); shape.contours.Add(cnt); //*** cnt = null; } } break; case VertexCmd.C3: { //C3 curve (Quadratic) if (cnt == null) { cnt = new Contour(); } VertexCmd cmd1 = vxs.GetVertex(i + 1, out double x1, out double y1); i++; if (cmd1 != VertexCmd.LineTo) { throw new NotSupportedException(); } //in this version, //we convert Quadratic to Cubic (https://stackoverflow.com/questions/9485788/convert-quadratic-curve-to-cubic-curve) //Control1X = StartX + ((2f/3) * (ControlX - StartX)) //Control2X = EndX + ((2f/3) * (ControlX - EndX)) //flattenEdges.Add(cnt.AddCubicSegment( // latestX, latestY, // ((2f / 3) * (x - latestX)) + latestX, ((2f / 3) * (y - latestY)) + latestY, // ((2f / 3) * (x - x1)) + x1, ((2f / 3) * (y - y1)) + y1, // x1, y1)); flattenEdges.Add(cnt.AddQuadraticSegment(latestX, latestY, x, y, x1, y1)); latestX = x1; latestY = y1; } break; case VertexCmd.C4: { //C4 curve (Cubic) if (cnt == null) { cnt = new Contour(); } VertexCmd cmd1 = vxs.GetVertex(i + 1, out double x2, out double y2); VertexCmd cmd2 = vxs.GetVertex(i + 2, out double x3, out double y3); i += 2; if (cmd1 != VertexCmd.C4 || cmd2 != VertexCmd.LineTo) { throw new NotSupportedException(); } flattenEdges.Add(cnt.AddCubicSegment(latestX, latestY, x, y, x2, y2, x3, y3)); latestX = x3; latestY = y3; } break; case VertexCmd.LineTo: { if (cnt == null) { cnt = new Contour(); } LinearSegment lineseg = cnt.AddLine(latestX, latestY, x, y); flattenEdges.Add(lineseg); latestX = x; latestY = y; } break; case VertexCmd.MoveTo: { latestX = latestMoveToX = x; latestY = latestMoveToY = y; if (cnt != null) { shape.contours.Add(cnt); cnt = null; } } break; } i++; } if (cnt != null) { shape.contours.Add(cnt); CreateCorners(cnt, corners); edgeOfNextContours.Add(flattenEdges.Count); cornerOfNextContours.Add(corners.Count); cnt = null; } GroupingOverlapContours(shape); //from a given shape we create a corner-arm for each corner bmpLut = new EdgeBmpLut(corners, flattenEdges, edgeOfNextContours, cornerOfNextContours); return(shape); }