From 1f5a54c768159e1bcf1c772ab236737994f638aa Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 24 Feb 2020 13:18:24 +0330 Subject: [PATCH] [gvar] fix infinite loop introduced by 11f3fca The attempt on removing end_points had made the code unreadable and has intrdouced infinite, fixed by making the code clear what it tries to achieve. --- src/hb-ot-var-gvar-table.hh | 22 ++++++++++++++++------ test/api/fonts/TestGVAREight.ttf | Bin 0 -> 4692 bytes test/api/test-ot-metrics-tt-var.c | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 test/api/fonts/TestGVAREight.ttf diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh index d8ee504c7..b7d1b5e42 100644 --- a/src/hb-ot-var-gvar-table.hh +++ b/src/hb-ot-var-gvar-table.hh @@ -625,17 +625,27 @@ struct gvar deltas[pt_index].y += y_deltas[i] * scalar; } + /* find point before phantoms start which is an end point */ + unsigned all_contours_end = points.length ? points.length - 1 : 0; + while (all_contours_end > 0) + { + if (points[all_contours_end].is_end_point) break; + --all_contours_end; + } + /* infer deltas for unreferenced points */ - for (unsigned start_point = 0; start_point + 4 < points.length; ++start_point) + for (unsigned start_point = 0; start_point < all_contours_end; ++start_point) { /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ - unsigned unref_count = 0; unsigned end_point = start_point; - do + unsigned unref_count = 0; + for (; end_point <= all_contours_end; ++end_point) { - if (!deltas[end_point].flag) unref_count++; - end_point++; - } while (!points[end_point].is_end_point && end_point + 4 < points.length); + if (!deltas[end_point].flag) + unref_count++; + if (points[end_point].is_end_point) + break; + } unsigned j = start_point; if (unref_count == 0 || unref_count > end_point - start_point) diff --git a/test/api/fonts/TestGVAREight.ttf b/test/api/fonts/TestGVAREight.ttf new file mode 100644 index 0000000000000000000000000000000000000000..271dc4b587c10750f77f6a726e7d649f5759a42c GIT binary patch literal 4692 zcmcgvS!^4}8UAOvyQD74QYZ^lDRs574Fp(IjbEs-ik z#&+uhO9*X%^r0;fpnwXrN)VtfkQ6E6mlk=@OIpJZ?g0c%n;=&U1ZaXHXzB;owb<{U z*%c4lfZd1ga%R5&pMU=OuUYPrAfg~S?f z*7Km>T1+M9KiGJ<1+t%@jV^-G{6qaZbnODYYjL@7w&~aOebARchfb&RS@KgWk>P-D zU&_rT>0U7j{o|mUmy>5#=pOn5mBA+&MKE zQnx|BC-&~_&DD*19sU0& z@6^&d%XH$32~q&wn}}bWHt0`uLrj#*;MdUQzm{Jw&z1L<^{q`enzhP8h%Ro#RwLv< zR*w&LOG9nFZM)IZ#(MgC%uHWf2l_WeS~xe_kB~c-3sMJ#sT;fznxMz%m$XU0LmK)< zh72?jGW$kiI}LkaWO#IFn>#$vXPX_NokOwF{wgf0a5ev)i0H7*ZV}o!CSs#sV6lT@ zWXvzw9c|D9w9gNon%yUqG_(8m3jFp7IXTj%mJU56_~+{z9@sr7VA}m(6fihs`h!?8 zG8Ed`*(0=57cOjFyl_G6w>vxSt?zW&cBlBU%X?s;t80MU)*n z|AFhT)-jA&{N-sYa<#j+xBF_untnMh=^OV(EC7&Jq|9^W3az~*<^FT2x4%KxeLh`p z=YyREkw*vo@evYU6 zgSca~AE!4)2SDEsl%Pe*(K01z71RU`qCZX*Ks+Fnr`ZoJ-@1Bz}_jW5FH|*y# z==1Q}f(;oUj%*|e~#i1|fHD}QIfFG@L%eg^?ED^e@3%i&gW@hZG}9}89_p@a9oj~>7YK4696DO+~?y5e|y^}$h` zle=++=b(@6Q`N;$NlE=h%&CZ1V#7L?T`tG>w6tOht8>6ALu|)knJr`nKJ1QhJQtZxK!Qj2?Y;ahyo28A!WW0oAmyWd zdbYT<#4-YRK)!8+WPgaX$>WwKnn{~_6eHd`re-iUkvPo!7V^bUVhoa=n8MhK@0e!n zJ&gC}FC$yh22uGK5ZFV0c`zW7@6?J1N%_s8cs$9Lk&uE_a?k~C!$LnDy$3#L&%1-)U$1{ZbjFjwh+1Z|EAR;wn zEx|UL{7s0biTZ+EtQGJmZDrGg7{{xy2P?cykA+u1bvXg#317t&*g&_5=3bw(bUI}D zsB6RHU>qkpZ)r*v*t;AO2ckXV?k??<9oHP)|7qw`zoTEzdKgbj`--Kk_d-Oa;(P83x}Pb2K=OH zS{vH43E9es5=*@YwL+`H9+a>B>BfG@--4fYr)L){vJ#0HA zvP$&c8odXw#`yg;dcQ=yYt-vutE7ov1;pjik|RF;%n>aej_7D{#AhGhJ^jC|sqFb* DNO0q6 literal 0 HcmV?d00001 diff --git a/test/api/test-ot-metrics-tt-var.c b/test/api/test-ot-metrics-tt-var.c index 2305a95b0..cffdeb764 100644 --- a/test/api/test-ot-metrics-tt-var.c +++ b/test/api/test-ot-metrics-tt-var.c @@ -234,6 +234,23 @@ test_advance_tt_var_comp_v (void) hb_font_destroy (font); } +static void +test_advance_tt_var_gvar_infer (void) +{ + hb_face_t *face = hb_test_open_font_file ("fonts/TestGVAREight.ttf"); + hb_font_t *font = hb_font_create (face); + hb_ot_font_set_funcs (font); + hb_face_destroy (face); + + int coords[6] = {100}; + hb_font_set_var_coords_normalized (font, coords, 6); + + hb_glyph_extents_t extents = {0}; + g_assert (hb_font_get_glyph_extents (font, 4, &extents)); + + hb_font_destroy (font); +} + int main (int argc, char **argv) { @@ -245,6 +262,7 @@ main (int argc, char **argv) hb_test_add (test_advance_tt_var_anchor); hb_test_add (test_extents_tt_var_comp); hb_test_add (test_advance_tt_var_comp_v); + hb_test_add (test_advance_tt_var_gvar_infer); return hb_test_run (); }