/***************************************************************************/ /* */ /* ftoutln.c */ /* */ /* FreeType outline management (body). */ /* */ /* Copyright 1996-1999 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ /* modified and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* All functions are declared in freetype.h. */ /* */ /*************************************************************************/ #include #include #include #include #include /*************************************************************************/ /* */ /* */ /* FT_Copy_Outline */ /* */ /* */ /* Copies an outline into another one. Both objects must have the */ /* same sizes (number of points & number of contours) when this */ /* function is called. */ /* */ /* */ /* source :: A handle to the source outline. */ /* target :: A handle to the target outline. */ /* */ /* */ /* FreeType error code. 0 means success. */ /* */ BASE_FUNC FT_Error FT_Copy_Outline( FT_Outline* source, FT_Outline* target ) { if ( !source || !target || source->n_points != target->n_points || source->n_contours != target->n_contours ) return FT_Err_Invalid_Argument; MEM_Copy( target->points, source->points, source->n_points * 2 * sizeof ( FT_Pos ) ); MEM_Copy( target->flags, source->flags, source->n_points * sizeof ( FT_Byte ) ); MEM_Copy( target->contours, source->contours, source->n_contours * sizeof ( FT_Short ) ); target->high_precision = source->high_precision; target->second_pass = target->second_pass; target->dropout_mode = source->dropout_mode; return FT_Err_Ok; } /*************************************************************************/ /* */ /* */ /* FT_Get_Outline_Bitmap */ /* */ /* */ /* Renders an outline within a bitmap. The outline's image is simply */ /* or-ed to the target bitmap. */ /* */ /* */ /* */ /* library :: A handle to a FreeType library object. */ /* outline :: A pointer to the source outline descriptor. */ /* map :: A pointer to the target bitmap descriptor. */ /* */ /* */ /* FreeType error code. 0 means success. */ /* */ /* */ /* YES. Rendering is synchronized, so that concurrent calls to the */ /* scan-line converter will be serialized. */ /* */ /* */ /* This function does NOT CREATE the bitmap, it only renders an */ /* outline image within the one you pass to it! */ /* */ /* It will use the raster correponding to the default glyph format. */ /* */ BASE_FUNC FT_Error FT_Get_Outline_Bitmap( FT_Library library, FT_Outline* outline, FT_Bitmap* map ) { FT_Error error; FT_Glyph_Format* format; error = FT_Err_Invalid_Glyph_Format; format = FT_Get_Glyph_Format( library, ft_glyph_format_outline ); if (!format) goto Exit; error = FT_Err_Invalid_Glyph_Format; if (!format->raster) goto Exit; error = format->raster_interface->render( format->raster, outline, map ); Exit: return error; } /*************************************************************************/ /* */ /* */ /* FT_Transform_Outline */ /* */ /* */ /* Applies a simple 2x2 matrix to all of an outline's points. Useful */ /* for applying rotations, slanting, flipping, etc. */ /* */ /* */ /* outline :: A pointer to the target outline descriptor. */ /* matrix :: A pointer to the transformation matrix. */ /* */ /* */ /* Yes. */ /* */ /* */ /* You can use FT_Translate_Outline() if you need to translate the */ /* outline's points. */ /* */ BASE_FUNC void FT_Transform_Outline( FT_Outline* outline, FT_Matrix* matrix ) { FT_UShort n; FT_Vector* vec; vec = outline->points; for ( n = 0; n < outline->n_points; n++ ) { FT_Pos x, y; x = FT_MulFix( vec->x, matrix->xx ) + FT_MulFix( vec->y, matrix->xy ); y = FT_MulFix( vec->x, matrix->yx ) + FT_MulFix( vec->y, matrix->yy ); vec->x = x; vec->y = y; vec++; } } /*************************************************************************/ /* */ /* */ /* FT_Transform_Vector */ /* */ /* */ /* Transforms a single vector through a 2x2 matrix. */ /* */ /* */ /* x :: The horizontal vector coordinate. */ /* y :: The vertical vector coordinate. */ /* */ /* */ /* matrix :: A pointer to the source 2x2 matrix. */ /* */ /* */ /* Yes. */ /* */ BASE_FUNC void FT_Transform_Vector( FT_Pos* x, FT_Pos* y, FT_Matrix* matrix ) { FT_Pos xz, yz; xz = FT_MulFix( *x, matrix->xx ) + FT_MulFix( *y, matrix->xy ); yz = FT_MulFix( *x, matrix->yx ) + FT_MulFix( *y, matrix->yy ); *x = xz; *y = yz; } /*************************************************************************/ /* */ /* */ /* FT_Matrix_Multiply */ /* */ /* */ /* Performs the matrix operation `b = a*b'. */ /* */ /* */ /* a :: A pointer to matrix `a'. */ /* */ /* */ /* b :: A pointer to matrix `b'. */ /* */ /* */ /* Yes. */ /* */ BASE_FUNC void FT_Matrix_Multiply( FT_Matrix* a, FT_Matrix* b ) { FT_Fixed xx, xy, yx, yy; xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); b->xx = xx; b->xy = xy; b->yx = yx; b->yy = yy; } /*************************************************************************/ /* */ /* */ /* FT_Matrix_Invert */ /* */ /* */ /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ /* */ /* */ /* matrix :: A pointer to the target matrix. Remains untouched in */ /* case of error. */ /* */ /* */ /* FreeType error code. 0 means success. */ /* */ /* */ /* Yes. */ /* */ BASE_FUNC FT_Error FT_Matrix_Invert( FT_Matrix* matrix ) { FT_Pos delta, xx, yy; /* compute discriminant */ delta = FT_MulFix( matrix->xx, matrix->yy ) - FT_MulFix( matrix->xy, matrix->yx ); if ( !delta ) return FT_Err_Invalid_Argument; /* matrix can't be inverted */ matrix->xy = - FT_DivFix( matrix->xy, delta ); matrix->yx = - FT_DivFix( matrix->yx, delta ); xx = matrix->xx; yy = matrix->yy; matrix->xx = FT_DivFix( yy, delta ); matrix->yy = FT_DivFix( xx, delta ); return FT_Err_Ok; } /* END */