From e5ff059f7fc32f43753230396efb62a4ac4c0cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wu=2C=20Chia-I=20=28=E5=90=B3=E4=BD=B3=E4=B8=80=29?= Date: Sun, 15 Jan 2006 06:00:49 +0000 Subject: [PATCH] * src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/pcf/pcfdrivr.c (PCF_Glyph_Load), src/winfonts/winfnt.c (FNT_Load_Glyph): Don't set the linear advance fields as they are only for the outline glyphs. * include/freetype/freetype.h: Documentation updates/clarificatoins. The meaning of FT_LOAD_FORCE_AUTOHINT is changed so that no real change need be made to the code. * src/base/ftobjs.c (FT_Load_Glyph): Resolve flag dependencies and decide whether to use the auto-hinter according to documentation. There should to be no real difference. Some checks (e.g., is text height positve?) after the glyph is loaded. (FT_Select_Size, FT_Request_Size): Scales are set to wrong values. Be careful that scales won't be negative. --- ChangeLog | 17 ++++++ include/freetype/freetype.h | 66 +++++++++++++----------- src/base/ftobjs.c | 100 ++++++++++++++++++++++++------------ src/bdf/bdfdrivr.c | 4 +- src/pcf/pcfdrivr.c | 4 +- src/winfonts/winfnt.c | 3 -- 6 files changed, 122 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index cea604d0c..e8a7c6726 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-01-15 Chia-I Wu + + * src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/pcf/pcfdrivr.c + (PCF_Glyph_Load), src/winfonts/winfnt.c (FNT_Load_Glyph): Don't set + the linear advance fields as they are only for the outline glyphs. + + * include/freetype/freetype.h: Documentation updates/clarificatoins. + The meaning of FT_LOAD_FORCE_AUTOHINT is changed so that no real + change need be made to the code. + + * src/base/ftobjs.c (FT_Load_Glyph): Resolve flag dependencies and + decide whether to use the auto-hinter according to documentation. + There should to be no real difference. + Some checks (e.g., is text height positve?) after the glyph is loaded. + (FT_Select_Size, FT_Request_Size): Scales are set to wrong values. + Be careful that scales won't be negative. + 2006-01-14 Chia-I Wu * docs/CHANGES: Mention the size selection change. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 12cb1a7cf..017dc8f63 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -1240,11 +1240,14 @@ FT_BEGIN_HEADER /* hence the term `ppem' (pixels per EM). It is also */ /* refeered to as `nominal height'. */ /* */ - /* x_scale :: A 16.16 fractional scale used to convert font */ - /* units to 26.6 fractional pixels horizontally. */ + /* x_scale :: A 16.16 fractional scale used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* formats. */ /* */ - /* y_scale :: A 16.16 fractional scale used to convert font */ - /* units to 26.6 fractional pixels vertically. */ + /* y_scale :: A 16.16 fractional scale used to convert vertical */ + /* metrics from font units to 26.6 fractional pixels. */ + /* Only relevant for scalable formats. */ /* */ /* ascender :: The ascender in 26.6 fractional pixels. See */ /* @FT_FaceRec for the details. */ @@ -1255,13 +1258,14 @@ FT_BEGIN_HEADER /* height :: The height in 26.6 fractional pixels. See */ /* @FT_FaceRec for the details. */ /* */ - /* max_advance :: Maximal horizontal advance in 26.6 fractional */ - /* pixels. Always positive. */ + /* max_advance :: The maximal advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ /* */ /* */ - /* For scalable fonts, the scales are determined first during a size */ - /* changing operation. Then other fields are set to the scaled */ - /* values of the corresponding fields in @FT_FaceRec. */ + /* The scales, if relevant, are determined first during a size */ + /* changing operation. The reset fields are then set by the driver. */ + /* For scalable formats, they are usually set to scaled values of the */ + /* corresponding fields in @FT_FaceRec. */ /* */ /* Note that due to glyph hinting, these values might not be exact */ /* for certain fonts. Thus they must be treated as unreliable */ @@ -1380,22 +1384,19 @@ FT_BEGIN_HEADER /* Note that even when the glyph image is */ /* transformed, the metrics are not. */ /* */ - /* linearHoriAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled horizontal advance width */ - /* for the glyph (i.e. the scaled and unhinted */ - /* value of the hori advance). This can be */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ /* */ - /* Note that this value is expressed by default */ - /* in 16.16 pixels. However, when the glyph is */ - /* loaded with the FT_LOAD_LINEAR_DESIGN flag, */ - /* this field contains simply the value of the */ - /* advance in original font units. */ - /* */ - /* linearVertAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled vertical advance height */ - /* for the glyph. See linearHoriAdvance for */ - /* comments. */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ /* */ /* advance :: This is the transformed advance width for the */ /* glyph. */ @@ -2296,7 +2297,8 @@ FT_BEGIN_HEADER * problematic currently. * * FT_LOAD_FORCE_AUTOHINT :: - * Disable the driver's native hinter. See also the note below. + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. * * FT_LOAD_CROP_BITMAP :: * Indicates that the font driver should crop the loaded bitmap glyph @@ -2327,6 +2329,8 @@ FT_BEGIN_HEADER * The description of sub-glyphs is not available to client * applications for now. * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * * FT_LOAD_IGNORE_TRANSFORM :: * Indicates that the tranform matrix set by @FT_Set_Transform should * be ignored. @@ -2341,7 +2345,7 @@ FT_BEGIN_HEADER * * FT_LOAD_LINEAR_DESIGN :: * Indicates that the `linearHoriAdvance' and `linearVertAdvance' - * fields of @FT_GlyphSlotRec should not be scaled. See + * fields of @FT_GlyphSlotRec should be kept in font units. See * @FT_GlyphSlotRec for details. * * FT_LOAD_NO_AUTOHINT :: @@ -2349,10 +2353,11 @@ FT_BEGIN_HEADER * * @note: * By default, hinting is enabled and the font's native hinter (see - * @FT_FACE_FLAG_HINTER) is preferred over auto-hinter. You can disable - * hinting by setting @FT_LOAD_NO_HINTING, disable the font's native - * hinter by setting @FT_LOAD_FORCE_AUTOHINT, and disable the - * auto-hinter by setting @FT_LOAD_NO_AUTOHINT. + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. * * Besides deciding which hinter to use, you can also decide which * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. @@ -2427,7 +2432,8 @@ FT_BEGIN_HEADER * `load_flags'. They can't be ORed. * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the - * corresponding mode (i.e., the mode best matching the algorithm used). + * corresponding mode (i.e., the mode best matching the algorithm used) + * unless @FT_LOAD_MONOCHROME is set. * * You can use a hinting algorithm that doesn't correspond to the same * rendering mode. As an example, it is possible to use the `light' diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index e3f425120..cbb466c1c 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -485,7 +485,7 @@ FT_Driver driver; FT_GlyphSlot slot; FT_Library library; - FT_Bool autohint; + FT_Bool autohint = 0; FT_Module hinter; @@ -498,48 +498,43 @@ slot = face->glyph; ft_glyphslot_clear( slot ); - driver = face->driver; + driver = face->driver; + library = driver->root.library; + hinter = library->auto_hinter; + + /* resolve load flags dependencies */ - /* if the flag NO_RECURSE is set, we disable hinting and scaling */ if ( load_flags & FT_LOAD_NO_RECURSE ) - { - /* disable scaling, hinting, and transformation */ load_flags |= FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM; - /* disable bitmap rendering */ + if ( load_flags & FT_LOAD_NO_SCALE ) + { + load_flags |= FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP; + load_flags &= ~FT_LOAD_RENDER; } - /* do we need to load the glyph through the auto-hinter? */ - library = driver->root.library; - hinter = library->auto_hinter; - autohint = - FT_BOOL( hinter && - !( load_flags & ( FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_NO_AUTOHINT ) ) && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) ); - - /* force auto-hinting for the LIGHT hinting mode */ - if ( autohint && - FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT ) + if ( FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT ) load_flags |= FT_LOAD_FORCE_AUTOHINT; - if ( autohint ) + /* auto-hinter is preferred and should be used */ + if ( ( !FT_DRIVER_HAS_HINTER( driver ) || + ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) && + !( load_flags & FT_LOAD_NO_HINTING ) && + !( load_flags & FT_LOAD_NO_AUTOHINT ) ) { - if ( FT_DRIVER_HAS_HINTER( driver ) && - !( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) - autohint = 0; + /* check if it works for this face */ + autohint = + FT_BOOL( hinter && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + face->internal->transform_matrix.yy > 0 && + face->internal->transform_matrix.yx == 0 ); } - /* don't apply autohinting if glyph is vertically distorted or */ - /* mirrored */ - if ( autohint && !( face->internal->transform_matrix.yy <= 0 || - face->internal->transform_matrix.yx != 0 ) ) + if ( autohint ) { FT_AutoHinter_Service hinting; @@ -602,6 +597,7 @@ FT_Size_Metrics* metrics = &face->size->metrics; + /* it's tricky! */ slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, metrics->x_scale, 64 ); @@ -1720,6 +1716,36 @@ } } + /* some checks */ + + if ( FT_IS_SCALABLE( face ) ) + { + if ( face->height < 0 ) + face->height = -face->height; + + if ( !FT_HAS_VERTICAL( face ) ) + face->max_advance_height = face->height; + } + + if ( FT_HAS_FIXED_SIZES( face ) ) + { + FT_Int i; + + + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( bsize->height < 0 ) + bsize->height = -bsize->height; + if ( bsize->x_ppem < 0 ) + bsize->x_ppem = -bsize->x_ppem; + if ( bsize->y_ppem < 0 ) + bsize->y_ppem = -bsize->y_ppem; + } + } + /* initialize internal face data */ { FT_Face_Internal internal = face->internal; @@ -2069,8 +2095,8 @@ } else { - metrics->x_scale = 0x10000L; - metrics->y_scale = 0x10000L; + metrics->x_scale = 1 << 22; + metrics->y_scale = 1 << 22; metrics->ascender = bsize->y_ppem; metrics->descender = 0; metrics->height = bsize->height << 6; @@ -2099,7 +2125,7 @@ if ( !face ) return FT_Err_Invalid_Face_Handle; - if ( !req ) + if ( !req || req->width < 0 || req->height < 0 ) return FT_Err_Invalid_Argument; clazz = face->driver->clazz; @@ -2135,6 +2161,12 @@ break; } + if ( w < 0 ) + w = -w; + + if ( h < 0 ) + h = -h; + if ( req->horiResolution ) scaled_w = ( req->width * req->horiResolution + 36 ) / 72; else @@ -2191,6 +2223,8 @@ else { FT_ZERO( metrics ); + metrics->x_scale = 1 << 22; + metrics->y_scale = 1 << 22; if ( FT_HAS_FIXED_SIZES( face ) ) bitmap_only = 1; diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 84026f569..64b6e1ff1 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -698,6 +698,7 @@ THE SOFTWARE. break; } + slot->format = FT_GLYPH_FORMAT_BITMAP; slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; @@ -708,9 +709,6 @@ THE SOFTWARE. slot->metrics.width = bitmap->width << 6; slot->metrics.height = bitmap->rows << 6; - slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16; - slot->format = FT_GLYPH_FORMAT_BITMAP; - Exit: return error; } diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index a0491ed92..0bb1f770e 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -520,6 +520,7 @@ THE SOFTWARE. } } + slot->format = FT_GLYPH_FORMAT_BITMAP; slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; @@ -530,9 +531,6 @@ THE SOFTWARE. metric->leftSideBearing ) << 6; slot->metrics.height = bitmap->rows << 6; - slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; - slot->format = FT_GLYPH_FORMAT_BITMAP; - FT_TRACE4(( " --- ok\n" )); Exit: diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index 819b0dbdc..c20d3bfe9 100644 --- a/src/winfonts/winfnt.c +++ b/src/winfonts/winfnt.c @@ -724,9 +724,6 @@ slot->metrics.horiBearingX = 0; slot->metrics.horiBearingY = slot->bitmap_top << 6; - slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; - slot->format = FT_GLYPH_FORMAT_BITMAP; - Exit: return error; }