freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] wl/sbix e75206610 3/5: [truetype] Fix 'sbix' table handling.


From: Werner Lemberg
Subject: [freetype2] wl/sbix e75206610 3/5: [truetype] Fix 'sbix' table handling.
Date: Sat, 19 Mar 2022 19:05:38 -0400 (EDT)

branch: wl/sbix
commit e75206610c67bd4fd3ae20953c3334f19d974720
Author: Werner Lemberg <wl@gnu.org>
Commit: Werner Lemberg <wl@gnu.org>

    [truetype] Fix 'sbix' table handling.
    
    * src/sfnt/ttsbit.c (tt_face_load_sbix_image): Correct calculation of
    'metrics->horiBearingY'.
    Set vertical metrics.
    
    * src/sfnt/sfobjs.c (sfnt_load_face): Adjust setting of
    `FT_FACE_FLAG_SBIT_OUTLINE`.
    Handle metrics of fonts with 'sbix' table.
    
    * src/truetype/ttgload.c (TT_Load_Glyph): For 'sbix' embedded bitmaps, apply
    bbox offset and bearing values of the corresponding glyph in the 'glyf'
    table if it exists and has a contour.
    
    * src/truetype/ttobjs.c (tt_face_init): Handle font with 'sbix' table.
    
    Fixes issue #998.
---
 src/sfnt/sfobjs.c      | 19 ++++++++-----------
 src/sfnt/ttsbit.c      | 21 +++++++++++++++++++--
 src/truetype/ttgload.c | 35 ++++++++++++++++++++++++++++++++++-
 src/truetype/ttobjs.c  |  3 ++-
 4 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index eb2d4a133..572d63527 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -851,12 +851,6 @@
     is_apple_sbit = 0;
     is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
 
-    /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
-     * outline rendered on top.  We don't support that yet, so just ignore
-     * the 'glyf' outline and advertise it as a bitmap-only font. */
-    if ( is_apple_sbix )
-      has_outline = FALSE;
-
     /* if this font doesn't contain outlines, we try to load */
     /* a `bhed' table                                        */
     if ( !has_outline && sfnt->load_bhed )
@@ -1059,10 +1053,12 @@
 
       if ( has_outline == TRUE )
       {
-        flags |= FT_FACE_FLAG_SCALABLE;   /* scalable outlines */
-
-        if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
-          flags |= FT_FACE_FLAG_SBIX_OUTLINE;   /* and 'sbix' bitmaps */
+        /* by default (and for backward compatibility) we handle */
+        /* fonts with an 'sbix' table as bitmap-only             */
+        if ( !is_apple_sbix )
+          flags |= FT_FACE_FLAG_SBIX_OUTLINE;   /* with 'sbix' bitmaps */
+        else
+          flags |= FT_FACE_FLAG_SCALABLE;       /* scalable outlines */
       }
 
       /* The sfnt driver only supports bitmap fonts natively, thus we */
@@ -1286,7 +1282,8 @@
        *
        * Set up metrics.
        */
-      if ( FT_IS_SCALABLE( root ) )
+      if ( FT_IS_SCALABLE( root )      ||
+           FT_HAS_SBIX_OUTLINE( root ) )
       {
         /* XXX What about if outline header is missing */
         /*     (e.g. sfnt wrapped bitmap)?             */
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 179e9cc55..0ab602632 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1580,17 +1580,34 @@
 
     if ( !error )
     {
-      FT_Short   abearing;
+      FT_Short   abearing; /* not used here */
       FT_UShort  aadvance;
 
 
       tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
 
       metrics->horiBearingX = (FT_Short)originOffsetX;
-      metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
+      metrics->vertBearingX = (FT_Short)originOffsetX;
+
+      metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
+      metrics->vertBearingY = (FT_Short)originOffsetY;
+
       metrics->horiAdvance  = (FT_UShort)( aadvance *
                                            face->root.size->metrics.x_ppem /
                                            face->header.Units_Per_EM );
+
+      if ( face->vertical_info )
+        tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
+      else if ( face->os2.version != 0xFFFFU )
+        aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
+                                      face->os2.sTypoDescender );
+      else
+        aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
+                                      face->horizontal.Descender );
+
+      metrics->vertAdvance  = (FT_UShort)( aadvance *
+                                           face->root.size->metrics.x_ppem /
+                                           face->header.Units_Per_EM );
     }
 
     return error;
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b19f7a283..2a80ed519 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2897,8 +2897,12 @@
       }
       else
       {
-        if ( FT_IS_SCALABLE( glyph->face ) )
+        if ( FT_IS_SCALABLE( glyph->face )      ||
+             FT_HAS_SBIX_OUTLINE( glyph->face ) )
         {
+          TT_Face  face = (TT_Face)glyph->face;
+
+
           /* for the bbox we need the header only */
           (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
           (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
@@ -2906,6 +2910,35 @@
           glyph->linearHoriAdvance = loader.linear;
           glyph->linearVertAdvance = loader.vadvance;
 
+          /* Bitmaps from the 'sbix' table need special treatment:  */
+          /* if there is a glyph contour, the bitmap origin must be */
+          /* shifted to be relative to the lower left corner of the */
+          /* glyph bounding box, also taking the left-side bearing  */
+          /* (or top bearing) into account.                         */
+          if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX &&
+               loader.n_contours > 0                            )
+          {
+            FT_Int  bitmap_left;
+            FT_Int  bitmap_top;
+
+
+            if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+            {
+              /* This is a guess, since Apple's CoreText engine doesn't */
+              /* really do vertical typesetting.                        */
+              bitmap_left = loader.bbox.xMin;
+              bitmap_top  = loader.top_bearing;
+            }
+            else
+            {
+              bitmap_left = loader.left_bearing;
+              bitmap_top  = loader.bbox.yMin;
+            }
+
+            glyph->bitmap_left += FT_MulFix( bitmap_left, x_scale ) >> 6;
+            glyph->bitmap_top  += FT_MulFix( bitmap_top,  y_scale ) >> 6;
+          }
+
           /* sanity checks: if `xxxAdvance' in the sbit metric */
           /* structure isn't set, use `linearXXXAdvance'      */
           if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 9cb1af6e6..5ef729b51 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -727,7 +727,8 @@
     if ( error )
       goto Exit;
 
-    if ( FT_IS_SCALABLE( ttface ) )
+    if ( FT_IS_SCALABLE( ttface )      ||
+         FT_HAS_SBIX_OUTLINE( ttface ) )
     {
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       if ( !ttface->internal->incremental_interface )



reply via email to

[Prev in Thread] Current Thread [Next in Thread]