Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /***************************************************************************/ |
michael@0 | 2 | /* */ |
michael@0 | 3 | /* ftcffdrv.h */ |
michael@0 | 4 | /* */ |
michael@0 | 5 | /* FreeType API for controlling the CFF driver (specification only). */ |
michael@0 | 6 | /* */ |
michael@0 | 7 | /* Copyright 2013 by */ |
michael@0 | 8 | /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
michael@0 | 9 | /* */ |
michael@0 | 10 | /* This file is part of the FreeType project, and may only be used, */ |
michael@0 | 11 | /* modified, and distributed under the terms of the FreeType project */ |
michael@0 | 12 | /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
michael@0 | 13 | /* this file you indicate that you have read the license and */ |
michael@0 | 14 | /* understand and accept it fully. */ |
michael@0 | 15 | /* */ |
michael@0 | 16 | /***************************************************************************/ |
michael@0 | 17 | |
michael@0 | 18 | |
michael@0 | 19 | #ifndef __FTCFFDRV_H__ |
michael@0 | 20 | #define __FTCFFDRV_H__ |
michael@0 | 21 | |
michael@0 | 22 | #include <ft2build.h> |
michael@0 | 23 | #include FT_FREETYPE_H |
michael@0 | 24 | |
michael@0 | 25 | #ifdef FREETYPE_H |
michael@0 | 26 | #error "freetype.h of FreeType 1 has been loaded!" |
michael@0 | 27 | #error "Please fix the directory search order for header files" |
michael@0 | 28 | #error "so that freetype.h of FreeType 2 is found first." |
michael@0 | 29 | #endif |
michael@0 | 30 | |
michael@0 | 31 | |
michael@0 | 32 | FT_BEGIN_HEADER |
michael@0 | 33 | |
michael@0 | 34 | |
michael@0 | 35 | /************************************************************************** |
michael@0 | 36 | * |
michael@0 | 37 | * @section: |
michael@0 | 38 | * cff_driver |
michael@0 | 39 | * |
michael@0 | 40 | * @title: |
michael@0 | 41 | * The CFF driver |
michael@0 | 42 | * |
michael@0 | 43 | * @abstract: |
michael@0 | 44 | * Controlling the CFF driver module. |
michael@0 | 45 | * |
michael@0 | 46 | * @description: |
michael@0 | 47 | * While FreeType's CFF driver doesn't expose API functions by itself, |
michael@0 | 48 | * it is possible to control its behaviour with @FT_Property_Set and |
michael@0 | 49 | * @FT_Property_Get. The list below gives the available properties |
michael@0 | 50 | * together with the necessary macros and structures. |
michael@0 | 51 | * |
michael@0 | 52 | * The CFF driver's module name is `cff'. |
michael@0 | 53 | * |
michael@0 | 54 | * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* |
michael@0 | 55 | * |
michael@0 | 56 | * The rasterizer is positioning horizontal features (e.g., ascender |
michael@0 | 57 | * height & x-height, or crossbars) on the pixel grid and minimizing the |
michael@0 | 58 | * amount of antialiasing applied to them, while placing vertical |
michael@0 | 59 | * features (vertical stems) on the pixel grid without hinting, thus |
michael@0 | 60 | * representing the stem position and weight accurately. Sometimes the |
michael@0 | 61 | * vertical stems may be only partially black. In this context, |
michael@0 | 62 | * `antialiasing' means that stems are not positioned exactly on pixel |
michael@0 | 63 | * borders, causing a fuzzy appearance. |
michael@0 | 64 | * |
michael@0 | 65 | * There are two principles behind this approach. |
michael@0 | 66 | * |
michael@0 | 67 | * 1) No hinting in the horizontal direction: Unlike `superhinted' |
michael@0 | 68 | * TrueType, which changes glyph widths to accommodate regular |
michael@0 | 69 | * inter-glyph spacing, Adobe's approach is `faithful to the design' in |
michael@0 | 70 | * representing both the glyph width and the inter-glyph spacing |
michael@0 | 71 | * designed for the font. This makes the screen display as close as it |
michael@0 | 72 | * can be to the result one would get with infinite resolution, while |
michael@0 | 73 | * preserving what is considered the key characteristics of each glyph. |
michael@0 | 74 | * Note that the distances between unhinted and grid-fitted positions at |
michael@0 | 75 | * small sizes are comparable to kerning values and thus would be |
michael@0 | 76 | * noticeable (and distracting) while reading if hinting were applied. |
michael@0 | 77 | * |
michael@0 | 78 | * One of the reasons to not hint horizontally is antialiasing for LCD |
michael@0 | 79 | * screens: The pixel geometry of modern displays supplies three |
michael@0 | 80 | * vertical sub-pixels as the eye moves horizontally across each visible |
michael@0 | 81 | * pixel. On devices where we can be certain this characteristic is |
michael@0 | 82 | * present a rasterizer can take advantage of the sub-pixels to add |
michael@0 | 83 | * increments of weight. In Western writing systems this turns out to |
michael@0 | 84 | * be the more critical direction anyway; the weights and spacing of |
michael@0 | 85 | * vertical stems (see above) are central to Armenian, Cyrillic, Greek, |
michael@0 | 86 | * and Latin type designs. Even when the rasterizer uses greyscale |
michael@0 | 87 | * antialiasing instead of color (a necessary compromise when one |
michael@0 | 88 | * doesn't know the screen characteristics), the unhinted vertical |
michael@0 | 89 | * features preserve the design's weight and spacing much better than |
michael@0 | 90 | * aliased type would. |
michael@0 | 91 | * |
michael@0 | 92 | * 2) Aligment in the vertical direction: Weights and spacing along the |
michael@0 | 93 | * y~axis are less critical; what is much more important is the visual |
michael@0 | 94 | * alignment of related features (like cap-height and x-height). The |
michael@0 | 95 | * sense of alignment for these is enhanced by the sharpness of grid-fit |
michael@0 | 96 | * edges, while the cruder vertical resolution (full pixels instead of |
michael@0 | 97 | * 1/3 pixels) is less of a problem. |
michael@0 | 98 | * |
michael@0 | 99 | * On the technical side, horizontal alignment zones for ascender, |
michael@0 | 100 | * x-height, and other important height values (traditionally called |
michael@0 | 101 | * `blue zones') as defined in the font are positioned independently, |
michael@0 | 102 | * each being rounded to the nearest pixel edge, taking care of |
michael@0 | 103 | * overshoot suppression at small sizes, stem darkening, and scaling. |
michael@0 | 104 | * |
michael@0 | 105 | * Hstems (this is, hint values defined in the font to help align |
michael@0 | 106 | * horizontal features) that fall within a blue zone are said to be |
michael@0 | 107 | * `captured' and are aligned to that zone. Uncaptured stems are moved |
michael@0 | 108 | * in one of four ways, top edge up or down, bottom edge up or down. |
michael@0 | 109 | * Unless there are conflicting hstems, the smallest movement is taken |
michael@0 | 110 | * to minimize distortion. |
michael@0 | 111 | */ |
michael@0 | 112 | |
michael@0 | 113 | |
michael@0 | 114 | /************************************************************************** |
michael@0 | 115 | * |
michael@0 | 116 | * @property: |
michael@0 | 117 | * hinting-engine |
michael@0 | 118 | * |
michael@0 | 119 | * @description: |
michael@0 | 120 | * Thanks to Adobe, which contributed a new hinting (and parsing) |
michael@0 | 121 | * engine, an application can select between `freetype' and `adobe' if |
michael@0 | 122 | * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration |
michael@0 | 123 | * macro isn't defined, `hinting-engine' does nothing. |
michael@0 | 124 | * |
michael@0 | 125 | * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is |
michael@0 | 126 | * defined, and `adobe' otherwise. |
michael@0 | 127 | * |
michael@0 | 128 | * The following example code demonstrates how to select Adobe's hinting |
michael@0 | 129 | * engine (omitting the error handling). |
michael@0 | 130 | * |
michael@0 | 131 | * { |
michael@0 | 132 | * FT_Library library; |
michael@0 | 133 | * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; |
michael@0 | 134 | * |
michael@0 | 135 | * |
michael@0 | 136 | * FT_Init_FreeType( &library ); |
michael@0 | 137 | * |
michael@0 | 138 | * FT_Property_Set( library, "cff", |
michael@0 | 139 | * "hinting-engine", &hinting_engine ); |
michael@0 | 140 | * } |
michael@0 | 141 | * |
michael@0 | 142 | * @note: |
michael@0 | 143 | * This property can be used with @FT_Property_Get also. |
michael@0 | 144 | * |
michael@0 | 145 | */ |
michael@0 | 146 | |
michael@0 | 147 | |
michael@0 | 148 | /************************************************************************** |
michael@0 | 149 | * |
michael@0 | 150 | * @enum: |
michael@0 | 151 | * FT_CFF_HINTING_XXX |
michael@0 | 152 | * |
michael@0 | 153 | * @description: |
michael@0 | 154 | * A list of constants used for the @hinting-engine property to select |
michael@0 | 155 | * the hinting engine for CFF fonts. |
michael@0 | 156 | * |
michael@0 | 157 | * @values: |
michael@0 | 158 | * FT_CFF_HINTING_FREETYPE :: |
michael@0 | 159 | * Use the old FreeType hinting engine. |
michael@0 | 160 | * |
michael@0 | 161 | * FT_CFF_HINTING_ADOBE :: |
michael@0 | 162 | * Use the hinting engine contributed by Adobe. |
michael@0 | 163 | * |
michael@0 | 164 | */ |
michael@0 | 165 | #define FT_CFF_HINTING_FREETYPE 0 |
michael@0 | 166 | #define FT_CFF_HINTING_ADOBE 1 |
michael@0 | 167 | |
michael@0 | 168 | |
michael@0 | 169 | /************************************************************************** |
michael@0 | 170 | * |
michael@0 | 171 | * @property: |
michael@0 | 172 | * no-stem-darkening |
michael@0 | 173 | * |
michael@0 | 174 | * @description: |
michael@0 | 175 | * By default, the Adobe CFF engine darkens stems at smaller sizes, |
michael@0 | 176 | * regardless of hinting, to enhance contrast. This feature requires |
michael@0 | 177 | * a rendering system with proper gamma correction. Setting this |
michael@0 | 178 | * property, stem darkening gets switched off. |
michael@0 | 179 | * |
michael@0 | 180 | * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. |
michael@0 | 181 | * |
michael@0 | 182 | * { |
michael@0 | 183 | * FT_Library library; |
michael@0 | 184 | * FT_Bool no_stem_darkening = TRUE; |
michael@0 | 185 | * |
michael@0 | 186 | * |
michael@0 | 187 | * FT_Init_FreeType( &library ); |
michael@0 | 188 | * |
michael@0 | 189 | * FT_Property_Set( library, "cff", |
michael@0 | 190 | * "no-stem-darkening", &no_stem_darkening ); |
michael@0 | 191 | * } |
michael@0 | 192 | * |
michael@0 | 193 | * @note: |
michael@0 | 194 | * This property can be used with @FT_Property_Get also. |
michael@0 | 195 | * |
michael@0 | 196 | */ |
michael@0 | 197 | |
michael@0 | 198 | |
michael@0 | 199 | /************************************************************************** |
michael@0 | 200 | * |
michael@0 | 201 | * @property: |
michael@0 | 202 | * darkening-parameters |
michael@0 | 203 | * |
michael@0 | 204 | * @description: |
michael@0 | 205 | * By default, the Adobe CFF engine darkens stems as follows (if the |
michael@0 | 206 | * `no-stem-darkening' property isn't set): |
michael@0 | 207 | * |
michael@0 | 208 | * { |
michael@0 | 209 | * stem width <= 0.5px: darkening amount = 0.4px |
michael@0 | 210 | * stem width = 1px: darkening amount = 0.275px |
michael@0 | 211 | * stem width = 1.667px: darkening amount = 0.275px |
michael@0 | 212 | * stem width >= 2.333px: darkening amount = 0px |
michael@0 | 213 | * } |
michael@0 | 214 | * |
michael@0 | 215 | * and piecewise linear in-between. Using the `darkening-parameters' |
michael@0 | 216 | * property, these four control points can be changed, as the following |
michael@0 | 217 | * example demonstrates. |
michael@0 | 218 | * |
michael@0 | 219 | * { |
michael@0 | 220 | * FT_Library library; |
michael@0 | 221 | * FT_Int darken_params[8] = { 500, 300, // x1, y1 |
michael@0 | 222 | * 1000, 200, // x2, y2 |
michael@0 | 223 | * 1500, 100, // x3, y3 |
michael@0 | 224 | * 2000, 0 }; // x4, y4 |
michael@0 | 225 | * |
michael@0 | 226 | * |
michael@0 | 227 | * FT_Init_FreeType( &library ); |
michael@0 | 228 | * |
michael@0 | 229 | * FT_Property_Set( library, "cff", |
michael@0 | 230 | * "darkening-parameters", darken_params ); |
michael@0 | 231 | * } |
michael@0 | 232 | * |
michael@0 | 233 | * The x~values give the stem width, and the y~values the darkening |
michael@0 | 234 | * amount. The unit is 1000th of pixels. All coordinate values must be |
michael@0 | 235 | * positive; the x~values must be monotonically increasing; the |
michael@0 | 236 | * y~values must be monotonically decreasing and smaller than or |
michael@0 | 237 | * equal to 500 (corresponding to half a pixel); the slope of each |
michael@0 | 238 | * linear piece must be shallower than -1 (e.g., -.4). |
michael@0 | 239 | * |
michael@0 | 240 | * @note: |
michael@0 | 241 | * This property can be used with @FT_Property_Get also. |
michael@0 | 242 | * |
michael@0 | 243 | */ |
michael@0 | 244 | |
michael@0 | 245 | |
michael@0 | 246 | /* */ |
michael@0 | 247 | |
michael@0 | 248 | FT_END_HEADER |
michael@0 | 249 | |
michael@0 | 250 | |
michael@0 | 251 | #endif /* __FTCFFDRV_H__ */ |
michael@0 | 252 | |
michael@0 | 253 | |
michael@0 | 254 | /* END */ |