Face.cs 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285
  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 System.Runtime.InteropServices;
  23. using SharpFont.Bdf;
  24. using SharpFont.Internal;
  25. using SharpFont.MultipleMasters;
  26. using SharpFont.PostScript;
  27. using SharpFont.TrueType;
  28. namespace SharpFont
  29. {
  30. /// <summary>
  31. /// FreeType root face class structure. A face object models a typeface in a font file.
  32. /// </summary>
  33. /// <remarks>
  34. /// Fields may be changed after a call to <see cref="AttachFile"/> or <see cref="AttachStream"/>.
  35. /// </remarks>
  36. public sealed class Face : IDisposable
  37. {
  38. #region Fields
  39. private IntPtr reference;
  40. private FaceRec rec;
  41. private bool disposed;
  42. private Library parentLibrary;
  43. private List<FTSize> childSizes;
  44. #endregion
  45. #region Constructors
  46. /// <summary>
  47. /// Initializes a new instance of the <see cref="Face"/> class with a default faceIndex of 0.
  48. /// </summary>
  49. /// <param name="library">The parent library.</param>
  50. /// <param name="path">The path of the font file.</param>
  51. public Face(Library library, string path)
  52. : this(library, path, 0)
  53. {
  54. }
  55. /// <summary>
  56. /// Initializes a new instance of the <see cref="Face"/> class.
  57. /// </summary>
  58. /// <param name="library">The parent library.</param>
  59. /// <param name="path">The path of the font file.</param>
  60. /// <param name="faceIndex">The index of the face to take from the file.</param>
  61. public Face(Library library, string path, int faceIndex)
  62. : this()
  63. {
  64. IntPtr reference;
  65. Error err = FT.FT_New_Face(library.Reference, path, faceIndex, out reference);
  66. if (err != Error.Ok)
  67. throw new FreeTypeException(err);
  68. Reference = reference;
  69. parentLibrary = library;
  70. parentLibrary.AddChildFace(this);
  71. }
  72. //TODO make an overload with a FileStream instead of a byte[]
  73. /// <summary>
  74. /// Initializes a new instance of the <see cref="Face"/> class from a file that's already loaded into memory.
  75. /// </summary>
  76. /// <param name="library">The parent library.</param>
  77. /// <param name="file">The loaded file.</param>
  78. /// <param name="faceIndex">The index of the face to take from the file.</param>
  79. public unsafe Face(Library library, byte[] file, int faceIndex)
  80. : this()
  81. {
  82. fixed (byte* ptr = file)
  83. {
  84. IntPtr reference;
  85. Error err = FT.FT_New_Memory_Face(library.Reference, (IntPtr)ptr, file.Length, faceIndex, out reference);
  86. if (err != Error.Ok)
  87. throw new FreeTypeException(err);
  88. Reference = reference;
  89. }
  90. parentLibrary = library;
  91. parentLibrary.AddChildFace(this);
  92. }
  93. /// <summary>
  94. /// Initializes a new instance of the Face class.
  95. /// </summary>
  96. /// <param name="reference">A pointer to the unmanaged memory containing the Face.</param>
  97. /// <param name="parent">The parent <see cref="Library"/>.</param>
  98. internal Face(IntPtr reference, Library parent)
  99. : this()
  100. {
  101. Reference = reference;
  102. if (parent != null)
  103. {
  104. parentLibrary = parent;
  105. parentLibrary.AddChildFace(this);
  106. }
  107. else
  108. {
  109. //if there's no parent, this is a marshalled duplicate.
  110. FT.FT_Reference_Face(Reference);
  111. }
  112. }
  113. private Face()
  114. {
  115. childSizes = new List<FTSize>();
  116. }
  117. /// <summary>
  118. /// Finalizes an instance of the Face class.
  119. /// </summary>
  120. ~Face()
  121. {
  122. Dispose(false);
  123. }
  124. #endregion
  125. #region Properties
  126. /// <summary>
  127. /// Gets a value indicating whether the object has been disposed.
  128. /// </summary>
  129. public bool IsDisposed
  130. {
  131. get
  132. {
  133. return disposed;
  134. }
  135. }
  136. /// <summary>
  137. /// Gets the number of faces in the font file. Some font formats can have multiple faces in a font file.
  138. /// </summary>
  139. public int FaceCount
  140. {
  141. get
  142. {
  143. if (disposed)
  144. throw new ObjectDisposedException("FaceCount", "Cannot access a disposed object.");
  145. return (int)rec.num_faces;
  146. }
  147. }
  148. /// <summary>
  149. /// Gets the index of the face in the font file. It is set to 0 if there is only one face in the font file.
  150. /// </summary>
  151. public int FaceIndex
  152. {
  153. get
  154. {
  155. if (disposed)
  156. throw new ObjectDisposedException("FaceIndex", "Cannot access a disposed object.");
  157. return (int)rec.face_index;
  158. }
  159. }
  160. /// <summary>
  161. /// Gets a set of bit flags that give important information about the face.
  162. /// </summary>
  163. /// <see cref="FaceFlags"/>
  164. public FaceFlags FaceFlags
  165. {
  166. get
  167. {
  168. if (disposed)
  169. throw new ObjectDisposedException("FaceFlags", "Cannot access a disposed object.");
  170. return (FaceFlags)rec.face_flags;
  171. }
  172. }
  173. /// <summary>
  174. /// Gets a set of bit flags indicating the style of the face.
  175. /// </summary>
  176. /// <see cref="StyleFlags"/>
  177. public StyleFlags StyleFlags
  178. {
  179. get
  180. {
  181. if (disposed)
  182. throw new ObjectDisposedException("StyleFlags", "Cannot access a disposed object.");
  183. return (StyleFlags)rec.style_flags;
  184. }
  185. }
  186. /// <summary><para>
  187. /// Gets the number of glyphs in the face. If the face is scalable and has sbits (see ‘num_fixed_sizes’), it is
  188. /// set to the number of outline glyphs.
  189. /// </para><para>
  190. /// For CID-keyed fonts, this value gives the highest CID used in the font.
  191. /// </para></summary>
  192. public int GlyphCount
  193. {
  194. get
  195. {
  196. if (disposed)
  197. throw new ObjectDisposedException("GlyphCount", "Cannot access a disposed object.");
  198. return (int)rec.num_glyphs;
  199. }
  200. }
  201. /// <summary>
  202. /// Gets the face's family name. This is an ASCII string, usually in English, which describes the typeface's
  203. /// family (like ‘Times New Roman’, ‘Bodoni’, ‘Garamond’, etc). This is a least common denominator used to list
  204. /// fonts. Some formats (TrueType &amp; OpenType) provide localized and Unicode versions of this string.
  205. /// Applications should use the format specific interface to access them. Can be NULL (e.g., in fonts embedded
  206. /// in a PDF file).
  207. /// </summary>
  208. public string FamilyName
  209. {
  210. get
  211. {
  212. if (disposed)
  213. throw new ObjectDisposedException("FamilyName", "Cannot access a disposed object.");
  214. return rec.family_name;
  215. }
  216. }
  217. /// <summary>
  218. /// Gets the face's style name. This is an ASCII string, usually in English, which describes the typeface's
  219. /// style (like ‘Italic’, ‘Bold’, ‘Condensed’, etc). Not all font formats provide a style name, so this field
  220. /// is optional, and can be set to NULL. As for ‘family_name’, some formats provide localized and Unicode
  221. /// versions of this string. Applications should use the format specific interface to access them.
  222. /// </summary>
  223. public string StyleName
  224. {
  225. get
  226. {
  227. if (disposed)
  228. throw new ObjectDisposedException("StyleName", "Cannot access a disposed object.");
  229. return rec.style_name;
  230. }
  231. }
  232. /// <summary>
  233. /// Gets the number of bitmap strikes in the face. Even if the face is scalable, there might still be bitmap
  234. /// strikes, which are called ‘sbits’ in that case.
  235. /// </summary>
  236. public int FixedSizesCount
  237. {
  238. get
  239. {
  240. if (disposed)
  241. throw new ObjectDisposedException("FixedSizesCount", "Cannot access a disposed object.");
  242. return rec.num_fixed_sizes;
  243. }
  244. }
  245. /// <summary>
  246. /// Gets an array of FT_Bitmap_Size for all bitmap strikes in the face. It is set to NULL if there is no bitmap
  247. /// strike.
  248. /// </summary>
  249. public BitmapSize[] AvailableSizes
  250. {
  251. get
  252. {
  253. if (disposed)
  254. throw new ObjectDisposedException("AvailableSizes", "Cannot access a disposed object.");
  255. int count = FixedSizesCount;
  256. if (count == 0)
  257. return null;
  258. BitmapSize[] sizes = new BitmapSize[count];
  259. IntPtr array = rec.available_sizes;
  260. for (int i = 0; i < count; i++)
  261. {
  262. sizes[i] = new BitmapSize(new IntPtr(array.ToInt64() + IntPtr.Size * i));
  263. }
  264. return sizes;
  265. }
  266. }
  267. /// <summary>
  268. /// Gets the number of charmaps in the face.
  269. /// </summary>
  270. public int CharmapsCount
  271. {
  272. get
  273. {
  274. if (disposed)
  275. throw new ObjectDisposedException("CharmapsCount", "Cannot access a disposed object.");
  276. return rec.num_charmaps;
  277. }
  278. }
  279. /// <summary>
  280. /// Gets an array of the charmaps of the face.
  281. /// </summary>
  282. public CharMap[] CharMaps
  283. {
  284. get
  285. {
  286. if (disposed)
  287. throw new ObjectDisposedException("CharMaps", "Cannot access a disposed object.");
  288. int count = CharmapsCount;
  289. if (count == 0)
  290. return null;
  291. CharMap[] charmaps = new CharMap[count];
  292. IntPtr array = rec.charmaps;
  293. for (int i = 0; i < count; i++)
  294. {
  295. charmaps[i] = new CharMap(new IntPtr(array.ToInt64() + IntPtr.Size * i), this);
  296. }
  297. return charmaps;
  298. }
  299. }
  300. /// <summary>
  301. /// Gets or sets a field reserved for client uses.
  302. /// </summary>
  303. /// <see cref="Generic"/>
  304. public Generic Generic
  305. {
  306. get
  307. {
  308. if (disposed)
  309. throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
  310. return new Generic(rec.generic);
  311. }
  312. set
  313. {
  314. if (disposed)
  315. throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
  316. //rec.generic = value;
  317. value.WriteToUnmanagedMemory(new IntPtr(reference.ToInt64() + Marshal.OffsetOf(typeof(FaceRec), "generic").ToInt64()));
  318. Reference = reference;
  319. }
  320. }
  321. /// <summary><para>
  322. /// Gets the font bounding box. Coordinates are expressed in font units (see ‘units_per_EM’). The box is large
  323. /// enough to contain any glyph from the font. Thus, ‘bbox.yMax’ can be seen as the ‘maximal ascender’, and
  324. /// ‘bbox.yMin’ as the ‘minimal descender’. Only relevant for scalable formats.
  325. /// </para><para>
  326. /// Note that the bounding box might be off by (at least) one pixel for hinted fonts. See FT_Size_Metrics for
  327. /// further discussion.
  328. /// </para></summary>
  329. public BBox BBox
  330. {
  331. get
  332. {
  333. if (disposed)
  334. throw new ObjectDisposedException("BBox", "Cannot access a disposed object.");
  335. return new BBox(rec.bbox);
  336. }
  337. }
  338. /// <summary>
  339. /// Gets the number of font units per EM square for this face. This is typically 2048 for TrueType fonts, and
  340. /// 1000 for Type 1 fonts. Only relevant for scalable formats.
  341. /// </summary>
  342. [CLSCompliant(false)]
  343. public ushort UnitsPerEM
  344. {
  345. get
  346. {
  347. if (disposed)
  348. throw new ObjectDisposedException("UnitsPerEM", "Cannot access a disposed object.");
  349. return rec.units_per_EM;
  350. }
  351. }
  352. /// <summary>
  353. /// Gets the typographic ascender of the face, expressed in font units. For font formats not having this
  354. /// information, it is set to ‘bbox.yMax’. Only relevant for scalable formats.
  355. /// </summary>
  356. public short Ascender
  357. {
  358. get
  359. {
  360. if (disposed)
  361. throw new ObjectDisposedException("Ascender", "Cannot access a disposed object.");
  362. return rec.ascender;
  363. }
  364. }
  365. /// <summary>
  366. /// Gets the typographic descender of the face, expressed in font units. For font formats not having this
  367. /// information, it is set to ‘bbox.yMin’.Note that this field is usually negative. Only relevant for scalable
  368. /// formats.
  369. /// </summary>
  370. public short Descender
  371. {
  372. get
  373. {
  374. if (disposed)
  375. throw new ObjectDisposedException("Descender", "Cannot access a disposed object.");
  376. return rec.descender;
  377. }
  378. }
  379. /// <summary>
  380. /// Gets the height is the vertical distance between two consecutive baselines, expressed in font units. It is
  381. /// always positive. Only relevant for scalable formats.
  382. /// </summary>
  383. public short Height
  384. {
  385. get
  386. {
  387. if (disposed)
  388. throw new ObjectDisposedException("Height", "Cannot access a disposed object.");
  389. return rec.height;
  390. }
  391. }
  392. /// <summary>
  393. /// Gets the maximal advance width, in font units, for all glyphs in this face. This can be used to make word
  394. /// wrapping computations faster. Only relevant for scalable formats.
  395. /// </summary>
  396. public short MaxAdvanceWidth
  397. {
  398. get
  399. {
  400. if (disposed)
  401. throw new ObjectDisposedException("MaxAdvanceWidth", "Cannot access a disposed object.");
  402. return rec.max_advance_width;
  403. }
  404. }
  405. /// <summary>
  406. /// Gets the maximal advance height, in font units, for all glyphs in this face. This is only relevant for
  407. /// vertical layouts, and is set to ‘height’ for fonts that do not provide vertical metrics. Only relevant for
  408. /// scalable formats.
  409. /// </summary>
  410. public short MaxAdvanceHeight
  411. {
  412. get
  413. {
  414. if (disposed)
  415. throw new ObjectDisposedException("MaxAdvanceHeight", "Cannot access a disposed object.");
  416. return rec.max_advance_height;
  417. }
  418. }
  419. /// <summary>
  420. /// Gets the position, in font units, of the underline line for this face. It is the center of the underlining
  421. /// stem. Only relevant for scalable formats.
  422. /// </summary>
  423. public short UnderlinePosition
  424. {
  425. get
  426. {
  427. if (disposed)
  428. throw new ObjectDisposedException("UnderlinePosition", "Cannot access a disposed object.");
  429. return rec.underline_position;
  430. }
  431. }
  432. /// <summary>
  433. /// Gets the thickness, in font units, of the underline for this face. Only relevant for scalable formats.
  434. /// </summary>
  435. public short UnderlineThickness
  436. {
  437. get
  438. {
  439. if (disposed)
  440. throw new ObjectDisposedException("UnderlineThickness", "Cannot access a disposed object.");
  441. return rec.underline_thickness;
  442. }
  443. }
  444. /// <summary>
  445. /// Gets the face's associated glyph slot(s).
  446. /// </summary>
  447. public GlyphSlot Glyph
  448. {
  449. get
  450. {
  451. if (disposed)
  452. throw new ObjectDisposedException("Glyph", "Cannot access a disposed object.");
  453. return new GlyphSlot(rec.glyph, this, parentLibrary);
  454. }
  455. }
  456. /// <summary>
  457. /// Gets the current active size for this face.
  458. /// </summary>
  459. public FTSize Size
  460. {
  461. get
  462. {
  463. if (disposed)
  464. throw new ObjectDisposedException("Size", "Cannot access a disposed object.");
  465. return new FTSize(rec.size, false, this);
  466. }
  467. }
  468. /// <summary>
  469. /// Gets the current active charmap for this face.
  470. /// </summary>
  471. public CharMap CharMap
  472. {
  473. get
  474. {
  475. if (disposed)
  476. throw new ObjectDisposedException("CharMap", "Cannot access a disposed object.");
  477. return new CharMap(rec.charmap, this);
  478. }
  479. }
  480. /// <summary>
  481. /// Gets a value indicating whether a face object contains horizontal metrics (this is true for all font
  482. /// formats though).
  483. /// </summary>
  484. public bool HasHoriziontal
  485. {
  486. get
  487. {
  488. return (FaceFlags & FaceFlags.Horizontal) == FaceFlags.Horizontal;
  489. }
  490. }
  491. /// <summary>
  492. /// Gets a value indicating whether a face object contains vertical metrics.
  493. /// </summary>
  494. public bool HasVertical
  495. {
  496. get
  497. {
  498. return (FaceFlags & FaceFlags.Vertical) == FaceFlags.Vertical;
  499. }
  500. }
  501. /// <summary>
  502. /// Gets a value indicating whether a face object contains kerning data that can be accessed with
  503. /// <see cref="GetKerning"/>.
  504. /// </summary>
  505. public bool HasKerning
  506. {
  507. get
  508. {
  509. return (FaceFlags & FaceFlags.Kerning) == FaceFlags.Kerning;
  510. }
  511. }
  512. /// <summary>
  513. /// Gets a value indicating whether a face object contains a scalable font face (true for TrueType, Type 1,
  514. /// Type 42, CID, OpenType/CFF, and PFR font formats.
  515. /// </summary>
  516. public bool IsScalable
  517. {
  518. get
  519. {
  520. return (FaceFlags & FaceFlags.Scalable) == FaceFlags.Scalable;
  521. }
  522. }
  523. /// <summary><para>
  524. /// Gets a value indicating whether a face object contains a font whose format is based on the SFNT storage
  525. /// scheme. This usually means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded bitmap fonts.
  526. /// </para><para>
  527. /// If this macro is true, all functions defined in FT_SFNT_NAMES_H and FT_TRUETYPE_TABLES_H are available.
  528. /// </para></summary>
  529. public bool IsSfnt
  530. {
  531. get
  532. {
  533. return (FaceFlags & FaceFlags.Sfnt) == FaceFlags.Sfnt;
  534. }
  535. }
  536. /// <summary>
  537. /// Gets a value indicating whether a face object contains a font face that contains fixed-width (or
  538. /// ‘monospace’, ‘fixed-pitch’, etc.) glyphs.
  539. /// </summary>
  540. public bool IsFixedWidth
  541. {
  542. get
  543. {
  544. return (FaceFlags & FaceFlags.FixedWidth) == FaceFlags.FixedWidth;
  545. }
  546. }
  547. /// <summary>
  548. /// Gets a value indicating whether a face object contains some embedded bitmaps.
  549. /// </summary>
  550. /// <see cref="Face.AvailableSizes"/>
  551. public bool HasFixedSizes
  552. {
  553. get
  554. {
  555. return (FaceFlags & FaceFlags.FixedSizes) == FaceFlags.FixedSizes;
  556. }
  557. }
  558. /// <summary>
  559. /// Gets a value indicating whether a face object contains some glyph names that can be accessed through
  560. /// <see cref="GetGlyphName(uint, int)"/>.
  561. /// </summary>
  562. public bool HasGlyphNames
  563. {
  564. get
  565. {
  566. return (FaceFlags & FaceFlags.GlyphNames) == FaceFlags.GlyphNames;
  567. }
  568. }
  569. /// <summary>
  570. /// Gets a value indicating whether a face object contains some multiple masters. The functions provided by
  571. /// FT_MULTIPLE_MASTERS_H are then available to choose the exact design you want.
  572. /// </summary>
  573. public bool HasMultipleMasters
  574. {
  575. get
  576. {
  577. return (FaceFlags & FaceFlags.MultipleMasters) == FaceFlags.MultipleMasters;
  578. }
  579. }
  580. /// <summary><para>
  581. /// Gets a value indicating whether a face object contains a CID-keyed font. See the discussion of
  582. /// FT_FACE_FLAG_CID_KEYED for more details.
  583. /// </para><para>
  584. /// If this macro is true, all functions defined in FT_CID_H are available.
  585. /// </para></summary>
  586. public bool IsCidKeyed
  587. {
  588. get
  589. {
  590. return (FaceFlags & FaceFlags.CidKeyed) == FaceFlags.CidKeyed;
  591. }
  592. }
  593. /// <summary>
  594. /// Gets a value indicating whether a face represents a ‘tricky’ font. See the discussion of
  595. /// FT_FACE_FLAG_TRICKY for more details.
  596. /// </summary>
  597. public bool IsTricky
  598. {
  599. get
  600. {
  601. return (FaceFlags & FaceFlags.Tricky) == FaceFlags.Tricky;
  602. }
  603. }
  604. internal IntPtr Reference
  605. {
  606. get
  607. {
  608. if (disposed)
  609. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  610. return reference;
  611. }
  612. set
  613. {
  614. if (disposed)
  615. throw new ObjectDisposedException("Reference", "Cannot access a disposed object.");
  616. reference = value;
  617. rec = PInvokeHelper.PtrToStructure<FaceRec>(reference);
  618. }
  619. }
  620. #endregion
  621. #region Methods
  622. #region FreeType Version
  623. /// <summary><para>
  624. /// Parse all bytecode instructions of a TrueType font file to check whether any of the patented opcodes are
  625. /// used. This is only useful if you want to be able to use the unpatented hinter with fonts that do not use
  626. /// these opcodes.
  627. /// </para><para>
  628. /// Note that this function parses all glyph instructions in the font file, which may be slow.
  629. /// </para></summary>
  630. /// <remarks>
  631. /// Since May 2010, TrueType hinting is no longer patented.
  632. /// </remarks>
  633. /// <returns>True if this is a TrueType font that uses one of the patented opcodes, false otherwise.</returns>
  634. public bool CheckTrueTypePatents()
  635. {
  636. if (disposed)
  637. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  638. return FT.FT_Face_CheckTrueTypePatents(Reference);
  639. }
  640. /// <summary>
  641. /// Enable or disable the unpatented hinter for a given <see cref="Face"/>. Only enable it if you have
  642. /// determined that the face doesn't use any patented opcodes.
  643. /// </summary>
  644. /// <remarks>
  645. /// Since May 2010, TrueType hinting is no longer patented.
  646. /// </remarks>
  647. /// <param name="value">New boolean setting.</param>
  648. /// <returns>
  649. /// The old setting value. This will always be false if this is not an SFNT font, or if the unpatented hinter
  650. /// is not compiled in this instance of the library.
  651. /// </returns>
  652. /// <see cref="CheckTrueTypePatents"/>
  653. public bool SetUnpatentedHinting(bool value)
  654. {
  655. if (disposed)
  656. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  657. return FT.FT_Face_SetUnpatentedHinting(Reference, value);
  658. }
  659. #endregion
  660. #region Base Interface
  661. /// <summary>
  662. /// This function calls <see cref="AttachStream"/> to attach a file.
  663. /// </summary>
  664. /// <param name="path">The pathname.</param>
  665. public void AttachFile(string path)
  666. {
  667. if (disposed)
  668. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  669. Error err = FT.FT_Attach_File(Reference, path);
  670. if (err != Error.Ok)
  671. throw new FreeTypeException(err);
  672. }
  673. /// <summary>
  674. /// ‘Attach’ data to a face object. Normally, this is used to read additional information for the face object.
  675. /// For example, you can attach an AFM file that comes with a Type 1 font to get the kerning values and other
  676. /// metrics.
  677. /// </summary>
  678. /// <remarks><para>
  679. /// The meaning of the ‘attach’ (i.e., what really happens when the new file is read) is not fixed by FreeType
  680. /// itself. It really depends on the font format (and thus the font driver).
  681. /// </para><para>
  682. /// Client applications are expected to know what they are doing when invoking this function. Most drivers
  683. /// simply do not implement file attachments.
  684. /// </para></remarks>
  685. /// <param name="parameters">A pointer to <see cref="OpenArgs"/> which must be filled by the caller.</param>
  686. public void AttachStream(OpenArgs parameters)
  687. {
  688. if (disposed)
  689. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  690. Error err = FT.FT_Attach_Stream(Reference, parameters.Reference);
  691. if (err != Error.Ok)
  692. throw new FreeTypeException(err);
  693. }
  694. /// <summary>
  695. /// Select a bitmap strike.
  696. /// </summary>
  697. /// <param name="strikeIndex">
  698. /// The index of the bitmap strike in the <see cref="Face.AvailableSizes"/> field of <see cref="Face"/>
  699. /// structure.
  700. /// </param>
  701. public void SelectSize(int strikeIndex)
  702. {
  703. if (disposed)
  704. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  705. Error err = FT.FT_Select_Size(Reference, strikeIndex);
  706. if (err != Error.Ok)
  707. throw new FreeTypeException(err);
  708. }
  709. /// <summary>
  710. /// Resize the scale of the active <see cref="FTSize"/> object in a face.
  711. /// </summary>
  712. /// <param name="request">A pointer to a <see cref="SizeRequest"/>.</param>
  713. public void RequestSize(SizeRequest request)
  714. {
  715. if (disposed)
  716. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  717. Error err = FT.FT_Request_Size(Reference, request.Reference);
  718. if (err != Error.Ok)
  719. throw new FreeTypeException(err);
  720. }
  721. /// <summary>
  722. /// This function calls <see cref="RequestSize"/> to request the nominal size (in points).
  723. /// </summary>
  724. /// <remarks><para>
  725. /// If either the character width or height is zero, it is set equal to the other value.
  726. /// </para><para>
  727. /// If either the horizontal or vertical resolution is zero, it is set equal to the other value.
  728. /// </para><para>
  729. /// A character width or height smaller than 1pt is set to 1pt; if both resolution values are zero, they are
  730. /// set to 72dpi.
  731. /// </para></remarks>
  732. /// <param name="width">The nominal width, in 26.6 fractional points.</param>
  733. /// <param name="height">The nominal height, in 26.6 fractional points.</param>
  734. /// <param name="horizontalResolution">The horizontal resolution in dpi.</param>
  735. /// <param name="verticalResolution">The vertical resolution in dpi.</param>
  736. [CLSCompliant(false)]
  737. public void SetCharSize(int width, int height, uint horizontalResolution, uint verticalResolution)
  738. {
  739. if (disposed)
  740. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  741. Error err = FT.FT_Set_Char_Size(Reference, width, height, horizontalResolution, verticalResolution);
  742. if (err != Error.Ok)
  743. throw new FreeTypeException(err);
  744. }
  745. /// <summary>
  746. /// This function calls <see cref="RequestSize"/> to request the nominal size (in pixels).
  747. /// </summary>
  748. /// <param name="width">The nominal width, in pixels.</param>
  749. /// <param name="height">The nominal height, in pixels</param>
  750. [CLSCompliant(false)]
  751. public void SetPixelSizes(uint width, uint height)
  752. {
  753. if (disposed)
  754. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  755. Error err = FT.FT_Set_Pixel_Sizes(Reference, width, height);
  756. if (err != Error.Ok)
  757. throw new FreeTypeException(err);
  758. }
  759. /// <summary>
  760. /// A function used to load a single glyph into the glyph slot of a face object.
  761. /// </summary>
  762. /// <remarks><para>
  763. /// The loaded glyph may be transformed. See <see cref="SetTransform"/> for the details.
  764. /// </para><para>
  765. /// For subsetted CID-keyed fonts, <see cref="Error.InvalidArgument"/> is returned for invalid CID values (this
  766. /// is, for CID values which don't have a corresponding glyph in the font). See the discussion of the
  767. /// <see cref="SharpFont.FaceFlags.CidKeyed"/> flag for more details.
  768. /// </para></remarks>
  769. /// <param name="glyphIndex">
  770. /// The index of the glyph in the font file. For CID-keyed fonts (either in PS or in CFF format) this argument
  771. /// specifies the CID value.
  772. /// </param>
  773. /// <param name="flags">
  774. /// A flag indicating what to load for this glyph. The <see cref="LoadFlags"/> constants can be used to control
  775. /// the glyph loading process (e.g., whether the outline should be scaled, whether to load bitmaps or not,
  776. /// whether to hint the outline, etc).
  777. /// </param>
  778. /// <param name="target">The target to OR with the flags.</param>
  779. [CLSCompliant(false)]
  780. public void LoadGlyph(uint glyphIndex, LoadFlags flags, LoadTarget target)
  781. {
  782. if (disposed)
  783. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  784. Error err = FT.FT_Load_Glyph(Reference, glyphIndex, (int)flags | (int)target);
  785. if (err != Error.Ok)
  786. throw new FreeTypeException(err);
  787. }
  788. /// <summary>
  789. /// A function used to load a single glyph into the glyph slot of a face object, according to its character
  790. /// code.
  791. /// </summary>
  792. /// <remarks>
  793. /// This function simply calls <see cref="GetCharIndex"/> and <see cref="LoadGlyph"/>
  794. /// </remarks>
  795. /// <param name="charCode">
  796. /// The glyph's character code, according to the current charmap used in the face.
  797. /// </param>
  798. /// <param name="flags">
  799. /// A flag indicating what to load for this glyph. The <see cref="LoadFlags"/> constants can be used to control
  800. /// the glyph loading process (e.g., whether the outline should be scaled, whether to load bitmaps or not,
  801. /// whether to hint the outline, etc).
  802. /// </param>
  803. /// <param name="target">The target to OR with the flags.</param>
  804. [CLSCompliant(false)]
  805. public void LoadChar(uint charCode, LoadFlags flags, LoadTarget target)
  806. {
  807. if (disposed)
  808. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  809. Error err = FT.FT_Load_Char(Reference, charCode, (int)flags | (int)target);
  810. if (err != Error.Ok)
  811. throw new FreeTypeException(err);
  812. }
  813. /// <summary>
  814. /// A function used to set the transformation that is applied to glyph images when they are loaded into a glyph
  815. /// slot through <see cref="LoadGlyph"/>.
  816. /// </summary>
  817. /// <remarks><para>
  818. /// The transformation is only applied to scalable image formats after the glyph has been loaded. It means that
  819. /// hinting is unaltered by the transformation and is performed on the character size given in the last call to
  820. /// <see cref="SetCharSize"/> or <see cref="SetPixelSizes"/>.
  821. /// </para><para>
  822. /// Note that this also transforms the ‘face.glyph.advance’ field, but not the values in ‘face.glyph.metrics’.
  823. /// </para></remarks>
  824. /// <param name="matrix">A pointer to the transformation's 2x2 matrix. Use 0 for the identity matrix.</param>
  825. /// <param name="delta">A pointer to the translation vector. Use 0 for the null vector.</param>
  826. public void SetTransform(FTMatrix matrix, FTVector delta)
  827. {
  828. if (disposed)
  829. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  830. FT.FT_Set_Transform(Reference, ref matrix, ref delta);
  831. }
  832. /// <summary>
  833. /// Return the kerning vector between two glyphs of a same face.
  834. /// </summary>
  835. /// <remarks>
  836. /// Only horizontal layouts (left-to-right &amp; right-to-left) are supported by this method. Other layouts, or
  837. /// more sophisticated kernings, are out of the scope of this API function -- they can be implemented through
  838. /// format-specific interfaces.
  839. /// </remarks>
  840. /// <param name="leftGlyph">The index of the left glyph in the kern pair.</param>
  841. /// <param name="rightGlyph">The index of the right glyph in the kern pair.</param>
  842. /// <param name="mode">Determines the scale and dimension of the returned kerning vector.</param>
  843. /// <returns>
  844. /// The kerning vector. This is either in font units or in pixels (26.6 format) for scalable formats, and in
  845. /// pixels for fixed-sizes formats.
  846. /// </returns>
  847. [CLSCompliant(false)]
  848. public FTVector GetKerning(uint leftGlyph, uint rightGlyph, KerningMode mode)
  849. {
  850. if (disposed)
  851. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  852. FTVector kern;
  853. Error err = FT.FT_Get_Kerning(Reference, leftGlyph, rightGlyph, mode, out kern);
  854. if (err != Error.Ok)
  855. throw new FreeTypeException(err);
  856. return kern;
  857. }
  858. /// <summary>
  859. /// Return the track kerning for a given face object at a given size.
  860. /// </summary>
  861. /// <param name="pointSize">The point size in 16.16 fractional points.</param>
  862. /// <param name="degree">The degree of tightness.</param>
  863. /// <returns>The kerning in 16.16 fractional points.</returns>
  864. public int GetTrackKerning(int pointSize, int degree)
  865. {
  866. if (disposed)
  867. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  868. int kerning;
  869. Error err = FT.FT_Get_Track_Kerning(Reference, pointSize, degree, out kerning);
  870. if (err != Error.Ok)
  871. throw new FreeTypeException(err);
  872. return kerning;
  873. }
  874. /// <summary>
  875. /// Retrieve the ASCII name of a given glyph in a face. This only works for those faces where
  876. /// <see cref="HasGlyphNames"/> returns 1.
  877. /// </summary>
  878. /// <remarks><para>
  879. /// An error is returned if the face doesn't provide glyph names or if the glyph index is invalid. In all cases
  880. /// of failure, the first byte of ‘buffer’ is set to 0 to indicate an empty name.
  881. /// </para><para>
  882. /// The glyph name is truncated to fit within the buffer if it is too long. The returned string is always
  883. /// zero-terminated.
  884. /// </para><para>
  885. /// Be aware that FreeType reorders glyph indices internally so that glyph index 0 always corresponds to the
  886. /// ‘missing glyph’ (called ‘.notdef’).
  887. /// </para><para>
  888. /// This function is not compiled within the library if the config macro ‘FT_CONFIG_OPTION_NO_GLYPH_NAMES’ is
  889. /// defined in ‘include/freetype/config/ftoptions.h’.
  890. /// </para></remarks>
  891. /// <param name="glyphIndex">The glyph index.</param>
  892. /// <param name="bufferSize">The maximal number of bytes available in the buffer.</param>
  893. /// <returns>The ASCII name of a given glyph in a face.</returns>
  894. [CLSCompliant(false)]
  895. public string GetGlyphName(uint glyphIndex, int bufferSize)
  896. {
  897. if (disposed)
  898. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  899. return GetGlyphName(glyphIndex, new byte[bufferSize]);
  900. }
  901. /// <summary>
  902. /// Retrieve the ASCII name of a given glyph in a face. This only works for those faces where
  903. /// <see cref="HasGlyphNames"/> returns 1.
  904. /// </summary>
  905. /// <remarks><para>
  906. /// An error is returned if the face doesn't provide glyph names or if the glyph index is invalid. In all cases
  907. /// of failure, the first byte of ‘buffer’ is set to 0 to indicate an empty name.
  908. /// </para><para>
  909. /// The glyph name is truncated to fit within the buffer if it is too long. The returned string is always
  910. /// zero-terminated.
  911. /// </para><para>
  912. /// Be aware that FreeType reorders glyph indices internally so that glyph index 0 always corresponds to the
  913. /// ‘missing glyph’ (called ‘.notdef’).
  914. /// </para><para>
  915. /// This function is not compiled within the library if the config macro ‘FT_CONFIG_OPTION_NO_GLYPH_NAMES’ is
  916. /// defined in ‘include/freetype/config/ftoptions.h’.
  917. /// </para></remarks>
  918. /// <param name="glyphIndex">The glyph index.</param>
  919. /// <param name="buffer">The target buffer where the name is copied to.</param>
  920. /// <returns>The ASCII name of a given glyph in a face.</returns>
  921. [CLSCompliant(false)]
  922. public unsafe string GetGlyphName(uint glyphIndex, byte[] buffer)
  923. {
  924. if (disposed)
  925. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  926. fixed (byte* ptr = buffer)
  927. {
  928. IntPtr intptr = new IntPtr(ptr);
  929. Error err = FT.FT_Get_Glyph_Name(Reference, glyphIndex, intptr, (uint)buffer.Length);
  930. if (err != Error.Ok)
  931. throw new FreeTypeException(err);
  932. return Marshal.PtrToStringAnsi(intptr);
  933. }
  934. }
  935. /// <summary>
  936. /// Retrieve the ASCII Postscript name of a given face, if available. This only works with Postscript and
  937. /// TrueType fonts.
  938. /// </summary>
  939. /// <remarks>
  940. /// The returned pointer is owned by the face and is destroyed with it.
  941. /// </remarks>
  942. /// <returns>A pointer to the face's Postscript name. NULL if unavailable.</returns>
  943. public string GetPostscriptName()
  944. {
  945. if (disposed)
  946. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  947. return Marshal.PtrToStringAnsi(FT.FT_Get_Postscript_Name(Reference));
  948. }
  949. /// <summary>
  950. /// Select a given charmap by its encoding tag (as listed in ‘freetype.h’).
  951. /// </summary>
  952. /// <remarks><para>
  953. /// This function returns an error if no charmap in the face corresponds to the encoding queried here.
  954. /// </para><para>
  955. /// Because many fonts contain more than a single cmap for Unicode encoding, this function has some special
  956. /// code to select the one which covers Unicode best. It is thus preferable to <see cref="SetCharmap"/> in
  957. /// this case.
  958. /// </para></remarks>
  959. /// <param name="encoding">A handle to the selected encoding.</param>
  960. [CLSCompliant(false)]
  961. public void SelectCharmap(Encoding encoding)
  962. {
  963. if (disposed)
  964. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  965. Error err = FT.FT_Select_Charmap(Reference, encoding);
  966. if (err != Error.Ok)
  967. throw new FreeTypeException(err);
  968. }
  969. /// <summary>
  970. /// Select a given charmap for character code to glyph index mapping.
  971. /// </summary>
  972. /// <remarks>
  973. /// This function returns an error if the charmap is not part of the face (i.e., if it is not listed in the
  974. /// <see cref="Face.CharMaps"/>’ table).
  975. /// </remarks>
  976. /// <param name="charmap">A handle to the selected charmap.</param>
  977. public void SetCharmap(CharMap charmap)
  978. {
  979. if (disposed)
  980. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  981. Error err = FT.FT_Set_Charmap(Reference, charmap.Reference);
  982. if (err != Error.Ok)
  983. throw new FreeTypeException(err);
  984. }
  985. /// <summary>
  986. /// Return the glyph index of a given character code. This function uses a charmap object to do the mapping.
  987. /// </summary>
  988. /// <remarks>
  989. /// If you use FreeType to manipulate the contents of font files directly, be aware that the glyph index
  990. /// returned by this function doesn't always correspond to the internal indices used within the file. This is
  991. /// done to ensure that value 0 always corresponds to the ‘missing glyph’.
  992. /// </remarks>
  993. /// <param name="charCode">The character code.</param>
  994. /// <returns>The glyph index. 0 means ‘undefined character code’.</returns>
  995. [CLSCompliant(false)]
  996. public uint GetCharIndex(uint charCode)
  997. {
  998. if (disposed)
  999. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1000. return FT.FT_Get_Char_Index(Reference, charCode);
  1001. }
  1002. /// <summary>
  1003. /// This function is used to return the first character code in the current charmap of a given face. It also
  1004. /// returns the corresponding glyph index.
  1005. /// </summary>
  1006. /// <remarks><para>
  1007. /// You should use this function with <see cref="GetNextChar"/> to be able to parse all character codes
  1008. /// available in a given charmap.
  1009. /// </para><para>
  1010. /// Note that ‘agindex’ is set to 0 if the charmap is empty. The result itself can be 0 in two cases: if the
  1011. /// charmap is empty or when the value 0 is the first valid character code.
  1012. /// </para></remarks>
  1013. /// <param name="glyphIndex">Glyph index of first character code. 0 if charmap is empty.</param>
  1014. /// <returns>The charmap's first character code.</returns>
  1015. [CLSCompliant(false)]
  1016. public uint GetFirstChar(out uint glyphIndex)
  1017. {
  1018. if (disposed)
  1019. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1020. return FT.FT_Get_First_Char(Reference, out glyphIndex);
  1021. }
  1022. /// <summary>
  1023. /// This function is used to return the next character code in the current charmap of a given face following
  1024. /// the value ‘charCode’, as well as the corresponding glyph index.
  1025. /// </summary>
  1026. /// <remarks><para>
  1027. /// You should use this function with <see cref="GetFirstChar"/> to walk over all character codes available
  1028. /// in a given charmap. See the note for this function for a simple code example.
  1029. /// </para><para>
  1030. /// Note that ‘*agindex’ is set to 0 when there are no more codes in the charmap.
  1031. /// </para></remarks>
  1032. /// <param name="charCode">The starting character code.</param>
  1033. /// <param name="glyphIndex">Glyph index of first character code. 0 if charmap is empty.</param>
  1034. /// <returns>The charmap's next character code.</returns>
  1035. [CLSCompliant(false)]
  1036. public uint GetNextChar(uint charCode, out uint glyphIndex)
  1037. {
  1038. if (disposed)
  1039. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1040. return FT.FT_Get_Next_Char(Reference, charCode, out glyphIndex);
  1041. }
  1042. /// <summary>
  1043. /// Return the glyph index of a given glyph name. This function uses driver specific objects to do the
  1044. /// translation.
  1045. /// </summary>
  1046. /// <param name="name">The glyph name.</param>
  1047. /// <returns>The glyph index. 0 means ‘undefined character code’.</returns>
  1048. [CLSCompliant(false)]
  1049. public uint GetNameIndex(string name)
  1050. {
  1051. if (disposed)
  1052. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1053. return FT.FT_Get_Name_Index(Reference, Marshal.StringToHGlobalAuto(name));
  1054. }
  1055. /// <summary>
  1056. /// Return the <see cref="EmbeddingTypes"/> flags for a font.
  1057. /// </summary>
  1058. /// <remarks>
  1059. /// Use this function rather than directly reading the ‘fs_type’ field in the <see cref="PostScript.FontInfo"/>
  1060. /// structure which is only guaranteed to return the correct results for Type 1 fonts.
  1061. /// </remarks>
  1062. /// <returns>The fsType flags, <see cref="EmbeddingTypes"/>.</returns>
  1063. [CLSCompliant(false)]
  1064. public EmbeddingTypes GetFSTypeFlags()
  1065. {
  1066. if (disposed)
  1067. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1068. return FT.FT_Get_FSType_Flags(Reference);
  1069. }
  1070. #endregion
  1071. #region Glyph Variants
  1072. /// <summary>
  1073. /// Return the glyph index of a given character code as modified by the variation selector.
  1074. /// </summary>
  1075. /// <remarks><para>
  1076. /// If you use FreeType to manipulate the contents of font files directly, be aware that the glyph index
  1077. /// returned by this function doesn't always correspond to the internal indices used within the file. This is
  1078. /// done to ensure that value 0 always corresponds to the ‘missing glyph’.
  1079. /// </para><para>
  1080. /// This function is only meaningful if a) the font has a variation selector cmap sub table, and b) the current
  1081. /// charmap has a Unicode encoding.
  1082. /// </para></remarks>
  1083. /// <param name="charCode">The character code point in Unicode.</param>
  1084. /// <param name="variantSelector">The Unicode code point of the variation selector.</param>
  1085. /// <returns>
  1086. /// The glyph index. 0 means either ‘undefined character code’, or ‘undefined selector code’, or ‘no variation
  1087. /// selector cmap subtable’, or ‘current CharMap is not Unicode’.
  1088. /// </returns>
  1089. [CLSCompliant(false)]
  1090. public uint GetCharVariantIndex(uint charCode, uint variantSelector)
  1091. {
  1092. if (disposed)
  1093. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1094. return FT.FT_Face_GetCharVariantIndex(Reference, charCode, variantSelector);
  1095. }
  1096. /// <summary>
  1097. /// Check whether this variant of this Unicode character is the one to be found in the ‘cmap’.
  1098. /// </summary>
  1099. /// <remarks>
  1100. /// This function is only meaningful if the font has a variation selector cmap subtable.
  1101. /// </remarks>
  1102. /// <param name="charCode">The character codepoint in Unicode.</param>
  1103. /// <param name="variantSelector">The Unicode codepoint of the variation selector.</param>
  1104. /// <returns>
  1105. /// 1 if found in the standard (Unicode) cmap, 0 if found in the variation selector cmap, or -1 if it is not a
  1106. /// variant.
  1107. /// </returns>
  1108. [CLSCompliant(false)]
  1109. public int GetCharVariantIsDefault(uint charCode, uint variantSelector)
  1110. {
  1111. if (disposed)
  1112. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1113. return FT.FT_Face_GetCharVariantIsDefault(Reference, charCode, variantSelector);
  1114. }
  1115. /// <summary>
  1116. /// Return a zero-terminated list of Unicode variant selectors found in the font.
  1117. /// </summary>
  1118. /// <remarks>
  1119. /// The last item in the array is 0; the array is owned by the <see cref="Face"/> object but can be overwritten
  1120. /// or released on the next call to a FreeType function.
  1121. /// </remarks>
  1122. /// <returns>
  1123. /// A pointer to an array of selector code points, or NULL if there is no valid variant selector cmap subtable.
  1124. /// </returns>
  1125. [CLSCompliant(false)]
  1126. public uint[] GetVariantSelectors()
  1127. {
  1128. if (disposed)
  1129. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1130. IntPtr ptr = FT.FT_Face_GetVariantSelectors(Reference);
  1131. List<uint> list = new List<uint>();
  1132. //temporary non-zero value to prevent complaining about uninitialized variable.
  1133. uint curValue = 1;
  1134. for (int i = 0; curValue != 0; i++)
  1135. {
  1136. curValue = (uint)Marshal.ReadInt32(Reference, sizeof(uint) * i);
  1137. list.Add(curValue);
  1138. }
  1139. return list.ToArray();
  1140. }
  1141. /// <summary>
  1142. /// Return a zero-terminated list of Unicode variant selectors found in the font.
  1143. /// </summary>
  1144. /// <remarks>
  1145. /// The last item in the array is 0; the array is owned by the <see cref="Face"/> object but can be overwritten
  1146. /// or released on the next call to a FreeType function.
  1147. /// </remarks>
  1148. /// <param name="charCode">The character codepoint in Unicode.</param>
  1149. /// <returns>
  1150. /// A pointer to an array of variant selector code points which are active for the given character, or NULL if
  1151. /// the corresponding list is empty.
  1152. /// </returns>
  1153. [CLSCompliant(false)]
  1154. public uint[] GetVariantsOfChar(uint charCode)
  1155. {
  1156. if (disposed)
  1157. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1158. IntPtr ptr = FT.FT_Face_GetVariantsOfChar(Reference, charCode);
  1159. List<uint> list = new List<uint>();
  1160. //temporary non-zero value to prevent complaining about uninitialized variable.
  1161. uint curValue = 1;
  1162. for (int i = 0; curValue != 0; i++)
  1163. {
  1164. curValue = (uint)Marshal.ReadInt32(Reference, sizeof(uint) * i);
  1165. list.Add(curValue);
  1166. }
  1167. return list.ToArray();
  1168. }
  1169. /// <summary>
  1170. /// Return a zero-terminated list of Unicode character codes found for the specified variant selector.
  1171. /// </summary>
  1172. /// <remarks>
  1173. /// The last item in the array is 0; the array is owned by the <see cref="Face"/> object but can be overwritten
  1174. /// or released on the next call to a FreeType function.
  1175. /// </remarks>
  1176. /// <param name="variantSelector">The variant selector code point in Unicode.</param>
  1177. /// <returns>
  1178. /// A list of all the code points which are specified by this selector (both default and non-default codes are
  1179. /// returned) or NULL if there is no valid cmap or the variant selector is invalid.
  1180. /// </returns>
  1181. [CLSCompliant(false)]
  1182. public uint[] GetCharsOfVariant(uint variantSelector)
  1183. {
  1184. if (disposed)
  1185. throw new ObjectDisposedException("face", "Cannot access a disposed object.");
  1186. IntPtr ptr = FT.FT_Face_GetCharsOfVariant(Reference, variantSelector);
  1187. List<uint> list = new List<uint>();
  1188. //temporary non-zero value to prevent complaining about uninitialized variable.
  1189. uint curValue = 1;
  1190. for (int i = 0; curValue != 0; i++)
  1191. {
  1192. curValue = (uint)Marshal.ReadInt32(Reference, sizeof(uint) * i);
  1193. list.Add(curValue);
  1194. }
  1195. return list.ToArray();
  1196. }
  1197. #endregion
  1198. #region Size Management
  1199. /// <summary>
  1200. /// Create a new size object from a given face object.
  1201. /// </summary>
  1202. /// <remarks>
  1203. /// You need to call <see cref="FTSize.Activate"/> in order to select the new size for upcoming calls to
  1204. /// <see cref="SetPixelSizes"/>, <see cref="SetCharSize"/>, <see cref="LoadGlyph"/>, <see cref="LoadChar"/>,
  1205. /// etc.
  1206. /// </remarks>
  1207. /// <returns>A handle to a new size object.</returns>
  1208. public FTSize NewSize()
  1209. {
  1210. return new FTSize(this);
  1211. }
  1212. #endregion
  1213. #region Multiple Masters
  1214. /// <summary><para>
  1215. /// Retrieve the Multiple Master descriptor of a given font.
  1216. /// </para><para>
  1217. /// This function can't be used with GX fonts.
  1218. /// </para></summary>
  1219. /// <returns>The Multiple Masters descriptor.</returns>
  1220. public MultiMaster GetMultiMaster()
  1221. {
  1222. IntPtr masterRef;
  1223. Error err = FT.FT_Get_Multi_Master(Reference, out masterRef);
  1224. if (err != Error.Ok)
  1225. throw new FreeTypeException(err);
  1226. return new MultiMaster(masterRef);
  1227. }
  1228. /// <summary>
  1229. /// Retrieve the Multiple Master/GX var descriptor of a given font.
  1230. /// </summary>
  1231. /// <returns>
  1232. /// The Multiple Masters/GX var descriptor. Allocates a data structure, which the user must free (a single call
  1233. /// to FT_FREE will do it).
  1234. /// </returns>
  1235. public MMVar GetMMVar()
  1236. {
  1237. IntPtr varRef;
  1238. Error err = FT.FT_Get_MM_Var(Reference, out varRef);
  1239. if (err != Error.Ok)
  1240. throw new FreeTypeException(err);
  1241. return new MMVar(varRef);
  1242. }
  1243. /// <summary><para>
  1244. /// For Multiple Masters fonts, choose an interpolated font design through design coordinates.
  1245. /// </para><para>
  1246. /// This function can't be used with GX fonts.
  1247. /// </para></summary>
  1248. /// <param name="coords">An array of design coordinates.</param>
  1249. public unsafe void SetMMDesignCoordinates(long[] coords)
  1250. {
  1251. fixed (void* ptr = coords)
  1252. {
  1253. IntPtr coordsPtr = (IntPtr)ptr;
  1254. Error err = FT.FT_Set_MM_Design_Coordinates(Reference, (uint)coords.Length, coordsPtr);
  1255. if (err != Error.Ok)
  1256. throw new FreeTypeException(err);
  1257. }
  1258. }
  1259. /// <summary>
  1260. /// For Multiple Master or GX Var fonts, choose an interpolated font design through design coordinates.
  1261. /// </summary>
  1262. /// <param name="coords">An array of design coordinates.</param>
  1263. public unsafe void SetVarDesignCoordinates(long[] coords)
  1264. {
  1265. fixed (void* ptr = coords)
  1266. {
  1267. IntPtr coordsPtr = (IntPtr)ptr;
  1268. Error err = FT.FT_Set_Var_Design_Coordinates(Reference, (uint)coords.Length, coordsPtr);
  1269. if (err != Error.Ok)
  1270. throw new FreeTypeException(err);
  1271. }
  1272. }
  1273. /// <summary>
  1274. /// For Multiple Masters and GX var fonts, choose an interpolated font design through normalized blend
  1275. /// coordinates.
  1276. /// </summary>
  1277. /// <param name="coords">The design coordinates array (each element must be between 0 and 1.0).</param>
  1278. public unsafe void SetMMBlendCoordinates(long[] coords)
  1279. {
  1280. fixed (void* ptr = coords)
  1281. {
  1282. IntPtr coordsPtr = (IntPtr)ptr;
  1283. Error err = FT.FT_Set_MM_Blend_Coordinates(Reference, (uint)coords.Length, coordsPtr);
  1284. if (err != Error.Ok)
  1285. throw new FreeTypeException(err);
  1286. }
  1287. }
  1288. /// <summary>
  1289. /// This is another name of <see cref="SetMMBlendCoordinates"/>.
  1290. /// </summary>
  1291. /// <param name="coords">The design coordinates array (each element must be between 0 and 1.0).</param>
  1292. public unsafe void SetVarBlendCoordinates(long[] coords)
  1293. {
  1294. fixed (void* ptr = coords)
  1295. {
  1296. IntPtr coordsPtr = (IntPtr)ptr;
  1297. Error err = FT.FT_Set_Var_Blend_Coordinates(Reference, (uint)coords.Length, coordsPtr);
  1298. if (err != Error.Ok)
  1299. throw new FreeTypeException(err);
  1300. }
  1301. }
  1302. #endregion
  1303. #region TrueType Tables
  1304. /// <summary>
  1305. /// Return a pointer to a given SFNT table within a face.
  1306. /// </summary>
  1307. /// <remarks><para>
  1308. /// The table is owned by the face object and disappears with it.
  1309. /// </para><para>
  1310. /// This function is only useful to access SFNT tables that are loaded by the sfnt, truetype, and opentype
  1311. /// drivers. See <see cref="SfntTag"/> for a list.
  1312. /// </para></remarks>
  1313. /// <param name="tag">The index of the SFNT table.</param>
  1314. /// <returns><para>
  1315. /// A type-less pointer to the table. This will be 0 in case of error, or if the corresponding table was not
  1316. /// found OR loaded from the file.
  1317. /// </para><para>
  1318. /// Use a typecast according to ‘tag’ to access the structure elements.
  1319. /// </para></returns>
  1320. public object GetSfntTable(SfntTag tag)
  1321. {
  1322. IntPtr tableRef = FT.FT_Get_Sfnt_Table(Reference, tag);
  1323. if (tableRef == IntPtr.Zero)
  1324. return null;
  1325. switch (tag)
  1326. {
  1327. case SfntTag.Header:
  1328. return new Header(tableRef);
  1329. case SfntTag.HorizontalHeader:
  1330. return new HoriHeader(tableRef);
  1331. case SfntTag.MaxProfile:
  1332. return new MaxProfile(tableRef);
  1333. case SfntTag.OS2:
  1334. return new OS2(tableRef);
  1335. case SfntTag.Pclt:
  1336. return new Pclt(tableRef);
  1337. case SfntTag.Postscript:
  1338. return new Postscript(tableRef);
  1339. case SfntTag.VertHeader:
  1340. return new VertHeader(tableRef);
  1341. default:
  1342. return null;
  1343. }
  1344. }
  1345. /// <summary>
  1346. /// Load any font table into client memory.
  1347. /// </summary>
  1348. /// <remarks>
  1349. /// If you need to determine the table's length you should first call this function with ‘*length’ set to 0, as
  1350. /// in the following example:
  1351. /// <code>
  1352. /// FT_ULong length = 0;
  1353. ///
  1354. ///
  1355. /// error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &amp;length );
  1356. /// if ( error ) { ... table does not exist ... }
  1357. ///
  1358. /// buffer = malloc( length );
  1359. /// if ( buffer == NULL ) { ... not enough memory ... }
  1360. ///
  1361. /// error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &amp;length );
  1362. /// if ( error ) { ... could not load table ... }
  1363. /// </code>
  1364. /// </remarks>
  1365. /// <param name="tag">
  1366. /// The four-byte tag of the table to load. Use the value 0 if you want to access the whole font file.
  1367. /// Otherwise, you can use one of the definitions found in the FT_TRUETYPE_TAGS_H file, or forge a new one with
  1368. /// FT_MAKE_TAG.
  1369. /// </param>
  1370. /// <param name="offset">The starting offset in the table (or file if tag == 0).</param>
  1371. /// <param name="buffer">
  1372. /// The target buffer address. The client must ensure that the memory array is big enough to hold the data.
  1373. /// </param>
  1374. /// <param name="length"><para>
  1375. /// If the ‘length’ parameter is NULL, then try to load the whole table. Return an error code if it fails.
  1376. /// </para><para>
  1377. /// Else, if ‘*length’ is 0, exit immediately while returning the table's (or file) full size in it.
  1378. /// </para><para>
  1379. /// Else the number of bytes to read from the table or file, from the starting offset.
  1380. /// </para></param>
  1381. [CLSCompliant(false)]
  1382. public void LoadSfntTable(uint tag, int offset, IntPtr buffer, ref uint length)
  1383. {
  1384. Error err = FT.FT_Load_Sfnt_Table(Reference, tag, offset, buffer, ref length);
  1385. if (err != Error.Ok)
  1386. throw new FreeTypeException(err);
  1387. }
  1388. /// <summary>
  1389. /// Return information on an SFNT table.
  1390. /// </summary>
  1391. /// <param name="tableIndex">
  1392. /// The index of an SFNT table. The function returns <see cref="Error.TableMissing"/> for an invalid value.
  1393. /// </param>
  1394. /// <param name="tag">
  1395. /// The name tag of the SFNT table. If the value is NULL, ‘table_index’ is ignored, and ‘length’ returns the
  1396. /// number of SFNT tables in the font.
  1397. /// </param>
  1398. /// <returns>The length of the SFNT table (or the number of SFNT tables, depending on ‘tag’).</returns>
  1399. [CLSCompliant(false)]
  1400. public unsafe uint SfntTableInfo(uint tableIndex, SfntTag tag)
  1401. {
  1402. uint length;
  1403. Error err = FT.FT_Sfnt_Table_Info(Reference, tableIndex, &tag, out length);
  1404. if (err != Error.Ok)
  1405. throw new FreeTypeException(err);
  1406. return length;
  1407. }
  1408. /// <summary>
  1409. /// Only gets the number of SFNT tables.
  1410. /// </summary>
  1411. /// <returns>The number of SFNT tables.</returns>
  1412. [CLSCompliant(false)]
  1413. public unsafe uint SfntTableInfo()
  1414. {
  1415. uint length;
  1416. Error err = FT.FT_Sfnt_Table_Info(Reference, 0, null, out length);
  1417. if (err != Error.Ok)
  1418. throw new FreeTypeException(err);
  1419. return length;
  1420. }
  1421. #endregion
  1422. #region Type 1 Tables
  1423. /// <summary><para>
  1424. /// Return true if a given face provides reliable PostScript glyph names. This is similar to using the
  1425. /// <see cref="HasGlyphNames"/> macro, except that certain fonts (mostly TrueType) contain incorrect
  1426. /// glyph name tables.
  1427. /// </para><para>
  1428. /// When this function returns true, the caller is sure that the glyph names returned by
  1429. /// <see cref="GetGlyphName(uint, int)"/> are reliable.
  1430. /// </para></summary>
  1431. /// <returns>Boolean. True if glyph names are reliable.</returns>
  1432. public bool HasPSGlyphNames()
  1433. {
  1434. return FT.FT_Has_PS_Glyph_Names(Reference);
  1435. }
  1436. /// <summary>
  1437. /// Retrieve the <see cref="PostScript.FontInfo"/> structure corresponding to a given PostScript font.
  1438. /// </summary>
  1439. /// <remarks><para>
  1440. /// The string pointers within the font info structure are owned by the face and don't need to be freed by the
  1441. /// caller.
  1442. /// </para><para>
  1443. /// If the font's format is not PostScript-based, this function will return the
  1444. /// <see cref="Error.InvalidArgument"/> error code.
  1445. /// </para></remarks>
  1446. /// <returns>Output font info structure pointer.</returns>
  1447. public FontInfo GetPSFontInfo()
  1448. {
  1449. IntPtr fontInfoRef;
  1450. Error err = FT.FT_Get_PS_Font_Info(Reference, out fontInfoRef);
  1451. if (err != Error.Ok)
  1452. throw new FreeTypeException(err);
  1453. return new FontInfo(fontInfoRef);
  1454. }
  1455. /// <summary>
  1456. /// Retrieve the <see cref="PostScript.Private"/> structure corresponding to a given PostScript font.
  1457. /// </summary>
  1458. /// <remarks><para>
  1459. /// The string pointers within the <see cref="PostScript.Private"/> structure are owned by the face and don't
  1460. /// need to be freed by the caller.
  1461. /// </para><para>
  1462. /// If the font's format is not PostScript-based, this function returns the <see cref="Error.InvalidArgument"/>
  1463. /// error code.
  1464. /// </para></remarks>
  1465. /// <returns>Output private dictionary structure pointer.</returns>
  1466. public Private GetPSFontPrivate()
  1467. {
  1468. IntPtr privateRef;
  1469. Error err = FT.FT_Get_PS_Font_Private(Reference, out privateRef);
  1470. if (err != Error.Ok)
  1471. throw new FreeTypeException(err);
  1472. return new Private(privateRef);
  1473. }
  1474. /// <summary>
  1475. /// Retrieve the value for the supplied key from a PostScript font.
  1476. /// </summary>
  1477. /// <remarks><para>
  1478. /// The values returned are not pointers into the internal structures of the face, but are ‘fresh’ copies, so
  1479. /// that the memory containing them belongs to the calling application. This also enforces the ‘read-only’
  1480. /// nature of these values, i.e., this function cannot be used to manipulate the face.
  1481. /// </para><para>
  1482. /// ‘value’ is a void pointer because the values returned can be of various types.
  1483. /// </para><para>
  1484. /// If either ‘value’ is NULL or ‘value_len’ is too small, just the required memory size for the requested
  1485. /// entry is returned.
  1486. /// </para><para>
  1487. /// The ‘idx’ parameter is used, not only to retrieve elements of, for example, the FontMatrix or FontBBox, but
  1488. /// also to retrieve name keys from the CharStrings dictionary, and the charstrings themselves. It is ignored
  1489. /// for atomic values.
  1490. /// </para><para>
  1491. /// <see cref="PostScript.DictionaryKeys.BlueScale"/> returns a value that is scaled up by 1000. To get the
  1492. /// value as in the font stream, you need to divide by 65536000.0 (to remove the FT_Fixed scale, and the x1000
  1493. /// scale).
  1494. /// </para><para>
  1495. /// IMPORTANT: Only key/value pairs read by the FreeType interpreter can be retrieved. So, for example,
  1496. /// PostScript procedures such as NP, ND, and RD are not available. Arbitrary keys are, obviously, not be
  1497. /// available either.
  1498. /// </para><para>
  1499. /// If the font's format is not PostScript-based, this function returns the <see cref="Error.InvalidArgument"/>
  1500. /// error code.
  1501. /// </para></remarks>
  1502. /// <param name="key">An enumeration value representing the dictionary key to retrieve.</param>
  1503. /// <param name="idx">For array values, this specifies the index to be returned.</param>
  1504. /// <param name="value">A pointer to memory into which to write the value.</param>
  1505. /// <param name="valueLength">The size, in bytes, of the memory supplied for the value.</param>
  1506. /// <returns>
  1507. /// The amount of memory (in bytes) required to hold the requested value (if it exists, -1 otherwise).
  1508. /// </returns>
  1509. [CLSCompliant(false)]
  1510. public int GetPSFontValue(DictionaryKeys key, uint idx, ref IntPtr value, int valueLength)
  1511. {
  1512. return FT.FT_Get_PS_Font_Value(Reference, key, idx, ref value, valueLength);
  1513. }
  1514. #endregion
  1515. #region SFNT Names
  1516. /// <summary>
  1517. /// Retrieve the number of name strings in the SFNT ‘name’ table.
  1518. /// </summary>
  1519. /// <returns>The number of strings in the ‘name’ table.</returns>
  1520. [CLSCompliant(false)]
  1521. public uint GetSfntNameCount()
  1522. {
  1523. return FT.FT_Get_Sfnt_Name_Count(Reference);
  1524. }
  1525. /// <summary>
  1526. /// Retrieve a string of the SFNT ‘name’ table for a given index.
  1527. /// </summary>
  1528. /// <remarks><para>
  1529. /// The ‘string’ array returned in the ‘aname’ structure is not null-terminated. The application should
  1530. /// deallocate it if it is no longer in use.
  1531. /// </para><para>
  1532. /// Use <see cref="GetSfntNameCount"/> to get the total number of available ‘name’ table entries, then do a
  1533. /// loop until you get the right platform, encoding, and name ID.
  1534. /// </para></remarks>
  1535. /// <param name="idx">The index of the ‘name’ string.</param>
  1536. /// <returns>The indexed <see cref="SfntName"/> structure.</returns>
  1537. [CLSCompliant(false)]
  1538. public SfntName GetSfntName(uint idx)
  1539. {
  1540. IntPtr nameRef;
  1541. Error err = FT.FT_Get_Sfnt_Name(Reference, idx, out nameRef);
  1542. if (err != Error.Ok)
  1543. throw new FreeTypeException(err);
  1544. return new SfntName(nameRef);
  1545. }
  1546. #endregion
  1547. #region BDF and PCF Files
  1548. /// <summary>
  1549. /// Retrieve a BDF font character set identity, according to the BDF specification.
  1550. /// </summary>
  1551. /// <remarks>
  1552. /// This function only works with BDF faces, returning an error otherwise.
  1553. /// </remarks>
  1554. /// <param name="encoding">Charset encoding, as a C string, owned by the face.</param>
  1555. /// <param name="registry">Charset registry, as a C string, owned by the face.</param>
  1556. public void GetBdfCharsetId(out string encoding, out string registry)
  1557. {
  1558. Error err = FT.FT_Get_BDF_Charset_ID(Reference, out encoding, out registry);
  1559. if (err != Error.Ok)
  1560. throw new FreeTypeException(err);
  1561. }
  1562. /// <summary>
  1563. /// Retrieve a BDF property from a BDF or PCF font file.
  1564. /// </summary>
  1565. /// <remarks><para>
  1566. /// This function works with BDF and PCF fonts. It returns an error otherwise. It also returns an error if the
  1567. /// property is not in the font.
  1568. /// </para><para>
  1569. /// A ‘property’ is a either key-value pair within the STARTPROPERTIES ... ENDPROPERTIES block of a BDF font or
  1570. /// a key-value pair from the ‘info->props’ array within a ‘FontRec’ structure of a PCF font.
  1571. /// </para><para>
  1572. /// Integer properties are always stored as ‘signed’ within PCF fonts; consequently,
  1573. /// <see cref="PropertyType.Cardinal"/> is a possible return value for BDF fonts only.
  1574. /// </para><para>
  1575. /// In case of error, ‘aproperty->type’ is always set to <see cref="PropertyType.None"/>.
  1576. /// </para></remarks>
  1577. /// <param name="propertyName">The property name.</param>
  1578. /// <returns>The property.</returns>
  1579. public Property GetBdfProperty(string propertyName)
  1580. {
  1581. IntPtr propertyRef;
  1582. Error err = FT.FT_Get_BDF_Property(Reference, propertyName, out propertyRef);
  1583. if (err != Error.Ok)
  1584. throw new FreeTypeException(err);
  1585. return new Property(propertyRef);
  1586. }
  1587. #endregion
  1588. #region CID Fonts
  1589. /// <summary>
  1590. /// Retrieve the Registry/Ordering/Supplement triple (also known as the "R/O/S") from a CID-keyed font.
  1591. /// </summary>
  1592. /// <remarks>
  1593. /// This function only works with CID faces, returning an error otherwise.
  1594. /// </remarks>
  1595. /// <param name="registry">The registry, as a C string, owned by the face.</param>
  1596. /// <param name="ordering">The ordering, as a C string, owned by the face.</param>
  1597. /// <param name="supplement">The supplement.</param>
  1598. public void GetCidRegistryOrderingSupplement(out string registry, out string ordering, out int supplement)
  1599. {
  1600. Error err = FT.FT_Get_CID_Registry_Ordering_Supplement(Reference, out registry, out ordering, out supplement);
  1601. if (err != Error.Ok)
  1602. throw new FreeTypeException(err);
  1603. }
  1604. /// <summary>
  1605. /// Retrieve the type of the input face, CID keyed or not. In constrast to the
  1606. /// <see cref="IsCidKeyed"/> macro this function returns successfully also for CID-keyed fonts in an
  1607. /// SNFT wrapper.
  1608. /// </summary>
  1609. /// <remarks>
  1610. /// This function only works with CID faces and OpenType fonts, returning an error otherwise.
  1611. /// </remarks>
  1612. /// <returns>The type of the face as an FT_Bool.</returns>
  1613. public bool GetCidIsInternallyCidKeyed()
  1614. {
  1615. byte is_cid;
  1616. Error err = FT.FT_Get_CID_Is_Internally_CID_Keyed(Reference, out is_cid);
  1617. if (err != Error.Ok)
  1618. throw new FreeTypeException(err);
  1619. return is_cid == 1;
  1620. }
  1621. /// <summary>
  1622. /// Retrieve the CID of the input glyph index.
  1623. /// </summary>
  1624. /// <remarks>
  1625. /// This function only works with CID faces and OpenType fonts, returning an error otherwise.
  1626. /// </remarks>
  1627. /// <param name="glyphIndex">The input glyph index.</param>
  1628. /// <returns>The CID as an uint.</returns>
  1629. [CLSCompliant(false)]
  1630. public uint GetCidFromGlyphIndex(uint glyphIndex)
  1631. {
  1632. uint cid;
  1633. Error err = FT.FT_Get_CID_From_Glyph_Index(Reference, glyphIndex, out cid);
  1634. if (err != Error.Ok)
  1635. throw new FreeTypeException(err);
  1636. return cid;
  1637. }
  1638. #endregion
  1639. #region PFR Fonts
  1640. /// <summary>
  1641. /// Return the outline and metrics resolutions of a given PFR face.
  1642. /// </summary>
  1643. /// <remarks>
  1644. /// If the input face is not a PFR, this function will return an error. However, in all cases, it will return
  1645. /// valid values.
  1646. /// </remarks>
  1647. /// <param name="outlineResolution">
  1648. /// Outline resolution. This is equivalent to ‘face->units_per_EM’ for non-PFR fonts. Optional (parameter can
  1649. /// be NULL).
  1650. /// </param>
  1651. /// <param name="metricsResolution">
  1652. /// Metrics resolution. This is equivalent to ‘outline_resolution’ for non-PFR fonts. Optional (parameter can
  1653. /// be NULL).
  1654. /// </param>
  1655. /// <param name="metricsXScale">
  1656. /// A 16.16 fixed-point number used to scale distance expressed in metrics units to device sub-pixels. This is
  1657. /// equivalent to ‘face->size->x_scale’, but for metrics only. Optional (parameter can be NULL).
  1658. /// </param>
  1659. /// <param name="metricsYScale">
  1660. /// Same as ‘ametrics_x_scale’ but for the vertical direction. optional (parameter can be NULL).
  1661. /// </param>
  1662. [CLSCompliant(false)]
  1663. public void GetPfrMetrics(out uint outlineResolution, out uint metricsResolution, out int metricsXScale, out int metricsYScale)
  1664. {
  1665. Error err = FT.FT_Get_PFR_Metrics(Reference, out outlineResolution, out metricsResolution, out metricsXScale, out metricsYScale);
  1666. if (err != Error.Ok)
  1667. throw new FreeTypeException(err);
  1668. }
  1669. /// <summary>
  1670. /// Return the kerning pair corresponding to two glyphs in a PFR face. The distance is expressed in metrics
  1671. /// units, unlike the result of <see cref="GetKerning"/>.
  1672. /// </summary>
  1673. /// <remarks><para>
  1674. /// This function always return distances in original PFR metrics units. This is unlike
  1675. /// <see cref="GetKerning"/> with the <see cref="KerningMode.Unscaled"/> mode, which always returns
  1676. /// distances converted to outline units.
  1677. /// </para><para>
  1678. /// You can use the value of the ‘x_scale’ and ‘y_scale’ parameters returned by <see cref="GetPfrMetrics"/> to
  1679. /// scale these to device sub-pixels.
  1680. /// </para></remarks>
  1681. /// <param name="left">Index of the left glyph.</param>
  1682. /// <param name="right">Index of the right glyph.</param>
  1683. /// <returns>A kerning vector.</returns>
  1684. [CLSCompliant(false)]
  1685. public FTVector GetPfrKerning(uint left, uint right)
  1686. {
  1687. FTVector vector;
  1688. Error err = FT.FT_Get_PFR_Kerning(Reference, left, right, out vector);
  1689. if (err != Error.Ok)
  1690. throw new FreeTypeException(err);
  1691. return vector;
  1692. }
  1693. /// <summary>
  1694. /// Return a given glyph advance, expressed in original metrics units, from a PFR font.
  1695. /// </summary>
  1696. /// <remarks>
  1697. /// You can use the ‘x_scale’ or ‘y_scale’ results of <see cref="GetPfrMetrics"/> to convert the advance to
  1698. /// device sub-pixels (i.e., 1/64th of pixels).
  1699. /// </remarks>
  1700. /// <param name="glyphIndex">The glyph index.</param>
  1701. /// <returns>The glyph advance in metrics units.</returns>
  1702. [CLSCompliant(false)]
  1703. public int GetPfrAdvance(uint glyphIndex)
  1704. {
  1705. int advance;
  1706. Error err = FT.FT_Get_PFR_Advance(Reference, glyphIndex, out advance);
  1707. if (err != Error.Ok)
  1708. throw new FreeTypeException(err);
  1709. return advance;
  1710. }
  1711. #endregion
  1712. #region Windows FNT Files
  1713. /// <summary>
  1714. /// Retrieve a Windows FNT font info header.
  1715. /// </summary>
  1716. /// <remarks>
  1717. /// This function only works with Windows FNT faces, returning an error otherwise.
  1718. /// </remarks>
  1719. /// <returns>The WinFNT header.</returns>
  1720. public Fnt.Header GetWinFntHeader()
  1721. {
  1722. IntPtr headerRef;
  1723. Error err = FT.FT_Get_WinFNT_Header(Reference, out headerRef);
  1724. if (err != Error.Ok)
  1725. throw new FreeTypeException(err);
  1726. return new Fnt.Header(headerRef);
  1727. }
  1728. #endregion
  1729. #region Font Formats
  1730. /// <summary>
  1731. /// Return a string describing the format of a given face, using values which can be used as an X11
  1732. /// FONT_PROPERTY. Possible values are ‘TrueType’, ‘Type 1’, ‘BDF’, ‘PCF’, ‘Type 42’, ‘CID Type 1’, ‘CFF’,
  1733. /// ‘PFR’, and ‘Windows FNT’.
  1734. /// </summary>
  1735. /// <returns>Font format string. NULL in case of error.</returns>
  1736. public string GetX11FontFormat()
  1737. {
  1738. return Marshal.PtrToStringAnsi(FT.FT_Get_X11_Font_Format(Reference));
  1739. }
  1740. #endregion
  1741. #region Gasp Table
  1742. /// <summary>
  1743. /// Read the ‘gasp’ table from a TrueType or OpenType font file and return the entry corresponding to a given
  1744. /// character pixel size.
  1745. /// </summary>
  1746. /// <param name="ppem">The vertical character pixel size.</param>
  1747. /// <returns>
  1748. /// Bit flags (see <see cref="Gasp"/>), or <see cref="Gasp.NoTable"/> if there is no ‘gasp’ table in the face.
  1749. /// </returns>
  1750. [CLSCompliant(false)]
  1751. public Gasp GetGasp(uint ppem)
  1752. {
  1753. return FT.FT_Get_Gasp(Reference, ppem);
  1754. }
  1755. #endregion
  1756. #region Quick retrieval of advance values
  1757. /// <summary>
  1758. /// Retrieve the advance value of a given glyph outline in a <see cref="Face"/>. By default, the unhinted
  1759. /// advance is returned in font units.
  1760. /// </summary>
  1761. /// <remarks><para>
  1762. /// This function may fail if you use <see cref="LoadFlags.AdvanceFlagFastOnly"/> and if the corresponding font
  1763. /// backend doesn't have a quick way to retrieve the advances.
  1764. /// </para><para>
  1765. /// A scaled advance is returned in 16.16 format but isn't transformed by the affine transformation specified
  1766. /// by <see cref="SetTransform"/>.
  1767. /// </para></remarks>
  1768. /// <param name="glyphIndex">The glyph index.</param>
  1769. /// <param name="flags">
  1770. /// A set of bit flags similar to those used when calling <see cref="LoadGlyph"/>, used to determine what kind
  1771. /// of advances you need.
  1772. /// </param>
  1773. /// <returns><para>
  1774. /// The advance value, in either font units or 16.16 format.
  1775. /// </para><para>
  1776. /// If <see cref="LoadFlags.VerticalLayout"/> is set, this is the vertical advance corresponding to a vertical
  1777. /// layout. Otherwise, it is the horizontal advance in a horizontal layout.
  1778. /// </para></returns>
  1779. [CLSCompliant(false)]
  1780. public int GetAdvance(uint glyphIndex, LoadFlags flags)
  1781. {
  1782. int padvance;
  1783. Error err = FT.FT_Get_Advance(Reference, glyphIndex, flags, out padvance);
  1784. if (err != Error.Ok)
  1785. throw new FreeTypeException(err);
  1786. return padvance;
  1787. }
  1788. /// <summary>
  1789. /// Retrieve the advance values of several glyph outlines in an
  1790. /// <see cref="Face"/>. By default, the unhinted advances are returned
  1791. /// in font units.
  1792. /// </summary>
  1793. /// <remarks><para>
  1794. /// This function may fail if you use
  1795. /// <see cref="LoadFlags.AdvanceFlagFastOnly"/> and if the
  1796. /// corresponding font backend doesn't have a quick way to retrieve the
  1797. /// advances.
  1798. /// </para><para>
  1799. /// Scaled advances are returned in 16.16 format but aren't transformed
  1800. /// by the affine transformation specified by
  1801. /// <see cref="SetTransform"/>.
  1802. /// </para></remarks>
  1803. /// <param name="start">The first glyph index.</param>
  1804. /// <param name="count">The number of advance values you want to retrieve.</param>
  1805. /// <param name="flags">A set of bit flags similar to those used when calling <see cref="LoadGlyph"/>.</param>
  1806. /// <returns><para>The advances, in either font units or 16.16 format. This array must contain at least ‘count’ elements.
  1807. /// </para><para>
  1808. /// If <see cref="LoadFlags.VerticalLayout"/> is set, these are the vertical advances corresponding to a vertical layout. Otherwise, they are the horizontal advances in a horizontal layout.</para></returns>
  1809. [CLSCompliant(false)]
  1810. public unsafe int[] GetAdvances(uint start, uint count, LoadFlags flags)
  1811. {
  1812. IntPtr advPtr;
  1813. Error err = FT.FT_Get_Advances(Reference, start, count, flags, out advPtr);
  1814. if (err != Error.Ok)
  1815. throw new FreeTypeException(err);
  1816. //create a new array and copy the data from the pointer over
  1817. int[] advances = new int[count];
  1818. int* ptr = (int*)advPtr;
  1819. for (int i = 0; i < count; i++)
  1820. advances[i] = ptr[i];
  1821. return advances;
  1822. }
  1823. #endregion
  1824. #region OpenType Validation
  1825. /// <summary>
  1826. /// Validate various OpenType tables to assure that all offsets and indices are valid. The idea is that a
  1827. /// higher-level library which actually does the text layout can access those tables without error checking
  1828. /// (which can be quite time consuming).
  1829. /// </summary>
  1830. /// <remarks><para>
  1831. /// This function only works with OpenType fonts, returning an error otherwise.
  1832. /// </para><para>
  1833. /// After use, the application should deallocate the five tables with <see cref="OpenTypeFree"/>. A NULL value
  1834. /// indicates that the table either doesn't exist in the font, or the application hasn't asked for validation.
  1835. /// </para></remarks>
  1836. /// <param name="flags">A bit field which specifies the tables to be validated.</param>
  1837. /// <param name="baseTable">A pointer to the BASE table.</param>
  1838. /// <param name="gdefTable">A pointer to the GDEF table.</param>
  1839. /// <param name="gposTable">A pointer to the GPOS table.</param>
  1840. /// <param name="gsubTable">A pointer to the GSUB table.</param>
  1841. /// <param name="jstfTable">A pointer to the JSTF table.</param>
  1842. [CLSCompliant(false)]
  1843. public void OpenTypeValidate(OpenTypeValidationFlags flags, out IntPtr baseTable, out IntPtr gdefTable, out IntPtr gposTable, out IntPtr gsubTable, out IntPtr jstfTable)
  1844. {
  1845. Error err = FT.FT_OpenType_Validate(Reference, flags, out baseTable, out gdefTable, out gposTable, out gsubTable, out jstfTable);
  1846. if (err != Error.Ok)
  1847. throw new FreeTypeException(err);
  1848. }
  1849. /// <summary>
  1850. /// Free the buffer allocated by OpenType validator.
  1851. /// </summary>
  1852. /// <remarks>
  1853. /// This function must be used to free the buffer allocated by <see cref="OpenTypeValidate"/> only.
  1854. /// </remarks>
  1855. /// <param name="table">The pointer to the buffer that is allocated by <see cref="OpenTypeValidate"/>.</param>
  1856. public void OpenTypeFree(IntPtr table)
  1857. {
  1858. FT.FT_OpenType_Free(Reference, table);
  1859. }
  1860. #endregion
  1861. #region TrueTypeGX/AAT Validation
  1862. /// <summary>
  1863. /// Validate various TrueTypeGX tables to assure that all offsets and indices are valid. The idea is that a
  1864. /// higher-level library which actually does the text layout can access those tables without error checking
  1865. /// (which can be quite time consuming).
  1866. /// </summary>
  1867. /// <remarks><para>
  1868. /// This function only works with TrueTypeGX fonts, returning an error otherwise.
  1869. /// </para><para>
  1870. /// After use, the application should deallocate the buffers pointed to by each ‘tables’ element, by calling
  1871. /// <see cref="TrueTypeGXFree"/>. A NULL value indicates that the table either doesn't exist in the font, the
  1872. /// application hasn't asked for validation, or the validator doesn't have the ability to validate the sfnt
  1873. /// table.
  1874. /// </para></remarks>
  1875. /// <param name="flags">A bit field which specifies the tables to be validated.</param>
  1876. /// <param name="tables">
  1877. /// The array where all validated sfnt tables are stored. The array itself must be allocated by a client.
  1878. /// </param>
  1879. /// <param name="tableLength">
  1880. /// The size of the ‘tables’ array. Normally, FT_VALIDATE_GX_LENGTH should be passed.
  1881. /// </param>
  1882. [CLSCompliant(false)]
  1883. public void TrueTypeGXValidate(TrueTypeValidationFlags flags, byte[][] tables, uint tableLength)
  1884. {
  1885. FT.FT_TrueTypeGX_Validate(Reference, flags, tables, tableLength);
  1886. }
  1887. /// <summary>
  1888. /// Free the buffer allocated by TrueTypeGX validator.
  1889. /// </summary>
  1890. /// <remarks>
  1891. /// This function must be used to free the buffer allocated by <see cref="TrueTypeGXValidate"/> only.
  1892. /// </remarks>
  1893. /// <param name="table">The pointer to the buffer allocated by <see cref="TrueTypeGXValidate"/>.</param>
  1894. public void TrueTypeGXFree(IntPtr table)
  1895. {
  1896. FT.FT_TrueTypeGX_Free(Reference, table);
  1897. }
  1898. /// <summary><para>
  1899. /// Validate classic (16-bit format) kern table to assure that the offsets and indices are valid. The idea is
  1900. /// that a higher-level library which actually does the text layout can access those tables without error
  1901. /// checking (which can be quite time consuming).
  1902. /// </para><para>
  1903. /// The ‘kern’ table validator in <see cref="TrueTypeGXValidate"/> deals with both the new 32-bit format and
  1904. /// the classic 16-bit format, while <see cref="ClassicKernValidate"/> only supports the classic 16-bit format.
  1905. /// </para></summary>
  1906. /// <remarks>
  1907. /// After use, the application should deallocate the buffers pointed to by ‘ckern_table’, by calling
  1908. /// <see cref="ClassicKernFree"/>. A NULL value indicates that the table doesn't exist in the font.
  1909. /// </remarks>
  1910. /// <param name="flags">A bit field which specifies the dialect to be validated.</param>
  1911. /// <returns>A pointer to the kern table.</returns>
  1912. [CLSCompliant(false)]
  1913. public IntPtr ClassicKernValidate(ClassicKernValidationFlags flags)
  1914. {
  1915. IntPtr ckernRef;
  1916. FT.FT_ClassicKern_Validate(Reference, flags, out ckernRef);
  1917. return ckernRef;
  1918. }
  1919. /// <summary>
  1920. /// Free the buffer allocated by classic Kern validator.
  1921. /// </summary>
  1922. /// <remarks>
  1923. /// This function must be used to free the buffer allocated by <see cref="ClassicKernValidate"/> only.
  1924. /// </remarks>
  1925. /// <param name="table">
  1926. /// The pointer to the buffer that is allocated by <see cref="ClassicKernValidate"/>.
  1927. /// </param>
  1928. public void ClassicKernFree(IntPtr table)
  1929. {
  1930. FT.FT_ClassicKern_Free(Reference, table);
  1931. }
  1932. #endregion
  1933. /// <summary>
  1934. /// Disposes the Face.
  1935. /// </summary>
  1936. public void Dispose()
  1937. {
  1938. Dispose(true);
  1939. GC.SuppressFinalize(this);
  1940. }
  1941. internal void AddChildSize(FTSize child)
  1942. {
  1943. childSizes.Add(child);
  1944. }
  1945. internal void RemoveChildSize(FTSize child)
  1946. {
  1947. childSizes.Remove(child);
  1948. }
  1949. private void Dispose(bool disposing)
  1950. {
  1951. if (!disposed)
  1952. {
  1953. disposed = true;
  1954. foreach (FTSize s in childSizes)
  1955. s.Dispose();
  1956. childSizes.Clear();
  1957. Error err = FT.FT_Done_Face(reference);
  1958. if (err != Error.Ok)
  1959. throw new FreeTypeException(err);
  1960. // removes itself from the parent Library, with a check to prevent this from happening when Library is
  1961. // being disposed (Library disposes all it's children with a foreach loop, this causes an
  1962. // InvalidOperationException for modifying a collection during enumeration)
  1963. if (!parentLibrary.IsDisposed)
  1964. parentLibrary.RemoveChildFace(this);
  1965. reference = IntPtr.Zero;
  1966. rec = null;
  1967. }
  1968. }
  1969. #endregion
  1970. }
  1971. }