Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 1 | # Configuring HarfBuzz |
| 2 | |
| 3 | Most of the time you will not need any custom configuration. The configuration |
Ebrahim Byagowi | 9fd48de | 2020-08-02 11:22:09 +0430 | [diff] [blame^] | 4 | options provided by `meson` should be enough. In particular, if you just want |
| 5 | HarfBuzz library plus hb-shape / hb-view utilities, make sure FreeType and Cairo |
| 6 | are available and found during configuration. |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 7 | |
| 8 | If you are building for distribution, you should more carefully consider whether |
| 9 | you need Glib, ICU, Graphite2, as well as CoreText / Uniscribe / DWrite. Make |
| 10 | sure the relevant ones are enabled. |
| 11 | |
| 12 | If you are building for custom environment (embedded, downloadable app, etc) |
| 13 | where you mostly just want to call `hb_shape()` and the binary size of the |
| 14 | resulting library is very important to you, the rest of this file guides you |
| 15 | through your options to disable features you may not need, in exchange for |
| 16 | binary size savings. |
| 17 | |
| 18 | ## Compiler Options |
| 19 | |
| 20 | Make sure you build with your compiler's "optimize for size" option. On `gcc` |
Ebrahim Byagowi | 9fd48de | 2020-08-02 11:22:09 +0430 | [diff] [blame^] | 21 | this is `-Os`, and can be enabled by passing `CXXFLAGS=-Os`. On clang there |
| 22 | is an even more extreme flag, `-Oz`. Meson also provides `--buildtype=minsize` |
| 23 | for more convenience. |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 24 | |
| 25 | HarfBuzz heavily uses inline functions and the optimize-size flag can make the |
| 26 | library smaller by 20% or more. Moreover, sometimes, based on the target CPU, |
| 27 | the optimize-size builds perform *faster* as well, thanks to lower code |
| 28 | footprint and caching effects. So, definitely try that even if size is not |
| 29 | extremely tight but you have a huge application. For example, Chrome does |
| 30 | that. Note that this configuration also automatically enables certain internal |
| 31 | optimizations. Search for `HB_OPTIMIZE_SIZE` for details, if you are using |
| 32 | other compilers, or continue reading. |
| 33 | |
| 34 | Another compiler option to consider is "link-time optimization", also known as |
Ebrahim Byagowi | 9fd48de | 2020-08-02 11:22:09 +0430 | [diff] [blame^] | 35 | 'lto'. To enable that, feel free to use `-Db_lto=true` of meson. |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 36 | This, also, can have a huge impact on the final size, 20% or more. |
| 37 | |
| 38 | Finally, if you are making a static library build or otherwise linking the |
| 39 | library into your app, make sure your linker removes unused functions. This |
| 40 | can be tricky and differ from environment to environment, but you definitely |
| 41 | want to make sure this happens. Otherwise, every unused public function will |
Behdad Esfahbod | 8d36ef5 | 2019-06-27 14:48:10 -0700 | [diff] [blame] | 42 | be adding unneeded bytes to your binary. The following pointers might come |
| 43 | handy: |
| 44 | |
| 45 | * https://lwn.net/Articles/741494/ (all of the four-part series) |
| 46 | * https://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 47 | |
| 48 | Combining the above three build options should already shrink your library a lot. |
| 49 | The rest of this file shows you ways to shrink the library even further at the |
Behdad Esfahbod | 33d8b76 | 2019-06-17 21:54:20 -0700 | [diff] [blame] | 50 | expense of removing functionality (that may not be needed). The remaining |
| 51 | options are all enabled by defining pre-processor macros, which can be done |
| 52 | via `CXXFLAGS` or `CPPFLAGS` similarly. |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 53 | |
Behdad Esfahbod | 3a93946 | 2019-06-17 20:10:36 -0700 | [diff] [blame] | 54 | |
Behdad Esfahbod | 33d8b76 | 2019-06-17 21:54:20 -0700 | [diff] [blame] | 55 | ## Unicode-functions |
| 56 | |
| 57 | Access to Unicode data can be configured at compile time as well as run-time. |
| 58 | By default, HarfBuzz ships with its own compact subset of properties from |
| 59 | Unicode Character Database that it needs. This is a highly-optimized |
| 60 | implementation that depending on compile settings (optimize-size or not) |
| 61 | takes around ~40kb or ~60kb. Using this implementation (default) is highly |
| 62 | recommended, as HarfBuzz always ships with data from latest version of Unicode. |
| 63 | This implementation can be disabled by defining `HB_NO_UCD`. |
| 64 | |
| 65 | For example, if you are enabling ICU as a built-in option, or GLib, those |
| 66 | can provide Unicode data as well, so defining `HB_NO_UCD` might save you |
| 67 | space without reducing functionality (to the extent that the Unicode version |
| 68 | of those implementations is recent.) |
| 69 | |
| 70 | If, however, you provide your own Unicode data to HarfBuzz at run-time by |
| 71 | calling `hb_buffer_set_unicode_funcs` on every buffer you create, and you do |
| 72 | not rely on `hb_unicode_funcs_get_default()` results, you can disable the |
| 73 | internal implementation by defining both `HB_NO_UCD` and `HB_NO_UNICODE_FUNCS`. |
| 74 | The latter is needed to guard against accidentally building a library without |
| 75 | any default Unicode implementations. |
| 76 | |
| 77 | |
| 78 | ## Font-functions |
| 79 | |
| 80 | Access to certain font functionalities can also be configured at run-time. By |
| 81 | default, HarfBuzz uses an efficient internal implementation of OpenType |
| 82 | functionality for this. This internal implementation is called `hb-ot-font`. |
| 83 | All newly-created `hb_font_t` objects by default use `hb-ot-font`. Using this |
| 84 | is highly recommended, and is what fonts use by default when they are created. |
| 85 | |
| 86 | Most embedded uses will probably use HarfBuzz with FreeType using `hb-ft.h`. |
| 87 | In that case, or if you otherwise provide those functions by calling |
| 88 | `hb_font_set_funcs()` on every font you create, you can disable `hb-ot-font` |
| 89 | without loss of functionality by defining `HB_NO_OT_FONT`. |
| 90 | |
| 91 | |
Behdad Esfahbod | 7aad536 | 2019-06-26 13:21:03 -0700 | [diff] [blame] | 92 | ## Shapers |
| 93 | |
| 94 | Most HarfBuzz clients use it for the main shaper, called "ot". However, it |
| 95 | is legitimate to want to compile HarfBuzz with only another backend, eg. |
Behdad Esfahbod | ab40a2f | 2019-06-26 13:25:02 -0700 | [diff] [blame] | 96 | CoreText, for example for an iOS app. For that, you want `HB_NO_OT_SHAPE`. |
| 97 | If you are going down that route, check if you want `HB_NO_OT`. |
Behdad Esfahbod | 7aad536 | 2019-06-26 13:21:03 -0700 | [diff] [blame] | 98 | |
| 99 | This is very rarely what you need. Make sure you understand exactly what you |
| 100 | are doing. |
| 101 | |
| 102 | Defining `HB_NO_FALLBACK_SHAPE` however is pretty harmless. That removes the |
| 103 | (unused) "fallback" shaper. |
| 104 | |
| 105 | |
Behdad Esfahbod | 33d8b76 | 2019-06-17 21:54:20 -0700 | [diff] [blame] | 106 | ## Thread-safety |
| 107 | |
| 108 | By default HarfBuzz builds as a thread-safe library. The exception is that |
| 109 | the `HB_TINY` predefined configuring (more below) disables thread-safety. |
| 110 | |
| 111 | If you do /not/ need thread-safety in the library (eg. you always call into |
| 112 | HarfBuzz from the same thread), you can disable thread-safety by defining |
| 113 | `HB_NO_MT`. As noted already, this is enabled by `HB_TINY`. |
| 114 | |
| 115 | |
| 116 | ## Pre-defined configurations |
| 117 | |
| 118 | The [`hb-config.hh`](src/hb-config.hh) internal header supports three |
| 119 | pre-defined configurations as well grouping of various configuration options. |
| 120 | The pre-defined configurations are: |
| 121 | |
| 122 | * `HB_MINI`: Disables shaping of AAT as well as legacy fonts. Ie. it produces |
| 123 | a capable OpenType shaper only. |
| 124 | |
Behdad Esfahbod | e9f7b33 | 2019-06-20 11:48:44 -0700 | [diff] [blame] | 125 | * `HB_LEAN`: Disables various non-shaping functionality in the library, as well |
| 126 | as esoteric or rarely-used shaping features. See the definition for details. |
Behdad Esfahbod | 33d8b76 | 2019-06-17 21:54:20 -0700 | [diff] [blame] | 127 | |
| 128 | * `HB_TINY`: Enables both `HB_MINI` and `HB_LEAN` configurations, as well as |
Behdad Esfahbod | ad97ec9 | 2019-06-21 00:44:29 -0700 | [diff] [blame] | 129 | disabling thread-safety and debugging, and use even more size-optimized data |
| 130 | tables. |
Behdad Esfahbod | 33d8b76 | 2019-06-17 21:54:20 -0700 | [diff] [blame] | 131 | |
| 132 | |
| 133 | ## Tailoring configuration |
| 134 | |
| 135 | Most of the time, one of the pre-defined configuration is exactly what one needs. |
| 136 | Sometimes, however, the pre-defined configuration cuts out features that might |
| 137 | be desired in the library. Unfortunately there is no quick way to undo those |
| 138 | configurations from the command-line. But one can add a header file called |
| 139 | `config-override.h` to undefine certain `HB_NO_*` symbols as desired. Then |
| 140 | define `HAVE_CONFIG_OVERRIDE_H` to make `hb-config.hh` include your configuration |
| 141 | overrides at the end. |
| 142 | |
| 143 | |
| 144 | ## Notes |
| 145 | |
| 146 | Note that the config option `HB_NO_CFF`, which is enabled by `HB_LEAN` and |
| 147 | `HB_TINY` does /not/ mean that the resulting library won't work with CFF fonts. |
| 148 | The library can shape valid CFF fonts just fine, with or without this option. |
| 149 | This option disables (among other things) the code to calculate glyph exntents |
| 150 | for CFF fonts. |