예제 #1
0
        /// <summary>
        /// Gets the clip path.
        /// </summary>
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            if (_computedPath == null)
            {
                Matrix4x4 transform;
                bool      applyExtra;

                if (ClipPathUnits == CoordinateUnits.ObjectBoundingBox)
                {
                    BoxRegion bounds = context.Bounds;

                    transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(
                                                  bounds.Width, bounds.Height, 0f
                                                  ));

                    transform *= Matrix4x4.TRS(new Vector3(
                                                   bounds.X, bounds.Y, 0f
                                                   ), Quaternion.identity, Vector3.one);

                    applyExtra = true;
                }
                else
                {
                    transform  = Matrix4x4.identity;
                    applyExtra = false;
                }

                // For each child which is a PathBase, append it.
                _computedPath = new VectorPath();

                AddChildPaths(this, _computedPath, renderer, transform, applyExtra);
            }

            return(_computedPath);
        }
예제 #2
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);
        }
예제 #3
0
        /// <summary>
        /// Gets the path representing this element.
        /// </summary>
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            Css.RenderableData rd = context.RenderData;

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

                try{
                    Css.Value points = Points;
                    int       count  = points.Count;

                    for (int i = 2; (i + 1) < count; i += 2)
                    {
                        float endPointX = points[i].GetDecimal(rd, ViewportAxis.X);
                        float endPointY = points[i + 1].GetDecimal(rd, ViewportAxis.Y);

                        if (Close)
                        {
                            //first line
                            if (_Path.FirstPathNode == null)
                            {
                                // Wrap around:
                                float startPointX = points[i - 2].GetDecimal(rd, ViewportAxis.X);
                                float startPointY = points[i - 1].GetDecimal(rd, ViewportAxis.Y);

                                _Path.MoveTo(startPointX, startPointY);
                            }

                            _Path.LineTo(endPointX, endPointY);
                        }
                        else
                        {
                            // It's a polyline

                            //first line
                            if (_Path.FirstPathNode == null)
                            {
                                _Path.MoveTo(endPointX, endPointY);
                            }
                            else
                            {
                                _Path.LineTo(endPointX, endPointY);
                            }
                        }
                    }
                }
                catch {
                    Dom.Log.Add("Warning: Failed to parse a set of points for a polygon definition in either an SVG or your CSS.");
                }
            }

            return(_Path);
        }
예제 #4
0
        /// <summary>Only pops if the given element had a transform to add earlier.</summary>
        public void PopTransform(SVGElement by)
        {
            // Get CS:
            Css.ComputedStyle computed  = by.Style.Computed;
            Transformation    transform = computed.TransformX;

            if (transform != null)
            {
                // Pop it off again:
                Transformations.Pop();
            }
        }
예제 #5
0
        /// <summary>Gets the defined shape as a region. Allows optimisations for rectangles.</summary>
        public virtual ScreenRegion GetRegion(SVGElement context, RenderContext ctx)
        {
            // Get the path:
            VectorPath path = GetPath(context, ctx);

            if (path == null || path.FirstPathNode == null)
            {
                // None!
                return(null);
            }

            // Create a shape region for it:
            return(new PathScreenRegion(path));
        }
예제 #6
0
        /*
         * internal override IEnumerable<ISvgNode> GetContentNodes()
         * {
         *      var refText = Document.GetElementById(ReferencedElement) as SVGTextContentElement;
         *      IEnumerable<ISvgNode> contentNodes = null;
         *
         *      if (refText == null)
         *      {
         *              contentNodes = base.GetContentNodes();
         *      }
         *      else
         *      {
         *              contentNodes = refText.GetContentNodes();
         *      }
         *
         *      contentNodes = contentNodes.Where(o => !(o is ISvgDescriptiveElement));
         *
         *      return contentNodes;
         * }
         */



        public override bool OnAttributeChange(string property)
        {
            if (property == "href")
            {
                // Try resolve now:
                _targetElement = TryResolveHref();
            }
            else if (!base.OnAttributeChange(property))
            {
                return(false);
            }


            return(true);
        }
예제 #7
0
        public void PushTransform(SVGElement by)
        {
            // Get CS:
            Css.ComputedStyle computed = by.Style.Computed;

            Transformation transform = computed.TransformX;

            // Push the transform to our stack, if we have one.
            if (transform != null)
            {
                // Add it to the stack:
                Transformations.Push(transform);

                // Update it:
                transform.RecalculateMatrix(computed, computed.FirstBox);
            }
        }
예제 #8
0
        /// <summary>
        /// Gets the path representing this element.
        /// </summary>
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            Css.RenderableData rd = context.RenderData;

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

                float startX = StartX.GetDecimal(rd, ViewportAxis.X);
                float startY = StartY.GetDecimal(rd, ViewportAxis.Y);

                float endX = EndX.GetDecimal(rd, ViewportAxis.X);
                float endY = EndY.GetDecimal(rd, ViewportAxis.Y);

                _Path.MoveTo(startX, startY);
                _Path.LineTo(endX, endY);
            }

            return(_Path);
        }
예제 #9
0
        /// <summary>Renders the child nodes of this tag.</summary>
        protected void BuildChildren(RenderContext renderer)
        {
            // Render child nodes as well:
            if (childNodes_ == null)
            {
                return;
            }

            foreach (Node child in childNodes_)
            {
                // Render it too:
                SVGElement svg = (child as SVGElement);

                if (svg == null)
                {
                    continue;
                }

                svg.BuildFilter(renderer);
            }
        }
예제 #10
0
        internal override void AddedToDOM()
        {
            Css.ReflowDocument doc = document as Css.ReflowDocument;

            if (doc != null)
            {
                if (doc.AttributeIndex != null)
                {
                    // Index element if needed:
                    AddToAttributeLookups();
                }

                // Make sure the stylesheet is present:
                doc.RequireStyleSheet(this);
            }

            // Update its css by telling it the parent changed.
            // This affects inherit, height/width etc.
            Style.Computed.ParentChanged();

            // Obtain the render context:
            SVGElement svgParent = (parentNode as SVGElement);

            if (svgParent != null)
            {
                if (Context == null)
                {
                    // Get the context:
                    Context = svgParent.Context;
                }

                if (Context != null)
                {
                    // Request a rebuild:
                    Context.RequestRebuild();
                }
            }
        }
예제 #11
0
        public override void BuildFilter(RenderContext renderer)
        {
            if (Visibility == VisibilityMode.Hidden)
            {
                return;
            }

            PushTransforms(renderer);

            SetClip(renderer);

            SVGElement element = Target;

            if (element != null)
            {
                Node origParent = element.parentNode;
                element.parentNode_ = this;
                element.BuildFilter(renderer);
                element.parentNode_ = origParent;
            }

            ResetClip(renderer);
            PopTransforms(renderer);
        }
예제 #12
0
        /// <summary>Computes a stroke path now and adds it.</summary>
        public void StrokePath(Loonim.TextureNode stroke, VectorPath transformedPath, float width, SVGElement settings)
        {
            if (StrokeHelper == null)
            {
                StrokeHelper = new Loonim.StrokePathMesh();
            }

            // Get other settings:
            StrokeHelper.LineCapMode = settings.StrokeLineCap;
            // Css.Value dashArray=settings.StrokeDashArray;
            StrokeHelper.LineJoinMode = settings.StrokeLineJoin;
            StrokeHelper.MiterLimit   = settings.StrokeMiterLimit;
            StrokeHelper.Accuracy     = Loonim.ClippingPath.DefaultAccuracy;
            StrokeHelper.Width        = width;

            // Generate now!
            List <Mesh> meshes = StrokeHelper.GenerateMeshes(transformedPath);

            foreach (Mesh mesh in meshes)
            {
                // Create Loonim node for each mesh:
                Loonim.ClippingPath path = new Loonim.ClippingPath(stroke, mesh);

                // Add to draw stack:
                if (DrawStack == null)
                {
                    DrawStack            = new Loonim.Stack(1);
                    DrawStack.Sources[0] = path;
                }
                else
                {
                    // Add a path to the draw stack:
                    DrawStack.Add(path);
                }
            }
        }
예제 #13
0
        public override VectorPath GetPath(SVGElement context, RenderContext renderer)
        {
            SVGElement element = Target;

            return((element != null) ? (element as SVGElement).GetPath(element, renderer) : null);
        }
예제 #14
0
 /// <summary>
 /// Gets the <see cref="GraphicsPath"/> for this element.
 /// </summary>
 /// <value></value>
 public override VectorPath GetPath(SVGElement context, RenderContext renderer)
 {
     return(GetPaths(context, renderer));
 }
예제 #15
0
 /// <summary>
 /// Gets the path this tag represents.
 /// Note that it can potentially be a clipping path.
 /// </summary>
 public virtual VectorPath GetPath(SVGElement context, RenderContext renderer)
 {
     return(null);
 }
예제 #16
0
 /// <summary>Gets or rebuilds the cached path.</summary>
 public virtual VectorPath GetPath(SVGElement context, RenderContext ctx)
 {
     return(_Path);
 }
예제 #17
0
        /// <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);
        }