1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  ttsubpix.c                                                             */
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*    TrueType Subpixel Hinting.                                           */
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  Copyright 2010-2013 by                                                 */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  This file is part of the FreeType project, and may only be used,       */
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  modified, and distributed under the terms of the FreeType project      */
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  this file you indicate that you have read the license and              */
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  understand and accept it fully.                                        */
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h"
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h"
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/sfnt.h"
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/tttags.h"
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftoutln.h"
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftttdrv.h"
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttsubpix.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* These rules affect how the TT Interpreter does hinting, with the      */
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* goal of doing subpixel hinting by (in general) ignoring x moves.      */
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Some of these rules are fixes that go above and beyond the            */
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* stated techniques in the MS whitepaper on Cleartype, due to           */
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* artifacts in many glyphs.  So, these rules make some glyphs render    */
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* better than they do in the MS rasterizer.                             */
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* "" string or 0 int/char indicates to apply to all glyphs.             */
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* "-" used as dummy placeholders, but any non-matching string works.    */
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Some of this could arguably be implemented in fontconfig, however:    */
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  - Fontconfig can't set things on a glyph-by-glyph basis.             */
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  - The tweaks that happen here are very low-level, from an average    */
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    user's point of view and are best implemented in the hinter.       */
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The goal is to make the subpixel hinting techniques as generalized    */
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* as possible across all fonts to prevent the need for extra rules such */
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* as these.                                                             */
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The rule structure is designed so that entirely new rules can easily  */
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* be added when a new compatibility feature is discovered.              */
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The rule structures could also use some enhancement to handle ranges. */
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*     ****************** WORK IN PROGRESS *******************           */
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* These are `classes' of fonts that can be grouped together and used in */
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* rules below.  A blank entry "" is required at the end of these!       */
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FAMILY_CLASS_RULES_SIZE  7
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_Font_Class FAMILY_CLASS_Rules
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [FAMILY_CLASS_RULES_SIZE] =
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "MS Legacy Fonts",
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Aharoni",
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Andale Mono",
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Andalus",
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Angsana New",
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "AngsanaUPC",
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arabic Transparent",
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Black",
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Narrow",
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Unicode MS",
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial",
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Batang",
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Browallia New",
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "BrowalliaUPC",
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Comic Sans MS",
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Cordia New",
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CordiaUPC",
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Courier New",
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "DFKai-SB",
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "David Transparent",
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "David",
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "DilleniaUPC",
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Estrangelo Edessa",
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "EucrosiaUPC",
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "FangSong_GB2312",
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Fixed Miriam Transparent",
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "FrankRuehl",
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Franklin Gothic Medium",
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "FreesiaUPC",
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Garamond",
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Gautami",
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Georgia",
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Gulim",
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Impact",
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "IrisUPC",
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "JasmineUPC",
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "KaiTi_GB2312",
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "KodchiangUPC",
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Latha",
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Levenim MT",
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LilyUPC",
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Console",
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Sans Unicode",
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "MS Gothic",
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "MS Mincho",
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "MV Boli",
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Mangal",
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Marlett",
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Microsoft Sans Serif",
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Mingliu",
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Miriam Fixed",
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Miriam Transparent",
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Miriam",
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Narkisim",
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Palatino Linotype",
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Raavi",
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Rod Transparent",
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Rod",
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Shruti",
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "SimHei",
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Simplified Arabic Fixed",
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Simplified Arabic",
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Simsun",
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Sylfaen",
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Symbol",
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Tahoma",
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Times New Roman",
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Traditional Arabic",
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Trebuchet MS",
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Tunga",
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Verdana",
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Webdings",
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Wingdings",
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Core MS Legacy Fonts",
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Arial Black",
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Narrow",
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Unicode MS",
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial",
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Comic Sans MS",
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Courier New",
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Garamond",
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Georgia",
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Impact",
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Console",
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Sans Unicode",
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Microsoft Sans Serif",
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Palatino Linotype",
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Tahoma",
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Times New Roman",
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Trebuchet MS",
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Verdana",
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Apple Legacy Fonts",
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Geneva",
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Times",
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Monaco",
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Century",
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Chalkboard",
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lobster",
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Century Gothic",
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Optima",
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Grande",
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Gill Sans",
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Baskerville",
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Helvetica",
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Helvetica Neue",
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Legacy Sans Fonts",
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Andale Mono",
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial Unicode MS",
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Arial",
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Century Gothic",
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Comic Sans MS",
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Franklin Gothic Medium",
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Geneva",
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Console",
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Grande",
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Sans Unicode",
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Lucida Sans Typewriter",
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Microsoft Sans Serif",
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Monaco",
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Tahoma",
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Trebuchet MS",
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Verdana",
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Misc Legacy Fonts",
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Dark Courier", "", }, },
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana Clones",
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "DejaVu Sans",
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Bitstream Vera Sans", "", }, },
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones",
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "DejaVu Sans",
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Bitstream Vera Sans",
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Verdana", "", }, },
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Define this to force natural (i.e. not bitmap-compatible) widths.     */
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The default leans strongly towards natural widths except for a few    */
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* legacy fonts where a selective combination produces nicer results.    */
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* #define FORCE_NATURAL_WIDTHS   */
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Define `classes' of styles that can be grouped together and used in   */
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* rules below.  A blank entry "" is required at the end of these!       */
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define STYLE_CLASS_RULES_SIZE  5
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_Font_Class STYLE_CLASS_Rules
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [STYLE_CLASS_RULES_SIZE] =
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Regular Class",
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Regular",
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Book",
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Medium",
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Roman",
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Normal",
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Regular/Italic Class",
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Regular",
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Book",
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Medium",
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Italic",
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Oblique",
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Roman",
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Normal",
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bold/BoldItalic Class",
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Bold",
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Bold Italic",
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Black",
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bold/Italic/BoldItalic Class",
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Bold",
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Bold Italic",
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Black",
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Italic",
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Oblique",
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Regular/Bold Class",
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      { "Regular",
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Book",
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Medium",
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Normal",
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Roman",
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Bold",
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "Black",
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "",
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      },
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Force special legacy fixes for fonts.                                 */
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define COMPATIBILITY_MODE_RULES_SIZE  1
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  COMPATIBILITY_MODE_Rules
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [COMPATIBILITY_MODE_RULES_SIZE] =
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting.         */
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define PIXEL_HINTING_RULES_SIZE  2
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  PIXEL_HINTING_Rules
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [PIXEL_HINTING_RULES_SIZE] =
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* these characters are almost always safe */
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 12, "Italic", 'z' },
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 11, "Italic", 'z' },
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Subpixel hinting ignores SHPIX rules on X.  Force SHPIX for these.    */
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DO_SHPIX_RULES_SIZE  1
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  DO_SHPIX_Rules
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [DO_SHPIX_RULES_SIZE] =
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip Y moves that start with a point that is not on a Y pixel         */
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* boundary and don't move that point to a Y pixel boundary.             */
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE  4
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* fix vwxyz thinness*/
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Consolas", 0, "", 0 },
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Fix thin middle stems */
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Core MS Legacy Fonts", 0, "Regular", 0 },
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter I */
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Legacy Sans Fonts", 0, "", 0 },
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Fix artifacts with some Regular & Bold */
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana Clones", 0, "", 0 },
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Fixes < and > */
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Regular", 0 },
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip Y moves that start with a point that is not on a Y pixel         */
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* boundary and don't move that point to a Y pixel boundary.             */
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE  2
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Maintain thickness of diagonal in 'N' */
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular/Bold Class", 'N' },
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 0, "Regular/Bold Class", 'N' },
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip Y moves that move a point off a Y pixel boundary.                */
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE  1
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Round moves that don't move a point to a Y pixel boundary.            */
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE  2
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Droid font instructions don't snap Y to pixels */
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Droid Sans", 0, "Regular/Italic Class", 0 },
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Droid Sans Mono", 0, "", 0 },
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Allow a Direct_Move along X freedom vector if matched.                */
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ALLOW_X_DMOVE_RULES_SIZE  1
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  ALLOW_X_DMOVE_Rules
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [ALLOW_X_DMOVE_RULES_SIZE] =
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Fixes vanishing diagonal in 4 */
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 0, "Regular", '4' },
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Return MS rasterizer version 35 if matched.                           */
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RASTERIZER_35_RULES_SIZE  8
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  RASTERIZER_35_Rules
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [RASTERIZER_35_RULES_SIZE] =
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* This seems to be the only way to make these look good */
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'i' },
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'j' },
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'm' },
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'r' },
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'a' },
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'n' },
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 0, "Regular", 'p' },
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times", 0, "", 0 },
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Don't round to the subpixel grid.  Round to pixel grid.               */
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NORMAL_ROUND_RULES_SIZE  1
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  NORMAL_ROUND_Rules
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [NORMAL_ROUND_RULES_SIZE] =
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Fix serif thickness for certain ppems */
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Can probably be generalized somehow   */
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "", 0 },
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip IUP instructions if matched.                                     */
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SKIP_IUP_RULES_SIZE  1
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  SKIP_IUP_Rules
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [SKIP_IUP_RULES_SIZE] =
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 13, "Regular", 'a' },
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip MIAP Twilight hack if matched.                                   */
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MIAP_HACK_RULES_SIZE  1
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  MIAP_HACK_Rules
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [MIAP_HACK_RULES_SIZE] =
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Geneva", 12, "", 0 },
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Skip DELTAP instructions if matched.                                  */
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ALWAYS_SKIP_DELTAP_RULES_SIZE  23
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  ALWAYS_SKIP_DELTAP_Rules
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 0, "Regular", 'k' },
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* fix various problems with e in different versions */
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 14, "Regular", 'e' },
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 13, "Regular", 'e' },
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 15, "Regular", 'e' },
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 0, "Italic", 'v' },
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 0, "Italic", 'w' },
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 0, "Regular", 'Y' },
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 11, "Regular", 's' },
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* prevent problems with '3' and others */
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 10, "Regular", 0 },
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 9, "Regular", 0 },
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter short I */
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Legacy Sans Fonts", 0, "", 0x438 },
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Legacy Sans Fonts", 0, "", 0x439 },
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 10, "Regular", '6' },
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 0, "Bold/BoldItalic Class", 'a' },
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Make horizontal stems consistent with the rest */
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 24, "Bold", 'a' },
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 25, "Bold", 'a' },
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 24, "Bold", 's' },
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 25, "Bold", 's' },
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 34, "Bold", 's' },
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 35, "Bold", 's' },
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 36, "Bold", 's' },
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 25, "Regular", 's' },
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 26, "Regular", 's' },
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Always do DELTAP instructions if matched.                             */
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ALWAYS_DO_DELTAP_RULES_SIZE  1
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const SPH_TweakRule  ALWAYS_DO_DELTAP_Rules
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       [ALWAYS_DO_DELTAP_RULES_SIZE] =
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Don't allow ALIGNRP after IUP.                                        */
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE  1
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  NO_ALIGNRP_AFTER_IUP_Rules
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] =
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Prevent creation of dents in outline */
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Don't allow DELTAP after IUP.                                         */
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NO_DELTAP_AFTER_IUP_RULES_SIZE  1
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  NO_DELTAP_AFTER_IUP_Rules
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [NO_DELTAP_AFTER_IUP_RULES_SIZE] =
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Don't allow CALL after IUP.                                           */
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NO_CALL_AFTER_IUP_RULES_SIZE  1
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  NO_CALL_AFTER_IUP_Rules
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [NO_CALL_AFTER_IUP_RULES_SIZE] =
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Prevent creation of dents in outline */
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* De-embolden these glyphs slightly.                                    */
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DEEMBOLDEN_RULES_SIZE  9
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  DEEMBOLDEN_Rules
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [DEEMBOLDEN_RULES_SIZE] =
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'A' },
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'W' },
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'w' },
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'M' },
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'X' },
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'K' },
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'x' },
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'z' },
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Bold", 'v' },
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Embolden these glyphs slightly.                                       */
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define EMBOLDEN_RULES_SIZE  2
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  EMBOLDEN_Rules
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [EMBOLDEN_RULES_SIZE] =
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Regular", 0 },
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 0, "Italic", 0 },
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7       */
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* similar to Windows XP.                                                */
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TIMES_NEW_ROMAN_HACK_RULES_SIZE  12
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  TIMES_NEW_ROMAN_HACK_Rules
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [TIMES_NEW_ROMAN_HACK_RULES_SIZE] =
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Italic", '2' },
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Italic", '5' },
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Italic", '7' },
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular", '2' },
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular", '5' },
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular", '7' },
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Italic", '2' },
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Italic", '5' },
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Italic", '7' },
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Regular", '2' },
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Regular", '5' },
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 17, "Regular", '7' },
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* This fudges distance on 2 to get rid of the vanishing stem issue.     */
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* A real solution to this is certainly welcome.                         */
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define COURIER_NEW_2_HACK_RULES_SIZE  15
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  COURIER_NEW_2_HACK_Rules
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [COURIER_NEW_2_HACK_RULES_SIZE] =
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 10, "Regular", '2' },
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 11, "Regular", '2' },
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 12, "Regular", '2' },
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 13, "Regular", '2' },
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 14, "Regular", '2' },
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 15, "Regular", '2' },
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 16, "Regular", '2' },
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 17, "Regular", '2' },
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 18, "Regular", '2' },
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 19, "Regular", '2' },
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 20, "Regular", '2' },
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 21, "Regular", '2' },
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 22, "Regular", '2' },
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 23, "Regular", '2' },
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Courier New", 24, "Regular", '2' },
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FORCE_NATURAL_WIDTHS
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Use compatible widths with these glyphs.  Compatible widths is always */
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* on when doing B/W TrueType instructing, but is used selectively here, */
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* typically on glyphs with 3 or more vertical stems.                    */
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define COMPATIBLE_WIDTHS_RULES_SIZE  38
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  COMPATIBLE_WIDTHS_Rules
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [COMPATIBLE_WIDTHS_RULES_SIZE] =
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial Unicode MS", 12, "Regular Class", 'm' },
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial Unicode MS", 14, "Regular Class", 'm' },
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter sha */
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 10, "Regular Class", 0x448 },
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 11, "Regular Class", 'm' },
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 12, "Regular Class", 'm' },
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter sha */
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 12, "Regular Class", 0x448 },
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 13, "Regular Class", 0x448 },
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 14, "Regular Class", 'm' },
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter sha */
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 14, "Regular Class", 0x448 },
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 15, "Regular Class", 0x448 },
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 17, "Regular Class", 'm' },
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 15, "Regular Class", 0 },
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Microsoft Sans Serif", 11, "Regular Class", 0 },
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Microsoft Sans Serif", 12, "Regular Class", 0 },
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 11, "Regular Class", 0 },
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Monaco", 0, "Regular Class", 0 },
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 12, "Regular Class", 'm' },
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 14, "Regular Class", 'm' },
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Tahoma", 11, "Regular Class", 0 },
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular Class", 'c' },
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular Class", 'm' },
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular Class", 'o' },
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular Class", 'w' },
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 11, "Regular Class", 0 },
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 12, "Regular Class", 0 },
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 14, "Regular Class", 0 },
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 15, "Regular Class", 0 },
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Ubuntu", 12, "Regular Class", 'm' },
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter sha */
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 10, "Regular Class", 0x448 },
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 11, "Regular Class", 0x448 },
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 12, "Regular Class", 'i' },
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 12, "Regular Class", 'j' },
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 12, "Regular Class", 'l' },
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 12, "Regular Class", 'm' },
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 13, "Regular Class", 'i' },
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 13, "Regular Class", 'j' },
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 13, "Regular Class", 'l' },
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 14, "Regular Class", 'm' },
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* Scaling slightly in the x-direction prior to hinting results in       */
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* more visually pleasing glyphs in certain cases.                       */
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* This sometimes needs to be coordinated with compatible width rules.   */
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* A value of 1000 corresponds to a scaled value of 1.0.                 */
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define X_SCALING_RULES_SIZE  50
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_ScaleRule  X_SCALING_Rules[X_SCALING_RULES_SIZE] =
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 12, "Regular Class", 'm', 950 },
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 12, "Regular Class", 'a', 1100 },
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana and Clones", 13, "Regular Class", 'a', 1050 },
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 11, "Regular Class", 'm', 975 },
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 12, "Regular Class", 'm', 1050 },
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter el */
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 13, "Regular Class", 0x43B, 950 },
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 13, "Regular Class", 'o', 950 },
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 13, "Regular Class", 'e', 950 },
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 14, "Regular Class", 'm', 950 },
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Cyrillic small letter el */
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Arial", 15, "Regular Class", 0x43B, 925 },
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 },
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 },
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 },
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 },
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 12, "Regular Class", 'l', 975 },
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 12, "Regular Class", 'i', 975 },
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 12, "Regular Class", 'j', 975 },
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 13, "Regular Class", 'l', 950 },
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 13, "Regular Class", 'i', 950 },
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 13, "Regular Class", 'j', 950 },
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 },
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 },
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 10, "", 0, 1050 },
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 11, "", 0, 1100 },
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 12, "", 0, 1025 },
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 13, "", 0, 1050 },
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 16, "", 0, 1050 },
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Georgia", 17, "", 0, 1030 },
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Liberation Sans", 12, "Regular Class", 'm', 1100 },
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Lucida Grande", 11, "Regular Class", 'm', 1100 },
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 },
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 },
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 12, "Regular Class", 'H', 1050 },
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 12, "Regular Class", 'm', 1050 },
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Segoe UI", 14, "Regular Class", 'm', 1050 },
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Tahoma", 11, "Regular Class", 'i', 975 },
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Tahoma", 11, "Regular Class", 'l', 975 },
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Tahoma", 11, "Regular Class", 'j', 900 },
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Tahoma", 11, "Regular Class", 'm', 918 },
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 10, "Regular/Italic Class", 0, 1100 },
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 12, "Regular Class", 'm', 975 },
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 12, "Regular/Italic Class", 0, 1050 },
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 13, "Regular/Italic Class", 'i', 950 },
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 13, "Regular/Italic Class", 'j', 950 },
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 13, "Regular/Italic Class", 'l', 950 },
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 16, "Regular Class", 0, 1050 },
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Verdana", 9, "Regular/Italic Class", 0, 1050 },
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Times New Roman", 16, "Regular Class", 'm', 918 },
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 11, "Regular Class", 'm', 800 },
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Trebuchet MS", 12, "Regular Class", 'm', 800 },
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define COMPATIBLE_WIDTHS_RULES_SIZE  1
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_TweakRule  COMPATIBLE_WIDTHS_Rules
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [COMPATIBLE_WIDTHS_RULES_SIZE] =
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0 },
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define X_SCALING_RULES_SIZE  1
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const SPH_ScaleRule  X_SCALING_Rules
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              [X_SCALING_RULES_SIZE] =
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "-", 0, "", 0, 1000 },
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FORCE_NATURAL_WIDTHS */
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Bool )
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  is_member_of_family_class( const FT_String*  detected_font_name,
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             const FT_String*  rule_font_name )
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt  i, j;
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Does font name match rule family? */
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( strcmp( detected_font_name, rule_font_name ) == 0 )
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return TRUE;
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Is font name a wildcard ""? */
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( strcmp( rule_font_name, "" ) == 0 )
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return TRUE;
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Is font name contained in a class list? */
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ )
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 )
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ )
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 )
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( strcmp( FAMILY_CLASS_Rules[i].member[j],
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       detected_font_name ) == 0 )
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Bool )
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  is_member_of_style_class( const FT_String*  detected_font_style,
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            const FT_String*  rule_font_style )
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt  i, j;
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Does font style match rule style? */
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( strcmp( detected_font_style, rule_font_style ) == 0 )
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return TRUE;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Is font style a wildcard ""? */
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( strcmp( rule_font_style, "" ) == 0 )
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return TRUE;
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Is font style contained in a class list? */
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ )
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 )
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ )
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 )
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( strcmp( STYLE_CLASS_Rules[i].member[j],
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       detected_font_style ) == 0 )
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Bool )
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  sph_test_tweak( TT_Face               face,
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  const FT_String*      family,
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt               ppem,
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  const FT_String*      style,
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt               glyph_index,
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  const SPH_TweakRule*  rule,
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt               num_rules )
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt  i;
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* rule checks may be able to be optimized further */
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( i = 0; i < num_rules; i++ )
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( family                                                   &&
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           ( is_member_of_family_class ( family, rule[i].family ) ) )
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( rule[i].ppem == 0    ||
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             rule[i].ppem == ppem )
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( style                                             &&
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               is_member_of_style_class ( style, rule[i].style ) )
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ( rule[i].glyph == 0                                ||
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 FT_Get_Char_Index( (FT_Face)face,
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    rule[i].glyph ) == glyph_index )
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_UInt
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  scale_test_tweak( TT_Face               face,
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const FT_String*      family,
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_UInt               ppem,
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const FT_String*      style,
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_UInt               glyph_index,
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const SPH_ScaleRule*  rule,
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_UInt               num_rules )
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt  i;
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* rule checks may be able to be optimized further */
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( i = 0; i < num_rules; i++ )
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( family                                                   &&
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           ( is_member_of_family_class ( family, rule[i].family ) ) )
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( rule[i].ppem == 0    ||
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             rule[i].ppem == ppem )
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( style                                            &&
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               is_member_of_style_class( style, rule[i].style ) )
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ( rule[i].glyph == 0                                ||
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 FT_Get_Char_Index( (FT_Face)face,
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    rule[i].glyph ) == glyph_index )
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return rule[i].scale;
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 1000;
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_UInt )
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  sph_test_tweak_x_scaling( TT_Face           face,
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            const FT_String*  family,
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            FT_UInt           ppem,
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            const FT_String*  style,
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            FT_UInt           glyph_index )
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return scale_test_tweak( face, family, ppem, style, glyph_index,
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             X_SCALING_Rules, X_SCALING_RULES_SIZE );
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TWEAK_RULES( x )                                       \
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       x##_Rules, x##_RULES_SIZE ) )           \
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    loader->exec->sph_tweak_flags |= SPH_TWEAK_##x;
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TWEAK_RULES_EXCEPTIONS( x )                                        \
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if ( sph_test_tweak( face, family, ppem, style, glyph_index,             \
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x;
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( void )
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  sph_set_tweaks( TT_Loader  loader,
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt    glyph_index )
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TT_Face     face   = (TT_Face)loader->face;
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_String*  family = face->root.family_name;
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int         ppem   = loader->size->metrics.x_ppem;
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_String*  style  = face->root.style_name;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* don't apply rules if style isn't set */
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !face->root.style_name )
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return;
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef SPH_DEBUG_MORE_VERBOSE
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    printf( "%s,%d,%s,%c=%d ",
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            family, ppem, style, glyph_index, glyph_index );
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( PIXEL_HINTING );
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING )
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      loader->exec->ignore_x_mode = FALSE;
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return;
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( ALLOW_X_DMOVE );
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( ALWAYS_DO_DELTAP );
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( ALWAYS_SKIP_DELTAP );
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( DEEMBOLDEN );
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( DO_SHPIX );
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( EMBOLDEN );
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( MIAP_HACK );
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( NORMAL_ROUND );
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( NO_ALIGNRP_AFTER_IUP );
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( NO_CALL_AFTER_IUP );
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( NO_DELTAP_AFTER_IUP );
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( RASTERIZER_35 );
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( SKIP_IUP );
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES );
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES );
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP );
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES );
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES );
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES );
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES );
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->size->cvt_ready    = FALSE;
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        tt_size_ready_bytecode(
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          loader->exec->size,
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( loader->exec->rasterizer_version  !=
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           SPH_OPTION_SET_RASTERIZER_VERSION )
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->size->cvt_ready    = FALSE;
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        tt_size_ready_bytecode(
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          loader->exec->size,
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( IS_HINTED( loader->load_flags ) )
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      TWEAK_RULES( TIMES_NEW_ROMAN_HACK );
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      TWEAK_RULES( COURIER_NEW_2_HACK );
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( sph_test_tweak( face, family, ppem, style, glyph_index,
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) )
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      loader->exec->face->sph_compatibility_mode = TRUE;
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( IS_HINTED( loader->load_flags ) )
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( sph_test_tweak( face, family, ppem, style, glyph_index,
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) )
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        loader->exec->compatible_widths |= TRUE;
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* ANSI C doesn't like empty source files */
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef int  _tt_subpix_dummy;
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */
1012