📄 ftoutln.c
字号:
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( const 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( const FT_Outline* outline, FT_Pos xOffset, FT_Pos yOffset ) { FT_UShort n; FT_Vector* vec = outline->points; if ( !outline ) return; 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; if ( !outline ) return; 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 ( !outline || !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, const 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, const 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( const FT_Outline* outline, const FT_Matrix* matrix ) { FT_Vector* vec; FT_Vector* limit; if ( !outline || !matrix ) return; vec = outline->points; limit = vec + outline->n_points; for ( ; vec < limit; vec++ ) FT_Vector_Transform( vec, matrix ); } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ) { FT_Vector* points; FT_Vector v_prev, v_first, v_next, v_cur; FT_Angle rotate, angle_in, angle_out; FT_Int c, n, first; if ( !outline ) return FT_Err_Invalid_Argument; if ( strength == 0 ) return FT_Err_Ok; if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_TRUETYPE ) rotate = -FT_ANGLE_PI2; else rotate = FT_ANGLE_PI2; points = outline->points; first = 0; for ( c = 0; c < outline->n_contours; c++ ) { int last = outline->contours[c]; v_first = points[first]; v_prev = points[last]; v_cur = v_first; for ( n = first; n <= last; n++ ) { FT_Vector in, out; FT_Angle angle_diff; FT_Pos d; FT_Fixed scale; if ( n < last ) v_next = points[n + 1]; else v_next = v_first; /* compute the in and out vectors */ in.x = v_cur.x - v_prev.x; in.y = v_cur.y - v_prev.y; out.x = v_next.x - v_cur.x; out.y = v_next.y - v_cur.y; angle_in = FT_Atan2( in.x, in.y ); angle_out = FT_Atan2( out.x, out.y ); angle_diff = FT_Angle_Diff( angle_in, angle_out ); scale = FT_Cos( angle_diff / 2 ); if ( scale < 0x4000L && scale > -0x4000L ) in.x = in.y = 0; else { d = FT_DivFix( strength, scale ); FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate ); } outline->points[n].x = v_cur.x + strength + in.x; outline->points[n].y = v_cur.y + strength + in.y; v_prev = v_cur; v_cur = v_next; } first = last + 1; } return FT_Err_Ok; } /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ) { FT_Pos xmin = 32768L; FT_Vector* xmin_point = NULL; FT_Vector* xmin_first = NULL; FT_Vector* xmin_last = NULL; short* contour; FT_Vector* first; FT_Vector* last; FT_Vector* prev; FT_Vector* next; if ( !outline || outline->n_points <= 0 ) return FT_ORIENTATION_TRUETYPE; first = outline->points; for ( contour = outline->contours; contour < outline->contours + outline->n_contours; contour++, first = last + 1 ) { FT_Vector* point; last = outline->points + *contour; /* skip degenerate contours */ if ( last < first + 2 ) continue; for ( point = first; point <= last; point++ ) { if ( point->x < xmin ) { xmin = point->x; xmin_point = point; xmin_first = first; xmin_last = last; } } } if ( !xmin_point ) return FT_ORIENTATION_TRUETYPE; prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1; next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1; if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) return FT_ORIENTATION_POSTSCRIPT; else return FT_ORIENTATION_TRUETYPE; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -