Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: src/autofit/aflatin.c

Issue 89753003: Update freetype to latest version of ASOP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src/third_party/freetype.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/autofit/aflatin.h ('k') | src/autofit/aflatin2.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* aflatin.c */ 3 /* aflatin.c */
4 /* */ 4 /* */
5 /* Auto-fitter hinting routines for latin script (body). */ 5 /* Auto-fitter hinting routines for latin script (body). */
6 /* */ 6 /* */
7 /* Copyright 2003-2011 by */ 7 /* Copyright 2003-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */ 9 /* */
10 /* This file is part of the FreeType project, and may only be used, */ 10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */ 11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */ 13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */ 14 /* understand and accept it fully. */
15 /* */ 15 /* */
16 /***************************************************************************/ 16 /***************************************************************************/
17 17
18 18
19 #include <ft2build.h> 19 #include <ft2build.h>
20 #include FT_ADVANCES_H 20 #include FT_ADVANCES_H
21 #include FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_DEBUG_H
22 22
23 #include "afglobal.h"
23 #include "aflatin.h" 24 #include "aflatin.h"
24 #include "aferrors.h" 25 #include "aferrors.h"
25 26
26 27
27 #ifdef AF_CONFIG_OPTION_USE_WARPER 28 #ifdef AF_CONFIG_OPTION_USE_WARPER
28 #include "afwarp.h" 29 #include "afwarp.h"
29 #endif 30 #endif
30 31
31 32
32 /*************************************************************************/ 33 /*************************************************************************/
(...skipping 13 matching lines...) Expand all
46 /***** *****/ 47 /***** *****/
47 /*************************************************************************/ 48 /*************************************************************************/
48 /*************************************************************************/ 49 /*************************************************************************/
49 50
50 51
51 /* Find segments and links, compute all stem widths, and initialize */ 52 /* Find segments and links, compute all stem widths, and initialize */
52 /* standard width and height for the glyph with given charcode. */ 53 /* standard width and height for the glyph with given charcode. */
53 54
54 FT_LOCAL_DEF( void ) 55 FT_LOCAL_DEF( void )
55 af_latin_metrics_init_widths( AF_LatinMetrics metrics, 56 af_latin_metrics_init_widths( AF_LatinMetrics metrics,
56 FT_Face face, 57 FT_Face face )
57 FT_ULong charcode )
58 { 58 {
59 /* scan the array of segments in each direction */ 59 /* scan the array of segments in each direction */
60 AF_GlyphHintsRec hints[1]; 60 AF_GlyphHintsRec hints[1];
61 61
62 62
63 FT_TRACE5(( "standard widths computation\n"
64 "===========================\n\n" ));
65
63 af_glyph_hints_init( hints, face->memory ); 66 af_glyph_hints_init( hints, face->memory );
64 67
65 metrics->axis[AF_DIMENSION_HORZ].width_count = 0; 68 metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
66 metrics->axis[AF_DIMENSION_VERT].width_count = 0; 69 metrics->axis[AF_DIMENSION_VERT].width_count = 0;
67 70
68 { 71 {
69 FT_Error error; 72 FT_Error error;
70 FT_UInt glyph_index; 73 FT_UInt glyph_index;
71 int dim; 74 int dim;
72 AF_LatinMetricsRec dummy[1]; 75 AF_LatinMetricsRec dummy[1];
73 AF_Scaler scaler = &dummy->root.scaler; 76 AF_Scaler scaler = &dummy->root.scaler;
74 77
75 78
76 glyph_index = FT_Get_Char_Index( face, charcode ); 79 glyph_index = FT_Get_Char_Index( face,
80 metrics->root.clazz->standard_char );
77 if ( glyph_index == 0 ) 81 if ( glyph_index == 0 )
78 goto Exit; 82 goto Exit;
79 83
84 FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n",
85 metrics->root.clazz->standard_char, glyph_index ));
86
80 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); 87 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
81 if ( error || face->glyph->outline.n_points <= 0 ) 88 if ( error || face->glyph->outline.n_points <= 0 )
82 goto Exit; 89 goto Exit;
83 90
84 FT_ZERO( dummy ); 91 FT_ZERO( dummy );
85 92
86 dummy->units_per_em = metrics->units_per_em; 93 dummy->units_per_em = metrics->units_per_em;
87 94
88 scaler->x_scale = 0x10000L; 95 scaler->x_scale = 0x10000L;
89 scaler->y_scale = 0x10000L; 96 scaler->y_scale = 0x10000L;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 138
132 dist = seg->pos - link->pos; 139 dist = seg->pos - link->pos;
133 if ( dist < 0 ) 140 if ( dist < 0 )
134 dist = -dist; 141 dist = -dist;
135 142
136 if ( num_widths < AF_LATIN_MAX_WIDTHS ) 143 if ( num_widths < AF_LATIN_MAX_WIDTHS )
137 axis->widths[num_widths++].org = dist; 144 axis->widths[num_widths++].org = dist;
138 } 145 }
139 } 146 }
140 147
141 af_sort_widths( num_widths, axis->widths ); 148 /* this also replaces multiple almost identical stem widths */
149 /* with a single one (the value 100 is heuristic) */
150 af_sort_and_quantize_widths( &num_widths, axis->widths,
151 dummy->units_per_em / 100 );
142 axis->width_count = num_widths; 152 axis->width_count = num_widths;
143 } 153 }
144 154
145 Exit: 155 Exit:
146 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) 156 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
147 { 157 {
148 AF_LatinAxis axis = &metrics->axis[dim]; 158 AF_LatinAxis axis = &metrics->axis[dim];
149 FT_Pos stdw; 159 FT_Pos stdw;
150 160
151 161
152 stdw = ( axis->width_count > 0 ) 162 stdw = ( axis->width_count > 0 )
153 ? axis->widths[0].org 163 ? axis->widths[0].org
154 : AF_LATIN_CONSTANT( metrics, 50 ); 164 : AF_LATIN_CONSTANT( metrics, 50 );
155 165
156 /* let's try 20% of the smallest width */ 166 /* let's try 20% of the smallest width */
157 axis->edge_distance_threshold = stdw / 5; 167 axis->edge_distance_threshold = stdw / 5;
158 axis->standard_width = stdw; 168 axis->standard_width = stdw;
159 axis->extra_light = 0; 169 axis->extra_light = 0;
170
171 #ifdef FT_DEBUG_LEVEL_TRACE
172 {
173 FT_UInt i;
174
175
176 FT_TRACE5(( "%s widths:\n",
177 dim == AF_DIMENSION_VERT ? "horizontal"
178 : "vertical" ));
179
180 FT_TRACE5(( " %d (standard)", axis->standard_width ));
181 for ( i = 1; i < axis->width_count; i++ )
182 FT_TRACE5(( " %d", axis->widths[i].org ));
183
184 FT_TRACE5(( "\n" ));
185 }
186 #endif
160 } 187 }
161 } 188 }
162 189
190 FT_TRACE5(( "\n" ));
191
163 af_glyph_hints_done( hints ); 192 af_glyph_hints_done( hints );
164 } 193 }
165 194
166 195
167 196
168 #define AF_LATIN_MAX_TEST_CHARACTERS 12 197 #define AF_LATIN_MAX_TEST_CHARACTERS 12
169 198
170 199
171 static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] 200 static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES]
172 [AF_LATIN_MAX_TEST_CHARACTERS + 1] = 201 [AF_LATIN_MAX_TEST_CHARACTERS + 1] =
(...skipping 15 matching lines...) Expand all
188 FT_Face face ) 217 FT_Face face )
189 { 218 {
190 FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; 219 FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS];
191 FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; 220 FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS];
192 FT_Int num_flats; 221 FT_Int num_flats;
193 FT_Int num_rounds; 222 FT_Int num_rounds;
194 FT_Int bb; 223 FT_Int bb;
195 AF_LatinBlue blue; 224 AF_LatinBlue blue;
196 FT_Error error; 225 FT_Error error;
197 AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; 226 AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
198 FT_GlyphSlot glyph = face->glyph; 227 FT_Outline outline;
199 228
200 229
201 /* we compute the blues simply by loading each character from the */ 230 /* we compute the blues simply by loading each character from the */
202 /* `af_latin_blue_chars[blues]' string, then finding its top-most or */ 231 /* `af_latin_blue_chars[blues]' string, then finding its top-most or */
203 /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ 232 /* bottom-most points (depending on `AF_IS_TOP_BLUE') */
204 233
205 FT_TRACE5(( "blue zones computation\n" )); 234 FT_TRACE5(( "blue zones computation\n"
206 FT_TRACE5(( "------------------------------------------------\n" )); 235 "======================\n\n" ));
207 236
208 for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) 237 for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
209 { 238 {
210 const char* p = af_latin_blue_chars[bb]; 239 const char* p = af_latin_blue_chars[bb];
211 const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; 240 const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS;
212 FT_Pos* blue_ref; 241 FT_Pos* blue_ref;
213 FT_Pos* blue_shoot; 242 FT_Pos* blue_shoot;
214 243
215 244
216 FT_TRACE5(( "blue %3d: ", bb )); 245 FT_TRACE5(( "blue zone %d:\n", bb ));
217 246
218 num_flats = 0; 247 num_flats = 0;
219 num_rounds = 0; 248 num_rounds = 0;
220 249
221 for ( ; p < limit && *p; p++ ) 250 for ( ; p < limit && *p; p++ )
222 { 251 {
223 FT_UInt glyph_index; 252 FT_UInt glyph_index;
224 FT_Pos best_y; /* same as points.y */ 253 FT_Pos best_y; /* same as points.y */
225 FT_Int best_point, best_first, best_last; 254 FT_Int best_point, best_contour_first, best_contour_last;
226 FT_Vector* points; 255 FT_Vector* points;
227 FT_Bool round = 0; 256 FT_Bool round = 0;
228 257
229 258
230 FT_TRACE5(( "'%c'", *p ));
231
232 /* load the character in the face -- skip unknown or empty ones */ 259 /* load the character in the face -- skip unknown or empty ones */
233 glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); 260 glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
234 if ( glyph_index == 0 ) 261 if ( glyph_index == 0 )
235 continue; 262 continue;
236 263
237 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); 264 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
238 if ( error || glyph->outline.n_points <= 0 ) 265 outline = face->glyph->outline;
266 if ( error || outline.n_points <= 0 )
239 continue; 267 continue;
240 268
241 /* now compute min or max point indices and coordinates */ 269 /* now compute min or max point indices and coordinates */
242 points = glyph->outline.points; 270 points = outline.points;
243 best_point = -1; 271 best_point = -1;
244 best_y = 0; /* make compiler happy */ 272 best_y = 0; /* make compiler happy */
245 best_first = 0; /* ditto */ 273 best_contour_first = 0; /* ditto */
246 best_last = 0; /* ditto */ 274 best_contour_last = 0; /* ditto */
247 275
248 { 276 {
249 FT_Int nn; 277 FT_Int nn;
250 FT_Int first = 0; 278 FT_Int first = 0;
251 FT_Int last = -1; 279 FT_Int last = -1;
252 280
253 281
254 for ( nn = 0; 282 for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
255 nn < glyph->outline.n_contours;
256 first = last + 1, nn++ )
257 { 283 {
258 FT_Int old_best_point = best_point; 284 FT_Int old_best_point = best_point;
259 FT_Int pp; 285 FT_Int pp;
260 286
261 287
262 last = glyph->outline.contours[nn]; 288 last = outline.contours[nn];
263 289
264 /* Avoid single-point contours since they are never rasterized. */ 290 /* Avoid single-point contours since they are never rasterized. */
265 /* In some fonts, they correspond to mark attachment points */ 291 /* In some fonts, they correspond to mark attachment points */
266 /* which are way outside of the glyph's real outline. */ 292 /* which are way outside of the glyph's real outline. */
267 if ( last <= first ) 293 if ( last <= first )
268 continue; 294 continue;
269 295
270 if ( AF_LATIN_IS_TOP_BLUE( bb ) ) 296 if ( AF_LATIN_IS_TOP_BLUE( bb ) )
271 { 297 {
272 for ( pp = first; pp <= last; pp++ ) 298 for ( pp = first; pp <= last; pp++ )
273 if ( best_point < 0 || points[pp].y > best_y ) 299 if ( best_point < 0 || points[pp].y > best_y )
274 { 300 {
275 best_point = pp; 301 best_point = pp;
276 best_y = points[pp].y; 302 best_y = points[pp].y;
277 } 303 }
278 } 304 }
279 else 305 else
280 { 306 {
281 for ( pp = first; pp <= last; pp++ ) 307 for ( pp = first; pp <= last; pp++ )
282 if ( best_point < 0 || points[pp].y < best_y ) 308 if ( best_point < 0 || points[pp].y < best_y )
283 { 309 {
284 best_point = pp; 310 best_point = pp;
285 best_y = points[pp].y; 311 best_y = points[pp].y;
286 } 312 }
287 } 313 }
288 314
289 if ( best_point != old_best_point ) 315 if ( best_point != old_best_point )
290 { 316 {
291 best_first = first; 317 best_contour_first = first;
292 best_last = last; 318 best_contour_last = last;
293 } 319 }
294 } 320 }
295 FT_TRACE5(( "%5d", best_y )); 321 FT_TRACE5(( " %c %ld", *p, best_y ));
296 } 322 }
297 323
298 /* now check whether the point belongs to a straight or round */ 324 /* now check whether the point belongs to a straight or round */
299 /* segment; we first need to find in which contour the extremum */ 325 /* segment; we first need to find in which contour the extremum */
300 /* lies, then inspect its previous and next points */ 326 /* lies, then inspect its previous and next points */
301 if ( best_point >= 0 ) 327 if ( best_point >= 0 )
302 { 328 {
329 FT_Pos best_x = points[best_point].x;
303 FT_Int prev, next; 330 FT_Int prev, next;
331 FT_Int best_on_point_first, best_on_point_last;
304 FT_Pos dist; 332 FT_Pos dist;
305 333
306 334
307 /* now look for the previous and next points that are not on the */ 335 if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON )
308 /* same Y coordinate. Threshold the `closeness'... */ 336 {
337 best_on_point_first = best_point;
338 best_on_point_last = best_point;
339 }
340 else
341 {
342 best_on_point_first = -1;
343 best_on_point_last = -1;
344 }
345
346 /* look for the previous and next points that are not on the */
347 /* same Y coordinate, then threshold the `closeness'... */
309 prev = best_point; 348 prev = best_point;
310 next = prev; 349 next = prev;
311 350
312 do 351 do
313 { 352 {
314 if ( prev > best_first ) 353 if ( prev > best_contour_first )
315 prev--; 354 prev--;
316 else 355 else
317 prev = best_last; 356 prev = best_contour_last;
318 357
319 dist = points[prev].y - best_y; 358 dist = FT_ABS( points[prev].y - best_y );
320 if ( dist < -5 || dist > 5 ) 359 /* accept a small distance or a small angle (both values are */
321 break; 360 /* heuristic; value 20 corresponds to approx. 2.9 degrees) */
361 if ( dist > 5 )
362 if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
363 break;
364
365 if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON )
366 {
367 best_on_point_first = prev;
368 if ( best_on_point_last < 0 )
369 best_on_point_last = prev;
370 }
322 371
323 } while ( prev != best_point ); 372 } while ( prev != best_point );
324 373
325 do 374 do
326 { 375 {
327 if ( next < best_last ) 376 if ( next < best_contour_last )
328 next++; 377 next++;
329 else 378 else
330 next = best_first; 379 next = best_contour_first;
331 380
332 dist = points[next].y - best_y; 381 dist = FT_ABS( points[next].y - best_y );
333 if ( dist < -5 || dist > 5 ) 382 if ( dist > 5 )
334 break; 383 if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
384 break;
385
386 if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON )
387 {
388 best_on_point_last = next;
389 if ( best_on_point_first < 0 )
390 best_on_point_first = next;
391 }
335 392
336 } while ( next != best_point ); 393 } while ( next != best_point );
337 394
338 /* now set the `round' flag depending on the segment's kind */ 395 /* now set the `round' flag depending on the segment's kind */
339 round = FT_BOOL( 396 /* (value 8 is heuristic) */
340 FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON || 397 if ( best_on_point_first >= 0 &&
341 FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON ); 398 best_on_point_last >= 0 &&
399 (FT_UInt)( FT_ABS( points[best_on_point_last].x -
400 points[best_on_point_first].x ) ) >
401 metrics->units_per_em / 8 )
402 round = 0;
403 else
404 round = FT_BOOL(
405 FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON ||
406 FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON );
342 407
343 FT_TRACE5(( "%c ", round ? 'r' : 'f' )); 408 FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
344 } 409 }
345 410
346 if ( round ) 411 if ( round )
347 rounds[num_rounds++] = best_y; 412 rounds[num_rounds++] = best_y;
348 else 413 else
349 flats[num_flats++] = best_y; 414 flats[num_flats++] = best_y;
350 } 415 }
351 416
352 FT_TRACE5(( "\n" ));
353
354 if ( num_flats == 0 && num_rounds == 0 ) 417 if ( num_flats == 0 && num_rounds == 0 )
355 { 418 {
356 /* 419 /*
357 * we couldn't find a single glyph to compute this blue zone, 420 * we couldn't find a single glyph to compute this blue zone,
358 * we will simply ignore it then 421 * we will simply ignore it then
359 */ 422 */
360 FT_TRACE5(( "empty\n" )); 423 FT_TRACE5(( " empty\n" ));
361 continue; 424 continue;
362 } 425 }
363 426
364 /* we have computed the contents of the `rounds' and `flats' tables, */ 427 /* we have computed the contents of the `rounds' and `flats' tables, */
365 /* now determine the reference and overshoot position of the blue -- */ 428 /* now determine the reference and overshoot position of the blue -- */
366 /* we simply take the median value after a simple sort */ 429 /* we simply take the median value after a simple sort */
367 af_sort_pos( num_rounds, rounds ); 430 af_sort_pos( num_rounds, rounds );
368 af_sort_pos( num_flats, flats ); 431 af_sort_pos( num_flats, flats );
369 432
370 blue = &axis->blues[axis->blue_count]; 433 blue = &axis->blues[axis->blue_count];
(...skipping 22 matching lines...) Expand all
393 /* zones is under its reference position, or the opposite for bottom */ 456 /* zones is under its reference position, or the opposite for bottom */
394 /* zones. We must thus check everything there and correct the errors */ 457 /* zones. We must thus check everything there and correct the errors */
395 if ( *blue_shoot != *blue_ref ) 458 if ( *blue_shoot != *blue_ref )
396 { 459 {
397 FT_Pos ref = *blue_ref; 460 FT_Pos ref = *blue_ref;
398 FT_Pos shoot = *blue_shoot; 461 FT_Pos shoot = *blue_shoot;
399 FT_Bool over_ref = FT_BOOL( shoot > ref ); 462 FT_Bool over_ref = FT_BOOL( shoot > ref );
400 463
401 464
402 if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) 465 if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
466 {
403 *blue_ref = 467 *blue_ref =
404 *blue_shoot = ( shoot + ref ) / 2; 468 *blue_shoot = ( shoot + ref ) / 2;
469
470 FT_TRACE5(( " [overshoot smaller than reference,"
471 " taking mean value]\n" ));
472 }
405 } 473 }
406 474
407 blue->flags = 0; 475 blue->flags = 0;
408 if ( AF_LATIN_IS_TOP_BLUE( bb ) ) 476 if ( AF_LATIN_IS_TOP_BLUE( bb ) )
409 blue->flags |= AF_LATIN_BLUE_TOP; 477 blue->flags |= AF_LATIN_BLUE_TOP;
410 478
411 /* 479 /*
412 * The following flag is used later to adjust the y and x scales 480 * The following flag is used later to adjust the y and x scales
413 * in order to optimize the pixel grid alignment of the top of small 481 * in order to optimize the pixel grid alignment of the top of small
414 * letters. 482 * letters.
415 */ 483 */
416 if ( bb == AF_LATIN_BLUE_SMALL_TOP ) 484 if ( bb == AF_LATIN_BLUE_SMALL_TOP )
417 blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; 485 blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
418 486
419 FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); 487 FT_TRACE5(( " -> reference = %ld\n"
488 " overshoot = %ld\n",
489 *blue_ref, *blue_shoot ));
420 } 490 }
421 491
422 FT_TRACE5(( "\n" )); 492 FT_TRACE5(( "\n" ));
423 493
424 return; 494 return;
425 } 495 }
426 496
427 497
428 /* Check whether all ASCII digits have the same advance width. */ 498 /* Check whether all ASCII digits have the same advance width. */
429 499
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 metrics->root.digits_have_same_width = same_width; 541 metrics->root.digits_have_same_width = same_width;
472 } 542 }
473 543
474 544
475 /* Initialize global metrics. */ 545 /* Initialize global metrics. */
476 546
477 FT_LOCAL_DEF( FT_Error ) 547 FT_LOCAL_DEF( FT_Error )
478 af_latin_metrics_init( AF_LatinMetrics metrics, 548 af_latin_metrics_init( AF_LatinMetrics metrics,
479 FT_Face face ) 549 FT_Face face )
480 { 550 {
481 FT_Error error = AF_Err_Ok;
482 FT_CharMap oldmap = face->charmap; 551 FT_CharMap oldmap = face->charmap;
483 FT_UInt ee;
484
485 static const FT_Encoding latin_encodings[] =
486 {
487 FT_ENCODING_UNICODE,
488 FT_ENCODING_APPLE_ROMAN,
489 FT_ENCODING_ADOBE_STANDARD,
490 FT_ENCODING_ADOBE_LATIN_1,
491
492 FT_ENCODING_NONE /* end of list */
493 };
494 552
495 553
496 metrics->units_per_em = face->units_per_EM; 554 metrics->units_per_em = face->units_per_EM;
497 555
498 /* do we have a latin charmap in there? */ 556 if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
499 for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )
500 { 557 {
501 error = FT_Select_Charmap( face, latin_encodings[ee] ); 558 af_latin_metrics_init_widths( metrics, face );
502 if ( !error )
503 break;
504 }
505
506 if ( !error )
507 {
508 /* For now, compute the standard width and height from the `o'. */
509 af_latin_metrics_init_widths( metrics, face, 'o' );
510 af_latin_metrics_init_blues( metrics, face ); 559 af_latin_metrics_init_blues( metrics, face );
511 af_latin_metrics_check_digits( metrics, face ); 560 af_latin_metrics_check_digits( metrics, face );
512 } 561 }
513 562
514 FT_Set_Charmap( face, oldmap ); 563 FT_Set_Charmap( face, oldmap );
515 return AF_Err_Ok; 564 return FT_Err_Ok;
516 } 565 }
517 566
518 567
519 /* Adjust scaling value, then scale and shift widths */ 568 /* Adjust scaling value, then scale and shift widths */
520 /* and blue zones (if applicable) for given dimension. */ 569 /* and blue zones (if applicable) for given dimension. */
521 570
522 static void 571 static void
523 af_latin_metrics_scale_dim( AF_LatinMetrics metrics, 572 af_latin_metrics_scale_dim( AF_LatinMetrics metrics,
524 AF_Scaler scaler, 573 AF_Scaler scaler,
525 AF_Dimension dim ) 574 AF_Dimension dim )
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 { 611 {
563 if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) 612 if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT )
564 { 613 {
565 blue = &Axis->blues[nn]; 614 blue = &Axis->blues[nn];
566 break; 615 break;
567 } 616 }
568 } 617 }
569 618
570 if ( blue ) 619 if ( blue )
571 { 620 {
572 FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); 621 FT_Pos scaled;
573 FT_Pos fitted = ( scaled + 40 ) & ~63; 622 FT_Pos threshold;
623 FT_Pos fitted;
624 FT_UInt limit;
625 FT_UInt ppem;
574 626
575 627
628 scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
629 ppem = metrics->root.scaler.face->size->metrics.x_ppem;
630 limit = metrics->root.globals->increase_x_height;
631 threshold = 40;
632
633 /* if the `increase-x-height' property is active, */
634 /* we round up much more often */
635 if ( limit &&
636 ppem <= limit &&
637 ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
638 threshold = 52;
639
640 fitted = ( scaled + threshold ) & ~63;
641
576 if ( scaled != fitted ) 642 if ( scaled != fitted )
577 { 643 {
578 #if 0 644 #if 0
579 if ( dim == AF_DIMENSION_HORZ ) 645 if ( dim == AF_DIMENSION_HORZ )
580 { 646 {
581 if ( fitted < scaled ) 647 if ( fitted < scaled )
582 scale -= scale / 50; /* scale *= 0.98 */ 648 scale -= scale / 50; /* scale *= 0.98 */
583 } 649 }
584 else 650 else
585 #endif 651 #endif
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 736
671 #else 737 #else
672 738
673 /* simplified version due to abs(dist) <= 48 */ 739 /* simplified version due to abs(dist) <= 48 */
674 delta2 = dist; 740 delta2 = dist;
675 if ( dist < 0 ) 741 if ( dist < 0 )
676 delta2 = -delta2; 742 delta2 = -delta2;
677 743
678 if ( delta2 < 32 ) 744 if ( delta2 < 32 )
679 delta2 = 0; 745 delta2 = 0;
680 else if ( delta < 48 ) 746 else if ( delta2 < 48 )
681 delta2 = 32; 747 delta2 = 32;
682 else 748 else
683 delta2 = 64; 749 delta2 = 64;
684 750
685 if ( dist < 0 ) 751 if ( dist < 0 )
686 delta2 = -delta2; 752 delta2 = -delta2;
687 753
688 blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); 754 blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
689 blue->shoot.fit = blue->ref.fit - delta2; 755 blue->shoot.fit = blue->ref.fit - delta2;
690 756
691 #endif 757 #endif
692 758
693 blue->flags |= AF_LATIN_BLUE_ACTIVE; 759 blue->flags |= AF_LATIN_BLUE_ACTIVE;
694 } 760 }
695 } 761 }
696 } 762 }
697 } 763 }
698 764
699 765
700 /* Scale global values in both directions. */ 766 /* Scale global values in both directions. */
701 767
702 FT_LOCAL_DEF( void ) 768 FT_LOCAL_DEF( void )
703 af_latin_metrics_scale( AF_LatinMetrics metrics, 769 af_latin_metrics_scale( AF_LatinMetrics metrics,
704 AF_Scaler scaler ) 770 AF_Scaler scaler )
705 { 771 {
706 metrics->root.scaler.render_mode = scaler->render_mode; 772 metrics->root.scaler.render_mode = scaler->render_mode;
707 metrics->root.scaler.face = scaler->face; 773 metrics->root.scaler.face = scaler->face;
774 metrics->root.scaler.flags = scaler->flags;
708 775
709 af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); 776 af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
710 af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); 777 af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
711 } 778 }
712 779
713 780
714 /*************************************************************************/ 781 /*************************************************************************/
715 /*************************************************************************/ 782 /*************************************************************************/
716 /***** *****/ 783 /***** *****/
717 /***** L A T I N G L Y P H A N A L Y S I S *****/ 784 /***** L A T I N G L Y P H A N A L Y S I S *****/
718 /***** *****/ 785 /***** *****/
719 /*************************************************************************/ 786 /*************************************************************************/
720 /*************************************************************************/ 787 /*************************************************************************/
721 788
722 789
723 /* Walk over all contours and compute its segments. */ 790 /* Walk over all contours and compute its segments. */
724 791
725 FT_LOCAL_DEF( FT_Error ) 792 FT_LOCAL_DEF( FT_Error )
726 af_latin_hints_compute_segments( AF_GlyphHints hints, 793 af_latin_hints_compute_segments( AF_GlyphHints hints,
727 AF_Dimension dim ) 794 AF_Dimension dim )
728 { 795 {
729 AF_AxisHints axis = &hints->axis[dim]; 796 AF_AxisHints axis = &hints->axis[dim];
730 FT_Memory memory = hints->memory; 797 FT_Memory memory = hints->memory;
731 FT_Error error = AF_Err_Ok; 798 FT_Error error = FT_Err_Ok;
732 AF_Segment segment = NULL; 799 AF_Segment segment = NULL;
733 AF_SegmentRec seg0; 800 AF_SegmentRec seg0;
734 AF_Point* contour = hints->contours; 801 AF_Point* contour = hints->contours;
735 AF_Point* contour_limit = contour + hints->num_contours; 802 AF_Point* contour_limit = contour + hints->num_contours;
736 AF_Direction major_dir, segment_dir; 803 AF_Direction major_dir, segment_dir;
737 804
738 805
739 FT_ZERO( &seg0 ); 806 FT_ZERO( &seg0 );
740 seg0.score = 32000; 807 seg0.score = 32000;
741 seg0.flags = AF_EDGE_NORMAL; 808 seg0.flags = AF_EDGE_NORMAL;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 if ( v > max_pos ) 908 if ( v > max_pos )
842 max_pos = v; 909 max_pos = v;
843 910
844 segment->min_coord = (FT_Short)min_pos; 911 segment->min_coord = (FT_Short)min_pos;
845 segment->max_coord = (FT_Short)max_pos; 912 segment->max_coord = (FT_Short)max_pos;
846 segment->height = (FT_Short)( segment->max_coord - 913 segment->height = (FT_Short)( segment->max_coord -
847 segment->min_coord ); 914 segment->min_coord );
848 915
849 on_edge = 0; 916 on_edge = 0;
850 segment = NULL; 917 segment = NULL;
851 /* fallthrough */ 918 /* fall through */
852 } 919 }
853 } 920 }
854 921
855 /* now exit if we are at the start/end point */ 922 /* now exit if we are at the start/end point */
856 if ( point == last ) 923 if ( point == last )
857 { 924 {
858 if ( passed ) 925 if ( passed )
859 break; 926 break;
860 passed = 1; 927 passed = 1;
861 } 928 }
(...skipping 15 matching lines...) Expand all
877 segment->last = point; 944 segment->last = point;
878 on_edge = 1; 945 on_edge = 1;
879 } 946 }
880 947
881 point = point->next; 948 point = point->next;
882 } 949 }
883 950
884 } /* contours */ 951 } /* contours */
885 952
886 953
887 /* now slightly increase the height of segments when this makes */ 954 /* now slightly increase the height of segments if this makes */
888 /* sense -- this is used to better detect and ignore serifs */ 955 /* sense -- this is used to better detect and ignore serifs */
889 { 956 {
890 AF_Segment segments = axis->segments; 957 AF_Segment segments = axis->segments;
891 AF_Segment segments_end = segments + axis->num_segments; 958 AF_Segment segments_end = segments + axis->num_segments;
892 959
893 960
894 for ( segment = segments; segment < segments_end; segment++ ) 961 for ( segment = segments; segment < segments_end; segment++ )
895 { 962 {
896 AF_Point first = segment->first; 963 AF_Point first = segment->first;
897 AF_Point last = segment->last; 964 AF_Point last = segment->last;
898 FT_Pos first_v = first->v; 965 FT_Pos first_v = first->v;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 } 1100 }
1034 1101
1035 1102
1036 /* Link segments to edges, using feature analysis for selection. */ 1103 /* Link segments to edges, using feature analysis for selection. */
1037 1104
1038 FT_LOCAL_DEF( FT_Error ) 1105 FT_LOCAL_DEF( FT_Error )
1039 af_latin_hints_compute_edges( AF_GlyphHints hints, 1106 af_latin_hints_compute_edges( AF_GlyphHints hints,
1040 AF_Dimension dim ) 1107 AF_Dimension dim )
1041 { 1108 {
1042 AF_AxisHints axis = &hints->axis[dim]; 1109 AF_AxisHints axis = &hints->axis[dim];
1043 FT_Error error = AF_Err_Ok; 1110 FT_Error error = FT_Err_Ok;
1044 FT_Memory memory = hints->memory; 1111 FT_Memory memory = hints->memory;
1045 AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; 1112 AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
1046 1113
1047 AF_Segment segments = axis->segments; 1114 AF_Segment segments = axis->segments;
1048 AF_Segment segment_limit = segments + axis->num_segments; 1115 AF_Segment segment_limit = segments + axis->num_segments;
1049 AF_Segment seg; 1116 AF_Segment seg;
1050 1117
1051 #if 0 1118 #if 0
1052 AF_Direction up_dir; 1119 AF_Direction up_dir;
1053 #endif 1120 #endif
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 { 1229 {
1163 /* if an edge was found, simply add the segment to the edge's */ 1230 /* if an edge was found, simply add the segment to the edge's */
1164 /* list */ 1231 /* list */
1165 seg->edge_next = found->first; 1232 seg->edge_next = found->first;
1166 found->last->edge_next = seg; 1233 found->last->edge_next = seg;
1167 found->last = seg; 1234 found->last = seg;
1168 } 1235 }
1169 } 1236 }
1170 1237
1171 1238
1172 /*********************************************************************/ 1239 /******************************************************************/
1173 /* */ 1240 /* */
1174 /* Good, we will now compute each edge's properties according to */ 1241 /* Good, we now compute each edge's properties according to the */
1175 /* the segments found on its position. Basically, these are */ 1242 /* segments found on its position. Basically, these are */
1176 /* */ 1243 /* */
1177 /* - the edge's main direction */ 1244 /* - the edge's main direction */
1178 /* - stem edge, serif edge or both (which defaults to stem then) */ 1245 /* - stem edge, serif edge or both (which defaults to stem then) */
1179 /* - rounded edge, straight or both (which defaults to straight) */ 1246 /* - rounded edge, straight or both (which defaults to straight) */
1180 /* - link for edge */ 1247 /* - link for edge */
1181 /* */ 1248 /* */
1182 /*********************************************************************/ 1249 /******************************************************************/
1183 1250
1184 /* first of all, set the `edge' field in each segment -- this is */ 1251 /* first of all, set the `edge' field in each segment -- this is */
1185 /* required in order to compute edge links */ 1252 /* required in order to compute edge links */
1186 1253
1187 /* 1254 /*
1188 * Note that removing this loop and setting the `edge' field of each 1255 * Note that removing this loop and setting the `edge' field of each
1189 * segment directly in the code above slows down execution speed for 1256 * segment directly in the code above slows down execution speed for
1190 * some reasons on platforms like the Sun. 1257 * some reasons on platforms like the Sun.
1191 */ 1258 */
1192 { 1259 {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; 1427 AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT];
1361 FT_Fixed scale = latin->scale; 1428 FT_Fixed scale = latin->scale;
1362 1429
1363 1430
1364 /* compute which blue zones are active, i.e. have their scaled */ 1431 /* compute which blue zones are active, i.e. have their scaled */
1365 /* size < 3/4 pixels */ 1432 /* size < 3/4 pixels */
1366 1433
1367 /* for each horizontal edge search the blue zone which is closest */ 1434 /* for each horizontal edge search the blue zone which is closest */
1368 for ( ; edge < edge_limit; edge++ ) 1435 for ( ; edge < edge_limit; edge++ )
1369 { 1436 {
1370 FT_Int bb; 1437 FT_UInt bb;
1371 AF_Width best_blue = NULL; 1438 AF_Width best_blue = NULL;
1372 FT_Pos best_dist; /* initial threshold */ 1439 FT_Pos best_dist; /* initial threshold */
1373 1440
1374 1441
1375 /* compute the initial threshold as a fraction of the EM size */ 1442 /* compute the initial threshold as a fraction of the EM size */
1376 /* (the value 40 is heuristic) */ 1443 /* (the value 40 is heuristic) */
1377 best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); 1444 best_dist = FT_MulFix( metrics->units_per_em / 40, scale );
1378 1445
1379 /* assure a minimum distance of 0.5px */ 1446 /* assure a minimum distance of 0.5px */
1380 if ( best_dist > 64 / 2 ) 1447 if ( best_dist > 64 / 2 )
1381 best_dist = 64 / 2; 1448 best_dist = 64 / 2;
1382 1449
1383 for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) 1450 for ( bb = 0; bb < latin->blue_count; bb++ )
1384 { 1451 {
1385 AF_LatinBlue blue = latin->blues + bb; 1452 AF_LatinBlue blue = latin->blues + bb;
1386 FT_Bool is_top_blue, is_major_dir; 1453 FT_Bool is_top_blue, is_major_dir;
1387 1454
1388 1455
1389 /* skip inactive blue zones (i.e., those that are too large) */ 1456 /* skip inactive blue zones (i.e., those that are too large) */
1390 if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) 1457 if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
1391 continue; 1458 continue;
1392 1459
1393 /* if it is a top zone, check for right edges -- if it is a bottom */ 1460 /* if it is a top zone, check for right edges -- if it is a bottom */
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; 1536 hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
1470 hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; 1537 hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
1471 hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; 1538 hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;
1472 hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; 1539 hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;
1473 1540
1474 /* compute flags depending on render mode, etc. */ 1541 /* compute flags depending on render mode, etc. */
1475 mode = metrics->root.scaler.render_mode; 1542 mode = metrics->root.scaler.render_mode;
1476 1543
1477 #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ 1544 #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
1478 if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) 1545 if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
1479 {
1480 metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; 1546 metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
1481 }
1482 #endif 1547 #endif
1483 1548
1484 scaler_flags = hints->scaler_flags; 1549 scaler_flags = hints->scaler_flags;
1485 other_flags = 0; 1550 other_flags = 0;
1486 1551
1487 /* 1552 /*
1488 * We snap the width of vertical stems for the monochrome and 1553 * We snap the width of vertical stems for the monochrome and
1489 * horizontal LCD rendering targets only. 1554 * horizontal LCD rendering targets only.
1490 */ 1555 */
1491 if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) 1556 if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
(...skipping 19 matching lines...) Expand all
1511 * In `light' hinting mode we disable horizontal hinting completely. 1576 * In `light' hinting mode we disable horizontal hinting completely.
1512 * We also do it if the face is italic. 1577 * We also do it if the face is italic.
1513 */ 1578 */
1514 if ( mode == FT_RENDER_MODE_LIGHT || 1579 if ( mode == FT_RENDER_MODE_LIGHT ||
1515 ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) 1580 ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
1516 scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; 1581 scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
1517 1582
1518 hints->scaler_flags = scaler_flags; 1583 hints->scaler_flags = scaler_flags;
1519 hints->other_flags = other_flags; 1584 hints->other_flags = other_flags;
1520 1585
1521 return AF_Err_Ok; 1586 return FT_Err_Ok;
1522 } 1587 }
1523 1588
1524 1589
1525 /*************************************************************************/ 1590 /*************************************************************************/
1526 /*************************************************************************/ 1591 /*************************************************************************/
1527 /***** *****/ 1592 /***** *****/
1528 /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ 1593 /***** L A T I N G L Y P H G R I D - F I T T I N G *****/
1529 /***** *****/ 1594 /***** *****/
1530 /*************************************************************************/ 1595 /*************************************************************************/
1531 /*************************************************************************/ 1596 /*************************************************************************/
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 /* vertical stems. */ 1780 /* vertical stems. */
1716 1781
1717 FT_Pos delta; 1782 FT_Pos delta;
1718 1783
1719 1784
1720 dist = ( dist + 22 ) & ~63; 1785 dist = ( dist + 22 ) & ~63;
1721 delta = dist - org_dist; 1786 delta = dist - org_dist;
1722 if ( delta < 0 ) 1787 if ( delta < 0 )
1723 delta = -delta; 1788 delta = -delta;
1724 1789
1725 if (delta >= 16) 1790 if ( delta >= 16 )
1726 { 1791 {
1727 dist = org_dist; 1792 dist = org_dist;
1728 if ( dist < 48 ) 1793 if ( dist < 48 )
1729 dist = ( dist + 64 ) >> 1; 1794 dist = ( dist + 64 ) >> 1;
1730 } 1795 }
1731 } 1796 }
1732 else 1797 else
1733 /* round otherwise to prevent color fringes in LCD mode */ 1798 /* round otherwise to prevent color fringes in LCD mode */
1734 dist = ( dist + 32 ) & ~63; 1799 dist = ( dist + 32 ) & ~63;
1735 } 1800 }
(...skipping 19 matching lines...) Expand all
1755 FT_Pos dist = stem_edge->opos - base_edge->opos; 1820 FT_Pos dist = stem_edge->opos - base_edge->opos;
1756 1821
1757 FT_Pos fitted_width = af_latin_compute_stem_width( 1822 FT_Pos fitted_width = af_latin_compute_stem_width(
1758 hints, dim, dist, 1823 hints, dim, dist,
1759 (AF_Edge_Flags)base_edge->flags, 1824 (AF_Edge_Flags)base_edge->flags,
1760 (AF_Edge_Flags)stem_edge->flags ); 1825 (AF_Edge_Flags)stem_edge->flags );
1761 1826
1762 1827
1763 stem_edge->pos = base_edge->pos + fitted_width; 1828 stem_edge->pos = base_edge->pos + fitted_width;
1764 1829
1765 FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to (%.2f)," 1830 FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to %.2f,"
1766 " dist was %.2f, now %.2f\n", 1831 " dist was %.2f, now %.2f\n",
1767 stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, 1832 stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
1768 stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); 1833 stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
1769 } 1834 }
1770 1835
1771 1836
1772 /* Shift the coordinates of the `serif' edge by the same amount */ 1837 /* Shift the coordinates of the `serif' edge by the same amount */
1773 /* as the corresponding `base' edge has been moved already. */ 1838 /* as the corresponding `base' edge has been moved already. */
1774 1839
1775 static void 1840 static void
(...skipping 25 matching lines...) Expand all
1801 AF_Dimension dim ) 1866 AF_Dimension dim )
1802 { 1867 {
1803 AF_AxisHints axis = &hints->axis[dim]; 1868 AF_AxisHints axis = &hints->axis[dim];
1804 AF_Edge edges = axis->edges; 1869 AF_Edge edges = axis->edges;
1805 AF_Edge edge_limit = edges + axis->num_edges; 1870 AF_Edge edge_limit = edges + axis->num_edges;
1806 FT_PtrDist n_edges; 1871 FT_PtrDist n_edges;
1807 AF_Edge edge; 1872 AF_Edge edge;
1808 AF_Edge anchor = NULL; 1873 AF_Edge anchor = NULL;
1809 FT_Int has_serifs = 0; 1874 FT_Int has_serifs = 0;
1810 1875
1876 #ifdef FT_DEBUG_LEVEL_TRACE
1877 FT_UInt num_actions = 0;
1878 #endif
1811 1879
1812 FT_TRACE5(("%s edge hinting\n", dim == AF_DIMENSION_VERT ? "horizontal" 1880
1813 : "vertical")); 1881 FT_TRACE5(( "%s edge hinting\n",
1882 dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" ));
1814 1883
1815 /* we begin by aligning all stems relative to the blue zone */ 1884 /* we begin by aligning all stems relative to the blue zone */
1816 /* if needed -- that's only for horizontal edges */ 1885 /* if needed -- that's only for horizontal edges */
1817 1886
1818 if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) 1887 if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )
1819 { 1888 {
1820 for ( edge = edges; edge < edge_limit; edge++ ) 1889 for ( edge = edges; edge < edge_limit; edge++ )
1821 { 1890 {
1822 AF_Width blue; 1891 AF_Width blue;
1823 AF_Edge edge1, edge2; /* these edges form the stem to check */ 1892 AF_Edge edge1, edge2; /* these edges form the stem to check */
(...skipping 13 matching lines...) Expand all
1837 else if ( edge2 && edge2->blue_edge ) 1906 else if ( edge2 && edge2->blue_edge )
1838 { 1907 {
1839 blue = edge2->blue_edge; 1908 blue = edge2->blue_edge;
1840 edge1 = edge2; 1909 edge1 = edge2;
1841 edge2 = edge; 1910 edge2 = edge;
1842 } 1911 }
1843 1912
1844 if ( !edge1 ) 1913 if ( !edge1 )
1845 continue; 1914 continue;
1846 1915
1847 FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to (%.2f)," 1916 #ifdef FT_DEBUG_LEVEL_TRACE
1848 " was (%.2f)\n", 1917 if ( !anchor )
1849 edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0, 1918 FT_TRACE5(( " BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f,"
1850 edge1->pos / 64.0 )); 1919 " was %.2f (anchor=edge %d)\n",
1920 edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
1921 edge1->pos / 64.0, edge - edges ));
1922 else
1923 FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to %.2f,"
1924 " was %.2f\n",
1925 edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
1926 edge1->pos / 64.0 ));
1927
1928 num_actions++;
1929 #endif
1851 1930
1852 edge1->pos = blue->fit; 1931 edge1->pos = blue->fit;
1853 edge1->flags |= AF_EDGE_DONE; 1932 edge1->flags |= AF_EDGE_DONE;
1854 1933
1855 if ( edge2 && !edge2->blue_edge ) 1934 if ( edge2 && !edge2->blue_edge )
1856 { 1935 {
1857 af_latin_align_linked_edge( hints, dim, edge1, edge2 ); 1936 af_latin_align_linked_edge( hints, dim, edge1, edge2 );
1858 edge2->flags |= AF_EDGE_DONE; 1937 edge2->flags |= AF_EDGE_DONE;
1938
1939 #ifdef FT_DEBUG_LEVEL_TRACE
1940 num_actions++;
1941 #endif
1859 } 1942 }
1860 1943
1861 if ( !anchor ) 1944 if ( !anchor )
1862 anchor = edge; 1945 anchor = edge;
1863 } 1946 }
1864 } 1947 }
1865 1948
1866 /* now we align all other stem edges, trying to maintain the */ 1949 /* now we align all other stem edges, trying to maintain the */
1867 /* relative order of stems in the glyph */ 1950 /* relative order of stems in the glyph */
1868 for ( edge = edges; edge < edge_limit; edge++ ) 1951 for ( edge = edges; edge < edge_limit; edge++ )
(...skipping 14 matching lines...) Expand all
1883 1966
1884 /* now align the stem */ 1967 /* now align the stem */
1885 1968
1886 /* this should not happen, but it's better to be safe */ 1969 /* this should not happen, but it's better to be safe */
1887 if ( edge2->blue_edge ) 1970 if ( edge2->blue_edge )
1888 { 1971 {
1889 FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); 1972 FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges ));
1890 1973
1891 af_latin_align_linked_edge( hints, dim, edge2, edge ); 1974 af_latin_align_linked_edge( hints, dim, edge2, edge );
1892 edge->flags |= AF_EDGE_DONE; 1975 edge->flags |= AF_EDGE_DONE;
1976
1977 #ifdef FT_DEBUG_LEVEL_TRACE
1978 num_actions++;
1979 #endif
1893 continue; 1980 continue;
1894 } 1981 }
1895 1982
1896 if ( !anchor ) 1983 if ( !anchor )
1897 { 1984 {
1898 /* if we reach this if clause, no stem has been aligned yet */ 1985 /* if we reach this if clause, no stem has been aligned yet */
1899 1986
1900 FT_Pos org_len, org_center, cur_len; 1987 FT_Pos org_len, org_center, cur_len;
1901 FT_Pos cur_pos1, error1, error2, u_off, d_off; 1988 FT_Pos cur_pos1, error1, error2, u_off, d_off;
1902 1989
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 cur_pos1 -= u_off; 2027 cur_pos1 -= u_off;
1941 else 2028 else
1942 cur_pos1 += d_off; 2029 cur_pos1 += d_off;
1943 2030
1944 edge->pos = cur_pos1 - cur_len / 2; 2031 edge->pos = cur_pos1 - cur_len / 2;
1945 edge2->pos = edge->pos + cur_len; 2032 edge2->pos = edge->pos + cur_len;
1946 } 2033 }
1947 else 2034 else
1948 edge->pos = FT_PIX_ROUND( edge->opos ); 2035 edge->pos = FT_PIX_ROUND( edge->opos );
1949 2036
2037 anchor = edge;
2038 edge->flags |= AF_EDGE_DONE;
2039
1950 FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)" 2040 FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
1951 " snapped to (%.2f) (%.2f)\n", 2041 " snapped to %.2f and %.2f\n",
1952 edge - edges, edge->opos / 64.0, 2042 edge - edges, edge->opos / 64.0,
1953 edge2 - edges, edge2->opos / 64.0, 2043 edge2 - edges, edge2->opos / 64.0,
1954 edge->pos / 64.0, edge2->pos / 64.0 )); 2044 edge->pos / 64.0, edge2->pos / 64.0 ));
1955 anchor = edge;
1956
1957 edge->flags |= AF_EDGE_DONE;
1958 2045
1959 af_latin_align_linked_edge( hints, dim, edge, edge2 ); 2046 af_latin_align_linked_edge( hints, dim, edge, edge2 );
2047
2048 #ifdef FT_DEBUG_LEVEL_TRACE
2049 num_actions += 2;
2050 #endif
1960 } 2051 }
1961 else 2052 else
1962 { 2053 {
1963 FT_Pos org_pos, org_len, org_center, cur_len; 2054 FT_Pos org_pos, org_len, org_center, cur_len;
1964 FT_Pos cur_pos1, cur_pos2, delta1, delta2; 2055 FT_Pos cur_pos1, cur_pos2, delta1, delta2;
1965 2056
1966 2057
1967 org_pos = anchor->pos + ( edge->opos - anchor->opos ); 2058 org_pos = anchor->pos + ( edge->opos - anchor->opos );
1968 org_len = edge2->opos - edge->opos; 2059 org_len = edge2->opos - edge->opos;
1969 org_center = org_pos + ( org_len >> 1 ); 2060 org_center = org_pos + ( org_len >> 1 );
(...skipping 12 matching lines...) Expand all
1982 edge->pos = edge2->pos - cur_len; 2073 edge->pos = edge2->pos - cur_len;
1983 } 2074 }
1984 2075
1985 else if ( cur_len < 96 ) 2076 else if ( cur_len < 96 )
1986 { 2077 {
1987 FT_Pos u_off, d_off; 2078 FT_Pos u_off, d_off;
1988 2079
1989 2080
1990 cur_pos1 = FT_PIX_ROUND( org_center ); 2081 cur_pos1 = FT_PIX_ROUND( org_center );
1991 2082
1992 if (cur_len <= 64 ) 2083 if ( cur_len <= 64 )
1993 { 2084 {
1994 u_off = 32; 2085 u_off = 32;
1995 d_off = 32; 2086 d_off = 32;
1996 } 2087 }
1997 else 2088 else
1998 { 2089 {
1999 u_off = 38; 2090 u_off = 38;
2000 d_off = 26; 2091 d_off = 26;
2001 } 2092 }
2002 2093
2003 delta1 = org_center - ( cur_pos1 - u_off ); 2094 delta1 = org_center - ( cur_pos1 - u_off );
2004 if ( delta1 < 0 ) 2095 if ( delta1 < 0 )
2005 delta1 = -delta1; 2096 delta1 = -delta1;
2006 2097
2007 delta2 = org_center - ( cur_pos1 + d_off ); 2098 delta2 = org_center - ( cur_pos1 + d_off );
2008 if ( delta2 < 0 ) 2099 if ( delta2 < 0 )
2009 delta2 = -delta2; 2100 delta2 = -delta2;
2010 2101
2011 if ( delta1 < delta2 ) 2102 if ( delta1 < delta2 )
2012 cur_pos1 -= u_off; 2103 cur_pos1 -= u_off;
2013 else 2104 else
2014 cur_pos1 += d_off; 2105 cur_pos1 += d_off;
2015 2106
2016 edge->pos = cur_pos1 - cur_len / 2; 2107 edge->pos = cur_pos1 - cur_len / 2;
2017 edge2->pos = cur_pos1 + cur_len / 2; 2108 edge2->pos = cur_pos1 + cur_len / 2;
2018 2109
2019 FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)" 2110 FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
2020 " snapped to (%.2f) and (%.2f)\n", 2111 " snapped to %.2f and %.2f\n",
2021 edge - edges, edge->opos / 64.0, 2112 edge - edges, edge->opos / 64.0,
2022 edge2 - edges, edge2->opos / 64.0, 2113 edge2 - edges, edge2->opos / 64.0,
2023 edge->pos / 64.0, edge2->pos / 64.0 )); 2114 edge->pos / 64.0, edge2->pos / 64.0 ));
2024 } 2115 }
2116
2025 else 2117 else
2026 { 2118 {
2027 org_pos = anchor->pos + ( edge->opos - anchor->opos ); 2119 org_pos = anchor->pos + ( edge->opos - anchor->opos );
2028 org_len = edge2->opos - edge->opos; 2120 org_len = edge2->opos - edge->opos;
2029 org_center = org_pos + ( org_len >> 1 ); 2121 org_center = org_pos + ( org_len >> 1 );
2030 2122
2031 cur_len = af_latin_compute_stem_width( 2123 cur_len = af_latin_compute_stem_width(
2032 hints, dim, org_len, 2124 hints, dim, org_len,
2033 (AF_Edge_Flags)edge->flags, 2125 (AF_Edge_Flags)edge->flags,
2034 (AF_Edge_Flags)edge2->flags ); 2126 (AF_Edge_Flags)edge2->flags );
2035 2127
2036 cur_pos1 = FT_PIX_ROUND( org_pos ); 2128 cur_pos1 = FT_PIX_ROUND( org_pos );
2037 delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; 2129 delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center;
2038 if ( delta1 < 0 ) 2130 if ( delta1 < 0 )
2039 delta1 = -delta1; 2131 delta1 = -delta1;
2040 2132
2041 cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; 2133 cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len;
2042 delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center; 2134 delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center;
2043 if ( delta2 < 0 ) 2135 if ( delta2 < 0 )
2044 delta2 = -delta2; 2136 delta2 = -delta2;
2045 2137
2046 edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; 2138 edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
2047 edge2->pos = edge->pos + cur_len; 2139 edge2->pos = edge->pos + cur_len;
2048 2140
2049 FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)" 2141 FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
2050 " snapped to (%.2f) and (%.2f)\n", 2142 " snapped to %.2f and %.2f\n",
2051 edge - edges, edge->opos / 64.0, 2143 edge - edges, edge->opos / 64.0,
2052 edge2 - edges, edge2->opos / 64.0, 2144 edge2 - edges, edge2->opos / 64.0,
2053 edge->pos / 64.0, edge2->pos / 64.0 )); 2145 edge->pos / 64.0, edge2->pos / 64.0 ));
2054 } 2146 }
2055 2147
2148 #ifdef FT_DEBUG_LEVEL_TRACE
2149 num_actions++;
2150 #endif
2151
2056 edge->flags |= AF_EDGE_DONE; 2152 edge->flags |= AF_EDGE_DONE;
2057 edge2->flags |= AF_EDGE_DONE; 2153 edge2->flags |= AF_EDGE_DONE;
2058 2154
2059 if ( edge > edges && edge->pos < edge[-1].pos ) 2155 if ( edge > edges && edge->pos < edge[-1].pos )
2060 { 2156 {
2061 FT_TRACE5(( " BOUND: %d (pos=%.2f) to (%.2f)\n", 2157 #ifdef FT_DEBUG_LEVEL_TRACE
2158 FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
2062 edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); 2159 edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
2160
2161 num_actions++;
2162 #endif
2163
2063 edge->pos = edge[-1].pos; 2164 edge->pos = edge[-1].pos;
2064 } 2165 }
2065 } 2166 }
2066 } 2167 }
2067 2168
2068 /* make sure that lowercase m's maintain their symmetry */ 2169 /* make sure that lowercase m's maintain their symmetry */
2069 2170
2070 /* In general, lowercase m's have six vertical edges if they are sans */ 2171 /* In general, lowercase m's have six vertical edges if they are sans */
2071 /* serif, or twelve if they are with serifs. This implementation is */ 2172 /* serif, or twelve if they are with serifs. This implementation is */
2072 /* based on that assumption, and seems to work very well with most */ 2173 /* based on that assumption, and seems to work very well with most */
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 { 2248 {
2148 delta = edge->serif->opos - edge->opos; 2249 delta = edge->serif->opos - edge->opos;
2149 if ( delta < 0 ) 2250 if ( delta < 0 )
2150 delta = -delta; 2251 delta = -delta;
2151 } 2252 }
2152 2253
2153 if ( delta < 64 + 16 ) 2254 if ( delta < 64 + 16 )
2154 { 2255 {
2155 af_latin_align_serif_edge( hints, edge->serif, edge ); 2256 af_latin_align_serif_edge( hints, edge->serif, edge );
2156 FT_TRACE5(( " SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)" 2257 FT_TRACE5(( " SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
2157 " aligned to (%.2f)\n", 2258 " aligned to %.2f\n",
2158 edge - edges, edge->opos / 64.0, 2259 edge - edges, edge->opos / 64.0,
2159 edge->serif - edges, edge->serif->opos / 64.0, 2260 edge->serif - edges, edge->serif->opos / 64.0,
2160 edge->pos / 64.0 )); 2261 edge->pos / 64.0 ));
2161 } 2262 }
2162 else if ( !anchor ) 2263 else if ( !anchor )
2163 { 2264 {
2164 edge->pos = FT_PIX_ROUND( edge->opos ); 2265 edge->pos = FT_PIX_ROUND( edge->opos );
2165 anchor = edge; 2266 anchor = edge;
2166 FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)" 2267 FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)"
2167 " snapped to (%.2f)\n", 2268 " snapped to %.2f\n",
2168 edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); 2269 edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
2169 } 2270 }
2170 else 2271 else
2171 { 2272 {
2172 AF_Edge before, after; 2273 AF_Edge before, after;
2173 2274
2174 2275
2175 for ( before = edge - 1; before >= edges; before-- ) 2276 for ( before = edge - 1; before >= edges; before-- )
2176 if ( before->flags & AF_EDGE_DONE ) 2277 if ( before->flags & AF_EDGE_DONE )
2177 break; 2278 break;
2178 2279
2179 for ( after = edge + 1; after < edge_limit; after++ ) 2280 for ( after = edge + 1; after < edge_limit; after++ )
2180 if ( after->flags & AF_EDGE_DONE ) 2281 if ( after->flags & AF_EDGE_DONE )
2181 break; 2282 break;
2182 2283
2183 if ( before >= edges && before < edge && 2284 if ( before >= edges && before < edge &&
2184 after < edge_limit && after > edge ) 2285 after < edge_limit && after > edge )
2185 { 2286 {
2186 if ( after->opos == before->opos ) 2287 if ( after->opos == before->opos )
2187 edge->pos = before->pos; 2288 edge->pos = before->pos;
2188 else 2289 else
2189 edge->pos = before->pos + 2290 edge->pos = before->pos +
2190 FT_MulDiv( edge->opos - before->opos, 2291 FT_MulDiv( edge->opos - before->opos,
2191 after->pos - before->pos, 2292 after->pos - before->pos,
2192 after->opos - before->opos ); 2293 after->opos - before->opos );
2193 2294
2194 FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)" 2295 FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f"
2195 " from %d (opos=%.2f)\n", 2296 " from %d (opos=%.2f)\n",
2196 edge - edges, edge->opos / 64.0, 2297 edge - edges, edge->opos / 64.0,
2197 edge->pos / 64.0, 2298 edge->pos / 64.0,
2198 before - edges, before->opos / 64.0 )); 2299 before - edges, before->opos / 64.0 ));
2199 } 2300 }
2200 else 2301 else
2201 { 2302 {
2202 edge->pos = anchor->pos + 2303 edge->pos = anchor->pos +
2203 ( ( edge->opos - anchor->opos + 16 ) & ~31 ); 2304 ( ( edge->opos - anchor->opos + 16 ) & ~31 );
2204
2205 FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)" 2305 FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)"
2206 " snapped to (%.2f)\n", 2306 " snapped to %.2f\n",
2207 edge - edges, edge->opos / 64.0, edge->pos / 64.0 )); 2307 edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
2208 } 2308 }
2209 } 2309 }
2210 2310
2311 #ifdef FT_DEBUG_LEVEL_TRACE
2312 num_actions++;
2313 #endif
2211 edge->flags |= AF_EDGE_DONE; 2314 edge->flags |= AF_EDGE_DONE;
2212 2315
2213 if ( edge > edges && edge->pos < edge[-1].pos ) 2316 if ( edge > edges && edge->pos < edge[-1].pos )
2317 {
2318 #ifdef FT_DEBUG_LEVEL_TRACE
2319 FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
2320 edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
2321
2322 num_actions++;
2323 #endif
2214 edge->pos = edge[-1].pos; 2324 edge->pos = edge[-1].pos;
2325 }
2215 2326
2216 if ( edge + 1 < edge_limit && 2327 if ( edge + 1 < edge_limit &&
2217 edge[1].flags & AF_EDGE_DONE && 2328 edge[1].flags & AF_EDGE_DONE &&
2218 edge->pos > edge[1].pos ) 2329 edge->pos > edge[1].pos )
2330 {
2331 #ifdef FT_DEBUG_LEVEL_TRACE
2332 FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
2333 edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 ));
2334
2335 num_actions++;
2336 #endif
2337
2219 edge->pos = edge[1].pos; 2338 edge->pos = edge[1].pos;
2339 }
2220 } 2340 }
2221 } 2341 }
2222 2342
2343 #ifdef FT_DEBUG_LEVEL_TRACE
2344 if ( !num_actions )
2345 FT_TRACE5(( " (none)\n" ));
2223 FT_TRACE5(( "\n" )); 2346 FT_TRACE5(( "\n" ));
2347 #endif
2224 } 2348 }
2225 2349
2226 2350
2227 /* Apply the complete hinting algorithm to a latin glyph. */ 2351 /* Apply the complete hinting algorithm to a latin glyph. */
2228 2352
2229 static FT_Error 2353 static FT_Error
2230 af_latin_hints_apply( AF_GlyphHints hints, 2354 af_latin_hints_apply( AF_GlyphHints hints,
2231 FT_Outline* outline, 2355 FT_Outline* outline,
2232 AF_LatinMetrics metrics ) 2356 AF_LatinMetrics metrics )
2233 { 2357 {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2326 AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Sup plement */ 2450 AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Sup plement */
2327 AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ 2451 AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */
2328 AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ 2452 AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */
2329 AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ 2453 AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */
2330 AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ 2454 AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */
2331 AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ 2455 AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */
2332 AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ 2456 AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */
2333 AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ 2457 AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */
2334 AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ 2458 AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */
2335 AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ 2459 AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */
2460 AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
2336 AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ 2461 AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */
2337 AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ 2462 AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */
2338 AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin L igs) */ 2463 AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin L igs) */
2339 AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbo ls */ 2464 AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbo ls */
2465 AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplemen t */
2340 AF_UNIRANGE_REC( 0UL, 0UL ) 2466 AF_UNIRANGE_REC( 0UL, 0UL )
2341 }; 2467 };
2342 2468
2343 2469
2344 AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, 2470 AF_DEFINE_SCRIPT_CLASS( af_latin_script_class,
2345 AF_SCRIPT_LATIN, 2471 AF_SCRIPT_LATIN,
2346 af_latin_uniranges, 2472 af_latin_uniranges,
2473 'o',
2347 2474
2348 sizeof ( AF_LatinMetricsRec ), 2475 sizeof ( AF_LatinMetricsRec ),
2349 2476
2350 (AF_Script_InitMetricsFunc) af_latin_metrics_init, 2477 (AF_Script_InitMetricsFunc) af_latin_metrics_init,
2351 (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, 2478 (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,
2352 (AF_Script_DoneMetricsFunc) NULL, 2479 (AF_Script_DoneMetricsFunc) NULL,
2353 2480
2354 (AF_Script_InitHintsFunc) af_latin_hints_init, 2481 (AF_Script_InitHintsFunc) af_latin_hints_init,
2355 (AF_Script_ApplyHintsFunc) af_latin_hints_apply 2482 (AF_Script_ApplyHintsFunc) af_latin_hints_apply
2356 ) 2483 )
2357 2484
2358 2485
2359 /* END */ 2486 /* END */
OLDNEW
« no previous file with comments | « src/autofit/aflatin.h ('k') | src/autofit/aflatin2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698