diff --git a/ChangeLog b/ChangeLog index 742241d54..99ac8d7f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-06-20 Chia I Wu + + * include/freetype/internal/ftobjs.h, src/base/ftobjs.c: New function + ft_glyphslot_grid_fit_metrics. + + * src/truetype/ttgload.c (compute_glyph_metrics): Use + ft_glyphslot_grid_fit_metrics. + + * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c + (cid_slot_load_glyph), src/type1/t1gload.c (T1_Load_Glyph): Use + ft_glyphslot_grid_fit_metrics. + FT_Outline_Get_CBox is called twice. + + * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Modify metrics to more + reasonable values when emboldening outline glyphs. The theoretic + ones are unrealistic. + 2005-06-16 Chia I Wu * src/base/ftoutln.c (FT_Outline_Embolden): Strength should be diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index e8e3ee79a..317c2f024 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -451,6 +451,13 @@ FT_BEGIN_HEADER /* */ + /* + * grid-fit slot->metrics + */ + FT_BASE( void ) + ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot ); + + /* * Free the bitmap of a given glyphslot when needed * (i.e., only when it was allocated with ft_glyphslot_alloc_bitmap). diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 1bf813a48..4a4fc0437 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -250,6 +250,29 @@ } + FT_BASE_DEF( void ) + ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot ) + { + FT_Pos tmp; + + + tmp = FT_PIX_CEIL( slot->metrics.horiBearingX + slot->metrics.width ); + slot->metrics.horiBearingX = FT_PIX_FLOOR( slot->metrics.horiBearingX ); + slot->metrics.width = tmp - slot->metrics.horiBearingX; + + tmp = FT_PIX_FLOOR( slot->metrics.horiBearingY - slot->metrics.height ); + slot->metrics.horiBearingY = FT_PIX_CEIL( slot->metrics.horiBearingY ); + slot->metrics.height = slot->metrics.horiBearingY - tmp; + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + + slot->metrics.vertBearingX = FT_PIX_FLOOR( slot->metrics.vertBearingX ); + /* note that vertBearinY should be floor'ed */ + slot->metrics.vertBearingY = FT_PIX_FLOOR( slot->metrics.vertBearingY ); + slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); + } + + FT_BASE_DEF( void ) ft_glyphslot_set_bitmap( FT_GlyphSlot slot, FT_Byte* buffer ) diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index ed809513a..c2d4d52fe 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -87,7 +87,10 @@ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { error = FT_Outline_Embolden( &slot->outline, xstr ); - xstr = xstr * 4; /* according to the documentation */ + + /* this is more than enough for most glyphs */ + /* if you need accurate values, you have to FT_Outline_Get_CBox */ + xstr = xstr * 2; ystr = xstr; } else if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index 3c0ef6bc2..03458cdae 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -2510,11 +2510,8 @@ glyph->root.linearHoriAdvance = decoder.glyph_width; glyph->root.internal->glyph_transformed = 0; - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; + /* make up vertical ones */ metrics->vertAdvance = 0; - glyph->root.linearVertAdvance = 0; glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; @@ -2559,42 +2556,26 @@ vec->y = FT_MulFix( vec->y, y_scale ); } - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - /* Then scale the metrics */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - - if ( hinting ) - { - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - - metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); - } } /* compute the other metrics */ FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - } - metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; + + /* make up vertical ones */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + + if ( hinting ) + ft_glyphslot_grid_fit_metrics( &glyph->root ); } } diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index cbd0865d3..b084d44c1 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -358,12 +358,10 @@ cidglyph->linearHoriAdvance = decoder.builder.advance.x; cidglyph->internal->glyph_transformed = 0; - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; + /* make up vertical ones */ metrics->vertAdvance = 0; - cidglyph->linearVertAdvance = 0; + cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; if ( size && cidsize->metrics.y_ppem < 24 ) @@ -403,42 +401,26 @@ vec->y = FT_MulFix( vec->y, y_scale ); } - FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); - /* Then scale the metrics */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - - if ( hinting ) - { - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - - metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); - } } /* compute the other metrics */ FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); - } - metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; + + /* make up vertical ones */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + + if ( hinting ) + ft_glyphslot_grid_fit_metrics( cidglyph ); } } diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index a83dbe328..a975aa484 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -1707,15 +1707,6 @@ FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); FT_Outline_Get_CBox( &glyph->outline, &bbox ); - - if ( IS_HINTED( loader->load_flags ) ) - { - /* grid-fit the bounding box */ - bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); - bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); - bbox.xMax = FT_PIX_CEIL( bbox.xMax ); - bbox.yMax = FT_PIX_CEIL( bbox.yMax ); - } } else bbox = loader->bbox; @@ -1744,10 +1735,6 @@ 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 = FT_PIX_ROUND( glyph->metrics.horiAdvance ); - /* 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'... */ @@ -1857,15 +1844,6 @@ /* */ left = ( bbox.xMin - bbox.xMax ) / 2; - /* grid-fit them if necessary */ - if ( IS_HINTED( loader->load_flags ) ) - { - left = FT_PIX_FLOOR( left ); - /* top should be floor'ed */ - top = FT_PIX_FLOOR( top ); - advance = FT_PIX_ROUND( advance ); - } - glyph->metrics.vertBearingX = left; glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; @@ -1888,6 +1866,9 @@ glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.height = bbox.yMax - bbox.yMin; + if ( IS_HINTED( loader->load_flags ) ) + ft_glyphslot_grid_fit_metrics( glyph ); + return 0; } diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index f45a83b40..75d2e9b69 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -315,11 +315,7 @@ glyph->root.linearHoriAdvance = decoder.builder.advance.x; glyph->root.internal->glyph_transformed = 0; - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - + metrics->vertAdvance = 0; glyph->root.linearVertAdvance = 0; glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; @@ -363,42 +359,26 @@ vec->y = FT_MulFix( vec->y, y_scale ); } - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - /* Then scale the metrics */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - - if ( hinting ) - { - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - - metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); - } } /* compute the other metrics */ FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); - } - metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; + + /* make up vertical ones */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + + if ( hinting ) + ft_glyphslot_grid_fit_metrics( &glyph->root ); } /* Set control data to the glyph charstrings. Note that this is */