/// <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); }
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); }
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; }
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); }
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; }
/// <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; }
/// <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); }
/// <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; }
/// <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); }