public void ShowGlyphAsDirectedContours_Cairo() { //load the glyph Typeface typeFace; using (var fs = Utility.ReadFile(Utility.FontDir + fontFileName)) { var reader = new OpenFontReader(); typeFace = reader.Read(fs); } Glyph glyph = typeFace.Lookup(character); Bounds boundingBox = typeFace.Bounds; short ascender = typeFace.Ascender; //read polygons and quadratic bezier segments GlyphLoader.Read(glyph, out var polygons, out var quadraticBezierSegments); //The actual position of points should apply ascender offset var offset = new Vector(0, ascender); // draw to an image using (Cairo.ImageSurface surface = new Cairo.ImageSurface(Cairo.Format.Argb32, boundingBox.XMax - boundingBox.XMin, boundingBox.YMax - boundingBox.YMin)) using (Cairo.Context g = new Cairo.Context(surface)) { //set surface back ground to white (1,1,1,1) g.SetSourceColor(CairoEx.ColorWhite); g.Paint(); //polygons for (var i = 0; i < polygons.Count; i++) { var polygon = polygons[i]; var startPoint = polygon[0] + offset; g.MoveTo(startPoint.X, startPoint.Y); var previousPoint = startPoint; foreach (var point in polygon) { var p = point + offset; g.LineTo(p.X, p.Y); g.DrawArrow(previousPoint, p); previousPoint = p; } g.LineTo(startPoint.X, startPoint.Y); g.DrawArrow(previousPoint, startPoint); } g.LineWidth = polygonLineWidth; g.SetSourceColor(polygonColor.ToCairoColor()); g.Stroke(); //quadratic bezier segments foreach (var segment in quadraticBezierSegments) { var p0 = segment.Item1 + offset; var c = segment.Item2 + offset; var p1 = segment.Item3 + offset; g.MoveTo(p0.X, p0.Y); g.QuadraticTo(c.X, c.Y, p1.X, p1.Y); } g.LineWidth = quadraticLineWidth; g.SetSourceColor(quadraticSegmentColor.ToCairoColor()); g.Stroke(); //start points g.SetSourceColor(startPointColor.ToCairoColor()); for (var i = 0; i < polygons.Count; i++) { var polygon = polygons[i]; var startPoint = polygon[0] + offset; g.Arc(startPoint.x, startPoint.y, 10, 0, System.Math.PI * 2); g.Fill(); } //show the image of contours var path = $"{OutputDir}{Path.DirectorySeparatorChar}{fontFileName}_{character}.png"; surface.WriteToPng(path); Util.OpenImage(path); } }