Library.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  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.Collections.Generic;
  22. using SharpFont.Cache;
  23. using SharpFont.Internal;
  24. using SharpFont.TrueType;
  25. namespace SharpFont
  26. {
  27. /// <summary><para>
  28. /// A handle to a FreeType library instance. Each ‘library’ is completely independent from the others; it is the
  29. /// ‘root’ of a set of objects like fonts, faces, sizes, etc.
  30. /// </para><para>
  31. /// It also embeds a memory manager (see <see cref="Memory"/>), as well as a scan-line converter object (see
  32. /// <see cref="Raster"/>).
  33. /// </para><para>
  34. /// For multi-threading applications each thread should have its own <see cref="Library"/> object.
  35. /// </para></summary>
  36. public sealed class Library : IDisposable
  37. {
  38. #region Fields
  39. private IntPtr reference;
  40. private bool customMemory;
  41. private bool disposed;
  42. private List<Face> childFaces;
  43. private List<Glyph> childGlyphs;
  44. private List<Outline> childOutlines;
  45. private List<Stroker> childStrokers;
  46. private List<Manager> childManagers;
  47. #endregion
  48. #region Constructors
  49. /// <summary>
  50. /// Initializes a new instance of the <see cref="Library"/> class.
  51. /// </summary>
  52. public Library()
  53. : this(false)
  54. {
  55. IntPtr libraryRef;
  56. Error err = FT.FT_Init_FreeType(out libraryRef);
  57. if (err != Error.Ok)
  58. throw new FreeTypeException(err);
  59. Reference = libraryRef;
  60. }
  61. /// <summary>
  62. /// Initializes a new instance of the <see cref="Library"/> class.
  63. /// </summary>
  64. /// <param name="memory">A custom FreeType memory manager.</param>
  65. public Library(Memory memory)
  66. : this(false)
  67. {
  68. IntPtr libraryRef;
  69. Error err = FT.FT_New_Library(memory.Reference, out libraryRef);
  70. if (err != Error.Ok)
  71. throw new FreeTypeException(err);
  72. Reference = libraryRef;
  73. customMemory = true;
  74. }
  75. private Library(bool duplicate)
  76. {
  77. childFaces = new List<Face>();
  78. childGlyphs = new List<Glyph>();
  79. childOutlines = new List<Outline>();
  80. childStrokers = new List<Stroker>();
  81. childManagers = new List<Manager>();
  82. }
  83. /// <summary>
  84. /// Finalizes an instance of the <see cref="Library"/> class.
  85. /// </summary>
  86. ~Library()
  87. {
  88. Dispose(false);
  89. }
  90. #endregion
  91. #region Properties
  92. /// <summary>
  93. /// Gets a value indicating whether the object has been disposed.
  94. /// </summary>
  95. public bool IsDisposed
  96. {
  97. get
  98. {
  99. return disposed;
  100. }
  101. }
  102. /// <summary>
  103. /// Gets the version of the FreeType library being used.
  104. /// </summary>
  105. public Version Version
  106. {
  107. get
  108. {
  109. if (disposed)
  110. throw new ObjectDisposedException("Version", "Cannot access a disposed object.");
  111. int major, minor, patch;
  112. FT.FT_Library_Version(Reference, out major, out minor, out patch);
  113. return new Version(major, minor, patch);
  114. }
  115. }
  116. internal IntPtr Reference
  117. {
  118. get
  119. {
  120. if (disposed)
  121. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  122. return reference;
  123. }
  124. set
  125. {
  126. if (disposed)
  127. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  128. reference = value;
  129. }
  130. }
  131. #endregion
  132. #region Methods
  133. #region Base Interface
  134. /// <summary>
  135. /// This function calls <see cref="OpenFace"/> to open a font by its pathname.
  136. /// </summary>
  137. /// <param name="path">A path to the font file.</param>
  138. /// <param name="faceIndex">The index of the face within the font. The first face has index 0.</param>
  139. /// <returns>
  140. /// A handle to a new face object. If ‘faceIndex’ is greater than or equal to zero, it must be non-NULL.
  141. /// </returns>
  142. /// <see cref="OpenFace"/>
  143. public Face NewFace(string path, int faceIndex)
  144. {
  145. if (disposed)
  146. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  147. return new Face(this, path, faceIndex);
  148. }
  149. /// <summary>
  150. /// This function calls <see cref="OpenFace"/> to open a font which has been loaded into memory.
  151. /// </summary>
  152. /// <remarks>
  153. /// You must not deallocate the memory before calling <see cref="Face.Dispose()"/>.
  154. /// </remarks>
  155. /// <param name="file">A pointer to the beginning of the font data.</param>
  156. /// <param name="faceIndex">The index of the face within the font. The first face has index 0.</param>
  157. /// <returns>
  158. /// A handle to a new face object. If ‘faceIndex’ is greater than or equal to zero, it must be non-NULL.
  159. /// </returns>
  160. /// <see cref="OpenFace"/>
  161. public Face NewMemoryFace(byte[] file, int faceIndex)
  162. {
  163. if (disposed)
  164. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  165. return new Face(this, file, faceIndex);
  166. }
  167. /// <summary>
  168. /// Create a <see cref="Face"/> object from a given resource described by <see cref="OpenArgs"/>.
  169. /// </summary>
  170. /// <remarks><para>
  171. /// Unlike FreeType 1.x, this function automatically creates a glyph slot for the face object which can be
  172. /// accessed directly through <see cref="Face.Glyph"/>.
  173. /// </para><para>
  174. /// OpenFace can be used to quickly check whether the font format of a given font resource is supported by
  175. /// FreeType. If the ‘faceIndex’ field is negative, the function's return value is 0 if the font format is
  176. /// recognized, or non-zero otherwise; the function returns a more or less empty face handle in ‘*aface’ (if
  177. /// ‘aface’ isn't NULL). The only useful field in this special case is <see cref="Face.FaceCount"/> which gives
  178. /// the number of faces within the font file. After examination, the returned <see cref="Face"/> structure
  179. /// should be deallocated with a call to <see cref="Face.Dispose()"/>.
  180. /// </para><para>
  181. /// Each new face object created with this function also owns a default <see cref="FTSize"/> object, accessible
  182. /// as <see cref="Face.Size"/>.
  183. /// </para><para>
  184. /// See the discussion of reference counters in the description of FT_Reference_Face.
  185. /// </para></remarks>
  186. /// <param name="args">
  187. /// A pointer to an <see cref="OpenArgs"/> structure which must be filled by the caller.
  188. /// </param>
  189. /// <param name="faceIndex">The index of the face within the font. The first face has index 0.</param>
  190. /// <returns>
  191. /// A handle to a new face object. If ‘faceIndex’ is greater than or equal to zero, it must be non-NULL.
  192. /// </returns>
  193. public Face OpenFace(OpenArgs args, int faceIndex)
  194. {
  195. if (disposed)
  196. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  197. IntPtr faceRef;
  198. Error err = FT.FT_Open_Face(Reference, args.Reference, faceIndex, out faceRef);
  199. if (err != Error.Ok)
  200. throw new FreeTypeException(err);
  201. return new Face(faceRef, this);
  202. }
  203. #endregion
  204. #region Mac Specific Interface
  205. /// <summary>
  206. /// Create a new face object from a FOND resource.
  207. /// </summary>
  208. /// <remarks>
  209. /// This function can be used to create <see cref="Face"/> objects from fonts that are installed in the system
  210. /// as follows.
  211. /// <code>
  212. /// fond = GetResource( 'FOND', fontName );
  213. /// error = FT_New_Face_From_FOND( library, fond, 0, &amp;face );
  214. /// </code>
  215. /// </remarks>
  216. /// <param name="fond">A FOND resource.</param>
  217. /// <param name="faceIndex">Only supported for the -1 ‘sanity check’ special case.</param>
  218. /// <returns>A handle to a new face object.</returns>
  219. public Face NewFaceFromFond(IntPtr fond, int faceIndex)
  220. {
  221. if (disposed)
  222. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  223. IntPtr faceRef;
  224. Error err = FT.FT_New_Face_From_FOND(Reference, fond, faceIndex, out faceRef);
  225. if (err != Error.Ok)
  226. throw new FreeTypeException(err);
  227. return new Face(faceRef, this);
  228. }
  229. /// <summary>
  230. /// Create a new face object from a given resource and typeface index using an FSSpec to the font file.
  231. /// </summary>
  232. /// <remarks>
  233. /// <see cref="NewFaceFromFSSpec"/> is identical to <see cref="NewFace"/> except it accepts an FSSpec instead
  234. /// of a path.
  235. /// </remarks>
  236. /// <param name="spec">FSSpec to the font file.</param>
  237. /// <param name="faceIndex">The index of the face within the resource. The first face has index 0.</param>
  238. /// <returns>A handle to a new face object.</returns>
  239. public Face NewFaceFromFSSpec(IntPtr spec, int faceIndex)
  240. {
  241. if (disposed)
  242. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  243. IntPtr faceRef;
  244. Error err = FT.FT_New_Face_From_FSSpec(Reference, spec, faceIndex, out faceRef);
  245. if (err != Error.Ok)
  246. throw new FreeTypeException(err);
  247. return new Face(faceRef, this);
  248. }
  249. /// <summary>
  250. /// Create a new face object from a given resource and typeface index using an FSRef to the font file.
  251. /// </summary>
  252. /// <remarks>
  253. /// <see cref="NewFaceFromFSRef"/> is identical to <see cref="NewFace"/> except it accepts an FSRef instead of
  254. /// a path.
  255. /// </remarks>
  256. /// <param name="ref">FSRef to the font file.</param>
  257. /// <param name="faceIndex">The index of the face within the resource. The first face has index 0.</param>
  258. /// <returns>A handle to a new face object.</returns>
  259. public Face NewFaceFromFSRef(IntPtr @ref, int faceIndex)
  260. {
  261. if (disposed)
  262. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  263. IntPtr faceRef;
  264. Error err = FT.FT_New_Face_From_FSRef(Reference, @ref, faceIndex, out faceRef);
  265. if (err != Error.Ok)
  266. throw new FreeTypeException(err);
  267. return new Face(faceRef, this);
  268. }
  269. #endregion
  270. #region Module Management
  271. /// <summary>
  272. /// Add a new module to a given library instance.
  273. /// </summary>
  274. /// <remarks>
  275. /// An error will be returned if a module already exists by that name, or if the module requires a version of
  276. /// FreeType that is too great.
  277. /// </remarks>
  278. /// <param name="clazz">A pointer to class descriptor for the module.</param>
  279. public void AddModule(ModuleClass clazz)
  280. {
  281. if (disposed)
  282. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  283. Error err = FT.FT_Add_Module(Reference, clazz.Reference);
  284. if (err != Error.Ok)
  285. throw new FreeTypeException(err);
  286. }
  287. /// <summary>
  288. /// Find a module by its name.
  289. /// </summary>
  290. /// <remarks>
  291. /// FreeType's internal modules aren't documented very well, and you should look up the source code for
  292. /// details.
  293. /// </remarks>
  294. /// <param name="moduleName">The module's name (as an ASCII string).</param>
  295. /// <returns>A module handle. 0 if none was found.</returns>
  296. public Module GetModule(string moduleName)
  297. {
  298. if (disposed)
  299. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  300. return new Module(FT.FT_Get_Module(Reference, moduleName));
  301. }
  302. /// <summary>
  303. /// Remove a given module from a library instance.
  304. /// </summary>
  305. /// <remarks>
  306. /// The module object is destroyed by the function in case of success.
  307. /// </remarks>
  308. /// <param name="module">A handle to a module object.</param>
  309. public void RemoveModule(Module module)
  310. {
  311. if (disposed)
  312. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  313. if (module == null)
  314. throw new ArgumentNullException("module");
  315. Error err = FT.FT_Remove_Module(Reference, module.Reference);
  316. if (err != Error.Ok)
  317. throw new FreeTypeException(err);
  318. }
  319. /// <summary>
  320. /// Set a debug hook function for debugging the interpreter of a font format.
  321. /// </summary>
  322. /// <remarks><para>
  323. /// Currently, four debug hook slots are available, but only two (for the TrueType and the Type 1 interpreter)
  324. /// are defined.
  325. /// </para><para>
  326. /// Since the internal headers of FreeType are no longer installed, the symbol ‘FT_DEBUG_HOOK_TRUETYPE’ isn't
  327. /// available publicly. This is a bug and will be fixed in a forthcoming release.
  328. /// </para></remarks>
  329. /// <param name="hookIndex">The index of the debug hook. You should use the values defined in ‘ftobjs.h’, e.g., ‘FT_DEBUG_HOOK_TRUETYPE’.</param>
  330. /// <param name="debugHook">The function used to debug the interpreter.</param>
  331. [CLSCompliant(false)]
  332. public void SetDebugHook(uint hookIndex, IntPtr debugHook)
  333. {
  334. if (disposed)
  335. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  336. FT.FT_Set_Debug_Hook(Reference, hookIndex, debugHook);
  337. }
  338. /// <summary>
  339. /// Add the set of default drivers to a given library object. This is only useful when you create a library
  340. /// object with <see cref="Library(Memory)"/> (usually to plug a custom memory manager).
  341. /// </summary>
  342. public void AddDefaultModules()
  343. {
  344. if (disposed)
  345. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  346. FT.FT_Add_Default_Modules(Reference);
  347. }
  348. /// <summary>
  349. /// Retrieve the current renderer for a given glyph format.
  350. /// </summary>
  351. /// <remarks><para>
  352. /// An error will be returned if a module already exists by that name, or if the module requires a version of
  353. /// FreeType that is too great.
  354. /// </para><para>
  355. /// To add a new renderer, simply use <see cref="AddModule"/>. To retrieve a renderer by its name, use
  356. /// <see cref="GetModule"/>.
  357. /// </para></remarks>
  358. /// <param name="format">The glyph format.</param>
  359. /// <returns>A renderer handle. 0 if none found.</returns>
  360. [CLSCompliant(false)]
  361. public Renderer GetRenderer(GlyphFormat format)
  362. {
  363. if (disposed)
  364. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  365. return new Renderer(FT.FT_Get_Renderer(Reference, format));
  366. }
  367. /// <summary>
  368. /// Set the current renderer to use, and set additional mode.
  369. /// </summary>
  370. /// <remarks><para>
  371. /// In case of success, the renderer will be used to convert glyph images in the renderer's known format into
  372. /// bitmaps.
  373. /// </para><para>
  374. /// This doesn't change the current renderer for other formats.
  375. /// </para><para>
  376. /// Currently, only the B/W renderer, if compiled with FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels
  377. /// anti-aliasing mode; this option must be set directly in ‘ftraster.c’ and is undefined by default) accepts a
  378. /// single tag ‘pal5’ to set its gray palette as a character string with 5 elements. Consequently, the third
  379. /// and fourth argument are zero normally.
  380. /// </para></remarks>
  381. /// <param name="renderer">A handle to the renderer object.</param>
  382. /// <param name="numParams">The number of additional parameters.</param>
  383. /// <param name="parameters">Additional parameters.</param>
  384. [CLSCompliant(false)]
  385. public unsafe void SetRenderer(Renderer renderer, uint numParams, Parameter[] parameters)
  386. {
  387. if (disposed)
  388. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  389. if (renderer == null)
  390. throw new ArgumentNullException("renderer");
  391. if (parameters == null)
  392. throw new ArgumentNullException("parameters");
  393. ParameterRec[] paramRecs = Array.ConvertAll<Parameter, ParameterRec>(parameters, p => p.Record);
  394. fixed (void* ptr = paramRecs)
  395. {
  396. Error err = FT.FT_Set_Renderer(Reference, renderer.Reference, numParams, (IntPtr)ptr);
  397. if (err != Error.Ok)
  398. throw new FreeTypeException(err);
  399. }
  400. }
  401. #endregion
  402. #region LCD Filtering
  403. /// <summary>
  404. /// This function is used to apply color filtering to LCD decimated bitmaps, like the ones used when calling
  405. /// <see cref="GlyphSlot.RenderGlyph"/> with <see cref="RenderMode.Lcd"/> or
  406. /// <see cref="RenderMode.VerticalLcd"/>.
  407. /// </summary>
  408. /// <remarks><para>
  409. /// This feature is always disabled by default. Clients must make an explicit call to this function with a
  410. /// ‘filter’ value other than <see cref="LcdFilter.None"/> in order to enable it.
  411. /// </para><para>
  412. /// Due to <b>PATENTS</b> covering subpixel rendering, this function doesn't do anything except returning
  413. /// <see cref="Error.UnimplementedFeature"/> if the configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is
  414. /// not defined in your build of the library, which should correspond to all default builds of FreeType.
  415. /// </para><para>
  416. /// The filter affects glyph bitmaps rendered through <see cref="GlyphSlot.RenderGlyph"/>,
  417. /// <see cref="Outline.GetBitmap(FTBitmap)"/>, <see cref="Face.LoadGlyph"/>, and <see cref="Face.LoadChar"/>.
  418. /// </para><para>
  419. /// It does not affect the output of <see cref="Outline.Render(RasterParams)"/> and
  420. /// <see cref="Outline.GetBitmap(FTBitmap)"/>.
  421. /// </para><para>
  422. /// If this feature is activated, the dimensions of LCD glyph bitmaps are either larger or taller than the
  423. /// dimensions of the corresponding outline with regards to the pixel grid. For example, for
  424. /// <see cref="RenderMode.Lcd"/>, the filter adds up to 3 pixels to the left, and up to 3 pixels to the right.
  425. /// </para><para>
  426. /// The bitmap offset values are adjusted correctly, so clients shouldn't need to modify their layout and glyph
  427. /// positioning code when enabling the filter.
  428. /// </para></remarks>
  429. /// <param name="filter"><para>
  430. /// The filter type.
  431. /// </para><para>
  432. /// You can use <see cref="LcdFilter.None"/> here to disable this feature, or <see cref="LcdFilter.Default"/>
  433. /// to use a default filter that should work well on most LCD screens.
  434. /// </para></param>
  435. public void SetLcdFilter(LcdFilter filter)
  436. {
  437. if (disposed)
  438. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  439. Error err = FT.FT_Library_SetLcdFilter(Reference, filter);
  440. if (err != Error.Ok)
  441. throw new FreeTypeException(err);
  442. }
  443. /// <summary>
  444. /// Use this function to override the filter weights selected by <see cref="SetLcdFilter"/>. By default,
  445. /// FreeType uses the quintuple (0x00, 0x55, 0x56, 0x55, 0x00) for <see cref="LcdFilter.Light"/>, and (0x10,
  446. /// 0x40, 0x70, 0x40, 0x10) for <see cref="LcdFilter.Default"/> and <see cref="LcdFilter.Legacy"/>.
  447. /// </summary>
  448. /// <remarks><para>
  449. /// Due to <b>PATENTS</b> covering subpixel rendering, this function doesn't do anything except returning
  450. /// <see cref="Error.UnimplementedFeature"/> if the configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is
  451. /// not defined in your build of the library, which should correspond to all default builds of FreeType.
  452. /// </para><para>
  453. /// This function must be called after <see cref="SetLcdFilter"/> to have any effect.
  454. /// </para></remarks>
  455. /// <param name="weights">
  456. /// A pointer to an array; the function copies the first five bytes and uses them to specify the filter
  457. /// weights.
  458. /// </param>
  459. public void SetLcdFilterWeights(byte[] weights)
  460. {
  461. if (disposed)
  462. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  463. if (weights == null)
  464. throw new ArgumentNullException("weights");
  465. Error err = FT.FT_Library_SetLcdFilterWeights(Reference, weights);
  466. if (err != Error.Ok)
  467. throw new FreeTypeException(err);
  468. }
  469. #endregion
  470. #region The TrueType Engine
  471. /// <summary>
  472. /// Return an <see cref="EngineType"/> value to indicate which level of the TrueType virtual machine a given
  473. /// library instance supports.
  474. /// </summary>
  475. /// <returns>A value indicating which level is supported.</returns>
  476. public EngineType GetTrueTypeEngineType()
  477. {
  478. if (disposed)
  479. throw new ObjectDisposedException("Library", "Cannot access a disposed object.");
  480. return FT.FT_Get_TrueType_Engine_Type(Reference);
  481. }
  482. #endregion
  483. /// <summary>
  484. /// Disposes the Library.
  485. /// </summary>
  486. public void Dispose()
  487. {
  488. Dispose(true);
  489. GC.SuppressFinalize(this);
  490. }
  491. internal void AddChildFace(Face child)
  492. {
  493. childFaces.Add(child);
  494. }
  495. internal void RemoveChildFace(Face child)
  496. {
  497. childFaces.Remove(child);
  498. }
  499. internal void AddChildGlyph(Glyph child)
  500. {
  501. childGlyphs.Add(child);
  502. }
  503. internal void RemoveChildGlyph(Glyph child)
  504. {
  505. childGlyphs.Remove(child);
  506. }
  507. internal void AddChildOutline(Outline child)
  508. {
  509. childOutlines.Add(child);
  510. }
  511. internal void RemoveChildOutline(Outline child)
  512. {
  513. childOutlines.Remove(child);
  514. }
  515. internal void AddChildStroker(Stroker child)
  516. {
  517. childStrokers.Add(child);
  518. }
  519. internal void RemoveChildStroker(Stroker child)
  520. {
  521. childStrokers.Remove(child);
  522. }
  523. internal void AddChildManager(Manager child)
  524. {
  525. childManagers.Add(child);
  526. }
  527. internal void RemoveChildManager(Manager child)
  528. {
  529. childManagers.Remove(child);
  530. }
  531. private void Dispose(bool disposing)
  532. {
  533. if (!disposed)
  534. {
  535. disposed = true;
  536. //dipose all the children before disposing the library.
  537. foreach (Face f in childFaces)
  538. f.Dispose();
  539. foreach (Glyph g in childGlyphs)
  540. g.Dispose();
  541. foreach (Outline o in childOutlines)
  542. o.Dispose();
  543. foreach (Stroker s in childStrokers)
  544. s.Dispose();
  545. foreach (Manager m in childManagers)
  546. m.Dispose();
  547. childFaces.Clear();
  548. childGlyphs.Clear();
  549. childOutlines.Clear();
  550. childStrokers.Clear();
  551. childManagers.Clear();
  552. Error err = customMemory ? FT.FT_Done_Library(reference) : FT.FT_Done_FreeType(reference);
  553. if (err != Error.Ok)
  554. throw new FreeTypeException(err);
  555. reference = IntPtr.Zero;
  556. }
  557. }
  558. #endregion
  559. }
  560. }