📄 ftoutln.c
字号:
/* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Done( FT_Library library, FT_Outline* outline ) { /* check for valid `outline' in FT_Outline_Done_Internal() */ if ( !library ) return FT_Err_Invalid_Library_Handle; return FT_Outline_Done_Internal( library->memory, outline ); } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) FT_Outline_Get_CBox( FT_Outline* outline, FT_BBox *acbox ) { FT_Pos xMin, yMin, xMax, yMax; if ( outline && acbox ) { if ( outline->n_points == 0 ) { xMin = 0; yMin = 0; xMax = 0; yMax = 0; } else { FT_Vector* vec = outline->points; FT_Vector* limit = vec + outline->n_points; xMin = xMax = vec->x; yMin = yMax = vec->y; vec++; for ( ; vec < limit; vec++ ) { FT_Pos x, y; x = vec->x; if ( x < xMin ) xMin = x; if ( x > xMax ) xMax = x; y = vec->y; if ( y < yMin ) yMin = y; if ( y > yMax ) yMax = y; } } acbox->xMin = xMin; acbox->xMax = xMax; acbox->yMin = yMin; acbox->yMax = yMax; } } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) FT_Outline_Translate( FT_Outline* outline, FT_Pos xOffset, FT_Pos yOffset ) { FT_UShort n; FT_Vector* vec = outline->points; for ( n = 0; n < outline->n_points; n++ ) { vec->x += xOffset; vec->y += yOffset; vec++; } } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) FT_Outline_Reverse( FT_Outline* outline ) { FT_UShort n; FT_Int first, last; first = 0; for ( n = 0; n < outline->n_contours; n++ ) { last = outline->contours[n]; /* reverse point table */ { FT_Vector* p = outline->points + first; FT_Vector* q = outline->points + last; FT_Vector swap; while ( p < q ) { swap = *p; *p = *q; *q = swap; p++; q--; } } /* reverse tags table */ { char* p = outline->tags + first; char* q = outline->tags + last; char swap; while ( p < q ) { swap = *p; *p = *q; *q = swap; p++; q--; } } first = last + 1; } outline->flags ^= FT_OUTLINE_REVERSE_FILL; } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Render( FT_Library library, FT_Outline* outline, FT_Raster_Params* params ) { FT_Error error; FT_Bool update = 0; FT_Renderer renderer; FT_ListNode node; if ( !library ) return FT_Err_Invalid_Library_Handle; if ( !params ) return FT_Err_Invalid_Argument; renderer = library->cur_renderer; node = library->renderers.head; params->source = (void*)outline; error = FT_Err_Cannot_Render_Glyph; while ( renderer ) { error = renderer->raster_render( renderer->raster, params ); if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) break; /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ /* is unsupported by the current renderer for this glyph image */ /* format */ /* now, look for another renderer that supports the same */ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); update = 1; } /* if we changed the current renderer for the glyph image format */ /* we need to select it as the next current one */ if ( !error && update && renderer ) FT_Set_Renderer( library, renderer, 0, 0 ); return error; } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, FT_Outline* outline, FT_Bitmap *abitmap ) { FT_Raster_Params params; if ( !abitmap ) return FT_Err_Invalid_Argument; /* other checks are delayed to FT_Outline_Render() */ params.target = abitmap; params.flags = 0; if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || abitmap->pixel_mode == FT_PIXEL_MODE_LCD || abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) params.flags |= FT_RASTER_FLAG_AA; return FT_Outline_Render( library, outline, ¶ms ); } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vector, FT_Matrix* matrix ) { FT_Pos xz, yz; if ( !vector || !matrix ) return; xz = FT_MulFix( vector->x, matrix->xx ) + FT_MulFix( vector->y, matrix->xy ); yz = FT_MulFix( vector->x, matrix->yx ) + FT_MulFix( vector->y, matrix->yy ); vector->x = xz; vector->y = yz; } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) FT_Outline_Transform( FT_Outline* outline, FT_Matrix* matrix ) { FT_Vector* vec = outline->points; FT_Vector* limit = vec + outline->n_points; for ( ; vec < limit; vec++ ) FT_Vector_Transform( vec, matrix ); } typedef struct FT_OrientationExtremumRec_ { FT_Int index; FT_Long pos; FT_Int first; FT_Int last; } FT_OrientationExtremumRec; static FT_Orientation ft_orientation_extremum_compute( FT_OrientationExtremumRec* extremum, FT_Outline* outline ) { FT_Vector *point, *first, *last, *prev, *next; FT_Vector* points = outline->points; FT_Angle angle_in, angle_out; /* compute the previous and next points in the same contour */ point = points + extremum->index; first = points + extremum->first; last = points + extremum->last; prev = point; next = point; do { prev = ( prev == first ) ? last : prev - 1; if ( prev == point ) return FT_ORIENTATION_TRUETYPE; /* degenerate case */ } while ( prev->x != point->x || prev->y != point->y ); do { next = ( next == last ) ? first : next + 1; if ( next == point ) return FT_ORIENTATION_TRUETYPE; /* shouldn't happen */ } while ( next->x != point->x || next->y != point->y ); /* now compute the orientation of the `out' vector relative */ /* to the `in' vector. */ angle_in = FT_Atan2( point->x - prev->x, point->y - prev->y ); angle_out = FT_Atan2( next->x - point->x, next->y - point->y ); return ( FT_Angle_Diff( angle_in, angle_out ) >= 0 ) ? FT_ORIENTATION_TRUETYPE : FT_ORIENTATION_POSTSCRIPT; } FT_EXPORT_DEF( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ) { FT_Orientation result = FT_ORIENTATION_TRUETYPE; if ( outline && outline->n_points > 0 ) { FT_OrientationExtremumRec xmin, ymin, xmax, ymax; FT_Int n; FT_Int first, last; FT_Vector* points = outline->points; xmin.pos = ymin.pos = +32768L; xmax.pos = ymax.pos = -32768L; xmin.index = ymin.index = xmax.index = ymax.index = -1; first = 0; for ( n = 0; n < outline->n_contours; n++, first = last + 1 ) { last = outline->contours[n]; /* skip single-point contours; these are degenerated cases */ if ( last > first + 1 ) { FT_Int i; for ( i = first; i < last; i++ ) { FT_Pos x = points[i].x; FT_Pos y = points[i].y; if ( x < xmin.pos ) { xmin.pos = x; xmin.index = i; xmin.first = first; xmin.last = last; } if ( x > xmax.pos ) { xmax.pos = x; xmax.index = i; xmax.first = first; xmax.last = last; } if ( y < ymin.pos ) { ymin.pos = y; ymin.index = i; ymin.first = first; ymin.last = last; } if ( y > ymax.pos ) { ymax.pos = y; ymax.index = i; ymax.first = first; ymax.last = last; } } } if ( xmin.index >= 0 ) result = ft_orientation_extremum_compute( &xmin, outline ); else if ( xmax.index >= 0 ) result = ft_orientation_extremum_compute( &xmax, outline ); else if ( ymin.index >= 0 ) result = ft_orientation_extremum_compute( &ymin, outline ); else if ( ymax.index >= 0 ) result = ft_orientation_extremum_compute( &ymax, outline ); } } return result; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -