Commit e5ff059f7fc32f43753230396efb62a4ac4c0cc5

Wu, Chia-I (吳佳一) 2006-01-15T06:00:49

* 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.

diff --git a/ChangeLog b/ChangeLog
index cea604d..e8a7c67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2006-01-15  Chia-I Wu  <b90201047@ntu.edu.tw>
+
+	* 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  <b90201047@ntu.edu.tw>
 
 	* docs/CHANGES: Mention the size selection change.
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 12cb1a7..017dc8f 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.          */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    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 e3f4251..cbb466c 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 84026f5..64b6e1f 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 a0491ed..0bb1f77 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 819b0db..c20d3bf 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;
   }