[ot-glyph] Add open/close callbacks
This commit is contained in:
parent
ec1fba1388
commit
79fed9a1e4
@ -523,18 +523,22 @@ hb_ot_font_set_funcs
|
||||
<SECTION>
|
||||
<FILE>hb-ot-glyph</FILE>
|
||||
hb_ot_glyph_decompose_funcs_t
|
||||
hb_ot_glyph_decompose_close_path_func_t
|
||||
hb_ot_glyph_decompose_conic_to_func_t
|
||||
hb_ot_glyph_decompose_cubic_to_func_t
|
||||
hb_ot_glyph_decompose_line_to_func_t
|
||||
hb_ot_glyph_decompose_move_to_func_t
|
||||
hb_ot_glyph_decompose_open_path_func_t
|
||||
hb_ot_glyph_decompose
|
||||
hb_ot_glyph_decompose_funcs_create
|
||||
hb_ot_glyph_decompose_funcs_destroy
|
||||
hb_ot_glyph_decompose_funcs_reference
|
||||
hb_ot_glyph_decompose_funcs_set_close_path_func
|
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func
|
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func
|
||||
hb_ot_glyph_decompose_funcs_set_line_to_func
|
||||
hb_ot_glyph_decompose_funcs_set_move_to_func
|
||||
hb_ot_glyph_decompose_funcs_set_open_path_func
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -357,8 +357,8 @@ struct cff1_path_param_t
|
||||
delta = delta_;
|
||||
}
|
||||
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { /* funcs->close_path (); */ path_open = false; }
|
||||
void start_path () { funcs->open_path (user_data); path_open = true; }
|
||||
void end_path () { if (path_open) funcs->close_path (user_data); path_open = false; }
|
||||
bool is_path_open () const { return path_open; }
|
||||
|
||||
void move_to (const point_t &p)
|
||||
|
@ -153,8 +153,8 @@ struct cff2_path_param_t
|
||||
user_data = user_data_;
|
||||
}
|
||||
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { /* funcs->close_path (); */ path_open = false; }
|
||||
void start_path () { funcs->open_path (user_data); path_open = true; }
|
||||
void end_path () { if (path_open) funcs->close_path (user_data); path_open = false; }
|
||||
bool is_path_open () const { return path_open; }
|
||||
|
||||
void move_to (const point_t &p)
|
||||
|
@ -1047,14 +1047,19 @@ struct glyf
|
||||
get_path (hb_font_t *font, hb_codepoint_t gid,
|
||||
const hb_ot_glyph_decompose_funcs_t *funcs, void *user_data) const
|
||||
{
|
||||
/* TODO: Make it alloc free and work without all_points vector */
|
||||
/* Making this completely alloc free is not that easy
|
||||
https://github.com/harfbuzz/harfbuzz/issues/2095
|
||||
mostly because of gvar handling in VF fonts,
|
||||
perhaps a separate path can be considered */
|
||||
contour_point_vector_t all_points;
|
||||
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);
|
||||
|
||||
unsigned contour_start = 0;
|
||||
/* Learnt from https://github.com/opentypejs/opentype.js/blob/4e0bb99/src/tables/glyf.js#L222 */
|
||||
while (contour_start < points.length)
|
||||
{
|
||||
funcs->open_path (user_data);
|
||||
unsigned contour_length = 0;
|
||||
for (unsigned i = contour_start; i < points.length; ++i)
|
||||
{
|
||||
@ -1093,8 +1098,8 @@ struct glyf
|
||||
font->em_scalef_x (to_x), font->em_scalef_y (to_y), user_data);
|
||||
}
|
||||
}
|
||||
/* funcs->end_path (); */
|
||||
contour_start += contour_length;
|
||||
funcs->close_path (user_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -100,6 +100,40 @@ hb_ot_glyph_decompose_funcs_set_cubic_to_func (hb_ot_glyph_decompose_funcs_t
|
||||
funcs->cubic_to = cubic_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_open_path_func:
|
||||
* @funcs: decompose functions object
|
||||
* @open_path: open-path callback
|
||||
*
|
||||
* Sets open-path callback to the decompose functions object.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
void
|
||||
hb_ot_glyph_decompose_funcs_set_open_path_func (hb_ot_glyph_decompose_funcs_t *funcs,
|
||||
hb_ot_glyph_decompose_open_path_func_t open_path)
|
||||
{
|
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return;
|
||||
funcs->open_path = open_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_close_path_func:
|
||||
* @funcs: decompose functions object
|
||||
* @close_path: close-path callback
|
||||
*
|
||||
* Sets close-path callback to the decompose functions object.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
void
|
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (hb_ot_glyph_decompose_funcs_t *funcs,
|
||||
hb_ot_glyph_decompose_close_path_func_t close_path)
|
||||
{
|
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return;
|
||||
funcs->close_path = close_path;
|
||||
}
|
||||
|
||||
static void
|
||||
_move_to_noop (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
||||
|
||||
@ -116,6 +150,9 @@ _cubic_to_noop (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_
|
||||
hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_open_close_path_noop (void *user_data HB_UNUSED) {}
|
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_create:
|
||||
*
|
||||
@ -134,6 +171,8 @@ hb_ot_glyph_decompose_funcs_create ()
|
||||
funcs->line_to = (hb_ot_glyph_decompose_line_to_func_t) _line_to_noop;
|
||||
funcs->conic_to = (hb_ot_glyph_decompose_conic_to_func_t) _conic_to_noop;
|
||||
funcs->cubic_to = (hb_ot_glyph_decompose_cubic_to_func_t) _cubic_to_noop;
|
||||
funcs->open_path = (hb_ot_glyph_decompose_open_path_func_t) _open_close_path_noop;
|
||||
funcs->close_path = (hb_ot_glyph_decompose_close_path_func_t) _open_close_path_noop;
|
||||
return funcs;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ typedef void (*hb_ot_glyph_decompose_cubic_to_func_t) (hb_position_t control1_x,
|
||||
hb_position_t control2_x, hb_position_t control2_y,
|
||||
hb_position_t to_x, hb_position_t to_y,
|
||||
void *user_data);
|
||||
typedef void (*hb_ot_glyph_decompose_open_path_func_t) (void *user_data);
|
||||
typedef void (*hb_ot_glyph_decompose_close_path_func_t) (void *user_data);
|
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_t:
|
||||
@ -68,6 +70,14 @@ HB_EXTERN void
|
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (hb_ot_glyph_decompose_funcs_t *funcs,
|
||||
hb_ot_glyph_decompose_cubic_to_func_t cubic_to);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_glyph_decompose_funcs_set_open_path_func (hb_ot_glyph_decompose_funcs_t *funcs,
|
||||
hb_ot_glyph_decompose_open_path_func_t open_path);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (hb_ot_glyph_decompose_funcs_t *funcs,
|
||||
hb_ot_glyph_decompose_close_path_func_t close_path);
|
||||
|
||||
HB_EXTERN hb_ot_glyph_decompose_funcs_t *
|
||||
hb_ot_glyph_decompose_funcs_create (void);
|
||||
|
||||
|
@ -38,6 +38,8 @@ struct hb_ot_glyph_decompose_funcs_t
|
||||
hb_ot_glyph_decompose_line_to_func_t line_to;
|
||||
hb_ot_glyph_decompose_conic_to_func_t conic_to;
|
||||
hb_ot_glyph_decompose_cubic_to_func_t cubic_to;
|
||||
hb_ot_glyph_decompose_open_path_func_t open_path;
|
||||
hb_ot_glyph_decompose_close_path_func_t close_path;
|
||||
};
|
||||
|
||||
|
||||
|
@ -70,6 +70,12 @@ cubic_to (hb_position_t control1_x, hb_position_t control1_y,
|
||||
to_x, user_data.ascender - to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
close_path (user_data_t &user_data)
|
||||
{
|
||||
fprintf (user_data.f, "Z");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
|
@ -74,6 +74,18 @@ cubic_to (hb_position_t control1_x, hb_position_t control1_y,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
open_path (user_data_t *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
close_path (user_data_t *user_data)
|
||||
{
|
||||
if (!user_data->consumed) return; /* XXX: CFF tables are inserting an Z in the beginning, we should resolve it */
|
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed,
|
||||
user_data->size - user_data->consumed,
|
||||
"Z");
|
||||
}
|
||||
|
||||
static hb_ot_glyph_decompose_funcs_t *funcs;
|
||||
|
||||
static void
|
||||
@ -98,12 +110,12 @@ test_hb_ot_glyph_glyf (void)
|
||||
g_assert (!hb_ot_glyph_decompose (font, 4, funcs, &user_data));
|
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data));
|
||||
char expected[] = "M275,442L275,442Q232,442 198,420Q164,397 145,353Q126,309 126,245L126,245"
|
||||
"Q126,182 147,139Q167,95 204,73Q240,50 287,50L287,50Q330,50 367,70Q404,90 427,128L427,128L451,116"
|
||||
"Q431,54 384,21Q336,-13 266,-13L266,-13Q198,-13 148,18Q97,48 70,104Q43,160 43,236L43,236Q43,314 76,371"
|
||||
"Q108,427 160,457Q212,487 272,487L272,487Q316,487 354,470Q392,453 417,424Q442,395 448,358"
|
||||
"L448,358Q441,321 403,321L403,321Q378,321 367,334Q355,347 350,366L350,366L325,454L371,417"
|
||||
"Q346,430 321,436Q296,442 275,442";
|
||||
g_assert_cmpmem (str, strlen (str), expected, sizeof (expected) - 1);
|
||||
"Q126,182 147,139Q167,95 204,73Q240,50 287,50L287,50Q330,50 367,70"
|
||||
"Q404,90 427,128L427,128L451,116Q431,54 384,21Q336,-13 266,-13L266,-13Q198,-13 148,18"
|
||||
"Q97,48 70,104Q43,160 43,236L43,236Q43,314 76,371Q108,427 160,457Q212,487 272,487L272,487"
|
||||
"Q316,487 354,470Q392,453 417,424Q442,395 448,358L448,358Q441,321 403,321L403,321"
|
||||
"Q378,321 367,334Q355,347 350,366L350,366L325,454L371,417Q346,430 321,436Q296,442 275,442Z";
|
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1);
|
||||
|
||||
hb_variation_t var;
|
||||
var.tag = HB_TAG ('w','g','h','t');
|
||||
@ -117,13 +129,13 @@ test_hb_ot_glyph_glyf (void)
|
||||
.consumed = 0
|
||||
};
|
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data2));
|
||||
char expected2[] = "M323,448L323,448Q297,448 271,430Q244,412 227,371Q209,330 209,261L209,261Q209,204 226,166"
|
||||
"Q242,127 273,107Q303,86 344,86L344,86Q378,86 404,101Q430,115 451,137L451,137L488,103"
|
||||
"Q458,42 404,13Q350,-16 279,-16L279,-16Q211,-16 153,13Q95,41 60,99Q25,156 25,241L25,241"
|
||||
"Q25,323 62,382Q99,440 163,471Q226,501 303,501L303,501Q357,501 399,481"
|
||||
char expected2[] = "M323,448L323,448Q297,448 271,430Q244,412 227,371"
|
||||
"Q209,330 209,261L209,261Q209,204 226,166Q242,127 273,107Q303,86 344,86L344,86Q378,86 404,101"
|
||||
"Q430,115 451,137L451,137L488,103Q458,42 404,13Q350,-16 279,-16L279,-16Q211,-16 153,13Q95,41 60,99"
|
||||
"Q25,156 25,241L25,241Q25,323 62,382Q99,440 163,471Q226,501 303,501L303,501Q357,501 399,481"
|
||||
"Q440,460 464,426Q488,392 492,352L492,352Q475,297 420,297L420,297Q390,297 366,320"
|
||||
"Q342,342 339,401L339,401L333,469L411,427Q387,438 368,443Q348,448 323,448";
|
||||
g_assert_cmpmem (str2, strlen (str2), expected2, sizeof (expected2) - 1);
|
||||
"Q342,342 339,401L339,401L333,469L411,427Q387,438 368,443Q348,448 323,448Z";
|
||||
g_assert_cmpmem (str2, user_data2.consumed, expected2, sizeof (expected2) - 1);
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
@ -142,10 +154,10 @@ test_hb_ot_glyph_cff1 (void)
|
||||
.consumed = 0
|
||||
};
|
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data));
|
||||
char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367"
|
||||
"L369,267L172,267M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656"
|
||||
"M300,653L342,694L201,861L143,806";
|
||||
g_assert_cmpmem (str, strlen (str), expected, sizeof (expected) - 1);
|
||||
char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267"
|
||||
"L172,267ZM3,0L88,0L151,200L390,200L452,0L541,0L319,656"
|
||||
"L225,656ZM300,653L342,694L201,861L143,806";
|
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1);
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
@ -164,11 +176,12 @@ test_hb_ot_glyph_cff2 (void)
|
||||
.consumed = 0
|
||||
};
|
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data));
|
||||
char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366C357,341 370,321 403,321"
|
||||
"C428,321 443,333 448,358C435,432 361,487 272,487C153,487 43,393 43,236"
|
||||
"C43,83 129,-13 266,-13C360,-13 424,33 451,116L427,128C396,78 345,50 287,50"
|
||||
char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366"
|
||||
"C357,341 370,321 403,321C428,321 443,333 448,358"
|
||||
"C435,432 361,487 272,487C153,487 43,393 43,236C43,83 129,-13 266,-13"
|
||||
"C360,-13 424,33 451,116L427,128C396,78 345,50 287,50"
|
||||
"C193,50 126,119 126,245C126,373 188,442 275,442";
|
||||
g_assert_cmpmem (str, strlen (str), expected, sizeof (expected) - 1);
|
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1);
|
||||
|
||||
hb_variation_t var;
|
||||
var.tag = HB_TAG ('w','g','h','t');
|
||||
@ -186,7 +199,7 @@ test_hb_ot_glyph_cff2 (void)
|
||||
"C458,297 480,314 492,352C486,433 412,501 303,501C148,501 25,406 25,241"
|
||||
"C25,70 143,-16 279,-16C374,-16 447,22 488,103L451,137C423,107 390,86 344,86"
|
||||
"C262,86 209,148 209,261C209,398 271,448 323,448";
|
||||
g_assert_cmpmem (str2, strlen (str2), expected2, sizeof (expected2) - 1);
|
||||
g_assert_cmpmem (str2, user_data2.consumed, expected2, sizeof (expected2) - 1);
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
@ -199,6 +212,8 @@ main (int argc, char **argv)
|
||||
hb_ot_glyph_decompose_funcs_set_line_to_func (funcs, (hb_ot_glyph_decompose_line_to_func_t) line_to);
|
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func (funcs, (hb_ot_glyph_decompose_conic_to_func_t) conic_to);
|
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (funcs, (hb_ot_glyph_decompose_cubic_to_func_t) cubic_to);
|
||||
hb_ot_glyph_decompose_funcs_set_open_path_func (funcs, (hb_ot_glyph_decompose_open_path_func_t) open_path);
|
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (funcs, (hb_ot_glyph_decompose_close_path_func_t) close_path);
|
||||
|
||||
hb_test_init (&argc, &argv);
|
||||
hb_test_add (test_hb_ot_glyph_empty);
|
||||
|
Loading…
Reference in New Issue
Block a user