Commit 054782c48ef12988bc278a7667c9368bf74e50d0

Alexei Podtelezhnikov 2022-01-19T22:14:06

[base] Undefined scale means no scale. It might be surprising that FreeType does not have default ppem and the size has to be set explicitly or face undefined behavior with undefined variables and errors. This offers an alternative to missing or zero scale by simply setting FT_LOAD_NO_SCALE. Defined behavior is bettr than undefined one. This is alternative to !132 and discussed in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43708 * src/base/ftobjs.c (FT_Load_Glyph): Deal with zero scale. * include/freetype/freetype.h: Document it.

diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index d3ea3f0..cb31c3c 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -522,13 +522,13 @@ FT_BEGIN_HEADER
    *   size.
    *
    * @note:
-   *   An @FT_Face has one _active_ @FT_Size object that is used by functions
-   *   like @FT_Load_Glyph to determine the scaling transformation that in
-   *   turn is used to load and hint glyphs and metrics.
+   *   An @FT_Face has one _active_ `FT_Size` object that is used by
+   *   functions like @FT_Load_Glyph to determine the scaling transformation
+   *   that in turn is used to load and hint glyphs and metrics.
    *
    *   You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, @FT_Request_Size
    *   or even @FT_Select_Size to change the content (i.e., the scaling
-   *   values) of the active @FT_Size.
+   *   values) of the active `FT_Size`.
    *
    *   You can use @FT_New_Size to create additional size objects for a given
    *   @FT_Face, but they won't be used by other functions until you activate
@@ -2702,8 +2702,8 @@ FT_BEGIN_HEADER
    *   'https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'.
    *
    *   Contrary to @FT_Set_Char_Size, this function doesn't have special code
-   *   to normalize zero-valued widths, heights, or resolutions (which lead
-   *   to errors in most cases).
+   *   to normalize zero-valued widths, heights, or resolutions, which are
+   *   treated as @FT_LOAD_NO_SCALE.
    *
    *   Don't use this function if you are using the FreeType cache API.
    */
@@ -2819,7 +2819,7 @@ FT_BEGIN_HEADER
    *
    *   load_flags ::
    *     A flag indicating what to load for this glyph.  The @FT_LOAD_XXX
-   *     constants can be used to control the glyph loading process (e.g.,
+   *     flags can be used to control the glyph loading process (e.g.,
    *     whether the outline should be scaled, whether to load bitmaps or
    *     not, whether to hint the outline, etc).
    *
@@ -2827,6 +2827,9 @@ FT_BEGIN_HEADER
    *   FreeType error code.  0~means success.
    *
    * @note:
+   *   For proper scaling and hinting, the active @FT_Size object owned by
+   *   the face has to be meaningfully non-trivially initialized by
+   *   calling @FT_Set_Char_Size before this function, for example.
    *   The loaded glyph may be transformed.  See @FT_Set_Transform for the
    *   details.
    *
@@ -2918,6 +2921,8 @@ FT_BEGIN_HEADER
    *
    *   FT_LOAD_NO_SCALE ::
    *     Don't scale the loaded outline glyph but keep it in font units.
+   *     This flag is also assumed if @FT_Size owned by the face was not
+   *     properly initialized.
    *
    *     This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and
    *     unsets @FT_LOAD_RENDER.
@@ -3410,7 +3415,7 @@ FT_BEGIN_HEADER
    *     @FT_Render_Mode for a list of possible values.
    *
    *     If @FT_RENDER_MODE_NORMAL is used, a previous call of @FT_Load_Glyph
-   *     with flag @FT_LOAD_COLOR makes FT_Render_Glyph provide a default
+   *     with flag @FT_LOAD_COLOR makes `FT_Render_Glyph` provide a default
    *     blending of colored glyph layers associated with the current glyph
    *     slot (provided the font contains such layers) instead of rendering
    *     the glyph slot's outline.  This is an experimental feature; see
@@ -3420,9 +3425,6 @@ FT_BEGIN_HEADER
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   To get meaningful results, font scaling values must be set with
-   *   functions like @FT_Set_Char_Size before calling `FT_Render_Glyph`.
-   *
    *   When FreeType outputs a bitmap of a glyph, it really outputs an alpha
    *   coverage map.  If a pixel is completely covered by a filled-in
    *   outline, the bitmap contains 0xFF at that pixel, meaning that
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 18de2f7..4f5e7d4 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -858,6 +858,11 @@
     library = driver->root.library;
     hinter  = library->auto_hinter;
 
+    /* undefined scale means no scale */
+    if ( face->size->metrics.x_ppem == 0 ||
+         face->size->metrics.y_ppem == 0 )
+      load_flags |= FT_LOAD_NO_SCALE;
+
     /* resolve load flags dependencies */
 
     if ( load_flags & FT_LOAD_NO_RECURSE )