示例#1
0
        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));
        }
示例#2
0
        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;
        }
示例#3
0
        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));
        }
示例#4
0
        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));
        }
示例#5
0
 public void SetBoundable(ISvgBoundable boundable)
 {
     _boundables.Push(boundable);
 }
示例#6
0
        /// <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;
        }
示例#7
0
 /// <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);
 }
示例#8
0
 public void SetBoundable(ISvgBoundable boundable)
 {
     _boundables.Push(boundable);
 }
示例#9
0
        /// <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);
        }
示例#10
0
 /// <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));
 }
示例#11
0
 private bool NeedToExpandGradient(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd)
 {
     return(SpreadMethod == SvgGradientSpreadMethod.Pad && (boundable.Bounds.Contains(specifiedStart) || boundable.Bounds.Contains(specifiedEnd)));
 }
示例#12
0
 private void Draw(ISvgRenderer renderer, ISvgBoundable boundable)
 {
     renderer.SetBoundable(boundable);
     this.Render(renderer);
 }
示例#13
0
 public void SetBoundable(ISvgBoundable boundable)
 {
     //m_defaultRenderer.SetBoundable(boundable);
 }
示例#14
0
 public void SetBoundable(ISvgBoundable boundable)
 {
     _svgRendererImplementation.SetBoundable(boundable);
 }
示例#15
0
 private PointF CalculateEnd(ISvgBoundable boundable)
 {
     return(TransformPoint(new PointF(this.X2.ToDeviceValue(boundable), this.Y2.ToDeviceValue(boundable, true))));
 }