diff --git a/ChangeLog b/ChangeLog index 78beb6ba2..9c746353f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,9 +36,10 @@ will ignore stem quantization only when FT_LOAD_TARGET_SMOOTH is used. - * src/base/ftobjs.c: Changed the default computations to include - rounding in all cases; this is required to provide accurate kerning - data when native TrueType hinting is enabled. + * src/base/ftobjs.c (FT_Set_Char_Size): Changed the default + computations to include rounding in all cases; this is required to + provide accurate kerning data when native TrueType hinting is + enabled. * src/type1/t1load.c: The Type 1 loader now accepts more general names according to the PostScript specification (the previous one @@ -71,9 +72,11 @@ * include/freetype/internal/ftobjs.h (ft_glyphslot_free_bitmap, ft_glyphslot_alloc_bitmap, ft_glyphslot_set_bitmap): New functions. - * src/base/ftobjs.c, src/bdf/bdfdrivr.c, src/pcf/pcfdriver.c, - src/pfr/pfrsbit.c, src/sfnt/ttsbit.c, src/type42/t42objs.c, - src/winfonts/winfnt.c: + * src/base/ftobjs.c: Implement them. + (ft_glyphslot_done): Use ft_glyphslot_free_bitmap. + + * src/bdf/bdfdrivr.c, src/pcf/pcfdriver.c, src/pfr/pfrsbit.c, + src/sfnt/ttsbit.c, src/type42/t42objs.c, src/winfonts/winfnt.c: * src/cache/ftlru.c: Fixed an invalid assertion check. @@ -99,10 +102,16 @@ 2003-03-13 David Turner - * src/base/ftdbgmem.c, docs/DEBUG.TXT: Added new environment - variables to control memory debugging with FreeType. See the - description of "FT2_DEBUG_MEMORY", "FT2_ALLOC_TOTAL_MAX" and - "FT2_ALLOC_COUNT_MAX" in DEBUG.TXT. + Added new environment variables to control memory debugging with + FreeType. See the description of "FT2_DEBUG_MEMORY", + "FT2_ALLOC_TOTAL_MAX" and "FT2_ALLOC_COUNT_MAX" in DEBUG.TXT. + + * src/base/ftdbgmem.c (FT_MemTableRec): Add `alloc_count', + `bound_total', `alloc_total_max', `bound_count', `alloc_count_max'. + (ft_mem_debug_alloc): Handle new variables. + (ft_mem_debug_init): s/FT_DEBUG_MEMORY/FT2_DEBUG_MEMORY/. + Handle new environment variables. + * docs/DEBUG.TXT: Updated. * src/cache/ftccache.c, src/cache/ftccmap.c, src/cache/ftcsbits.c, src/cache/ftlru.c: Fixed the cache sub-system to correctly deal with @@ -166,11 +175,14 @@ 2003-02-18 David Turner - * src/truetype/ttdriver.c, src/truetype/ttobjs.h, - src/truetype/ttobjs.c, src/truetype/ttinterp.c, src/base/ftobjs.c: - Fixing the slight distortion problem that ocurred due to the latest + Fixing the slight distortion problem that occurred due to the latest auto-hinter changes. + * src/base/ftobjs.c (ft_recompute_scaled_metrics): Fix rounding. + + * src/truetype/ttdriver.c, src/truetype/ttobjs.h, + src/truetype/ttobjs.c, src/truetype/ttinterp.c: + * src/autohint/ahhint.c (ah_hinter_load): Disabled the advance width "correction" which seemed to provide more trouble than benefits. @@ -214,7 +226,9 @@ the top of non-capital letters is aligned on a pixel boundary whenever possible. - * src/base/ftobjs.c, src/truetype/ttobjs.c: + * src/base/ftobjs.c (FT_Set_Char_Size) + [FT_CONFIG_CHESTER_BLUE_SCALE]: Round differently. + * src/truetype/ttobjs.c: * src/pshinter/pshalgo3.c: Improved the Postscript hinter. Getting rid of stem snapping seems to work well here (though the stems are @@ -238,8 +252,12 @@ FT_Get_BDF_Property): New function. * include/freetype/internal/bdftypes.h: Include FT_BDF_H. (BDF_GetPropertyFunc): New function pointer. - src/base/ftbdf.c, src/bdf/bdfdrivr.c, src/pcf/pcfdrivr.c, - src/pcf/pcfread.h: + + * src/base/ftbdf.c (test_font_type): New helper function. + (FT_Get_BDF_Charset_ID): Use `test_font_type'. + (FT_Get_BDF_Property): New function. + + * src/bdf/bdfdrivr.c, src/pcf/pcfdrivr.c, src/pcf/pcfread.h: * src/sfnt/ttload.c (sfnt_dir_check): Relaxed the "head" table size verification to accept a few broken fonts who pad the size @@ -279,9 +297,11 @@ * include/freetype/internal/fnttypes.h: Move Windows FNT definition to... * include/freetype/ftwinfnt.h: This new file. - * include/freetype/internal/fnttypes.h, src/base/winfnt.c, - src/winfonts/winfnt.c, src/base/Jamfile, src/base/rules.mk, - src/base/descrip.mms: + * src/base/ftwinfnt.c: New file, providing `FT_Get_WinFNT_Header'. + * src/winfonts/winfnt.c: + + * src/base/Jamfile, src/base/descrip.mms, src/base/rules.mk: + Updated. 2003-01-14 Graham Asher @@ -353,6 +373,7 @@ returned when the font doesn't contain a Unicode charmap. This allows FT2 to load "symbol.ttf" and a few others correctly since the last release. + (open_face): Fix return value. 2003-01-08 Owen Taylor @@ -382,6 +403,11 @@ * src/base/ftstroker.c: Probably the last bug-fixes to the stroker; the API is likely to change, however. + (ft_stroke_border_close): Don't record empty paths. + (ft_stroke_border_get_counts): Increase `num_points' also in for loop. + (ft_stroke_border_export): Don't increase `write' twice in for loops. + (ft_stroker_outside): Handle `phi' together with `theta'. + (FT_Stroker_ParseOutline): New function. * src/base/fttrigon.c (FT_Angle_Diff): Fixing function: It returned invalid values for large negative angle differences (resulting in @@ -391,7 +417,7 @@ assertion, and changing code to avoid hash table size contraction. * src/base/Jamfile, src/base/rules.mk, src/base/descrip.mms: Adding - "ftstroker.obj" to default build, as optional component. + "ftstroker" to default build, as optional component. 2002-12-26 David Turner @@ -417,6 +443,7 @@ function pointer. * include/freetype/tttables.h (FT_Load_Sfnt_Table): New function. + * src/base/ftobjs.c: Implement it. 2002-12-17 David Turner @@ -443,9 +470,9 @@ * src/base/ftobjs.c: Modified the logic to get Unicode charmaps. Now it loads UCS-4 charmaps when there is one. - * src/base/ftobjs.c (find_unicode_charmap): New function. - * src/base/ftobjs.c (open_face): Refer to the above one. - * src/base/ftobjs.c (FT_Select_Charmap): Idem. + (find_unicode_charmap): New function. + (open_face): Refer to the above one. + (FT_Select_Charmap): Idem. 2002-11-29 Antoine Leca @@ -538,6 +565,29 @@ * src/psaux/psobjs.c (ps_table_add): Modified increment loop in order to implement exponential behaviour. +2002-11-01 David Turner + + Added PFR-specific public API. Fixed the kerning retrievel routine + (it returned invalid values when the outline and metrics resolution + differ). + + * include/freetype/ftpfr.h, include/freetype/internal/pfr.h: New + files. + + * include/freetype/internal/internal.h (FT_INTERNAL_PFR_H): New + macro for pfr.h. + + src/base/ftpfr.c: New file. + + * src/base/Jamfile, src/base/descrip.mms: Updated. + + * src/base/ftobjs.c (ft_glyphslot_clear): Small internal fix to + better support bitmap-based font formats. + + * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Fix handling of + `scale'. + Fix arguments to `FT_Vector_From_Polar'. + 2002-10-31 David Turner * include/freetype/ftgzip.h, src/gzip/ftgzip.c: New files, adding @@ -550,9 +600,6 @@ * include/freetype/internal/pcftypes.h (PCF_Public_FaceRec): Add `gzip_stream' and `gzip_source'. - * include/freetype/ftpfr.h, include/freetype/internal/pfr.h: New - files. - * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_USE_ZLIB): New macro. (T1_CONFIG_OPTION_DISABLE_HINTER, FT_CONFIG_OPTION_USE_CMAPS @@ -564,8 +611,6 @@ that platform specific configuration file can override. * include/freetype/internal/ftstream.h: Include FT_SYSTEM_H. - * include/freetype/internal/internal.h (FT_INTERNAL_PFR_H): New - macro for pfr.h. 2002-10-30 David Turner diff --git a/src/base/ftbdf.c b/src/base/ftbdf.c index 3e76e9f32..54e73d444 100644 --- a/src/base/ftbdf.c +++ b/src/base/ftbdf.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,13 +20,16 @@ #include FT_INTERNAL_BDF_TYPES_H #include FT_INTERNAL_OBJECTS_H + static FT_Bool - test_font_type( FT_Face face, const char* name ) + test_font_type( FT_Face face, + const char* name ) { if ( face && face->driver ) { FT_Module driver = (FT_Module)face->driver; + if ( driver->clazz && driver->clazz->module_name ) { if ( ft_strcmp( driver->clazz->module_name, name ) == 0 ) @@ -74,7 +77,8 @@ const char* prop_name, BDF_PropertyRec *aproperty ) { - FT_Error error; + FT_Error error; + error = FT_Err_Invalid_Argument; @@ -82,15 +86,17 @@ if ( face != NULL && face->driver != NULL ) { - FT_Driver driver = face->driver; - BDF_GetPropertyFunc func; + FT_Driver driver = face->driver; + BDF_GetPropertyFunc func; - func = (BDF_GetPropertyFunc) driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_bdf_property" ); + + func = (BDF_GetPropertyFunc)driver->root.clazz->get_interface( + FT_MODULE( driver ), "get_bdf_property" ); if ( func ) error = func( face, prop_name, aproperty ); } return error; } + /* END */ diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index 15d186a20..dc4a1bbf2 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index dbd31ea82..047aacda1 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,7 +57,7 @@ FT_EXPORT_DEF( void ) FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix* b ) + FT_Matrix *b ) { FT_Fixed xx, xy, yx, yy; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 40fd28604..08708d12a 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -260,7 +260,7 @@ slot->bitmap.rows = 0; slot->bitmap.pitch = 0; slot->bitmap.pixel_mode = 0; - /* don't touch 'slot->bitmap.buffer' !! */ + /* don't touch 'slot->bitmap.buffer'! */ slot->bitmap_left = 0; slot->bitmap_top = 0; @@ -748,11 +748,11 @@ /* */ /* This function finds a Unicode charmap, if there is one. */ /* And if there is more than one, it tries to favour the more */ - /* extensive one, i.e. one that supports UCS-4 against those which */ + /* extensive one, i.e., one that supports UCS-4 against those which */ /* are limited to the BMP (said UCS-2 encoding.) */ /* */ /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( , FT_ENCODING_UNICODE). */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE). */ /* */ static FT_Error find_unicode_charmap( FT_Face face ) @@ -771,26 +771,26 @@ return FT_Err_Invalid_CharMap_Handle; /* - * the original TrueType specification(s) only specified charmap + * The original TrueType specification(s) only specified charmap * formats that are capable of mapping 8 or 16 bit character codes to * glyph indices. * - * however, recent updates to the Apple and OpenType specifications + * However, recent updates to the Apple and OpenType specifications * introduced new formats that are capable of mapping 32-bit character - * codes as well. And these are already used on some fonts, mainly to + * codes as well. And these are already used on some fonts, mainly to * map non-BMP Asian ideographs as defined in Unicode. * - * for compatibility purposes, these fonts generally come with + * For compatibility purposes, these fonts generally come with * *several* Unicode charmaps: * - * - one of them in the "old" 16-bit format, that cannot access - * all glyphs in the font + * - One of them in the "old" 16-bit format, that cannot access + * all glyphs in the font. * - * - another one in the "new" 32-bit format, that can access all + * - Another one in the "new" 32-bit format, that can access all * the glyphs. * - * this function has been written to always favor a 32-bit charmap - * when found. Otherwise, a 16-bit one is returned when found + * This function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found. */ /* since the `interesting' table, with id's 3,10, is normally the */ @@ -1570,10 +1570,10 @@ if ( !face ) return FT_Err_Invalid_Face_Handle; - /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ - /* charmap available, i.e. one with UCS-4 characters, if possible. */ - /* */ - /* This is done by find_unicode_charmap() above, to share code. */ + /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ + /* charmap available, i.e., one with UCS-4 characters, if possible. */ + /* */ + /* This is done by find_unicode_charmap() above, to share code. */ if ( encoding == FT_ENCODING_UNICODE ) return find_unicode_charmap( face ); @@ -1906,11 +1906,11 @@ /* documentation is in tttables.h */ FT_EXPORT_DEF( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) { SFNT_Load_Table_Func func; FT_Driver driver; diff --git a/src/base/ftpfr.c b/src/base/ftpfr.c index bf2c2a2a5..d9594cb78 100644 --- a/src/base/ftpfr.c +++ b/src/base/ftpfr.c @@ -2,9 +2,9 @@ /* */ /* ftpfr.c */ /* */ -/* FreeType API for accessing PFR-specific data */ +/* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,18 +20,20 @@ #include FT_INTERNAL_OBJECTS_H - /* check the format */ + /* check the format */ static FT_Error - ft_pfr_check( FT_Face face, - FT_PFR_Service *aservice ) + ft_pfr_check( FT_Face face, + FT_PFR_Service *aservice ) { FT_Error error = FT_Err_Bad_Argument; + if ( face && face->driver ) { FT_Module module = (FT_Module) face->driver; const char* name = module->clazz->module_name; + if ( name[0] == 'p' && name[1] == 'f' && name[2] == 'r' && @@ -45,17 +47,17 @@ } - FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Metrics( FT_Face face, - FT_UInt *aoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) { FT_Error error; FT_PFR_Service service; + error = ft_pfr_check( face, &service ); if ( !error ) { @@ -68,6 +70,7 @@ return error; } + FT_EXPORT_DEF( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, FT_UInt left, @@ -77,6 +80,7 @@ FT_Error error; FT_PFR_Service service; + error = ft_pfr_check( face, &service ); if ( !error ) { @@ -87,13 +91,14 @@ FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Advance( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) { FT_Error error; FT_PFR_Service service; + error = ft_pfr_check( face, &service ); if ( !error ) { @@ -102,4 +107,5 @@ return error; } + /* END */ diff --git a/src/base/ftstroker.c b/src/base/ftstroker.c index 712020e78..66fe19a43 100644 --- a/src/base/ftstroker.c +++ b/src/base/ftstroker.c @@ -1,9 +1,28 @@ +/***************************************************************************/ +/* */ +/* ftstroker.c */ +/* */ +/* FreeType path stroker (body). */ +/* */ +/* Copyright 2002, 2003 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. */ +/* */ +/***************************************************************************/ + + #include #include FT_STROKER_H #include FT_TRIGONOMETRY_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H + /***************************************************************************/ /***************************************************************************/ /***** *****/ @@ -12,18 +31,20 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_SMALL_CONIC_THRESHOLD (FT_ANGLE_PI/6) -#define FT_SMALL_CUBIC_THRESHOLD (FT_ANGLE_PI/6) +#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) +#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 6 ) #define FT_EPSILON 2 -#define FT_IS_SMALL(x) ((x) > -FT_EPSILON && (x) < FT_EPSILON) +#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) + static FT_Pos ft_pos_abs( FT_Pos x ) { - return x >= 0 ? x : -x ; + return x >= 0 ? x : -x ; } + static void ft_conic_split( FT_Vector* base ) { @@ -32,15 +53,15 @@ base[4].x = base[2].x; b = base[1].x; - a = base[3].x = ( base[2].x + b )/2; - b = base[1].x = ( base[0].x + b )/2; - base[2].x = ( a + b )/2; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; base[4].y = base[2].y; b = base[1].y; - a = base[3].y = ( base[2].y + b )/2; - b = base[1].y = ( base[0].y + b )/2; - base[2].y = ( a + b )/2; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; } @@ -53,22 +74,23 @@ FT_Angle theta; FT_Int close1, close2; + d1.x = base[1].x - base[2].x; d1.y = base[1].y - base[2].y; d2.x = base[0].x - base[1].x; d2.y = base[0].y - base[1].y; - close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); - close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - if (close1) + if ( close1 ) { - if (close2) + if ( close2 ) *angle_in = *angle_out = 0; else *angle_in = *angle_out = FT_Atan2( d2.x, d2.y ); } - else if (close2) + else if ( close2 ) { *angle_in = *angle_out = FT_Atan2( d1.x, d1.y ); } @@ -93,22 +115,22 @@ base[6].x = base[3].x; c = base[1].x; d = base[2].x; - base[1].x = a = ( base[0].x + c )/2; - base[5].x = b = ( base[3].x + d )/2; - c = ( c + d )/2; - base[2].x = a = ( a + c )/2; - base[4].x = b = ( b + c )/2; - base[3].x = ( a + b )/2; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; base[6].y = base[3].y; c = base[1].y; d = base[2].y; - base[1].y = a = ( base[0].y + c )/2; - base[5].y = b = ( base[3].y + d )/2; - c = ( c + d )/2; - base[2].y = a = ( a + c )/2; - base[4].y = b = ( b + c )/2; - base[3].y = ( a + b )/2; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; } @@ -122,6 +144,7 @@ FT_Angle theta1, theta2; FT_Int close1, close2, close3; + d1.x = base[2].x - base[3].x; d1.y = base[2].y - base[3].y; d2.x = base[1].x - base[2].x; @@ -129,18 +152,18 @@ d3.x = base[0].x - base[1].x; d3.y = base[0].y - base[1].y; - close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); - close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); - close3 = FT_IS_SMALL(d3.x) && FT_IS_SMALL(d3.y); + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); - if (close1 || close3) + if ( close1 || close3 ) { - if (close2) + if ( close2 ) { /* basically a point */ *angle_in = *angle_out = *angle_mid = 0; } - else if (close1) + else if ( close1 ) { *angle_in = *angle_mid = FT_Atan2( d2.x, d2.y ); *angle_out = FT_Atan2( d3.x, d3.y ); @@ -151,7 +174,7 @@ *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y ); } } - else if (close2) + else if ( close2 ) { *angle_in = *angle_mid = FT_Atan2( d1.x, d1.y ); *angle_out = FT_Atan2( d3.x, d3.y ); @@ -162,6 +185,7 @@ *angle_mid = FT_Atan2( d2.x, d2.y ); *angle_out = FT_Atan2( d3.x, d3.y ); } + theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); @@ -170,7 +194,6 @@ } - /***************************************************************************/ /***************************************************************************/ /***** *****/ @@ -189,7 +212,7 @@ } FT_StrokeTags; - typedef struct FT_StrokeBorderRec_ + typedef struct FT_StrokeBorderRec_ { FT_UInt num_points; FT_UInt max_points; @@ -210,13 +233,15 @@ FT_UInt new_max = border->num_points + new_points; FT_Error error = 0; + if ( new_max > old_max ) { FT_UInt cur_max = old_max; FT_Memory memory = border->memory; + while ( cur_max < new_max ) - cur_max += (cur_max >> 1) + 16; + cur_max += ( cur_max >> 1 ) + 16; if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) @@ -228,16 +253,17 @@ return error; } + static void ft_stroke_border_close( FT_StrokeBorder border ) { FT_ASSERT( border->start >= 0 ); - /* don't record empty paths !! */ + /* don't record empty paths! */ if ( border->num_points > (FT_UInt)border->start ) { - border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN; - border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END; + border->tags[border->start ] |= FT_STROKE_TAG_BEGIN; + border->tags[border->num_points - 1] |= FT_STROKE_TAG_END; } border->start = -1; @@ -252,22 +278,24 @@ { FT_Error error = 0; + FT_ASSERT( border->start >= 0 ); if ( border->movable ) { /* move last point */ - border->points[ border->num_points-1 ] = *to; + border->points[border->num_points - 1] = *to; } else { /* add one point */ error = ft_stroke_border_grow( border, 1 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; + vec[0] = *to; tag[0] = FT_STROKE_TAG_ON; @@ -286,10 +314,11 @@ { FT_Error error; + FT_ASSERT( border->start >= 0 ); error = ft_stroke_border_grow( border, 2 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; @@ -315,14 +344,16 @@ { FT_Error error; + FT_ASSERT( border->start >= 0 ); error = ft_stroke_border_grow( border, 3 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; + vec[0] = *control1; vec[1] = *control2; vec[2] = *to; @@ -338,7 +369,7 @@ } -#define FT_ARC_CUBIC_ANGLE (FT_ANGLE_PI/2) +#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) static FT_Error @@ -353,6 +384,7 @@ FT_Fixed length; FT_Error error = 0; + /* compute start point */ FT_Vector_From_Polar( &a, radius, angle_start ); a.x += center->x; @@ -362,11 +394,11 @@ angle = angle_start; rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; - while (total != 0) + while ( total != 0 ) { step = total; if ( step > FT_ARC_CUBIC_ANGLE ) - step = FT_ARC_CUBIC_ANGLE; + step = FT_ARC_CUBIC_ANGLE; else if ( step < -FT_ARC_CUBIC_ANGLE ) step = -FT_ARC_CUBIC_ANGLE; @@ -384,8 +416,8 @@ b.y += center->y; /* compute first and second control points */ - length = FT_MulDiv( radius, FT_Sin(theta)*4, - (0x10000L + FT_Cos(theta))*3 ); + length = FT_MulDiv( radius, FT_Sin( theta ) * 4, + ( 0x10000L + FT_Cos( theta ) ) * 3 ); FT_Vector_From_Polar( &a2, length, angle + rotate ); a2.x += a.x; @@ -397,13 +429,15 @@ /* add cubic arc */ error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); - if (error) break; + if ( error ) + break; /* process the rest of the arc ?? */ a = b; total -= step; angle = next; } + return error; } @@ -423,139 +457,144 @@ } - static void - ft_stroke_border_init( FT_StrokeBorder border, - FT_Memory memory ) - { - border->memory = memory; - border->points = NULL; - border->tags = NULL; + static void + ft_stroke_border_init( FT_StrokeBorder border, + FT_Memory memory ) + { + border->memory = memory; + border->points = NULL; + border->tags = NULL; - border->num_points = 0; - border->max_points = 0; - border->start = -1; - } + border->num_points = 0; + border->max_points = 0; + border->start = -1; + } - static void - ft_stroke_border_reset( FT_StrokeBorder border ) - { - border->num_points = 0; - border->start = -1; - } + static void + ft_stroke_border_reset( FT_StrokeBorder border ) + { + border->num_points = 0; + border->start = -1; + } - static void - ft_stroke_border_done( FT_StrokeBorder border ) - { - FT_Memory memory = border->memory; - - FT_FREE( border->points ); - FT_FREE( border->tags ); - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - } + static void + ft_stroke_border_done( FT_StrokeBorder border ) + { + FT_Memory memory = border->memory; - static FT_Error - ft_stroke_border_get_counts( FT_StrokeBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_Error error = 0; - FT_UInt num_points = 0; - FT_UInt num_contours = 0; + FT_FREE( border->points ); + FT_FREE( border->tags ); - FT_UInt count = border->num_points; - FT_Vector* point = border->points; - FT_Byte* tags = border->tags; - FT_Int in_contour = 0; - - for ( ; count > 0; count--, num_points++, point++, tags++ ) - { - if ( tags[0] & FT_STROKE_TAG_BEGIN ) - { - if ( in_contour != 0 ) - goto Fail; - - in_contour = 1; - } - else if ( in_contour == 0 ) - goto Fail; - - if ( tags[0] & FT_STROKE_TAG_END ) - { - if ( in_contour == 0 ) - goto Fail; - - in_contour = 0; - num_contours++; - } - } - if ( in_contour != 0 ) - goto Fail; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - - Fail: - num_points = 0; - num_contours = 0; - goto Exit; - } + border->num_points = 0; + border->max_points = 0; + border->start = -1; + } - static void - ft_stroke_border_export( FT_StrokeBorder border, - FT_Outline* outline ) - { - /* copy point locations */ - FT_MEM_COPY( outline->points + outline->n_points, - border->points, - border->num_points * sizeof(FT_Vector) ); + static FT_Error + ft_stroke_border_get_counts( FT_StrokeBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_Error error = 0; + FT_UInt num_points = 0; + FT_UInt num_contours = 0; - /* copy tags */ - { - FT_UInt count = border->num_points; - FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*) outline->tags + outline->n_points; + FT_UInt count = border->num_points; + FT_Vector* point = border->points; + FT_Byte* tags = border->tags; + FT_Int in_contour = 0; - for ( ; count > 0; count--, read++, write++ ) - { - if ( *read & FT_STROKE_TAG_ON ) - *write = FT_CURVE_TAG_ON; - else if ( *read & FT_STROKE_TAG_CUBIC ) - *write = FT_CURVE_TAG_CUBIC; - else - *write = FT_CURVE_TAG_CONIC; - } - } - /* copy contours */ - { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short index = (FT_Short) outline->n_points; + for ( ; count > 0; count--, num_points++, point++, tags++ ) + { + if ( tags[0] & FT_STROKE_TAG_BEGIN ) + { + if ( in_contour != 0 ) + goto Fail; - for ( ; count > 0; count--, tags++, index++ ) - { - if ( *tags & FT_STROKE_TAG_END ) - { - *write++ = index; - outline->n_contours++; - } - } - } + in_contour = 1; + } + else if ( in_contour == 0 ) + goto Fail; + + if ( tags[0] & FT_STROKE_TAG_END ) + { + if ( in_contour == 0 ) + goto Fail; - outline->n_points = (short)( outline->n_points + border->num_points ); + in_contour = 0; + num_contours++; + } + } - FT_ASSERT( FT_Outline_Check( outline ) == 0 ); - } + if ( in_contour != 0 ) + goto Fail; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + + Fail: + num_points = 0; + num_contours = 0; + goto Exit; + } + + + static void + ft_stroke_border_export( FT_StrokeBorder border, + FT_Outline* outline ) + { + /* copy point locations */ + FT_MEM_COPY( outline->points + outline->n_points, + border->points, + border->num_points * sizeof ( FT_Vector ) ); + + /* copy tags */ + { + FT_UInt count = border->num_points; + FT_Byte* read = border->tags; + FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + + + for ( ; count > 0; count--, read++, write++ ) + { + if ( *read & FT_STROKE_TAG_ON ) + *write = FT_CURVE_TAG_ON; + else if ( *read & FT_STROKE_TAG_CUBIC ) + *write = FT_CURVE_TAG_CUBIC; + else + *write = FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_Short* write = outline->contours + outline->n_contours; + FT_Short index = (FT_Short)outline->n_points; + + + for ( ; count > 0; count--, tags++, index++ ) + { + if ( *tags & FT_STROKE_TAG_END ) + { + *write++ = index; + outline->n_contours++; + } + } + } + + outline->n_points = (short)( outline->n_points + border->num_points ); + + FT_ASSERT( FT_Outline_Check( outline ) == 0 ); + } /***************************************************************************/ @@ -566,9 +605,9 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_SIDE_TO_ROTATE(s) (FT_ANGLE_PI2 - (s)*FT_ANGLE_PI) +#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) - typedef struct FT_StrokerRec_ + typedef struct FT_StrokerRec_ { FT_Angle angle_in; FT_Angle angle_out; @@ -597,6 +636,7 @@ FT_Error error; FT_Stroker stroker; + if ( !FT_NEW( stroker ) ) { stroker->memory = memory; @@ -635,6 +675,7 @@ { FT_Memory memory = stroker->memory; + ft_stroke_border_done( &stroker->borders[0] ); ft_stroke_border_done( &stroker->borders[1] ); @@ -644,22 +685,22 @@ } - - /* creates a circular arc at a corner or cap */ + /* creates a circular arc at a corner or cap */ static FT_Error ft_stroker_arcto( FT_Stroker stroker, FT_Int side ) { - FT_Angle total, rotate; - FT_Fixed radius = stroker->radius; - FT_Error error = 0; - FT_StrokeBorder border = stroker->borders + side; + FT_Angle total, rotate; + FT_Fixed radius = stroker->radius; + FT_Error error = 0; + FT_StrokeBorder border = stroker->borders + side; - rotate = FT_SIDE_TO_ROTATE(side); + + rotate = FT_SIDE_TO_ROTATE( side ); total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if (total == FT_ANGLE_PI) - total = -rotate*2; + if ( total == FT_ANGLE_PI ) + total = -rotate * 2; error = ft_stroke_border_arcto( border, &stroker->center, @@ -679,6 +720,7 @@ { FT_Error error = 0; + if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) { /* add a round cap */ @@ -689,21 +731,23 @@ else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) { /* add a square cap */ - FT_Vector delta, delta2; - FT_Angle rotate = FT_SIDE_TO_ROTATE(side); - FT_Fixed radius = stroker->radius; - FT_StrokeBorder border = stroker->borders + side; + FT_Vector delta, delta2; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; - FT_Vector_From_Polar( &delta2, radius, angle+rotate ); + + FT_Vector_From_Polar( &delta2, radius, angle + rotate ); FT_Vector_From_Polar( &delta, radius, angle ); delta.x += stroker->center.x + delta2.x; delta.y += stroker->center.y + delta2.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; - FT_Vector_From_Polar( &delta2, radius, angle-rotate ); + FT_Vector_From_Polar( &delta2, radius, angle - rotate ); FT_Vector_From_Polar( &delta, radius, angle ); delta.x += delta2.x + stroker->center.x; @@ -711,13 +755,13 @@ error = ft_stroke_border_lineto( border, &delta, 0 ); } + Exit: return error; } - - /* process an inside corner, i.e. compute intersection */ + /* process an inside corner, i.e. compute intersection */ static FT_Error ft_stroker_inside( FT_Stroker stroker, FT_Int side) @@ -729,14 +773,14 @@ FT_Error error = 0; - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute median angle */ theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); if ( theta == FT_ANGLE_PI ) theta = rotate; else - theta = theta/2; + theta = theta / 2; phi = stroker->angle_in + theta; @@ -745,7 +789,8 @@ if ( sigma < 0x10000L ) { - FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; border->movable = 0; @@ -765,7 +810,7 @@ } - /* process an outside corner, i.e. compute bevel/miter/round */ + /* process an outside corner, i.e. compute bevel/miter/round */ static FT_Error ft_stroker_outside( FT_Stroker stroker, FT_Int side ) @@ -774,6 +819,7 @@ FT_Error error; FT_Angle rotate; + if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) { error = ft_stroker_arcto( stroker, side ); @@ -781,54 +827,58 @@ else { /* this is a mitered or beveled corner */ - FT_Fixed sigma, radius = stroker->radius; - FT_Angle theta, phi; - FT_Fixed thcos; - FT_Bool miter; + FT_Fixed sigma, radius = stroker->radius; + FT_Angle theta, phi; + FT_Fixed thcos; + FT_Bool miter; - rotate = FT_SIDE_TO_ROTATE(side); + + rotate = FT_SIDE_TO_ROTATE( side ); miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if (theta == FT_ANGLE_PI) + if ( theta == FT_ANGLE_PI ) { theta = rotate; phi = stroker->angle_in; } else { - theta = theta/2; + theta = theta / 2; phi = stroker->angle_in + theta + rotate; } - thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); if ( sigma >= 0x10000L ) miter = 0; - - if (miter) /* this is a miter (broken angle) */ + if ( miter ) /* this is a miter (broken angle) */ { FT_Vector middle, delta; - FT_Fixed length; + FT_Fixed length; + /* compute middle point */ - FT_Vector_From_Polar( &middle, FT_MulFix( radius, stroker->miter_limit ), + FT_Vector_From_Polar( &middle, + FT_MulFix( radius, stroker->miter_limit ), phi ); middle.x += stroker->center.x; middle.y += stroker->center.y; /* compute first angle point */ - length = FT_MulFix( radius, FT_DivFix( 0x10000L - sigma, - ft_pos_abs( FT_Sin( theta ) ) ) ); + length = FT_MulFix( radius, + FT_DivFix( 0x10000L - sigma, + ft_pos_abs( FT_Sin( theta ) ) ) ); FT_Vector_From_Polar( &delta, length, phi + rotate ); delta.x += middle.x; delta.y += middle.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* compute second angle point */ FT_Vector_From_Polar( &delta, length, phi - rotate ); @@ -836,7 +886,8 @@ delta.y += middle.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* finally, add a movable end point */ FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate ); @@ -845,11 +896,13 @@ error = ft_stroke_border_lineto( border, &delta, 1 ); } + else /* this is a bevel (intersection) */ { - FT_Fixed length; + FT_Fixed length; FT_Vector delta; + length = FT_DivFix( stroker->radius, thcos ); FT_Vector_From_Polar( &delta, length, phi ); @@ -860,13 +913,15 @@ if (error) goto Exit; /* now add end point */ - FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; error = ft_stroke_border_lineto( border, &delta, 1 ); } } + Exit: return error; } @@ -879,33 +934,35 @@ FT_Angle turn; FT_Int inside_side; + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); /* no specific corner processing is required if the turn is 0 */ - if (turn == 0) + if ( turn == 0 ) goto Exit; /* when we turn to the right, the inside side is 0 */ inside_side = 0; /* otherwise, the inside side is 1 */ - if (turn < 0) + if ( turn < 0 ) inside_side = 1; /* process the inside side */ error = ft_stroker_inside( stroker, inside_side ); - if (error) goto Exit; + if ( error ) + goto Exit; /* process the outside side */ - error = ft_stroker_outside( stroker, 1-inside_side ); + error = ft_stroker_outside( stroker, 1 - inside_side ); Exit: return error; } - /* add two points to the left and right borders corresponding to the */ - /* start of the subpath.. */ + /* add two points to the left and right borders corresponding to the */ + /* start of the subpath.. */ static FT_Error ft_stroker_subpath_start( FT_Stroker stroker, FT_Angle start_angle ) @@ -915,14 +972,17 @@ FT_Error error; FT_StrokeBorder border; - FT_Vector_From_Polar( &delta, stroker->radius, start_angle + FT_ANGLE_PI2 ); + + FT_Vector_From_Polar( &delta, stroker->radius, + start_angle + FT_ANGLE_PI2 ); point.x = stroker->center.x + delta.x; point.y = stroker->center.y + delta.y; border = stroker->borders; error = ft_stroke_border_moveto( border, &point ); - if (error) goto Exit; + if ( error ) + goto Exit; point.x = stroker->center.x - delta.x; point.y = stroker->center.y - delta.y; @@ -958,18 +1018,20 @@ /* process corner if necessary */ if ( stroker->first_point ) { - /* this is the first segment of a subpath. We need to */ + /* This is the first segment of a subpath. We need to */ /* add a point to each border at their respective starting */ - /* point locations.. */ + /* point locations. */ error = ft_stroker_subpath_start( stroker, angle ); - if (error) goto Exit; + if ( error ) + goto Exit; } else { /* process the current corner */ stroker->angle_out = angle; error = ft_stroker_process_corner( stroker ); - if (error) goto Exit; + if ( error ) + goto Exit; } /* now add a line segment to both the "inside" and "outside" paths */ @@ -978,25 +1040,26 @@ { FT_Vector point; + point.x = to->x + delta.x; point.y = to->y + delta.y; error = ft_stroke_border_lineto( border, &point, 1 ); - if (error) goto Exit; + if ( error ) + goto Exit; delta.x = -delta.x; delta.y = -delta.y; } - stroker->angle_in = angle; - stroker->center = *to; + stroker->angle_in = angle; + stroker->center = *to; Exit: return error; } - FT_EXPORT_DEF( FT_Error ) FT_Stroker_ConicTo( FT_Stroker stroker, FT_Vector* control, @@ -1009,6 +1072,7 @@ FT_Angle start_angle; FT_Bool first_arc = 1; + arc = bez_stack; arc[0] = *to; arc[1] = *control; @@ -1018,9 +1082,10 @@ { FT_Angle angle_in, angle_out; + angle_in = angle_out = 0; /* remove compiler warnings */ - if ( arc < limit && + if ( arc < limit && !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) { ft_conic_split( arc ); @@ -1044,21 +1109,22 @@ } } - /* the arc's angle is small enough, we can add it directly to each */ - /* border.. */ + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ { FT_Vector ctrl, end; FT_Angle theta, phi, rotate; - FT_Fixed length; + FT_Fixed length; FT_Int side; - theta = FT_Angle_Diff( angle_in, angle_out )/2; + + theta = FT_Angle_Diff( angle_in, angle_out ) / 2; phi = angle_in + theta; - length = FT_DivFix( stroker->radius, FT_Cos(theta) ); + length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); for ( side = 0; side <= 1; side++ ) { - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute control point */ FT_Vector_From_Polar( &ctrl, length, phi + rotate ); @@ -1070,14 +1136,16 @@ end.x += arc[0].x; end.y += arc[0].y; - error = ft_stroke_border_conicto( stroker->borders + side, &ctrl, &end ); - if (error) goto Exit; + error = ft_stroke_border_conicto( stroker->borders + side, + &ctrl, &end ); + if ( error ) + goto Exit; } } arc -= 2; - if (arc < bez_stack) + if ( arc < bez_stack ) stroker->angle_in = angle_out; } @@ -1088,12 +1156,11 @@ } - FT_EXPORT_DEF( FT_Error ) FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) { FT_Error error = 0; FT_Vector bez_stack[37]; @@ -1102,6 +1169,7 @@ FT_Angle start_angle; FT_Bool first_arc = 1; + arc = bez_stack; arc[0] = *to; arc[1] = *control2; @@ -1112,11 +1180,13 @@ { FT_Angle angle_in, angle_mid, angle_out; + /* remove compiler warnings */ angle_in = angle_out = angle_mid = 0; - if ( arc < limit && - !ft_cubic_is_small_enough( arc, &angle_in, &angle_mid, &angle_out ) ) + if ( arc < limit && + !ft_cubic_is_small_enough( arc, &angle_in, + &angle_mid, &angle_out ) ) { ft_cubic_split( arc ); arc += 3; @@ -1133,31 +1203,33 @@ if ( stroker->first_point ) error = ft_stroker_subpath_start( stroker, start_angle ); else - { - stroker->angle_out = start_angle; - error = ft_stroker_process_corner( stroker ); - } - if (error) goto Exit; + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + if ( error ) + goto Exit; } - /* the arc's angle is small enough, we can add it directly to each */ - /* border.. */ + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ { FT_Vector ctrl1, ctrl2, end; FT_Angle theta1, phi1, theta2, phi2, rotate; FT_Fixed length1, length2; FT_Int side; - theta1 = ft_pos_abs( angle_mid - angle_in )/2; - theta2 = ft_pos_abs( angle_out - angle_mid )/2; - phi1 = (angle_mid+angle_in)/2; - phi2 = (angle_mid+angle_out)/2; - length1 = FT_DivFix( stroker->radius, FT_Cos(theta1) ); + + theta1 = ft_pos_abs( angle_mid - angle_in ) / 2; + theta2 = ft_pos_abs( angle_out - angle_mid ) / 2; + phi1 = (angle_mid + angle_in ) / 2; + phi2 = (angle_mid + angle_out ) / 2; + length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); for ( side = 0; side <= 1; side++ ) { - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute control points */ FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); @@ -1173,13 +1245,15 @@ end.x += arc[0].x; end.y += arc[0].y; - error = ft_stroke_border_cubicto( stroker->borders + side, &ctrl1, &ctrl2, &end ); - if (error) goto Exit; + error = ft_stroke_border_cubicto( stroker->borders + side, + &ctrl1, &ctrl2, &end ); + if ( error ) + goto Exit; } } arc -= 3; - if (arc < bez_stack) + if ( arc < bez_stack ) stroker->angle_in = angle_out; } @@ -1195,10 +1269,10 @@ FT_Vector* to, FT_Bool open ) { - /* we cannot process the first point, because there is not enough */ - /* information regarding its corner/cap. The latter will be processed */ - /* in the "end_subpath" routine */ - /* */ + /* We cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the "end_subpath" routine. */ + /* */ stroker->first_point = 1; stroker->center = *to; stroker->subpath_open = open; @@ -1209,40 +1283,43 @@ } - static - FT_Error ft_stroker_add_reverse_left( FT_Stroker stroker, - FT_Bool open ) + static FT_Error + ft_stroker_add_reverse_left( FT_Stroker stroker, + FT_Bool open ) { FT_StrokeBorder right = stroker->borders + 0; FT_StrokeBorder left = stroker->borders + 1; FT_Int new_points; FT_Error error = 0; + FT_ASSERT( left->start >= 0 ); new_points = left->num_points - left->start; if ( new_points > 0 ) { error = ft_stroke_border_grow( right, (FT_UInt)new_points ); - if (error) goto Exit; + if ( error ) + goto Exit; + { - FT_Vector* dst_point = right->points + right->num_points; - FT_Byte* dst_tag = right->tags + right->num_points; - FT_Vector* src_point = left->points + left->num_points - 1; - FT_Byte* src_tag = left->tags + left->num_points - 1; + FT_Vector* dst_point = right->points + right->num_points; + FT_Byte* dst_tag = right->tags + right->num_points; + FT_Vector* src_point = left->points + left->num_points - 1; + FT_Byte* src_tag = left->tags + left->num_points - 1; while ( src_point >= left->points + left->start ) { *dst_point = *src_point; *dst_tag = *src_tag; - if (open) - dst_tag[0] &= ~(FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + if ( open ) + dst_tag[0] &= ~( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); else { /* switch begin/end tags if necessary.. */ - if (dst_tag[0] & (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END)) - dst_tag[0] ^= (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + if ( dst_tag[0] & ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ) ) + dst_tag[0] ^= ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); } src_point--; @@ -1251,73 +1328,84 @@ dst_tag++; } } + left->num_points = left->start; right->num_points += new_points; right->movable = 0; left->movable = 0; } + Exit: return error; } - /* there's a lot of magic in this function !! */ + /* there's a lot of magic in this function! */ FT_EXPORT_DEF( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ) { FT_Error error = 0; + if ( stroker->subpath_open ) { FT_StrokeBorder right = stroker->borders; - /* all right, this is an opened path, we need to add a cap between */ - /* right & left, add the reverse of left, then add a final cap between */ - /* left & right.. */ + /* All right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap */ + /* between left & right. */ error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* add reversed points from "left" to "right" */ error = ft_stroker_add_reverse_left( stroker, 1 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* now add the final cap */ stroker->center = stroker->subpath_start; - error = ft_stroker_cap( stroker, stroker->subpath_angle+FT_ANGLE_PI, 0 ); - if (error) goto Exit; + error = ft_stroker_cap( stroker, + stroker->subpath_angle + FT_ANGLE_PI, 0 ); + if ( error ) + goto Exit; - /* now, end the right subpath accordingly. the left one is */ - /* rewind and doesn't need further processing.. */ + /* Now end the right subpath accordingly. The left one is */ + /* rewind and doesn't need further processing. */ ft_stroke_border_close( right ); } else { - FT_Angle turn; - FT_Int inside_side; + FT_Angle turn; + FT_Int inside_side; - /* process the corner ... */ + + /* process the corner */ stroker->angle_out = stroker->subpath_angle; - turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + turn = FT_Angle_Diff( stroker->angle_in, + stroker->angle_out ); /* no specific corner processing is required if the turn is 0 */ - if (turn != 0) + if ( turn != 0 ) { /* when we turn to the right, the inside side is 0 */ inside_side = 0; /* otherwise, the inside side is 1 */ - if (turn < 0) + if ( turn < 0 ) inside_side = 1; - /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE !! */ - /* process the inside side */ - /* error = ft_stroker_inside( stroker, inside_side ); - if (error) goto Exit; */ + /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE! */ + /* process the inside side */ + /* error = ft_stroker_inside( stroker, inside_side ); */ + /* if ( error ) */ + /* goto Exit; */ /* process the outside side */ - error = ft_stroker_outside( stroker, 1-inside_side ); - if (error) goto Exit; + error = ft_stroker_outside( stroker, 1 - inside_side ); + if ( error ) + goto Exit; } /* we will first end our two subpaths */ @@ -1326,7 +1414,8 @@ /* now, add the reversed left subpath to "right" */ error = ft_stroker_add_reverse_left( stroker, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; } Exit: @@ -1343,11 +1432,16 @@ FT_UInt count3, count4, num_contours = 0; FT_Error error; - error = ft_stroke_border_get_counts( stroker->borders+0, &count1, &count2 ); - if (error) goto Exit; - error = ft_stroke_border_get_counts( stroker->borders+1, &count3, &count4 ); - if (error) goto Exit; + error = ft_stroke_border_get_counts( stroker->borders + 0, + &count1, &count2 ); + if ( error ) + goto Exit; + + error = ft_stroke_border_get_counts( stroker->borders + 1, + &count3, &count4 ); + if ( error ) + goto Exit; num_points = count1 + count3; num_contours = count2 + count4; @@ -1367,19 +1461,16 @@ { if ( stroker->valid ) { - ft_stroke_border_export( stroker->borders+0, outline ); - ft_stroke_border_export( stroker->borders+1, outline ); + ft_stroke_border_export( stroker->borders + 0, outline ); + ft_stroke_border_export( stroker->borders + 1, outline ); } } - - - - /* - * the following is very similar to FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline - */ + /* + * The following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. + */ FT_EXPORT_DEF( FT_Error ) FT_Stroker_ParseOutline( FT_Stroker stroker, FT_Outline* outline, @@ -1400,6 +1491,7 @@ FT_Int tag; /* current point's state */ FT_Int in_path; + if ( !outline || !stroker ) return FT_Err_Invalid_Argument; @@ -1431,7 +1523,7 @@ /* check first point to determine origin */ if ( tag == FT_CURVE_TAG_CONIC ) { - /* first point is conic control. Yes, this happens. */ + /* First point is conic control. Yes, this happens. */ if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) { /* start at last point if it is on the curve */ @@ -1575,3 +1667,6 @@ Invalid_Outline: return FT_Err_Invalid_Outline; } + + +/* END */ diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index 45459f3ee..e4a09b028 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2002 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c index 88644e954..d55597a02 100644 --- a/src/base/ftwinfnt.c +++ b/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,10 +23,11 @@ FT_EXPORT_DEF( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *header ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ) { - FT_Error error; + FT_Error error; + error = FT_Err_Invalid_Argument; @@ -41,10 +42,11 @@ FNT_Size size = (FNT_Size)face->size; FNT_Font font = size->font; - if (font) + + if ( font ) { - FT_MEM_COPY( header, &font->header, sizeof(*header) ); - error = 0; + FT_MEM_COPY( header, &font->header, sizeof ( *header ) ); + error = FT_Err_Ok; } } }