ReactOS 0.4.15-dev-7907-g95bf896
aflatin.h File Reference
#include "afhints.h"
Include dependency graph for aflatin.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  AF_LatinBlueRec_
 
struct  AF_LatinAxisRec_
 
struct  AF_LatinMetricsRec_
 

Macros

#define AF_LATIN_CONSTANT(metrics, c)    ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
 
#define AF_LATIN_IS_TOP_BLUE(b)    ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP )
 
#define AF_LATIN_IS_SUB_TOP_BLUE(b)    ( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP )
 
#define AF_LATIN_IS_NEUTRAL_BLUE(b)    ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )
 
#define AF_LATIN_IS_X_HEIGHT_BLUE(b)    ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT )
 
#define AF_LATIN_IS_LONG_BLUE(b)    ( (b)->properties & AF_BLUE_PROPERTY_LATIN_LONG )
 
#define AF_LATIN_MAX_WIDTHS   16
 
#define AF_LATIN_BLUE_ACTIVE   ( 1U << 0 ) /* zone height is <= 3/4px */
 
#define AF_LATIN_BLUE_TOP   ( 1U << 1 ) /* we have a top blue zone */
 
#define AF_LATIN_BLUE_SUB_TOP   ( 1U << 2 ) /* we have a subscript top */
 
#define AF_LATIN_BLUE_NEUTRAL   ( 1U << 3 ) /* we have neutral blue zone */
 
#define AF_LATIN_BLUE_ADJUSTMENT   ( 1U << 4 ) /* used for scale adjustment */
 
#define AF_LATIN_HINTS_HORZ_SNAP   ( 1U << 0 ) /* stem width snapping */
 
#define AF_LATIN_HINTS_VERT_SNAP   ( 1U << 1 ) /* stem height snapping */
 
#define AF_LATIN_HINTS_STEM_ADJUST   ( 1U << 2 ) /* stem width/height */
 
#define AF_LATIN_HINTS_MONO   ( 1U << 3 ) /* monochrome rendering */
 
#define AF_LATIN_HINTS_DO_HORZ_SNAP(h)    AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )
 
#define AF_LATIN_HINTS_DO_VERT_SNAP(h)    AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )
 
#define AF_LATIN_HINTS_DO_STEM_ADJUST(h)    AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )
 
#define AF_LATIN_HINTS_DO_MONO(h)    AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )
 

Typedefs

typedef struct AF_LatinBlueRec_ AF_LatinBlueRec
 
typedef struct AF_LatinBlueRec_AF_LatinBlue
 
typedef struct AF_LatinAxisRec_ AF_LatinAxisRec
 
typedef struct AF_LatinAxisRec_AF_LatinAxis
 
typedef struct AF_LatinMetricsRec_ AF_LatinMetricsRec
 
typedef struct AF_LatinMetricsRec_AF_LatinMetrics
 

Functions

 af_latin_metrics_init (AF_LatinMetrics metrics, FT_Face face)
 
 af_latin_metrics_scale (AF_LatinMetrics metrics, AF_Scaler scaler)
 
 af_latin_metrics_init_widths (AF_LatinMetrics metrics, FT_Face face)
 
 af_latin_metrics_check_digits (AF_LatinMetrics metrics, FT_Face face)
 
 af_latin_hints_compute_segments (AF_GlyphHints hints, AF_Dimension dim)
 
 af_latin_hints_link_segments (AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
 
 af_latin_hints_compute_edges (AF_GlyphHints hints, AF_Dimension dim)
 
 af_latin_hints_detect_features (AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
 

Macro Definition Documentation

◆ AF_LATIN_BLUE_ACTIVE

#define AF_LATIN_BLUE_ACTIVE   ( 1U << 0 ) /* zone height is <= 3/4px */

Definition at line 68 of file aflatin.h.

◆ AF_LATIN_BLUE_ADJUSTMENT

#define AF_LATIN_BLUE_ADJUSTMENT   ( 1U << 4 ) /* used for scale adjustment */

Definition at line 73 of file aflatin.h.

◆ AF_LATIN_BLUE_NEUTRAL

#define AF_LATIN_BLUE_NEUTRAL   ( 1U << 3 ) /* we have neutral blue zone */

Definition at line 72 of file aflatin.h.

◆ AF_LATIN_BLUE_SUB_TOP

#define AF_LATIN_BLUE_SUB_TOP   ( 1U << 2 ) /* we have a subscript top */

Definition at line 70 of file aflatin.h.

◆ AF_LATIN_BLUE_TOP

#define AF_LATIN_BLUE_TOP   ( 1U << 1 ) /* we have a top blue zone */

Definition at line 69 of file aflatin.h.

◆ AF_LATIN_CONSTANT

#define AF_LATIN_CONSTANT (   metrics,
  c 
)     ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )

Definition at line 34 of file aflatin.h.

◆ AF_LATIN_HINTS_DO_HORZ_SNAP

#define AF_LATIN_HINTS_DO_HORZ_SNAP (   h)     AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )

Definition at line 150 of file aflatin.h.

◆ AF_LATIN_HINTS_DO_MONO

#define AF_LATIN_HINTS_DO_MONO (   h)     AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )

Definition at line 159 of file aflatin.h.

◆ AF_LATIN_HINTS_DO_STEM_ADJUST

#define AF_LATIN_HINTS_DO_STEM_ADJUST (   h)     AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )

Definition at line 156 of file aflatin.h.

◆ AF_LATIN_HINTS_DO_VERT_SNAP

#define AF_LATIN_HINTS_DO_VERT_SNAP (   h)     AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )

Definition at line 153 of file aflatin.h.

◆ AF_LATIN_HINTS_HORZ_SNAP

#define AF_LATIN_HINTS_HORZ_SNAP   ( 1U << 0 ) /* stem width snapping */

Definition at line 143 of file aflatin.h.

◆ AF_LATIN_HINTS_MONO

#define AF_LATIN_HINTS_MONO   ( 1U << 3 ) /* monochrome rendering */

Definition at line 147 of file aflatin.h.

◆ AF_LATIN_HINTS_STEM_ADJUST

#define AF_LATIN_HINTS_STEM_ADJUST   ( 1U << 2 ) /* stem width/height */

Definition at line 145 of file aflatin.h.

◆ AF_LATIN_HINTS_VERT_SNAP

#define AF_LATIN_HINTS_VERT_SNAP   ( 1U << 1 ) /* stem height snapping */

Definition at line 144 of file aflatin.h.

◆ AF_LATIN_IS_LONG_BLUE

#define AF_LATIN_IS_LONG_BLUE (   b)     ( (b)->properties & AF_BLUE_PROPERTY_LATIN_LONG )

Definition at line 62 of file aflatin.h.

◆ AF_LATIN_IS_NEUTRAL_BLUE

#define AF_LATIN_IS_NEUTRAL_BLUE (   b)     ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )

Definition at line 58 of file aflatin.h.

◆ AF_LATIN_IS_SUB_TOP_BLUE

#define AF_LATIN_IS_SUB_TOP_BLUE (   b)     ( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP )

Definition at line 56 of file aflatin.h.

◆ AF_LATIN_IS_TOP_BLUE

#define AF_LATIN_IS_TOP_BLUE (   b)     ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP )

Definition at line 54 of file aflatin.h.

◆ AF_LATIN_IS_X_HEIGHT_BLUE

#define AF_LATIN_IS_X_HEIGHT_BLUE (   b)     ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT )

Definition at line 60 of file aflatin.h.

◆ AF_LATIN_MAX_WIDTHS

#define AF_LATIN_MAX_WIDTHS   16

Definition at line 65 of file aflatin.h.

Typedef Documentation

◆ AF_LatinAxis

◆ AF_LatinAxisRec

◆ AF_LatinBlue

◆ AF_LatinBlueRec

◆ AF_LatinMetrics

◆ AF_LatinMetricsRec

Function Documentation

◆ af_latin_hints_compute_edges()

af_latin_hints_compute_edges ( AF_GlyphHints  hints,
AF_Dimension  dim 
)

Definition at line 2065 of file aflatin.c.

2067 {
2068 AF_AxisHints axis = &hints->axis[dim];
2070 FT_Memory memory = hints->memory;
2071 AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
2072
2073#ifdef FT_CONFIG_OPTION_PIC
2074 AF_FaceGlobals globals = hints->metrics->globals;
2075#endif
2076
2077 AF_StyleClass style_class = hints->metrics->style_class;
2079 [style_class->script];
2080
2081 FT_Bool top_to_bottom_hinting = 0;
2082
2083 AF_Segment segments = axis->segments;
2084 AF_Segment segment_limit = segments + axis->num_segments;
2085 AF_Segment seg;
2086
2087#if 0
2088 AF_Direction up_dir;
2089#endif
2091 FT_Pos edge_distance_threshold;
2092 FT_Pos segment_length_threshold;
2093 FT_Pos segment_width_threshold;
2094
2095
2096 axis->num_edges = 0;
2097
2098 scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
2099 : hints->y_scale;
2100
2101#if 0
2102 up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
2103 : AF_DIR_RIGHT;
2104#endif
2105
2106 if ( dim == AF_DIMENSION_VERT )
2107 top_to_bottom_hinting = script_class->top_to_bottom_hinting;
2108
2109 /*
2110 * We ignore all segments that are less than 1 pixel in length
2111 * to avoid many problems with serif fonts. We compute the
2112 * corresponding threshold in font units.
2113 */
2114 if ( dim == AF_DIMENSION_HORZ )
2115 segment_length_threshold = FT_DivFix( 64, hints->y_scale );
2116 else
2117 segment_length_threshold = 0;
2118
2119 /*
2120 * Similarly, we ignore segments that have a width delta
2121 * larger than 0.5px (i.e., a width larger than 1px).
2122 */
2123 segment_width_threshold = FT_DivFix( 32, scale );
2124
2125 /*********************************************************************/
2126 /* */
2127 /* We begin by generating a sorted table of edges for the current */
2128 /* direction. To do so, we simply scan each segment and try to find */
2129 /* an edge in our table that corresponds to its position. */
2130 /* */
2131 /* If no edge is found, we create and insert a new edge in the */
2132 /* sorted table. Otherwise, we simply add the segment to the edge's */
2133 /* list which gets processed in the second step to compute the */
2134 /* edge's properties. */
2135 /* */
2136 /* Note that the table of edges is sorted along the segment/edge */
2137 /* position. */
2138 /* */
2139 /*********************************************************************/
2140
2141 /* assure that edge distance threshold is at most 0.25px */
2142 edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
2143 scale );
2144 if ( edge_distance_threshold > 64 / 4 )
2145 edge_distance_threshold = 64 / 4;
2146
2147 edge_distance_threshold = FT_DivFix( edge_distance_threshold,
2148 scale );
2149
2150 for ( seg = segments; seg < segment_limit; seg++ )
2151 {
2152 AF_Edge found = NULL;
2153 FT_Int ee;
2154
2155
2156 /* ignore too short segments, too wide ones, and, in this loop, */
2157 /* one-point segments without a direction */
2158 if ( seg->height < segment_length_threshold ||
2159 seg->delta > segment_width_threshold ||
2160 seg->dir == AF_DIR_NONE )
2161 continue;
2162
2163 /* A special case for serif edges: If they are smaller than */
2164 /* 1.5 pixels we ignore them. */
2165 if ( seg->serif &&
2166 2 * seg->height < 3 * segment_length_threshold )
2167 continue;
2168
2169 /* look for an edge corresponding to the segment */
2170 for ( ee = 0; ee < axis->num_edges; ee++ )
2171 {
2172 AF_Edge edge = axis->edges + ee;
2173 FT_Pos dist;
2174
2175
2176 dist = seg->pos - edge->fpos;
2177 if ( dist < 0 )
2178 dist = -dist;
2179
2180 if ( dist < edge_distance_threshold && edge->dir == seg->dir )
2181 {
2182 found = edge;
2183 break;
2184 }
2185 }
2186
2187 if ( !found )
2188 {
2189 AF_Edge edge;
2190
2191
2192 /* insert a new edge in the list and */
2193 /* sort according to the position */
2194 error = af_axis_hints_new_edge( axis, seg->pos,
2195 (AF_Direction)seg->dir,
2196 top_to_bottom_hinting,
2197 memory, &edge );
2198 if ( error )
2199 goto Exit;
2200
2201 /* add the segment to the new edge's list */
2202 FT_ZERO( edge );
2203
2204 edge->first = seg;
2205 edge->last = seg;
2206 edge->dir = seg->dir;
2207 edge->fpos = seg->pos;
2208 edge->opos = FT_MulFix( seg->pos, scale );
2209 edge->pos = edge->opos;
2210 seg->edge_next = seg;
2211 }
2212 else
2213 {
2214 /* if an edge was found, simply add the segment to the edge's */
2215 /* list */
2216 seg->edge_next = found->first;
2217 found->last->edge_next = seg;
2218 found->last = seg;
2219 }
2220 }
2221
2222 /* we loop again over all segments to catch one-point segments */
2223 /* without a direction: if possible, link them to existing edges */
2224 for ( seg = segments; seg < segment_limit; seg++ )
2225 {
2226 AF_Edge found = NULL;
2227 FT_Int ee;
2228
2229
2230 if ( seg->dir != AF_DIR_NONE )
2231 continue;
2232
2233 /* look for an edge corresponding to the segment */
2234 for ( ee = 0; ee < axis->num_edges; ee++ )
2235 {
2236 AF_Edge edge = axis->edges + ee;
2237 FT_Pos dist;
2238
2239
2240 dist = seg->pos - edge->fpos;
2241 if ( dist < 0 )
2242 dist = -dist;
2243
2244 if ( dist < edge_distance_threshold )
2245 {
2246 found = edge;
2247 break;
2248 }
2249 }
2250
2251 /* one-point segments without a match are ignored */
2252 if ( found )
2253 {
2254 seg->edge_next = found->first;
2255 found->last->edge_next = seg;
2256 found->last = seg;
2257 }
2258 }
2259
2260
2261 /******************************************************************/
2262 /* */
2263 /* Good, we now compute each edge's properties according to the */
2264 /* segments found on its position. Basically, these are */
2265 /* */
2266 /* - the edge's main direction */
2267 /* - stem edge, serif edge or both (which defaults to stem then) */
2268 /* - rounded edge, straight or both (which defaults to straight) */
2269 /* - link for edge */
2270 /* */
2271 /******************************************************************/
2272
2273 /* first of all, set the `edge' field in each segment -- this is */
2274 /* required in order to compute edge links */
2275
2276 /*
2277 * Note that removing this loop and setting the `edge' field of each
2278 * segment directly in the code above slows down execution speed for
2279 * some reasons on platforms like the Sun.
2280 */
2281 {
2282 AF_Edge edges = axis->edges;
2283 AF_Edge edge_limit = edges + axis->num_edges;
2284 AF_Edge edge;
2285
2286
2287 for ( edge = edges; edge < edge_limit; edge++ )
2288 {
2289 seg = edge->first;
2290 if ( seg )
2291 do
2292 {
2293 seg->edge = edge;
2294 seg = seg->edge_next;
2295
2296 } while ( seg != edge->first );
2297 }
2298
2299 /* now compute each edge properties */
2300 for ( edge = edges; edge < edge_limit; edge++ )
2301 {
2302 FT_Int is_round = 0; /* does it contain round segments? */
2303 FT_Int is_straight = 0; /* does it contain straight segments? */
2304#if 0
2305 FT_Pos ups = 0; /* number of upwards segments */
2306 FT_Pos downs = 0; /* number of downwards segments */
2307#endif
2308
2309
2310 seg = edge->first;
2311
2312 do
2313 {
2314 FT_Bool is_serif;
2315
2316
2317 /* check for roundness of segment */
2318 if ( seg->flags & AF_EDGE_ROUND )
2319 is_round++;
2320 else
2321 is_straight++;
2322
2323#if 0
2324 /* check for segment direction */
2325 if ( seg->dir == up_dir )
2326 ups += seg->max_coord - seg->min_coord;
2327 else
2328 downs += seg->max_coord - seg->min_coord;
2329#endif
2330
2331 /* check for links -- if seg->serif is set, then seg->link must */
2332 /* be ignored */
2333 is_serif = (FT_Bool)( seg->serif &&
2334 seg->serif->edge &&
2335 seg->serif->edge != edge );
2336
2337 if ( ( seg->link && seg->link->edge ) || is_serif )
2338 {
2339 AF_Edge edge2;
2340 AF_Segment seg2;
2341
2342
2343 edge2 = edge->link;
2344 seg2 = seg->link;
2345
2346 if ( is_serif )
2347 {
2348 seg2 = seg->serif;
2349 edge2 = edge->serif;
2350 }
2351
2352 if ( edge2 )
2353 {
2354 FT_Pos edge_delta;
2355 FT_Pos seg_delta;
2356
2357
2358 edge_delta = edge->fpos - edge2->fpos;
2359 if ( edge_delta < 0 )
2360 edge_delta = -edge_delta;
2361
2362 seg_delta = seg->pos - seg2->pos;
2363 if ( seg_delta < 0 )
2364 seg_delta = -seg_delta;
2365
2366 if ( seg_delta < edge_delta )
2367 edge2 = seg2->edge;
2368 }
2369 else
2370 edge2 = seg2->edge;
2371
2372 if ( is_serif )
2373 {
2374 edge->serif = edge2;
2375 edge2->flags |= AF_EDGE_SERIF;
2376 }
2377 else
2378 edge->link = edge2;
2379 }
2380
2381 seg = seg->edge_next;
2382
2383 } while ( seg != edge->first );
2384
2385 /* set the round/straight flags */
2386 edge->flags = AF_EDGE_NORMAL;
2387
2388 if ( is_round > 0 && is_round >= is_straight )
2389 edge->flags |= AF_EDGE_ROUND;
2390
2391#if 0
2392 /* set the edge's main direction */
2393 edge->dir = AF_DIR_NONE;
2394
2395 if ( ups > downs )
2396 edge->dir = (FT_Char)up_dir;
2397
2398 else if ( ups < downs )
2399 edge->dir = (FT_Char)-up_dir;
2400
2401 else if ( ups == downs )
2402 edge->dir = 0; /* both up and down! */
2403#endif
2404
2405 /* get rid of serifs if link is set */
2406 /* XXX: This gets rid of many unpleasant artefacts! */
2407 /* Example: the `c' in cour.pfa at size 13 */
2408
2409 if ( edge->serif && edge->link )
2410 edge->serif = NULL;
2411 }
2412 }
2413
2414 Exit:
2415 return error;
2416 }
af_axis_hints_new_edge(AF_AxisHints axis, FT_Int fpos, AF_Direction dir, FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge)
Definition: afhints.c:99
#define AF_EDGE_ROUND
Definition: afhints.h:230
@ AF_DIMENSION_HORZ
Definition: afhints.h:35
@ AF_DIMENSION_VERT
Definition: afhints.h:37
enum AF_Direction_ AF_Direction
#define AF_EDGE_SERIF
Definition: afhints.h:231
#define AF_EDGE_NORMAL
Definition: afhints.h:229
@ AF_DIR_RIGHT
Definition: afhints.h:50
@ AF_DIR_UP
Definition: afhints.h:52
@ AF_DIR_NONE
Definition: afhints.h:49
struct AF_LatinMetricsRec_ * AF_LatinMetrics
#define AF_SCRIPT_CLASSES_GET
Definition: afpic.h:32
unsigned int dir
Definition: maze.c:112
#define NULL
Definition: types.h:112
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
return FT_Err_Ok
Definition: ftbbox.c:511
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_ZERO(p)
Definition: ftmemory.h:237
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
signed char FT_Char
Definition: fttypes.h:143
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
signed int FT_Int
Definition: fttypes.h:220
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
static void Exit(void)
Definition: sock.c:1330
AF_Segment segments
Definition: afhints.h:309
FT_Int num_edges
Definition: afhints.h:314
AF_Edge edges
Definition: afhints.h:316
FT_Int num_segments
Definition: afhints.h:307
FT_Char dir
Definition: afhints.h:289
AF_Edge serif
Definition: afhints.h:294
FT_Pos pos
Definition: afhints.h:286
AF_Edge link
Definition: afhints.h:293
AF_Segment first
Definition: afhints.h:297
AF_Segment last
Definition: afhints.h:298
FT_Short fpos
Definition: afhints.h:284
FT_Pos opos
Definition: afhints.h:285
FT_Byte flags
Definition: afhints.h:288
FT_Pos edge_distance_threshold
Definition: aflatin.h:95
FT_Bool top_to_bottom_hinting
Definition: aftypes.h:346
FT_Byte flags
Definition: afhints.h:260
FT_Char dir
Definition: afhints.h:261
FT_Short min_coord
Definition: afhints.h:264
FT_Short max_coord
Definition: afhints.h:265
FT_Short height
Definition: afhints.h:266
AF_Segment edge_next
Definition: afhints.h:269
FT_Short delta
Definition: afhints.h:263
AF_Segment link
Definition: afhints.h:271
FT_Short pos
Definition: afhints.h:262
AF_Edge edge
Definition: afhints.h:268
AF_Segment serif
Definition: afhints.h:272
AF_Script script
Definition: aftypes.h:450

Referenced by af_latin_hints_detect_features().

◆ af_latin_hints_compute_segments()

af_latin_hints_compute_segments ( AF_GlyphHints  hints,
AF_Dimension  dim 
)

Definition at line 1499 of file aflatin.c.

1501 {
1503 AF_AxisHints axis = &hints->axis[dim];
1504 FT_Memory memory = hints->memory;
1506 AF_Segment segment = NULL;
1507 AF_SegmentRec seg0;
1508 AF_Point* contour = hints->contours;
1509 AF_Point* contour_limit = contour + hints->num_contours;
1510 AF_Direction major_dir, segment_dir;
1511
1512 FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em );
1513
1514
1515 FT_ZERO( &seg0 );
1516 seg0.score = 32000;
1517 seg0.flags = AF_EDGE_NORMAL;
1518
1519 major_dir = (AF_Direction)FT_ABS( axis->major_dir );
1520 segment_dir = major_dir;
1521
1522 axis->num_segments = 0;
1523
1524 /* set up (u,v) in each point */
1525 if ( dim == AF_DIMENSION_HORZ )
1526 {
1527 AF_Point point = hints->points;
1528 AF_Point limit = point + hints->num_points;
1529
1530
1531 for ( ; point < limit; point++ )
1532 {
1533 point->u = point->fx;
1534 point->v = point->fy;
1535 }
1536 }
1537 else
1538 {
1539 AF_Point point = hints->points;
1540 AF_Point limit = point + hints->num_points;
1541
1542
1543 for ( ; point < limit; point++ )
1544 {
1545 point->u = point->fy;
1546 point->v = point->fx;
1547 }
1548 }
1549
1550 /* do each contour separately */
1551 for ( ; contour < contour_limit; contour++ )
1552 {
1553 AF_Point point = contour[0];
1554 AF_Point last = point->prev;
1555 int on_edge = 0;
1556
1557 /* we call values measured along a segment (point->v) */
1558 /* `coordinates', and values orthogonal to it (point->u) */
1559 /* `positions' */
1560 FT_Pos min_pos = 32000;
1561 FT_Pos max_pos = -32000;
1562 FT_Pos min_coord = 32000;
1563 FT_Pos max_coord = -32000;
1564 FT_UShort min_flags = AF_FLAG_NONE;
1565 FT_UShort max_flags = AF_FLAG_NONE;
1566 FT_Pos min_on_coord = 32000;
1567 FT_Pos max_on_coord = -32000;
1568
1569 FT_Bool passed;
1570
1571 AF_Segment prev_segment = NULL;
1572
1573 FT_Pos prev_min_pos = min_pos;
1574 FT_Pos prev_max_pos = max_pos;
1575 FT_Pos prev_min_coord = min_coord;
1576 FT_Pos prev_max_coord = max_coord;
1577 FT_UShort prev_min_flags = min_flags;
1578 FT_UShort prev_max_flags = max_flags;
1579 FT_Pos prev_min_on_coord = min_on_coord;
1580 FT_Pos prev_max_on_coord = max_on_coord;
1581
1582
1583 if ( FT_ABS( last->out_dir ) == major_dir &&
1584 FT_ABS( point->out_dir ) == major_dir )
1585 {
1586 /* we are already on an edge, try to locate its start */
1587 last = point;
1588
1589 for (;;)
1590 {
1591 point = point->prev;
1592 if ( FT_ABS( point->out_dir ) != major_dir )
1593 {
1594 point = point->next;
1595 break;
1596 }
1597 if ( point == last )
1598 break;
1599 }
1600 }
1601
1602 last = point;
1603 passed = 0;
1604
1605 for (;;)
1606 {
1607 FT_Pos u, v;
1608
1609
1610 if ( on_edge )
1611 {
1612 /* get minimum and maximum position */
1613 u = point->u;
1614 if ( u < min_pos )
1615 min_pos = u;
1616 if ( u > max_pos )
1617 max_pos = u;
1618
1619 /* get minimum and maximum coordinate together with flags */
1620 v = point->v;
1621 if ( v < min_coord )
1622 {
1623 min_coord = v;
1624 min_flags = point->flags;
1625 }
1626 if ( v > max_coord )
1627 {
1628 max_coord = v;
1629 max_flags = point->flags;
1630 }
1631
1632 /* get minimum and maximum coordinate of `on' points */
1633 if ( !( point->flags & AF_FLAG_CONTROL ) )
1634 {
1635 v = point->v;
1636 if ( v < min_on_coord )
1637 min_on_coord = v;
1638 if ( v > max_on_coord )
1639 max_on_coord = v;
1640 }
1641
1642 if ( point->out_dir != segment_dir || point == last )
1643 {
1644 /* check whether the new segment's start point is identical to */
1645 /* the previous segment's end point; for example, this might */
1646 /* happen for spikes */
1647
1648 if ( !prev_segment || segment->first != prev_segment->last )
1649 {
1650 /* points are different: we are just leaving an edge, thus */
1651 /* record a new segment */
1652
1653 segment->last = point;
1654 segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
1655 segment->delta = (FT_Short)( ( max_pos - min_pos ) >> 1 );
1656
1657 /* a segment is round if either its first or last point */
1658 /* is a control point, and the length of the on points */
1659 /* inbetween doesn't exceed a heuristic limit */
1660 if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
1661 ( max_on_coord - min_on_coord ) < flat_threshold )
1662 segment->flags |= AF_EDGE_ROUND;
1663
1664 segment->min_coord = (FT_Short)min_coord;
1665 segment->max_coord = (FT_Short)max_coord;
1666 segment->height = segment->max_coord - segment->min_coord;
1667
1668 prev_segment = segment;
1669 prev_min_pos = min_pos;
1670 prev_max_pos = max_pos;
1671 prev_min_coord = min_coord;
1672 prev_max_coord = max_coord;
1673 prev_min_flags = min_flags;
1674 prev_max_flags = max_flags;
1675 prev_min_on_coord = min_on_coord;
1676 prev_max_on_coord = max_on_coord;
1677 }
1678 else
1679 {
1680 /* points are the same: we don't create a new segment but */
1681 /* merge the current segment with the previous one */
1682
1683 if ( prev_segment->last->in_dir == point->in_dir )
1684 {
1685 /* we have identical directions (this can happen for */
1686 /* degenerate outlines that move zig-zag along the main */
1687 /* axis without changing the coordinate value of the other */
1688 /* axis, and where the segments have just been merged): */
1689 /* unify segments */
1690
1691 /* update constraints */
1692
1693 if ( prev_min_pos < min_pos )
1694 min_pos = prev_min_pos;
1695 if ( prev_max_pos > max_pos )
1696 max_pos = prev_max_pos;
1697
1698 if ( prev_min_coord < min_coord )
1699 {
1700 min_coord = prev_min_coord;
1701 min_flags = prev_min_flags;
1702 }
1703 if ( prev_max_coord > max_coord )
1704 {
1705 max_coord = prev_max_coord;
1706 max_flags = prev_max_flags;
1707 }
1708
1709 if ( prev_min_on_coord < min_on_coord )
1710 min_on_coord = prev_min_on_coord;
1711 if ( prev_max_on_coord > max_on_coord )
1712 max_on_coord = prev_max_on_coord;
1713
1714 prev_segment->last = point;
1715 prev_segment->pos = (FT_Short)( ( min_pos +
1716 max_pos ) >> 1 );
1717 prev_segment->delta = (FT_Short)( ( max_pos -
1718 min_pos ) >> 1 );
1719
1720 if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
1721 ( max_on_coord - min_on_coord ) < flat_threshold )
1722 prev_segment->flags |= AF_EDGE_ROUND;
1723 else
1724 prev_segment->flags &= ~AF_EDGE_ROUND;
1725
1726 prev_segment->min_coord = (FT_Short)min_coord;
1727 prev_segment->max_coord = (FT_Short)max_coord;
1728 prev_segment->height = prev_segment->max_coord -
1729 prev_segment->min_coord;
1730 }
1731 else
1732 {
1733 /* we have different directions; use the properties of the */
1734 /* longer segment and discard the other one */
1735
1736 if ( FT_ABS( prev_max_coord - prev_min_coord ) >
1737 FT_ABS( max_coord - min_coord ) )
1738 {
1739 /* discard current segment */
1740
1741 if ( min_pos < prev_min_pos )
1742 prev_min_pos = min_pos;
1743 if ( max_pos > prev_max_pos )
1744 prev_max_pos = max_pos;
1745
1746 prev_segment->last = point;
1747 prev_segment->pos = (FT_Short)( ( prev_min_pos +
1748 prev_max_pos ) >> 1 );
1749 prev_segment->delta = (FT_Short)( ( prev_max_pos -
1750 prev_min_pos ) >> 1 );
1751 }
1752 else
1753 {
1754 /* discard previous segment */
1755
1756 if ( prev_min_pos < min_pos )
1757 min_pos = prev_min_pos;
1758 if ( prev_max_pos > max_pos )
1759 max_pos = prev_max_pos;
1760
1761 segment->last = point;
1762 segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
1763 segment->delta = (FT_Short)( ( max_pos - min_pos ) >> 1 );
1764
1765 if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
1766 ( max_on_coord - min_on_coord ) < flat_threshold )
1767 segment->flags |= AF_EDGE_ROUND;
1768
1769 segment->min_coord = (FT_Short)min_coord;
1770 segment->max_coord = (FT_Short)max_coord;
1771 segment->height = segment->max_coord -
1772 segment->min_coord;
1773
1774 *prev_segment = *segment;
1775
1776 prev_min_pos = min_pos;
1777 prev_max_pos = max_pos;
1778 prev_min_coord = min_coord;
1779 prev_max_coord = max_coord;
1780 prev_min_flags = min_flags;
1781 prev_max_flags = max_flags;
1782 prev_min_on_coord = min_on_coord;
1783 prev_max_on_coord = max_on_coord;
1784 }
1785 }
1786
1787 axis->num_segments--;
1788 }
1789
1790 on_edge = 0;
1791 segment = NULL;
1792
1793 /* fall through */
1794 }
1795 }
1796
1797 /* now exit if we are at the start/end point */
1798 if ( point == last )
1799 {
1800 if ( passed )
1801 break;
1802 passed = 1;
1803 }
1804
1805 /* if we are not on an edge, check whether the major direction */
1806 /* coincides with the current point's `out' direction, or */
1807 /* whether we have a single-point contour */
1808 if ( !on_edge &&
1809 ( FT_ABS( point->out_dir ) == major_dir ||
1810 point == point->prev ) )
1811 {
1812 /* this is the start of a new segment! */
1813 segment_dir = (AF_Direction)point->out_dir;
1814
1815 error = af_axis_hints_new_segment( axis, memory, &segment );
1816 if ( error )
1817 goto Exit;
1818
1819 /* clear all segment fields */
1820 segment[0] = seg0;
1821
1822 segment->dir = (FT_Char)segment_dir;
1823 segment->first = point;
1824 segment->last = point;
1825
1826 /* `af_axis_hints_new_segment' reallocates memory, */
1827 /* thus we have to refresh the `prev_segment' pointer */
1828 if ( prev_segment )
1829 prev_segment = segment - 1;
1830
1831 min_pos = max_pos = point->u;
1832 min_coord = max_coord = point->v;
1833 min_flags = max_flags = point->flags;
1834
1835 if ( point->flags & AF_FLAG_CONTROL )
1836 {
1837 min_on_coord = 32000;
1838 max_on_coord = -32000;
1839 }
1840 else
1841 min_on_coord = max_on_coord = point->v;
1842
1843 on_edge = 1;
1844
1845 if ( point == point->prev )
1846 {
1847 /* we have a one-point segment: this is a one-point */
1848 /* contour with `in' and `out' direction set to */
1849 /* AF_DIR_NONE */
1850 segment->pos = (FT_Short)min_pos;
1851
1852 if (point->flags & AF_FLAG_CONTROL)
1853 segment->flags |= AF_EDGE_ROUND;
1854
1855 segment->min_coord = (FT_Short)point->v;
1856 segment->max_coord = (FT_Short)point->v;
1857 segment->height = 0;
1858
1859 on_edge = 0;
1860 segment = NULL;
1861 }
1862 }
1863
1864 point = point->next;
1865 }
1866
1867 } /* contours */
1868
1869
1870 /* now slightly increase the height of segments if this makes */
1871 /* sense -- this is used to better detect and ignore serifs */
1872 {
1873 AF_Segment segments = axis->segments;
1874 AF_Segment segments_end = segments + axis->num_segments;
1875
1876
1877 for ( segment = segments; segment < segments_end; segment++ )
1878 {
1879 AF_Point first = segment->first;
1880 AF_Point last = segment->last;
1881 FT_Pos first_v = first->v;
1882 FT_Pos last_v = last->v;
1883
1884
1885 if ( first_v < last_v )
1886 {
1887 AF_Point p;
1888
1889
1890 p = first->prev;
1891 if ( p->v < first_v )
1892 segment->height = (FT_Short)( segment->height +
1893 ( ( first_v - p->v ) >> 1 ) );
1894
1895 p = last->next;
1896 if ( p->v > last_v )
1897 segment->height = (FT_Short)( segment->height +
1898 ( ( p->v - last_v ) >> 1 ) );
1899 }
1900 else
1901 {
1902 AF_Point p;
1903
1904
1905 p = first->prev;
1906 if ( p->v > first_v )
1907 segment->height = (FT_Short)( segment->height +
1908 ( ( p->v - first_v ) >> 1 ) );
1909
1910 p = last->next;
1911 if ( p->v < last_v )
1912 segment->height = (FT_Short)( segment->height +
1913 ( ( last_v - p->v ) >> 1 ) );
1914 }
1915 }
1916 }
1917
1918 Exit:
1919 return error;
1920 }
af_axis_hints_new_segment(AF_AxisHints axis, FT_Memory memory, AF_Segment *asegment)
Definition: afhints.c:38
#define AF_FLAG_NONE
Definition: afhints.h:210
#define AF_FLAG_CONTROL
Definition: afhints.h:215
#define FLAT_THRESHOLD(x)
Definition: aflatin.c:45
POINTL point
Definition: edittest.c:50
#define FT_ABS(a)
Definition: ftobjs.h:74
unsigned short FT_UShort
Definition: fttypes.h:209
signed short FT_Short
Definition: fttypes.h:198
const GLdouble * v
Definition: gl.h:2040
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLint limit
Definition: glext.h:10326
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static UINT UINT last
Definition: font.c:45
FT_Char in_dir
Definition: afhints.h:244
AF_Point last
Definition: afhints.h:277

Referenced by af_latin_hints_detect_features(), and af_latin_metrics_init_widths().

◆ af_latin_hints_detect_features()

af_latin_hints_detect_features ( AF_GlyphHints  hints,
FT_UInt  width_count,
AF_WidthRec widths,
AF_Dimension  dim 
)

Definition at line 2422 of file aflatin.c.

2426 {
2428
2429
2431 if ( !error )
2432 {
2433 af_latin_hints_link_segments( hints, width_count, widths, dim );
2434
2436 }
2437
2438 return error;
2439 }
af_latin_hints_link_segments(AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
Definition: aflatin.c:1927
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:1499
af_latin_hints_compute_edges(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:2065

Referenced by af_latin_hints_apply().

◆ af_latin_hints_link_segments()

af_latin_hints_link_segments ( AF_GlyphHints  hints,
FT_UInt  width_count,
AF_WidthRec widths,
AF_Dimension  dim 
)

Definition at line 1927 of file aflatin.c.

1931 {
1932 AF_AxisHints axis = &hints->axis[dim];
1933 AF_Segment segments = axis->segments;
1934 AF_Segment segment_limit = segments + axis->num_segments;
1935 FT_Pos len_threshold, len_score, dist_score, max_width;
1936 AF_Segment seg1, seg2;
1937
1938
1939 if ( width_count )
1940 max_width = widths[width_count - 1].org;
1941 else
1942 max_width = 0;
1943
1944 /* a heuristic value to set up a minimum value for overlapping */
1945 len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
1946 if ( len_threshold == 0 )
1947 len_threshold = 1;
1948
1949 /* a heuristic value to weight lengths */
1950 len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
1951
1952 /* a heuristic value to weight distances (no call to */
1953 /* AF_LATIN_CONSTANT needed, since we work on multiples */
1954 /* of the stem width) */
1955 dist_score = 3000;
1956
1957 /* now compare each segment to the others */
1958 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1959 {
1960 if ( seg1->dir != axis->major_dir )
1961 continue;
1962
1963 /* search for stems having opposite directions, */
1964 /* with seg1 to the `left' of seg2 */
1965 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
1966 {
1967 FT_Pos pos1 = seg1->pos;
1968 FT_Pos pos2 = seg2->pos;
1969
1970
1971 if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
1972 {
1973 /* compute distance between the two segments */
1974 FT_Pos min = seg1->min_coord;
1975 FT_Pos max = seg1->max_coord;
1976 FT_Pos len;
1977
1978
1979 if ( min < seg2->min_coord )
1980 min = seg2->min_coord;
1981
1982 if ( max > seg2->max_coord )
1983 max = seg2->max_coord;
1984
1985 /* compute maximum coordinate difference of the two segments */
1986 /* (this is, how much they overlap) */
1987 len = max - min;
1988 if ( len >= len_threshold )
1989 {
1990 /*
1991 * The score is the sum of two demerits indicating the
1992 * `badness' of a fit, measured along the segments' main axis
1993 * and orthogonal to it, respectively.
1994 *
1995 * o The less overlapping along the main axis, the worse it
1996 * is, causing a larger demerit.
1997 *
1998 * o The nearer the orthogonal distance to a stem width, the
1999 * better it is, causing a smaller demerit. For simplicity,
2000 * however, we only increase the demerit for values that
2001 * exceed the largest stem width.
2002 */
2003
2004 FT_Pos dist = pos2 - pos1;
2005
2006 FT_Pos dist_demerit, score;
2007
2008
2009 if ( max_width )
2010 {
2011 /* distance demerits are based on multiples of `max_width'; */
2012 /* we scale by 1024 for getting more precision */
2013 FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 );
2014
2015
2016 if ( delta > 10000 )
2017 dist_demerit = 32000;
2018 else if ( delta > 0 )
2019 dist_demerit = delta * delta / dist_score;
2020 else
2021 dist_demerit = 0;
2022 }
2023 else
2024 dist_demerit = dist; /* default if no widths available */
2025
2026 score = dist_demerit + len_score / len;
2027
2028 /* and we search for the smallest score */
2029 if ( score < seg1->score )
2030 {
2031 seg1->score = score;
2032 seg1->link = seg2;
2033 }
2034
2035 if ( score < seg2->score )
2036 {
2037 seg2->score = score;
2038 seg2->link = seg1;
2039 }
2040 }
2041 }
2042 }
2043 }
2044
2045 /* now compute the `serif' segments, cf. explanations in `afhints.h' */
2046 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
2047 {
2048 seg2 = seg1->link;
2049
2050 if ( seg2 )
2051 {
2052 if ( seg2->link != seg1 )
2053 {
2054 seg1->link = 0;
2055 seg1->serif = seg2->link;
2056 }
2057 }
2058 }
2059 }
#define AF_LATIN_CONSTANT(metrics, c)
Definition: aflatin.h:34
GLenum GLsizei len
Definition: glext.h:6722
#define min(a, b)
Definition: monoChain.cc:55
AF_Direction major_dir
Definition: afhints.h:318
FT_Pos score
Definition: afhints.h:273
#define max(a, b)
Definition: svc.c:63

Referenced by af_latin_hints_detect_features(), and af_latin_metrics_init_widths().

◆ af_latin_metrics_check_digits()

af_latin_metrics_check_digits ( AF_LatinMetrics  metrics,
FT_Face  face 
)

Definition at line 1054 of file aflatin.c.

1056 {
1057 FT_Bool started = 0, same_width = 1;
1058 FT_Fixed advance = 0, old_advance = 0;
1059
1060 void* shaper_buf;
1061
1062 /* in all supported charmaps, digits have character codes 0x30-0x39 */
1063 const char digits[] = "0 1 2 3 4 5 6 7 8 9";
1064 const char* p;
1065
1066
1067 p = digits;
1068 shaper_buf = af_shaper_buf_create( face );
1069
1070 while ( *p )
1071 {
1072 FT_ULong glyph_index;
1073 unsigned int num_idx;
1074
1075
1076 /* reject input that maps to more than a single glyph */
1077 p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx );
1078 if ( num_idx > 1 )
1079 continue;
1080
1081 glyph_index = af_shaper_get_elem( &metrics->root,
1082 shaper_buf,
1083 0,
1084 &advance,
1085 NULL );
1086 if ( !glyph_index )
1087 continue;
1088
1089 if ( started )
1090 {
1091 if ( advance != old_advance )
1092 {
1093 same_width = 0;
1094 break;
1095 }
1096 }
1097 else
1098 {
1099 old_advance = advance;
1100 started = 1;
1101 }
1102 }
1103
1104 af_shaper_buf_destroy( face, shaper_buf );
1105
1106 metrics->root.digits_have_same_width = same_width;
1107 }
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
void * af_shaper_buf_create(FT_Face face)
Definition: afshaper.c:592
const char * af_shaper_get_cluster(const char *p, AF_StyleMetrics metrics, void *buf_, unsigned int *count)
Definition: afshaper.c:617
FT_ULong af_shaper_get_elem(AF_StyleMetrics metrics, void *buf_, unsigned int idx, FT_Long *advance, FT_Long *y_offset)
Definition: afshaper.c:653
void af_shaper_buf_destroy(FT_Face face, void *buf)
Definition: afshaper.c:606
unsigned long FT_ULong
Definition: fttypes.h:253
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
static const int digits[]
Definition: decode.c:71

Referenced by af_latin_metrics_init().

◆ af_latin_metrics_init()

af_latin_metrics_init ( AF_LatinMetrics  metrics,
FT_Face  face 
)

Definition at line 1113 of file aflatin.c.

1115 {
1116 FT_CharMap oldmap = face->charmap;
1117
1118
1119 metrics->units_per_em = face->units_per_EM;
1120
1121 if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
1122 {
1126 }
1127
1128 FT_Set_Charmap( face, oldmap );
1129 return FT_Err_Ok;
1130 }
af_latin_metrics_init_widths(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:61
af_latin_metrics_check_digits(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:1054
static void af_latin_metrics_init_blues(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:332
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3457
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3499

◆ af_latin_metrics_init_widths()

af_latin_metrics_init_widths ( AF_LatinMetrics  metrics,
FT_Face  face 
)

Definition at line 61 of file aflatin.c.

63 {
64 /* scan the array of segments in each direction */
65#ifdef __REACTOS__
67 if (!hints) return;
68#else
70#endif
71
72
73 FT_TRACE5(( "\n"
74 "latin standard widths computation (style `%s')\n"
75 "=====================================================\n"
76 "\n",
77 af_style_names[metrics->root.style_class->style] ));
78
79 af_glyph_hints_init( hints, face->memory );
80
81 metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
82 metrics->axis[AF_DIMENSION_VERT].width_count = 0;
83
84 {
86 FT_ULong glyph_index;
87 int dim;
88#ifdef __REACTOS__
90 if (!dummy)
91 goto Exit;
92 {
93#else
95#endif
96 AF_Scaler scaler = &dummy->root.scaler;
97
98#ifdef FT_CONFIG_OPTION_PIC
99 AF_FaceGlobals globals = metrics->root.globals;
100#endif
101
102 AF_StyleClass style_class = metrics->root.style_class;
104 [style_class->script];
105
106 void* shaper_buf;
107 const char* p;
108
109#ifdef FT_DEBUG_LEVEL_TRACE
110 FT_ULong ch = 0;
111#endif
112
113 p = script_class->standard_charstring;
114 shaper_buf = af_shaper_buf_create( face );
115
116 /*
117 * We check a list of standard characters to catch features like
118 * `c2sc' (small caps from caps) that don't contain lowercase letters
119 * by definition, or other features that mainly operate on numerals.
120 * The first match wins.
121 */
122
123 glyph_index = 0;
124 while ( *p )
125 {
126 unsigned int num_idx;
127
128#ifdef FT_DEBUG_LEVEL_TRACE
129 const char* p_old;
130#endif
131
132
133 while ( *p == ' ' )
134 p++;
135
136#ifdef FT_DEBUG_LEVEL_TRACE
137 p_old = p;
138 GET_UTF8_CHAR( ch, p_old );
139#endif
140
141 /* reject input that maps to more than a single glyph */
142 p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx );
143 if ( num_idx > 1 )
144 continue;
145
146 /* otherwise exit loop if we have a result */
147 glyph_index = af_shaper_get_elem( &metrics->root,
148 shaper_buf,
149 0,
150 NULL,
151 NULL );
152 if ( glyph_index )
153 break;
154 }
155
156 af_shaper_buf_destroy( face, shaper_buf );
157
158 if ( !glyph_index )
159 goto Exit;
160
161 FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
162 ch, glyph_index ));
163
164 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
165 if ( error || face->glyph->outline.n_points <= 0 )
166 goto Exit;
167
168 FT_ZERO( dummy );
169
170 dummy->units_per_em = metrics->units_per_em;
171
172 scaler->x_scale = 0x10000L;
173 scaler->y_scale = 0x10000L;
174 scaler->x_delta = 0;
175 scaler->y_delta = 0;
176
177 scaler->face = face;
179 scaler->flags = 0;
180
182
183 error = af_glyph_hints_reload( hints, &face->glyph->outline );
184 if ( error )
185 goto Exit;
186
187 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
188 {
189 AF_LatinAxis axis = &metrics->axis[dim];
190 AF_AxisHints axhints = &hints->axis[dim];
191 AF_Segment seg, limit, link;
192 FT_UInt num_widths = 0;
193
194
196 (AF_Dimension)dim );
197 if ( error )
198 goto Exit;
199
200 /*
201 * We assume that the glyphs selected for the stem width
202 * computation are `featureless' enough so that the linking
203 * algorithm works fine without adjustments of its scoring
204 * function.
205 */
207 0,
208 NULL,
209 (AF_Dimension)dim );
210
211 seg = axhints->segments;
212 limit = seg + axhints->num_segments;
213
214 for ( ; seg < limit; seg++ )
215 {
216 link = seg->link;
217
218 /* we only consider stem segments there! */
219 if ( link && link->link == seg && link > seg )
220 {
221 FT_Pos dist;
222
223
224 dist = seg->pos - link->pos;
225 if ( dist < 0 )
226 dist = -dist;
227
228 if ( num_widths < AF_LATIN_MAX_WIDTHS )
229 axis->widths[num_widths++].org = dist;
230 }
231 }
232
233 /* this also replaces multiple almost identical stem widths */
234 /* with a single one (the value 100 is heuristic) */
235 af_sort_and_quantize_widths( &num_widths, axis->widths,
236 dummy->units_per_em / 100 );
237 axis->width_count = num_widths;
238 }
239
240 Exit:
241 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
242 {
243 AF_LatinAxis axis = &metrics->axis[dim];
244 FT_Pos stdw;
245
246
247 stdw = ( axis->width_count > 0 ) ? axis->widths[0].org
248 : AF_LATIN_CONSTANT( metrics, 50 );
249
250 /* let's try 20% of the smallest width */
251 axis->edge_distance_threshold = stdw / 5;
252 axis->standard_width = stdw;
253 axis->extra_light = 0;
254
255#ifdef FT_DEBUG_LEVEL_TRACE
256 {
257 FT_UInt i;
258
259
260 FT_TRACE5(( "%s widths:\n",
261 dim == AF_DIMENSION_VERT ? "horizontal"
262 : "vertical" ));
263
264 FT_TRACE5(( " %d (standard)", axis->standard_width ));
265 for ( i = 1; i < axis->width_count; i++ )
266 FT_TRACE5(( " %d", axis->widths[i].org ));
267
268 FT_TRACE5(( "\n" ));
269 }
270#endif
271 }
272#ifdef __REACTOS__
273 free(dummy);
274 }
275#endif
276 }
277
278 FT_TRACE5(( "\n" ));
279
281
282#ifdef __REACTOS__
283 free(hints);
284#endif
285
286 }
af_sort_and_quantize_widths(FT_UInt *count, AF_Width table, FT_Pos threshold)
Definition: afangles.c:210
#define GET_UTF8_CHAR(ch, p)
Definition: afblue.h:31
af_glyph_hints_done(AF_GlyphHints hints)
Definition: afhints.c:672
af_glyph_hints_rescale(AF_GlyphHints hints, AF_StyleMetrics metrics)
Definition: afhints.c:720
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:732
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
Definition: afhints.c:662
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
@ AF_DIMENSION_MAX
Definition: afhints.h:40
#define AF_LATIN_MAX_WIDTHS
Definition: aflatin.h:65
const WCHAR * link
Definition: db.cpp:997
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
WORD face[3]
Definition: mesh.c:4747
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:760
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3009
@ FT_RENDER_MODE_NORMAL
Definition: freetype.h:3234
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
unsigned int FT_UInt
Definition: fttypes.h:231
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FT_Bool extra_light
Definition: aflatin.h:97
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]
Definition: aflatin.h:94
FT_Pos standard_width
Definition: aflatin.h:96
FT_UInt width_count
Definition: aflatin.h:93
FT_UInt32 flags
Definition: aftypes.h:186
FT_Render_Mode render_mode
Definition: aftypes.h:185
FT_Pos y_delta
Definition: aftypes.h:184
FT_Face face
Definition: aftypes.h:180
FT_Pos x_delta
Definition: aftypes.h:183
FT_Fixed y_scale
Definition: aftypes.h:182
FT_Fixed x_scale
Definition: aftypes.h:181
const char * standard_charstring
Definition: aftypes.h:348

Referenced by af_latin_metrics_init().

◆ af_latin_metrics_scale()

af_latin_metrics_scale ( AF_LatinMetrics  metrics,
AF_Scaler  scaler 
)

Definition at line 1459 of file aflatin.c.

1461 {
1462 metrics->root.scaler.render_mode = scaler->render_mode;
1463 metrics->root.scaler.face = scaler->face;
1464 metrics->root.scaler.flags = scaler->flags;
1465
1468 }
static void af_latin_metrics_scale_dim(AF_LatinMetrics metrics, AF_Scaler scaler, AF_Dimension dim)
Definition: aflatin.c:1137