From bce2986d0d884886ae76e024b55199996cf6b52c Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 14 Dec 2001 14:52:58 +0000 Subject: [PATCH] fixing hinted advance width bug in all font drivers --- ChangeLog | 10 +++++++- include/freetype/freetype.h | 1 + include/freetype/ftglyph.h | 48 ++++++++++++++++++++++++++++++++++--- src/base/ftdbgmem.c | 20 ++++++++-------- src/cff/cffgload.c | 19 +++++++++++---- src/cid/cidgload.c | 9 +++++++ src/pshinter/pshglob.c | 17 ++++++------- src/truetype/ttgload.c | 4 ++++ src/type1/t1gload.c | 9 +++++++ 9 files changed, 110 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index fcd8ddad1..d7ff3a290 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2001-12-14 David Turner + + * src/truetype/ttgload.c (TT_Load_Glyph), src/type1/t1gload.c + (T1_Load_Glyph), src/cid/cidgload.c (CID_Load_Glyph), src/cff/cffgload.c + (CFF_Load_Glyph): fixed an important bug common to all font drivers (the + advance width was never hinted when it should) + + 2001-12-12 David Turner * src/pshint/pshglob.c: adding correct BlueScale/BlueShift support, @@ -24,7 +32,7 @@ * docs/FTL.TXT: Simple fix (change "LICENSE.TXT" to "FTL.TXT"). - * builds/unix/freetype2.m4: New file for checking configure paths. + * builds/unix/freetype2.m4: New file for checking configure paths. We need to install it in $(prefix)/share/aclocal/freetype2.m4 but I didn't modify builds/unix/install.mk yet. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index c9a5c2808..81b29e281 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -35,6 +35,7 @@ /* */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 0 +#define FREETYPE_PATCH 5 #include diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h index f9666539d..b51e95989 100644 --- a/include/freetype/ftglyph.h +++ b/include/freetype/ftglyph.h @@ -63,6 +63,24 @@ FT_BEGIN_HEADER typedef struct FT_Glyph_Class_ FT_Glyph_Class; + /*************************************************************************/ + /* */ + /* */ + /* FT_Glyph */ + /* */ + /* */ + /* Handle to an object used to model generic glyph images. It's a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer.. */ + /* */ + /* */ + /* glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + /*************************************************************************/ /* */ /* */ @@ -88,7 +106,19 @@ FT_BEGIN_HEADER FT_Glyph_Format format; FT_Vector advance; - } FT_GlyphRec, *FT_Glyph; + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_BitmapGlyph */ + /* */ + /* */ + /* Handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; /*************************************************************************/ @@ -128,7 +158,19 @@ FT_BEGIN_HEADER FT_Int top; FT_Bitmap bitmap; - } FT_BitmapGlyphRec, *FT_BitmapGlyph; + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_OutlineGlyph */ + /* */ + /* */ + /* Handle to an object used to model an outline glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; /*************************************************************************/ @@ -162,7 +204,7 @@ FT_BEGIN_HEADER FT_GlyphRec root; FT_Outline outline; - } FT_OutlineGlyphRec, *FT_OutlineGlyph; + } FT_OutlineGlyphRec; /*************************************************************************/ diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index bca789bbd..324d84814 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -163,7 +163,7 @@ { FT_Memory memory = table->memory; FT_Pointer block; - + memory->user = table->memory_user; block = table->alloc( memory, size ); @@ -178,7 +178,7 @@ FT_Pointer block ) { FT_Memory memory = table->memory; - + memory->user = table->memory_user; table->free( memory, block ); @@ -297,7 +297,7 @@ if ( node->size > 0 ) { - printf( + printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", node->address, node->size, FT_FILENAME( node->alloc_file_name ), @@ -485,7 +485,7 @@ return (FT_Pointer) block; } - + extern void ft_mem_debug_free( FT_Memory memory, @@ -505,7 +505,7 @@ table->file_name = NULL; table->line_no = 0; } - + extern FT_Pointer ft_mem_debug_realloc( FT_Memory memory, @@ -520,7 +520,7 @@ const char* file_name = FT_FILENAME( table->file_name ); FT_Long line_no = table->line_no; - + if ( block == NULL || cur_size == 0 ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); @@ -620,7 +620,7 @@ table->line_no = line_no; } return FT_Alloc( memory, size, P ); - } + } FT_BASE_DEF( FT_Error ) @@ -640,7 +640,7 @@ table->line_no = line_no; } return FT_Realloc( memory, current, size, P ); - } + } FT_BASE_DEF( void ) @@ -662,9 +662,9 @@ #else /* !FT_DEBUG_MEMORY */ - + /* ANSI C doesn't like empty source files */ - extern const FT_Byte _debug_mem_dummy = 0; + const FT_Byte _debug_mem_dummy = 0; #endif /* !FT_DEBUG_MEMORY */ diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index 2e8c55aaf..8ea8c5382 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -1065,17 +1065,17 @@ FT_TRACE4(( op == cff_op_hstem ? " hstem" : ( op == cff_op_vstem ? " vstem" : ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" )) )); - + if ( hinter ) hinter->stems( hinter->hints, ( op == cff_op_vstem || op == cff_op_vstemhm ), num_args/2, args ); - + decoder->num_hints += num_args / 2; args = stack; break; - + case cff_op_hintmask: case cff_op_cntrmask: @@ -1095,7 +1095,7 @@ (decoder->num_hints+7) >> 3, ip ); } - + #ifdef FT_DEBUG_LEVEL_TRACE { FT_UInt maskbyte; @@ -1647,7 +1647,7 @@ { if (hinter->close( hinter->hints, builder->current->n_points )) goto Syntax_Error; - + /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, @@ -2301,6 +2301,15 @@ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = (metrics->horiAdvance+32) & -64; + metrics->vertAdvance = (metrics->vertAdvance+32) & -64; + + metrics->vertBearingX = (metrics->vertBearingX+32) & -64; + metrics->vertBearingY = (metrics->vertBearingY+32) & -64; + } } /* compute the other metrics */ diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index e07c702bd..c37dd1c8b 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -330,6 +330,15 @@ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = (metrics->horiAdvance+32) & -64; + metrics->vertAdvance = (metrics->vertAdvance+32) & -64; + + metrics->vertBearingX = (metrics->vertBearingX+32) & -64; + metrics->vertBearingY = (metrics->vertBearingY+32) & -64; + } } /* compute the other metrics */ diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c index 406ca11e4..36f775917 100644 --- a/src/pshinter/pshglob.c +++ b/src/pshinter/pshglob.c @@ -383,10 +383,10 @@ /* */ { FT_Int threshold = blues->blue_shift; - + while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) threshold --; - + blues->blue_threshold = threshold; } @@ -434,23 +434,23 @@ /* process the families now */ for ( num = 0; num < 2; num++ ) - { + { PSH_Blue_Zone zone1, zone2; FT_UInt count1, count2; PSH_Blue_Table normal, family; - + switch (num) { case 0: normal = &blues->normal_top; family = &blues->family_top; break; - + default: normal = &blues->normal_bottom; family = &blues->family_bottom; } - + zone1 = normal->zones; count1 = normal->count; for ( ; count1 > 0; count1--, zone1++ ) @@ -640,8 +640,9 @@ globals->blues.blue_scale = priv->blue_scale ? priv->blue_scale : (0.039625*0x400000L); - - globals->blues.blue_shift = priv->blue_shift; + + globals->blues.blue_shift = priv->blue_shift ? priv->blue_shift + : 7; globals->dimension[0].scale_mult = 0; globals->dimension[0].scale_delta = 0; diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 3f89fa7d4..588ec41d8 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -1174,6 +1174,10 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + /* don't forget to hint the advance when we need to */ + if ( IS_HINTED( loader->load_flags ) ) + glyph->metrics.horiAdvance = (glyph->metrics.horiAdvance+32) & -64; + /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), make */ /* up some metrics by `hand'... */ diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index a801032a0..688564562 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -277,6 +277,15 @@ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = (metrics->horiAdvance+32) & -64; + metrics->vertAdvance = (metrics->vertAdvance+32) & -64; + + metrics->vertBearingX = (metrics->vertBearingX+32) & -64; + metrics->vertBearingY = (metrics->vertBearingY+32) & -64; + } } /* compute the other metrics */