ReactOS 0.4.16-dev-1067-ge98bba2
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 2088 of file aflatin.c.

2090 {
2091 AF_AxisHints axis = &hints->axis[dim];
2093 FT_Memory memory = hints->memory;
2094 AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
2095
2096 AF_StyleClass style_class = hints->metrics->style_class;
2097 AF_ScriptClass script_class = af_script_classes[style_class->script];
2098
2099 FT_Bool top_to_bottom_hinting = 0;
2100
2101 AF_Segment segments = axis->segments;
2102 AF_Segment segment_limit = segments + axis->num_segments;
2103 AF_Segment seg;
2104
2105#if 0
2106 AF_Direction up_dir;
2107#endif
2109 FT_Pos edge_distance_threshold;
2110 FT_Pos segment_length_threshold;
2111 FT_Pos segment_width_threshold;
2112
2113
2114 axis->num_edges = 0;
2115
2116 scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
2117 : hints->y_scale;
2118
2119#if 0
2120 up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
2121 : AF_DIR_RIGHT;
2122#endif
2123
2124 if ( dim == AF_DIMENSION_VERT )
2125 top_to_bottom_hinting = script_class->top_to_bottom_hinting;
2126
2127 /*
2128 * We ignore all segments that are less than 1 pixel in length
2129 * to avoid many problems with serif fonts. We compute the
2130 * corresponding threshold in font units.
2131 */
2132 if ( dim == AF_DIMENSION_HORZ )
2133 segment_length_threshold = FT_DivFix( 64, hints->y_scale );
2134 else
2135 segment_length_threshold = 0;
2136
2137 /*
2138 * Similarly, we ignore segments that have a width delta
2139 * larger than 0.5px (i.e., a width larger than 1px).
2140 */
2141 segment_width_threshold = FT_DivFix( 32, scale );
2142
2143 /**********************************************************************
2144 *
2145 * We begin by generating a sorted table of edges for the current
2146 * direction. To do so, we simply scan each segment and try to find
2147 * an edge in our table that corresponds to its position.
2148 *
2149 * If no edge is found, we create and insert a new edge in the
2150 * sorted table. Otherwise, we simply add the segment to the edge's
2151 * list which gets processed in the second step to compute the
2152 * edge's properties.
2153 *
2154 * Note that the table of edges is sorted along the segment/edge
2155 * position.
2156 *
2157 */
2158
2159 /* assure that edge distance threshold is at most 0.25px */
2160 edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
2161 scale );
2162 if ( edge_distance_threshold > 64 / 4 )
2163 edge_distance_threshold = 64 / 4;
2164
2165 edge_distance_threshold = FT_DivFix( edge_distance_threshold,
2166 scale );
2167
2168 for ( seg = segments; seg < segment_limit; seg++ )
2169 {
2170 AF_Edge found = NULL;
2171 FT_Int ee;
2172
2173
2174 /* ignore too short segments, too wide ones, and, in this loop, */
2175 /* one-point segments without a direction */
2176 if ( seg->height < segment_length_threshold ||
2177 seg->delta > segment_width_threshold ||
2178 seg->dir == AF_DIR_NONE )
2179 continue;
2180
2181 /* A special case for serif edges: If they are smaller than */
2182 /* 1.5 pixels we ignore them. */
2183 if ( seg->serif &&
2184 2 * seg->height < 3 * segment_length_threshold )
2185 continue;
2186
2187 /* look for an edge corresponding to the segment */
2188 for ( ee = 0; ee < axis->num_edges; ee++ )
2189 {
2190 AF_Edge edge = axis->edges + ee;
2191 FT_Pos dist;
2192
2193
2194 dist = seg->pos - edge->fpos;
2195 if ( dist < 0 )
2196 dist = -dist;
2197
2198 if ( dist < edge_distance_threshold && edge->dir == seg->dir )
2199 {
2200 found = edge;
2201 break;
2202 }
2203 }
2204
2205 if ( !found )
2206 {
2207 AF_Edge edge;
2208
2209
2210 /* insert a new edge in the list and */
2211 /* sort according to the position */
2212 error = af_axis_hints_new_edge( axis, seg->pos,
2213 (AF_Direction)seg->dir,
2214 top_to_bottom_hinting,
2215 memory, &edge );
2216 if ( error )
2217 goto Exit;
2218
2219 /* add the segment to the new edge's list */
2220 FT_ZERO( edge );
2221
2222 edge->first = seg;
2223 edge->last = seg;
2224 edge->dir = seg->dir;
2225 edge->fpos = seg->pos;
2226 edge->opos = FT_MulFix( seg->pos, scale );
2227 edge->pos = edge->opos;
2228 seg->edge_next = seg;
2229 }
2230 else
2231 {
2232 /* if an edge was found, simply add the segment to the edge's */
2233 /* list */
2234 seg->edge_next = found->first;
2235 found->last->edge_next = seg;
2236 found->last = seg;
2237 }
2238 }
2239
2240 /* we loop again over all segments to catch one-point segments */
2241 /* without a direction: if possible, link them to existing edges */
2242 for ( seg = segments; seg < segment_limit; seg++ )
2243 {
2244 AF_Edge found = NULL;
2245 FT_Int ee;
2246
2247
2248 if ( seg->dir != AF_DIR_NONE )
2249 continue;
2250
2251 /* look for an edge corresponding to the segment */
2252 for ( ee = 0; ee < axis->num_edges; ee++ )
2253 {
2254 AF_Edge edge = axis->edges + ee;
2255 FT_Pos dist;
2256
2257
2258 dist = seg->pos - edge->fpos;
2259 if ( dist < 0 )
2260 dist = -dist;
2261
2262 if ( dist < edge_distance_threshold )
2263 {
2264 found = edge;
2265 break;
2266 }
2267 }
2268
2269 /* one-point segments without a match are ignored */
2270 if ( found )
2271 {
2272 seg->edge_next = found->first;
2273 found->last->edge_next = seg;
2274 found->last = seg;
2275 }
2276 }
2277
2278
2279 /*******************************************************************
2280 *
2281 * Good, we now compute each edge's properties according to the
2282 * segments found on its position. Basically, these are
2283 *
2284 * - the edge's main direction
2285 * - stem edge, serif edge or both (which defaults to stem then)
2286 * - rounded edge, straight or both (which defaults to straight)
2287 * - link for edge
2288 *
2289 */
2290
2291 /* first of all, set the `edge' field in each segment -- this is */
2292 /* required in order to compute edge links */
2293
2294 /*
2295 * Note that removing this loop and setting the `edge' field of each
2296 * segment directly in the code above slows down execution speed for
2297 * some reasons on platforms like the Sun.
2298 */
2299 {
2300 AF_Edge edges = axis->edges;
2301 AF_Edge edge_limit = edges + axis->num_edges;
2302 AF_Edge edge;
2303
2304
2305 for ( edge = edges; edge < edge_limit; edge++ )
2306 {
2307 seg = edge->first;
2308 if ( seg )
2309 do
2310 {
2311 seg->edge = edge;
2312 seg = seg->edge_next;
2313
2314 } while ( seg != edge->first );
2315 }
2316
2317 /* now compute each edge properties */
2318 for ( edge = edges; edge < edge_limit; edge++ )
2319 {
2320 FT_Int is_round = 0; /* does it contain round segments? */
2321 FT_Int is_straight = 0; /* does it contain straight segments? */
2322#if 0
2323 FT_Pos ups = 0; /* number of upwards segments */
2324 FT_Pos downs = 0; /* number of downwards segments */
2325#endif
2326
2327
2328 seg = edge->first;
2329
2330 do
2331 {
2332 FT_Bool is_serif;
2333
2334
2335 /* check for roundness of segment */
2336 if ( seg->flags & AF_EDGE_ROUND )
2337 is_round++;
2338 else
2339 is_straight++;
2340
2341#if 0
2342 /* check for segment direction */
2343 if ( seg->dir == up_dir )
2344 ups += seg->max_coord - seg->min_coord;
2345 else
2346 downs += seg->max_coord - seg->min_coord;
2347#endif
2348
2349 /* check for links -- if seg->serif is set, then seg->link must */
2350 /* be ignored */
2351 is_serif = FT_BOOL( seg->serif &&
2352 seg->serif->edge &&
2353 seg->serif->edge != edge );
2354
2355 if ( ( seg->link && seg->link->edge ) || is_serif )
2356 {
2357 AF_Edge edge2;
2358 AF_Segment seg2;
2359
2360
2361 edge2 = edge->link;
2362 seg2 = seg->link;
2363
2364 if ( is_serif )
2365 {
2366 seg2 = seg->serif;
2367 edge2 = edge->serif;
2368 }
2369
2370 if ( edge2 )
2371 {
2372 FT_Pos edge_delta;
2373 FT_Pos seg_delta;
2374
2375
2376 edge_delta = edge->fpos - edge2->fpos;
2377 if ( edge_delta < 0 )
2378 edge_delta = -edge_delta;
2379
2380 seg_delta = seg->pos - seg2->pos;
2381 if ( seg_delta < 0 )
2382 seg_delta = -seg_delta;
2383
2384 if ( seg_delta < edge_delta )
2385 edge2 = seg2->edge;
2386 }
2387 else
2388 edge2 = seg2->edge;
2389
2390 if ( is_serif )
2391 {
2392 edge->serif = edge2;
2393 edge2->flags |= AF_EDGE_SERIF;
2394 }
2395 else
2396 edge->link = edge2;
2397 }
2398
2399 seg = seg->edge_next;
2400
2401 } while ( seg != edge->first );
2402
2403 /* set the round/straight flags */
2404 edge->flags = AF_EDGE_NORMAL;
2405
2406 if ( is_round > 0 && is_round >= is_straight )
2407 edge->flags |= AF_EDGE_ROUND;
2408
2409#if 0
2410 /* set the edge's main direction */
2411 edge->dir = AF_DIR_NONE;
2412
2413 if ( ups > downs )
2414 edge->dir = (FT_Char)up_dir;
2415
2416 else if ( ups < downs )
2417 edge->dir = (FT_Char)-up_dir;
2418
2419 else if ( ups == downs )
2420 edge->dir = 0; /* both up and down! */
2421#endif
2422
2423 /* get rid of serifs if link is set */
2424 /* XXX: This gets rid of many unpleasant artefacts! */
2425 /* Example: the `c' in cour.pfa at size 13 */
2426
2427 if ( edge->serif && edge->link )
2428 edge->serif = NULL;
2429 }
2430 }
2431
2432 Exit:
2433 return error;
2434 }
af_script_classes[]
Definition: afglobal.c:88
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
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:527
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:65
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:287
int FT_Error
Definition: fttypes.h:299
#define FT_BOOL(x)
Definition: fttypes.h:591
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:315
FT_Int num_edges
Definition: afhints.h:320
AF_Edge edges
Definition: afhints.h:322
FT_Int num_segments
Definition: afhints.h:313
FT_Char dir
Definition: afhints.h:295
AF_Edge serif
Definition: afhints.h:300
FT_Pos pos
Definition: afhints.h:292
AF_Edge link
Definition: afhints.h:299
AF_Segment first
Definition: afhints.h:303
AF_Segment last
Definition: afhints.h:304
FT_Short fpos
Definition: afhints.h:290
FT_Pos opos
Definition: afhints.h:291
FT_Byte flags
Definition: afhints.h:294
FT_Pos edge_distance_threshold
Definition: aflatin.h:95
FT_Bool top_to_bottom_hinting
Definition: aftypes.h:348
FT_Byte flags
Definition: afhints.h:266
FT_Char dir
Definition: afhints.h:267
FT_Short min_coord
Definition: afhints.h:270
FT_Short max_coord
Definition: afhints.h:271
FT_Short height
Definition: afhints.h:272
AF_Segment edge_next
Definition: afhints.h:275
FT_Short delta
Definition: afhints.h:269
AF_Segment link
Definition: afhints.h:277
FT_Short pos
Definition: afhints.h:268
AF_Edge edge
Definition: afhints.h:274
AF_Segment serif
Definition: afhints.h:278
AF_Script script
Definition: aftypes.h:452

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 1522 of file aflatin.c.

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

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 2440 of file aflatin.c.

2444 {
2446
2447
2449 if ( !error )
2450 {
2451 af_latin_hints_link_segments( hints, width_count, widths, dim );
2452
2454 }
2455
2456 return error;
2457 }
af_latin_hints_link_segments(AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
Definition: aflatin.c:1950
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:1522
af_latin_hints_compute_edges(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:2088

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 1950 of file aflatin.c.

1954 {
1955 AF_AxisHints axis = &hints->axis[dim];
1956 AF_Segment segments = axis->segments;
1957 AF_Segment segment_limit = segments + axis->num_segments;
1958 FT_Pos len_threshold, len_score, dist_score, max_width;
1959 AF_Segment seg1, seg2;
1960
1961
1962 if ( width_count )
1963 max_width = widths[width_count - 1].org;
1964 else
1965 max_width = 0;
1966
1967 /* a heuristic value to set up a minimum value for overlapping */
1968 len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
1969 if ( len_threshold == 0 )
1970 len_threshold = 1;
1971
1972 /* a heuristic value to weight lengths */
1973 len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
1974
1975 /* a heuristic value to weight distances (no call to */
1976 /* AF_LATIN_CONSTANT needed, since we work on multiples */
1977 /* of the stem width) */
1978 dist_score = 3000;
1979
1980 /* now compare each segment to the others */
1981 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1982 {
1983 if ( seg1->dir != axis->major_dir )
1984 continue;
1985
1986 /* search for stems having opposite directions, */
1987 /* with seg1 to the `left' of seg2 */
1988 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
1989 {
1990 FT_Pos pos1 = seg1->pos;
1991 FT_Pos pos2 = seg2->pos;
1992
1993
1994 if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
1995 {
1996 /* compute distance between the two segments */
1997 FT_Pos min = seg1->min_coord;
1998 FT_Pos max = seg1->max_coord;
1999 FT_Pos len;
2000
2001
2002 if ( min < seg2->min_coord )
2003 min = seg2->min_coord;
2004
2005 if ( max > seg2->max_coord )
2006 max = seg2->max_coord;
2007
2008 /* compute maximum coordinate difference of the two segments */
2009 /* (this is, how much they overlap) */
2010 len = max - min;
2011 if ( len >= len_threshold )
2012 {
2013 /*
2014 * The score is the sum of two demerits indicating the
2015 * `badness' of a fit, measured along the segments' main axis
2016 * and orthogonal to it, respectively.
2017 *
2018 * - The less overlapping along the main axis, the worse it
2019 * is, causing a larger demerit.
2020 *
2021 * - The nearer the orthogonal distance to a stem width, the
2022 * better it is, causing a smaller demerit. For simplicity,
2023 * however, we only increase the demerit for values that
2024 * exceed the largest stem width.
2025 */
2026
2027 FT_Pos dist = pos2 - pos1;
2028
2029 FT_Pos dist_demerit, score;
2030
2031
2032 if ( max_width )
2033 {
2034 /* distance demerits are based on multiples of `max_width'; */
2035 /* we scale by 1024 for getting more precision */
2036 FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 );
2037
2038
2039 if ( delta > 10000 )
2040 dist_demerit = 32000;
2041 else if ( delta > 0 )
2042 dist_demerit = delta * delta / dist_score;
2043 else
2044 dist_demerit = 0;
2045 }
2046 else
2047 dist_demerit = dist; /* default if no widths available */
2048
2049 score = dist_demerit + len_score / len;
2050
2051 /* and we search for the smallest score */
2052 if ( score < seg1->score )
2053 {
2054 seg1->score = score;
2055 seg1->link = seg2;
2056 }
2057
2058 if ( score < seg2->score )
2059 {
2060 seg2->score = score;
2061 seg2->link = seg1;
2062 }
2063 }
2064 }
2065 }
2066 }
2067
2068 /* now compute the `serif' segments, cf. explanations in `afhints.h' */
2069 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
2070 {
2071 seg2 = seg1->link;
2072
2073 if ( seg2 )
2074 {
2075 if ( seg2->link != seg1 )
2076 {
2077 seg1->link = 0;
2078 seg1->serif = seg2->link;
2079 }
2080 }
2081 }
2082 }
#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:324
FT_Pos score
Definition: afhints.h:279
#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 1067 of file aflatin.c.

1069 {
1070 FT_Bool started = 0, same_width = 1;
1071 FT_Fixed advance = 0, old_advance = 0;
1072
1073 /* If HarfBuzz is not available, we need a pointer to a single */
1074 /* unsigned long value. */
1075#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
1076 void* shaper_buf;
1077#else
1078 FT_ULong shaper_buf_;
1079 void* shaper_buf = &shaper_buf_;
1080#endif
1081
1082 /* in all supported charmaps, digits have character codes 0x30-0x39 */
1083 const char digits[] = "0 1 2 3 4 5 6 7 8 9";
1084 const char* p;
1085
1086
1087 p = digits;
1088
1089#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
1090 shaper_buf = af_shaper_buf_create( face );
1091#endif
1092
1093 while ( *p )
1094 {
1095 FT_ULong glyph_index;
1096 unsigned int num_idx;
1097
1098
1099 /* reject input that maps to more than a single glyph */
1100 p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx );
1101 if ( num_idx > 1 )
1102 continue;
1103
1104 glyph_index = af_shaper_get_elem( &metrics->root,
1105 shaper_buf,
1106 0,
1107 &advance,
1108 NULL );
1109 if ( !glyph_index )
1110 continue;
1111
1112 if ( started )
1113 {
1114 if ( advance != old_advance )
1115 {
1116 same_width = 0;
1117 break;
1118 }
1119 }
1120 else
1121 {
1122 old_advance = advance;
1123 started = 1;
1124 }
1125 }
1126
1127 af_shaper_buf_destroy( face, shaper_buf );
1128
1129 metrics->root.digits_have_same_width = same_width;
1130 }
_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:610
FT_ULong af_shaper_get_elem(AF_StyleMetrics metrics, void *buf_, unsigned int idx, FT_Long *advance, FT_Long *y_offset)
Definition: afshaper.c:646
void af_shaper_buf_destroy(FT_Face face, void *buf)
Definition: afshaper.c:601
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 1136 of file aflatin.c.

1138 {
1139 FT_CharMap oldmap = face->charmap;
1140
1141
1142 metrics->units_per_em = face->units_per_EM;
1143
1144 if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
1145 {
1149 }
1150
1151 FT_Set_Charmap( face, oldmap );
1152 return FT_Err_Ok;
1153 }
af_latin_metrics_init_widths(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:60
af_latin_metrics_check_digits(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:1067
static void af_latin_metrics_init_blues(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:336
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3501
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3544

◆ af_latin_metrics_init_widths()

af_latin_metrics_init_widths ( AF_LatinMetrics  metrics,
FT_Face  face 
)

Definition at line 60 of file aflatin.c.

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

Referenced by af_latin_metrics_init().

◆ af_latin_metrics_scale()

af_latin_metrics_scale ( AF_LatinMetrics  metrics,
AF_Scaler  scaler 
)

Definition at line 1482 of file aflatin.c.

1484 {
1485 metrics->root.scaler.render_mode = scaler->render_mode;
1486 metrics->root.scaler.face = scaler->face;
1487 metrics->root.scaler.flags = scaler->flags;
1488
1491 }
static void af_latin_metrics_scale_dim(AF_LatinMetrics metrics, AF_Scaler scaler, AF_Dimension dim)
Definition: aflatin.c:1160