Merge pull request #4107 from harfbuzz/cubic-glyf
[glyf] Support cubic curves
This commit is contained in:
commit
c6c1c6ddf1
|
@ -20,7 +20,7 @@ struct SimpleGlyph
|
||||||
FLAG_X_SAME = 0x10,
|
FLAG_X_SAME = 0x10,
|
||||||
FLAG_Y_SAME = 0x20,
|
FLAG_Y_SAME = 0x20,
|
||||||
FLAG_OVERLAP_SIMPLE = 0x40,
|
FLAG_OVERLAP_SIMPLE = 0x40,
|
||||||
FLAG_RESERVED2 = 0x80
|
FLAG_CUBIC = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
const GlyphHeader &header;
|
const GlyphHeader &header;
|
||||||
|
|
|
@ -26,22 +26,29 @@ struct path_builder_t
|
||||||
|
|
||||||
optional_point_t lerp (optional_point_t p, float t)
|
optional_point_t lerp (optional_point_t p, float t)
|
||||||
{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
|
{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
|
||||||
} first_oncurve, first_offcurve, last_offcurve;
|
} first_oncurve, first_offcurve, last_offcurve, last_offcurve2;
|
||||||
|
|
||||||
path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
|
path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
|
||||||
{
|
{
|
||||||
font = font_;
|
font = font_;
|
||||||
draw_session = &draw_session_;
|
draw_session = &draw_session_;
|
||||||
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
|
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
|
/* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
|
||||||
See also:
|
See also:
|
||||||
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
|
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
|
||||||
* https://stackoverflow.com/a/20772557 */
|
* https://stackoverflow.com/a/20772557
|
||||||
|
*
|
||||||
|
* Cubic support added (incomplete). */
|
||||||
void consume_point (const contour_point_t &point)
|
void consume_point (const contour_point_t &point)
|
||||||
{
|
{
|
||||||
bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
|
bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
|
||||||
|
#ifdef HB_NO_CUBIC_GLYF
|
||||||
|
bool is_cubic = false;
|
||||||
|
#else
|
||||||
|
bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
|
||||||
|
#endif
|
||||||
optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
|
optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
|
||||||
if (!first_oncurve)
|
if (!first_oncurve)
|
||||||
{
|
{
|
||||||
|
@ -69,16 +76,41 @@ struct path_builder_t
|
||||||
{
|
{
|
||||||
if (is_on_curve)
|
if (is_on_curve)
|
||||||
{
|
{
|
||||||
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
if (last_offcurve2)
|
||||||
p.x, p.y);
|
{
|
||||||
|
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
|
||||||
|
last_offcurve.x, last_offcurve.y,
|
||||||
|
p.x, p.y);
|
||||||
|
last_offcurve2 = optional_point_t ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
||||||
|
p.x, p.y);
|
||||||
last_offcurve = optional_point_t ();
|
last_offcurve = optional_point_t ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
optional_point_t mid = last_offcurve.lerp (p, .5f);
|
if (is_cubic && !last_offcurve2)
|
||||||
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
{
|
||||||
mid.x, mid.y);
|
last_offcurve2 = last_offcurve;
|
||||||
last_offcurve = p;
|
last_offcurve = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optional_point_t mid = last_offcurve.lerp (p, .5f);
|
||||||
|
|
||||||
|
if (is_cubic)
|
||||||
|
{
|
||||||
|
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
|
||||||
|
last_offcurve.x, last_offcurve.y,
|
||||||
|
mid.x, mid.y);
|
||||||
|
last_offcurve2 = optional_point_t ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
||||||
|
mid.x, mid.y);
|
||||||
|
last_offcurve = p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -105,8 +137,15 @@ struct path_builder_t
|
||||||
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
|
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
|
||||||
first_oncurve.x, first_oncurve.y);
|
first_oncurve.x, first_oncurve.y);
|
||||||
else if (last_offcurve && first_oncurve)
|
else if (last_offcurve && first_oncurve)
|
||||||
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
{
|
||||||
first_oncurve.x, first_oncurve.y);
|
if (last_offcurve2)
|
||||||
|
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
|
||||||
|
last_offcurve.x, last_offcurve.y,
|
||||||
|
first_oncurve.x, first_oncurve.y);
|
||||||
|
else
|
||||||
|
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
||||||
|
first_oncurve.x, first_oncurve.y);
|
||||||
|
}
|
||||||
else if (first_oncurve)
|
else if (first_oncurve)
|
||||||
draw_session->line_to (first_oncurve.x, first_oncurve.y);
|
draw_session->line_to (first_oncurve.x, first_oncurve.y);
|
||||||
else if (first_offcurve)
|
else if (first_offcurve)
|
||||||
|
@ -117,7 +156,7 @@ struct path_builder_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getting ready for the next contour */
|
/* Getting ready for the next contour */
|
||||||
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
|
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
|
||||||
draw_session->close_path ();
|
draw_session->close_path ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#ifndef HB_EXPERIMENTAL_API
|
#ifndef HB_EXPERIMENTAL_API
|
||||||
#define HB_NO_BEYOND_64K
|
#define HB_NO_BEYOND_64K
|
||||||
|
#define HB_NO_CUBIC_GLYF
|
||||||
#define HB_NO_VAR_COMPOSITES
|
#define HB_NO_VAR_COMPOSITES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue