From 7722a5b2b221b8457b9ea37345bb3478b6848bfa Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 23 Apr 2025 19:29:59 +0200 Subject: [PATCH] [autofit] Support two below/above accents for vertical adjustment. (2/2) * src/autofit/afadjust.h (AF_ADJUST_UP2, AF_ADJUST_DOWN2): New macros. * src/autofit/afadjust.c (af_reverse_character_map_new): Updated. * src/autofit/aflatin.c (af_glyph_hints_apply_vertical_separation_adjustments): Implement it. --- src/autofit/afadjust.c | 8 +++++--- src/autofit/afadjust.h | 12 ++++++++++++ src/autofit/aflatin.c | 42 +++++++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/autofit/afadjust.c b/src/autofit/afadjust.c index 7fe578df2..d2855c359 100644 --- a/src/autofit/afadjust.c +++ b/src/autofit/afadjust.c @@ -682,12 +682,14 @@ "down", /* AF_ADJUST_DOWN */ "", "", - "top tilde", /* AF_ADJUST_TILDE_TOP */ - "bottom tilde", /* AF_ADJUST_TILDE_BOTTOM */ + "top tilde", /* AF_ADJUST_TILDE_TOP */ + "bottom tilde", /* AF_ADJUST_TILDE_BOTTOM */ + "below-top tilde", /* AF_ADJUST_TILDE_TOP2 */ + "above-bottom tilde", /* AF_ADJUST_TILDE_BOTTOM2 */ }; size_t flag_names_size = sizeof ( flag_names ) / sizeof ( char* ); - char flag_str[64]; + char flag_str[128]; int need_comma; size_t j; diff --git a/src/autofit/afadjust.h b/src/autofit/afadjust.h index 7fa929656..a31901be0 100644 --- a/src/autofit/afadjust.h +++ b/src/autofit/afadjust.h @@ -48,6 +48,18 @@ FT_BEGIN_HEADER /* is one pixel below the lowest point not enclosed by that contour. */ #define AF_ADJUST_DOWN 0x02 + /* Find the contour below the topmost contour and push it up, together */ + /* with the topmost contour, until its lowest point is one pixel above */ + /* the highest point not enclosed by that contour. This flag is */ + /* mutually exclusive with `AF_ADJUST_UP`. */ +#define AF_ADJUST_UP2 0x04 + + /* Find the contour above the bottommost contour and push it down, */ + /* together with the bottommost contour, until its highest point is */ + /* one pixel below the lowest point not enclosed by that contour. */ + /* This flag is mutually exclusive with `AF_ADJUST_DOWN`. */ +#define AF_ADJUST_DOWN2 0x08 + /* The topmost contour is a tilde. Enlarge it vertically so that it */ /* stays legible at small sizes, not degenerating to a horizontal line. */ #define AF_ADJUST_TILDE_TOP 0x10 diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index a86ad3fb8..89acea309 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -3460,16 +3460,18 @@ adj_type = db_entry->flags; } - if ( ( adj_type & ( AF_ADJUST_UP | AF_ADJUST_DOWN ) ) && - hints->num_contours >= 2 ) + if ( ( ( adj_type & ( AF_ADJUST_UP | AF_ADJUST_DOWN ) ) && + hints->num_contours >= 2 ) || + ( ( adj_type & ( AF_ADJUST_UP2 | AF_ADJUST_DOWN2 ) ) && + hints->num_contours >= 3 ) ) { /* Recompute vertical extrema, this time acting on already */ /* auto-hinted outlines. */ af_compute_vertical_extrema( hints ); } - if ( adj_type & AF_ADJUST_UP && - hints->num_contours >= 2 ) + if ( ( ( adj_type & AF_ADJUST_UP ) && hints->num_contours >= 2 ) || + ( ( adj_type & AF_ADJUST_UP2 ) && hints->num_contours >= 3 ) ) { FT_Int high_contour = 0; FT_Pos high_min_y; @@ -3493,7 +3495,9 @@ FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n" " Applying vertical adjustment: AF_ADJUST_UP\n" )); - high_contour = af_find_highest_contour( hints ); + high_contour = adj_type & AF_ADJUST_UP2 + ? af_find_second_highest_contour( hints ) + : af_find_highest_contour( hints ); /* Check for a horizontal overlap between the top contour and the */ /* rest. If there is no overlap, do not adjust. */ @@ -3570,7 +3574,6 @@ /* Value 8 is heuristic. */ FT_Pos height_delta = ( high_max_y - high_min_y ) / 8; FT_Pos min_y_limit = high_min_y - height_delta; - FT_Pos max_y_limit = high_max_y + height_delta; FT_TRACE4(( " Pushing top contour %ld units up\n", @@ -3578,10 +3581,10 @@ /* While we use only a single contour (the 'high' one) for */ /* computing `adjustment_amount`, we apply it to all contours */ - /* that are (approximately) in the same vertical range. This */ - /* covers, for example, the inner contour of the Czech ring */ - /* accent or the second acute accent in the Hungarian double */ - /* acute accent. */ + /* that are (approximately) in the same vertical range or */ + /* higher. This covers, for example, the inner contour of */ + /* the Czech ring accent or the second acute accent in the */ + /* Hungarian double acute accent. */ for ( contour = 0; contour < hints->num_contours; contour++ ) { FT_Pos min_y = hints->contour_y_minima[contour]; @@ -3589,16 +3592,15 @@ if ( min_y < max_y && - min_y > min_y_limit && - max_y < max_y_limit ) + min_y > min_y_limit ) af_move_contour_vertically( hints->contours[contour], adjustment_amount ); } } } - if ( adj_type & AF_ADJUST_DOWN && - hints->num_contours >= 2 ) + if ( ( ( adj_type & AF_ADJUST_DOWN ) && hints->num_contours >= 2 ) || + ( ( adj_type & AF_ADJUST_DOWN2 ) && hints->num_contours >= 3 ) ) { FT_Int low_contour = 0; FT_Pos low_min_y; @@ -3622,7 +3624,9 @@ FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n" " Applying vertical adjustment: AF_ADJUST_DOWN\n" )); - low_contour = af_find_lowest_contour( hints ); + low_contour = adj_type & AF_ADJUST_DOWN2 + ? af_find_second_lowest_contour( hints ) + : af_find_lowest_contour( hints ); horizontal_overlap = af_check_contour_horizontal_overlap( hints, low_contour ); @@ -3684,7 +3688,6 @@ else if ( adjustment_amount > 0 ) { FT_Pos height_delta = ( low_max_y - low_min_y ) / 8; - FT_Pos min_y_limit = low_min_y - height_delta; FT_Pos max_y_limit = low_max_y + height_delta; @@ -3698,7 +3701,6 @@ if ( min_y < max_y && - min_y > min_y_limit && max_y < max_y_limit ) af_move_contour_vertically( hints->contours[contour], -adjustment_amount ); @@ -3707,8 +3709,10 @@ } #ifdef FT_DEBUG_LEVEL_TRACE - if ( !( adj_type & ( AF_ADJUST_UP | AF_ADJUST_DOWN ) ) || - hints->num_contours < 2 ) + if ( !( ( ( adj_type & ( AF_ADJUST_UP | AF_ADJUST_DOWN ) ) && + hints->num_contours >= 2 ) || + ( ( adj_type & ( AF_ADJUST_UP2 | AF_ADJUST_DOWN2 ) ) && + hints->num_contours >= 3 ) ) ) FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n" " No vertical adjustment applied\n" )); #endif