From 21a181af2bf1582991c55de5f9281494733c5d12 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 10 Apr 2018 15:40:24 -0700 Subject: [PATCH] [subset] sketch out support for a call that lists all codepoints present in a font. Implement support for it in format 4 cmap sub table. --- src/hb-ot-cmap-table.hh | 37 ++++++++++- src/hb-subset.cc | 14 +++++ src/hb-subset.h | 5 +- test/api/Makefile.am | 2 + test/api/fonts/Roboto-Regular.abc.format4.ttf | Bin 0 -> 2424 bytes test/api/test-subset-codepoints.c | 59 ++++++++++++++++++ 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 test/api/fonts/Roboto-Regular.abc.format4.ttf create mode 100644 test/api/test-subset-codepoints.c diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index c2bfe4b5e..f94dc0687 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -127,6 +127,13 @@ struct CmapSubtableFormat4 return true; } + static inline void get_all_codepoints_func (const void *obj, hb_set_t *out) + { + const accelerator_t *thiz = (const accelerator_t *) obj; + for (unsigned int i = 0; i < thiz->segCount - 1; i++) // Skip the last segment (0xFFFF) + hb_set_add_range (out, thiz->startCount[i], thiz->endCount[i]); + } + const HBUINT16 *endCount; const HBUINT16 *startCount; const HBUINT16 *idDelta; @@ -667,20 +674,30 @@ struct cmap this->get_glyph_data = subtable; if (unlikely (symbol)) + { this->get_glyph_func = get_glyph_from_symbol; - else + this->get_all_codepoints_func = null_get_all_codepoints_func; + } else { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ - default: this->get_glyph_func = get_glyph_from; break; - case 12: this->get_glyph_func = get_glyph_from; break; + default: + this->get_glyph_func = get_glyph_from; + this->get_all_codepoints_func = null_get_all_codepoints_func; + break; + case 12: + this->get_glyph_func = get_glyph_from; + this->get_all_codepoints_func = null_get_all_codepoints_func; + break; case 4: { this->format4_accel.init (&subtable->u.format4); this->get_glyph_data = &this->format4_accel; this->get_glyph_func = this->format4_accel.get_glyph_func; + this->get_all_codepoints_func = this->format4_accel.get_all_codepoints_func; } break; } + } } inline void fini (void) @@ -710,10 +727,22 @@ struct cmap return get_nominal_glyph (unicode, glyph); } + inline void get_all_codepoints (hb_set_t *out) const + { + this->get_all_codepoints_func (get_glyph_data, out); + } + protected: typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); + typedef void (*hb_cmap_get_all_codepoints_func_t) (const void *obj, + hb_set_t *out); + + static inline void null_get_all_codepoints_func (const void *obj, hb_set_t *out) + { + // NOOP + } template static inline bool get_glyph_from (const void *obj, @@ -749,6 +778,8 @@ struct cmap private: hb_cmap_get_glyph_func_t get_glyph_func; const void *get_glyph_data; + hb_cmap_get_all_codepoints_func_t get_all_codepoints_func; + OT::CmapSubtableFormat4::accelerator_t format4_accel; const OT::CmapSubtableFormat14 *uvs_table; diff --git a/src/hb-subset.cc b/src/hb-subset.cc index b253817eb..5da46c797 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -371,3 +371,17 @@ hb_subset (hb_face_t *source, hb_subset_plan_destroy (plan); return result; } + +/** + * hb_subset_get_all_codepoints: + * @source: font face data to load. + * @out: set to add the all codepoints covered by font face, source. + */ +void +hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out) +{ + OT::cmap::accelerator_t cmap; + cmap.init (source); + cmap.get_all_codepoints (out); + cmap.fini(); +} diff --git a/src/hb-subset.h b/src/hb-subset.h index 55ce25b0a..409581c76 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -72,12 +72,15 @@ HB_EXTERN hb_bool_t * hb_subset_input_drop_hints (hb_subset_input_t *subset_input); /* hb_subset() */ - HB_EXTERN hb_face_t * hb_subset (hb_face_t *source, hb_subset_profile_t *profile, hb_subset_input_t *input); +/* hb_subset_get_all_codepoints */ +HB_EXTERN void +hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out); + HB_END_DECLS #endif /* HB_SUBSET_H */ diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 0f7c82f77..65ceeda3c 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -32,6 +32,7 @@ TEST_PROGS = \ test-set \ test-shape \ test-subset \ + test-subset-codepoints \ test-subset-cmap \ test-subset-glyf \ test-subset-hdmx \ @@ -44,6 +45,7 @@ TEST_PROGS = \ $(NULL) test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la +test_subset_codepoints_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la diff --git a/test/api/fonts/Roboto-Regular.abc.format4.ttf b/test/api/fonts/Roboto-Regular.abc.format4.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccb074a8e7566eefed943c575625b6f7345e25bd GIT binary patch literal 2424 zcmZuzeQaCR6+idAXXp8YBrOQWVytNlKriLSyWFmAG*e zr-W&R0&NMVrR(T4sf-VyX)6V-*9Mw|7AX>-X&}BfgqBGlA@N74iuOHKpxT`CoHP{e zS?}EYJNKO5{hfR5dkqW#oMolI68cx1A^39)cad3WiC(v36nsfVwcVFCH(*9rY(lh{X z|HE-3wV(d$($}yne_2w^1T7#?gAe8vP2}vza{zWhSW*q9!dSsdhDU<>l^mK0fGP)} z3W!dWj<8>V32QlJYC+1%LMwg@BQ(wGRFrl-dsk0S7la@RF*D=hyw9$M%|3X0l z2Y)xW^y(SLo{B86{9%4*ea0g0zBj;`UsXHC!<-ETxZvk(qc6ZkzuL*g>dro0i>PTe zeP=wacB*61IG3u876*pYkw%q6zdnw3K=<)b#Cxqf9Er3AxI{FVfzjy*66{$az}9dz zUJY=Qzgy*EO|QOP=Lf@H9tuaiKA+mbmwI)+6!!WekpMSe(}-FRjF%VG7Wuh(V}Q#A zhJKxgyc{CwH1YN8nvWk$r@d*cU==T2j~5vH&=LB+16QD9fgS8cDr_{LmmHc;^P$2> zIKVCb?tZ-kCHhdJ)z9lX0^H{3_1M_`nOZidru+595bjBAL58^jeG%%!i^+(WYbaKo zTTpP_R(w?D4SpV)TTo$8&(uTMy9o8-#W4Eq4ICOE%M_u3WgQIdyrZqD+N*%v0P}3? ztvC8y*qs;jtvA;hJ+bd6t<`1ZlkWX#d&4^FnS%Ze>q@9+-gi%DvzK~BCmz_Fw#VYz3UT)3Y&zCXz8hSM-D0L*aeH&^j~&!23ANU* zH*%HU+Y727>$DYN0fl|b-sWM`+1+FwCe!F)sca9KNixUDoF$VdQ|VzdlrcjYGn6rt zEvcYfGJhviS%Go8$s8y1A(=dx+bS@4l1!tDag%89CjlGbSvUx3n1xU9blC=j@Hh;? z-Owtu!v)B~Q-J3kxN<|_5}pB7^np!k1DA9R6#RX<%;iwZeg_Wo5)_-4jnjZw0e%L{ zEP$;5iTq{plC%vfpbmbXb=PlnIB(%@g{vO{hYp>)8@(B~XG_EY5(3G&0ssLZ$O>)= zld?9W;kHIh&y+B3ZP0yx_5LSHLo9bi8Z(ul4i4%@zMjSB?#C{rrzR@1vTJuAH>RuntDDPLG%5 zITbEq&2pnrsU3^6ua+$$5Le4KBQR6hCRwDit#)d-UCB7t%Hg7taj(IqP0S@|8)}O* zM~fqG7 zch&Uf2WN8rGaumji1&ne8Fy?wbZ3={N}Rl~Qwj=GRwc^_WK@}fH5FW@61k#q7uo9t z()zX(qeyUUURidn#@Gd1a$!sCq#OBPg(ci2i_z}v|VeJ~04;hVy@4~AhBW?%yE znknO^z~KBIx=;Vl!;n`70q=|wH2|L2 zgHsdW8J!xwA3PJ$)L!u5xrYz38u9lJPwmB73YiSYh>y{{_&cG