unsigned first = 0; for (unsigned contour : contours)
{ auto it = points.as_array ().sub_array (first, contour - first); while (it)
{
hb_outline_point_t p1 = *it++; switch (p1.type)
{ case hb_outline_point_t::type_t::MOVE_TO:
{
pen->move_to (pen_data, st,
p1.x, p1.y);
} break; case hb_outline_point_t::type_t::LINE_TO:
{
pen->line_to (pen_data, st,
p1.x, p1.y);
} break; case hb_outline_point_t::type_t::QUADRATIC_TO:
{
hb_outline_point_t p2 = *it++;
pen->quadratic_to (pen_data, st,
p1.x, p1.y,
p2.x, p2.y);
} break; case hb_outline_point_t::type_t::CUBIC_TO:
{
hb_outline_point_t p2 = *it++;
hb_outline_point_t p3 = *it++;
pen->cubic_to (pen_data, st,
p1.x, p1.y,
p2.x, p2.y,
p3.x, p3.y);
} break;
}
}
pen->close_path (pen_data, st);
first = contour;
}
}
float hb_outline_t::control_area () const
{ float a = 0; unsigned first = 0; for (unsigned contour : contours)
{ for (unsigned i = first; i < contour; i++)
{ unsigned j = i + 1 < contour ? i + 1 : first;
auto &pi = points[i]; auto &pj = points[j];
a += pi.x * pj.y - pi.y * pj.x;
}
first = contour;
} return a * .5f;
}
void hb_outline_t::embolden (float x_strength, float y_strength, float x_shift, float y_shift)
{ /* This function is a straight port of FreeType's FT_Outline_EmboldenXY. * Permission has been obtained from the FreeType authors of the code
* to relicense it under the HarfBuzz license. */
if (!x_strength && !y_strength) return; if (!points) return;
x_strength /= 2.f;
y_strength /= 2.f;
bool orientation_negative = control_area () < 0;
signed first = 0; for (unsigned c = 0; c < contours.length; c++)
{
hb_outline_vector_t in, out, anchor, shift; float l_in, l_out, l_anchor = 0, l, q, d;
/* Counter j cycles though the points; counter i advances only */ /* when points are moved; anchor k marks the first moved point. */ for ( signed i = last, j = first, k = -1;
j != i && i != k;
j = j < last ? j + 1 : first )
{ if ( j != k )
{
out.x = points[j].x - points[i].x;
out.y = points[j].y - points[i].y;
l_out = out.normalize_len ();
if ( l_out == 0 ) continue;
} else
{
out = anchor;
l_out = l_anchor;
}
if ( l_in != 0 )
{ if ( k < 0 )
{
k = i;
anchor = in;
l_anchor = l_in;
}
d = in.x * out.x + in.y * out.y;
/* shift only if turn is less than ~160 degrees */ if ( d > -15.f/16.f )
{
d = d + 1.f;
/* shift components along lateral bisector in proper orientation */
shift.x = in.y + out.y;
shift.y = in.x + out.x;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.