GlyphSlot.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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 glyph slot class structure. A glyph slot is a container where individual glyphs can be loaded, be
  27. /// they in outline or bitmap format.
  28. /// </summary>
  29. /// <remarks><para>
  30. /// If <see cref="SharpFont.Face.LoadGlyph"/> is called with default flags (see <see cref="LoadFlags.Default"/>)
  31. /// the glyph image is loaded in the glyph slot in its native format (e.g., an outline glyph for TrueType and Type
  32. /// 1 formats).
  33. /// </para><para>
  34. /// This image can later be converted into a bitmap by calling <see cref="RenderGlyph"/>. This function finds the
  35. /// current renderer for the native image's format, then invokes it.
  36. /// </para><para>
  37. /// The renderer is in charge of transforming the native image through the slot's face transformation fields, then
  38. /// converting it into a bitmap that is returned in ‘slot->bitmap’.
  39. /// </para><para>
  40. /// Note that ‘slot->bitmap_left’ and ‘slot->bitmap_top’ are also used to specify the position of the bitmap
  41. /// relative to the current pen position (e.g., coordinates (0,0) on the baseline). Of course, ‘slot->format’ is
  42. /// also changed to <see cref="GlyphFormat.Bitmap"/>.
  43. /// </para></remarks>
  44. /// <example>
  45. /// <code>
  46. /// FT_Pos origin_x = 0;
  47. /// FT_Pos prev_rsb_delta = 0;
  48. ///
  49. ///
  50. /// for all glyphs do
  51. /// &lt;compute kern between current and previous glyph and add it to
  52. /// `origin_x'&gt;
  53. ///
  54. /// &lt;load glyph with `FT_Load_Glyph'&gt;
  55. ///
  56. /// if ( prev_rsb_delta - face-&gt;glyph-&gt;lsb_delta &gt;= 32 )
  57. /// origin_x -= 64;
  58. /// else if ( prev_rsb_delta - face->glyph-&gt;lsb_delta &lt; -32 )
  59. /// origin_x += 64;
  60. ///
  61. /// prev_rsb_delta = face-&gt;glyph->rsb_delta;
  62. ///
  63. /// &lt;save glyph image, or render glyph, or ...&gt;
  64. ///
  65. /// origin_x += face-&gt;glyph-&gt;advance.x;
  66. /// endfor
  67. /// </code>
  68. /// </example>
  69. public sealed class GlyphSlot
  70. {
  71. #region Fields
  72. private IntPtr reference;
  73. private GlyphSlotRec rec;
  74. private Face parentFace;
  75. private Library parentLibrary;
  76. #endregion
  77. #region Constructors
  78. internal GlyphSlot(IntPtr reference, Face parentFace, Library parentLibrary)
  79. {
  80. Reference = reference;
  81. this.parentFace = parentFace;
  82. this.parentLibrary = parentLibrary;
  83. }
  84. #endregion
  85. #region Properties
  86. /// <summary>
  87. /// Gets a handle to the FreeType library instance this slot belongs to.
  88. /// </summary>
  89. public Library Library
  90. {
  91. get
  92. {
  93. return parentLibrary;
  94. }
  95. }
  96. /// <summary>
  97. /// Gets a handle to the parent face object.
  98. /// </summary>
  99. public Face Face
  100. {
  101. get
  102. {
  103. return parentFace;
  104. }
  105. }
  106. /// <summary>
  107. /// Gets the next <see cref="GlyphSlot"/>. In some cases (like some font tools), several glyph slots per face
  108. /// object can be a good thing. As this is rare, the glyph slots are listed through a direct, single-linked
  109. /// list using its ‘next’ field.
  110. /// </summary>
  111. public GlyphSlot Next
  112. {
  113. get
  114. {
  115. return new GlyphSlot(rec.next, parentFace, parentLibrary);
  116. }
  117. }
  118. /// <summary>
  119. /// Gets a typeless pointer which is unused by the FreeType library or any of its drivers. It can be used by
  120. /// client applications to link their own data to each glyph slot object.
  121. /// </summary>
  122. public Generic Generic
  123. {
  124. get
  125. {
  126. return new Generic(rec.generic);
  127. }
  128. }
  129. /// <summary><para>
  130. /// Gets the metrics of the last loaded glyph in the slot. The returned values depend on the last load flags
  131. /// (see the <see cref="SharpFont.Face.LoadGlyph"/> API function) and can be expressed either in 26.6
  132. /// fractional pixels or font units.
  133. /// </para><para>
  134. /// Note that even when the glyph image is transformed, the metrics are not.
  135. /// </para></summary>
  136. public GlyphMetrics Metrics
  137. {
  138. get
  139. {
  140. return new GlyphMetrics(rec.metrics);
  141. }
  142. }
  143. /// <summary>
  144. /// Gets the advance width of the unhinted glyph. Its value is expressed in 16.16 fractional pixels, unless
  145. /// <see cref="LoadFlags.LinearDesign"/> is set when loading the glyph. This field can be important to perform
  146. /// correct WYSIWYG layout. Only relevant for outline glyphs.
  147. /// </summary>
  148. public int LinearHorizontalAdvance
  149. {
  150. get
  151. {
  152. return (int)rec.linearHoriAdvance;
  153. }
  154. }
  155. /// <summary>
  156. /// Gets the advance height of the unhinted glyph. Its value is expressed in 16.16 fractional pixels, unless
  157. /// <see cref="LoadFlags.LinearDesign"/> is set when loading the glyph. This field can be important to perform
  158. /// correct WYSIWYG layout. Only relevant for outline glyphs.
  159. /// </summary>
  160. public int LinearVerticalAdvance
  161. {
  162. get
  163. {
  164. return (int)rec.linearVertAdvance;
  165. }
  166. }
  167. /// <summary>
  168. /// Gets the advance. This shorthand is, depending on <see cref="LoadFlags.IgnoreTransform"/>, the transformed
  169. /// advance width for the glyph (in 26.6 fractional pixel format). As specified with
  170. /// <see cref="LoadFlags.VerticalLayout"/>, it uses either the ‘horiAdvance’ or the ‘vertAdvance’ value of
  171. /// ‘metrics’ field.
  172. /// </summary>
  173. public FTVector Advance
  174. {
  175. get
  176. {
  177. return rec.advance;
  178. }
  179. }
  180. /// <summary>
  181. /// Gets the glyph format. This field indicates the format of the image contained in the glyph slot. Typically
  182. /// <see cref="GlyphFormat.Bitmap"/>, <see cref="GlyphFormat.Outline"/>, or
  183. /// <see cref="GlyphFormat.Composite"/>, but others are possible.
  184. /// </summary>
  185. [CLSCompliant(false)]
  186. public GlyphFormat Format
  187. {
  188. get
  189. {
  190. return rec.format;
  191. }
  192. }
  193. /// <summary>
  194. /// Gets the bitmap. This field is used as a bitmap descriptor when the slot format is
  195. /// <see cref="GlyphFormat.Bitmap"/>. Note that the address and content of the bitmap buffer can change between
  196. /// calls of <see cref="SharpFont.Face.LoadGlyph"/> and a few other functions.
  197. /// </summary>
  198. public FTBitmap Bitmap
  199. {
  200. get
  201. {
  202. return new FTBitmap(rec.bitmap, parentLibrary);
  203. }
  204. }
  205. /// <summary>
  206. /// Gets the bitmap's left bearing expressed in integer pixels. Of course, this is only valid if the format is
  207. /// <see cref="GlyphFormat.Bitmap"/>.
  208. /// </summary>
  209. public int BitmapLeft
  210. {
  211. get
  212. {
  213. return rec.bitmap_left;
  214. }
  215. }
  216. /// <summary>
  217. /// Gets the bitmap's top bearing expressed in integer pixels. Remember that this is the distance from the
  218. /// baseline to the top-most glyph scanline, upwards y coordinates being positive.
  219. /// </summary>
  220. public int BitmapTop
  221. {
  222. get
  223. {
  224. return rec.bitmap_top;
  225. }
  226. }
  227. /// <summary>
  228. /// Gets the outline descriptor for the current glyph image if its format is <see cref="GlyphFormat.Outline"/>.
  229. /// Once a glyph is loaded, ‘outline’ can be transformed, distorted, embolded, etc. However, it must not be
  230. /// freed.
  231. /// </summary>
  232. public Outline Outline
  233. {
  234. get
  235. {
  236. return new Outline(rec.outline);
  237. }
  238. }
  239. /// <summary>
  240. /// Gets the number of subglyphs in a composite glyph. This field is only valid for the composite glyph format
  241. /// that should normally only be loaded with the <see cref="LoadFlags.NoRecurse"/> flag. For now this is
  242. /// internal to FreeType.
  243. /// </summary>
  244. [CLSCompliant(false)]
  245. public uint SubglyphsCount
  246. {
  247. get
  248. {
  249. return rec.num_subglyphs;
  250. }
  251. }
  252. /// <summary>
  253. /// Gets an array of subglyph descriptors for composite glyphs. There are ‘num_subglyphs’ elements in there.
  254. /// Currently internal to FreeType.
  255. /// </summary>
  256. public SubGlyph[] Subglyphs
  257. {
  258. get
  259. {
  260. int count = (int)SubglyphsCount;
  261. if (count == 0)
  262. return null;
  263. SubGlyph[] subglyphs = new SubGlyph[count];
  264. IntPtr array = rec.subglyphs;
  265. for (int i = 0; i < count; i++)
  266. {
  267. subglyphs[i] = new SubGlyph(array, IntPtr.Size * i);
  268. }
  269. return subglyphs;
  270. }
  271. }
  272. /// <summary>
  273. /// Gets the control data. Certain font drivers can also return the control data for a given glyph image (e.g.
  274. /// TrueType bytecode, Type 1 charstrings, etc.). This field is a pointer to such data.
  275. /// </summary>
  276. public IntPtr ControlData
  277. {
  278. get
  279. {
  280. return rec.control_data;
  281. }
  282. }
  283. /// <summary>
  284. /// Gets the length in bytes of the control data.
  285. /// </summary>
  286. public int ControlLength
  287. {
  288. get
  289. {
  290. return (int)rec.control_len;
  291. }
  292. }
  293. /// <summary>
  294. /// Gets the difference between hinted and unhinted left side bearing while autohinting is active. Zero
  295. /// otherwise.
  296. /// </summary>
  297. public int DeltaLsb
  298. {
  299. get
  300. {
  301. return (int)rec.lsb_delta;
  302. }
  303. }
  304. /// <summary>
  305. /// Gets the difference between hinted and unhinted right side bearing while autohinting is active. Zero
  306. /// otherwise.
  307. /// </summary>
  308. public int DeltaRsb
  309. {
  310. get
  311. {
  312. return (int)rec.rsb_delta;
  313. }
  314. }
  315. /// <summary>
  316. /// Gets other data. Really wicked formats can use this pointer to present their own glyph image to client
  317. /// applications. Note that the application needs to know about the image format.
  318. /// </summary>
  319. public IntPtr Other
  320. {
  321. get
  322. {
  323. return rec.other;
  324. }
  325. }
  326. internal IntPtr Reference
  327. {
  328. get
  329. {
  330. return reference;
  331. }
  332. set
  333. {
  334. reference = value;
  335. rec = PInvokeHelper.PtrToStructure<GlyphSlotRec>(reference);
  336. }
  337. }
  338. #endregion
  339. #region Public Methods
  340. #region Base Interface
  341. /// <summary>
  342. /// Convert a given glyph image to a bitmap. It does so by inspecting the glyph image format, finding the
  343. /// relevant renderer, and invoking it.
  344. /// </summary>
  345. /// <param name="mode">This is the render mode used to render the glyph image into a bitmap.</param>
  346. public void RenderGlyph(RenderMode mode)
  347. {
  348. Error err = FT.FT_Render_Glyph(Reference, mode);
  349. if (err != Error.Ok)
  350. throw new FreeTypeException(err);
  351. }
  352. /// <summary>
  353. /// Retrieve a description of a given subglyph. Only use it if <see cref="GlyphSlot.Format"/> is
  354. /// <see cref="GlyphFormat.Composite"/>; an error is returned otherwise.
  355. /// </summary>
  356. /// <remarks>
  357. /// The values of ‘*p_arg1’, ‘*p_arg2’, and ‘*p_transform’ must be interpreted depending on the flags returned
  358. /// in ‘*p_flags’. See the TrueType specification for details.
  359. /// </remarks>
  360. /// <param name="subIndex">
  361. /// The index of the subglyph. Must be less than <see cref="GlyphSlot.SubglyphsCount"/>.
  362. /// </param>
  363. /// <param name="index">The glyph index of the subglyph.</param>
  364. /// <param name="flags">The subglyph flags, see <see cref="SubGlyphFlags"/>.</param>
  365. /// <param name="arg1">The subglyph's first argument (if any).</param>
  366. /// <param name="arg2">The subglyph's second argument (if any).</param>
  367. /// <param name="transform">The subglyph transformation (if any).</param>
  368. [CLSCompliant(false)]
  369. public void GetSubGlyphInfo(uint subIndex, out int index, out SubGlyphFlags flags, out int arg1, out int arg2, out FTMatrix transform)
  370. {
  371. Error err = FT.FT_Get_SubGlyph_Info(Reference, subIndex, out index, out flags, out arg1, out arg2, out transform);
  372. if (err != Error.Ok)
  373. throw new FreeTypeException(err);
  374. }
  375. #endregion
  376. #region Glyph Management
  377. /// <summary>
  378. /// A function used to extract a glyph image from a slot. Note that the created <see cref="Glyph"/> object must
  379. /// be released with <see cref="Glyph.Dispose()"/>.
  380. /// </summary>
  381. /// <returns>A handle to the glyph object.</returns>
  382. public Glyph GetGlyph()
  383. {
  384. IntPtr glyphRef;
  385. Error err = FT.FT_Get_Glyph(Reference, out glyphRef);
  386. if (err != Error.Ok)
  387. throw new FreeTypeException(err);
  388. return new Glyph(glyphRef, Library);
  389. }
  390. #endregion
  391. #region Bitmap Handling
  392. /// <summary>
  393. /// Make sure that a glyph slot owns ‘slot->bitmap’.
  394. /// </summary>
  395. /// <remarks>
  396. /// This function is to be used in combination with <see cref="FTBitmap.Embolden"/>.
  397. /// </remarks>
  398. public void OwnBitmap()
  399. {
  400. Error err = FT.FT_GlyphSlot_Own_Bitmap(Reference);
  401. if (err != Error.Ok)
  402. throw new FreeTypeException(err);
  403. }
  404. #endregion
  405. #endregion
  406. }
  407. }