📄 ahglyph.c
字号:
new_contours ) ) goto Exit; outline->max_contours = new_contours; } /* then, reallocate the points, segments & edges arrays if needed -- */ /* note that we reserved two additional point positions, used to */ /* hint metrics appropriately */ /* */ if ( num_points + 2 > outline->max_points ) { FT_Int news = ( num_points + 2 + 7 ) & -8; FT_Int max = outline->max_points; if ( FT_RENEW_ARRAY( outline->points, max, news ) || FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) || FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) ) goto Exit; /* readjust some pointers */ outline->vert_edges = outline->horz_edges + news; outline->vert_segments = outline->horz_segments + news; outline->max_points = news; } outline->num_points = num_points; outline->num_contours = num_contours; outline->num_hedges = 0; outline->num_vedges = 0; outline->num_hsegments = 0; outline->num_vsegments = 0; /* 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. */ /* */ outline->vert_major_dir = AH_DIR_UP; outline->horz_major_dir = AH_DIR_LEFT; if ( ah_get_orientation( source ) > 1 ) { outline->vert_major_dir = AH_DIR_DOWN; outline->horz_major_dir = AH_DIR_RIGHT; } outline->x_scale = x_scale; outline->y_scale = y_scale; points = outline->points; if ( outline->num_points == 0 ) goto Exit; { /* do one thing at a time -- it is easier to understand, and */ /* the code is clearer */ AH_Point point; AH_Point point_limit = points + outline->num_points; /* compute coordinates */ { FT_Vector* vec = source->points; for ( point = points; point < point_limit; vec++, point++ ) { point->fx = vec->x; point->fy = vec->y; point->ox = point->x = FT_MulFix( vec->x, x_scale ); point->oy = point->y = FT_MulFix( vec->y, y_scale ); point->flags = 0; } } /* compute Bezier flags */ { char* tag = source->tags; for ( point = points; point < point_limit; point++, tag++ ) { switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: point->flags = AH_FLAG_CONIC; break; case FT_CURVE_TAG_CUBIC: point->flags = AH_FLAG_CUBIC; break; default: ; } } } /* compute `next' and `prev' */ { FT_Int contour_index; AH_Point prev; AH_Point first; AH_Point end; contour_index = 0; first = points; end = points + source->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 + source->contours[contour_index]; first = point + 1; prev = end; } } } } /* set-up the contours array */ { AH_Point* contour = outline->contours; AH_Point* contour_limit = contour + outline->num_contours; short* end = source->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++ ) { AH_Point prev; AH_Point next; FT_Vector ivec, ovec; prev = point->prev; ivec.x = point->fx - prev->fx; ivec.y = point->fy - prev->fy; point->in_dir = ah_compute_direction( ivec.x, ivec.y ); next = point->next; ovec.x = next->fx - point->fx; ovec.y = next->fy - point->fy; point->out_dir = ah_compute_direction( ovec.x, ovec.y );#ifndef AH_OPTION_NO_WEAK_INTERPOLATION if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) ) { Is_Weak_Point: point->flags |= AH_FLAG_WEAK_INTERPOLATION; } else if ( point->out_dir == point->in_dir ) { AH_Angle angle_in, angle_out, delta; if ( point->out_dir != AH_DIR_NONE ) goto Is_Weak_Point; angle_in = ah_angle( &ivec ); angle_out = ah_angle( &ovec ); delta = angle_in - angle_out; if ( delta > AH_PI ) delta = AH_2PI - delta; if ( delta < 0 ) delta = -delta; if ( delta < 2 ) goto Is_Weak_Point; } else if ( point->in_dir == -point->out_dir ) goto Is_Weak_Point;#endif } } } Exit: return error; } FT_LOCAL_DEF( void ) ah_setup_uv( AH_Outline outline, AH_UV source ) { AH_Point point = outline->points; AH_Point point_limit = point + outline->num_points; switch ( source ) { case AH_UV_FXY: for ( ; point < point_limit; point++ ) { point->u = point->fx; point->v = point->fy; } break; case AH_UV_FYX: for ( ; point < point_limit; point++ ) { point->u = point->fy; point->v = point->fx; } break; case AH_UV_OXY: for ( ; point < point_limit; point++ ) { point->u = point->ox; point->v = point->oy; } break; case AH_UV_OYX: for ( ; point < point_limit; point++ ) { point->u = point->oy; point->v = point->ox; } break; case AH_UV_YX: for ( ; point < point_limit; point++ ) { point->u = point->y; point->v = point->x; } break; case AH_UV_OX: for ( ; point < point_limit; point++ ) { point->u = point->x; point->v = point->ox; } break; case AH_UV_OY: for ( ; point < point_limit; point++ ) { point->u = point->y; point->v = point->oy; } break; default: for ( ; point < point_limit; point++ ) { point->u = point->x; point->v = point->y; } } } /* compute all inflex points in a given glyph */ static void ah_outline_compute_inflections( AH_Outline outline ) { AH_Point* contour = outline->contours; AH_Point* contour_limit = contour + outline->num_contours; /* load original coordinates in (u,v) */ ah_setup_uv( outline, AH_UV_FXY ); /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { FT_Vector vec; AH_Point point = contour[0]; AH_Point first = point; AH_Point start = point; AH_Point end = point; AH_Point before; AH_Point after; AH_Angle angle_in, angle_seg, angle_out; AH_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->u == first->u && end->v == first->v ); vec.x = end->u - start->u; vec.y = end->v - start->v; angle_seg = ah_angle( &vec ); /* extend the segment start whenever possible */ before = start; do { do { start = before; before = before->prev; if ( before == first ) goto Skip; } while ( before->u == start->u && before->v == start->v ); vec.x = start->u - before->u; vec.y = start->v - before->v; angle_in = ah_angle( &vec ); } while ( angle_in == angle_seg ); first = start; diff_in = ah_angle_diff( 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->u == after->u && end->v == after->v ); vec.x = after->u - end->u; vec.y = after->v - end->v; angle_out = ah_angle( &vec ); } while ( angle_out == angle_seg ); diff_out = ah_angle_diff( 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 |= AH_FLAG_INFLECTION; start = start->next; } while ( start != end ); start->flags |= AH_FLAG_INFLECTION; } start = end; end = after; angle_seg = angle_out; diff_in = diff_out; } while ( !finished ); Skip: ; } } FT_LOCAL_DEF( void ) ah_outline_compute_segments( AH_Outline outline ) { int dimension; AH_Segment segments; FT_Int* p_num_segments; AH_Direction segment_dir; AH_Direction major_dir; segments = outline->horz_segments; p_num_segments = &outline->num_hsegments; major_dir = AH_DIR_RIGHT; /* This value must be positive! */ segment_dir = major_dir; /* set up (u,v) in each point */ ah_setup_uv( outline, AH_UV_FYX ); for ( dimension = 1; dimension >= 0; dimension-- ) { AH_Point* contour = outline->contours; AH_Point* contour_limit = contour + outline->num_contours; AH_Segment segment = segments; FT_Int num_segments = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -