SVG/Source/DataTypes/SvgUnit.cs

245 строки
7.4 KiB
C#
Исходник Постоянная ссылка Обычный вид История

using System;
2008-03-07 17:47:05 +03:00
using System.ComponentModel;
namespace Svg
{
/// <summary>
/// Represents a unit in an Scalable Vector Graphics document.
/// </summary>
[TypeConverter(typeof(SvgUnitConverter))]
public partial struct SvgUnit
2008-03-07 17:47:05 +03:00
{
private SvgUnitType _type;
private float _value;
private bool _isEmpty;
private float? _deviceValue;
/// <summary>
/// Gets and empty <see cref="SvgUnit"/>.
/// </summary>
public static readonly SvgUnit Empty = new SvgUnit(SvgUnitType.User, 0) { _isEmpty = true };
2008-03-07 17:47:05 +03:00
/// <summary>
/// Gets an <see cref="SvgUnit"/> with a value of none.
/// </summary>
public static readonly SvgUnit None = new SvgUnit(SvgUnitType.None, 0f);
2008-03-07 17:47:05 +03:00
/// <summary>
/// Gets a value to determine whether the unit is empty.
/// </summary>
public bool IsEmpty
{
get { return this._isEmpty; }
}
/// <summary>
/// Gets whether this unit is none.
/// </summary>
public bool IsNone
{
get { return _type == SvgUnitType.None; }
}
2008-03-07 17:47:05 +03:00
/// <summary>
/// Gets the value of the unit.
/// </summary>
public float Value
{
get { return this._value; }
}
/// <summary>
/// Gets the <see cref="SvgUnitType"/> of unit.
/// </summary>
2008-03-07 17:47:05 +03:00
public SvgUnitType Type
{
get { return this._type; }
}
/// <summary>
/// Converts the current unit to a percentage, if applicable.
/// </summary>
/// <returns>An <see cref="SvgUnit"/> of type <see cref="SvgUnitType.Percentage"/>.</returns>
public SvgUnit ToPercentage()
{
switch (this.Type)
{
case SvgUnitType.Percentage:
return this;
case SvgUnitType.User:
return new SvgUnit(SvgUnitType.Percentage, this.Value * 100);
default:
throw new NotImplementedException();
}
}
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
#region Equals and GetHashCode implementation
public override bool Equals(object obj)
{
if (obj == null) return false;
if (!(obj.GetType() == typeof(SvgUnit))) return false;
2008-03-07 17:47:05 +03:00
var unit = (SvgUnit)obj;
2008-03-07 17:47:05 +03:00
return (unit.Value == this.Value && unit.Type == this.Type);
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
}
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
public bool Equals(SvgUnit other)
{
return this._type == other._type && (this._value == other._value);
}
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
public override int GetHashCode()
{
int hashCode = 0;
unchecked
{
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
hashCode += 1000000007 * _type.GetHashCode();
hashCode += 1000000009 * _value.GetHashCode();
hashCode += 1000000021 * _isEmpty.GetHashCode();
hashCode += 1000000033 * _deviceValue.GetHashCode();
}
return hashCode;
}
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
public static bool operator ==(SvgUnit lhs, SvgUnit rhs)
{
return lhs.Equals(rhs);
}
Gradient Improvements - Added support for the "gradientTransform" attribute on both linear and radial gradients. The matrix in this attribute needs to be applied to attributes with coordinate values on the gradient element in order to transform them into the correct coordinate space. - Added support for a value of "pad" for the "spreadMode" attribute on both linear and radial gradients. This is the default value but was not implemented correctly. In order to implement, we examine the properties of the gradient along with the element to which the gradient is being applied to determine if we need to expand the bounds of the gradient to fill the element. If so, we do so and adjust the color stops and positions so they are correct for the new gradient bounds. - Divided ISvgStylable into ISvgBoundable and ISvgStylable. The SvgUnit.ToDeviceValue method just needs bounds so it can take ISvgBoundable. Moved SvgDocument.GetDimensions() to SvgFragment and made SvgFragment ISvgBoundable. - Fixed a bug in SvgFragment.PushTransforms where it was calling the SvgUnit.ToDeviceValue overload that takes no parameters. This overload doesn't work if the value being converted is a percentage. (The overload should probably be removed entirely, but we didn't take that on in this commit.) - Fixed an issue in SvgGroup.Bounds where a child with empty bounds would cause the group's bounds to be reported as empty. - Fixed broken build by adding missing SvgMarker.MarkerUnits property. - Converted files that we touched with mixed tabs and spaces to spaces. Also removed unused usings from files we touched. - Converted SvgLinearGradientServer to use properties without backing fields for X1, Y1, etc. in order to match SvgRadialGradientServer. - Moved default value assignments into constructors for consistency.
2014-07-09 02:55:43 +04:00
public static bool operator !=(SvgUnit lhs, SvgUnit rhs)
{
return !(lhs == rhs);
}
#endregion
2008-03-07 17:47:05 +03:00
public override string ToString()
{
string type = string.Empty;
switch (this.Type)
{
case SvgUnitType.None:
return "none";
2008-03-07 17:47:05 +03:00
case SvgUnitType.Pixel:
type = "px";
break;
case SvgUnitType.Point:
type = "pt";
break;
case SvgUnitType.Inch:
type = "in";
break;
case SvgUnitType.Centimeter:
type = "cm";
break;
case SvgUnitType.Millimeter:
type = "mm";
break;
case SvgUnitType.Percentage:
type = "%";
break;
case SvgUnitType.Em:
type = "em";
break;
}
return string.Concat(this.Value.ToSvgString(), type);
2008-03-07 17:47:05 +03:00
}
/// <summary>
/// Performs an implicit conversion from <see cref="System.Single"/> to <see cref="Svg.SvgUnit"/>.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
2008-03-07 17:47:05 +03:00
public static implicit operator SvgUnit(float value)
{
return new SvgUnit(value);
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgUnit"/> struct.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="value">The value.</param>
2008-03-07 17:47:05 +03:00
public SvgUnit(SvgUnitType type, float value)
{
this._isEmpty = false;
2008-03-07 17:47:05 +03:00
this._type = type;
this._value = value;
this._deviceValue = null;
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgUnit"/> struct.
/// </summary>
/// <param name="value">The value.</param>
2008-03-07 17:47:05 +03:00
public SvgUnit(float value)
{
this._isEmpty = false;
2008-03-07 17:47:05 +03:00
this._value = value;
this._type = SvgUnitType.User;
this._deviceValue = null;
}
}
public enum UnitRenderingType
{
Other,
Horizontal,
HorizontalOffset,
Vertical,
VerticalOffset
2008-03-07 17:47:05 +03:00
}
/// <summary>
/// Defines the various types of unit an <see cref="SvgUnit"/> can be.
/// </summary>
public enum SvgUnitType
{
/// <summary>
/// Indicates that the unit holds no value.
/// </summary>
None,
2008-03-07 17:47:05 +03:00
/// <summary>
/// Indicates that the unit is in pixels.
/// </summary>
Pixel,
/// <summary>
/// Indicates that the unit is equal to the pt size of the current font.
/// </summary>
Em,
/// <summary>
/// Indicates that the unit is equal to the x-height of the current font.
/// </summary>
Ex,
/// <summary>
2008-03-07 17:47:05 +03:00
/// Indicates that the unit is a percentage.
/// </summary>
Percentage,
/// <summary>
/// Indicates that the unit has no unit identifier and is a value in the current user coordinate system.
/// </summary>
User,
/// <summary>
/// Indicates the the unit is in inches.
/// </summary>
Inch,
/// <summary>
/// Indicates that the unit is in centimeters.
/// </summary>
Centimeter,
/// <summary>
/// Indicates that the unit is in millimeters.
/// </summary>
Millimeter,
/// <summary>
/// Indicates that the unit is in picas.
/// </summary>
Pica,
/// <summary>
/// Indicates that the unit is in points, the smallest unit of measure, being a subdivision of the larger <see cref="Pica"/>. There are 12 points in the <see cref="Pica"/>.
/// </summary>
Point
}
}