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_ppem
hb_font_get_ptem hb_font_get_ptem
hb_font_get_scale hb_font_get_scale
hb_font_get_synthetic_slant
hb_font_get_user_data hb_font_get_user_data
hb_font_get_variation_glyph hb_font_get_variation_glyph
hb_font_get_variation_glyph_func_t hb_font_get_variation_glyph_func_t
@ -346,6 +347,7 @@ hb_font_set_parent
hb_font_set_ppem hb_font_set_ppem
hb_font_set_ptem hb_font_set_ptem
hb_font_set_scale hb_font_set_scale
hb_font_set_synthetic_slant
hb_font_set_user_data hb_font_set_user_data
hb_font_set_variations hb_font_set_variations
hb_font_set_var_coords_design hb_font_set_var_coords_design

View File

@ -1477,6 +1477,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */ 1000, /* x_scale */
1000, /* y_scale */ 1000, /* y_scale */
0., /* slant */
0., /* slant_xy; */
1<<16, /* x_mult */ 1<<16, /* x_mult */
1<<16, /* y_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->x_scale = parent->x_scale;
font->y_scale = parent->y_scale; font->y_scale = parent->y_scale;
font->slant = parent->slant;
font->mults_changed (); font->mults_changed ();
font->x_ppem = parent->x_ppem; font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_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." * Return value: Point size. A value of zero means "not set."
* *
* Since: 0.9.2 * Since: 1.6.0
**/ **/
float float
hb_font_get_ptem (hb_font_t *font) hb_font_get_ptem (hb_font_t *font)
@ -2033,6 +2036,49 @@ hb_font_get_ptem (hb_font_t *font)
return font->ptem; 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 #ifndef HB_NO_VAR
/* /*
* Variations * Variations

View File

@ -1023,6 +1023,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem);
HB_EXTERN float HB_EXTERN float
hb_font_get_ptem (hb_font_t *font); 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_EXTERN void
hb_font_set_variations (hb_font_t *font, hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations, const hb_variation_t *variations,

View File

@ -109,6 +109,8 @@ struct hb_font_t
int32_t x_scale; int32_t x_scale;
int32_t y_scale; int32_t y_scale;
float slant;
float slant_xy;
int64_t x_mult; int64_t x_mult;
int64_t y_mult; int64_t y_mult;
@ -617,6 +619,7 @@ struct hb_font_t
signed upem = face->get_upem (); signed upem = face->get_upem ();
x_mult = ((int64_t) x_scale << 16) / upem; x_mult = ((int64_t) x_scale << 16) / upem;
y_mult = ((int64_t) y_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) 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 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); _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 */ /* Handle attachments */
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) 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); 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)) (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_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_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); case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
#ifndef HB_NO_VERTICAL #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_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun); 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.)); return tanf (a * float (M_PI / 180.));
} }
#if 0
static inline float static inline float
_hb_ratio_to_angle (float r) _hb_ratio_to_angle (float r)
{ {
return atanf (r) * float (180. / M_PI); return atanf (r) * float (180. / M_PI);
} }
#endif
/** /**
* hb_style_get_value: * hb_style_get_value:
@ -73,7 +72,8 @@ float
hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag) hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
{ {
if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO)) 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; 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; : 12.f;
} }
case HB_STYLE_TAG_SLANT_ANGLE: 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: case HB_STYLE_TAG_WIDTH:
return face->table.OS2->has_data () return face->table.OS2->has_data ()
? face->table.OS2->get_width () ? face->table.OS2->get_width ()