From 670768e5b9f24958f60a74f3d194b24333def446 Mon Sep 17 00:00:00 2001 From: blueshade7 Date: Fri, 12 Jul 2019 16:14:23 -0700 Subject: [PATCH] fix inc-bimap for subsetting VarStore with retain-gids --- src/hb-bimap.hh | 19 +++++++- src/hb-ot-layout-common.hh | 43 ++++++++---------- src/hb-ot-var-hvar-table.hh | 5 +- .../fonts/AdobeVFPrototype.ac.retaingids.otf | Bin 6416 -> 6412 bytes ...urceHanSans-Regular.41,4C2E.retaingids.otf | Bin 2656 -> 2736 bytes ...SourceSansVariable-Roman.ac.retaingids.ttf | Bin 2616 -> 2616 bytes ...SerifVariable-Roman-VVAR.ac.retaingids.ttf | Bin 5296 -> 5288 bytes 7 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/hb-bimap.hh b/src/hb-bimap.hh index cdea03b9a..e9f3a6a52 100644 --- a/src/hb-bimap.hh +++ b/src/hb-bimap.hh @@ -94,6 +94,14 @@ struct hb_bimap_t /* Inremental bimap: only lhs is given, rhs is incrementally assigned */ struct hb_inc_bimap_t : hb_bimap_t { + hb_inc_bimap_t () { init (); } + + void init () + { + hb_bimap_t::init (); + next_value = 0; + } + /* Add a mapping from lhs to rhs with a unique value if lhs is unknown. * Return the rhs value as the result. */ @@ -102,12 +110,18 @@ struct hb_inc_bimap_t : hb_bimap_t hb_codepoint_t rhs = forw_map[lhs]; if (rhs == HB_MAP_VALUE_INVALID) { - rhs = get_population (); + rhs = next_value++; set (lhs, rhs); } return rhs; } + hb_codepoint_t skip () + { return next_value++; } + + hb_codepoint_t get_next_value () const + { return next_value; } + void add_set (const hb_set_t *set) { hb_codepoint_t i = HB_SET_VALUE_INVALID; @@ -144,6 +158,9 @@ struct hb_inc_bimap_t : hb_bimap_t for (hb_codepoint_t rhs = 0; rhs < count; rhs++) set (work[rhs], rhs); } + + protected: + unsigned int next_value; }; #endif /* HB_BIMAP_HH */ diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 8cc64336e..52bf4f8ce 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1723,6 +1723,9 @@ struct VarData unsigned int get_region_index_count () const { return regionIndices.len; } + unsigned int get_row_size () const + { return shortCount + regionIndices.len; } + unsigned int get_size () const { return itemCount * get_row_size (); } @@ -1783,13 +1786,13 @@ struct VarData bool serialize (hb_serialize_context_t *c, const VarData *src, - const hb_bimap_t &inner_map, + const hb_inc_bimap_t &inner_map, const hb_bimap_t ®ion_map) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - itemCount = inner_map.get_population (); - + itemCount = inner_map.get_next_value (); + /* Optimize short count */ unsigned short ri_count = src->regionIndices.len; enum delta_size_t { kZero=0, kByte, kShort }; @@ -1802,7 +1805,7 @@ struct VarData for (r = 0; r < ri_count; r++) { delta_sz[r] = kZero; - for (unsigned int i = 0; i < inner_map.get_population (); i++) + for (unsigned int i = 0; i < inner_map.get_next_value (); i++) { unsigned int old = inner_map.backward (i); int16_t delta = src->get_item_delta (old, r); @@ -1838,8 +1841,7 @@ struct VarData for (unsigned int i = 0; i < itemCount; i++) { - hb_codepoint_t old = inner_map.backward (i); - if (unlikely (old >= src->itemCount)) return_trace (false); + unsigned int old = inner_map.backward (i); for (unsigned int r = 0; r < ri_count; r++) if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r)); } @@ -1847,13 +1849,13 @@ struct VarData return_trace (true); } - void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_bimap_t &inner_map) const + void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_inc_bimap_t &inner_map) const { for (unsigned int r = 0; r < regionIndices.len; r++) { unsigned int region = regionIndices[r]; if (region_map.has (region)) continue; - for (unsigned int i = 0; i < inner_map.get_population (); i++) + for (unsigned int i = 0; i < inner_map.get_next_value (); i++) if (get_item_delta (inner_map.backward (i), r) != 0) { region_map.add (region); @@ -1863,9 +1865,6 @@ struct VarData } protected: - unsigned int get_row_size () const - { return shortCount + regionIndices.len; } - const HBUINT8 *get_delta_bytes () const { return &StructAfter (regionIndices); } @@ -1874,7 +1873,7 @@ struct VarData int16_t get_item_delta (unsigned int item, unsigned int region) const { - if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0; + if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0; const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size (); if (region < shortCount) return ((const HBINT16 *)p)[region]; @@ -1940,20 +1939,20 @@ struct VariationStore bool serialize (hb_serialize_context_t *c, const VariationStore *src, - const hb_array_t &inner_remaps) + const hb_array_t &inner_maps) { TRACE_SERIALIZE (this); unsigned int set_count = 0; - for (unsigned int i = 0; i < inner_remaps.length; i++) - if (inner_remaps[i].get_population () > 0) set_count++; + for (unsigned int i = 0; i < inner_maps.length; i++) + if (inner_maps[i].get_population () > 0) set_count++; unsigned int size = min_size + HBUINT32::static_size * set_count; if (unlikely (!c->allocate_size (size))) return_trace (false); format = 1; hb_inc_bimap_t region_map; - for (unsigned int i = 0; i < inner_remaps.length; i++) - (src+src->dataSets[i]).collect_region_refs (region_map, inner_remaps[i]); + for (unsigned int i = 0; i < inner_maps.length; i++) + (src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]); region_map.sort (); if (unlikely (!regions.serialize (c, this) @@ -1964,14 +1963,14 @@ struct VariationStore */ dataSets.len = set_count; unsigned int set_index = 0; - for (unsigned int i = 0; i < inner_remaps.length; i++) + for (unsigned int i = 0; i < inner_maps.length; i++) { - if (inner_remaps[i].get_population () == 0) continue; + if (inner_maps[i].get_population () == 0) continue; if (unlikely (!dataSets[set_index++].serialize (c, this) - .serialize (c, &(src+src->dataSets[i]), inner_remaps[i], region_map))) + .serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map))) return_trace (false); } - + return_trace (true); } @@ -1993,8 +1992,6 @@ struct VariationStore &scalars[0], num_scalars); } - const VarRegionList &get_regions () const { return this+regions; } - unsigned int get_sub_table_count () const { return dataSets.len; } protected: diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index 0fb1523c0..c1935f7d0 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -290,7 +290,10 @@ struct hvarvvar_subset_plan_t if (retain_adv_map) { for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) - inner_maps[0].add (hb_set_has (inner_sets[0], gid)? gid: HB_MAP_VALUE_INVALID); + if (hb_set_has (inner_sets[0], gid)) + inner_maps[0].add (gid); + else + inner_maps[0].skip (); } else { diff --git a/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf b/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf index d9048ee6ec462a04b6cbac603da193da01cf5400..15419b04dc81a32dbcdf9456a60833710346c853 100644 GIT binary patch delta 250 zcmbPW)MGS3p`KCPZ6X5$`xgcVh7jK{$Dq}JS7b0SaCiXuP5#09M$zjk<^cI;fc%8u z5XX=ca!;l(FmUPs`L7bo5{r~_RjL^nxFmpljpW?K0){rGOF+H@ke`zVl)t2-l?UXn z0rFR5q$Z~D`IWc>?b`$7n`LCAPMpu-7y@LgWaO4quq839WMJT~0P+QL6DtZBSOS1d z?hYWqmY0~D`s;ba3m|_20|ReNL4I+`|BDPp3=9%)HomyS#v+|CLvr#7c5_CbNgRga c%s@R%42%p63V#_GR6#5jActwQ562M!09C|4TL1t6 delta 254 zcmeA%nqV|Rq25@@y^n!`{R;yFLzr)vW64`uIDCNoCjVf4qv&-NbAbE{Kz>4S zh-1hJxhGQ?7&r}p{8x!(iA74eD%A`OTrxnuMsjXq0Ye+pB_Q7g$j?aw%3spa$^-H@ z0QoC2QWI17{7T$`_U!@k%`!4lC(h?^i~zD#GIC2Q*pe7lGB9x00QmyBi4_G5ECE0! zcMp(Y%S+5n{q?-z1&|N4pEsr;zqsW8MFt}V28j{#=2mk=yvq4$_ diff --git a/test/api/fonts/SourceHanSans-Regular.41,4C2E.retaingids.otf b/test/api/fonts/SourceHanSans-Regular.41,4C2E.retaingids.otf index fa2a0e4469e99944f90be57b6e70da09eee8e138..906bdbefd595a64a682884a2ffd18b7592f7d530 100644 GIT binary patch delta 648 zcmYk3O=uHQ6ot=ylQ(~v7*eKolWK{hXoUu=7K#z1g;cRM+J;cNX$Kn;p=qPWHi8&M z5TrFKvvJ`Ecp*Zm7p6}c@ch1cF;681wWwO}} z99)5hBmL=g$M(7B-vBHD@=InU*`2#)?+5f%_9k+f;Q{R|D;R@(Gf$WN^4-*lcIGVe zR59;QTA%Z4ynm6or^tpAv)*w3HM3VNRjPIpH<&*$yCuImRE9js+W5scecCVO_w6~x z!%RjoTAn#yS-*~Mz#e6zW0nV6m)kt%Dzi7s1H;eog83e^duOSbJP_qP;;^$*l~azV z%KaE@0phRvi0}A`b&6Apa#W?D;nN%i<6>(qcif-$K}3fBu;;;{Fp!Xsy;pzg8YB+~ zX%GS$ArxXm5=Gnh_722p!PynZHhzt4Yl+j%O*+U_SLCYR2-7V^DwixU-QMgiw?GPq z^9eqQh$xCPjiXvY1W)A4#P9mNdLTWoFWc|J3r=k9lB>d~MfzgjkE@NUzJqE~`-(|1 z&d10X>x8NR|J#4zVPK4V6tdWS&uc>yx|lY!z!uV*TEif@O&$7gk3@wgn!b)sT0uW% wP{zd|WxWjyt1B{$JPNpgDfl=SJTixZUb7NJ&CVcV_qD2&DqWzmaow%zU&gX^bpQYW delta 605 zcmYk3%WD%+6vn@E=aJ5Inlz=-P1?pZ7O9Vc6bfn=QlYwNjWi`xUDzQVI*W`GYpemm z2!f#aKxX4Yve52SsHBTR!0M)}`~h7Sf*@UX6LC||l_@wd_kO=~?ws?Txtk~U2kZI8 z#XKxLfr86dW@po%c4jO9Z9r?}3wEyf)SLwL4UR1r^9xs%d#n&sdFd(nPUYS7^c=3~F#_Sfl-_mBh@Z)Rq zg|Z~Vj@F9HmhvUN5gho<@A??kRpl2}#2vmLepqJ!p7ozS#Bht_q#B&sqwz=+&f|Ba z1>!h}w1PP_BCY;+Mne@7QCw#Q6cFG6)=+{QUNlF;mQf7@W3F!jE><~HhJ&>*XV~HG Sp1ts$dwFfe$8IR-gw6x3&AWZ3M;=+DgfZSzEy<*WdW5eQZQ delta 40 ucmdlXvO`3WfsuiMK>$dwFfe$8IR<5I6x3&A)Y|OG=+Df!X!Ast<*WdZSqN4D diff --git a/test/api/fonts/SourceSerifVariable-Roman-VVAR.ac.retaingids.ttf b/test/api/fonts/SourceSerifVariable-Roman-VVAR.ac.retaingids.ttf index e0999884a0adb7264fe211c2c417a6d16da31a15..734f6e82a6488c5f7c85ecf12f3972ea28aac5a0 100644 GIT binary patch delta 472 zcmXw#%}WAN6vgiwM=>R}l3EoKqaa0wi)vw%3u_1@NU=f!C-Z}t$w5UlB3o2gOM__9 zrd>ru=*Fe%kic@^##O8Sfv7VB&12r2-??Y*eY_X%y|+q?h(@sSG%Ln}8*Fr?Lc{`a z#W1*VsW!l;;J|vs=idoeP-AUyA`%ToPx|$7BF+VF#E^IS1P{0ePD&*yKdA_ZM1}>h zC#gs(opbNt1Xxa&q-wr)_Vxv%10#`fjdgb6FUsO}0p67QsSRDV9yU^Z=H@4mp>USco2xe*#++sjSifg-|~NyAGr^C3W|D z{Q={a$l6kKh2n3Q{6x;E7ARqWdEbr`JBwhUgaOtTzY4wqJM`NFKrdg3%spm+;xyOw zL*&*J58#?L7H3-#6#t*N{;LCFWbsacxi+;S(F=>TR*cvX*>tG|nT1)oK_0f=Rr~Tr TGBuYB7aVUHmbaT7W8d}%dO%sv delta 480 zcmXw$JuE{}9L3MQeXUa3if&RVDTzdo5?zpzG(Hj`NDV&Hr&=X_G&D~uf}y00BxVu= z1`#!M>|hXs#K&N>bTSz&!f6xl<-K=)=YQ`1e{nUh+FRqU!2egXZ1@ z3_fyGNK@n3moMZfITq2?owdx~(5JtF6s?~2keO^F`BJVtg$wM5c1k4tibY>%ymRN==J^LOM5O-;s84nON@vTH>h z*1~6xC$BWl0ZT5vx}Nxbh6ixW6azX3n3rwbv15zu);YkEQwGSVWP9oK2-N+@gQBrk zp^`<{^#e4@b|bYSV30sIEvCgxfPw#OuC(0F1