usermanual-fonts-and-faces.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <?xml version="1.0"?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
  4. <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
  5. <!ENTITY version SYSTEM "version.xml">
  6. ]>
  7. <chapter id="fonts-and-faces">
  8. <title>Fonts, faces, and output</title>
  9. <para>
  10. In the previous chapter, we saw how to set up a buffer and fill
  11. it with text as Unicode code points. In order to shape this
  12. buffer text with HarfBuzz, you will need also need a font
  13. object.
  14. </para>
  15. <para>
  16. HarfBuzz provides abstractions to help you cache and reuse the
  17. heavier parts of working with binary fonts, so we will look at
  18. how to do that. We will also look at how to work with the
  19. FreeType font-rendering library and at how you can customize
  20. HarfBuzz to work with other libraries.
  21. </para>
  22. <para>
  23. Finally, we will look at how to work with OpenType variable
  24. fonts, the latest update to the OpenType font format, and at
  25. some other recent additions to OpenType.
  26. </para>
  27. <section id="fonts-and-faces-objects">
  28. <title>Font and face objects</title>
  29. <para>
  30. The outcome of shaping a run of text depends on the contents of
  31. a specific font file (such as the substitutions and positioning
  32. moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes
  33. accessing those internals fast.
  34. </para>
  35. <para>
  36. An <type>hb_face_t</type> represents a <emphasis>face</emphasis>
  37. in HarfBuzz. This data type is a wrapper around an
  38. <type>hb_blob_t</type> blob that holds the contents of a binary
  39. font file. Since HarfBuzz supports TrueType Collections and
  40. OpenType Collections (each of which can include multiple
  41. typefaces), a HarfBuzz face also requires an index number
  42. specifying which typeface in the file you want to use. Most of
  43. the font files you will encounter in the wild include just a
  44. single face, however, so most of the time you would pass in
  45. <literal>0</literal> as the index when you create a face:
  46. </para>
  47. <programlisting language="C">
  48. hb_blob_t* blob = hb_blob_create_from_file(file);
  49. ...
  50. hb_face_t* face = hb_face_create(blob, 0);
  51. </programlisting>
  52. <para>
  53. On its own, a face object is not quite ready to use for
  54. shaping. The typeface must be set to a specific point size in
  55. order for some details (such as hinting) to work. In addition,
  56. if the font file in question is an OpenType Variable Font, then
  57. you may need to specify one or variation-axis settings (or a
  58. named instance) in order to get the output you need.
  59. </para>
  60. <para>
  61. In HarfBuzz, you do this by creating a <emphasis>font</emphasis>
  62. object from your face.
  63. </para>
  64. <para>
  65. Font objects also have the advantage of being considerably
  66. lighter-weight than face objects (remember that a face contains
  67. the contents of a binary font file mapped into memory). As a
  68. result, you can cache and reuse a font object, but you could
  69. also create a new one for each additional size you needed.
  70. Creating new fonts incurs some additional overhead, of course,
  71. but whether or not it is excessive is your call in the end. In
  72. contrast, face objects are substantially larger, and you really
  73. should cache them and reuse them whenever possible.
  74. </para>
  75. <para>
  76. You can create a font object from a face object:
  77. </para>
  78. <programlisting language="C">
  79. hb_font_t* hb_font = hb_font_create(hb_face);
  80. </programlisting>
  81. <para>
  82. After creating a font, there are a few properties you should
  83. set. Many fonts enable and disable hints based on the size it
  84. is used at, so setting this is important for font
  85. objects. <function>hb_font_set_ppem(font, x_ppem,
  86. y_ppem)</function> sets the pixels-per-EM value of the font. You
  87. can also set the point size of the font with
  88. <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
  89. industry standard 72 points per inch.
  90. </para>
  91. <para>
  92. HarfBuzz lets you specify the degree subpixel precision you want
  93. through a scaling factor. You can set horizontal and
  94. vertical scaling factors on the
  95. font by calling <function>hb_font_set_scale(font, x_scale,
  96. y_scale)</function>.
  97. </para>
  98. <para>
  99. There may be times when you are handed a font object and need to
  100. access the face object that it comes from. For that, you can call
  101. </para>
  102. <programlisting language="C">
  103. hb_face = hb_font_get_face(hb_font);
  104. </programlisting>
  105. <para>
  106. You can also create a font object from an existing font object
  107. using the <function>hb_font_create_sub_font()</function>
  108. function. This creates a child font object that is initiated
  109. with the same attributes as its parent; it can be used to
  110. quickly set up a new font for the purpose of overriding a specific
  111. font-functions method.
  112. </para>
  113. <para>
  114. All face objects and font objects are lifecycle-managed by
  115. HarfBuzz. After creating a face, you increase its reference
  116. count with <function>hb_face_reference(face)</function> and
  117. decrease it with
  118. <function>hb_face_destroy(face)</function>. Likewise, you
  119. increase the reference count on a font with
  120. <function>hb_font_reference(font)</function> and decrease it
  121. with <function>hb_font_destroy(font)</function>.
  122. </para>
  123. <para>
  124. You can also attach user data to face objects and font objects.
  125. </para>
  126. </section>
  127. <section id="fonts-and-faces-custom-functions">
  128. <title>Customizing font functions</title>
  129. <para>
  130. During shaping, HarfBuzz frequently needs to query font objects
  131. to get at the contents and parameters of the glyphs in a font
  132. file. It includes a built-in set of functions that is tailored
  133. to working with OpenType fonts. However, as was the case with
  134. Unicode functions in the buffers chapter, HarfBuzz also wants to
  135. make it easy for you to assign a substitute set of font
  136. functions if you are developing a program to work with a library
  137. or platform that provides its own font functions.
  138. </para>
  139. <para>
  140. Therefore, the HarfBuzz API defines a set of virtual
  141. methods for accessing font-object properties, and you can
  142. replace the defaults with your own selections without
  143. interfering with the shaping process. Each font object in
  144. HarfBuzz includes a structure called
  145. <literal>font_funcs</literal> that serves as a vtable for the
  146. font object. The virtual methods in
  147. <literal>font_funcs</literal> are:
  148. </para>
  149. <itemizedlist>
  150. <listitem>
  151. <para>
  152. <function>hb_font_get_font_h_extents_func_t</function>: returns
  153. the extents of the font for horizontal text.
  154. </para>
  155. </listitem>
  156. <listitem>
  157. <para>
  158. <function>hb_font_get_font_v_extents_func_t</function>: returns
  159. the extents of the font for vertical text.
  160. </para>
  161. </listitem>
  162. <listitem>
  163. <para>
  164. <function>hb_font_get_nominal_glyph_func_t</function>: returns
  165. the font's nominal glyph for a given code point.
  166. </para>
  167. </listitem>
  168. <listitem>
  169. <para>
  170. <function>hb_font_get_variation_glyph_func_t</function>: returns
  171. the font's glyph for a given code point when it is followed by a
  172. given Variation Selector.
  173. </para>
  174. </listitem>
  175. <listitem>
  176. <para>
  177. <function>hb_font_get_nominal_glyphs_func_t</function>: returns
  178. the font's nominal glyphs for a series of code points.
  179. </para>
  180. </listitem>
  181. <listitem>
  182. <para>
  183. <function>hb_font_get_glyph_advance_func_t</function>: returns
  184. the advance for a glyph.
  185. </para>
  186. </listitem>
  187. <listitem>
  188. <para>
  189. <function>hb_font_get_glyph_h_advance_func_t</function>: returns
  190. the advance for a glyph for horizontal text.
  191. </para>
  192. </listitem>
  193. <listitem>
  194. <para>
  195. <function>hb_font_get_glyph_v_advance_func_t</function>:returns
  196. the advance for a glyph for vertical text.
  197. </para>
  198. </listitem>
  199. <listitem>
  200. <para>
  201. <function>hb_font_get_glyph_advances_func_t</function>: returns
  202. the advances for a series of glyphs.
  203. </para>
  204. </listitem>
  205. <listitem>
  206. <para>
  207. <function>hb_font_get_glyph_h_advances_func_t</function>: returns
  208. the advances for a series of glyphs for horizontal text .
  209. </para>
  210. </listitem>
  211. <listitem>
  212. <para>
  213. <function>hb_font_get_glyph_v_advances_func_t</function>: returns
  214. the advances for a series of glyphs for vertical text.
  215. </para>
  216. </listitem>
  217. <listitem>
  218. <para>
  219. <function>hb_font_get_glyph_origin_func_t</function>: returns
  220. the origin coordinates of a glyph.
  221. </para>
  222. </listitem>
  223. <listitem>
  224. <para>
  225. <function>hb_font_get_glyph_h_origin_func_t</function>: returns
  226. the origin coordinates of a glyph for horizontal text.
  227. </para>
  228. </listitem>
  229. <listitem>
  230. <para>
  231. <function>hb_font_get_glyph_v_origin_func_t</function>: returns
  232. the origin coordinates of a glyph for vertical text.
  233. </para>
  234. </listitem>
  235. <listitem>
  236. <para>
  237. <function>hb_font_get_glyph_extents_func_t</function>: returns
  238. the extents for a glyph.
  239. </para>
  240. </listitem>
  241. <listitem>
  242. <para>
  243. <function>hb_font_get_glyph_contour_point_func_t</function>:
  244. returns the coordinates of a specific contour point from a glyph.
  245. </para>
  246. </listitem>
  247. <listitem>
  248. <para>
  249. <function>hb_font_get_glyph_name_func_t</function>: returns the
  250. name of a glyph (from its glyph index).
  251. </para>
  252. </listitem>
  253. <listitem>
  254. <para>
  255. <function>hb_font_get_glyph_from_name_func_t</function>: returns
  256. the glyph index that corresponds to a given glyph name.
  257. </para>
  258. </listitem>
  259. </itemizedlist>
  260. <para>
  261. You can create new font-functions by calling
  262. <function>hb_font_funcs_create()</function>:
  263. </para>
  264. <programlisting language="C">
  265. hb_font_funcs_t *ffunctions = hb_font_funcs_create ();
  266. hb_font_set_funcs (font, ffunctions, font_data, destroy);
  267. </programlisting>
  268. <para>
  269. The individual methods can each be set with their own setter
  270. function, such as
  271. <function>hb_font_funcs_set_nominal_glyph_func(ffunctions,
  272. func, user_data, destroy)</function>.
  273. </para>
  274. <para>
  275. Font-functions structures can be reused for multiple font
  276. objects, and can be reference counted with
  277. <function>hb_font_funcs_reference()</function> and
  278. <function>hb_font_funcs_destroy()</function>. Just like other
  279. objects in HarfBuzz, you can set user-data for each
  280. font-functions structure and assign a destroy callback for
  281. it.
  282. </para>
  283. <para>
  284. You can also mark a font-functions structure as immutable,
  285. with <function>hb_font_funcs_make_immutable()</function>. This
  286. is especially useful if your code is a library or framework that
  287. will have its own client programs. By marking your
  288. font-functions structures as immutable, you prevent your client
  289. programs from changing the configuration and introducing
  290. inconsistencies and errors downstream.
  291. </para>
  292. <para>
  293. To override only some functions while using the default implementation
  294. for the others, you will need to create a sub-font. By default, the
  295. sub-font uses the font functions of its parent except for the functions
  296. that were explicitly set. The following code will override only the
  297. <function>hb_font_get_nominal_glyph_func_t</function> for the sub-font:
  298. </para>
  299. <programlisting language="C">
  300. hb_font_t *subfont = hb_font_create_sub_font (font)
  301. hb_font_funcs_t *ffunctions = hb_font_funcs_create ();
  302. hb_font_funcs_set_nominal_glyph_func (ffunctions, func, user_data, destroy);
  303. hb_font_set_funcs (subfont, ffunctions, font_data, destroy);
  304. hb_font_funcs_destroy (ffunctions);
  305. </programlisting>
  306. </section>
  307. <section id="fonts-and-faces-native-opentype">
  308. <title>Font objects and HarfBuzz's native OpenType implementation</title>
  309. <para>
  310. By default, whenever HarfBuzz creates a font object, it will
  311. configure the font to use a built-in set of font functions that
  312. supports contemporary OpenType font internals. If you want to
  313. work with OpenType or TrueType fonts, you should be able to use
  314. these functions without difficulty.
  315. </para>
  316. <para>
  317. Many of the methods in the font-functions structure deal with
  318. the fundamental properties of glyphs that are required for
  319. shaping text: extents (the maximums and minimums on each axis),
  320. origins (the <literal>(0,0)</literal> coordinate point which
  321. glyphs are drawn in reference to), and advances (the amount that
  322. the cursor needs to be moved after drawing each glyph, including
  323. any empty space for the glyph's side bearings).
  324. </para>
  325. <para>
  326. As you can see in the list of functions, there are separate "horizontal"
  327. and "vertical" variants depending on whether the text is set in
  328. the horizontal or vertical direction. For some scripts, fonts
  329. that are designed to support text set horizontally or vertically (for
  330. example, in Japanese) may include metrics for both text
  331. directions. When fonts don't include this information, HarfBuzz
  332. does its best to transform what the font provides.
  333. </para>
  334. <para>
  335. In addition to the direction-specific functions, HarfBuzz
  336. provides some higher-level functions for fetching information
  337. like extents and advances for a glyph. If you call
  338. </para>
  339. <programlisting language="C">
  340. hb_font_get_glyph_advance_for_direction(font, direction, extents);
  341. </programlisting>
  342. <para>
  343. then you can provide any <type>hb_direction_t</type> as the
  344. <parameter>direction</parameter> parameter, and HarfBuzz will
  345. use the correct function variant for the text direction. There
  346. are similar higher-level versions of the functions for fetching
  347. extents, origin coordinates, and contour-point
  348. coordinates. There are also addition and subtraction functions
  349. for moving points with respect to the origin.
  350. </para>
  351. <para>
  352. There are also methods for fetching the glyph ID that
  353. corresponds to a Unicode code point (possibly when followed by a
  354. variation-selector code point), fetching the glyph name from the
  355. font, and fetching the glyph ID that corresponds to a glyph name
  356. you already have.
  357. </para>
  358. <para>
  359. HarfBuzz also provides functions for converting between glyph
  360. names and string
  361. variables. <function>hb_font_glyph_to_string(font, glyph, s,
  362. size)</function> retrieves the name for the glyph ID
  363. <parameter>glyph</parameter> from the font object. It generates a
  364. generic name of the form <literal>gidDDD</literal> (where DDD is
  365. the glyph index) if there is no name for the glyph in the
  366. font. The <function>hb_font_glyph_from_string(font, s, len,
  367. glyph)</function> takes an input string <parameter>s</parameter>
  368. and looks for a glyph with that name in the font, returning its
  369. glyph ID in the <parameter>glyph</parameter>
  370. output parameter. It automatically parses
  371. <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings.
  372. </para>
  373. </section>
  374. <!-- Commenting out FreeType integration section-holder for now. May move
  375. to the full-blown Integration Chapter. -->
  376. <!-- <section id="fonts-and-faces-freetype">
  377. <title>Using FreeType</title>
  378. <para>
  379. </para>
  380. <para>
  381. </para>
  382. </section> -->
  383. <section id="fonts-and-faces-variable">
  384. <title>Working with OpenType Variable Fonts</title>
  385. <para>
  386. If you are working with OpenType Variable Fonts, there are a few
  387. additional functions you should use to specify the
  388. variation-axis settings of your font object. Without doing so,
  389. your variable font's font object can still be used, but only at
  390. the default setting for every axis (which, of course, is
  391. sometimes what you want, but does not cover general usage).
  392. </para>
  393. <para>
  394. HarfBuzz manages variation settings in the
  395. <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the
  396. variation-axis identifier tag and a <property>value</property> for its
  397. setting. You can retrieve the list of variation axes in a font
  398. binary from the face object (not from a font object, notably) by
  399. calling <function>hb_ot_var_get_axis_count(face)</function> to
  400. find the number of axes, then using
  401. <function>hb_ot_var_get_axis_infos()</function> to collect the
  402. axis structures:
  403. </para>
  404. <programlisting language="C">
  405. axes = hb_ot_var_get_axis_count(face);
  406. ...
  407. hb_ot_var_get_axis_infos(face, 0, axes, axes_array);
  408. </programlisting>
  409. <para>
  410. For each axis returned in the array, you can can access the
  411. identifier in its <property>tag</property>. HarfBuzz also has
  412. tag definitions predefined for the five standard axes specified
  413. in OpenType (<literal>ital</literal> for italic,
  414. <literal>opsz</literal> for optical size,
  415. <literal>slnt</literal> for slant, <literal>wdth</literal> for
  416. width, and <literal>wght</literal> for weight). Each axis also
  417. has a <property>min_value</property>, a
  418. <property>default_value</property>, and a <property>max_value</property>.
  419. </para>
  420. <para>
  421. To set your font object's variation settings, you call the
  422. <function>hb_font_set_variations()</function> function with an
  423. array of <type>hb_variation_t</type> variation settings. Let's
  424. say our font has weight and width axes. We need to specify each
  425. of the axes by tag and assign a value on the axis:
  426. </para>
  427. <programlisting language="C">
  428. unsigned int variation_count = 2;
  429. hb_variation_t variation_data[variation_count];
  430. variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH;
  431. variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT;
  432. variation_data[0].value = 80;
  433. variation_data[1].value = 750;
  434. ...
  435. hb_font_set_variations(font, variation_data, variation_count);
  436. </programlisting>
  437. <para>
  438. That should give us a slightly condensed font ("normal" on the
  439. <literal>wdth</literal> axis is 100) at a noticeably bolder
  440. weight ("regular" is 400 on the <literal>wght</literal> axis).
  441. </para>
  442. <para>
  443. In practice, though, you should always check that the value you
  444. want to set on the axis is within the
  445. [<property>min_value</property>,<property>max_value</property>]
  446. range actually implemented in the font's variation axis. After
  447. all, a font might only provide lighter-than-regular weights, and
  448. setting a heavier value on the <literal>wght</literal> axis will
  449. not change that.
  450. </para>
  451. <para>
  452. Once your variation settings are specified on your font object,
  453. however, shaping with a variable font is just like shaping a
  454. static font.
  455. </para>
  456. </section>
  457. </chapter>