#region MIT License /*Copyright (c) 2012-2013, 2015-2016 Robert Rouhani SharpFont based on Tao.FreeType, Copyright (c) 2003-2007 Tao Framework Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ #endregion using System; using System.Runtime.InteropServices; namespace SharpFont { /// /// Represents a fixed-point decimal value with 6 bits of decimal precision. /// [StructLayout(LayoutKind.Sequential)] public struct Fixed26Dot6 : IEquatable, IComparable { #region Fields /// /// The raw 26.6 integer. /// private int value; #endregion #region Constructors /// /// Initializes a new instance of the struct. /// /// An integer value. public Fixed26Dot6(int value) { this.value = value << 6; } /// /// Initializes a new instance of the struct. /// /// A floating point value. public Fixed26Dot6(float value) { this.value = (int)(value * 64); } /// /// Initializes a new instance of the struct. /// /// A floating point value. public Fixed26Dot6(double value) { this.value = (int)(value * 64); } /// /// Initializes a new instance of the struct. /// /// A floating point value. public Fixed26Dot6(decimal value) { this.value = (int)(value * 64); } #endregion #region Properties /// /// Gets the raw 26.6 integer. /// public int Value { get { return value; } } #endregion #region Methods #region Static /// /// Creates a from an int containing a 26.6 value. /// /// A 26.6 value. /// An instance of . public static Fixed26Dot6 FromRawValue(int value) { Fixed26Dot6 f = new Fixed26Dot6(); f.value = value; return f; } /// /// Creates a new from a /// /// A value. /// The equivalent value. public static Fixed26Dot6 FromInt32(int value) { return new Fixed26Dot6(value); } /// /// Creates a new from . /// /// A floating-point value. /// A fixed 26.6 value. public static Fixed26Dot6 FromSingle(float value) { return new Fixed26Dot6(value); } /// /// Creates a new from a . /// /// A floating-point value. /// A fixed 26.6 value. public static Fixed26Dot6 FromDouble(double value) { return new Fixed26Dot6(value); } /// /// Creates a new from a . /// /// A floating-point value. /// A fixed 26.6 value. public static Fixed26Dot6 FromDecimal(decimal value) { return new Fixed26Dot6(value); } /// /// Adds two 26.6 values together. /// /// The left operand. /// The right operand. /// The result of the addition. public static Fixed26Dot6 Add(Fixed26Dot6 left, Fixed26Dot6 right) { return Fixed26Dot6.FromRawValue(left.value + right.value); } /// /// Subtacts one 26.6 values from another. /// /// The left operand. /// The right operand. /// The result of the subtraction. public static Fixed26Dot6 Subtract(Fixed26Dot6 left, Fixed26Dot6 right) { return Fixed26Dot6.FromRawValue(left.value - right.value); } /// /// Multiplies two 26.6 values together. /// /// The left operand. /// The right operand. /// The result of the multiplication. public static Fixed26Dot6 Multiply(Fixed26Dot6 left, Fixed26Dot6 right) { long mul = (long)left.value * (long)right.value; Fixed26Dot6 ans = new Fixed26Dot6(); ans.value = (int)(mul >> 6); return ans; } /// /// Divides one 26.6 values from another. /// /// The left operand. /// The right operand. /// The result of the division. public static Fixed26Dot6 Divide(Fixed26Dot6 left, Fixed26Dot6 right) { long div = ((long)left.Value << 6) / right.value; Fixed26Dot6 ans = new Fixed26Dot6(); ans.value = (int)div; return ans; } #endregion #region Operators /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator Fixed26Dot6(short value) { return new Fixed26Dot6(value); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator Fixed26Dot6(int value) { return new Fixed26Dot6(value); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator Fixed26Dot6(float value) { return new Fixed26Dot6(value); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator Fixed26Dot6(double value) { return new Fixed26Dot6(value); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator Fixed26Dot6(decimal value) { return new Fixed26Dot6(value); } /// /// Casts a to a . /// /// /// This operation can result in a loss of data. /// /// A value. /// The equivalent value. public static explicit operator int(Fixed26Dot6 value) { return value.ToInt32(); } /// /// Casts a to a . /// /// /// This operation can result in a loss of data. /// /// A value. /// The equivalent value. public static explicit operator float(Fixed26Dot6 value) { return value.ToSingle(); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator double(Fixed26Dot6 value) { return value.ToDouble(); } /// /// Casts a to a . /// /// A value. /// The equivalent value. public static implicit operator decimal(Fixed26Dot6 value) { return value.ToDecimal(); } /// /// Adds two 26.6 values together. /// /// The left operand. /// The right operand. /// The result of the addition. public static Fixed26Dot6 operator +(Fixed26Dot6 left, Fixed26Dot6 right) { return Add(left, right); } /// /// Subtacts one 26.6 values from another. /// /// The left operand. /// The right operand. /// The result of the subtraction. public static Fixed26Dot6 operator -(Fixed26Dot6 left, Fixed26Dot6 right) { return Subtract(left, right); } /// /// Multiplies two 26.6 values together. /// /// The left operand. /// The right operand. /// The result of the multiplication. public static Fixed26Dot6 operator *(Fixed26Dot6 left, Fixed26Dot6 right) { return Multiply(left, right); } /// /// Divides one 26.6 values from another. /// /// The left operand. /// The right operand. /// The result of the division. public static Fixed26Dot6 operator /(Fixed26Dot6 left, Fixed26Dot6 right) { return Divide(left, right); } /// /// Compares two instances of for equality. /// /// The left operand. /// The right operand. /// A value indicating whether the two instances are equal. public static bool operator ==(Fixed26Dot6 left, Fixed26Dot6 right) { return left.Equals(right); } /// /// Compares two instances of for inequality. /// /// The left operand. /// The right operand. /// A value indicating whether the two instances are not equal. public static bool operator !=(Fixed26Dot6 left, Fixed26Dot6 right) { return !(left == right); } /// /// Checks if the left operand is less than the right operand. /// /// The left operand. /// The right operand. /// A value indicating whether left is less than right. public static bool operator <(Fixed26Dot6 left, Fixed26Dot6 right) { return left.CompareTo(right) < 0; } /// /// Checks if the left operand is less than or equal to the right operand. /// /// The left operand. /// The right operand. /// A value indicating whether left is less than or equal to right. public static bool operator <=(Fixed26Dot6 left, Fixed26Dot6 right) { return left.CompareTo(right) <= 0; } /// /// Checks if the left operand is greater than the right operand. /// /// The left operand. /// The right operand. /// A value indicating whether left is greater than right. public static bool operator >(Fixed26Dot6 left, Fixed26Dot6 right) { return left.CompareTo(right) > 0; } /// /// Checks if the left operand is greater than or equal to the right operand. /// /// The left operand. /// The right operand. /// A value indicating whether left is greater than or equal to right. public static bool operator >=(Fixed26Dot6 left, Fixed26Dot6 right) { return left.CompareTo(right) >= 0; } #endregion #region Instance /// /// Removes the decimal part of the value. /// /// The truncated number. public int Floor() { return value >> 6; } /// /// Rounds to the nearest whole number. /// /// The nearest whole number. public int Round() { //add 2^5, rounds the integer part up if the decimal value is >= 0.5 return (value + 32) >> 6; } /// /// Rounds up to the next whole number. /// /// The next whole number. public int Ceiling() { //add 2^6 - 1, rounds the integer part up if there's any decimal value return (value + 63) >> 6; } /// /// Converts the value to a . The value is floored. /// /// An integer value. public int ToInt32() { return Floor(); } /// /// Converts the value to a . /// /// A floating-point value. public float ToSingle() { return value / 64f; } /// /// Converts the value to a . /// /// A floating-point value. public double ToDouble() { return value / 64d; } /// /// Converts the value to a . /// /// A decimal value. public decimal ToDecimal() { return value / 64m; } /// /// Compares this instance to another for equality. /// /// A . /// A value indicating whether the two instances are equal. public bool Equals(Fixed26Dot6 other) { return value == other.value; } /// /// Compares this instnace with another and returns an integer that indicates /// whether the current instance precedes, follows, or occurs in the same position in the sort order as the /// other . /// /// A . /// A value indicating the relative order of the instances. public int CompareTo(Fixed26Dot6 other) { return value.CompareTo(other.value); } #endregion #region Overrides /// /// Returns a string that represents the current object. /// /// An object that supplies culture-specific formatting information. /// A string that represents the current object. public string ToString(IFormatProvider provider) { return ToDecimal().ToString(provider); } /// /// Returns a string that represents the current object. /// /// A numeric format string. /// A string that represents the current object. public string ToString(string format) { return ToDecimal().ToString(format); } /// /// Returns a string that represents the current object. /// /// A numeric format string. /// An object that supplies culture-specific formatting information. /// A string that represents the current object. public string ToString(string format, IFormatProvider provider) { return ToDecimal().ToString(format, provider); } /// /// Returns a string that represents the current object. /// /// A string that represents the current object. public override string ToString() { return ToDecimal().ToString(); } /// /// Calculates a hash code for the current object. /// /// A hash code for the current object. public override int GetHashCode() { return value.GetHashCode(); } /// /// Determines whether the specified object isequal to the current object. /// /// The object to compare with the current object. /// A value indicating equality between the two objects. public override bool Equals(object obj) { if (obj is Fixed26Dot6) return this.Equals((Fixed26Dot6)obj); else if (obj is int) return value == ((Fixed26Dot6)obj).value; else return false; } #endregion #endregion } }