ReactOS 0.4.16-dev-2358-g0df3463
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 2121 of file aflatin.c.

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

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

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

2477 {
2479
2480
2482 if ( !error )
2483 {
2484 af_latin_hints_link_segments( hints, width_count, widths, dim );
2485
2487 }
2488
2489 return error;
2490 }
af_latin_hints_link_segments(AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
Definition: aflatin.c:1983
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:1555
af_latin_hints_compute_edges(AF_GlyphHints hints, AF_Dimension dim)
Definition: aflatin.c:2121

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

1987 {
1988 AF_AxisHints axis = &hints->axis[dim];
1989 AF_Segment segments = axis->segments;
1990 AF_Segment segment_limit = segments + axis->num_segments;
1991 FT_Pos len_threshold, len_score, dist_score, max_width;
1992 AF_Segment seg1, seg2;
1993
1994
1995 if ( width_count )
1996 max_width = widths[width_count - 1].org;
1997 else
1998 max_width = 0;
1999
2000 /* a heuristic value to set up a minimum value for overlapping */
2001 len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
2002 if ( len_threshold == 0 )
2003 len_threshold = 1;
2004
2005 /* a heuristic value to weight lengths */
2006 len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
2007
2008 /* a heuristic value to weight distances (no call to */
2009 /* AF_LATIN_CONSTANT needed, since we work on multiples */
2010 /* of the stem width) */
2011 dist_score = 3000;
2012
2013 /* now compare each segment to the others */
2014 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
2015 {
2016 if ( seg1->dir != axis->major_dir )
2017 continue;
2018
2019 /* search for stems having opposite directions, */
2020 /* with seg1 to the `left' of seg2 */
2021 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
2022 {
2023 FT_Pos pos1 = seg1->pos;
2024 FT_Pos pos2 = seg2->pos;
2025
2026
2027 if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
2028 {
2029 /* compute distance between the two segments */
2030 FT_Pos min = seg1->min_coord;
2031 FT_Pos max = seg1->max_coord;
2032 FT_Pos len;
2033
2034
2035 if ( min < seg2->min_coord )
2036 min = seg2->min_coord;
2037
2038 if ( max > seg2->max_coord )
2039 max = seg2->max_coord;
2040
2041 /* compute maximum coordinate difference of the two segments */
2042 /* (this is, how much they overlap) */
2043 len = max - min;
2044 if ( len >= len_threshold )
2045 {
2046 /*
2047 * The score is the sum of two demerits indicating the
2048 * `badness' of a fit, measured along the segments' main axis
2049 * and orthogonal to it, respectively.
2050 *
2051 * - The less overlapping along the main axis, the worse it
2052 * is, causing a larger demerit.
2053 *
2054 * - The nearer the orthogonal distance to a stem width, the
2055 * better it is, causing a smaller demerit. For simplicity,
2056 * however, we only increase the demerit for values that
2057 * exceed the largest stem width.
2058 */
2059
2060 FT_Pos dist = pos2 - pos1;
2061
2062 FT_Pos dist_demerit, score;
2063
2064
2065 if ( max_width )
2066 {
2067 /* distance demerits are based on multiples of `max_width'; */
2068 /* we scale by 1024 for getting more precision */
2069 FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 );
2070
2071
2072 if ( delta > 10000 )
2073 dist_demerit = 32000;
2074 else if ( delta > 0 )
2075 dist_demerit = delta * delta / dist_score;
2076 else
2077 dist_demerit = 0;
2078 }
2079 else
2080 dist_demerit = dist; /* default if no widths available */
2081
2082 score = dist_demerit + len_score / len;
2083
2084 /* and we search for the smallest score */
2085 if ( score < seg1->score )
2086 {
2087 seg1->score = score;
2088 seg1->link = seg2;
2089 }
2090
2091 if ( score < seg2->score )
2092 {
2093 seg2->score = score;
2094 seg2->link = seg1;
2095 }
2096 }
2097 }
2098 }
2099 }
2100
2101 /* now compute the `serif' segments, cf. explanations in `afhints.h' */
2102 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
2103 {
2104 seg2 = seg1->link;
2105
2106 if ( seg2 )
2107 {
2108 if ( seg2->link != seg1 )
2109 {
2110 seg1->link = 0;
2111 seg1->serif = seg2->link;
2112 }
2113 }
2114 }
2115 }
#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 1092 of file aflatin.c.

1094 {
1095 FT_Bool started = 0, same_width = 1;
1096 FT_Fixed advance = 0, old_advance = 0;
1097
1098 /* If HarfBuzz is not available, we need a pointer to a single */
1099 /* unsigned long value. */
1100#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
1101 void* shaper_buf;
1102#else
1103 FT_ULong shaper_buf_;
1104 void* shaper_buf = &shaper_buf_;
1105#endif
1106
1107 /* in all supported charmaps, digits have character codes 0x30-0x39 */
1108 const char digits[] = "0 1 2 3 4 5 6 7 8 9";
1109 const char* p;
1110
1111
1112 p = digits;
1113
1114#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
1115 shaper_buf = af_shaper_buf_create( face );
1116#endif
1117
1118 while ( *p )
1119 {
1120 FT_ULong glyph_index;
1121 unsigned int num_idx;
1122
1123
1124 /* reject input that maps to more than a single glyph */
1125 p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx );
1126 if ( num_idx > 1 )
1127 continue;
1128
1129 glyph_index = af_shaper_get_elem( &metrics->root,
1130 shaper_buf,
1131 0,
1132 &advance,
1133 NULL );
1134 if ( !glyph_index )
1135 continue;
1136
1137 if ( started )
1138 {
1139 if ( advance != old_advance )
1140 {
1141 same_width = 0;
1142 break;
1143 }
1144 }
1145 else
1146 {
1147 old_advance = advance;
1148 started = 1;
1149 }
1150 }
1151
1152 af_shaper_buf_destroy( face, shaper_buf );
1153
1154 metrics->root.digits_have_same_width = same_width;
1155 }
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
void * af_shaper_buf_create(FT_Face face)
Definition: afshaper.c:591
const char * af_shaper_get_cluster(const char *p, AF_StyleMetrics metrics, void *buf_, unsigned int *count)
Definition: afshaper.c:609
FT_ULong af_shaper_get_elem(AF_StyleMetrics metrics, void *buf_, unsigned int idx, FT_Long *advance, FT_Long *y_offset)
Definition: afshaper.c:645
void af_shaper_buf_destroy(FT_Face face, void *buf)
Definition: afshaper.c:600
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 1161 of file aflatin.c.

1163 {
1165
1166 FT_CharMap oldmap = face->charmap;
1167
1168
1169 metrics->units_per_em = face->units_per_EM;
1170
1171 if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
1172 {
1175 {
1176 /* use internal error code to indicate missing blue zones */
1177 error = -1;
1178 goto Exit;
1179 }
1181 }
1182
1183 Exit:
1184 FT_Set_Charmap( face, oldmap );
1185 return error;
1186 }
static int af_latin_metrics_init_blues(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:337
af_latin_metrics_init_widths(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:59
af_latin_metrics_check_digits(AF_LatinMetrics metrics, FT_Face face)
Definition: aflatin.c:1092
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3521
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3564

◆ af_latin_metrics_init_widths()

af_latin_metrics_init_widths ( AF_LatinMetrics  metrics,
FT_Face  face 
)

Definition at line 59 of file aflatin.c.

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

Referenced by af_latin_metrics_init().

◆ af_latin_metrics_scale()

af_latin_metrics_scale ( AF_LatinMetrics  metrics,
AF_Scaler  scaler 
)

Definition at line 1515 of file aflatin.c.

1517 {
1518 metrics->root.scaler.render_mode = scaler->render_mode;
1519 metrics->root.scaler.face = scaler->face;
1520 metrics->root.scaler.flags = scaler->flags;
1521
1524 }
static void af_latin_metrics_scale_dim(AF_LatinMetrics metrics, AF_Scaler scaler, AF_Dimension dim)
Definition: aflatin.c:1193