ReactOS 0.4.16-dev-319-g6cf4263
afhints.c File Reference
#include "afhints.h"
#include "aferrors.h"
Include dependency graph for afhints.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FT_COMPONENT   trace_afhints
 

Functions

 af_axis_hints_new_segment (AF_AxisHints axis, FT_Memory memory, AF_Segment *asegment)
 
 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)
 
 af_direction_compute (FT_Pos dx, FT_Pos dy)
 
 af_glyph_hints_init (AF_GlyphHints hints, FT_Memory memory)
 
 af_glyph_hints_done (AF_GlyphHints hints)
 
 af_glyph_hints_rescale (AF_GlyphHints hints, AF_StyleMetrics metrics)
 
 af_glyph_hints_reload (AF_GlyphHints hints, FT_Outline *outline)
 
 af_glyph_hints_save (AF_GlyphHints hints, FT_Outline *outline)
 
 af_glyph_hints_align_edge_points (AF_GlyphHints hints, AF_Dimension dim)
 
 af_glyph_hints_align_strong_points (AF_GlyphHints hints, AF_Dimension dim)
 
static void af_iup_shift (AF_Point p1, AF_Point p2, AF_Point ref)
 
static void af_iup_interp (AF_Point p1, AF_Point p2, AF_Point ref1, AF_Point ref2)
 
 af_glyph_hints_align_weak_points (AF_GlyphHints hints, AF_Dimension dim)
 

Macro Definition Documentation

◆ FT_COMPONENT

#define FT_COMPONENT   trace_afhints

Definition at line 32 of file afhints.c.

Function Documentation

◆ af_axis_hints_new_edge()

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 at line 99 of file afhints.c.

105 {
107 AF_Edge edge = NULL;
108 AF_Edge edges;
109
110
111 if ( axis->num_edges < AF_EDGES_EMBEDDED )
112 {
113 if ( !axis->edges )
114 {
115 axis->edges = axis->embedded.edges;
117 }
118 }
119 else if ( axis->num_edges >= axis->max_edges )
120 {
121 FT_Int old_max = axis->max_edges;
122 FT_Int new_max = old_max;
123 FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );
124
125
126 if ( old_max >= big_max )
127 {
128 error = FT_THROW( Out_Of_Memory );
129 goto Exit;
130 }
131
132 new_max += ( new_max >> 2 ) + 4;
133 if ( new_max < old_max || new_max > big_max )
134 new_max = big_max;
135
136 if ( axis->edges == axis->embedded.edges )
137 {
138 if ( FT_NEW_ARRAY( axis->edges, new_max ) )
139 goto Exit;
140 ft_memcpy( axis->edges, axis->embedded.edges,
141 sizeof ( axis->embedded.edges ) );
142 }
143 else
144 {
145 if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
146 goto Exit;
147 }
148
149 axis->max_edges = new_max;
150 }
151
152 edges = axis->edges;
153 edge = edges + axis->num_edges;
154
155 while ( edge > edges )
156 {
157 if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
158 : ( edge[-1].fpos < fpos ) )
159 break;
160
161 /* we want the edge with same position and minor direction */
162 /* to appear before those in the major one in the list */
163 if ( edge[-1].fpos == fpos && dir == axis->major_dir )
164 break;
165
166 edge[0] = edge[-1];
167 edge--;
168 }
169
170 axis->num_edges++;
171
172 Exit:
173 *anedge = edge;
174 return error;
175 }
#define AF_EDGES_EMBEDDED
Definition: afhints.h:303
unsigned int dir
Definition: maze.c:112
#define NULL
Definition: types.h:112
return FT_Err_Ok
Definition: ftbbox.c:511
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
#define ft_memcpy
Definition: ftstdlib.h:82
#define FT_INT_MAX
Definition: ftstdlib.h:63
int FT_Error
Definition: fttypes.h:300
signed int FT_Int
Definition: fttypes.h:220
#define error(str)
Definition: mkdosfs.c:1605
static void Exit(void)
Definition: sock.c:1330
FT_Int num_edges
Definition: afhints.h:314
AF_Edge edges
Definition: afhints.h:316
AF_Direction major_dir
Definition: afhints.h:318
FT_Int max_edges
Definition: afhints.h:315
struct AF_AxisHintsRec_::@4234 embedded
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by af_latin_hints_compute_edges().

◆ af_axis_hints_new_segment()

af_axis_hints_new_segment ( AF_AxisHints  axis,
FT_Memory  memory,
AF_Segment asegment 
)

Definition at line 38 of file afhints.c.

41 {
43 AF_Segment segment = NULL;
44
45
47 {
48 if ( !axis->segments )
49 {
50 axis->segments = axis->embedded.segments;
52 }
53 }
54 else if ( axis->num_segments >= axis->max_segments )
55 {
56 FT_Int old_max = axis->max_segments;
57 FT_Int new_max = old_max;
58 FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );
59
60
61 if ( old_max >= big_max )
62 {
63 error = FT_THROW( Out_Of_Memory );
64 goto Exit;
65 }
66
67 new_max += ( new_max >> 2 ) + 4;
68 if ( new_max < old_max || new_max > big_max )
69 new_max = big_max;
70
71 if ( axis->segments == axis->embedded.segments )
72 {
73 if ( FT_NEW_ARRAY( axis->segments, new_max ) )
74 goto Exit;
75 ft_memcpy( axis->segments, axis->embedded.segments,
76 sizeof ( axis->embedded.segments ) );
77 }
78 else
79 {
80 if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
81 goto Exit;
82 }
83
84 axis->max_segments = new_max;
85 }
86
87 segment = axis->segments + axis->num_segments++;
88
89 Exit:
90 *asegment = segment;
91 return error;
92 }
#define AF_SEGMENTS_EMBEDDED
Definition: afhints.h:302
AF_Segment segments
Definition: afhints.h:309
FT_Int num_segments
Definition: afhints.h:307
FT_Int max_segments
Definition: afhints.h:308

Referenced by af_latin_hints_compute_segments().

◆ af_direction_compute()

af_direction_compute ( FT_Pos  dx,
FT_Pos  dy 
)

Definition at line 613 of file afhints.c.

615 {
616 FT_Pos ll, ss; /* long and short arm lengths */
617 AF_Direction dir; /* candidate direction */
618
619
620 if ( dy >= dx )
621 {
622 if ( dy >= -dx )
623 {
624 dir = AF_DIR_UP;
625 ll = dy;
626 ss = dx;
627 }
628 else
629 {
631 ll = -dx;
632 ss = dy;
633 }
634 }
635 else /* dy < dx */
636 {
637 if ( dy >= -dx )
638 {
640 ll = dx;
641 ss = dy;
642 }
643 else
644 {
646 ll = -dy;
647 ss = dx;
648 }
649 }
650
651 /* return no direction if arm lengths do not differ enough */
652 /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
653 /* the long arm is never negative */
654 if ( ll <= 14 * FT_ABS( ss ) )
656
657 return dir;
658 }
enum AF_Direction_ AF_Direction
@ AF_DIR_RIGHT
Definition: afhints.h:50
@ AF_DIR_DOWN
Definition: afhints.h:53
@ AF_DIR_UP
Definition: afhints.h:52
@ AF_DIR_LEFT
Definition: afhints.h:51
@ AF_DIR_NONE
Definition: afhints.h:49
w ll
Definition: byte_order.h:167
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_ABS(a)
Definition: ftobjs.h:74
#define ss
Definition: i386-dis.c:441
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97

Referenced by af_glyph_hints_reload().

◆ af_glyph_hints_align_edge_points()

af_glyph_hints_align_edge_points ( AF_GlyphHints  hints,
AF_Dimension  dim 
)

Definition at line 1181 of file afhints.c.

1183 {
1184 AF_AxisHints axis = & hints->axis[dim];
1185 AF_Segment segments = axis->segments;
1186 AF_Segment segment_limit = segments + axis->num_segments;
1187 AF_Segment seg;
1188
1189
1190 if ( dim == AF_DIMENSION_HORZ )
1191 {
1192 for ( seg = segments; seg < segment_limit; seg++ )
1193 {
1194 AF_Edge edge = seg->edge;
1196
1197
1198 if ( !edge )
1199 continue;
1200
1201 first = seg->first;
1202 last = seg->last;
1203 point = first;
1204 for (;;)
1205 {
1206 point->x = edge->pos;
1207 point->flags |= AF_FLAG_TOUCH_X;
1208
1209 if ( point == last )
1210 break;
1211
1212 point = point->next;
1213 }
1214 }
1215 }
1216 else
1217 {
1218 for ( seg = segments; seg < segment_limit; seg++ )
1219 {
1220 AF_Edge edge = seg->edge;
1222
1223
1224 if ( !edge )
1225 continue;
1226
1227 first = seg->first;
1228 last = seg->last;
1229 point = first;
1230 for (;;)
1231 {
1232 point->y = edge->pos;
1233 point->flags |= AF_FLAG_TOUCH_Y;
1234
1235 if ( point == last )
1236 break;
1237
1238 point = point->next;
1239 }
1240 }
1241 }
1242 }
#define AF_FLAG_TOUCH_Y
Definition: afhints.h:219
@ AF_DIMENSION_HORZ
Definition: afhints.h:35
#define AF_FLAG_TOUCH_X
Definition: afhints.h:218
POINTL point
Definition: edittest.c:50
const GLint * first
Definition: glext.h:5794
static UINT UINT last
Definition: font.c:45
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
FT_Pos pos
Definition: afhints.h:286
AF_Point last
Definition: afhints.h:277
AF_Point first
Definition: afhints.h:276
AF_Edge edge
Definition: afhints.h:268
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329

Referenced by af_latin_hints_apply().

◆ af_glyph_hints_align_strong_points()

af_glyph_hints_align_strong_points ( AF_GlyphHints  hints,
AF_Dimension  dim 
)

Definition at line 1256 of file afhints.c.

1258 {
1259 AF_Point points = hints->points;
1260 AF_Point point_limit = points + hints->num_points;
1261 AF_AxisHints axis = &hints->axis[dim];
1262 AF_Edge edges = axis->edges;
1263 AF_Edge edge_limit = edges + axis->num_edges;
1264 FT_UInt touch_flag;
1265
1266
1267 if ( dim == AF_DIMENSION_HORZ )
1268 touch_flag = AF_FLAG_TOUCH_X;
1269 else
1270 touch_flag = AF_FLAG_TOUCH_Y;
1271
1272 if ( edges < edge_limit )
1273 {
1275 AF_Edge edge;
1276
1277
1278 for ( point = points; point < point_limit; point++ )
1279 {
1280 FT_Pos u, ou, fu; /* point position */
1281 FT_Pos delta;
1282
1283
1284 if ( point->flags & touch_flag )
1285 continue;
1286
1287 /* if this point is candidate to weak interpolation, we */
1288 /* interpolate it after all strong points have been processed */
1289
1290 if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
1291 continue;
1292
1293 if ( dim == AF_DIMENSION_VERT )
1294 {
1295 u = point->fy;
1296 ou = point->oy;
1297 }
1298 else
1299 {
1300 u = point->fx;
1301 ou = point->ox;
1302 }
1303
1304 fu = u;
1305
1306 /* is the point before the first edge? */
1307 edge = edges;
1308 delta = edge->fpos - u;
1309 if ( delta >= 0 )
1310 {
1311 u = edge->pos - ( edge->opos - ou );
1312 goto Store_Point;
1313 }
1314
1315 /* is the point after the last edge? */
1316 edge = edge_limit - 1;
1317 delta = u - edge->fpos;
1318 if ( delta >= 0 )
1319 {
1320 u = edge->pos + ( ou - edge->opos );
1321 goto Store_Point;
1322 }
1323
1324 {
1325 FT_PtrDist min, max, mid;
1326 FT_Pos fpos;
1327
1328
1329 /* find enclosing edges */
1330 min = 0;
1331 max = edge_limit - edges;
1332
1333#if 1
1334 /* for a small number of edges, a linear search is better */
1335 if ( max <= 8 )
1336 {
1337 FT_PtrDist nn;
1338
1339
1340 for ( nn = 0; nn < max; nn++ )
1341 if ( edges[nn].fpos >= u )
1342 break;
1343
1344 if ( edges[nn].fpos == u )
1345 {
1346 u = edges[nn].pos;
1347 goto Store_Point;
1348 }
1349 min = nn;
1350 }
1351 else
1352#endif
1353 while ( min < max )
1354 {
1355 mid = ( max + min ) >> 1;
1356 edge = edges + mid;
1357 fpos = edge->fpos;
1358
1359 if ( u < fpos )
1360 max = mid;
1361 else if ( u > fpos )
1362 min = mid + 1;
1363 else
1364 {
1365 /* we are on the edge */
1366 u = edge->pos;
1367 goto Store_Point;
1368 }
1369 }
1370
1371 /* point is not on an edge */
1372 {
1373 AF_Edge before = edges + min - 1;
1374 AF_Edge after = edges + min + 0;
1375
1376
1377 /* assert( before && after && before != after ) */
1378 if ( before->scale == 0 )
1379 before->scale = FT_DivFix( after->pos - before->pos,
1380 after->fpos - before->fpos );
1381
1382 u = before->pos + FT_MulFix( fu - before->fpos,
1383 before->scale );
1384 }
1385 }
1386
1387 Store_Point:
1388 /* save the point position */
1389 if ( dim == AF_DIMENSION_HORZ )
1390 point->x = u;
1391 else
1392 point->y = u;
1393
1394 point->flags |= touch_flag;
1395 }
1396 }
1397 }
@ AF_DIMENSION_VERT
Definition: afhints.h:37
#define AF_FLAG_WEAK_INTERPOLATION
Definition: afhints.h:222
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:337
unsigned int FT_UInt
Definition: fttypes.h:231
GLsizei const GLfloat * points
Definition: glext.h:8112
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
#define min(a, b)
Definition: monoChain.cc:55
FT_Short fpos
Definition: afhints.h:284
FT_Pos opos
Definition: afhints.h:285
#define max(a, b)
Definition: svc.c:63
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2395

Referenced by af_latin_hints_apply().

◆ af_glyph_hints_align_weak_points()

af_glyph_hints_align_weak_points ( AF_GlyphHints  hints,
AF_Dimension  dim 
)

Definition at line 1507 of file afhints.c.

1509 {
1510 AF_Point points = hints->points;
1511 AF_Point point_limit = points + hints->num_points;
1512 AF_Point* contour = hints->contours;
1513 AF_Point* contour_limit = contour + hints->num_contours;
1514 FT_UInt touch_flag;
1516 AF_Point end_point;
1517 AF_Point first_point;
1518
1519
1520 /* PASS 1: Move segment points to edge positions */
1521
1522 if ( dim == AF_DIMENSION_HORZ )
1523 {
1524 touch_flag = AF_FLAG_TOUCH_X;
1525
1526 for ( point = points; point < point_limit; point++ )
1527 {
1528 point->u = point->x;
1529 point->v = point->ox;
1530 }
1531 }
1532 else
1533 {
1534 touch_flag = AF_FLAG_TOUCH_Y;
1535
1536 for ( point = points; point < point_limit; point++ )
1537 {
1538 point->u = point->y;
1539 point->v = point->oy;
1540 }
1541 }
1542
1543 for ( ; contour < contour_limit; contour++ )
1544 {
1545 AF_Point first_touched, last_touched;
1546
1547
1548 point = *contour;
1549 end_point = point->prev;
1550 first_point = point;
1551
1552 /* find first touched point */
1553 for (;;)
1554 {
1555 if ( point > end_point ) /* no touched point in contour */
1556 goto NextContour;
1557
1558 if ( point->flags & touch_flag )
1559 break;
1560
1561 point++;
1562 }
1563
1564 first_touched = point;
1565
1566 for (;;)
1567 {
1568 FT_ASSERT( point <= end_point &&
1569 ( point->flags & touch_flag ) != 0 );
1570
1571 /* skip any touched neighbours */
1572 while ( point < end_point &&
1573 ( point[1].flags & touch_flag ) != 0 )
1574 point++;
1575
1576 last_touched = point;
1577
1578 /* find the next touched point, if any */
1579 point++;
1580 for (;;)
1581 {
1582 if ( point > end_point )
1583 goto EndContour;
1584
1585 if ( ( point->flags & touch_flag ) != 0 )
1586 break;
1587
1588 point++;
1589 }
1590
1591 /* interpolate between last_touched and point */
1592 af_iup_interp( last_touched + 1, point - 1,
1593 last_touched, point );
1594 }
1595
1596 EndContour:
1597 /* special case: only one point was touched */
1598 if ( last_touched == first_touched )
1599 af_iup_shift( first_point, end_point, first_touched );
1600
1601 else /* interpolate the last part */
1602 {
1603 if ( last_touched < end_point )
1604 af_iup_interp( last_touched + 1, end_point,
1605 last_touched, first_touched );
1606
1607 if ( first_touched > points )
1608 af_iup_interp( first_point, first_touched - 1,
1609 last_touched, first_touched );
1610 }
1611
1612 NextContour:
1613 ;
1614 }
1615
1616 /* now save the interpolated values back to x/y */
1617 if ( dim == AF_DIMENSION_HORZ )
1618 {
1619 for ( point = points; point < point_limit; point++ )
1620 point->x = point->u;
1621 }
1622 else
1623 {
1624 for ( point = points; point < point_limit; point++ )
1625 point->y = point->u;
1626 }
1627 }
static void af_iup_interp(AF_Point p1, AF_Point p2, AF_Point ref1, AF_Point ref2)
Definition: afhints.c:1439
static void af_iup_shift(AF_Point p1, AF_Point p2, AF_Point ref)
Definition: afhints.c:1412
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
GLbitfield flags
Definition: glext.h:7161

Referenced by af_latin_hints_apply().

◆ af_glyph_hints_done()

af_glyph_hints_done ( AF_GlyphHints  hints)

Definition at line 672 of file afhints.c.

673 {
675 int dim;
676
677
678 if ( !( hints && hints->memory ) )
679 return;
680
681 memory = hints->memory;
682
683 /*
684 * note that we don't need to free the segment and edge
685 * buffers since they are really within the hints->points array
686 */
687 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
688 {
689 AF_AxisHints axis = &hints->axis[dim];
690
691
692 axis->num_segments = 0;
693 axis->max_segments = 0;
694 if ( axis->segments != axis->embedded.segments )
695 FT_FREE( axis->segments );
696
697 axis->num_edges = 0;
698 axis->max_edges = 0;
699 if ( axis->edges != axis->embedded.edges )
700 FT_FREE( axis->edges );
701 }
702
703 if ( hints->contours != hints->embedded.contours )
704 FT_FREE( hints->contours );
705 hints->max_contours = 0;
706 hints->num_contours = 0;
707
708 if ( hints->points != hints->embedded.points )
709 FT_FREE( hints->points );
710 hints->max_points = 0;
711 hints->num_points = 0;
712
713 hints->memory = NULL;
714 }
@ AF_DIMENSION_MAX
Definition: afhints.h:40
#define FT_FREE(ptr)
Definition: ftmemory.h:329
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
static char memory[1024 *256]
Definition: process.c:116

Referenced by af_autofitter_done(), af_autofitter_load_glyph(), and af_latin_metrics_init_widths().

◆ af_glyph_hints_init()

af_glyph_hints_init ( AF_GlyphHints  hints,
FT_Memory  memory 
)

Definition at line 662 of file afhints.c.

664 {
665 /* no need to initialize the embedded items */
666 FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
667 hints->memory = memory;
668 }
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235

Referenced by af_autofitter_load_glyph(), and af_latin_metrics_init_widths().

◆ af_glyph_hints_reload()

af_glyph_hints_reload ( AF_GlyphHints  hints,
FT_Outline outline 
)

Definition at line 732 of file afhints.c.

734 {
737 FT_UInt old_max, new_max;
738 FT_Fixed x_scale = hints->x_scale;
739 FT_Fixed y_scale = hints->y_scale;
740 FT_Pos x_delta = hints->x_delta;
741 FT_Pos y_delta = hints->y_delta;
742 FT_Memory memory = hints->memory;
743
744
745 hints->num_points = 0;
746 hints->num_contours = 0;
747
748 hints->axis[0].num_segments = 0;
749 hints->axis[0].num_edges = 0;
750 hints->axis[1].num_segments = 0;
751 hints->axis[1].num_edges = 0;
752
753 /* first of all, reallocate the contours array if necessary */
754 new_max = (FT_UInt)outline->n_contours;
755 old_max = (FT_UInt)hints->max_contours;
756
757 if ( new_max <= AF_CONTOURS_EMBEDDED )
758 {
759 if ( !hints->contours )
760 {
761 hints->contours = hints->embedded.contours;
762 hints->max_contours = AF_CONTOURS_EMBEDDED;
763 }
764 }
765 else if ( new_max > old_max )
766 {
767 if ( hints->contours == hints->embedded.contours )
768 hints->contours = NULL;
769
770 new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */
771
772 if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
773 goto Exit;
774
775 hints->max_contours = (FT_Int)new_max;
776 }
777
778 /*
779 * then reallocate the points arrays if necessary --
780 * note that we reserve two additional point positions, used to
781 * hint metrics appropriately
782 */
783 new_max = (FT_UInt)( outline->n_points + 2 );
784 old_max = (FT_UInt)hints->max_points;
785
786 if ( new_max <= AF_POINTS_EMBEDDED )
787 {
788 if ( !hints->points )
789 {
790 hints->points = hints->embedded.points;
791 hints->max_points = AF_POINTS_EMBEDDED;
792 }
793 }
794 else if ( new_max > old_max )
795 {
796 if ( hints->points == hints->embedded.points )
797 hints->points = NULL;
798
799 new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */
800
801 if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
802 goto Exit;
803
804 hints->max_points = (FT_Int)new_max;
805 }
806
807 hints->num_points = outline->n_points;
808 hints->num_contours = outline->n_contours;
809
810 /* We can't rely on the value of `FT_Outline.flags' to know the fill */
811 /* direction used for a glyph, given that some fonts are broken (e.g., */
812 /* the Arphic ones). We thus recompute it each time we need to. */
813 /* */
814 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
815 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;
816
818 {
819 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
820 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
821 }
822
823 hints->x_scale = x_scale;
824 hints->y_scale = y_scale;
825 hints->x_delta = x_delta;
826 hints->y_delta = y_delta;
827
828 hints->xmin_delta = 0;
829 hints->xmax_delta = 0;
830
831 points = hints->points;
832 if ( hints->num_points == 0 )
833 goto Exit;
834
835 {
837 AF_Point point_limit = points + hints->num_points;
838
839 /* value 20 in `near_limit' is heuristic */
840 FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM;
841 FT_Int near_limit = 20 * units_per_em / 2048;
842
843
844 /* compute coordinates & Bezier flags, next and prev */
845 {
846 FT_Vector* vec = outline->points;
847 char* tag = outline->tags;
848 FT_Short endpoint = outline->contours[0];
850 AF_Point prev = end;
851 FT_Int contour_index = 0;
852
853
854 for ( point = points; point < point_limit; point++, vec++, tag++ )
855 {
856 FT_Pos out_x, out_y;
857
858
859 point->in_dir = (FT_Char)AF_DIR_NONE;
860 point->out_dir = (FT_Char)AF_DIR_NONE;
861
862 point->fx = (FT_Short)vec->x;
863 point->fy = (FT_Short)vec->y;
864 point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
865 point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
866
867 end->fx = (FT_Short)outline->points[endpoint].x;
868 end->fy = (FT_Short)outline->points[endpoint].y;
869
870 switch ( FT_CURVE_TAG( *tag ) )
871 {
873 point->flags = AF_FLAG_CONIC;
874 break;
876 point->flags = AF_FLAG_CUBIC;
877 break;
878 default:
879 point->flags = AF_FLAG_NONE;
880 }
881
882 out_x = point->fx - prev->fx;
883 out_y = point->fy - prev->fy;
884
885 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
886 prev->flags |= AF_FLAG_NEAR;
887
888 point->prev = prev;
889 prev->next = point;
890 prev = point;
891
892 if ( point == end )
893 {
894 if ( ++contour_index < outline->n_contours )
895 {
896 endpoint = outline->contours[contour_index];
897 end = points + endpoint;
898 prev = end;
899 }
900 }
901 }
902 }
903
904 /* set up the contours array */
905 {
906 AF_Point* contour = hints->contours;
907 AF_Point* contour_limit = contour + hints->num_contours;
908 short* end = outline->contours;
909 short idx = 0;
910
911
912 for ( ; contour < contour_limit; contour++, end++ )
913 {
914 contour[0] = points + idx;
915 idx = (short)( end[0] + 1 );
916 }
917 }
918
919 {
920 /*
921 * Compute directions of `in' and `out' vectors.
922 *
923 * Note that distances between points that are very near to each
924 * other are accumulated. In other words, the auto-hinter either
925 * prepends the small vectors between near points to the first
926 * non-near vector, or the sum of small vector lengths exceeds a
927 * threshold, thus `grouping' the small vectors. All intermediate
928 * points are tagged as weak; the directions are adjusted also to
929 * be equal to the accumulated one.
930 */
931
932 FT_Int near_limit2 = 2 * near_limit - 1;
933
934 AF_Point* contour;
935 AF_Point* contour_limit = hints->contours + hints->num_contours;
936
937
938 for ( contour = hints->contours; contour < contour_limit; contour++ )
939 {
940 AF_Point first = *contour;
941 AF_Point next, prev, curr;
942
943 FT_Pos out_x, out_y;
944
945
946 /* since the first point of a contour could be part of a */
947 /* series of near points, go backwards to find the first */
948 /* non-near point and adjust `first' */
949
950 point = first;
951 prev = first->prev;
952
953 while ( prev != first )
954 {
955 out_x = point->fx - prev->fx;
956 out_y = point->fy - prev->fy;
957
958 /*
959 * We use Taxicab metrics to measure the vector length.
960 *
961 * Note that the accumulated distances so far could have the
962 * opposite direction of the distance measured here. For this
963 * reason we use `near_limit2' for the comparison to get a
964 * non-near point even in the worst case.
965 */
966 if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
967 break;
968
969 point = prev;
970 prev = prev->prev;
971 }
972
973 /* adjust first point */
974 first = point;
975
976 /* now loop over all points of the contour to get */
977 /* `in' and `out' vector directions */
978
979 curr = first;
980
981 /*
982 * We abuse the `u' and `v' fields to store index deltas to the
983 * next and previous non-near point, respectively.
984 *
985 * To avoid problems with not having non-near points, we point to
986 * `first' by default as the next non-near point.
987 *
988 */
989 curr->u = (FT_Pos)( first - curr );
990 first->v = -curr->u;
991
992 out_x = 0;
993 out_y = 0;
994
995 next = first;
996 do
997 {
998 AF_Direction out_dir;
999
1000
1001 point = next;
1002 next = point->next;
1003
1004 out_x += next->fx - point->fx;
1005 out_y += next->fy - point->fy;
1006
1007 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
1008 {
1010 continue;
1011 }
1012
1013 curr->u = (FT_Pos)( next - curr );
1014 next->v = -curr->u;
1015
1016 out_dir = af_direction_compute( out_x, out_y );
1017
1018 /* adjust directions for all points inbetween; */
1019 /* the loop also updates position of `curr' */
1020 curr->out_dir = (FT_Char)out_dir;
1021 for ( curr = curr->next; curr != next; curr = curr->next )
1022 {
1023 curr->in_dir = (FT_Char)out_dir;
1024 curr->out_dir = (FT_Char)out_dir;
1025 }
1026 next->in_dir = (FT_Char)out_dir;
1027
1028 curr->u = (FT_Pos)( first - curr );
1029 first->v = -curr->u;
1030
1031 out_x = 0;
1032 out_y = 0;
1033
1034 } while ( next != first );
1035 }
1036
1037 /*
1038 * The next step is to `simplify' an outline's topology so that we
1039 * can identify local extrema more reliably: A series of
1040 * non-horizontal or non-vertical vectors pointing into the same
1041 * quadrant are handled as a single, long vector. From a
1042 * topological point of the view, the intermediate points are of no
1043 * interest and thus tagged as weak.
1044 */
1045
1046 for ( point = points; point < point_limit; point++ )
1047 {
1048 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1049 continue;
1050
1051 if ( point->in_dir == AF_DIR_NONE &&
1052 point->out_dir == AF_DIR_NONE )
1053 {
1054 /* check whether both vectors point into the same quadrant */
1055
1056 FT_Pos in_x, in_y;
1057 FT_Pos out_x, out_y;
1058
1059 AF_Point next_u = point + point->u;
1060 AF_Point prev_v = point + point->v;
1061
1062
1063 in_x = point->fx - prev_v->fx;
1064 in_y = point->fy - prev_v->fy;
1065
1066 out_x = next_u->fx - point->fx;
1067 out_y = next_u->fy - point->fy;
1068
1069 if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
1070 {
1071 /* yes, so tag current point as weak */
1072 /* and update index deltas */
1073
1075
1076 prev_v->u = (FT_Pos)( next_u - prev_v );
1077 next_u->v = -prev_v->u;
1078 }
1079 }
1080 }
1081
1082 /*
1083 * Finally, check for remaining weak points. Everything else not
1084 * collected in edges so far is then implicitly classified as strong
1085 * points.
1086 */
1087
1088 for ( point = points; point < point_limit; point++ )
1089 {
1090 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1091 continue;
1092
1093 if ( point->flags & AF_FLAG_CONTROL )
1094 {
1095 /* control points are always weak */
1096 Is_Weak_Point:
1098 }
1099 else if ( point->out_dir == point->in_dir )
1100 {
1101 if ( point->out_dir != AF_DIR_NONE )
1102 {
1103 /* current point lies on a horizontal or */
1104 /* vertical segment (but doesn't start or end it) */
1105 goto Is_Weak_Point;
1106 }
1107
1108 {
1109 AF_Point next_u = point + point->u;
1110 AF_Point prev_v = point + point->v;
1111
1112
1113 if ( ft_corner_is_flat( point->fx - prev_v->fx,
1114 point->fy - prev_v->fy,
1115 next_u->fx - point->fx,
1116 next_u->fy - point->fy ) )
1117 {
1118 /* either the `in' or the `out' vector is much more */
1119 /* dominant than the other one, so tag current point */
1120 /* as weak and update index deltas */
1121
1122 prev_v->u = (FT_Pos)( next_u - prev_v );
1123 next_u->v = -prev_v->u;
1124
1125 goto Is_Weak_Point;
1126 }
1127 }
1128 }
1129 else if ( point->in_dir == -point->out_dir )
1130 {
1131 /* current point forms a spike */
1132 goto Is_Weak_Point;
1133 }
1134 }
1135 }
1136 }
1137
1138 Exit:
1139 return error;
1140 }
af_direction_compute(FT_Pos dx, FT_Pos dy)
Definition: afhints.c:613
#define AF_CONTOURS_EMBEDDED
Definition: afhints.h:332
#define AF_FLAG_NEAR
Definition: afhints.h:225
#define AF_FLAG_NONE
Definition: afhints.h:210
#define AF_FLAG_CONIC
Definition: afhints.h:213
#define AF_FLAG_CUBIC
Definition: afhints.h:214
#define AF_FLAG_CONTROL
Definition: afhints.h:215
#define AF_POINTS_EMBEDDED
Definition: afhints.h:331
unsigned int idx
Definition: utils.c:41
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
FT_Vector * vec
Definition: ftbbox.c:448
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:975
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:455
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:454
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:451
@ FT_ORIENTATION_POSTSCRIPT
Definition: ftoutln.h:534
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1044
signed char FT_Char
Definition: fttypes.h:143
signed long FT_Fixed
Definition: fttypes.h:288
signed short FT_Short
Definition: fttypes.h:198
GLuint GLuint end
Definition: gl.h:1545
if(dx< 0)
Definition: linetemp.h:194
static unsigned __int64 next
Definition: rand_nt.c:6
AF_Point prev
Definition: afhints.h:253
FT_Char in_dir
Definition: afhints.h:244
AF_Point next
Definition: afhints.h:252
FT_Short fy
Definition: afhints.h:248
FT_Pos u
Definition: afhints.h:250
FT_Pos v
Definition: afhints.h:250
FT_Char out_dir
Definition: afhints.h:245
FT_Short fx
Definition: afhints.h:248
FT_UShort flags
Definition: afhints.h:243
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
Definition: nis.h:10
Definition: mesh.c:5330
Definition: ecma_167.h:138

Referenced by af_dummy_hints_apply(), af_latin_hints_apply(), and af_latin_metrics_init_widths().

◆ af_glyph_hints_rescale()

af_glyph_hints_rescale ( AF_GlyphHints  hints,
AF_StyleMetrics  metrics 
)

Definition at line 720 of file afhints.c.

722 {
723 hints->metrics = metrics;
724 hints->scaler_flags = metrics->scaler.flags;
725 }
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745

Referenced by af_dummy_hints_init(), af_latin_hints_init(), and af_latin_metrics_init_widths().

◆ af_glyph_hints_save()

af_glyph_hints_save ( AF_GlyphHints  hints,
FT_Outline outline 
)

Definition at line 1146 of file afhints.c.

1148 {
1149 AF_Point point = hints->points;
1150 AF_Point limit = point + hints->num_points;
1151 FT_Vector* vec = outline->points;
1152 char* tag = outline->tags;
1153
1154
1155 for ( ; point < limit; point++, vec++, tag++ )
1156 {
1157 vec->x = point->x;
1158 vec->y = point->y;
1159
1160 if ( point->flags & AF_FLAG_CONIC )
1162 else if ( point->flags & AF_FLAG_CUBIC )
1164 else
1165 tag[0] = FT_CURVE_TAG_ON;
1166 }
1167 }
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
GLint limit
Definition: glext.h:10326

Referenced by af_dummy_hints_apply(), and af_latin_hints_apply().

◆ af_iup_interp()

static void af_iup_interp ( AF_Point  p1,
AF_Point  p2,
AF_Point  ref1,
AF_Point  ref2 
)
static

Definition at line 1439 of file afhints.c.

1443 {
1444 AF_Point p;
1445 FT_Pos u, v1, v2, u1, u2, d1, d2;
1446
1447
1448 if ( p1 > p2 )
1449 return;
1450
1451 if ( ref1->v > ref2->v )
1452 {
1453 p = ref1;
1454 ref1 = ref2;
1455 ref2 = p;
1456 }
1457
1458 v1 = ref1->v;
1459 v2 = ref2->v;
1460 u1 = ref1->u;
1461 u2 = ref2->u;
1462 d1 = u1 - v1;
1463 d2 = u2 - v2;
1464
1465 if ( u1 == u2 || v1 == v2 )
1466 {
1467 for ( p = p1; p <= p2; p++ )
1468 {
1469 u = p->v;
1470
1471 if ( u <= v1 )
1472 u += d1;
1473 else if ( u >= v2 )
1474 u += d2;
1475 else
1476 u = u1;
1477
1478 p->u = u;
1479 }
1480 }
1481 else
1482 {
1483 FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 );
1484
1485
1486 for ( p = p1; p <= p2; p++ )
1487 {
1488 u = p->v;
1489
1490 if ( u <= v1 )
1491 u += d1;
1492 else if ( u >= v2 )
1493 u += d2;
1494 else
1495 u = u1 + FT_MulFix( u - v1, scale );
1496
1497 p->u = u;
1498 }
1499 }
1500 }
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLdouble GLdouble u2
Definition: glext.h:8308
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLdouble u1
Definition: glext.h:8308

Referenced by af_glyph_hints_align_weak_points().

◆ af_iup_shift()

static void af_iup_shift ( AF_Point  p1,
AF_Point  p2,
AF_Point  ref 
)
static

Definition at line 1412 of file afhints.c.

1415 {
1416 AF_Point p;
1417 FT_Pos delta = ref->u - ref->v;
1418
1419
1420 if ( delta == 0 )
1421 return;
1422
1423 for ( p = p1; p < ref; p++ )
1424 p->u = p->v + delta;
1425
1426 for ( p = ref + 1; p <= p2; p++ )
1427 p->u = p->v + delta;
1428 }
#define for
Definition: utility.h:88
Definition: send.c:48

Referenced by af_glyph_hints_align_weak_points().