Merge pull request #3338 from harfbuzz/slant

[font] Add public API for synthetic slant
This commit is contained in:
Behdad Esfahbod 2022-01-02 12:02:20 -07:00 committed by GitHub
commit 165a6073fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 9 deletions

View File

@ -329,6 +329,7 @@ hb_font_get_parent
hb_font_get_ppem
hb_font_get_ptem
hb_font_get_scale
hb_font_get_synthetic_slant
hb_font_get_user_data
hb_font_get_variation_glyph
hb_font_get_variation_glyph_func_t
@ -346,6 +347,7 @@ hb_font_set_parent
hb_font_set_ppem
hb_font_set_ptem
hb_font_set_scale
hb_font_set_synthetic_slant
hb_font_set_user_data
hb_font_set_variations
hb_font_set_var_coords_design

View File

@ -1477,6 +1477,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */
1000, /* y_scale */
0., /* slant */
0., /* slant_xy; */
1<<16, /* x_mult */
1<<16, /* y_mult */
@ -1588,6 +1590,7 @@ hb_font_create_sub_font (hb_font_t *parent)
font->x_scale = parent->x_scale;
font->y_scale = parent->y_scale;
font->slant = parent->slant;
font->mults_changed ();
font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem;
@ -2025,7 +2028,7 @@ hb_font_set_ptem (hb_font_t *font,
*
* Return value: Point size. A value of zero means "not set."
*
* Since: 0.9.2
* Since: 1.6.0
**/
float
hb_font_get_ptem (hb_font_t *font)
@ -2033,6 +2036,49 @@ hb_font_get_ptem (hb_font_t *font)
return font->ptem;
}
/**
* hb_font_set_synthetic_slant:
* @font: #hb_font_t to work upon
* @ptem: font size in points.
*
* Sets the "synthetic slant" of a font. By default is zero.
* Synthetic slant is the graphical skew that the renderer
* applies to the font at rendering time.
*
* HarfBuzz needs to know this value to adjust shaping results,
* metrics, and style values to match the slanted rendering.
*
* <note>Note: The slant value is a ratio. For example, a
* 20% slant would be represented as a 0.2 value.</note>
*
* Since: REPLACEME
**/
HB_EXTERN void
hb_font_set_synthetic_slant (hb_font_t *font, float slant)
{
if (hb_object_is_immutable (font))
return;
font->slant = slant;
font->mults_changed ();
}
/**
* hb_font_get_synthetic_slant:
* @font: #hb_font_t to work upon
*
* Fetches the "synthetic slant" of a font.
*
* Return value: Synthetic slant. By default is zero.
*
* Since: REPLACEME
**/
HB_EXTERN float
hb_font_get_synthetic_slant (hb_font_t *font)
{
return font->slant;
}
#ifndef HB_NO_VAR
/*
* Variations

View File

@ -1023,6 +1023,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem);
HB_EXTERN float
hb_font_get_ptem (hb_font_t *font);
HB_EXTERN void
hb_font_set_synthetic_slant (hb_font_t *font, float slant);
HB_EXTERN float
hb_font_get_synthetic_slant (hb_font_t *font);
HB_EXTERN void
hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,

View File

@ -109,6 +109,8 @@ struct hb_font_t
int32_t x_scale;
int32_t y_scale;
float slant;
float slant_xy;
int64_t x_mult;
int64_t y_mult;
@ -617,6 +619,7 @@ struct hb_font_t
signed upem = face->get_upem ();
x_mult = ((int64_t) x_scale << 16) / upem;
y_mult = ((int64_t) y_scale << 16) / upem;
slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
}
hb_position_t em_mult (int16_t v, int64_t mult)

View File

@ -2951,7 +2951,7 @@ GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer H
}
void
GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
{
_hb_buffer_assert_gsubgpos_vars (buffer);
@ -2961,8 +2961,15 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
/* Handle attachments */
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
for (unsigned int i = 0; i < len; i++)
for (unsigned i = 0; i < len; i++)
propagate_attachment_offsets (pos, len, i, direction);
if (unlikely (font->slant))
{
for (unsigned i = 0; i < len; i++)
if (unlikely (pos[i].y_offset))
pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
}
}

View File

@ -160,9 +160,50 @@ hb_ot_metrics_get_position (hb_font_t *font,
(position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
{
unsigned mult = 1u;
if (font->slant)
{
unsigned rise = face->table.hhea->caretSlopeRise;
unsigned upem = face->get_upem ();
mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u;
}
if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE)
{
bool ret = GET_METRIC_Y (hhea, caretSlopeRise);
if (position)
*position *= mult;
return ret;
}
else
{
hb_position_t rise = 0;
if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise))
rise = *position;
bool ret = GET_METRIC_X (hhea, caretSlopeRun);
if (position)
{
*position *= mult;
if (font->slant)
*position += _hb_roundf (mult * font->slant_xy * rise);
}
return ret;
}
}
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
#ifndef HB_NO_VERTICAL
case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);

View File

@ -48,13 +48,12 @@ _hb_angle_to_ratio (float a)
{
return tanf (a * float (M_PI / 180.));
}
#if 0
static inline float
_hb_ratio_to_angle (float r)
{
return atanf (r) * float (180. / M_PI);
}
#endif
/**
* hb_style_get_value:
@ -73,7 +72,8 @@ float
hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
{
if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
+ font->slant;
hb_face_t *face = font->face;
@ -109,7 +109,14 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
: 12.f;
}
case HB_STYLE_TAG_SLANT_ANGLE:
return face->table.post->table->italicAngle.to_float ();
{
float angle = face->table.post->table->italicAngle.to_float ();
if (font->slant)
angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle));
return angle;
}
case HB_STYLE_TAG_WIDTH:
return face->table.OS2->has_data ()
? face->table.OS2->get_width ()