📄 afhints.c
字号:
do { end = after; after = after->next; if ( after == first ) finished = 1; out_x = after->fx - end->fx; out_y = after->fy - end->fy; } while ( out_x == 0 && out_y == 0 ); orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y ); } while ( orient_cur == 0 ); if ( ( orient_prev + orient_cur ) == 0 ) { /* we have an inflection point here */ do { start->flags |= AF_FLAG_INFLECTION; start = start->next; } while ( start != end ); start->flags |= AF_FLAG_INFLECTION; } start = end; end = after; orient_prev = orient_cur; in_x = out_x; in_y = out_y; } while ( !finished ); Skip: ; } }#else /* old code */ static void af_glyph_hints_compute_inflections( AF_GlyphHints hints ) { AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { AF_Point point = contour[0]; AF_Point first = point; AF_Point start = point; AF_Point end = point; AF_Point before; AF_Point after; AF_Angle angle_in, angle_seg, angle_out; AF_Angle diff_in, diff_out; FT_Int finished = 0; /* compute first segment in contour */ first = point; start = end = first; do { end = end->next; if ( end == first ) goto Skip; } while ( end->fx == first->fx && end->fy == first->fy ); angle_seg = af_angle_atan( end->fx - start->fx, end->fy - start->fy ); /* extend the segment start whenever possible */ before = start; do { do { start = before; before = before->prev; if ( before == first ) goto Skip; } while ( before->fx == start->fx && before->fy == start->fy ); angle_in = af_angle_atan( start->fx - before->fx, start->fy - before->fy ); } while ( angle_in == angle_seg ); first = start; AF_ANGLE_DIFF( diff_in, angle_in, angle_seg ); /* now, process all segments in the contour */ do { /* first, extend current segment's end whenever possible */ after = end; do { do { end = after; after = after->next; if ( after == first ) finished = 1; } while ( end->fx == after->fx && end->fy == after->fy ); angle_out = af_angle_atan( after->fx - end->fx, after->fy - end->fy ); } while ( angle_out == angle_seg ); AF_ANGLE_DIFF( diff_out, angle_seg, angle_out ); if ( ( diff_in ^ diff_out ) < 0 ) { /* diff_in and diff_out have different signs, we have */ /* inflection points here... */ do { start->flags |= AF_FLAG_INFLECTION; start = start->next; } while ( start != end ); start->flags |= AF_FLAG_INFLECTION; } start = end; end = after; angle_seg = angle_out; diff_in = diff_out; } while ( !finished ); Skip: ; } }#endif /* old code */ FT_LOCAL_DEF( void ) af_glyph_hints_init( AF_GlyphHints hints, FT_Memory memory ) { FT_ZERO( hints ); hints->memory = memory; } FT_LOCAL_DEF( void ) af_glyph_hints_done( AF_GlyphHints hints ) { if ( hints && hints->memory ) { FT_Memory memory = hints->memory; int dim; /* * note that we don't need to free the segment and edge * buffers, since they are really within the hints->points array */ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { AF_AxisHints axis = &hints->axis[dim]; axis->num_segments = 0; axis->max_segments = 0; FT_FREE( axis->segments ); axis->num_edges = 0; axis->max_edges = 0; FT_FREE( axis->edges ); } FT_FREE( hints->contours ); hints->max_contours = 0; hints->num_contours = 0; FT_FREE( hints->points ); hints->num_points = 0; hints->max_points = 0; hints->memory = NULL; } } FT_LOCAL_DEF( void ) af_glyph_hints_rescale( AF_GlyphHints hints, AF_ScriptMetrics metrics ) { hints->metrics = metrics; hints->scaler_flags = metrics->scaler.flags; } FT_LOCAL_DEF( FT_Error ) af_glyph_hints_reload( AF_GlyphHints hints, FT_Outline* outline ) { FT_Error error = AF_Err_Ok; AF_Point points; FT_UInt old_max, new_max; FT_Fixed x_scale = hints->x_scale; FT_Fixed y_scale = hints->y_scale; FT_Pos x_delta = hints->x_delta; FT_Pos y_delta = hints->y_delta; FT_Memory memory = hints->memory; hints->num_points = 0; hints->num_contours = 0; hints->axis[0].num_segments = 0; hints->axis[0].num_edges = 0; hints->axis[1].num_segments = 0; hints->axis[1].num_edges = 0; /* first of all, reallocate the contours array when necessary */ new_max = (FT_UInt)outline->n_contours; old_max = hints->max_contours; if ( new_max > old_max ) { new_max = ( new_max + 3 ) & ~3; if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; hints->max_contours = new_max; } /* * then reallocate the points arrays if necessary -- * note that we reserve two additional point positions, used to * hint metrics appropriately */ new_max = (FT_UInt)( outline->n_points + 2 ); old_max = hints->max_points; if ( new_max > old_max ) { new_max = ( new_max + 2 + 7 ) & ~7; if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) goto Exit; hints->max_points = new_max; } hints->num_points = outline->n_points; hints->num_contours = outline->n_contours; /* We can't rely on the value of `FT_Outline.flags' to know the fill */ /* direction used for a glyph, given that some fonts are broken (e.g., */ /* the Arphic ones). We thus recompute it each time we need to. */ /* */ hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) { hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; } hints->x_scale = x_scale; hints->y_scale = y_scale; hints->x_delta = x_delta; hints->y_delta = y_delta; hints->xmin_delta = 0; hints->xmax_delta = 0; points = hints->points; if ( hints->num_points == 0 ) goto Exit; { AF_Point point; AF_Point point_limit = points + hints->num_points; /* compute coordinates & Bezier flags */ { FT_Vector* vec = outline->points; char* tag = outline->tags; for ( point = points; point < point_limit; point++, vec++, tag++ ) { point->fx = (FT_Short)vec->x; point->fy = (FT_Short)vec->y; point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: point->flags = AF_FLAG_CONIC; break; case FT_CURVE_TAG_CUBIC: point->flags = AF_FLAG_CUBIC; break; default: point->flags = 0; } } } /* compute `next' and `prev' */ { FT_Int contour_index; AF_Point prev; AF_Point first; AF_Point end; contour_index = 0; first = points; end = points + outline->contours[0]; prev = end; for ( point = points; point < point_limit; point++ ) { point->prev = prev; if ( point < end ) { point->next = point + 1; prev = point; } else { point->next = first; contour_index++; if ( point + 1 < point_limit ) { end = points + outline->contours[contour_index]; first = point + 1; prev = end; } } } } /* set-up the contours array */ { AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; short* end = outline->contours; short idx = 0; for ( ; contour < contour_limit; contour++, end++ ) { contour[0] = points + idx; idx = (short)( end[0] + 1 ); } } /* compute directions of in & out vectors */ { for ( point = points; point < point_limit; point++ ) { AF_Point prev; AF_Point next; FT_Pos in_x, in_y, out_x, out_y; prev = point->prev; in_x = point->fx - prev->fx; in_y = point->fy - prev->fy; point->in_dir = (FT_Char)af_direction_compute( in_x, in_y ); next = point->next; out_x = next->fx - point->fx; out_y = next->fy - point->fy; point->out_dir = (FT_Char)af_direction_compute( out_x, out_y ); if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) { Is_Weak_Point: point->flags |= AF_FLAG_WEAK_INTERPOLATION; } else if ( point->out_dir == point->in_dir ) {#if 1 if ( point->out_dir != AF_DIR_NONE ) goto Is_Weak_Point; if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) goto Is_Weak_Point;#else /* old code */ AF_Angle angle_in, angle_out, delta; if ( point->out_dir != AF_DIR_NONE ) goto Is_Weak_Point; angle_in = af_angle_atan( in_x, in_y ); angle_out = af_angle_atan( out_x, out_y ); AF_ANGLE_DIFF( delta, angle_in, angle_out ); if ( delta < 2 && delta > -2 ) goto Is_Weak_Point;#endif /* old code */ } else if ( point->in_dir == -point->out_dir ) goto Is_Weak_Point; } } } /* compute inflection points */ af_glyph_hints_compute_inflections( hints ); Exit: return error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -