Exemplo n.º 1
0
        /// <summary>
        /// Gets the path representing this element.
        /// </summary>
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            Css.RenderableData rd = context.RenderData;

            // Don't build the path if there's no radius:
            float radius = Radius.GetDecimal(rd, ViewportAxis.None);

            if (radius <= 0)
            {
                return(null);
            }

            if (_Path == null)
            {
                // Don't need to consider stroke width.

                _Path = new VectorPath();

                float centerX = CenterX.GetDecimal(rd, ViewportAxis.X);
                float centerY = CenterX.GetDecimal(rd, ViewportAxis.Y);

                // Get the C values:
                float cX = BezierC * radius;
                float cY = cX;

                // Offset to match the center:
                cX += centerX;
                cY += centerY;

                float radiusX = centerX + radius;
                float radiusY = centerY + radius;

                float nRadiusX = centerX - radius;
                float nRadiusY = centerY - radius;

                _Path.MoveTo(centerX, radiusY);

                // First quadrant (top right, going clockwise):
                _Path.CurveTo(cX, radiusY, radiusX, cY, radiusX, centerY);

                // Bottom right:
                _Path.CurveTo(radiusX, -cY, cX, nRadiusY, centerX, nRadiusY);

                // Bottom left:
                _Path.CurveTo(-cX, nRadiusY, nRadiusX, -cY, nRadiusX, centerY);

                // Top left:
                _Path.CurveTo(nRadiusX, cY, -cX, radiusY, centerX, radiusY);

                // Mark as closed:
                _Path.LatestPathNode.IsClose = true;
            }

            return(_Path);
        }
 public void curveTo(float c1x, float c1y, float c2x, float c2y, float x, float y)
 {
     Path.CurveTo(c1x, c1y, c2x, c2y, x, y);
 }
        /// <summary>
        /// Gets the path representing this element.
        /// </summary>
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            Css.RenderableData rd = context.RenderData;

            // Get w/h:
            float width  = Width.GetDecimal(rd, ViewportAxis.X);
            float height = Height.GetDecimal(rd, ViewportAxis.Y);

            if (width <= 0f && height > 0f)
            {
                return(null);
            }

            if (_Path == null)
            {
                _Path = new VectorPath();

                // Get corner radius:
                float rx = CornerRadiusX.GetDecimal(rd, ViewportAxis.X);
                float ry = CornerRadiusY.GetDecimal(rd, ViewportAxis.Y);

                // Get x/y:
                float x = X.GetDecimal(rd, ViewportAxis.X);
                float y = Y.GetDecimal(rd, ViewportAxis.Y);

                // Note: This goes clockwise (like the other standard shapes).

                // If the corners aren't to be rounded just create a rectangle
                if (rx == 0f && ry == 0f)
                {
                    // Ordinary rectangle.
                    _Path.MoveTo(x, y);
                    _Path.LineTo(x, y + height);
                    _Path.LineTo(x + width, y + height);
                    _Path.LineTo(x + width, y);
                    _Path.ClosePath();
                }
                else
                {
                    // Clip the corner radius:
                    rx = (float)Math.Min(rx * 2, width);
                    ry = (float)Math.Min(ry * 2, height);

                    // Get the C values (used to shape the 4 corners arcs - see CircleProvider for some clarity):
                    float cx = (CircleProvider.BezierC * rx);
                    float cy = (CircleProvider.BezierC * ry);

                    float limit = x + width * 0.5f;

                    // The start/ end of arcs from the left along x.
                    float leftArcX = Math.Min(x + rx, limit);
                    // The start/ end of arcs from the right along x.
                    float rightArcX = Math.Max(x + width - rx, limit);

                    limit = y + height * 0.5f;

                    // The start/ end of arcs from the bottom along y.
                    float bottomArcY = Math.Min(y + ry, limit);
                    // The start/ end of arcs from the top along y.
                    float topArcY = Math.Max(y + height - ry, limit);

                    // Start from bottom left:
                    _Path.MoveTo(
                        leftArcX,
                        y
                        );

                    // First arc (bottom left):
                    _Path.CurveTo(
                        leftArcX - cx, y,
                        x, bottomArcY - cy,
                        x, bottomArcY
                        );

                    // Up the left edge:
                    _Path.LineTo(x, topArcY);

                    // Top left arc:
                    _Path.CurveTo(
                        x, topArcY + cy,
                        leftArcX - cx, y + height,
                        leftArcX, y + height
                        );

                    // Along the top edge:
                    _Path.LineTo(rightArcX, y);

                    // Top right arc:
                    _Path.CurveTo(
                        rightArcX + cx, y,
                        x + width, topArcY + cy,
                        x + width, topArcY
                        );

                    // Down the right edge:
                    _Path.LineTo(x + width, bottomArcY);

                    // Bottom right arc:
                    _Path.CurveTo(
                        x + width, bottomArcY - cy,
                        rightArcX + cx, y,
                        rightArcX, y
                        );

                    // Line along the bottom!
                    _Path.ClosePath();
                }
            }

            return(_Path);
        }
Exemplo n.º 4
0
        /// <summary>Adds the given parsed command into the given path.</summary>
        public static void AddCommand(VectorPath path, char command, float[] param, int currentLimit)
        {
            if (command == '\0')
            {
                return;
            }

            // Get the lc command:
            char lower = char.ToLower(command);

            // A lowercase char is relative
            // (and its lowercase if the lower one matches the original):
            bool isRelative = (command == lower);

            // Current point:
            float curX = 0f;
            float curY = 0f;
            float c1x  = 0f;
            float c1y  = 0f;

            if (path.LatestPathNode != null)
            {
                // Get current point:
                curX = path.LatestPathNode.X;
                curY = path.LatestPathNode.Y;
            }

            switch (lower)
            {
            case 'a':
                // Eliptical arc

                if (isRelative)
                {
                    param[5] += curX;
                    param[6] += curY;
                }

                path.EllipseArc(param[0], param[1], param[2], param[5], param[6], (param[3] == 1f), (param[4] == 1f));

                break;

            case 'c':
                // Curve to

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                    param[2] += curX;
                    param[3] += curY;
                    param[4] += curX;
                    param[5] += curY;
                }

                path.CurveTo(param[0], param[1], param[2], param[3], param[4], param[5]);
                break;

            case 'h':
                // Horizontal line to

                if (isRelative)
                {
                    param[0] += curX;
                }

                path.LineTo(param[0], curY);
                break;

            case 'l':
                // Line to

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                }

                path.LineTo(param[0], param[1]);
                break;

            case 'm':
                // Move to

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                }

                path.MoveTo(param[0], param[1]);
                break;

            case 'q':
                // Quadratic bezier to

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                    param[2] += curX;
                    param[3] += curY;
                }

                path.QuadraticCurveTo(param[0], param[1], param[2], param[3]);
                break;

            case 's':
                // Smooth curve to
                Reflect(path, out c1x, out c1y);

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                    param[2] += curX;
                    param[3] += curY;
                }

                path.CurveTo(c1x, c1y, param[0], param[1], param[2], param[3]);
                break;

            case 't':
                // Smooth quadratic bezier to
                Reflect(path, out c1x, out c1y);

                if (isRelative)
                {
                    param[0] += curX;
                    param[1] += curY;
                }

                path.QuadraticCurveTo(c1x, c1y, param[0], param[1]);
                break;

            case 'v':
                // Vertical line to

                if (isRelative)
                {
                    param[0] += curY;
                }

                path.LineTo(curX, param[0]);
                break;

            case 'z':
                // Close path
                path.ClosePath();
                break;
            }
        }