public void OriginUsed() { // Y axis is inverted as it expects to be drawing for bottom left GlyphBuilder fullBuilder = new GlyphBuilder(new System.Numerics.Vector2(10, 99)); IGlyphRenderer builder = fullBuilder; builder.BeginGlyph(Vector2.Zero); builder.BeginFigure(); builder.MoveTo(new Vector2(0, 0)); builder.LineTo(new Vector2(0, 10)); // becomes 0, -10 builder.CubicBezierTo( new Vector2(15, 15), // control point - will not be in the final point collection new Vector2(15, 10), // control point - will not be in the final point collection new Vector2(10, 10)); // becomes 10, -10 builder.QuadraticBezierTo( new Vector2(10, 5), // control point - will not be in the final point collection new Vector2(10, 0)); builder.EndFigure(); builder.EndGlyph(); System.Collections.Immutable.ImmutableArray <Vector2> points = fullBuilder.Paths.Single().Flatten().Single().Points; Assert.Contains(new Vector2(10, 99), points); Assert.Contains(new Vector2(10, 109), points); Assert.Contains(new Vector2(20, 99), points); Assert.Contains(new Vector2(20, 109), points); }
public void EachGlypeCausesNewPath() { // Y axis is inverted as it expects to be drawing for bottom left GlyphBuilder fullBuilder = new GlyphBuilder(); IGlyphRenderer builder = fullBuilder; for (int i = 0; i < 10; i++) { builder.BeginGlyph(Vector2.Zero); builder.BeginFigure(); builder.MoveTo(new Vector2(0, 0)); builder.LineTo(new Vector2(0, 10)); // becomes 0, -10 builder.LineTo(new Vector2(10, 10)); // becomes 10, -10 builder.LineTo(new Vector2(10, 0)); builder.EndFigure(); builder.EndGlyph(); } Assert.Equal(10, fullBuilder.Paths.Count()); }
/// <summary> /// Renders the glyph to the render surface in font units relative to a bottom left origin at (0,0) /// </summary> /// <param name="surface">The surface.</param> /// <param name="pointSize">Size of the point.</param> /// <param name="location">The location.</param> /// <param name="dpi">The dpi.</param> /// <param name="lineHeight">The lineHeight the current glyph was draw agains to offset topLeft while calling out to IGlyphRenderer.</param> /// <exception cref="NotSupportedException">Too many control points</exception> public void RenderTo(IGlyphRenderer surface, float pointSize, Vector2 location, Vector2 dpi, float lineHeight) { location = location * dpi; Vector2 firstPoint = Vector2.Zero; Vector2 scaledPoint = dpi * pointSize; FontRectangle box = this.BoundingBox(location, scaledPoint); var paramaters = new GlyphRendererParameters(this, pointSize, dpi); if (surface.BeginGlyph(box, paramaters)) { int startOfContor = 0; int endOfContor = -1; for (int i = 0; i < this.endPoints.Length; i++) { surface.BeginFigure(); startOfContor = endOfContor + 1; endOfContor = this.endPoints[i]; Vector2 prev = Vector2.Zero; Vector2 curr = this.GetPoint(ref scaledPoint, endOfContor) + location; Vector2 next = this.GetPoint(ref scaledPoint, startOfContor) + location; if (this.onCurves[endOfContor]) { surface.MoveTo(curr); } else { if (this.onCurves[startOfContor]) { surface.MoveTo(next); } else { // If both first and last points are off-curve, start at their middle. Vector2 startPoint = (curr + next) / 2; surface.MoveTo(startPoint); } } int length = (endOfContor - startOfContor) + 1; for (int p = 0; p < length; p++) { prev = curr; curr = next; int currentIndex = startOfContor + p; int nextIndex = startOfContor + ((p + 1) % length); int prevIndex = startOfContor + (((length + p) - 1) % length); next = this.GetPoint(ref scaledPoint, nextIndex) + location; if (this.onCurves[currentIndex]) { // This is a straight line. surface.LineTo(curr); } else { Vector2 prev2 = prev; Vector2 next2 = next; if (!this.onCurves[prevIndex]) { prev2 = (curr + prev) / 2; surface.LineTo(prev2); } if (!this.onCurves[nextIndex]) { next2 = (curr + next) / 2; } surface.LineTo(prev2); surface.QuadraticBezierTo(curr, next2); } } surface.EndFigure(); } } surface.EndGlyph(); }
/// <summary> /// Renders the glyph to the render surface in font units relative to a bottom left origin at (0,0) /// </summary> /// <param name="surface">The surface.</param> /// <param name="pointSize">Size of the point.</param> /// <param name="location">The location.</param> /// <param name="dpi">The dpi.</param> /// <exception cref="System.NotSupportedException">Too many control points</exception> public void RenderTo(IGlyphRenderer surface, float pointSize, Vector2 location, Vector2 dpi) { location = location * dpi; int pointIndex = 0; var scaleFactor = (float)(this.sizeOfEm * 72f); surface.BeginGlyph(); Vector2 firstPoint = Vector2.Zero; Vector2 scale = new Vector2(1, -1); for (int i = 0; i < this.endPoints.Length; i++) { int nextContour = this.endPoints[i] + 1; bool isFirstPoint = true; ControlPointCollection points = new ControlPointCollection(); bool justFromCurveMode = false; for (; pointIndex < nextContour; ++pointIndex) { var point = location + (scale * ((this.controlPoints[pointIndex] * pointSize * dpi) / scaleFactor)); // scale each point as we go, w will now have the correct relative point size if (this.onCurves[pointIndex]) { // on curve if (justFromCurveMode) { points = DrawPoints(surface, points, point); } else { if (isFirstPoint) { isFirstPoint = false; firstPoint = point; surface.MoveTo(firstPoint); } else { surface.LineTo(point); } } } else { switch (points.Count) { case 0: points.Add(point); break; case 1: // we already have prev second control point // so auto calculate line to // between 2 point Vector2 mid = (points.SecondControlPoint + point) / 2; surface.QuadraticBezierTo( points.SecondControlPoint, mid); points.SecondControlPoint = point; //replace 2nd break; default: throw new NotSupportedException("Too many control points"); } } justFromCurveMode = !this.onCurves[pointIndex]; } // close figure // if in curve mode if (justFromCurveMode) { DrawPoints(surface, points, firstPoint); } surface.EndFigure(); } surface.EndGlyph(); }