private GradientPoints ExpandGradient(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) { var pointsToMove = PointsToMove(boundable, specifiedStart, specifiedEnd); if (pointsToMove == LinePoints.None) { Debug.Fail("Unexpectedly expanding gradient when not needed!"); return(new GradientPoints(specifiedStart, specifiedEnd)); } var bounds = boundable.Bounds; var effectiveStart = specifiedStart; var effectiveEnd = specifiedEnd; var intersectionPoints = CandidateIntersections(bounds, specifiedStart, specifiedEnd); Debug.Assert(intersectionPoints.Count == 2, "Unanticipated number of intersection points"); if (!(Math.Sign(intersectionPoints[1].X - intersectionPoints[0].X) == Math.Sign(specifiedEnd.X - specifiedStart.X) && Math.Sign(intersectionPoints[1].Y - intersectionPoints[0].Y) == Math.Sign(specifiedEnd.Y - specifiedStart.Y))) { intersectionPoints = intersectionPoints.Reverse().ToList(); } if ((pointsToMove & LinePoints.Start) > 0) { effectiveStart = intersectionPoints[0]; } if ((pointsToMove & LinePoints.End) > 0) { effectiveEnd = intersectionPoints[1]; } switch (SpreadMethod) { case SvgGradientSpreadMethod.Reflect: case SvgGradientSpreadMethod.Repeat: var specifiedLength = CalculateDistance(specifiedStart, specifiedEnd); var specifiedUnitVector = new PointF((specifiedEnd.X - specifiedStart.X) / (float)specifiedLength, (specifiedEnd.Y - specifiedStart.Y) / (float)specifiedLength); var oppUnitVector = new PointF(-specifiedUnitVector.X, -specifiedUnitVector.Y); var startExtend = (float)(Math.Ceiling(CalculateDistance(effectiveStart, specifiedStart) / specifiedLength) * specifiedLength); effectiveStart = MovePointAlongVector(specifiedStart, oppUnitVector, startExtend); var endExtend = (float)(Math.Ceiling(CalculateDistance(effectiveEnd, specifiedEnd) / specifiedLength) * specifiedLength); effectiveEnd = MovePointAlongVector(specifiedEnd, specifiedUnitVector, endExtend); break; } return(new GradientPoints(effectiveStart, effectiveEnd)); }
void ISvgRenderer.SetBoundable(ISvgBoundable boundable) { _states.Push(new Tuple <Region, Matrix3x2, Matrix3x2>(_currentClip, _currentTransform, _initialTransform)); _boundables.Push(boundable); // for transformation _innerGraphics.PushState(); _initialTransform = _innerGraphics.Transform = Matrix3x2.Multiply(GetTransform(Convert(boundable.Bounds), _bounds), _innerGraphics.Transform); // for intersection _innerGraphics.PushState(); _currentClip = null; _currentTransform = Matrix3x2.Identity; }
private LinePoints PointsToMove(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) { var bounds = boundable.Bounds; if (specifiedStart.X == specifiedEnd.X) { return((bounds.Top < specifiedStart.Y && specifiedStart.Y < bounds.Bottom ? LinePoints.Start : LinePoints.None) | (bounds.Top < specifiedEnd.Y && specifiedEnd.Y < bounds.Bottom ? LinePoints.End : LinePoints.None)); } else if (specifiedStart.Y == specifiedEnd.Y) { return((bounds.Left < specifiedStart.X && specifiedStart.X < bounds.Right ? LinePoints.Start : LinePoints.None) | (bounds.Left < specifiedEnd.X && specifiedEnd.X < bounds.Right ? LinePoints.End : LinePoints.None)); } return((boundable.Bounds.Contains(specifiedStart) ? LinePoints.Start : LinePoints.None) | (boundable.Bounds.Contains(specifiedEnd) ? LinePoints.End : LinePoints.None)); }
private GradientPoints ExpandGradient(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) { if (!NeedToExpandGradient(boundable, specifiedStart, specifiedEnd)) { Debug.Fail("Unexpectedly expanding gradient when not needed!"); return(new GradientPoints(specifiedStart, specifiedEnd)); } var specifiedLength = CalculateDistance(specifiedStart, specifiedEnd); var specifiedUnitVector = new PointF((specifiedEnd.X - specifiedStart.X) / (float)specifiedLength, (specifiedEnd.Y - specifiedStart.Y) / (float)specifiedLength); var effectiveStart = specifiedStart; var effectiveEnd = specifiedEnd; var elementDiagonal = (float)CalculateDistance(new PointF(boundable.Bounds.Left, boundable.Bounds.Top), new PointF(boundable.Bounds.Right, boundable.Bounds.Bottom)); var expandedStart = MovePointAlongVector(effectiveStart, specifiedUnitVector, -elementDiagonal); var expandedEnd = MovePointAlongVector(effectiveEnd, specifiedUnitVector, elementDiagonal); var intersectionPoints = new LineF(expandedStart.X, expandedStart.Y, expandedEnd.X, expandedEnd.Y).Intersection(boundable.Bounds); if (boundable.Bounds.Contains(specifiedStart)) { effectiveStart = CalculateClosestIntersectionPoint(expandedStart, intersectionPoints); effectiveStart = MovePointAlongVector(effectiveStart, specifiedUnitVector, -1); } if (boundable.Bounds.Contains(specifiedEnd)) { effectiveEnd = CalculateClosestIntersectionPoint(effectiveEnd, intersectionPoints); effectiveEnd = MovePointAlongVector(effectiveEnd, specifiedUnitVector, 1); } return(new GradientPoints(effectiveStart, effectiveEnd)); }
public void SetBoundable(ISvgBoundable boundable) { _boundables.Push(boundable); }
/// <summary> /// Converts the current unit to one that can be used at render time. /// </summary> /// <returns>The representation of the current unit in a device value (usually pixels).</returns> public float ToDeviceValue(ISvgBoundable boundable, bool vertical) { // If it's already been calculated if (this._deviceValue.HasValue) { return this._deviceValue.Value; } if (this._value == 0.0f) { this._deviceValue = 0.0f; return this._deviceValue.Value; } // http://www.w3.org/TR/CSS21/syndata.html#values // http://www.w3.org/TR/SVG11/coords.html#Units const float cmInInch = 2.54f; int ppi = SvgDocument.PointsPerInch; switch (this.Type) { case SvgUnitType.Em: float points = (float)(this.Value * 9); _deviceValue = (points / 72) * ppi; break; case SvgUnitType.Centimeter: _deviceValue = (float)((this.Value / cmInInch) * ppi); break; case SvgUnitType.Inch: _deviceValue = this.Value * ppi; break; case SvgUnitType.Millimeter: _deviceValue = (float)((this.Value / 10) / cmInInch) * ppi; break; case SvgUnitType.Pica: _deviceValue = ((this.Value * 12) / 72) * ppi; break; case SvgUnitType.Point: _deviceValue = (this.Value / 72) * ppi; break; case SvgUnitType.Pixel: _deviceValue = this.Value; break; case SvgUnitType.User: _deviceValue = this.Value; break; case SvgUnitType.Percentage: // Can't calculate if there is no style owner if (boundable == null) { _deviceValue = this.Value; break; } // TODO : Support height percentages System.Drawing.SizeF size = boundable.Bounds.Size; _deviceValue = (((vertical) ? size.Height : size.Width) / 100) * this.Value; break; default: _deviceValue = this.Value; break; } return this._deviceValue.Value; }
/// <summary> /// Converts the current unit to one that can be used at render time. /// </summary> /// <returns>The representation of the current unit in a device value (usually pixels).</returns> public float ToDeviceValue(ISvgBoundable boundable) { return this.ToDeviceValue(boundable, false); }
/// <summary> /// Converts the current unit to one that can be used at render time. /// </summary> /// <returns>The representation of the current unit in a device value (usually pixels).</returns> public float ToDeviceValue(ISvgBoundable boundable, bool vertical) { // If it's already been calculated if (this._deviceValue.HasValue) { return(this._deviceValue.Value); } if (this._value == 0.0f) { this._deviceValue = 0.0f; return(this._deviceValue.Value); } // http://www.w3.org/TR/CSS21/syndata.html#values // http://www.w3.org/TR/SVG11/coords.html#Units const float cmInInch = 2.54f; int ppi = SvgDocument.PointsPerInch; switch (this.Type) { case SvgUnitType.Em: float points = (float)(this.Value * 9); _deviceValue = (points / 72) * ppi; break; case SvgUnitType.Centimeter: _deviceValue = (float)((this.Value / cmInInch) * ppi); break; case SvgUnitType.Inch: _deviceValue = this.Value * ppi; break; case SvgUnitType.Millimeter: _deviceValue = (float)((this.Value / 10) / cmInInch) * ppi; break; case SvgUnitType.Pica: _deviceValue = ((this.Value * 12) / 72) * ppi; break; case SvgUnitType.Point: _deviceValue = (this.Value / 72) * ppi; break; case SvgUnitType.Pixel: _deviceValue = this.Value; break; case SvgUnitType.User: _deviceValue = this.Value; break; case SvgUnitType.Percentage: // Can't calculate if there is no style owner if (boundable == null) { _deviceValue = this.Value; break; } // TODO : Support height percentages System.Drawing.SizeF size = boundable.Bounds.Size; _deviceValue = (((vertical) ? size.Height : size.Width) / 100) * this.Value; break; default: _deviceValue = this.Value; break; } return(this._deviceValue.Value); }
/// <summary> /// Converts the current unit to one that can be used at render time. /// </summary> /// <returns>The representation of the current unit in a device value (usually pixels).</returns> public float ToDeviceValue(ISvgBoundable boundable) { return(this.ToDeviceValue(boundable, false)); }
private bool NeedToExpandGradient(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) { return(SpreadMethod == SvgGradientSpreadMethod.Pad && (boundable.Bounds.Contains(specifiedStart) || boundable.Bounds.Contains(specifiedEnd))); }
private void Draw(ISvgRenderer renderer, ISvgBoundable boundable) { renderer.SetBoundable(boundable); this.Render(renderer); }
public void SetBoundable(ISvgBoundable boundable) { //m_defaultRenderer.SetBoundable(boundable); }
public void SetBoundable(ISvgBoundable boundable) { _svgRendererImplementation.SetBoundable(boundable); }
private PointF CalculateEnd(ISvgBoundable boundable) { return(TransformPoint(new PointF(this.X2.ToDeviceValue(boundable), this.Y2.ToDeviceValue(boundable, true)))); }