Exemple #1
0
        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);
        }
Exemple #2
0
        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());
        }
Exemple #3
0
        /// <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();
        }