/// <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); }
/// <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); }
/// <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); }
/// <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(); } }
/// <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)); }
/* * 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); }
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); } }
/// <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); }
/// <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); } }
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(); } } }
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); }
/// <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); } } }
public override VectorPath GetPath(SVGElement context, RenderContext renderer) { SVGElement element = Target; return((element != null) ? (element as SVGElement).GetPath(element, renderer) : null); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> /// <value></value> public override VectorPath GetPath(SVGElement context, RenderContext renderer) { return(GetPaths(context, renderer)); }
/// <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); }
/// <summary>Gets or rebuilds the cached path.</summary> public virtual VectorPath GetPath(SVGElement context, RenderContext ctx) { return(_Path); }
/// <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); }