Merge pull request #3726 from harfbuzz/ft-bitmap

Ft bitmap
This commit is contained in:
Behdad Esfahbod 2022-07-15 15:32:58 -06:00 committed by GitHub
commit c8908f92d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 37 deletions

View File

@ -308,7 +308,7 @@ if $have_freetype; then
AC_DEFINE(HAVE_FREETYPE, 1, [Have FreeType 2 library])
save_libs=$LIBS
LIBS="$LIBS $FREETYPE_LIBS"
AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var FT_Get_Transform)
LIBS=$save_libs
fi
AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)

View File

@ -198,6 +198,7 @@ if freetype_dep.found()
['FT_Get_Var_Blend_Coordinates', {'deps': freetype_dep}],
['FT_Set_Var_Blend_Coordinates', {'deps': freetype_dep}],
['FT_Done_MM_Var', {'deps': freetype_dep}],
['FT_Get_Transform', {'deps': freetype_dep}],
]
if freetype_dep.type_name() == 'internal'

View File

@ -136,18 +136,42 @@ _hb_ft_font_destroy (void *data)
/* hb_font changed, update FT_Face. */
static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face)
{
float x_mult = 1.f, y_mult = 1.f;
FT_Set_Char_Size (ft_face,
abs (font->x_scale), abs (font->y_scale),
0, 0);
if (font->x_scale < 0) x_mult = -x_mult;
if (font->y_scale < 0) y_mult = -y_mult;
if (FT_Set_Char_Size (ft_face,
abs (font->x_scale), abs (font->y_scale),
0, 0
#if 0
font->x_ppem * 72 * 64 / font->x_scale,
font->y_ppem * 72 * 64 / font->y_scale);
font->y_ppem * 72 * 64 / font->y_scale
#endif
if (font->x_scale < 0 || font->y_scale < 0)
) && ft_face->num_fixed_sizes)
{
FT_Matrix matrix = { font->x_scale < 0 ? -(1<<16) : +(1<<16), 0,
0, font->y_scale < 0 ? -(1<<16) : +(1<<16)};
#ifdef HAVE_FT_GET_TRANSFORM
/* Bitmap font, eg. bitmap color emoji. */
/* TODO Pick largest size? */
int x_scale = ft_face->available_sizes[0].x_ppem;
int y_scale = ft_face->available_sizes[0].y_ppem;
FT_Set_Char_Size (ft_face,
x_scale, y_scale,
0, 0);
/* This contains the sign that was previously in x_mult/y_mult. */
x_mult = (float) font->x_scale / x_scale;
y_mult = (float) font->y_scale / y_scale;
#endif
}
else
{ /* Shrug */ }
if (x_mult != 1.f || y_mult != 1.f)
{
FT_Matrix matrix = { (int) roundf (x_mult * (1<<16)), 0,
0, (int) roundf (y_mult * (1<<16))};
FT_Set_Transform (ft_face, &matrix, nullptr);
}
@ -404,7 +428,13 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
int load_flags = ft_font->load_flags;
int mult = font->x_scale < 0 ? -1 : +1;
#ifdef HAVE_FT_GET_TRANSFORM
FT_Matrix matrix;
FT_Get_Transform (ft_face, &matrix, nullptr);
float mult = matrix.xx / 65536.f;
#else
float mult = font->x_scale < 0 ? -1 : +1;
#endif
for (unsigned int i = 0; i < count; i++)
{
@ -420,7 +450,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
ft_font->advance_cache.set (glyph, v);
}
*first_advance = (v * mult + (1<<9)) >> 10;
*first_advance = (int) (v * mult + (1<<9)) >> 10;
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
}
@ -436,12 +466,18 @@ hb_ft_get_glyph_v_advance (hb_font_t *font,
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Fixed v;
#ifdef HAVE_FT_GET_TRANSFORM
FT_Matrix matrix;
FT_Get_Transform (ft_font->ft_face, &matrix, nullptr);
float y_mult = matrix.yy / 65536.f;
#else
float y_mult = font->y_scale < 0 ? -1 : +1;
#endif
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
return 0;
if (font->y_scale < 0)
v = -v;
v = (int) (y_mult * v);
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
* have a Y growing upward. Hence the extra negation. */
@ -462,6 +498,15 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
#ifdef HAVE_FT_GET_TRANSFORM
FT_Matrix matrix;
FT_Get_Transform (ft_face, &matrix, nullptr);
float x_mult = matrix.xx / 65536.f;
float y_mult = matrix.yy / 65536.f;
#else
float x_mult = font->x_scale < 0 ? -1 : +1;
float y_mult = font->y_scale < 0 ? -1 : +1;
#endif
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
return false;
@ -471,10 +516,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
*x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX;
*y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
if (font->x_scale < 0)
*x = -*x;
if (font->y_scale < 0)
*y = -*y;
*x = (hb_position_t) (x_mult * *x);
*y = (hb_position_t) (y_mult * *y);
return true;
}
@ -510,24 +553,24 @@ hb_ft_get_glyph_extents (hb_font_t *font,
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
#ifdef HAVE_FT_GET_TRANSFORM
FT_Matrix matrix;
FT_Get_Transform (ft_face, &matrix, nullptr);
float x_mult = matrix.xx / 65536.f;
float y_mult = matrix.yy / 65536.f;
#else
float x_mult = font->x_scale < 0 ? -1 : +1;
float y_mult = font->y_scale < 0 ? -1 : +1;
#endif
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
return false;
extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
extents->width = ft_face->glyph->metrics.width;
extents->height = -ft_face->glyph->metrics.height;
if (font->x_scale < 0)
{
extents->x_bearing = -extents->x_bearing;
extents->width = -extents->width;
}
if (font->y_scale < 0)
{
extents->y_bearing = -extents->y_bearing;
extents->height = -extents->height;
}
extents->x_bearing = (hb_position_t) (x_mult * ft_face->glyph->metrics.horiBearingX);
extents->y_bearing = (hb_position_t) (y_mult * ft_face->glyph->metrics.horiBearingY);
extents->width = (hb_position_t) (x_mult * ft_face->glyph->metrics.width);
extents->height = (hb_position_t) (y_mult * -ft_face->glyph->metrics.height);
return true;
}
@ -620,16 +663,32 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
#ifdef HAVE_FT_GET_TRANSFORM
FT_Matrix matrix;
FT_Get_Transform (ft_face, &matrix, nullptr);
float y_mult = matrix.yy / 65536.f;
#else
float y_mult = font->y_scale < 0 ? -1 : +1;
#endif
metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
if (font->y_scale < 0)
if (ft_face->units_per_EM != 0)
{
metrics->ascender = -metrics->ascender;
metrics->descender = -metrics->descender;
metrics->line_gap = -metrics->line_gap;
metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
}
else
{
/* Bitmap-only font, eg. color bitmap font. */
metrics->ascender = ft_face->size->metrics.ascender;
metrics->descender = ft_face->size->metrics.descender;
metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender);
}
metrics->ascender = (hb_position_t) (y_mult * metrics->ascender);
metrics->descender = (hb_position_t) (y_mult * metrics->descender);
metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap);
return true;
}