diff --git a/src/fontations/lib.rs b/src/fontations/lib.rs index 06025d931..82e6b87a1 100644 --- a/src/fontations/lib.rs +++ b/src/fontations/lib.rs @@ -357,7 +357,7 @@ impl OutlinePen for HbPen { } extern "C" fn _hb_fontations_draw_glyph( - _font: *mut hb_font_t, + font: *mut hb_font_t, font_data: *mut ::std::os::raw::c_void, glyph: hb_codepoint_t, draw_funcs: *mut hb_draw_funcs_t, @@ -380,11 +380,23 @@ extern "C" fn _hb_fontations_draw_glyph( // Allocate zero bytes for the draw_state_t on the stack. let mut draw_state: hb_draw_state_t = unsafe { std::mem::zeroed::() }; + let slant = unsafe { hb_font_get_synthetic_slant(font) }; + let mut x_scale: i32 = 0; + let mut y_scale: i32 = 0; + unsafe { hb_font_get_scale(font, &mut x_scale, &mut y_scale); } + let slant = if y_scale != 0 { + slant as f32 * x_scale as f32 / y_scale as f32 + } else { + 0. + }; + draw_state.slant_xy = slant; + let mut pen = HbPen { draw_state: &mut draw_state, draw_funcs, draw_data, }; + let _ = outline_glyph.draw(draw_settings, &mut pen); } diff --git a/src/hb-draw.h b/src/hb-draw.h index 6306b69c0..89ef1b22a 100644 --- a/src/hb-draw.h +++ b/src/hb-draw.h @@ -41,6 +41,7 @@ HB_BEGIN_DECLS * @path_start_y: Y component of the start of current path * @current_x: X component of current point * @current_y: Y component of current point + * @slant_xy: (Since: REPLACEME) Slanting factor for synthetic oblique * * Current drawing state. * @@ -55,6 +56,8 @@ typedef struct hb_draw_state_t { float current_x; float current_y; + float slant_xy; + /*< private >*/ hb_var_num_t reserved1; hb_var_num_t reserved2; @@ -62,7 +65,6 @@ typedef struct hb_draw_state_t { hb_var_num_t reserved4; hb_var_num_t reserved5; hb_var_num_t reserved6; - hb_var_num_t reserved7; } hb_draw_state_t; /** diff --git a/src/hb-draw.hh b/src/hb-draw.hh index 87d03a488..15978cdf0 100644 --- a/src/hb-draw.hh +++ b/src/hb-draw.hh @@ -99,6 +99,10 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (st.path_open)) close_path (draw_data, st); + + if (st.slant_xy) + to_x += to_y * st.slant_xy; + st.current_x = to_x; st.current_y = to_y; } @@ -109,7 +113,12 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + to_x += to_y * st.slant_xy; + emit_line_to (draw_data, st, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -121,7 +130,15 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + { + control_x += control_y * st.slant_xy; + to_x += to_y * st.slant_xy; + } + emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -134,7 +151,16 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + { + control1_x += control1_y * st.slant_xy; + control2_x += control2_y * st.slant_xy; + to_x += to_y * st.slant_xy; + } + emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -168,46 +194,32 @@ DECLARE_NULL_INSTANCE (hb_draw_funcs_t); struct hb_draw_session_t { - hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f) - : slant {slant_}, not_slanted {slant == 0.f}, - funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT - {} + hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_xy = 0.f) + : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT + { st.slant_xy = slant_xy; } ~hb_draw_session_t () { close_path (); } HB_ALWAYS_INLINE void move_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->move_to (draw_data, st, - to_x, to_y); - else - funcs->move_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->move_to (draw_data, st, + to_x, to_y); } HB_ALWAYS_INLINE void line_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->line_to (draw_data, st, - to_x, to_y); - else - funcs->line_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->line_to (draw_data, st, + to_x, to_y); } void HB_ALWAYS_INLINE quadratic_to (float control_x, float control_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->quadratic_to (draw_data, st, - control_x, control_y, - to_x, to_y); - else - funcs->quadratic_to (draw_data, st, - control_x + control_y * slant, control_y, - to_x + to_y * slant, to_y); + funcs->quadratic_to (draw_data, st, + control_x, control_y, + to_x, to_y); } void HB_ALWAYS_INLINE @@ -215,16 +227,10 @@ struct hb_draw_session_t float control2_x, float control2_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->cubic_to (draw_data, st, - control1_x, control1_y, - control2_x, control2_y, - to_x, to_y); - else - funcs->cubic_to (draw_data, st, - control1_x + control1_y * slant, control1_y, - control2_x + control2_y * slant, control2_y, - to_x + to_y * slant, to_y); + funcs->cubic_to (draw_data, st, + control1_x, control1_y, + control2_x, control2_y, + to_x, to_y); } HB_ALWAYS_INLINE void close_path () @@ -233,8 +239,6 @@ struct hb_draw_session_t } public: - float slant; - bool not_slanted; hb_draw_funcs_t *funcs; void *draw_data; hb_draw_state_t st;