FTSize.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #region MIT License
  2. /*Copyright (c) 2012 Robert Rouhani <robert.rouhani@gmail.com>
  3. SharpFont based on Tao.FreeType, Copyright (c) 2003-2007 Tao Framework Team
  4. Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. this software and associated documentation files (the "Software"), to deal in
  6. the Software without restriction, including without limitation the rights to
  7. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  8. of the Software, and to permit persons to whom the Software is furnished to do
  9. so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.*/
  19. #endregion
  20. using System;
  21. using System.Runtime.InteropServices;
  22. using SharpFont.Internal;
  23. namespace SharpFont
  24. {
  25. /// <summary>
  26. /// FreeType root size class structure. A size object models a face object at a given size.
  27. /// </summary>
  28. public sealed class FTSize : IDisposable
  29. {
  30. #region Fields
  31. private bool userAlloc;
  32. private bool disposed;
  33. private bool duplicate;
  34. private IntPtr reference;
  35. private SizeRec rec;
  36. private Face parentFace;
  37. #endregion
  38. #region Constructors
  39. /// <summary>
  40. /// Initializes a new instance of the <see cref="FTSize"/> class.
  41. /// </summary>
  42. /// <param name="parent">The parent face.</param>
  43. public FTSize(Face parent)
  44. {
  45. IntPtr reference;
  46. Error err = FT.FT_New_Size(parent.Reference, out reference);
  47. if (err != Error.Ok)
  48. throw new FreeTypeException(err);
  49. Reference = reference;
  50. userAlloc = true;
  51. }
  52. internal FTSize(IntPtr reference, bool userAlloc, Face parentFace)
  53. {
  54. Reference = reference;
  55. this.userAlloc = userAlloc;
  56. if (parentFace != null)
  57. {
  58. this.parentFace = parentFace;
  59. parentFace.AddChildSize(this);
  60. }
  61. else
  62. {
  63. duplicate = true;
  64. }
  65. }
  66. /// <summary>
  67. /// Finalizes an instance of the FTSize class.
  68. /// </summary>
  69. ~FTSize()
  70. {
  71. Dispose(false);
  72. }
  73. #endregion
  74. #region Properties
  75. /// <summary>
  76. /// Gets a value indicating whether the object has been disposed.
  77. /// </summary>
  78. public bool IsDisposed
  79. {
  80. get
  81. {
  82. return disposed;
  83. }
  84. }
  85. /// <summary>
  86. /// Gets a handle to the parent face object.
  87. /// </summary>
  88. public Face Face
  89. {
  90. get
  91. {
  92. if (disposed)
  93. throw new ObjectDisposedException("Face", "Cannot access a disposed object.");
  94. return parentFace;
  95. }
  96. }
  97. /// <summary>
  98. /// Gets or sets a typeless pointer, which is unused by the FreeType library or any of its drivers. It can be used by
  99. /// client applications to link their own data to each size object.
  100. /// </summary>
  101. public Generic Generic
  102. {
  103. get
  104. {
  105. if (disposed)
  106. throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
  107. return new Generic(rec.generic);
  108. }
  109. set
  110. {
  111. if (disposed)
  112. throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
  113. value.WriteToUnmanagedMemory(new IntPtr(reference.ToInt64() + Marshal.OffsetOf(typeof(FaceRec), "generic").ToInt64()));
  114. Reference = reference; //update rec.
  115. }
  116. }
  117. /// <summary>
  118. /// Gets metrics for this size object. This field is read-only.
  119. /// </summary>
  120. public SizeMetrics Metrics
  121. {
  122. get
  123. {
  124. if (disposed)
  125. throw new ObjectDisposedException("Metrics", "Cannot access a disposed object.");
  126. return new SizeMetrics(rec.metrics);
  127. }
  128. }
  129. internal IntPtr Reference
  130. {
  131. get
  132. {
  133. if (disposed)
  134. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  135. return reference;
  136. }
  137. set
  138. {
  139. if (disposed)
  140. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  141. reference = value;
  142. this.rec = PInvokeHelper.PtrToStructure<SizeRec>(reference);
  143. }
  144. }
  145. #endregion
  146. #region Public Methods
  147. /// <summary><para>
  148. /// Even though it is possible to create several size objects for a given face (see
  149. /// <see cref="SharpFont.Face.NewSize"/> for details), functions like <see cref="SharpFont.Face.LoadGlyph"/> or
  150. /// <see cref="SharpFont.Face.LoadChar"/> only use the one which has been activated last to determine the
  151. /// ‘current character pixel size’.
  152. /// </para><para>
  153. /// This function can be used to ‘activate’ a previously created size object.
  154. /// </para></summary>
  155. /// <remarks>
  156. /// If ‘face’ is the size's parent face object, this function changes the value of ‘face->size’ to the input
  157. /// size handle.
  158. /// </remarks>
  159. public void Activate()
  160. {
  161. if (disposed)
  162. throw new ObjectDisposedException("Activate", "Cannot access a disposed object.");
  163. Error err = FT.FT_Activate_Size(Reference);
  164. if (err != Error.Ok)
  165. throw new FreeTypeException(err);
  166. }
  167. /// <summary>
  168. /// Diposes the FTSize.
  169. /// </summary>
  170. public void Dispose()
  171. {
  172. Dispose(true);
  173. GC.SuppressFinalize(this);
  174. }
  175. #endregion
  176. #region Private Methods
  177. private void Dispose(bool disposing)
  178. {
  179. if (!disposed)
  180. {
  181. disposed = true;
  182. //only dispose the user allocated sizes that are not duplicates.
  183. if (userAlloc && !duplicate)
  184. {
  185. Error err = FT.FT_Done_Size(reference);
  186. if (err != Error.Ok)
  187. throw new FreeTypeException(err);
  188. // removes itself from the parent Face, with a check to prevent this from happening when Face is
  189. // being disposed (Face disposes all it's children with a foreach loop, this causes an
  190. // InvalidOperationException for modifying a collection during enumeration)
  191. if (!parentFace.IsDisposed)
  192. parentFace.RemoveChildSize(this);
  193. }
  194. reference = IntPtr.Zero;
  195. rec = null;
  196. }
  197. }
  198. #endregion
  199. }
  200. }