From be67c4ef33a610afc475e62fc2fd69b96cd4d845 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Mon, 24 Nov 2003 22:54:58 +0000 Subject: [PATCH] * src/truetype/ttinterp.c (CUR_Func_move_orig): New macro. (Direct_Move_Orig, Direct_Move_Orig_X, Direct_Move_Orig_Y): New functions. Similar to Direct_Move, Direct_Move_X, and Direct_Move_Y but without touching. (Compute_Funcs): Use new functions. (Round_None, Round_To_Grid, Round_To_Half_Grid, Round_Down_To_Grid, Round_Up_To_Grid, Round_To_Double_Grid, Round_Super, Round_Super_45): Fix rounding of value zero. (DO_DIV): Don't use TT_MULDIV. (Ins_SHC): This instruction actually touches the points. (Ins_MSIRP): Fix undocumented behaviour. * src/truetype/ttinterp.h (TT_ExecContextRec): Updated. * docs/VERSION.DLL: Updated. * src/base/ftobjs.c (FT_Set_Char_Size): Make metrics->x_scale and metrics->y_scale really precise. (FT_Load_Glyph): Update computation of linearHoriAdvance and linearVertAdvance. * src/true/type/ttinterp.c (Update_Max): Use FT_REALLOC. --- ChangeLog | 39 +++++++++++- docs/VERSION.DLL | 17 +++-- src/base/ftobjs.c | 13 ++-- src/pfr/pfrdrivr.c | 43 +++++++------ src/truetype/ttinterp.c | 135 +++++++++++++++++++++++++++++++++------- src/truetype/ttinterp.h | 3 +- 6 files changed, 188 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84fbdeaa8..3bdce81b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,41 @@ -2003-11-22 David Turner +2003-11-22 Rogier van Dalen - * src/autofit/*: more updates + * src/truetype/ttinterp.c (CUR_Func_move_orig): New macro. + (Direct_Move_Orig, Direct_Move_Orig_X, Direct_Move_Orig_Y): New + functions. Similar to Direct_Move, Direct_Move_X, and + Direct_Move_Y but without touching. + (Compute_Funcs): Use new functions. + + (Round_None, Round_To_Grid, Round_To_Half_Grid, Round_Down_To_Grid, + Round_Up_To_Grid, Round_To_Double_Grid, Round_Super, + Round_Super_45): Fix rounding of value zero. + + (DO_DIV): Don't use TT_MULDIV. + + (Ins_SHC): This instruction actually touches the points. + (Ins_MSIRP): Fix undocumented behaviour. + + * src/truetype/ttinterp.h (TT_ExecContextRec): Updated. + +2003-11-22 Werner Lemberg + + * docs/VERSION.DLL: Updated. + + * src/base/ftobjs.c (FT_Set_Char_Size): Make metrics->x_scale and + metrics->y_scale really precise. + + (FT_Load_Glyph): Update computation of linearHoriAdvance and + linearVertAdvance. + + * src/true/type/ttinterp.c (Update_Max): Use FT_REALLOC. + +2003-11-22 David Turner + + * src/autofit/*: More updates. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 8. + * builds/unix/configure.ac (version_info): Set to 9:6:3. + * README: Updated. 2003-11-13 John A. Boyd Jr. diff --git a/docs/VERSION.DLL b/docs/VERSION.DLL index 9bdd643c7..5b178bdc4 100644 --- a/docs/VERSION.DLL +++ b/docs/VERSION.DLL @@ -91,20 +91,19 @@ other release numbers. old_CPPFLAGS="$CPPFLAGS" CPPFLAGS=`freetype-config --cflags` AC_TRY_CPP([ + #include #include FT_FREETYPE_H #if (FREETYPE_MAJOR*1000 + FREETYPE_MINOR)*1000 + FREETYPE_PATCH < 2000009 #error Freetype version too low. #endif - ],[ - AC_MSG_RESULT(yes) - FREETYPE_LIBS=`freetype-config --libs` - AC_SUBST(FREETYPE_LIBS) - AC_DEFINE(HAVE_FREETYPE,1,[Define if you have the FreeType2 library]) - CPPFLAGS="$old_CPPFLAGS" - ],[ - AC_MSG_ERROR([Need FreeType library version 2.0.9 or higher]) - ]) + ], + [AC_MSG_RESULT(yes) + FREETYPE_LIBS=`freetype-config --libs` + AC_SUBST(FREETYPE_LIBS) + AC_DEFINE(HAVE_FREETYPE,1,[Define if you have the FreeType2 library]) + CPPFLAGS="$old_CPPFLAGS"], + [AC_MSG_ERROR([Need FreeType library version 2.0.9 or higher])]) --- end of VERSION.DLL --- diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 67e491b1b..69f74c07e 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -575,15 +575,14 @@ if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) { - FT_UInt EM = face->units_per_EM; FT_Size_Metrics* metrics = &face->size->metrics; slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, - (FT_Long)metrics->x_ppem << 16, EM ); + metrics->x_scale, 64 ); slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, - (FT_Long)metrics->y_ppem << 16, EM ); + metrics->y_scale, 64 ); } if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) @@ -2042,11 +2041,11 @@ char_height = 1 * 64; /* Compute pixel sizes in 26.6 units with rounding */ - dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; - dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + dim_x = ( char_width * horz_resolution + 36 ) / 72; + dim_y = ( char_height * vert_resolution + 36 ) / 72; - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); + metrics->x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 ); + metrics->y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 ); metrics->x_scale = 0x10000L; metrics->y_scale = 0x10000L; diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c index f25c73293..6a72d09bb 100644 --- a/src/pfr/pfrdrivr.c +++ b/src/pfr/pfrdrivr.c @@ -26,6 +26,7 @@ #include "pfrerror.h" + static FT_Error pfr_get_kerning( PFR_Face face, FT_UInt left, @@ -52,15 +53,16 @@ return PFR_Err_Ok; } + /* * PFR METRICS SERVICE * */ static FT_Error - pfr_get_advance( PFR_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) + pfr_get_advance( PFR_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) { FT_Error error = PFR_Err_Bad_Argument; @@ -68,12 +70,12 @@ *aadvance = 0; if ( face ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; if ( gindex < phys->num_chars ) { - *aadvance = phys->chars[ gindex ].advance; + *aadvance = phys->chars[gindex].advance; error = 0; } } @@ -89,7 +91,7 @@ FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; FT_Fixed x_scale, y_scale; FT_Size size = face->root.size; @@ -118,7 +120,7 @@ if ( ametrics_y_scale ) *ametrics_y_scale = y_scale; - return 0; + return PFR_Err_Ok; } @@ -130,6 +132,7 @@ (FT_PFR_GetAdvanceFunc)pfr_get_advance }; + /* * SERVICE LIST * @@ -137,7 +140,7 @@ static const FT_ServiceDescRec pfr_services[] = { - { FT_SERVICE_ID_PFR_METRICS, & pfr_metrics_service_rec }, + { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, { NULL, NULL } }; @@ -177,20 +180,20 @@ sizeof( PFR_SizeRec ), sizeof( PFR_SlotRec ), - (FT_Face_InitFunc) pfr_face_init, - (FT_Face_DoneFunc) pfr_face_done, - (FT_Size_InitFunc) NULL, - (FT_Size_DoneFunc) NULL, - (FT_Slot_InitFunc) pfr_slot_init, - (FT_Slot_DoneFunc) pfr_slot_done, + (FT_Face_InitFunc) pfr_face_init, + (FT_Face_DoneFunc) pfr_face_done, + (FT_Size_InitFunc) NULL, + (FT_Size_DoneFunc) NULL, + (FT_Slot_InitFunc) pfr_slot_init, + (FT_Slot_DoneFunc) pfr_slot_done, - (FT_Size_ResetPointsFunc) NULL, - (FT_Size_ResetPixelsFunc) NULL, - (FT_Slot_LoadFunc) pfr_slot_load, + (FT_Size_ResetPointsFunc)NULL, + (FT_Size_ResetPixelsFunc)NULL, + (FT_Slot_LoadFunc) pfr_slot_load, - (FT_Face_GetKerningFunc) pfr_get_kerning, - (FT_Face_AttachFunc) 0, - (FT_Face_GetAdvancesFunc) 0 + (FT_Face_GetKerningFunc) pfr_get_kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc)0 }; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 2dca6a212..d996a5dd8 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -162,6 +162,9 @@ #define CUR_Func_move( z, p, d ) \ CUR.func_move( EXEC_ARG_ z, p, d ) +#define CUR_Func_move_orig( z, p, d ) \ + CUR.func_move_orig( EXEC_ARG_ z, p, d ) + #define CUR_Func_dualproj( x, y ) \ CUR.func_dualproj( EXEC_ARG_ x, y ) @@ -515,8 +518,7 @@ if ( *size < new_max ) { - FT_FREE( *buff ); - if ( FT_ALLOC( *buff, new_max * multiplier ) ) + if ( FT_REALLOC( *buff, *size, new_max * multiplier ) ) return error; *size = new_max; } @@ -1566,7 +1568,6 @@ if ( v != 0 ) { - zone->cur[point].x += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); @@ -1578,7 +1579,6 @@ if ( v != 0 ) { - zone->cur[point].y += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); @@ -1588,6 +1588,51 @@ } + /*************************************************************************/ + /* */ + /* */ + /* Direct_Move_Orig */ + /* */ + /* */ + /* Moves a point by a given distance along the freedom vector. The */ + /* point will not be `touched'. */ + /* */ + /* */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + zone->org[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + zone->org[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + } + + /*************************************************************************/ /* */ /* Special versions of Direct_Move() */ @@ -1622,6 +1667,38 @@ } + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move_Orig() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].x += distance; + } + + + static void + Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].y += distance; + } + + /*************************************************************************/ /* */ /* */ @@ -1656,7 +1733,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; } else { @@ -1696,7 +1773,7 @@ if ( distance >= 0 ) { val = distance + compensation + 32; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; @@ -1740,7 +1817,7 @@ if ( distance >= 0 ) { val = ( ( distance + compensation ) & -64 ) + 32; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; } else @@ -1782,7 +1859,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; @@ -1826,7 +1903,7 @@ if ( distance >= 0 ) { val = distance + compensation + 63; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; @@ -1870,7 +1947,7 @@ if ( distance >= 0 ) { val = distance + compensation + 16; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~31; else val = 0; @@ -1919,7 +1996,7 @@ { val = ( distance - CUR.phase + CUR.threshold + compensation ) & -CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -1967,7 +2044,7 @@ { val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / CUR.period ) * CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -2243,13 +2320,15 @@ if ( CUR.GS.both_x_axis ) { - CUR.func_project = Project_x; - CUR.func_move = Direct_Move_X; + CUR.func_project = Project_x; + CUR.func_move = Direct_Move_X; + CUR.func_move_orig = Direct_Move_Orig_X; } else { - CUR.func_project = Project_y; - CUR.func_move = Direct_Move_Y; + CUR.func_project = Project_y; + CUR.func_move = Direct_Move_Y; + CUR.func_move_orig = Direct_Move_Orig_Y; } if ( CUR.GS.dualVector.x == 0x4000 ) @@ -2300,16 +2379,23 @@ CUR.func_dualproj = (TT_Project_Func)Dual_Project; } - CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; if ( CUR.F_dot_P == 0x40000000L ) { if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_X; + { + CUR.func_move = (TT_Move_Func)Direct_Move_X; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + } else { if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_Y; + { + CUR.func_move = (TT_Move_Func)Direct_Move_Y; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + } } } @@ -2891,7 +2977,8 @@ if ( args[1] == 0 ) \ CUR.error = TT_Err_Divide_By_Zero; \ else \ - args[0] = TT_MULDIV( args[0], 64L, args[1] ); +/* Should args[0] be cast to FT_Int64 first? */ \ + args[0] = ( args[0] * 64L ) / args[1]; #define DO_MUL \ @@ -5359,11 +5446,11 @@ last_point = 0; } - /* XXX: UNDOCUMENTED! SHC doesn't touch the points */ + /* XXX: UNDOCUMENTED! SHC does touch the points */ for ( i = first_point; i <= last_point; i++ ) { if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); + MOVE_Zp2_Point( i, dx, dy, TRUE ); } } @@ -5498,9 +5585,11 @@ } /* XXX: UNDOCUMENTED! behaviour */ - if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ + if ( CUR.GS.gep1 == 0 ) /* if the point that is to be moved */ + /* is in twilight zone */ { CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR_Func_move_orig( &CUR.zp1, point, args[1] ); CUR.zp1.cur[point] = CUR.zp1.org[point]; } diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h index e750963ff..eb0bb0bb6 100644 --- a/src/truetype/ttinterp.h +++ b/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* 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, */ @@ -210,6 +210,7 @@ FT_BEGIN_HEADER func_freeProj; /* current freedom proj. func */ TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move_orig; /* move original position function */ TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */