freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] gsoc-craig-2023 62378cca3 1/2: * Add trace output


From: Werner Lemberg
Subject: [freetype2] gsoc-craig-2023 62378cca3 1/2: * Add trace output
Date: Sun, 25 Jun 2023 23:47:17 -0400 (EDT)

branch: gsoc-craig-2023
commit 62378cca3a8f222aa96c3584d7738144a77270d2
Author: Craig White <gerzytet@gmail.com>
Commit: Craig White <gerzytet@gmail.com>

    * Add trace output
    * Remove assumption of exactly 2 contours
    * Adjustment database lookups use binary search now
---
 include/freetype/internal/fttrace.h |   1 +
 src/autofit/afadjust.c              | 138 ++++++++++++++++++++++++------------
 src/autofit/afadjust.h              |  23 +++---
 src/autofit/aflatin.c               |  74 +++++++++++++------
 4 files changed, 159 insertions(+), 77 deletions(-)

diff --git a/include/freetype/internal/fttrace.h 
b/include/freetype/internal/fttrace.h
index 319fe56fd..156fb21dc 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -164,6 +164,7 @@ FT_TRACE_DEF( afhints )
 FT_TRACE_DEF( afmodule )
 FT_TRACE_DEF( aflatin )
 FT_TRACE_DEF( afshaper )
+FT_TRACE_DEF( afadjust )
 
   /* SDF components */
 FT_TRACE_DEF( sdf )       /* signed distance raster for outlines (ftsdf.c) */
diff --git a/src/autofit/afadjust.c b/src/autofit/afadjust.c
index 00a21a447..cf2a59671 100644
--- a/src/autofit/afadjust.c
+++ b/src/autofit/afadjust.c
@@ -2,34 +2,52 @@
 #include <freetype/freetype.h>
 #include <freetype/internal/ftobjs.h>
 #include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftdebug.h>
 
-#define AF_ADJUSTMENT_DATABASE_LENGTH 12
+#define AF_ADJUSTMENT_DATABASE_LENGTH 
(sizeof(adjustment_database)/sizeof(adjustment_database[0]))
+#undef  FT_COMPONENT
+#define FT_COMPONENT  afadjust
 
 /*TODO: find out whether capital u/U with accent entries are needed*/
 /*the accent won't merge with the rest of the glyph because the accent mark is 
sitting above empty space*/
 FT_LOCAL_ARRAY_DEF( AF_AdjustmentDatabaseEntry )
-adjustment_database[AF_ADJUSTMENT_DATABASE_LENGTH] = {
-    {'i',   AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE},
-    {'j',   AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE},
-    {0xC8,  AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*E with grave*/
-    {0xCC,  AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*I with grave*/
-    {0xD9,  AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*U with grave*/
-    {0xE0,  AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*a with grave*/
-    {0xEC,  AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*i with grave*/
-    {0x114, AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*E with macron*/
-    {0x12A, AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*I with macron*/
-    {0x12B, AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*i with macron*/
-    {0x16A, AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}, /*U with macron*/
-    {0x16B, AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE}  /*u with macron*/
-    /*TODO: find out why E won't work, even though it appears to be 
one-on-one*/
+adjustment_database[] =
+{
+    {0x21,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* ! */
+    {0x69,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* i */
+    {0x6A,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* j */
+    {0xA1,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*Inverted Exclamation 
Mark*/
+    {0xBF,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*Inverted Question Mark*/
+    {0xC0,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*A with grave*/
+    {0xC1,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*A with acute*/
+    {0xC2,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*A with circumflex*/
+    {0xC3,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*A with tilde*/
+    {0xC8,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*E with grave*/
+    {0xCC,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*I with grave*/
+    {0xD9,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*U with grave*/
+    {0xE0,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*a with grave*/
+    {0xEC,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*i with grave*/
+    {0x114, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*E with macron*/
+    {0x12A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*I with macron*/
+    {0x12B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*i with macron*/
+    {0x16A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*U with macron*/
+    {0x16B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}  /*u with macron*/
 };
 
 /*Helper function: get the adjustment database entry for a codepoint*/
 FT_LOCAL_DEF( const AF_AdjustmentDatabaseEntry* )
 af_adjustment_database_lookup( FT_UInt32 codepoint ) {
-    for ( FT_Int entry = 0; entry < AF_ADJUSTMENT_DATABASE_LENGTH; entry++ ) {
-        if ( adjustment_database[entry].codepoint == codepoint ) {
-            return &adjustment_database[entry];
+    /* Binary search for database entry */
+    FT_UInt low = 0;
+    FT_UInt high = AF_ADJUSTMENT_DATABASE_LENGTH - 1;
+    while (high > low) {
+        FT_UInt mid = (low + high) / 2;
+        if (adjustment_database[mid].codepoint < codepoint) {
+            low = mid + 1;
+        } else if (adjustment_database[mid].codepoint > codepoint) {
+            high = mid - 1;
+        } else {
+            return &adjustment_database[mid];
         }
     }
 
@@ -40,30 +58,37 @@ FT_LOCAL_DEF( AF_VerticalSeparationAdjustmentType )
 af_lookup_vertical_seperation_type( AF_ReverseCharacterMap map, FT_Int 
glyph_index ) {
     FT_UInt32 codepoint = af_reverse_character_map_lookup( map, glyph_index );
     const AF_AdjustmentDatabaseEntry *entry = af_adjustment_database_lookup( 
codepoint );
-    if ( entry == NULL ) {
+    if ( entry == NULL )
+    {
         return AF_VERTICAL_ADJUSTMENT_NONE;
     }
     return entry->vertical_separation_adjustment_type;
 }
 
-typedef struct AF_ReverseMapEntry_ {
+typedef struct AF_ReverseMapEntry_
+{
     FT_Int glyph_index;
     FT_UInt32 codepoint;
 } AF_ReverseMapEntry;
 
-typedef struct AF_ReverseCharacterMap_ {
+typedef struct AF_ReverseCharacterMap_
+{
     FT_UInt length;
     AF_ReverseMapEntry *entries;
 } AF_ReverseCharacterMap_Rec;
 
 FT_LOCAL_DEF(FT_UInt32)
-af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int 
glyph_index ) {
-    if ( map == NULL ) {
+af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int 
glyph_index )
+{
+    if ( map == NULL )
+    {
         return 0;
     }
 
-    for ( FT_UInt entry = 0; entry < map->length; entry++ ) {
-        if ( map->entries[entry].glyph_index == glyph_index ) {
+    for ( FT_UInt entry = 0; entry < map->length; entry++ )
+    {
+        if ( map->entries[entry].glyph_index == glyph_index )
+        {
             return map->entries[entry].codepoint;
         }
     }
@@ -72,64 +97,87 @@ af_reverse_character_map_lookup( AF_ReverseCharacterMap 
map, FT_Int glyph_index
 }
 
 FT_LOCAL_DEF( FT_Error )
-af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, 
FT_Memory memory ) {
+af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, 
FT_Memory memory )
+{
     /* Search for a unicode charmap */
     /* If there isn't one, create a blank map */
-    
+
     /*TODO: change this to logic that searches for a "preferred" unicode 
charmap that maps the most codepoints*/
     /*see find_unicode_charmap*/
     /*TODO: use GSUB lookups    */
+    FT_TRACE4(( "af_reverse_character_map_new: building reverse character 
map\n" ));
     FT_CMap unicode_charmap = NULL;
-    for ( FT_UInt i = 0; i < face->num_charmaps; i++ ) {
-        if ( face->charmaps[i]->encoding == FT_ENCODING_UNICODE ) {
+    for ( FT_UInt i = 0; i < face->num_charmaps; i++ )
+    {
+        if ( face->charmaps[i]->encoding == FT_ENCODING_UNICODE )
+        {
             unicode_charmap = FT_CMAP( face->charmaps[i] );
         }
     }
-    
-    if ( unicode_charmap == NULL ) {
+
+    if ( unicode_charmap == NULL )
+    {
         *map = NULL;
         return FT_Err_Ok;
     }
 
     FT_Error error;
 
-    if ( FT_NEW( *map ) ) {
+    if ( FT_NEW( *map ) )
+    {
         goto Exit;
     }
 
     FT_Int capacity = 10;
     FT_Int size = 0;
-    
-    if ( FT_NEW_ARRAY((*map)->entries, capacity) ) {
+
+    if ( FT_NEW_ARRAY((*map)->entries, capacity) )
+    {
         goto Exit;
     }
-    for ( FT_Int i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ ) {
+#ifdef FT_DEBUG_LEVEL_TRACE
+    int failed_lookups = 0;
+#endif
+    for ( FT_Int i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ )
+    {
         FT_UInt32 codepoint = adjustment_database[i].codepoint;
         FT_Int glyph = unicode_charmap->clazz->char_index(unicode_charmap, 
codepoint);
-        if ( glyph == 0 ) {
+        if ( glyph == 0 )
+        {
+#ifdef FT_DEBUG_LEVEL_TRACE
+            failed_lookups++;
+#endif
             continue;
         }
-        if (size == capacity) {
+        if ( size == capacity )
+        {
             capacity += capacity / 2;
-            if ( FT_RENEW_ARRAY((*map)->entries, size, capacity) ) {
+            if ( FT_RENEW_ARRAY((*map)->entries, size, capacity) )
+            {
                 goto Exit;
             }
         }
         size++;
-        (*map)->entries[i].glyph_index = glyph;
-        (*map)->entries[i].codepoint = codepoint;
+        ( *map )->entries[i].glyph_index = glyph;
+        ( *map )->entries[i].codepoint = codepoint;
     }
-    (*map)->length = size;
+    ( *map )->length = size;
 
 Exit:
-    if ( error ) {
-        if ( *map ) {
+    if ( error )
+    {
+        FT_TRACE4(( "    error while building reverse character map.  Using 
blank map.\n" ));
+        if ( *map )
+        {
             FT_FREE( ( *map )->entries );
         }
         FT_FREE( *map );
         return error;
     }
-
+#ifdef FT_DEBUG_LEVEL_TRACE
+    FT_TRACE4(( "    reverse character map built successfully"\
+                " with %d entries and %d failed lookups.\n", size, 
failed_lookups ));
+#endif
     return FT_Err_Ok;
 }
 
@@ -137,4 +185,4 @@ FT_LOCAL_DEF( FT_Error )
 af_reverse_character_map_done( AF_ReverseCharacterMap map, FT_Memory memory ) {
     FT_FREE( map->entries );
     return FT_Err_Ok;
-}
\ No newline at end of file
+}
diff --git a/src/autofit/afadjust.h b/src/autofit/afadjust.h
index f1c8c47d3..65cdfaa66 100644
--- a/src/autofit/afadjust.h
+++ b/src/autofit/afadjust.h
@@ -7,11 +7,11 @@ FT_BEGIN_HEADER
 
 /*The type of adjustment that should be done to prevent cases where 2 parts of 
a character*/
 /*stacked vertically merge, even though they should be separate*/
-typedef enum AF_VerticalSeparationAdjustmentType_ {
-    AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE,
-    /*"One on one" means that the character is expected to be one contour on 
top of another, where the contours should not touch*/
-    /*the hinter will force the contours to have a gap of at least 1 pixel 
between them*/
-    /*by moving the top contour up */
+typedef enum AF_VerticalSeparationAdjustmentType_
+{
+    AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP,
+    /*This means that the hinter should find the topmost contour and push it 
up until its lowest point is 1 pixel*/
+    /*above the highest point not part of that contour.*/
     AF_VERTICAL_ADJUSTMENT_NONE
 
     /*others will be needed, such as the case where the lower contour should 
be moved in the adjustment instead of the upper one*/
@@ -19,10 +19,11 @@ typedef enum AF_VerticalSeparationAdjustmentType_ {
     /*and a way of handling A and O, where the letter consists of 2 contours*/
 } AF_VerticalSeparationAdjustmentType;
 
-typedef struct AF_AdjustmentDatabaseEntry_ {
-    FT_UInt32 codepoint;
-    AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
-  } AF_AdjustmentDatabaseEntry;
+typedef struct AF_AdjustmentDatabaseEntry_
+{
+  FT_UInt32 codepoint;
+  AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
+} AF_AdjustmentDatabaseEntry;
 
 struct AF_ReverseCharacterMap_;
 
@@ -37,11 +38,11 @@ af_reverse_character_map_lookup( AF_ReverseCharacterMap 
map, FT_Int glyph_index
 /*allocate and populate the reverse character map, using the character map 
within the face*/
 FT_LOCAL( FT_Error )
 af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, 
FT_Memory memory );
- 
+
 /*free the reverse character map*/
 FT_LOCAL( FT_Error )
 af_reverse_character_map_done( AF_ReverseCharacterMap map, FT_Memory memory );
 
 FT_END_HEADER
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 8177c66f1..2e870f59e 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -1153,7 +1153,7 @@
         goto Exit;
       }
       af_latin_metrics_check_digits( metrics, face );
-      
+
       af_reverse_character_map_new( face, &metrics->root.reverse_charmap, 
face->memory );
     }
 
@@ -2745,13 +2745,25 @@
   }
 
 
-void af_glyph_hints_apply_adjustments(AF_GlyphHints hints, AF_Dimension dim, 
FT_Int glyph_index, AF_ReverseCharacterMap reverse_charmap) {
-  if ( dim != AF_DIMENSION_VERT ) {
+#undef  FT_COMPONENT
+#define FT_COMPONENT  afadjust
+
+void
+af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
+                                                      AF_Dimension dim,
+                                                      FT_Int glyph_index,
+                                                      AF_ReverseCharacterMap 
reverse_charmap )
+{
+  if ( dim != AF_DIMENSION_VERT )
+  {
     return;
   }
-  if ( af_lookup_vertical_seperation_type( reverse_charmap, glyph_index ) == 
AF_VERTICAL_ADJUSTMENT_ONE_ON_ONE &&
-      hints->num_contours == 2 ) {
-    
+
+  if ( af_lookup_vertical_seperation_type( reverse_charmap, glyph_index ) == 
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
+       && hints->num_contours >= 2 )
+  {
+    FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments: 
Applying vertical adjustment: AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP\n" ));
+
     /* Figure out which contout is the higher one by finding the one */
     /* with the highest minimum y value */
 
@@ -2759,22 +2771,27 @@ void af_glyph_hints_apply_adjustments(AF_GlyphHints 
hints, AF_Dimension dim, FT_
     FT_Pos highest_min_y = 0;
     FT_Pos current_min_y = 0;
 
-    for ( FT_Int contour = 0; contour < hints->num_contours; contour++ ) {
+    for ( FT_Int contour = 0; contour < hints->num_contours; contour++ )
+    {
       AF_Point point = hints->contours[contour];
       AF_Point first_point = point;
-      if ( point == NULL ) { /*TODO: is this necessary?*/
+      if ( point == NULL )
+      { /*TODO: is this necessary?*/
         continue;
       }
       current_min_y = point->y;
 
-      do {
-        if ( point->y < current_min_y ) {
+      do
+      {
+        if ( point->y < current_min_y )
+        {
           current_min_y = point->y;
         }
         point = point->next;
       } while ( point != first_point );
 
-      if ( highest_contour == -1 || current_min_y > highest_min_y ) {
+      if ( highest_contour == -1 || current_min_y > highest_min_y )
+      {
         highest_min_y = current_min_y;
         highest_contour = contour;
       }
@@ -2785,42 +2802,57 @@ void af_glyph_hints_apply_adjustments(AF_GlyphHints 
hints, AF_Dimension dim, FT_
     /* contour, bump the high contour up until the distance is one pixel */
 
     FT_Int adjustment_amount = 0;
-    for ( FT_Int contour = 0; contour < hints->num_contours; contour++ ) {
-      if (contour == highest_contour) {
+    for ( FT_Int contour = 0; contour < hints->num_contours; contour++ )
+    {
+      if ( contour == highest_contour )
+      {
         continue;
       }
       AF_Point point = hints->contours[contour];
       AF_Point first_point = point;
-      if ( point == NULL ) {
+      if ( point == NULL )
+      {
         continue;
       }
       FT_Pos max_y = point->y;
 
-      do {
-        if ( point->y > max_y ) {
+      do
+      {
+        if ( point->y > max_y )
+        {
           max_y = point->y;
         }
         point = point->next;
       } while ( point != first_point );
 
-      if ( max_y >= highest_min_y - 64 ) {
-        adjustment_amount = 64 - (highest_min_y - max_y);
+      if ( max_y >= highest_min_y - 64 )
+      {
+        adjustment_amount = 64 - ( highest_min_y - max_y );
       }
     }
 
+    FT_TRACE4(( "    Pushing top contour %d units up\n", adjustment_amount ));
     if ( adjustment_amount > 0 ) {
       AF_Point point = hints->contours[highest_contour];
       AF_Point first_point = point;
-      if ( point != NULL ) {
-        do {
+      if ( point != NULL )
+      {
+        do
+        {
           point->y += adjustment_amount;
           point = point->next;
         } while ( point != first_point );
       }
     }
+  } else {
+    FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments: No 
vertical adjustment needed\n" ));
   }
 }
 
+#undef  FT_COMPONENT
+#define FT_COMPONENT  aflatin
+
+
 
   /* Compute the snapped width of a given stem, ignoring very thin ones. */
   /* There is a lot of voodoo in this function; changing the hard-coded  */
@@ -3689,7 +3721,7 @@ void af_glyph_hints_apply_adjustments(AF_GlyphHints 
hints, AF_Dimension dim, FT_
         af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
         af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
         af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
-        af_glyph_hints_apply_adjustments(hints, (AF_Dimension) dim, 
glyph_index, metrics->root.reverse_charmap);
+        af_glyph_hints_apply_vertical_separation_adjustments(hints, 
(AF_Dimension) dim, glyph_index, metrics->root.reverse_charmap);
       }
     }
 



reply via email to

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