mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-05 13:35:06 +00:00
[glyf] Change drawing algorithm to match FreeType / CoreText
This commit is contained in:
parent
f858def14b
commit
4b54ee1148
2 changed files with 108 additions and 53 deletions
|
@ -230,8 +230,60 @@ struct glyf_accelerator_t
|
|||
if (consumer.is_consuming_contour_points ())
|
||||
{
|
||||
auto *points = all_points.arrayZ;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
consumer.consume_point (points[i]);
|
||||
|
||||
if (false)
|
||||
{
|
||||
/* Our path-builder was designed to work with this simple loop.
|
||||
* But FreeType and CoreText do it differently, so we match those
|
||||
* with the other, more complicated, code branch below. */
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
consumer.consume_point (points[i]);
|
||||
if (points[i].is_end_point)
|
||||
consumer.contour_end ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
// Start of a contour.
|
||||
if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE)
|
||||
{
|
||||
// First point is on-curve. Draw the contour.
|
||||
for (; i < count; i++)
|
||||
{
|
||||
consumer.consume_point (points[i]);
|
||||
if (points[i].is_end_point)
|
||||
{
|
||||
consumer.contour_end ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned start = i;
|
||||
|
||||
// Find end of the contour.
|
||||
for (; i < count; i++)
|
||||
if (points[i].is_end_point)
|
||||
break;
|
||||
|
||||
unsigned end = i;
|
||||
|
||||
// Enough to start from the end. Our path-builder takes care of the rest.
|
||||
if (likely (end < count)) // Can only fail in case of alloc failure *maybe*.
|
||||
consumer.consume_point (points[end]);
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
consumer.consume_point (points[i]);
|
||||
|
||||
consumer.contour_end ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consumer.points_end ();
|
||||
}
|
||||
|
||||
|
@ -304,6 +356,7 @@ struct glyf_accelerator_t
|
|||
|
||||
HB_ALWAYS_INLINE
|
||||
void consume_point (const contour_point_t &point) { bounds.add (point); }
|
||||
void contour_end () {}
|
||||
void points_end () { bounds.get_extents (font, extents, scaled); }
|
||||
|
||||
bool is_consuming_contour_points () { return extents; }
|
||||
|
|
|
@ -124,58 +124,60 @@ struct path_builder_t
|
|||
}
|
||||
}
|
||||
|
||||
if (unlikely (point.is_end_point))
|
||||
{
|
||||
if (first_offcurve && last_offcurve)
|
||||
{
|
||||
optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
|
||||
first_offcurve2 :
|
||||
first_offcurve);
|
||||
if (last_offcurve2)
|
||||
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
|
||||
last_offcurve.x, last_offcurve.y,
|
||||
mid.x, mid.y);
|
||||
else
|
||||
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
||||
mid.x, mid.y);
|
||||
last_offcurve = optional_point_t ();
|
||||
}
|
||||
/* now check the rest */
|
||||
|
||||
if (first_offcurve && first_oncurve)
|
||||
{
|
||||
if (first_offcurve2)
|
||||
draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
|
||||
first_offcurve.x, first_offcurve.y,
|
||||
first_oncurve.x, first_oncurve.y);
|
||||
else
|
||||
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
|
||||
first_oncurve.x, first_oncurve.y);
|
||||
}
|
||||
else if (last_offcurve && first_oncurve)
|
||||
{
|
||||
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)
|
||||
draw_session->line_to (first_oncurve.x, first_oncurve.y);
|
||||
else if (first_offcurve)
|
||||
{
|
||||
float x = first_offcurve.x, y = first_offcurve.y;
|
||||
draw_session->move_to (x, y);
|
||||
draw_session->quadratic_to (x, y, x, y);
|
||||
}
|
||||
|
||||
/* Getting ready for the next contour */
|
||||
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
|
||||
draw_session->close_path ();
|
||||
}
|
||||
}
|
||||
|
||||
void contour_end ()
|
||||
{
|
||||
if (first_offcurve && last_offcurve)
|
||||
{
|
||||
optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
|
||||
first_offcurve2 :
|
||||
first_offcurve);
|
||||
if (last_offcurve2)
|
||||
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
|
||||
last_offcurve.x, last_offcurve.y,
|
||||
mid.x, mid.y);
|
||||
else
|
||||
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
|
||||
mid.x, mid.y);
|
||||
last_offcurve = optional_point_t ();
|
||||
}
|
||||
/* now check the rest */
|
||||
|
||||
if (first_offcurve && first_oncurve)
|
||||
{
|
||||
if (first_offcurve2)
|
||||
draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
|
||||
first_offcurve.x, first_offcurve.y,
|
||||
first_oncurve.x, first_oncurve.y);
|
||||
else
|
||||
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
|
||||
first_oncurve.x, first_oncurve.y);
|
||||
}
|
||||
else if (last_offcurve && first_oncurve)
|
||||
{
|
||||
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)
|
||||
draw_session->line_to (first_oncurve.x, first_oncurve.y);
|
||||
else if (first_offcurve)
|
||||
{
|
||||
float x = first_offcurve.x, y = first_offcurve.y;
|
||||
draw_session->move_to (x, y);
|
||||
draw_session->quadratic_to (x, y, x, y);
|
||||
}
|
||||
|
||||
/* Getting ready for the next contour */
|
||||
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
|
||||
draw_session->close_path ();
|
||||
}
|
||||
|
||||
void points_end () {}
|
||||
|
||||
bool is_consuming_contour_points () { return true; }
|
||||
|
|
Loading…
Add table
Reference in a new issue