2020-06-07 20:30:37 +03:00
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))]
2022-01-10 22:02:27 +03:00
public partial struct SvgUnit
2008-03-07 17:47:05 +03:00
{
private SvgUnitType _type ;
private float _value ;
private bool _isEmpty ;
private float? _deviceValue ;
2008-06-17 17:20:58 +04:00
/// <summary>
/// Gets and empty <see cref="SvgUnit"/>.
/// </summary>
2014-08-23 19:44:44 +04:00
public static readonly SvgUnit Empty = new SvgUnit ( SvgUnitType . User , 0 ) { _isEmpty = true } ;
2008-03-07 17:47:05 +03:00
2010-11-02 03:11:11 +03:00
/// <summary>
/// Gets an <see cref="SvgUnit"/> with a value of none.
/// </summary>
2013-06-04 18:19:56 +04:00
public static readonly SvgUnit None = new SvgUnit ( SvgUnitType . None , 0f ) ;
2010-11-02 03:11:11 +03:00
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 ; }
}
2010-11-02 14:54:59 +03:00
/// <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 ; }
}
2008-06-17 17:20:58 +04:00
/// <summary>
/// Gets the <see cref="SvgUnitType"/> of unit.
/// </summary>
2008-03-07 17:47:05 +03:00
public SvgUnitType Type
{
get { return this . _type ; }
}
2008-06-17 17:20:58 +04:00
/// <summary>
/// Converts the current unit to a percentage, if applicable.
/// </summary>
2018-11-21 22:41:39 +03:00
/// <returns>An <see cref="SvgUnit"/> of type <see cref="SvgUnitType.Percentage"/>.</returns>
2008-04-29 14:53:14 +04:00
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 ( ) ;
}
}
2014-07-09 02:55:43 +04:00
#region Equals and GetHashCode implementation
public override bool Equals ( object obj )
{
if ( obj = = null ) return false ;
2019-05-20 22:46:35 +03:00
if ( ! ( obj . GetType ( ) = = typeof ( SvgUnit ) ) ) return false ;
2008-03-07 17:47:05 +03:00
2009-08-24 20:37:20 +04:00
var unit = ( SvgUnit ) obj ;
2008-03-07 17:47:05 +03:00
return ( unit . Value = = this . Value & & unit . Type = = this . Type ) ;
2014-07-09 02:55:43 +04:00
}
2019-05-20 22:46:35 +03:00
2014-07-09 02:55:43 +04:00
public bool Equals ( SvgUnit other )
{
return this . _type = = other . _type & & ( this . _value = = other . _value ) ;
}
2019-05-20 22:46:35 +03:00
2014-07-09 02:55:43 +04:00
public override int GetHashCode ( )
{
int hashCode = 0 ;
2019-05-20 22:46:35 +03:00
unchecked
{
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 ;
}
2019-05-20 22:46:35 +03:00
2014-07-09 02:55:43 +04:00
public static bool operator = = ( SvgUnit lhs , SvgUnit rhs )
{
return lhs . Equals ( rhs ) ;
}
2019-05-20 22:46:35 +03:00
2014-07-09 02:55:43 +04:00
public static bool operator ! = ( SvgUnit lhs , SvgUnit rhs )
{
return ! ( lhs = = rhs ) ;
}
#endregion
2009-08-24 20:37:20 +04:00
2008-03-07 17:47:05 +03:00
public override string ToString ( )
{
string type = string . Empty ;
switch ( this . Type )
{
2010-11-02 03:11:11 +03:00
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 ;
}
2021-01-12 20:36:33 +03:00
return string . Concat ( this . Value . ToSvgString ( ) , type ) ;
2008-03-07 17:47:05 +03:00
}
2008-06-17 17:20:58 +04: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 ) ;
}
2008-06-17 17:20:58 +04:00
/// <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 )
{
2014-08-23 19:44:44 +04:00
this . _isEmpty = false ;
2008-03-07 17:47:05 +03:00
this . _type = type ;
this . _value = value ;
this . _deviceValue = null ;
}
2008-06-17 17:20:58 +04:00
/// <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 )
{
2014-08-23 19:44:44 +04:00
this . _isEmpty = false ;
2008-03-07 17:47:05 +03:00
this . _value = value ;
this . _type = SvgUnitType . User ;
this . _deviceValue = null ;
}
2014-08-04 05:33:49 +04:00
}
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
{
2010-11-02 03:11:11 +03:00
/// <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>
2014-08-04 05:33:49 +04:00
/// 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
}
}