public ActiveEdge(GlyphEdge e, int offsetX, float start) { float dxDy = (e.X1 - e.X) / (e.Y1 - e.Y); Fdx = dxDy; Fdy = dxDy != 0.0f ? 1.0f / dxDy : 0.0f; Fx = e.X + dxDy * (start - e.Y); Fx -= offsetX; Direction = e.Invert ? 1.0f : -1.0f; Sy = e.Y; Ey = e.Y1; }
public static void RenderGlyph(GlyphCanvas canvas, Glyph glyph, float scale, bool invertY = true) { if (scale == 0f) { return; } if (canvas.Width == 0 || canvas.Height == 0) { return; } GlyphVertex[] vertices = glyph.Vertices; var flatnessInPixels = 0.35f; Vector2[] windings = FlattenCurves(vertices, flatnessInPixels / scale, out int[] contourLengths); if (windings == null) { return; } float scaleX = scale; float scaleY = scale; if (invertY) { scaleY = -scaleY; } int n = contourLengths.Sum(); var e = new GlyphEdge[n + 1]; n = 0; var wOffset = 0; var subSample = 1; for (var i = 0; i < contourLengths.Length; i++) { int j = contourLengths[i] - 1; for (var k = 0; k < contourLengths[i]; j = k++) { int a = k; int b = j; if (windings[wOffset + j].Y == windings[wOffset + k].Y) { continue; } e[n].Invert = false; if (invertY && windings[wOffset + j].Y > windings[wOffset + k].Y || !invertY && windings[wOffset + j].Y < windings[wOffset + k].Y) { e[n].Invert = true; a = j; b = k; } e[n].X = windings[wOffset + a].X * scaleX; e[n].Y = windings[wOffset + a].Y * scaleY * subSample; e[n].X1 = windings[wOffset + b].X * scaleX; e[n].Y1 = windings[wOffset + b].Y * scaleY * subSample; n++; } wOffset += contourLengths[i]; } Array.Resize(ref e, n + 1); // todo QuickSortEdges(new Span <GlyphEdge>(e), n); // Insert Sort for (var i = 1; i < n; i++) { GlyphEdge t = e[i]; int j = i; while (j > 0) { ref GlyphEdge b = ref e[j - 1]; if (!(t.Y < b.Y)) { break; } e[j] = e[j - 1]; j--; } if (i != j) { e[j] = t; } }