ReactOS 0.4.15-dev-7924-g5949c20
pshalgo.c File Reference
#include <ft2build.h>
#include "pshalgo.h"
#include "pshnterr.h"
Include dependency graph for pshalgo.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_pshalgo
 
#define COMPUTE_INFLEXS   /* compute inflection points to optimize `S' */
 
#define xxDEBUG_ZONES
 
#define psh_corner_is_flat   ft_corner_is_flat
 
#define psh_corner_orientation   ft_corner_orientation
 
#define PSH_STRONG_THRESHOLD   32
 
#define PSH_STRONG_THRESHOLD_MAXIMUM   30
 
#define PSH_MAX_STRONG_INTERNAL   16
 

Functions

static FT_Int psh_hint_overlap (PSH_Hint hint1, PSH_Hint hint2)
 
static void psh_hint_table_done (PSH_Hint_Table table, FT_Memory memory)
 
static void psh_hint_table_deactivate (PSH_Hint_Table table)
 
static void psh_hint_table_record (PSH_Hint_Table table, FT_UInt idx)
 
static void psh_hint_table_record_mask (PSH_Hint_Table table, PS_Mask hint_mask)
 
static FT_Error psh_hint_table_init (PSH_Hint_Table table, PS_Hint_Table hints, PS_Mask_Table hint_masks, PS_Mask_Table counter_masks, FT_Memory memory)
 
static void psh_hint_table_activate_mask (PSH_Hint_Table table, PS_Mask hint_mask)
 
static FT_Pos psh_dimension_quantize_len (PSH_Dimension dim, FT_Pos len, FT_Bool do_snapping)
 
static FT_Fixed psh_hint_snap_stem_side_delta (FT_Fixed pos, FT_Fixed len)
 
static void psh_hint_align (PSH_Hint hint, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
 
static void psh_hint_table_align_hints (PSH_Hint_Table table, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
 
static void psh_glyph_compute_inflections (PSH_Glyph glyph)
 
static void psh_glyph_done (PSH_Glyph glyph)
 
static int psh_compute_dir (FT_Pos dx, FT_Pos dy)
 
static void psh_glyph_load_points (PSH_Glyph glyph, FT_Int dimension)
 
static void psh_glyph_save_points (PSH_Glyph glyph, FT_Int dimension)
 
static FT_Error psh_glyph_init (PSH_Glyph glyph, FT_Outline *outline, PS_Hints ps_hints, PSH_Globals globals)
 
static void psh_glyph_compute_extrema (PSH_Glyph glyph)
 
static void psh_hint_table_find_strong_points (PSH_Hint_Table table, PSH_Point point, FT_UInt count, FT_Int threshold, FT_Int major_dir)
 
static void psh_glyph_find_strong_points (PSH_Glyph glyph, FT_Int dimension)
 
static void psh_glyph_find_blue_points (PSH_Blues blues, PSH_Glyph glyph)
 
static void psh_glyph_interpolate_strong_points (PSH_Glyph glyph, FT_Int dimension)
 
static void psh_glyph_interpolate_normal_points (PSH_Glyph glyph, FT_Int dimension)
 
static void psh_glyph_interpolate_other_points (PSH_Glyph glyph, FT_Int dimension)
 
FT_Error ps_hints_apply (PS_Hints ps_hints, FT_Outline *outline, PSH_Globals globals, FT_Render_Mode hint_mode)
 

Macro Definition Documentation

◆ COMPUTE_INFLEXS

#define COMPUTE_INFLEXS   /* compute inflection points to optimize `S' */

Definition at line 39 of file pshalgo.c.

◆ FT_COMPONENT

#define FT_COMPONENT   trace_pshalgo

Definition at line 29 of file pshalgo.c.

◆ psh_corner_is_flat

#define psh_corner_is_flat   ft_corner_is_flat

Definition at line 919 of file pshalgo.c.

◆ psh_corner_orientation

#define psh_corner_orientation   ft_corner_orientation

Definition at line 920 of file pshalgo.c.

◆ PSH_MAX_STRONG_INTERNAL

#define PSH_MAX_STRONG_INTERNAL   16

Definition at line 1767 of file pshalgo.c.

◆ PSH_STRONG_THRESHOLD

#define PSH_STRONG_THRESHOLD   32

Definition at line 1557 of file pshalgo.c.

◆ PSH_STRONG_THRESHOLD_MAXIMUM

#define PSH_STRONG_THRESHOLD_MAXIMUM   30

Definition at line 1560 of file pshalgo.c.

◆ xxDEBUG_ZONES

#define xxDEBUG_ZONES

Definition at line 891 of file pshalgo.c.

Function Documentation

◆ ps_hints_apply()

FT_Error ps_hints_apply ( PS_Hints  ps_hints,
FT_Outline outline,
PSH_Globals  globals,
FT_Render_Mode  hint_mode 
)

Definition at line 2070 of file pshalgo.c.

2074 {
2075 PSH_GlyphRec glyphrec;
2076 PSH_Glyph glyph = &glyphrec;
2078#ifdef DEBUG_HINTER
2080#endif
2081 FT_Int dimension;
2082
2083
2084 /* something to do? */
2085 if ( outline->n_points == 0 || outline->n_contours == 0 )
2086 return FT_Err_Ok;
2087
2088#ifdef DEBUG_HINTER
2089
2090 memory = globals->memory;
2091
2092 if ( ps_debug_glyph )
2093 {
2094 psh_glyph_done( ps_debug_glyph );
2095 FT_FREE( ps_debug_glyph );
2096 }
2097
2098 if ( FT_NEW( glyph ) )
2099 return error;
2100
2101 ps_debug_glyph = glyph;
2102
2103#endif /* DEBUG_HINTER */
2104
2105 error = psh_glyph_init( glyph, outline, ps_hints, globals );
2106 if ( error )
2107 goto Exit;
2108
2109 /* try to optimize the y_scale so that the top of non-capital letters
2110 * is aligned on a pixel boundary whenever possible
2111 */
2112 {
2113 PSH_Dimension dim_x = &glyph->globals->dimension[0];
2114 PSH_Dimension dim_y = &glyph->globals->dimension[1];
2115
2116 FT_Fixed x_scale = dim_x->scale_mult;
2117 FT_Fixed y_scale = dim_y->scale_mult;
2118
2119 FT_Fixed old_x_scale = x_scale;
2120 FT_Fixed old_y_scale = y_scale;
2121
2122 FT_Fixed scaled;
2123 FT_Fixed fitted;
2124
2125 FT_Bool rescale = FALSE;
2126
2127
2128 scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
2129 fitted = FT_PIX_ROUND( scaled );
2130
2131 if ( fitted != 0 && scaled != fitted )
2132 {
2133 rescale = TRUE;
2134
2135 y_scale = FT_MulDiv( y_scale, fitted, scaled );
2136
2137 if ( fitted < scaled )
2138 x_scale -= x_scale / 50;
2139
2140 psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 );
2141 }
2142
2143 glyph->do_horz_hints = 1;
2144 glyph->do_vert_hints = 1;
2145
2146 glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
2147 hint_mode == FT_RENDER_MODE_LCD );
2148
2149 glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
2150 hint_mode == FT_RENDER_MODE_LCD_V );
2151
2152 glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
2153
2154 for ( dimension = 0; dimension < 2; dimension++ )
2155 {
2156 /* load outline coordinates into glyph */
2157 psh_glyph_load_points( glyph, dimension );
2158
2159 /* compute local extrema */
2161
2162 /* compute aligned stem/hints positions */
2163 psh_hint_table_align_hints( &glyph->hint_tables[dimension],
2164 glyph->globals,
2165 dimension,
2166 glyph );
2167
2168 /* find strong points, align them, then interpolate others */
2169 psh_glyph_find_strong_points( glyph, dimension );
2170 if ( dimension == 1 )
2171 psh_glyph_find_blue_points( &globals->blues, glyph );
2172 psh_glyph_interpolate_strong_points( glyph, dimension );
2173 psh_glyph_interpolate_normal_points( glyph, dimension );
2174 psh_glyph_interpolate_other_points( glyph, dimension );
2175
2176 /* save hinted coordinates back to outline */
2177 psh_glyph_save_points( glyph, dimension );
2178
2179 if ( rescale )
2181 old_x_scale, old_y_scale, 0, 0 );
2182 }
2183 }
2184
2185 Exit:
2186
2187#ifndef DEBUG_HINTER
2188 psh_glyph_done( glyph );
2189#endif
2190
2191 return error;
2192 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ FT_RENDER_MODE_MONO
Definition: freetype.h:3236
@ FT_RENDER_MODE_LIGHT
Definition: freetype.h:3235
@ FT_RENDER_MODE_LCD_V
Definition: freetype.h:3238
@ FT_RENDER_MODE_LCD
Definition: freetype.h:3237
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
return FT_Err_Ok
Definition: ftbbox.c:511
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:93
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
#define FT_BOOL(x)
Definition: fttypes.h:578
signed int FT_Int
Definition: fttypes.h:220
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
static void psh_glyph_interpolate_other_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1924
static void psh_glyph_compute_extrema(PSH_Glyph glyph)
Definition: pshalgo.c:1289
static void psh_glyph_interpolate_strong_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1719
static void psh_glyph_find_strong_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1565
static void psh_glyph_find_blue_points(PSH_Blues blues, PSH_Glyph glyph)
Definition: pshalgo.c:1644
static void psh_glyph_save_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1115
static void psh_glyph_done(PSH_Glyph glyph)
Definition: pshalgo.c:1035
static void psh_glyph_load_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1081
static void psh_hint_table_align_hints(PSH_Hint_Table table, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
Definition: pshalgo.c:846
static void psh_glyph_interpolate_normal_points(PSH_Glyph glyph, FT_Int dimension)
Definition: pshalgo.c:1770
static FT_Error psh_glyph_init(PSH_Glyph glyph, FT_Outline *outline, PS_Hints ps_hints, PSH_Globals globals)
Definition: pshalgo.c:1155
psh_globals_set_scale(PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, FT_Fixed x_delta, FT_Fixed y_delta)
Definition: pshglob.c:754
static void Exit(void)
Definition: sock.c:1330
FT_Fixed scale_mult
Definition: pshglob.h:85
FT_Bool do_vert_snapping
Definition: pshalgo.h:209
FT_Bool do_horz_hints
Definition: pshalgo.h:206
FT_Bool do_stem_adjust
Definition: pshalgo.h:210
FT_Bool do_vert_hints
Definition: pshalgo.h:207
FT_Bool do_horz_snapping
Definition: pshalgo.h:208
PSH_Globals globals
Definition: pshalgo.h:199
PSH_Hint_TableRec hint_tables[2]
Definition: pshalgo.h:200
Definition: mesh.c:5330

Referenced by t1_hints_funcs_init(), and t2_hints_funcs_init().

◆ psh_compute_dir()

static int psh_compute_dir ( FT_Pos  dx,
FT_Pos  dy 
)
static

Definition at line 1054 of file pshalgo.c.

1056 {
1057 FT_Pos ax, ay;
1058 int result = PSH_DIR_NONE;
1059
1060
1061 ax = FT_ABS( dx );
1062 ay = FT_ABS( dy );
1063
1064 if ( ay * 12 < ax )
1065 {
1066 /* |dy| <<< |dx| means a near-horizontal segment */
1067 result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT;
1068 }
1069 else if ( ax * 12 < ay )
1070 {
1071 /* |dx| <<< |dy| means a near-vertical segment */
1072 result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN;
1073 }
1074
1075 return result;
1076 }
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_ABS(a)
Definition: ftobjs.h:74
GLuint64EXT * result
Definition: glext.h:11304
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97
@ PSH_DIR_LEFT
Definition: pshalgo.h:101
@ PSH_DIR_UP
Definition: pshalgo.h:99
@ PSH_DIR_RIGHT
Definition: pshalgo.h:102
@ PSH_DIR_DOWN
Definition: pshalgo.h:100
@ PSH_DIR_NONE
Definition: pshalgo.h:98
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw ax
Definition: synth_sse3d.h:180

Referenced by psh_glyph_init().

◆ psh_dimension_quantize_len()

static FT_Pos psh_dimension_quantize_len ( PSH_Dimension  dim,
FT_Pos  len,
FT_Bool  do_snapping 
)
static

Definition at line 344 of file pshalgo.c.

347 {
348 if ( len <= 64 )
349 len = 64;
350 else
351 {
352 FT_Pos delta = len - dim->stdw.widths[0].cur;
353
354
355 if ( delta < 0 )
356 delta = -delta;
357
358 if ( delta < 40 )
359 {
360 len = dim->stdw.widths[0].cur;
361 if ( len < 48 )
362 len = 48;
363 }
364
365 if ( len < 3 * 64 )
366 {
367 delta = ( len & 63 );
368 len &= -64;
369
370 if ( delta < 10 )
371 len += delta;
372
373 else if ( delta < 32 )
374 len += 10;
375
376 else if ( delta < 54 )
377 len += 54;
378
379 else
380 len += delta;
381 }
382 else
383 len = FT_PIX_ROUND( len );
384 }
385
386 if ( do_snapping )
387 len = FT_PIX_ROUND( len );
388
389 return len;
390 }
GLenum GLsizei len
Definition: glext.h:6722
PSH_WidthsRec stdw
Definition: pshglob.h:84
FT_Pos cur
Definition: pshglob.h:67
PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]
Definition: pshglob.h:77

Referenced by psh_hint_align().

◆ psh_glyph_compute_extrema()

static void psh_glyph_compute_extrema ( PSH_Glyph  glyph)
static

Definition at line 1289 of file pshalgo.c.

1290 {
1291 FT_UInt n;
1292
1293
1294 /* first of all, compute all local extrema */
1295 for ( n = 0; n < glyph->num_contours; n++ )
1296 {
1297 PSH_Point first = glyph->contours[n].start;
1299
1300
1301 if ( glyph->contours[n].count == 0 )
1302 continue;
1303
1304 point = first;
1305 before = point;
1306
1307 do
1308 {
1309 before = before->prev;
1310 if ( before == first )
1311 goto Skip;
1312
1313 } while ( before->org_u == point->org_u );
1314
1315 first = point = before->next;
1316
1317 for (;;)
1318 {
1319 after = point;
1320 do
1321 {
1322 after = after->next;
1323 if ( after == first )
1324 goto Next;
1325
1326 } while ( after->org_u == point->org_u );
1327
1328 if ( before->org_u < point->org_u )
1329 {
1330 if ( after->org_u < point->org_u )
1331 {
1332 /* local maximum */
1333 goto Extremum;
1334 }
1335 }
1336 else /* before->org_u > point->org_u */
1337 {
1338 if ( after->org_u > point->org_u )
1339 {
1340 /* local minimum */
1341 Extremum:
1342 do
1343 {
1345 point = point->next;
1346
1347 } while ( point != after );
1348 }
1349 }
1350
1351 before = after->prev;
1352 point = after;
1353
1354 } /* for */
1355
1356 Next:
1357 ;
1358 }
1359
1360 /* for each extremum, determine its direction along the */
1361 /* orthogonal axis */
1362 for ( n = 0; n < glyph->num_points; n++ )
1363 {
1365
1366
1367 point = &glyph->points[n];
1368 before = point;
1369 after = point;
1370
1372 {
1373 do
1374 {
1375 before = before->prev;
1376 if ( before == point )
1377 goto Skip;
1378
1379 } while ( before->org_v == point->org_v );
1380
1381 do
1382 {
1383 after = after->next;
1384 if ( after == point )
1385 goto Skip;
1386
1387 } while ( after->org_v == point->org_v );
1388 }
1389
1390 if ( before->org_v < point->org_v &&
1391 after->org_v > point->org_v )
1392 {
1394 }
1395 else if ( before->org_v > point->org_v &&
1396 after->org_v < point->org_v )
1397 {
1399 }
1400
1401 Skip:
1402 ;
1403 }
1404 }
POINTL point
Definition: edittest.c:50
unsigned int FT_UInt
Definition: fttypes.h:231
GLdouble n
Definition: glext.h:7729
const GLint * first
Definition: glext.h:5794
#define psh_point_is_extremum(p)
Definition: pshalgo.h:141
#define psh_point_set_negative(p)
Definition: pshalgo.h:151
#define psh_point_set_extremum(p)
Definition: pshalgo.h:149
#define psh_point_set_positive(p)
Definition: pshalgo.h:150
FT_UInt count
Definition: pshalgo.h:184
PSH_Point start
Definition: pshalgo.h:183
PSH_Point points
Definition: pshalgo.h:194
FT_UInt num_points
Definition: pshalgo.h:191
FT_UInt num_contours
Definition: pshalgo.h:192
PSH_Contour contours
Definition: pshalgo.h:195
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2395

Referenced by ps_hints_apply().

◆ psh_glyph_compute_inflections()

static void psh_glyph_compute_inflections ( PSH_Glyph  glyph)
static

Definition at line 927 of file pshalgo.c.

928 {
929 FT_UInt n;
930
931
932 for ( n = 0; n < glyph->num_contours; n++ )
933 {
935 FT_Pos in_x, in_y, out_x, out_y;
936 FT_Int orient_prev, orient_cur;
937 FT_Int finished = 0;
938
939
940 /* we need at least 4 points to create an inflection point */
941 if ( glyph->contours[n].count < 4 )
942 continue;
943
944 /* compute first segment in contour */
945 first = glyph->contours[n].start;
946
947 start = end = first;
948 do
949 {
950 end = end->next;
951 if ( end == first )
952 goto Skip;
953
954 in_x = end->org_u - start->org_u;
955 in_y = end->org_v - start->org_v;
956
957 } while ( in_x == 0 && in_y == 0 );
958
959 /* extend the segment start whenever possible */
960 before = start;
961 do
962 {
963 do
964 {
965 start = before;
966 before = before->prev;
967 if ( before == first )
968 goto Skip;
969
970 out_x = start->org_u - before->org_u;
971 out_y = start->org_v - before->org_v;
972
973 } while ( out_x == 0 && out_y == 0 );
974
975 orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y );
976
977 } while ( orient_prev == 0 );
978
979 first = start;
980 in_x = out_x;
981 in_y = out_y;
982
983 /* now, process all segments in the contour */
984 do
985 {
986 /* first, extend current segment's end whenever possible */
987 after = end;
988 do
989 {
990 do
991 {
992 end = after;
993 after = after->next;
994 if ( after == first )
995 finished = 1;
996
997 out_x = after->org_u - end->org_u;
998 out_y = after->org_v - end->org_v;
999
1000 } while ( out_x == 0 && out_y == 0 );
1001
1002 orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y );
1003
1004 } while ( orient_cur == 0 );
1005
1006 if ( ( orient_cur ^ orient_prev ) < 0 )
1007 {
1008 do
1009 {
1011 start = start->next;
1012 }
1013 while ( start != end );
1014
1016 }
1017
1018 start = end;
1019 end = after;
1020 orient_prev = orient_cur;
1021 in_x = out_x;
1022 in_y = out_y;
1023
1024 } while ( !finished );
1025
1026 Skip:
1027 ;
1028 }
1029 }
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
#define psh_corner_orientation
Definition: pshalgo.c:920
#define psh_point_set_inflex(p)
Definition: pshalgo.h:126

Referenced by psh_glyph_init().

◆ psh_glyph_done()

static void psh_glyph_done ( PSH_Glyph  glyph)
static

Definition at line 1035 of file pshalgo.c.

1036 {
1037 FT_Memory memory = glyph->memory;
1038
1039
1040 psh_hint_table_done( &glyph->hint_tables[1], memory );
1041 psh_hint_table_done( &glyph->hint_tables[0], memory );
1042
1043 FT_FREE( glyph->points );
1044 FT_FREE( glyph->contours );
1045
1046 glyph->num_points = 0;
1047 glyph->num_contours = 0;
1048
1049 glyph->memory = NULL;
1050 }
#define NULL
Definition: types.h:112
static void psh_hint_table_done(PSH_Hint_Table table, FT_Memory memory)
Definition: pshalgo.c:63
FT_Memory memory
Definition: pshalgo.h:197

Referenced by ps_hints_apply().

◆ psh_glyph_find_blue_points()

static void psh_glyph_find_blue_points ( PSH_Blues  blues,
PSH_Glyph  glyph 
)
static

Definition at line 1644 of file pshalgo.c.

1646 {
1649 FT_UInt glyph_count = glyph->num_points;
1650 FT_UInt blue_count;
1651 PSH_Point point = glyph->points;
1652
1653
1654 for ( ; glyph_count > 0; glyph_count--, point++ )
1655 {
1656 FT_Pos y;
1657
1658
1659 /* check tangents */
1660 if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) &&
1662 continue;
1663
1664 /* skip strong points */
1665 if ( psh_point_is_strong( point ) )
1666 continue;
1667
1668 y = point->org_u;
1669
1670 /* look up top zones */
1671 table = &blues->normal_top;
1672 blue_count = table->count;
1673 zone = table->zones;
1674
1675 for ( ; blue_count > 0; blue_count--, zone++ )
1676 {
1677 FT_Pos delta = y - zone->org_bottom;
1678
1679
1680 if ( delta < -blues->blue_fuzz )
1681 break;
1682
1683 if ( y <= zone->org_top + blues->blue_fuzz )
1684 if ( blues->no_overshoots || delta <= blues->blue_threshold )
1685 {
1686 point->cur_u = zone->cur_bottom;
1689 }
1690 }
1691
1692 /* look up bottom zones */
1693 table = &blues->normal_bottom;
1694 blue_count = table->count;
1695 zone = table->zones + blue_count - 1;
1696
1697 for ( ; blue_count > 0; blue_count--, zone-- )
1698 {
1699 FT_Pos delta = zone->org_top - y;
1700
1701
1702 if ( delta < -blues->blue_fuzz )
1703 break;
1704
1705 if ( y >= zone->org_bottom - blues->blue_fuzz )
1706 if ( blues->no_overshoots || delta < blues->blue_threshold )
1707 {
1708 point->cur_u = zone->cur_top;
1711 }
1712 }
1713 }
1714 }
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
DWORD zone
Definition: sec_mgr.c:1754
#define psh_point_is_strong(p)
Definition: pshalgo.h:139
#define psh_point_set_strong(p)
Definition: pshalgo.h:147
#define PSH_DIR_COMPARE(d1, d2)
Definition: pshalgo.h:108
#define psh_point_set_fitted(p)
Definition: pshalgo.h:148
#define PSH_DIR_HORIZONTAL
Definition: pshalgo.h:105
FT_Int blue_fuzz
Definition: pshglob.h:126
FT_Bool no_overshoots
Definition: pshglob.h:127
PSH_Blue_TableRec normal_top
Definition: pshglob.h:118
PSH_Blue_TableRec normal_bottom
Definition: pshglob.h:119

Referenced by ps_hints_apply().

◆ psh_glyph_find_strong_points()

static void psh_glyph_find_strong_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1565 of file pshalgo.c.

1567 {
1568 /* a point is `strong' if it is located on a stem edge and */
1569 /* has an `in' or `out' tangent parallel to the hint's direction */
1570
1571 PSH_Hint_Table table = &glyph->hint_tables[dimension];
1572 PS_Mask mask = table->hint_masks->masks;
1573 FT_UInt num_masks = table->hint_masks->num_masks;
1574 FT_UInt first = 0;
1575 FT_Int major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL
1577 PSH_Dimension dim = &glyph->globals->dimension[dimension];
1578 FT_Fixed scale = dim->scale_mult;
1579 FT_Int threshold;
1580
1581
1582 threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale );
1583 if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM )
1584 threshold = PSH_STRONG_THRESHOLD_MAXIMUM;
1585
1586 /* process secondary hints to `selected' points */
1587 if ( num_masks > 1 && glyph->num_points > 0 )
1588 {
1589 /* the `endchar' op can reduce the number of points */
1590 first = mask->end_point > glyph->num_points
1591 ? glyph->num_points
1592 : mask->end_point;
1593 mask++;
1594 for ( ; num_masks > 1; num_masks--, mask++ )
1595 {
1596 FT_UInt next = FT_MIN( mask->end_point, glyph->num_points );
1597
1598
1599 if ( next > first )
1600 {
1601 FT_UInt count = next - first;
1602 PSH_Point point = glyph->points + first;
1603
1604
1606
1608 threshold, major_dir );
1609 }
1610 first = next;
1611 }
1612 }
1613
1614 /* process primary hints for all points */
1615 if ( num_masks == 1 )
1616 {
1617 FT_UInt count = glyph->num_points;
1618 PSH_Point point = glyph->points;
1619
1620
1621 psh_hint_table_activate_mask( table, table->hint_masks->masks );
1622
1624 threshold, major_dir );
1625 }
1626
1627 /* now, certain points may have been attached to a hint and */
1628 /* not marked as strong; update their flags then */
1629 {
1630 FT_UInt count = glyph->num_points;
1631 PSH_Point point = glyph->points;
1632
1633
1634 for ( ; count > 0; count--, point++ )
1635 if ( point->hint && !psh_point_is_strong( point ) )
1637 }
1638 }
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_MIN(a, b)
Definition: ftobjs.h:71
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLenum GLint GLuint mask
Definition: glext.h:6028
static void psh_hint_table_activate_mask(PSH_Hint_Table table, PS_Mask hint_mask)
Definition: pshalgo.c:244
#define PSH_STRONG_THRESHOLD
Definition: pshalgo.c:1557
#define PSH_STRONG_THRESHOLD_MAXIMUM
Definition: pshalgo.c:1560
static void psh_hint_table_find_strong_points(PSH_Hint_Table table, PSH_Point point, FT_UInt count, FT_Int threshold, FT_Int major_dir)
Definition: pshalgo.c:1412
#define PSH_DIR_VERTICAL
Definition: pshalgo.h:106
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by ps_hints_apply().

◆ psh_glyph_init()

static FT_Error psh_glyph_init ( PSH_Glyph  glyph,
FT_Outline outline,
PS_Hints  ps_hints,
PSH_Globals  globals 
)
static

Definition at line 1155 of file pshalgo.c.

1159 {
1162
1163
1164 /* clear all fields */
1165 FT_ZERO( glyph );
1166
1167 memory = glyph->memory = globals->memory;
1168
1169 /* allocate and setup points + contours arrays */
1170 if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) ||
1171 FT_NEW_ARRAY( glyph->contours, outline->n_contours ) )
1172 goto Exit;
1173
1174 glyph->num_points = (FT_UInt)outline->n_points;
1175 glyph->num_contours = (FT_UInt)outline->n_contours;
1176
1177 {
1178 FT_UInt first = 0, next, n;
1179 PSH_Point points = glyph->points;
1180 PSH_Contour contour = glyph->contours;
1181
1182
1183 for ( n = 0; n < glyph->num_contours; n++ )
1184 {
1185 FT_UInt count;
1187
1188
1189 next = (FT_UInt)outline->contours[n] + 1;
1190 count = next - first;
1191
1192 contour->start = points + first;
1193 contour->count = count;
1194
1195 if ( count > 0 )
1196 {
1197 point = points + first;
1198
1199 point->prev = points + next - 1;
1200 point->contour = contour;
1201
1202 for ( ; count > 1; count-- )
1203 {
1204 point[0].next = point + 1;
1205 point[1].prev = point;
1206 point++;
1207 point->contour = contour;
1208 }
1209 point->next = points + first;
1210 }
1211
1212 contour++;
1213 first = next;
1214 }
1215 }
1216
1217 {
1218 PSH_Point points = glyph->points;
1220 FT_Vector* vec = outline->points;
1221 FT_UInt n;
1222
1223
1224 for ( n = 0; n < glyph->num_points; n++, point++ )
1225 {
1226 FT_Int n_prev = (FT_Int)( point->prev - points );
1227 FT_Int n_next = (FT_Int)( point->next - points );
1228 FT_Pos dxi, dyi, dxo, dyo;
1229
1230
1231 if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) )
1232 point->flags = PSH_POINT_OFF;
1233
1234 dxi = vec[n].x - vec[n_prev].x;
1235 dyi = vec[n].y - vec[n_prev].y;
1236
1237 point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi );
1238
1239 dxo = vec[n_next].x - vec[n].x;
1240 dyo = vec[n_next].y - vec[n].y;
1241
1242 point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo );
1243
1244 /* detect smooth points */
1245 if ( point->flags & PSH_POINT_OFF )
1246 point->flags |= PSH_POINT_SMOOTH;
1247
1248 else if ( point->dir_in == point->dir_out )
1249 {
1250 if ( point->dir_out != PSH_DIR_NONE ||
1251 psh_corner_is_flat( dxi, dyi, dxo, dyo ) )
1252 point->flags |= PSH_POINT_SMOOTH;
1253 }
1254 }
1255 }
1256
1257 glyph->outline = outline;
1258 glyph->globals = globals;
1259
1260#ifdef COMPUTE_INFLEXS
1261 psh_glyph_load_points( glyph, 0 );
1263#endif /* COMPUTE_INFLEXS */
1264
1265 /* now deal with hints tables */
1266 error = psh_hint_table_init( &glyph->hint_tables [0],
1267 &ps_hints->dimension[0].hints,
1268 &ps_hints->dimension[0].masks,
1269 &ps_hints->dimension[0].counters,
1270 memory );
1271 if ( error )
1272 goto Exit;
1273
1274 error = psh_hint_table_init( &glyph->hint_tables [1],
1275 &ps_hints->dimension[1].hints,
1276 &ps_hints->dimension[1].masks,
1277 &ps_hints->dimension[1].counters,
1278 memory );
1279 if ( error )
1280 goto Exit;
1281
1282 Exit:
1283 return error;
1284 }
FT_Vector * vec
Definition: ftbbox.c:448
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_ZERO(p)
Definition: ftmemory.h:237
signed char FT_Char
Definition: fttypes.h:143
GLsizei const GLfloat * points
Definition: glext.h:8112
if(dx< 0)
Definition: linetemp.h:194
#define psh_corner_is_flat
Definition: pshalgo.c:919
static int psh_compute_dir(FT_Pos dx, FT_Pos dy)
Definition: pshalgo.c:1054
static FT_Error psh_hint_table_init(PSH_Hint_Table table, PS_Hint_Table hints, PS_Mask_Table hint_masks, PS_Mask_Table counter_masks, FT_Memory memory)
Definition: pshalgo.c:171
static void psh_glyph_compute_inflections(PSH_Glyph glyph)
Definition: pshalgo.c:927
#define PSH_POINT_OFF
Definition: pshalgo.h:115
#define PSH_POINT_SMOOTH
Definition: pshalgo.h:116
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
FT_Outline * outline
Definition: pshalgo.h:198
PS_Mask_TableRec masks
Definition: pshrec.h:118
PS_Mask_TableRec counters
Definition: pshrec.h:119
PS_Hint_TableRec hints
Definition: pshrec.h:117
PS_DimensionRec dimension[2]
Definition: pshrec.h:133

Referenced by ps_hints_apply().

◆ psh_glyph_interpolate_normal_points()

static void psh_glyph_interpolate_normal_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1770 of file pshalgo.c.

1772 {
1773
1774#if 1
1775 /* first technique: a point is strong if it is a local extremum */
1776
1777 PSH_Dimension dim = &glyph->globals->dimension[dimension];
1778 FT_Fixed scale = dim->scale_mult;
1779 FT_Memory memory = glyph->memory;
1780
1781 PSH_Point* strongs = NULL;
1783 FT_UInt num_strongs = 0;
1784
1785 PSH_Point points = glyph->points;
1786 PSH_Point points_end = points + glyph->num_points;
1788
1789
1790 /* first count the number of strong points */
1791 for ( point = points; point < points_end; point++ )
1792 {
1793 if ( psh_point_is_strong( point ) )
1794 num_strongs++;
1795 }
1796
1797 if ( num_strongs == 0 ) /* nothing to do here */
1798 return;
1799
1800 /* allocate an array to store a list of points, */
1801 /* stored in increasing org_u order */
1802 if ( num_strongs <= PSH_MAX_STRONG_INTERNAL )
1803 strongs = strongs_0;
1804 else
1805 {
1807
1808
1809 if ( FT_NEW_ARRAY( strongs, num_strongs ) )
1810 return;
1811 }
1812
1813 num_strongs = 0;
1814 for ( point = points; point < points_end; point++ )
1815 {
1817
1818
1819 if ( !psh_point_is_strong( point ) )
1820 continue;
1821
1822 for ( insert = strongs + num_strongs; insert > strongs; insert-- )
1823 {
1824 if ( insert[-1]->org_u <= point->org_u )
1825 break;
1826
1827 insert[0] = insert[-1];
1828 }
1829 insert[0] = point;
1830 num_strongs++;
1831 }
1832
1833 /* now try to interpolate all normal points */
1834 for ( point = points; point < points_end; point++ )
1835 {
1836 if ( psh_point_is_strong( point ) )
1837 continue;
1838
1839 /* sometimes, some local extrema are smooth points */
1840 if ( psh_point_is_smooth( point ) )
1841 {
1842 if ( point->dir_in == PSH_DIR_NONE ||
1843 point->dir_in != point->dir_out )
1844 continue;
1845
1846 if ( !psh_point_is_extremum( point ) &&
1848 continue;
1849
1850 point->flags &= ~PSH_POINT_SMOOTH;
1851 }
1852
1853 /* find best enclosing point coordinates then interpolate */
1854 {
1856 FT_UInt nn;
1857
1858
1859 for ( nn = 0; nn < num_strongs; nn++ )
1860 if ( strongs[nn]->org_u > point->org_u )
1861 break;
1862
1863 if ( nn == 0 ) /* point before the first strong point */
1864 {
1865 after = strongs[0];
1866
1867 point->cur_u = after->cur_u +
1868 FT_MulFix( point->org_u - after->org_u,
1869 scale );
1870 }
1871 else
1872 {
1873 before = strongs[nn - 1];
1874
1875 for ( nn = num_strongs; nn > 0; nn-- )
1876 if ( strongs[nn - 1]->org_u < point->org_u )
1877 break;
1878
1879 if ( nn == num_strongs ) /* point is after last strong point */
1880 {
1881 before = strongs[nn - 1];
1882
1883 point->cur_u = before->cur_u +
1884 FT_MulFix( point->org_u - before->org_u,
1885 scale );
1886 }
1887 else
1888 {
1889 FT_Pos u;
1890
1891
1892 after = strongs[nn];
1893
1894 /* now interpolate point between before and after */
1895 u = point->org_u;
1896
1897 if ( u == before->org_u )
1898 point->cur_u = before->cur_u;
1899
1900 else if ( u == after->org_u )
1901 point->cur_u = after->cur_u;
1902
1903 else
1904 point->cur_u = before->cur_u +
1905 FT_MulDiv( u - before->org_u,
1906 after->cur_u - before->cur_u,
1907 after->org_u - before->org_u );
1908 }
1909 }
1911 }
1912 }
1913
1914 if ( strongs != strongs_0 )
1915 FT_FREE( strongs );
1916
1917#endif /* 1 */
1918
1919 }
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 PSH_MAX_STRONG_INTERNAL
Definition: pshalgo.c:1767
#define psh_point_is_inflex(p)
Definition: pshalgo.h:122
#define psh_point_is_smooth(p)
Definition: pshalgo.h:120
static int insert
Definition: xmllint.c:138

Referenced by ps_hints_apply().

◆ psh_glyph_interpolate_other_points()

static void psh_glyph_interpolate_other_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1924 of file pshalgo.c.

1926 {
1927 PSH_Dimension dim = &glyph->globals->dimension[dimension];
1928 FT_Fixed scale = dim->scale_mult;
1929 FT_Fixed delta = dim->scale_delta;
1930 PSH_Contour contour = glyph->contours;
1931 FT_UInt num_contours = glyph->num_contours;
1932
1933
1934 for ( ; num_contours > 0; num_contours--, contour++ )
1935 {
1936 PSH_Point start = contour->start;
1938 FT_UInt fit_count;
1939
1940
1941 /* count the number of strong points in this contour */
1942 next = start + contour->count;
1943 fit_count = 0;
1944 first = NULL;
1945
1946 for ( point = start; point < next; point++ )
1947 if ( psh_point_is_fitted( point ) )
1948 {
1949 if ( !first )
1950 first = point;
1951
1952 fit_count++;
1953 }
1954
1955 /* if there are less than 2 fitted points in the contour, we */
1956 /* simply scale and eventually translate the contour points */
1957 if ( fit_count < 2 )
1958 {
1959 if ( fit_count == 1 )
1960 delta = first->cur_u - FT_MulFix( first->org_u, scale );
1961
1962 for ( point = start; point < next; point++ )
1963 if ( point != first )
1964 point->cur_u = FT_MulFix( point->org_u, scale ) + delta;
1965
1966 goto Next_Contour;
1967 }
1968
1969 /* there are more than 2 strong points in this contour; we */
1970 /* need to interpolate weak points between them */
1971 start = first;
1972 do
1973 {
1974 /* skip consecutive fitted points */
1975 for (;;)
1976 {
1977 next = first->next;
1978 if ( next == start )
1979 goto Next_Contour;
1980
1981 if ( !psh_point_is_fitted( next ) )
1982 break;
1983
1984 first = next;
1985 }
1986
1987 /* find next fitted point after unfitted one */
1988 for (;;)
1989 {
1990 next = next->next;
1991 if ( psh_point_is_fitted( next ) )
1992 break;
1993 }
1994
1995 /* now interpolate between them */
1996 {
1997 FT_Pos org_a, org_ab, cur_a, cur_ab;
1998 FT_Pos org_c, org_ac, cur_c;
1999 FT_Fixed scale_ab;
2000
2001
2002 if ( first->org_u <= next->org_u )
2003 {
2004 org_a = first->org_u;
2005 cur_a = first->cur_u;
2006 org_ab = next->org_u - org_a;
2007 cur_ab = next->cur_u - cur_a;
2008 }
2009 else
2010 {
2011 org_a = next->org_u;
2012 cur_a = next->cur_u;
2013 org_ab = first->org_u - org_a;
2014 cur_ab = first->cur_u - cur_a;
2015 }
2016
2017 scale_ab = 0x10000L;
2018 if ( org_ab > 0 )
2019 scale_ab = FT_DivFix( cur_ab, org_ab );
2020
2021 point = first->next;
2022 do
2023 {
2024 org_c = point->org_u;
2025 org_ac = org_c - org_a;
2026
2027 if ( org_ac <= 0 )
2028 {
2029 /* on the left of the interpolation zone */
2030 cur_c = cur_a + FT_MulFix( org_ac, scale );
2031 }
2032 else if ( org_ac >= org_ab )
2033 {
2034 /* on the right on the interpolation zone */
2035 cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale );
2036 }
2037 else
2038 {
2039 /* within the interpolation zone */
2040 cur_c = cur_a + FT_MulFix( org_ac, scale_ab );
2041 }
2042
2043 point->cur_u = cur_c;
2044
2045 point = point->next;
2046
2047 } while ( point != next );
2048 }
2049
2050 /* keep going until all points in the contours have been processed */
2051 first = next;
2052
2053 } while ( first != start );
2054
2055 Next_Contour:
2056 ;
2057 }
2058 }
#define psh_point_is_fitted(p)
Definition: pshalgo.h:140
FT_Fixed scale_delta
Definition: pshglob.h:86

Referenced by ps_hints_apply().

◆ psh_glyph_interpolate_strong_points()

static void psh_glyph_interpolate_strong_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1719 of file pshalgo.c.

1721 {
1722 PSH_Dimension dim = &glyph->globals->dimension[dimension];
1723 FT_Fixed scale = dim->scale_mult;
1724
1725 FT_UInt count = glyph->num_points;
1726 PSH_Point point = glyph->points;
1727
1728
1729 for ( ; count > 0; count--, point++ )
1730 {
1731 PSH_Hint hint = point->hint;
1732
1733
1734 if ( hint )
1735 {
1736 FT_Pos delta;
1737
1738
1740 point->cur_u = hint->cur_pos;
1741
1742 else if ( psh_point_is_edge_max( point ) )
1743 point->cur_u = hint->cur_pos + hint->cur_len;
1744
1745 else
1746 {
1747 delta = point->org_u - hint->org_pos;
1748
1749 if ( delta <= 0 )
1750 point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );
1751
1752 else if ( delta >= hint->org_len )
1753 point->cur_u = hint->cur_pos + hint->cur_len +
1754 FT_MulFix( delta - hint->org_len, scale );
1755
1756 else /* hint->org_len > 0 */
1757 point->cur_u = hint->cur_pos +
1758 FT_MulDiv( delta, hint->cur_len,
1759 hint->org_len );
1760 }
1762 }
1763 }
1764 }
typedefFT_BEGIN_HEADER struct PSH_HintRec_ * PSH_Hint
Definition: pshalgo.h:31
#define psh_point_is_edge_max(p)
Definition: pshalgo.h:145
#define psh_point_is_edge_min(p)
Definition: pshalgo.h:144
DWORD hint
Definition: vfdcmd.c:88

Referenced by ps_hints_apply().

◆ psh_glyph_load_points()

static void psh_glyph_load_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1081 of file pshalgo.c.

1083 {
1084 FT_Vector* vec = glyph->outline->points;
1085 PSH_Point point = glyph->points;
1086 FT_UInt count = glyph->num_points;
1087
1088
1089 for ( ; count > 0; count--, point++, vec++ )
1090 {
1091 point->flags2 = 0;
1092 point->hint = NULL;
1093 if ( dimension == 0 )
1094 {
1095 point->org_u = vec->x;
1096 point->org_v = vec->y;
1097 }
1098 else
1099 {
1100 point->org_u = vec->y;
1101 point->org_v = vec->x;
1102 }
1103
1104#ifdef DEBUG_HINTER
1105 point->org_x = vec->x;
1106 point->org_y = vec->y;
1107#endif
1108
1109 }
1110 }
FT_Vector * points
Definition: ftimage.h:339

Referenced by ps_hints_apply(), and psh_glyph_init().

◆ psh_glyph_save_points()

static void psh_glyph_save_points ( PSH_Glyph  glyph,
FT_Int  dimension 
)
static

Definition at line 1115 of file pshalgo.c.

1117 {
1118 FT_UInt n;
1119 PSH_Point point = glyph->points;
1120 FT_Vector* vec = glyph->outline->points;
1121 char* tags = glyph->outline->tags;
1122
1123
1124 for ( n = 0; n < glyph->num_points; n++ )
1125 {
1126 if ( dimension == 0 )
1127 vec[n].x = point->cur_u;
1128 else
1129 vec[n].y = point->cur_u;
1130
1131 if ( psh_point_is_strong( point ) )
1132 tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 );
1133
1134#ifdef DEBUG_HINTER
1135
1136 if ( dimension == 0 )
1137 {
1138 point->cur_x = point->cur_u;
1139 point->flags_x = point->flags2 | point->flags;
1140 }
1141 else
1142 {
1143 point->cur_y = point->cur_u;
1144 point->flags_y = point->flags2 | point->flags;
1145 }
1146
1147#endif
1148
1149 point++;
1150 }
1151 }
unsigned char
Definition: typeof.h:29
const char * tags[7 *8]
Definition: apphelp.c:216
char * tags
Definition: ftimage.h:340

Referenced by ps_hints_apply().

◆ psh_hint_align()

static void psh_hint_align ( PSH_Hint  hint,
PSH_Globals  globals,
FT_Int  dimension,
PSH_Glyph  glyph 
)
static

Definition at line 437 of file pshalgo.c.

441 {
442 PSH_Dimension dim = &globals->dimension[dimension];
444 FT_Fixed delta = dim->scale_delta;
445
446
447 if ( !psh_hint_is_fitted( hint ) )
448 {
449 FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
450 FT_Pos len = FT_MulFix( hint->org_len, scale );
451
452 FT_Int do_snapping;
453 FT_Pos fit_len;
455
456
457 /* ignore stem alignments when requested through the hint flags */
458 if ( ( dimension == 0 && !glyph->do_horz_hints ) ||
459 ( dimension == 1 && !glyph->do_vert_hints ) )
460 {
461 hint->cur_pos = pos;
462 hint->cur_len = len;
463
465 return;
466 }
467
468 /* perform stem snapping when requested - this is necessary
469 * for monochrome and LCD hinting modes only
470 */
471 do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) ||
472 ( dimension == 1 && glyph->do_vert_snapping );
473
474 hint->cur_len = fit_len = len;
475
476 /* check blue zones for horizontal stems */
478 align.align_bot = align.align_top = 0;
479
480 if ( dimension == 1 )
481 psh_blues_snap_stem( &globals->blues,
482 hint->org_pos + hint->org_len,
483 hint->org_pos,
484 &align );
485
486 switch ( align.align )
487 {
489 /* the top of the stem is aligned against a blue zone */
490 hint->cur_pos = align.align_top - fit_len;
491 break;
492
494 /* the bottom of the stem is aligned against a blue zone */
495 hint->cur_pos = align.align_bot;
496 break;
497
499 /* both edges of the stem are aligned against blue zones */
500 hint->cur_pos = align.align_bot;
501 hint->cur_len = align.align_top - align.align_bot;
502 break;
503
504 default:
505 {
506 PSH_Hint parent = hint->parent;
507
508
509 if ( parent )
510 {
511 FT_Pos par_org_center, par_cur_center;
512 FT_Pos cur_org_center, cur_delta;
513
514
515 /* ensure that parent is already fitted */
516 if ( !psh_hint_is_fitted( parent ) )
517 psh_hint_align( parent, globals, dimension, glyph );
518
519 /* keep original relation between hints, this is, use the */
520 /* scaled distance between the centers of the hints to */
521 /* compute the new position */
522 par_org_center = parent->org_pos + ( parent->org_len >> 1 );
523 par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
524 cur_org_center = hint->org_pos + ( hint->org_len >> 1 );
525
526 cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
527 pos = par_cur_center + cur_delta - ( len >> 1 );
528 }
529
530 hint->cur_pos = pos;
531 hint->cur_len = fit_len;
532
533 /* Stem adjustment tries to snap stem widths to standard
534 * ones. This is important to prevent unpleasant rounding
535 * artefacts.
536 */
537 if ( glyph->do_stem_adjust )
538 {
539 if ( len <= 64 )
540 {
541 /* the stem is less than one pixel; we will center it
542 * around the nearest pixel center
543 */
544 if ( len >= 32 )
545 {
546 /* This is a special case where we also widen the stem
547 * and align it to the pixel grid.
548 *
549 * stem_center = pos + (len/2)
550 * nearest_pixel_center = FT_ROUND(stem_center-32)+32
551 * new_pos = nearest_pixel_center-32
552 * = FT_ROUND(stem_center-32)
553 * = FT_FLOOR(stem_center-32+32)
554 * = FT_FLOOR(stem_center)
555 * new_len = 64
556 */
557 pos = FT_PIX_FLOOR( pos + ( len >> 1 ) );
558 len = 64;
559 }
560 else if ( len > 0 )
561 {
562 /* This is a very small stem; we simply align it to the
563 * pixel grid, trying to find the minimum displacement.
564 *
565 * left = pos
566 * right = pos + len
567 * left_nearest_edge = ROUND(pos)
568 * right_nearest_edge = ROUND(right)
569 *
570 * if ( ABS(left_nearest_edge - left) <=
571 * ABS(right_nearest_edge - right) )
572 * new_pos = left
573 * else
574 * new_pos = right
575 */
576 FT_Pos left_nearest = FT_PIX_ROUND( pos );
577 FT_Pos right_nearest = FT_PIX_ROUND( pos + len );
578 FT_Pos left_disp = left_nearest - pos;
579 FT_Pos right_disp = right_nearest - ( pos + len );
580
581
582 if ( left_disp < 0 )
583 left_disp = -left_disp;
584 if ( right_disp < 0 )
585 right_disp = -right_disp;
586 if ( left_disp <= right_disp )
587 pos = left_nearest;
588 else
589 pos = right_nearest;
590 }
591 else
592 {
593 /* this is a ghost stem; we simply round it */
594 pos = FT_PIX_ROUND( pos );
595 }
596 }
597 else
598 {
600 }
601 }
602
603 /* now that we have a good hinted stem width, try to position */
604 /* the stem along a pixel grid integer coordinate */
606 hint->cur_len = len;
607 }
608 }
609
610 if ( do_snapping )
611 {
612 pos = hint->cur_pos;
613 len = hint->cur_len;
614
615 if ( len < 64 )
616 len = 64;
617 else
618 len = FT_PIX_ROUND( len );
619
620 switch ( align.align )
621 {
623 hint->cur_pos = align.align_top - len;
624 hint->cur_len = len;
625 break;
626
628 hint->cur_len = len;
629 break;
630
632 /* don't touch */
633 break;
634
635
636 default:
637 hint->cur_len = len;
638 if ( len & 64 )
639 pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32;
640 else
641 pos = FT_PIX_ROUND( pos + ( len >> 1 ) );
642
643 hint->cur_pos = pos - ( len >> 1 );
644 hint->cur_len = len;
645 }
646 }
647
649
650#ifdef DEBUG_HINTER
651 if ( ps_debug_hint_func )
652 ps_debug_hint_func( hint, dimension );
653#endif
654 }
655 }
r parent
Definition: btrfs.c:3010
int align(int length, int align)
Definition: dsound8.c:36
#define FT_PIX_FLOOR(x)
Definition: ftobjs.h:92
static void psh_hint_align(PSH_Hint hint, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
Definition: pshalgo.c:437
static FT_Pos psh_dimension_quantize_len(PSH_Dimension dim, FT_Pos len, FT_Bool do_snapping)
Definition: pshalgo.c:344
static FT_Fixed psh_hint_snap_stem_side_delta(FT_Fixed pos, FT_Fixed len)
Definition: pshalgo.c:422
#define psh_hint_set_fitted(x)
Definition: pshalgo.h:47
#define psh_hint_is_fitted(x)
Definition: pshalgo.h:43
psh_blues_snap_stem(PSH_Blues blues, FT_Int stem_top, FT_Int stem_bot, PSH_Alignment alignment)
Definition: pshglob.c:548
#define PSH_BLUE_ALIGN_BOT
Definition: pshglob.h:146
#define PSH_BLUE_ALIGN_NONE
Definition: pshglob.h:144
#define PSH_BLUE_ALIGN_TOP
Definition: pshglob.h:145

Referenced by psh_hint_align(), and psh_hint_table_align_hints().

◆ psh_hint_overlap()

static FT_Int psh_hint_overlap ( PSH_Hint  hint1,
PSH_Hint  hint2 
)
static

Definition at line 53 of file pshalgo.c.

55 {
56 return hint1->org_pos + hint1->org_len >= hint2->org_pos &&
57 hint2->org_pos + hint2->org_len >= hint1->org_pos;
58 }

Referenced by psh_hint_table_activate_mask(), and psh_hint_table_record().

◆ psh_hint_snap_stem_side_delta()

static FT_Fixed psh_hint_snap_stem_side_delta ( FT_Fixed  pos,
FT_Fixed  len 
)
static

Definition at line 422 of file pshalgo.c.

424 {
425 FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos;
426 FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len;
427
428
429 if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) )
430 return delta1;
431 else
432 return delta2;
433 }

Referenced by psh_hint_align().

◆ psh_hint_table_activate_mask()

static void psh_hint_table_activate_mask ( PSH_Hint_Table  table,
PS_Mask  hint_mask 
)
static

Definition at line 244 of file pshalgo.c.

246 {
247 FT_Int mask = 0, val = 0;
248 FT_Byte* cursor = hint_mask->bytes;
250
251
252 limit = hint_mask->num_bits;
253 count = 0;
254
256
257 for ( idx = 0; idx < limit; idx++ )
258 {
259 if ( mask == 0 )
260 {
261 val = *cursor++;
262 mask = 0x80;
263 }
264
265 if ( val & mask )
266 {
267 PSH_Hint hint = &table->hints[idx];
268
269
270 if ( !psh_hint_is_active( hint ) )
271 {
272 FT_UInt count2;
273
274#if 0
275 PSH_Hint* sort = table->sort;
276 PSH_Hint hint2;
277
278
279 for ( count2 = count; count2 > 0; count2--, sort++ )
280 {
281 hint2 = sort[0];
282 if ( psh_hint_overlap( hint, hint2 ) )
283 FT_TRACE0(( "psh_hint_table_activate_mask:"
284 " found overlapping hints\n" ))
285 }
286#else
287 count2 = 0;
288#endif
289
290 if ( count2 == 0 )
291 {
293 if ( count < table->max_hints )
294 table->sort[count++] = hint;
295 else
296 FT_TRACE0(( "psh_hint_tableactivate_mask:"
297 " too many active hints\n" ));
298 }
299 }
300 }
301
302 mask >>= 1;
303 }
304 table->num_hints = count;
305
306 /* now, sort the hints; they are guaranteed to not overlap */
307 /* so we can compare their "org_pos" field directly */
308 {
309 FT_Int i1, i2;
310 PSH_Hint hint1, hint2;
311 PSH_Hint* sort = table->sort;
312
313
314 /* a simple bubble sort will do, since in 99% of cases, the hints */
315 /* will be already sorted -- and the sort will be linear */
316 for ( i1 = 1; i1 < (FT_Int)count; i1++ )
317 {
318 hint1 = sort[i1];
319 for ( i2 = i1 - 1; i2 >= 0; i2-- )
320 {
321 hint2 = sort[i2];
322
323 if ( hint2->org_pos < hint1->org_pos )
324 break;
325
326 sort[i2 + 1] = hint2;
327 sort[i2] = hint1;
328 }
329 }
330 }
331 }
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
Definition: _algo.c:993
unsigned int idx
Definition: utils.c:41
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
unsigned char FT_Byte
Definition: fttypes.h:154
GLint limit
Definition: glext.h:10326
GLuint GLfloat * val
Definition: glext.h:7180
const char cursor[]
Definition: icontest.c:13
static FT_Int psh_hint_overlap(PSH_Hint hint1, PSH_Hint hint2)
Definition: pshalgo.c:53
static void psh_hint_table_deactivate(PSH_Hint_Table table)
Definition: pshalgo.c:80
#define psh_hint_is_active(x)
Definition: pshalgo.h:41
#define psh_hint_activate(x)
Definition: pshalgo.h:45
FT_UInt num_bits
Definition: pshrec.h:96
FT_Byte * bytes
Definition: pshrec.h:98

Referenced by psh_glyph_find_strong_points().

◆ psh_hint_table_align_hints()

static void psh_hint_table_align_hints ( PSH_Hint_Table  table,
PSH_Globals  globals,
FT_Int  dimension,
PSH_Glyph  glyph 
)
static

Definition at line 846 of file pshalgo.c.

850 {
853
854#ifdef DEBUG_HINTER
855
856 PSH_Dimension dim = &globals->dimension[dimension];
858 FT_Fixed delta = dim->scale_delta;
859
860
861 if ( ps_debug_no_vert_hints && dimension == 0 )
862 {
863 ps_simple_scale( table, scale, delta, dimension );
864 return;
865 }
866
867 if ( ps_debug_no_horz_hints && dimension == 1 )
868 {
869 ps_simple_scale( table, scale, delta, dimension );
870 return;
871 }
872
873#endif /* DEBUG_HINTER*/
874
875 hint = table->hints;
876 count = table->max_hints;
877
878 for ( ; count > 0; count--, hint++ )
879 psh_hint_align( hint, globals, dimension, glyph );
880 }

Referenced by ps_hints_apply().

◆ psh_hint_table_deactivate()

static void psh_hint_table_deactivate ( PSH_Hint_Table  table)
static

Definition at line 80 of file pshalgo.c.

81 {
82 FT_UInt count = table->max_hints;
83 PSH_Hint hint = table->hints;
84
85
86 for ( ; count > 0; count--, hint++ )
87 {
89 hint->order = -1;
90 }
91 }
#define psh_hint_deactivate(x)
Definition: pshalgo.h:46

Referenced by psh_hint_table_activate_mask().

◆ psh_hint_table_done()

static void psh_hint_table_done ( PSH_Hint_Table  table,
FT_Memory  memory 
)
static

Definition at line 63 of file pshalgo.c.

65 {
66 FT_FREE( table->zones );
67 table->num_zones = 0;
68 table->zone = NULL;
69
70 FT_FREE( table->sort );
71 FT_FREE( table->hints );
72 table->num_hints = 0;
73 table->max_hints = 0;
74 table->sort_global = NULL;
75 }

Referenced by psh_glyph_done().

◆ psh_hint_table_find_strong_points()

static void psh_hint_table_find_strong_points ( PSH_Hint_Table  table,
PSH_Point  point,
FT_UInt  count,
FT_Int  threshold,
FT_Int  major_dir 
)
static

Definition at line 1412 of file pshalgo.c.

1417 {
1418 PSH_Hint* sort = table->sort;
1419 FT_UInt num_hints = table->num_hints;
1420
1421
1422 for ( ; count > 0; count--, point++ )
1423 {
1424 FT_Int point_dir = 0;
1425 FT_Pos org_u = point->org_u;
1426
1427
1428 if ( psh_point_is_strong( point ) )
1429 continue;
1430
1431 if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
1432 point_dir = point->dir_in;
1433
1434 else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
1435 point_dir = point->dir_out;
1436
1437 if ( point_dir )
1438 {
1439 if ( point_dir == major_dir )
1440 {
1441 FT_UInt nn;
1442
1443
1444 for ( nn = 0; nn < num_hints; nn++ )
1445 {
1446 PSH_Hint hint = sort[nn];
1447 FT_Pos d = org_u - hint->org_pos;
1448
1449
1450 if ( d < threshold && -d < threshold )
1451 {
1453 point->flags2 |= PSH_POINT_EDGE_MIN;
1454 point->hint = hint;
1455 break;
1456 }
1457 }
1458 }
1459 else if ( point_dir == -major_dir )
1460 {
1461 FT_UInt nn;
1462
1463
1464 for ( nn = 0; nn < num_hints; nn++ )
1465 {
1466 PSH_Hint hint = sort[nn];
1467 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1468
1469
1470 if ( d < threshold && -d < threshold )
1471 {
1473 point->flags2 |= PSH_POINT_EDGE_MAX;
1474 point->hint = hint;
1475 break;
1476 }
1477 }
1478 }
1479 }
1480
1481#if 1
1482 else if ( psh_point_is_extremum( point ) )
1483 {
1484 /* treat extrema as special cases for stem edge alignment */
1485 FT_UInt nn, min_flag, max_flag;
1486
1487
1488 if ( major_dir == PSH_DIR_HORIZONTAL )
1489 {
1490 min_flag = PSH_POINT_POSITIVE;
1491 max_flag = PSH_POINT_NEGATIVE;
1492 }
1493 else
1494 {
1495 min_flag = PSH_POINT_NEGATIVE;
1496 max_flag = PSH_POINT_POSITIVE;
1497 }
1498
1499 if ( point->flags2 & min_flag )
1500 {
1501 for ( nn = 0; nn < num_hints; nn++ )
1502 {
1503 PSH_Hint hint = sort[nn];
1504 FT_Pos d = org_u - hint->org_pos;
1505
1506
1507 if ( d < threshold && -d < threshold )
1508 {
1509 point->flags2 |= PSH_POINT_EDGE_MIN;
1510 point->hint = hint;
1512 break;
1513 }
1514 }
1515 }
1516 else if ( point->flags2 & max_flag )
1517 {
1518 for ( nn = 0; nn < num_hints; nn++ )
1519 {
1520 PSH_Hint hint = sort[nn];
1521 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1522
1523
1524 if ( d < threshold && -d < threshold )
1525 {
1526 point->flags2 |= PSH_POINT_EDGE_MAX;
1527 point->hint = hint;
1529 break;
1530 }
1531 }
1532 }
1533
1534 if ( !point->hint )
1535 {
1536 for ( nn = 0; nn < num_hints; nn++ )
1537 {
1538 PSH_Hint hint = sort[nn];
1539
1540
1541 if ( org_u >= hint->org_pos &&
1542 org_u <= hint->org_pos + hint->org_len )
1543 {
1544 point->hint = hint;
1545 break;
1546 }
1547 }
1548 }
1549 }
1550
1551#endif /* 1 */
1552 }
1553 }
#define d
Definition: ke_i.h:81
#define PSH_POINT_POSITIVE
Definition: pshalgo.h:133
#define PSH_POINT_EDGE_MIN
Definition: pshalgo.h:135
#define PSH_POINT_NEGATIVE
Definition: pshalgo.h:134
#define PSH_POINT_EDGE_MAX
Definition: pshalgo.h:136

Referenced by psh_glyph_find_strong_points().

◆ psh_hint_table_init()

static FT_Error psh_hint_table_init ( PSH_Hint_Table  table,
PS_Hint_Table  hints,
PS_Mask_Table  hint_masks,
PS_Mask_Table  counter_masks,
FT_Memory  memory 
)
static

Definition at line 171 of file pshalgo.c.

176 {
179
180 FT_UNUSED( counter_masks );
181
182
183 count = hints->num_hints;
184
185 /* allocate our tables */
186 if ( FT_NEW_ARRAY( table->sort, 2 * count ) ||
187 FT_NEW_ARRAY( table->hints, count ) ||
188 FT_NEW_ARRAY( table->zones, 2 * count + 1 ) )
189 goto Exit;
190
191 table->max_hints = count;
192 table->sort_global = table->sort + count;
193 table->num_hints = 0;
194 table->num_zones = 0;
195 table->zone = NULL;
196
197 /* initialize the `table->hints' array */
198 {
199 PSH_Hint write = table->hints;
200 PS_Hint read = hints->hints;
201
202
203 for ( ; count > 0; count--, write++, read++ )
204 {
205 write->org_pos = read->pos;
206 write->org_len = read->len;
207 write->flags = read->flags;
208 }
209 }
210
211 /* we now need to determine the initial `parent' stems; first */
212 /* activate the hints that are given by the initial hint masks */
213 if ( hint_masks )
214 {
215 PS_Mask mask = hint_masks->masks;
216
217
218 count = hint_masks->num_masks;
219 table->hint_masks = hint_masks;
220
221 for ( ; count > 0; count--, mask++ )
223 }
224
225 /* finally, do a linear parse in case some hints were left alone */
226 if ( table->num_hints != table->max_hints )
227 {
228 FT_UInt idx;
229
230
231 FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" ));
232
233 count = table->max_hints;
234 for ( idx = 0; idx < count; idx++ )
236 }
237
238 Exit:
239 return error;
240 }
#define read
Definition: acwin.h:96
#define write
Definition: acwin.h:97
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
static void psh_hint_table_record_mask(PSH_Hint_Table table, PS_Mask hint_mask)
Definition: pshalgo.c:143
static void psh_hint_table_record(PSH_Hint_Table table, FT_UInt idx)
Definition: pshalgo.c:96
typedefFT_BEGIN_HEADER struct PS_HintRec_ * PS_Hint
Definition: pshrec.h:52
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
PS_Mask masks
Definition: pshrec.h:109
FT_UInt num_masks
Definition: pshrec.h:107

Referenced by psh_glyph_init().

◆ psh_hint_table_record()

static void psh_hint_table_record ( PSH_Hint_Table  table,
FT_UInt  idx 
)
static

Definition at line 96 of file pshalgo.c.

98 {
99 PSH_Hint hint = table->hints + idx;
100
101
102 if ( idx >= table->max_hints )
103 {
104 FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx ));
105 return;
106 }
107
108 /* ignore active hints */
109 if ( psh_hint_is_active( hint ) )
110 return;
111
113
114 /* now scan the current active hint set to check */
115 /* whether `hint' overlaps with another hint */
116 {
117 PSH_Hint* sorted = table->sort_global;
118 FT_UInt count = table->num_hints;
119 PSH_Hint hint2;
120
121
122 hint->parent = NULL;
123 for ( ; count > 0; count--, sorted++ )
124 {
125 hint2 = sorted[0];
126
127 if ( psh_hint_overlap( hint, hint2 ) )
128 {
129 hint->parent = hint2;
130 break;
131 }
132 }
133 }
134
135 if ( table->num_hints < table->max_hints )
136 table->sort_global[table->num_hints++] = hint;
137 else
138 FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" ));
139 }

Referenced by psh_hint_table_init(), and psh_hint_table_record_mask().

◆ psh_hint_table_record_mask()

static void psh_hint_table_record_mask ( PSH_Hint_Table  table,
PS_Mask  hint_mask 
)
static

Definition at line 143 of file pshalgo.c.

145 {
146 FT_Int mask = 0, val = 0;
147 FT_Byte* cursor = hint_mask->bytes;
149
150
151 limit = hint_mask->num_bits;
152
153 for ( idx = 0; idx < limit; idx++ )
154 {
155 if ( mask == 0 )
156 {
157 val = *cursor++;
158 mask = 0x80;
159 }
160
161 if ( val & mask )
163
164 mask >>= 1;
165 }
166 }

Referenced by psh_hint_table_init().