[ot-glyph] move glyph decompose logic of glyf to itself
One less vector allocation yet isn't zero alloc yet which needs more work.
This commit is contained in:
parent
017f606c83
commit
6118523502
|
@ -1043,10 +1043,10 @@ struct glyf
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_path (hb_font_t *font, hb_codepoint_t gid, hb_vector_t<hb_position_t> *coords, hb_vector_t<uint8_t> *commands) const
|
get_path (hb_font_t *font, hb_codepoint_t gid,
|
||||||
|
hb_ot_glyph_decompose_funcs_t *funcs, void *user_data) const
|
||||||
{
|
{
|
||||||
#define PUSH_POINT(x, y) HB_STMT_START { coords->push (font->em_scalef_x (x)); coords->push (font->em_scalef_y (y)); } HB_STMT_END
|
/* TODO: Make it work alloc free and without all_points vector */
|
||||||
#define PUSH_POINT_CMD(c, x, y) HB_STMT_START { commands->push (c); PUSH_POINT(x, y); } HB_STMT_END
|
|
||||||
contour_point_vector_t all_points;
|
contour_point_vector_t all_points;
|
||||||
if (unlikely (!get_points (font, gid, all_points))) return false;
|
if (unlikely (!get_points (font, gid, all_points))) return false;
|
||||||
hb_array_t<contour_point_t> points = all_points.sub_array (0, all_points.length - 4);
|
hb_array_t<contour_point_t> points = all_points.sub_array (0, all_points.length - 4);
|
||||||
|
@ -1065,14 +1065,15 @@ struct glyf
|
||||||
contour_point_t *next = &points[contour_start];
|
contour_point_t *next = &points[contour_start];
|
||||||
|
|
||||||
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
||||||
PUSH_POINT_CMD ('M', curr->x, curr->y);
|
funcs->move_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y), user_data);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (next->flag & Glyph::FLAG_ON_CURVE)
|
if (next->flag & Glyph::FLAG_ON_CURVE)
|
||||||
PUSH_POINT_CMD ('M', next->x, next->y);
|
funcs->move_to (font->em_scalef_x (next->x), font->em_scalef_y (next->y), user_data);
|
||||||
else
|
else
|
||||||
/* If both first and last points are off-curve, start at their middle. */
|
/* If both first and last points are off-curve, start at their middle. */
|
||||||
PUSH_POINT_CMD ('M', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f);
|
funcs->move_to (font->em_scalef_x ((curr->x + next->x) / 2.f),
|
||||||
|
font->em_scalef_y ((curr->y + next->y) / 2.f), user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < contour_length; ++i)
|
for (unsigned i = 0; i < contour_length; ++i)
|
||||||
|
@ -1081,21 +1082,19 @@ struct glyf
|
||||||
next = &points[contour_start + ((i + 1) % contour_length)];
|
next = &points[contour_start + ((i + 1) % contour_length)];
|
||||||
|
|
||||||
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
||||||
PUSH_POINT_CMD ('L', curr->x, curr->y); /* straight line */
|
funcs->line_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y), user_data);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PUSH_POINT_CMD ('Q', curr->x, curr->y);
|
float to_x, to_y;
|
||||||
if (next->flag & Glyph::FLAG_ON_CURVE)
|
if (next->flag & Glyph::FLAG_ON_CURVE) { to_x = next->x; to_y = next->y; }
|
||||||
PUSH_POINT (next->x, next->y);
|
else { to_x = (curr->x + next->x) / 2.f; to_y = (curr->y + next->y) / 2.f; }
|
||||||
else
|
funcs->conic_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y),
|
||||||
PUSH_POINT ((curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f);
|
font->em_scalef_x (to_x), font->em_scalef_y (to_y), user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands->push ('Z');
|
/* funcs->end_path (); */
|
||||||
contour_start += contour_length;
|
contour_start += contour_length;
|
||||||
}
|
}
|
||||||
#undef PUSH_POINT_CMD
|
|
||||||
#undef PUSH_POINT
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,16 +38,15 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
|
||||||
{
|
{
|
||||||
if (unlikely (!funcs || glyph >= font->face->get_num_glyphs ())) return false;
|
if (unlikely (!funcs || glyph >= font->face->get_num_glyphs ())) return false;
|
||||||
|
|
||||||
|
if (font->face->table.glyf->get_path (font, glyph, funcs, user_data)) return true;
|
||||||
|
|
||||||
|
#ifndef HB_NO_OT_FONT_CFF
|
||||||
hb_vector_t<hb_position_t> coords;
|
hb_vector_t<hb_position_t> coords;
|
||||||
hb_vector_t<uint8_t> commands;
|
hb_vector_t<uint8_t> commands;
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (!ret) ret = font->face->table.glyf->get_path (font, glyph, &coords, &commands);
|
|
||||||
#ifndef HB_NO_OT_FONT_CFF
|
|
||||||
if (!ret) ret = font->face->table.cff1->get_path (font, glyph, &coords, &commands);
|
if (!ret) ret = font->face->table.cff1->get_path (font, glyph, &coords, &commands);
|
||||||
if (!ret) ret = font->face->table.cff2->get_path (font, glyph, &coords, &commands);
|
if (!ret) ret = font->face->table.cff2->get_path (font, glyph, &coords, &commands);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (unlikely (!ret || coords.length % 2 != 0)) return false;
|
if (unlikely (!ret || coords.length % 2 != 0)) return false;
|
||||||
|
|
||||||
|
@ -68,12 +67,6 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
|
||||||
funcs->line_to (coords[coords_idx + 0], coords[coords_idx + 1], user_data);
|
funcs->line_to (coords[coords_idx + 0], coords[coords_idx + 1], user_data);
|
||||||
coords_idx += 2;
|
coords_idx += 2;
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
|
||||||
if (unlikely (coords.length < coords_idx + 4)) return false;
|
|
||||||
funcs->conic_to (coords[coords_idx + 0], coords[coords_idx + 1],
|
|
||||||
coords[coords_idx + 2], coords[coords_idx + 3], user_data);
|
|
||||||
coords_idx += 4;
|
|
||||||
break;
|
|
||||||
case 'C':
|
case 'C':
|
||||||
if (unlikely (coords.length >= coords_idx + 6)) return false;
|
if (unlikely (coords.length >= coords_idx + 6)) return false;
|
||||||
funcs->cubic_to (coords[coords_idx + 0], coords[coords_idx + 1],
|
funcs->cubic_to (coords[coords_idx + 0], coords[coords_idx + 1],
|
||||||
|
@ -84,6 +77,9 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,7 +107,12 @@ main (int argc, char **argv)
|
||||||
hb_font_extents_t font_extents;
|
hb_font_extents_t font_extents;
|
||||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
|
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
|
||||||
hb_glyph_extents_t extents = {0};
|
hb_glyph_extents_t extents = {0};
|
||||||
hb_font_get_glyph_extents (font, gid, &extents);
|
if (!hb_font_get_glyph_extents (font, gid, &extents))
|
||||||
|
{
|
||||||
|
printf ("Skip gid: %d\n", gid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
char name[100];
|
char name[100];
|
||||||
sprintf (name, "%d.svg", gid);
|
sprintf (name, "%d.svg", gid);
|
||||||
FILE *f = fopen (name, "wb");
|
FILE *f = fopen (name, "wb");
|
||||||
|
|
Loading…
Reference in New Issue