Esempio n. 1
0
        /// <summary>
        /// Converts the current unit to one that can be used at render time.
        /// </summary>
        /// <param name="boundable">The container element used as the basis for calculations</param>
        /// <returns>The representation of the current unit in a device value (usually pixels).</returns>
        public float ToDeviceValue(ISvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // 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;

            var type  = this.Type;
            var value = this.Value;

            float points;

            switch (type)
            {
            case SvgUnitType.Em:
                using (var currFont = GetFont(renderer, owner))
                {
                    if (currFont == null)
                    {
                        points       = (float)(value * 9);
                        _deviceValue = (points / 72.0f) * ppi;
                    }
                    else
                    {
                        _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                    }
                }
                break;

            case SvgUnitType.Ex:
                using (var currFont = GetFont(renderer, owner))
                {
                    if (currFont == null)
                    {
                        points       = (float)(value * 9);
                        _deviceValue = (points * 0.5f / 72.0f) * ppi;
                    }
                    else
                    {
                        _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                    }
                    break;
                }

            case SvgUnitType.Centimeter:
                _deviceValue = (float)((value / cmInInch) * ppi);
                break;

            case SvgUnitType.Inch:
                _deviceValue = value * ppi;
                break;

            case SvgUnitType.Millimeter:
                _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                break;

            case SvgUnitType.Pica:
                _deviceValue = ((value * 12) / 72) * ppi;
                break;

            case SvgUnitType.Point:
                _deviceValue = (value / 72) * ppi;
                break;

            case SvgUnitType.Pixel:
                _deviceValue = value;
                break;

            case SvgUnitType.User:
                _deviceValue = value;
                break;

            case SvgUnitType.Percentage:
                // Can't calculate if there is no style owner
                var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.GetBoundable());
                if (boundable == null)
                {
                    _deviceValue = value;
                    break;
                }

                System.Drawing.SizeF size = boundable.Bounds.Size;

                switch (renderType)
                {
                case UnitRenderingType.Horizontal:
                    _deviceValue = (size.Width / 100) * value;
                    break;

                case UnitRenderingType.HorizontalOffset:
                    _deviceValue = (size.Width / 100) * value + boundable.Location.X;
                    break;

                case UnitRenderingType.Vertical:
                    _deviceValue = (size.Height / 100) * value;
                    break;

                case UnitRenderingType.VerticalOffset:
                    _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
                    break;

                default:
                    _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    break;
                }
                break;

            default:
                _deviceValue = value;
                break;
            }
            return(this._deviceValue.Value);
        }
Esempio n. 2
0
            private IList <float> GetValues(int maxCount, Func <SvgTextBase, IEnumerable <SvgUnit> > listGetter, UnitRenderingType renderingType)
            {
                var currState   = this;
                int charCount   = 0;
                var results     = new List <float>();
                int resultCount = 0;

                while (currState != null)
                {
                    charCount += currState.NumChars;
                    results.AddRange(listGetter.Invoke(currState.Element).Skip(charCount).Take(maxCount).Select(p => p.ToDeviceValue(currState.Renderer, renderingType, currState.Element)));
                    if (results.Count > resultCount)
                    {
                        maxCount   -= results.Count - resultCount;
                        charCount  += results.Count - resultCount;
                        resultCount = results.Count;
                    }

                    if (maxCount < 1)
                    {
                        return(results);
                    }

                    currState = currState.Parent;
                }

                return(results);
            }
Esempio n. 3
0
            private IList<float> GetValues(int maxCount, Func<SvgTextBase, IEnumerable<SvgUnit>> listGetter, UnitRenderingType renderingType)
            {
                var currState = this;
                int charCount = 0;
                var results = new List<float>();
                int resultCount = 0;

                while (currState != null)
                {
                    charCount += currState.NumChars;
                    results.AddRange(listGetter.Invoke(currState.Element).Skip(charCount).Take(maxCount).Select(p => p.ToDeviceValue(currState.Renderer, renderingType, currState.Element)));
                    if (results.Count > resultCount)
                    {
                        maxCount -= results.Count - resultCount;
                        charCount += results.Count - resultCount;
                        resultCount = results.Count;
                    }

                    if (maxCount < 1) return results;

                    currState = currState.Parent;
                }

                return results;
            }
Esempio n. 4
0
        public static float ToDeviceValue(this SvgUnit svgUnit, UnitRenderingType renderType, SvgElement?owner, SKRect skBounds)
        {
            /*
             * // 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;

            var type  = svgUnit.Type;
            var value = svgUnit.Value;

            float?_deviceValue = null;
            //if (value == 0.0f)
            //{
            //    _deviceValue = 0.0f;
            //    return _deviceValue.Value;
            //}

            float points;

            switch (type)
            {
            case SvgUnitType.Em:
                points       = value * 9;
                _deviceValue = (points / 72.0f) * ppi;
                // TODO: Implement GetFont for Skia.
                //using (var currFont = GetFont(renderer, owner))
                //{
                //    if (currFont == null)
                //    {
                //        points = (float)(value * 9);
                //        _deviceValue = (points / 72.0f) * ppi;
                //    }
                //    else
                //    {
                //        _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                //    }
                //}
                break;

            case SvgUnitType.Ex:
                points       = value * 9;
                _deviceValue = (points * 0.5f / 72.0f) * ppi;
                // TODO: Implement GetFont for Skia.
                //using (var currFont = GetFont(renderer, owner))
                //{
                //    if (currFont == null)
                //    {
                //        points = (float)(value * 9);
                //        _deviceValue = (points * 0.5f / 72.0f) * ppi;
                //    }
                //    else
                //    {
                //        _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                //    }
                //    break;
                //}
                break;

            case SvgUnitType.Centimeter:
                _deviceValue = (value / cmInInch) * ppi;
                break;

            case SvgUnitType.Inch:
                _deviceValue = value * ppi;
                break;

            case SvgUnitType.Millimeter:
                _deviceValue = (value / 10) / cmInInch * ppi;
                break;

            case SvgUnitType.Pica:
                _deviceValue = ((value * 12) / 72) * ppi;
                break;

            case SvgUnitType.Point:
                _deviceValue = (value / 72) * ppi;
                break;

            case SvgUnitType.Pixel:
                _deviceValue = value;
                break;

            case SvgUnitType.User:
                _deviceValue = value;
                break;

            case SvgUnitType.Percentage:
                var size = skBounds.Size;

                switch (renderType)
                {
                case UnitRenderingType.Horizontal:
                    _deviceValue = (size.Width / 100) * value;
                    break;

                case UnitRenderingType.HorizontalOffset:
                    _deviceValue = (size.Width / 100) * value + skBounds.Location.X;
                    break;

                case UnitRenderingType.Vertical:
                    _deviceValue = (size.Height / 100) * value;
                    break;

                case UnitRenderingType.VerticalOffset:
                    _deviceValue = (size.Height / 100) * value + skBounds.Location.Y;
                    break;

                default:
                case UnitRenderingType.Other:
                    // Calculate a percentage value of the normalized viewBox diagonal length.
                    if (owner?.OwnerDocument != null && owner.OwnerDocument.ViewBox != null && owner.OwnerDocument.ViewBox.Width != 0 && owner.OwnerDocument.ViewBox.Height != 0)
                    {
                        _deviceValue = (float)(Math.Sqrt(Math.Pow(owner.OwnerDocument.ViewBox.Width, 2) + Math.Pow(owner.OwnerDocument.ViewBox.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    }
                    else
                    {
                        _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    }

                    break;
                }
                break;

            default:
                _deviceValue = value;
                break;
            }
            return(_deviceValue.Value);
        }
Esempio n. 5
0
        internal static float ToDeviceValue(this SvgUnit svgUnit, UnitRenderingType renderType, SvgElement?owner, SKRect skBounds)
        {
            const float cmInInch = 2.54f;
            var         ppi      = SvgDocument.PointsPerInch;
            var         type     = svgUnit.Type;
            var         value    = svgUnit.Value;
            float?      _deviceValue;
            float       points;
            float?      ownerFontSize = owner?.FontSize;

            switch (type)
            {
            case SvgUnitType.Em:
                if (ownerFontSize.HasValue)
                {
                    _deviceValue = ownerFontSize.Value * value;
                }
                else
                {
                    points       = value * 9;
                    _deviceValue = points / 72.0f * ppi;
                }
                break;

            case SvgUnitType.Ex:
                points       = value * 9;
                _deviceValue = points * 0.5f / 72.0f * ppi;
                break;

            case SvgUnitType.Centimeter:
                _deviceValue = value / cmInInch * ppi;
                break;

            case SvgUnitType.Inch:
                _deviceValue = value * ppi;
                break;

            case SvgUnitType.Millimeter:
                _deviceValue = value / 10 / cmInInch * ppi;
                break;

            case SvgUnitType.Pica:
                _deviceValue = value * 12 / 72 * ppi;
                break;

            case SvgUnitType.Point:
                _deviceValue = value / 72 * ppi;
                break;

            case SvgUnitType.Pixel:
                _deviceValue = value;
                break;

            case SvgUnitType.User:
                _deviceValue = value;
                break;

            case SvgUnitType.Percentage:
                var size = skBounds.Size;

                switch (renderType)
                {
                case UnitRenderingType.Horizontal:
                    _deviceValue = size.Width / 100 * value;
                    break;

                case UnitRenderingType.HorizontalOffset:
                    _deviceValue = size.Width / 100 * value + skBounds.Location.X;
                    break;

                case UnitRenderingType.Vertical:
                    _deviceValue = size.Height / 100 * value;
                    break;

                case UnitRenderingType.VerticalOffset:
                    _deviceValue = size.Height / 100 * value + skBounds.Location.Y;
                    break;

                default:
                case UnitRenderingType.Other:
                    if (owner?.OwnerDocument?.ViewBox is { } && owner.OwnerDocument.ViewBox.Width != 0 && owner.OwnerDocument.ViewBox.Height != 0)
                    {
                        _deviceValue = (float)(Math.Sqrt(Math.Pow(owner.OwnerDocument.ViewBox.Width, 2) + Math.Pow(owner.OwnerDocument.ViewBox.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    }
                    else
                    {
                        _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    }
                    break;
                }
Esempio n. 6
0
File: SvgUnit.cs Progetto: vvvv/SVG
        /// <summary>
        /// Converts the current unit to one that can be used at render time.
        /// </summary>
        /// <param name="boundable">The container element used as the basis for calculations</param>
        /// <returns>The representation of the current unit in a device value (usually pixels).</returns>
        public float ToDeviceValue(ISvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // 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;

            var type = this.Type;
            var value = this.Value;

            float points;

            switch (type)
            {
                case SvgUnitType.Em:
                    using (var currFont = GetFont(renderer, owner))
                    {
                        if (currFont == null)
                        {
                            points = (float)(value * 9);
                            _deviceValue = (points / 72.0f) * ppi;
                        }
                        else
                        {
                            _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                        }
                    }
                    break;
                case SvgUnitType.Ex:
                    using (var currFont = GetFont(renderer, owner))
                    {
                        if (currFont == null)
                        {
                            points = (float)(value * 9);
                            _deviceValue = (points * 0.5f / 72.0f) * ppi;
                        }
                        else
                        {
                            _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                        }
                        break;
                    }
                case SvgUnitType.Centimeter:
                    _deviceValue = (float)((value / cmInInch) * ppi);
                    break;
                case SvgUnitType.Inch:
                    _deviceValue = value * ppi;
                    break;
                case SvgUnitType.Millimeter:
                    _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                    break;
                case SvgUnitType.Pica:
                    _deviceValue = ((value * 12) / 72) * ppi;
                    break;
                case SvgUnitType.Point:
                    _deviceValue = (value / 72) * ppi;
                    break;
                case SvgUnitType.Pixel:
                    _deviceValue = value;
                    break;
                case SvgUnitType.User:
                    _deviceValue = value;
                    break;
                case SvgUnitType.Percentage:
                    // Can't calculate if there is no style owner
                    var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.GetBoundable());
                    if (boundable == null)
                    {
                        _deviceValue = value;
                        break;
                    }

                    System.Drawing.SizeF size = boundable.Bounds.Size;

                    switch (renderType)
                    {
                        case UnitRenderingType.Horizontal:
                            _deviceValue = (size.Width / 100) * value;
                            break;
                        case UnitRenderingType.HorizontalOffset:
                            _deviceValue = (size.Width / 100) * value + boundable.Location.X;
                            break;
                        case UnitRenderingType.Vertical:
                            _deviceValue = (size.Height / 100) * value;
                            break;
                        case UnitRenderingType.VerticalOffset:
                            _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
                            break;
                        default:
                            _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                            break;
                    }
                    break;
                default:
                    _deviceValue = value;
                    break;
            }
            return this._deviceValue.Value;
        }
Esempio n. 7
0
        /// <summary>
        /// Converts the current unit to one that can be used at render time.
        /// </summary>
        /// <param name="boundable">The container element used as the basis for calculations</param>
        /// <returns>The representation of the current unit in a device value (usually pixels).</returns>
        public float ToDeviceValue(SvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // 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;

            var type  = this.Type;
            var value = this.Value;

            // Deal with fractional pattern units
            var coordElem = owner as ISvgSupportsCoordinateUnits;

            if (coordElem != null && coordElem.GetUnits() == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
            {
                type   = SvgUnitType.Percentage;
                value *= 100;
            }

            var element = owner as SvgElement;

            if (element != null)
            {
                var pattern = element.Parents.OfType <SvgPatternServer>().FirstOrDefault();
                if (pattern != null && pattern.PatternContentUnits == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
                {
                    type   = SvgUnitType.Percentage;
                    value *= 100;
                }
            }

            float points;
            Font  currFont;

            switch (type)
            {
            case SvgUnitType.Em:
                currFont = GetFont(renderer, owner);
                if (currFont == null)
                {
                    points       = (float)(value * 9);
                    _deviceValue = (points / 72.0f) * ppi;
                }
                else
                {
                    _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                }
                break;

            case SvgUnitType.Ex:
                currFont = GetFont(renderer, owner);
                if (currFont == null)
                {
                    points       = (float)(value * 9);
                    _deviceValue = (points * 0.5f / 72.0f) * ppi;
                }
                else
                {
                    _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                }
                break;

            case SvgUnitType.Centimeter:
                _deviceValue = (float)((value / cmInInch) * ppi);
                break;

            case SvgUnitType.Inch:
                _deviceValue = value * ppi;
                break;

            case SvgUnitType.Millimeter:
                _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                break;

            case SvgUnitType.Pica:
                _deviceValue = ((value * 12) / 72) * ppi;
                break;

            case SvgUnitType.Point:
                _deviceValue = (value / 72) * ppi;
                break;

            case SvgUnitType.Pixel:
                _deviceValue = value;
                break;

            case SvgUnitType.User:
                _deviceValue = value;
                break;

            case SvgUnitType.Percentage:
                // Can't calculate if there is no style owner
                var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.Boundable());
                if (boundable == null)
                {
                    _deviceValue = value;
                    break;
                }

                System.Drawing.SizeF size = boundable.Bounds.Size;

                switch (renderType)
                {
                case UnitRenderingType.Horizontal:
                    _deviceValue = (size.Width / 100) * value;
                    break;

                case UnitRenderingType.HorizontalOffset:
                    _deviceValue = (size.Width / 100) * value + boundable.Location.X;
                    break;

                case UnitRenderingType.Vertical:
                    _deviceValue = (size.Height / 100) * value;
                    break;

                case UnitRenderingType.VerticalOffset:
                    _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
                    break;

                default:
                    _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                    break;
                }
                break;

            default:
                _deviceValue = value;
                break;
            }
            return(this._deviceValue.Value);
        }
Esempio n. 8
0
        /// <summary>
        /// Converts the current unit to one that can be used at render time.
        /// </summary>
        /// <param name="boundable">The container element used as the basis for calculations</param>
        /// <returns>The representation of the current unit in a device value (usually pixels).</returns>
        public float ToDeviceValue(SvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // 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;

            var type = this.Type;
            var value = this.Value;

            // Deal with fractional pattern units
            var coordElem = owner as ISvgSupportsCoordinateUnits;
            if (coordElem != null && coordElem.GetUnits() == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
            {
                type = SvgUnitType.Percentage;
                value *= 100;
            }

            var element = owner as SvgElement;
            if (element != null)
            {
                var pattern = element.Parents.OfType<SvgPatternServer>().FirstOrDefault();
                if (pattern != null && pattern.PatternContentUnits == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
                {
                    type = SvgUnitType.Percentage;
                    value *= 100;
                }
            }

            float points;
            Font currFont;

            switch (type)
            {
                case SvgUnitType.Em:
                    currFont = GetFont(renderer, owner);
                    if (currFont == null)
                    {
                        points = (float)(value * 9);
                        _deviceValue = (points / 72.0f) * ppi;
                    }
                    else
                    {
                        _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                    }
                    break;
                case SvgUnitType.Ex:
                    currFont = GetFont(renderer, owner);
                    if (currFont == null)
                    {
                        points = (float)(value * 9);
                        _deviceValue = (points * 0.5f / 72.0f) * ppi;
                    }
                    else
                    {
                        _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                    }
                    break;
                case SvgUnitType.Centimeter:
                    _deviceValue = (float)((value / cmInInch) * ppi);
                    break;
                case SvgUnitType.Inch:
                    _deviceValue = value * ppi;
                    break;
                case SvgUnitType.Millimeter:
                    _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                    break;
                case SvgUnitType.Pica:
                    _deviceValue = ((value * 12) / 72) * ppi;
                    break;
                case SvgUnitType.Point:
                    _deviceValue = (value / 72) * ppi;
                    break;
                case SvgUnitType.Pixel:
                    _deviceValue = value;
                    break;
                case SvgUnitType.User:
                    _deviceValue = value;
                    break;
                case SvgUnitType.Percentage:
                    // Can't calculate if there is no style owner
                    var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.Boundable());
                    if (boundable == null)
                    {
                        _deviceValue = value;
                        break;
                    }

                    System.Drawing.SizeF size = boundable.Bounds.Size;

                    switch (renderType)
                    {
                        case UnitRenderingType.Horizontal:
                            _deviceValue = (size.Width / 100) * value;
                            break;
                        case UnitRenderingType.HorizontalOffset:
                            _deviceValue = (size.Width / 100) * value + boundable.Location.X;
                            break;
                        case UnitRenderingType.Vertical:
                            _deviceValue = (size.Height / 100) * value;
                            break;
                        case UnitRenderingType.VerticalOffset:
                            _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
                            break;
                        default:
                            _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                            break;
                    }
                    break;
                default:
                    _deviceValue = value;
                    break;
            }
            return this._deviceValue.Value;
        }
Esempio n. 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(ISvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // 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;

            var type  = this.Type;
            var value = this.Value;

            switch (type)
            {
            case SvgUnitType.Em:
                _deviceValue = value;
                break;

            case SvgUnitType.Ex:
                _deviceValue = value;
                break;

            case SvgUnitType.Centimeter:
                _deviceValue = (float)((value / cmInInch) * ppi);
                break;

            case SvgUnitType.Inch:
                _deviceValue = value * ppi;
                break;

            case SvgUnitType.Millimeter:
                _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                break;

            case SvgUnitType.Pica:
                _deviceValue = ((value * 12) / 72) * ppi;
                break;

            case SvgUnitType.Point:
                _deviceValue = (value / 72) * ppi;
                break;

            case SvgUnitType.Pixel:
                _deviceValue = value;
                break;

            case SvgUnitType.User:
                _deviceValue = value;
                break;

            case SvgUnitType.Percentage:
                _deviceValue = value;
                break;

            default:
                _deviceValue = value;
                break;
            }
            return(this._deviceValue.Value);
        }