From 1bc710a8c94fbe08ca3a3e535c7b6597a57883df Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Fri, 2 Nov 2018 15:28:01 -0700 Subject: [PATCH] added CFF1 desubr api test cases & bug fixes --- src/hb-cff1-interp-cs.hh | 7 - src/hb-ot-cff-common.hh | 56 +++++--- src/hb-subset-cff-common.hh | 100 +++++++------- src/hb-subset-cff1.cc | 53 +++----- .../SourceHanSans-Regular.41,3041,4C2E.otf | Bin 3892 -> 2576 bytes .../SourceHanSans-Regular.41,4C2E.nohints.otf | Bin 0 -> 2380 bytes ...anSans-Regular.41,4C2E.nosubrs.nohints.otf | Bin 0 -> 2360 bytes .../SourceHanSans-Regular.41,4C2E.nosubrs.otf | Bin 0 -> 2548 bytes .../fonts/SourceHanSans-Regular.41,4C2E.otf | Bin 2548 -> 2576 bytes test/api/fonts/SourceSansPro-Regular.abc.otf | Bin 3412 -> 1812 bytes .../SourceSansPro-Regular.ac.nohints.otf | Bin 3228 -> 1592 bytes ...urceSansPro-Regular.ac.nosubrs.nohints.otf | Bin 0 -> 1540 bytes .../SourceSansPro-Regular.ac.nosubrs.otf | Bin 0 -> 1632 bytes test/api/fonts/SourceSansPro-Regular.ac.otf | Bin 3332 -> 1708 bytes test/api/test-subset-cff1.c | 122 ++++++++++++++++++ 15 files changed, 232 insertions(+), 106 deletions(-) create mode 100644 test/api/fonts/SourceHanSans-Regular.41,4C2E.nohints.otf create mode 100644 test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.nohints.otf create mode 100644 test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.otf create mode 100644 test/api/fonts/SourceSansPro-Regular.ac.nosubrs.nohints.otf create mode 100644 test/api/fonts/SourceSansPro-Regular.ac.nosubrs.otf diff --git a/src/hb-cff1-interp-cs.hh b/src/hb-cff1-interp-cs.hh index ec8a7faed..0d267ac33 100644 --- a/src/hb-cff1-interp-cs.hh +++ b/src/hb-cff1-interp-cs.hh @@ -111,16 +111,9 @@ struct CFF1CSOpSet : CSOpSet break; } env.set_width (has_width); - if (has_width) - { - OPSET::process_width (env, param); - } } } - static inline void process_width (CFF1CSInterpEnv &env, PARAM& param) - {} - static inline void flush_args (CFF1CSInterpEnv &env, PARAM& param) { SUPER::flush_args (env, param); diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 40ae9578c..2f5e2f86d 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -93,7 +93,12 @@ struct CFFIndex { return calculate_offset_array_size (offSize, count); } inline static unsigned int calculate_serialized_size (unsigned int offSize, unsigned int count, unsigned int dataSize) - { return min_size + calculate_offset_array_size (offSize, count) + dataSize; } + { + if (count == 0) + return COUNT::static_size; + else + return min_size + calculate_offset_array_size (offSize, count) + dataSize; + } inline bool serialize (hb_serialize_context_t *c, const CFFIndex &src) { @@ -110,30 +115,39 @@ struct CFFIndex const ByteStrArray &byteArray) { TRACE_SERIALIZE (this); - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (*this))) return_trace (false); - this->count.set (byteArray.len); - this->offSize.set (offSize_); - if (!unlikely (c->allocate_size (offSize_ * (byteArray.len + 1)))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - unsigned int i = 0; - for (; i < byteArray.len; i++) + if (byteArray.len == 0) { - set_offset_at (i, offset); - offset += byteArray[i].get_size (); + COUNT *dest = c->allocate_min (); + if (unlikely (dest == nullptr)) return_trace (false); + dest->set (0); } - set_offset_at (i, offset); - - /* serialize data */ - for (unsigned int i = 0; i < byteArray.len; i++) + else { - ByteStr *dest = c->start_embed (); - if (unlikely (dest == nullptr || - !dest->serialize (c, byteArray[i]))) + /* serialize CFFIndex header */ + if (unlikely (!c->extend_min (*this))) return_trace (false); + this->count.set (byteArray.len); + this->offSize.set (offSize_); + if (!unlikely (c->allocate_size (offSize_ * (byteArray.len + 1)))) return_trace (false); + + /* serialize indices */ + unsigned int offset = 1; + unsigned int i = 0; + for (; i < byteArray.len; i++) + { + set_offset_at (i, offset); + offset += byteArray[i].get_size (); + } + set_offset_at (i, offset); + + /* serialize data */ + for (unsigned int i = 0; i < byteArray.len; i++) + { + ByteStr *dest = c->start_embed (); + if (unlikely (dest == nullptr || + !dest->serialize (c, byteArray[i]))) + return_trace (false); + } } return_trace (true); } diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh index 944d5e901..edee147b1 100644 --- a/src/hb-subset-cff-common.hh +++ b/src/hb-subset-cff-common.hh @@ -378,8 +378,10 @@ struct ParsedCSOp : OpStr inline void init (unsigned int subr_num_ = 0) { OpStr::init (); - flags = kDropFlag_None; subr_num = subr_num_; + drop_flag = false; + keep_flag = false; + skip_flag = false; } inline void fini (void) @@ -387,20 +389,19 @@ struct ParsedCSOp : OpStr OpStr::fini (); } - inline bool for_keep (void) const { return (flags & kDropFlag_Keep) != 0; } - inline bool for_drop (void) const { return (flags & kDropFlag_Drop) != 0; } - inline void set_drop (void) { if (!for_keep ()) flags |= kDropFlag_Drop; } - inline void set_keep (void) { flags |= kDropFlag_Keep; } + inline bool for_drop (void) const { return drop_flag; } + inline void set_drop (void) { if (!for_keep ()) drop_flag = true; } + inline bool for_keep (void) const { return keep_flag; } + inline void set_keep (void) { keep_flag = true; } + inline bool for_skip (void) const { return skip_flag; } + inline void set_skip (void) { skip_flag = true; } - enum DropFlag - { - kDropFlag_None = 0, - kDropFlag_Drop = 1, - kDropFlag_Keep = 2 - }; - - unsigned int flags; unsigned int subr_num; + + protected: + bool drop_flag : 1; + bool keep_flag : 1; + bool skip_flag : 1; }; struct ParsedCStr : ParsedValues @@ -425,7 +426,7 @@ struct ParsedCStr : ParsedValues { unsigned int parsed_len = get_count (); if (likely (parsed_len > 0)) - values[parsed_len-1].set_drop (); + values[parsed_len-1].set_skip (); ParsedCSOp val; val.init (subr_num); @@ -629,8 +630,8 @@ struct SubrSubsetter * 4. re-encode all charstrings and subroutines with new subroutine numbers * * Phases #1 and #2 are done at the same time in collect_subrs (). - * Phase #3 requires walking charstrings/subroutines forward then backward (hence parsing), because - * we can't tell if a number belongs to a hint op until we see the first moveto. + * Phase #3 walks charstrings/subroutines forward then backward (hence parsing required), + * because we can't tell if a number belongs to a hint op until we see the first moveto. * * Assumption: a callsubr/callgsubr operator must immediately follow a (biased) subroutine number * within the same charstring/subroutine, e.g., not split across a charstring and a subroutine. @@ -686,7 +687,8 @@ struct SubrSubsetter drop_hints); bool seen_moveto = false; - if (drop_hints_in_str (parsed_charstrings[i], param, seen_moveto)) + bool ends_in_hint = false; + if (drop_hints_in_str (parsed_charstrings[i], param, seen_moveto, ends_in_hint)) parsed_charstrings[i].set_hint_removed (); } @@ -755,39 +757,39 @@ struct SubrSubsetter ParsedCStrs &subrs, unsigned int subr_num, const SubrSubsetParam ¶m, bool &seen_moveto) { - if (drop_hints_in_str (subrs[subr_num], param, seen_moveto)) - { - /* if the first op in the subr is a hint op, then all args/ops (especially including other subr calls) - * preceding this subr no and call op are hints */ - /* TODO CFF2 vsindex */ - for (unsigned int i = 0; i + 1 < pos; i++) - str.values[i].set_drop (); - return true; - } - else - return false; + bool ends_in_hint = false; + bool has_hint = drop_hints_in_str (subrs[subr_num], param, seen_moveto, ends_in_hint); + + /* if this subr ends with a stem hint (i.e., not a number a potential argument for moveto), + * then this entire subroutine must be a hint. drop its call. */ + if (ends_in_hint) + str.values[pos].set_drop (); + + return has_hint; } - /* returns true if it sees a hint op before moveto */ - inline bool drop_hints_in_str (ParsedCStr &str, const SubrSubsetParam ¶m, bool &seen_moveto) + /* returns true if it sees a hint op before the first moveto */ + inline bool drop_hints_in_str (ParsedCStr &str, const SubrSubsetParam ¶m, + bool &seen_moveto, bool &ends_in_hint) { bool seen_hint = false; - unsigned int next_check_pos = 0; for (unsigned int pos = 0; pos < str.values.len; pos++) { + bool has_hint = false; switch (str.values[pos].op) { case OpCode_callsubr: - seen_hint |= drop_hints_in_subr (str, pos, - *param.parsed_local_subrs, str.values[pos].subr_num, - param, seen_moveto); + has_hint = drop_hints_in_subr (str, pos, + *param.parsed_local_subrs, str.values[pos].subr_num, + param, seen_moveto); + break; case OpCode_callgsubr: - seen_hint |= drop_hints_in_subr (str, pos, - *param.parsed_global_subrs, str.values[pos].subr_num, - param, seen_moveto); + has_hint = drop_hints_in_subr (str, pos, + *param.parsed_global_subrs, str.values[pos].subr_num, + param, seen_moveto); break; case OpCode_rmoveto: @@ -809,19 +811,27 @@ struct SubrSubsetter case OpCode_vstemhm: case OpCode_hstem: case OpCode_vstem: - seen_hint = true; - for (unsigned int i = next_check_pos; i <= pos; i++) - { - /* TODO: CFF2 vsindex */ - str.values[i].set_drop (); - } - next_check_pos = pos + 1; + has_hint = true; + str.values[pos].set_drop (); + if ((pos + 1 >= str.values.len) /* CFF2 */ + || (str.values[pos + 1].op == OpCode_return)) + ends_in_hint = true; break; default: /* NONE */ break; } + if (has_hint) + { + for (int i = pos - 1; i >= 0; i--) + { + if (str.values[i].for_drop ()) + break; + str.values[i].set_drop (); + } + seen_hint |= has_hint; + } } return seen_hint; @@ -878,7 +888,7 @@ struct SubrSubsetter for (unsigned int i = 0; i < str.get_count(); i++) { const ParsedCSOp &opstr = str.values[i]; - if (!opstr.for_drop ()) + if (!opstr.for_drop () && !opstr.for_skip ()) { switch (opstr.op) { diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 414642f3f..216d09535 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -380,11 +380,6 @@ struct CFF1CSOpSet_SubrSubset : CFF1CSOpSet 0) + { + offsets.localSubrsInfos[fd].offset = final_size; + offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize); + offsets.localSubrsInfos[fd].size = CFF1Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].len, dataSize); + } } } } @@ -779,8 +779,11 @@ struct cff_subset_plan { fontdicts_mod.push (fontdict_mod); final_size += privInfo.size; - if (!plan->desubroutinize) + if (!plan->desubroutinize && (offsets.localSubrsInfos[i].size > 0)) + { + offsets.localSubrsInfos[i].offset = final_size; final_size += offsets.localSubrsInfos[i].size; + } } } @@ -900,21 +903,12 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, assert (plan.offsets.globalSubrsInfo.offset != 0); assert (plan.offsets.globalSubrsInfo.offset == c.head - c.start); - if (plan.desubroutinize) + CFF1Subrs *dest = c.start_embed (); + if (unlikely (dest == nullptr)) return false; + if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs))) { - CFF1Subrs *dest = c.allocate_size (HBUINT16::static_size); - if (unlikely (dest == nullptr)) return false; - dest->count.set (0); - } - else - { - CFF1Subrs *dest = c.start_embed (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines"); - return false; - } + DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines"); + return false; } } @@ -1010,7 +1004,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, assert (plan.offsets.privateDictInfo.offset == c.head - c.start); for (unsigned int i = 0; i < acc.privateDicts.len; i++) { - if (!plan.fdmap.excludes (i)) + if (plan.fdmap.includes (i)) { PrivateDict *pd = c.start_embed (); if (unlikely (pd == nullptr)) return false; @@ -1024,14 +1018,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i); return false; } - } - } - - if (!plan.desubroutinize) - { - for (unsigned int i = 0; i < acc.privateDicts.len; i++) - { - if (!plan.fdmap.excludes (i)) + if (plan.offsets.localSubrsInfos[i].size > 0) { CFF1Subrs *dest = c.start_embed (); if (unlikely (dest == nullptr)) return false; diff --git a/test/api/fonts/SourceHanSans-Regular.41,3041,4C2E.otf b/test/api/fonts/SourceHanSans-Regular.41,3041,4C2E.otf index 08bc0e03aecfaf4842e3dc6ee539320808d26904..b4d1165c7321308d35bf724581476491a86fb749 100644 GIT binary patch delta 686 zcmX|<&uddb5XZl}@Ac)q*JnaQTLoW25~6LeG`31FMrcr43#BP0gep=SO-KUyWep`F znu0|et5VpDXFaF~4<#a=Y6})}5JV9C161h6gI)p(#@Sk2nElRYW_D*-_LX7@ht%wi{g*^cK?V_E-IwHko1*MGlK<8le3SaOOZFJ~lgw2Zv z`*9$eE?>z^r8A{!zIucD^ow_S(1IT z$&>X`P13Va<>Nvll@mm#hdUkOJ?(5YKkZdhfPRo%vQ{om7Tq_xZ+iHjQJhF!{j&vh nzY)icL%qr_()=8X93h0yp1P1>CB(WccFurkaoaixF<=cS*2oSqXwd9DEP^ldQ-ST^&#$Oj1_4HeTvs_hNtMd zgLq+Dn!%zM`gvW&07^6{(=v1O1@WW-@l?dVnfiPaa8{xU4{>mf`b@)uIdKW-$AZX2 zQ&vu{y9^>QK?V8)^Du)~@$^7|DZYr6c^Hq~Oq3#KBgQH)76(fQHVFhlOw-nmNW?2# zGS>{7Q0|&Zxa6cu!E#9`9x>-_*M%vr%fi_+G4U;-(lz1-0^9{$Y}ZW~1vfE+SW4)K ze1eKj$=Ym)OEDO8x8@d5n}|o$MpDaOt~ctbMl#r<&Dw5GHpJ?UTD>tRY?UE(dxqW| zrepj}6+CY9!Xrz(0fIRvl;6CtvzQXGNEVPJu&`D(8aPa95`=_=mBX$Q1qp%$w3hA) z6x0sTojo_c(_HhX)&2C00c{UGG${VlwU)jgP=D&ezAl-ij=L>t!}7#Le#uv5U00;B zB>{0%%zlkLJK0c}DKq9bwhs1<40kB#a(ZzRv@2dK^vZ%74GOr?sU$wKq zwo{g2d8gKyrKnMHD!v>jZ<94P+NuvI%2O*+DmU}Th_!QPjd7*RIx~9CTs-*2dAXy| zS>z}lI3(HARC>7d$Y5XJuNP=8e|SgxYPED$*t=sPh4M2iIP|*KVVa;x>4W&2K`nAe zJ=N^k%NJ?8PxorO>C~>G-aQ@8V+Sv#b+@%IWT{BYy#c!UYJYEhuRndOpZ2}B=JLiq z`s5Gdht?;Bt`kVREW5%(yJWYmL?*svP2N;moTR8ZZf~(4ec&9eyHj7)FA?9gMi#tf zonOuuKd{;l**~>6*6ep2u-Cm;BSGp_#qv@uXFYdIoYQGi)WmVbzgsI>`zlY!EcFex z>PCk4mdY*spu{L;s8rRFe(7vy!{_JZ4y5d`e1Aw%+O+4hvcuPVzP;1&7ytT>Q)_h6 zH)N`FrHDfB2(u5EJG@t^sOJr6Jy*0(B<%9ZYs8|UO|N?n&A z$JE(|G^6JMXo?$$T2+a zJgL7c=%u>I-xVwjX=1E8f7dKwNE@SW^LHsuKbG`{~#9n7Q70I3J%eoIK(>{7%Gydq>{Mv z36gSh7qn;c5=jdH^A59cFn0x`Cm>=XDRCBfFdM>g=Ho-+93395p67N?XzokbyW597 zd(enK&%FeZR;8g*u1+;E(k!NgL}!>ZNu5U@PUP;r+)1a-q}s>Kse0QK+`cpt>5 z6JTy~fjI*frY(nP)KPg6?(F z@*jseHv*SVLVCK!^kSSj(?RC@!d&%CYq1+F6OQ}1j)L0|3de!)1>*4wJh$HGpG|wd L-rEEe?dA73_5Dre diff --git a/test/api/fonts/SourceHanSans-Regular.41,4C2E.nohints.otf b/test/api/fonts/SourceHanSans-Regular.41,4C2E.nohints.otf new file mode 100644 index 0000000000000000000000000000000000000000..e0548264ffcd121f2ebd23f9ec1a4c8ea8159d1d GIT binary patch literal 2380 zcma)8Z%`9w8h_qwvRNbp)H50-!VW_#wi*PL>8ZUF|CT$?Sb|pDj&(^E5+K>Q*$`qQ zAb$iYL5LEO6BV%kPAXcvdTrkze_>`eRN&U#B-H21t4Xg$Zd zxi|B^&;Q^1ywCgWZk$zBPOv~LFtB;+jvf51-;8YmfWH73lTKH0>Av;_YXMB>Pu0O*hylf?MANnh?qT&#F(Ar5_rr}CD%HwD&>MQVeUB_*trVXW z5E|%>n%VKPv5lDk1%)3n*u*%90Sp9LhLG&#PuNMXi%uHFe*vINKA860KuhxB7z@9xneDUn)?h#vSI9hi^ z=Co|K^^!6X9^c<+I~yGiCmT6!$+K$x^P1~`>e{PC_RXAQHOC9qH^XmvFUZ#>Y>`XV z6LlB3yOrCmx2Mf@J+<96dB0LetkVS>ShZpCh99O`ZNyl{_Fe6roLDx^s@1cPS=+k1 zT94KB^w#EG9`5>m$7tK=(&=H7`sHnF#4FX;1-Z6AbWC*W`)oQ_Eaz zuMqc~tl=~x`-%CD{?|^8ovL};cA&`-d#YogIT4MwT#jEod1ZimR$I7VUAWa;+v)2H z9Pd1He5mt`FJ?NwWc(;rI&<1Ji|Ihhz4 zxHZz()^{x47VotsVu{ASBixNQdryt#j}9h=t}Of7{KdHw?`}M5`b5nzC#nXY8*+1Q z>7a5jdb)L39%#9KerojEYuthH%hFr9gQt5>Ci1;)jqR@7*(EIBl>B49`p!RRY+AlK z`TEf0nTefATW5Xqp%x!4|Ex{TF~_tVL0kH$219MnJ*&lkJZvgN za`&+5TlOFi?dW@gZwgEE6Xm>vxC zSJDqAe7*D-_M_^zX-W=4DcO$NOf=08!p(C?%eQTD!e%Jnlrfgn;h)pw;mhUev2p0D#{I{jml!JV&!L z(vQL4aHe?z4wTZo0kQ}?$1|{tESlqu_xYGWA&2JlEIdv=hpiw%5TYQ14{E^+3h?j- z&Qe$dC9n=w{lu?Ft{gn*UkxJiE{qDHzX*P$JXAmc+-Q{%kFJ7l^Pr_j$5l|j0gCY# z(SHu~m`8Kyk$$wT)OUJ{pG+T;WixCZ|kspvsFn$gG*1<+R@iy23PUP-KOykX?t$rXr9p%Kh z?XVB`k?{mRJ!>9o`ZM+(#QblK7rhj{76Cl(yv+em;(ctyvkFj;c+{r`aT*Y{8Z8c3 ykFyNcV#aHb{{NY#dka$S^nb=f2FU^P!#(V7+OKz?$9_#e&p*2o{b@c0MgIYv(|7a$ literal 0 HcmV?d00001 diff --git a/test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.nohints.otf b/test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.nohints.otf new file mode 100644 index 0000000000000000000000000000000000000000..00a112fd90f531731b89588e5cb6a1297e448389 GIT binary patch literal 2360 zcma)8Z)_7s7JuWl*Bh{s6k#x6l2w$J&;us~h+3d0!rw+kn8qoE7SU|%P3$DzHS2X8 zQY{2(s zowOW6r<>Kxd%ySI{N~NunYGtL5C%!K}1%N*Qm^<8_;?n&c3)TZz zdeBzA-(9(zIf5EkZsEXrgFLx>Cg zLA7~7F`Pu)hS(MqnnS?QP&PpaNeGJTR##M^dIrFBAS8#?^a&`%rM^Kw--LWwElYWT zEF0p&Cgd}}3`K}b5OV~~W*~$t@yHRyD?Tkq9zhDPtrY7bjeNnUxymggkh z#7TNgPI8iQl1{V!xQ)5ja&KZKz`_s?)?7{reOd zYo!KcNod4(4h4lDGI(~e5fhjQsth4HD}UxB3EN{%u;9BfM;19rk|Ktpqlo$_VktVd z2pIa_Oz@;>W47keZrUd`^J`y>|K-x(mYrh9%Pwtx{fVo(*>Ow1Y5xbSCx19%DMWGi zh~;bcQ%$vKud>;9w#`i0_4x0!XFt%NeP65puz)>xVdT|wV|zy(ZIM|0QH9fU*tW~+ zL}dIxljB@$Br?>*=}Vv28eY^r2Q|-gdUXHHc~*BFvcDC1+ka8HKH-R7u9>L6$la~n zX}>*ft?#Ytsm=SjHfo25n--Q?**o2VuovP(@ zGyAdi&Hgt|Upig;YsbN6SNy5YftFM(*?J{;?bOu)?su+!e$FIn5uNXX&IF-uxw>NcoR?IGC`R1YD!Lny8cG9R+KlhnAObV z<6jTuA5XRgkHaSHzk}uf+4;xpsZ(_4m2#JMqQ;w&O7K z-Qpi|?05|6Q6y~j-#_@|rJOCdfnn&k68?BOw{Kp~F41o-3|Vs#GkEYajbZ*o`oV&q zl3vpRG(D4%+yooHQ%uK7l|c@1Uxj%{w(3gvrTOeo!hN4ke>t#%PB4Kd}LK1aa= zOY>qv)MnfkdSmcD7}-*}0Pzkm({Cxp;#U;&LdJ9&u_4nR-T2IiMg#s{&_-ivqdO>{ z>$u7uSEi#Kk-6vINBBv7cXmm-Vqxe<1`IbEt&Y$1l2N4s0Q@a5?lM^61)7~X3#0yw zJ);wFA3!LG-OQR*YgcD$e4e68Xc}6==edvh6~4$;fjrG6d1e!z#>1h6qM^5wF4>-;a5C z8Y3l)^B9t5OL^;XMk8932hcj4UxLpD*o-^g0o%Zh+Wm|fzInE_56sWZa^t+6upie^ za0dY+YaVO*6Zbyk{BMgNqg10767F~2=Yl8jeQd_P3ebRjG^Q4L8j-aIJucXYy$sf4 t#w95K|4cJy3(_6*KgB~D$p!NLJv`m?yxx5g&uivB{}f7$+k6^|{sYyzeD44N literal 0 HcmV?d00001 diff --git a/test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.otf b/test/api/fonts/SourceHanSans-Regular.41,4C2E.nosubrs.otf new file mode 100644 index 0000000000000000000000000000000000000000..6fe9bf302087c07fa43c17b312990d801f4b5069 GIT binary patch literal 2548 zcma)8eNaQpntzlS6O2)Bgeh`~g7zx=x>(w!1ETJph@Fwu8HM z`P-$3Py=!p2g+zOIJ!6Qibp(xxXfZUn8Lm_KR~QRoMAzOa#7eV0EHTHvc<+#gr`C? z;?0PaHbaF2q{W?)6nI~t-zL$tOk6Es94p&^mN~0NFPa`?oR<4{I&9aCF+*b?K|caRZ%YVhYW)-s9xVHYc5H zH!`e)VGW$wM5kCd&ap8ywYIeHhCi(V00 z>k2I$QfRA_HqabvFqv%zwv=Xy{@3fQcAB%8={N0G@#T6BbHM3#Q!2yK40>4F$hhnr zYc)Hy^ZZy7xWu@MrG5U5HCB5L_78lp}4vIY`xZ)9J`XbA6P6hPz?(TnJl zFOLDKxNj23kqkthb@SX`__@ClzS$q7yq=#>jq`L6&yL22im>D-sM8~NBV#oL8J=iiku8Jk{XrXeF zf8z_`jnDa#8%bo(nclNK1H1avH7-xdVU`l2$eLkp#5J_Xt?u#ky1Lwyu;eYibf2K# z%j@41%6HG6CSzA!m=d(_s4loZvGlW-N7UuRg(D^X)WiI3s{1pFl9uA8qJ-D^KGjUp zMv^aEyz%E5Qs|RqkiJW8qa({^NWO6HWmRocW6jZ$mbT)A^SzDl*ALVVES>3<^LOv7 z$}LQ3iGzxb2CDWq^`i~r6#uIUGByVCgxAQ%(dM!7WqPvB;58jDq68Tkn-0^r73bPN zIx%>n=u`FH3T@?U^&M4ykGJ}~_tNo;9n@Pw%pN{wtD?BU+Gs!4aOzlh!zpW}x{K>% zIuB*msQX6yulHOp>{D0k9lD09y7%gj*0!`)`W@bCszuS|@9X%f&sXa^>aF#*sr{9H zx9>1DaiQ(RK;l5Bzx(2{ZxmmhZvJf35&3OCOyMu+e7oC7#ZJExZDjUy`#mRXdfATZ zu`}ZXmp`KR4xMK{iSInwcHEz6sdd-sf(X4OKXqU+=C(NiPayVMP( zRR^oB;+Dith0EsDe6*rch&BjIUlO3Z_Kd6Z$hY5L&Ghil!Vzhl9vq) zeb<$E)LZ4PZug&VANGwL={Ve3eTph*YH(G?dn)?QS0-M)bb0*4ek*D9XboK|uy zd@N$@A4(wn+A%>DM7i?1waB8(JgKwa^G^K|`69y+sF^khN1Qbp)F5sx}ds2epJk z43Q*CzCu9*Ddr`0h_>KO7jL@;H8ERJhNH{|nfM*RSo{KDUdR{-AP&mF&9N_o(P+SL zo!G=!v570ln(xTBQyc1NMACzLYB5yIyC_@YT3|fct*W!~7n{dV1umyCeJ2+S9nRYZyYW3NuD}}1n#P(w;m$+O|F&2#iVN1lj_Y0UY2j7ek4?B%1C%147*m8i zWyo5H9xZIZo&oDIil zWGrEgMJ^?-@4?^qDR2cJ+;}4R;P>=>wI^D(O;|bS zK*qs!d*`3b+%I%ta~|_tCTXB%26bVOZH873qU*o2EWNk*)}n`!{R*;^4VjhX7L zzDh=JNd=caLnn}L1LX7MCRTVBFfa!I+3X%bf-NsGH`P$nGX%&73Nl3$}OkS tw#a&!#k$`t5-)!56MZ}RKdbm=Mdlq$yg=JQE?{I+EEL$Z*@W#5GXTF$TiE~r diff --git a/test/api/fonts/SourceSansPro-Regular.abc.otf b/test/api/fonts/SourceSansPro-Regular.abc.otf index 1f1af4aa404c8c9b02a783c074633695092d9de2..4db5c796b58ad718509e106278258ee89b34d554 100644 GIT binary patch delta 649 zcmca2HHEL(uftf+T+09L1#r57k1_p*X3=GVS{=xc2(Q0KJK=uuwSVD4c zVgZ9R<9h}M77HLhA|o|1Mbsxg9w@&6$T!OX3UIZs9s|lx0PW${2Zp{4GGf zKyG410Ru|_kjZicNU-H4=1Qje3Z@tX1V}rdc}$A++|1vX z)r%fIv}n_Id1bEOrtkE=i^_AWYRD?ea);Kd$a0^}D*NGdp8Na{uJhcJ_OkY|rEJ?* zqRI7rGW)ij+tg*b7j2P#zTR2kH&1|*wLEvdrYyIrEaT1x+$JX??r_(uad9&;I59D> zFfuZWc=^8KQgQ{HI-^1!fPaIsmai@GA8#n8!%=o3= z(!T|NGwS^|=f03$_QUZ4x6pp&+u!ry&#&+t-%#Pb3=kWH_%B8j6lr9D)+^| z>Bi;-%*u@6>`~Uy| literal 3412 zcmbVO3v5%@8UC-Yubnp~nNhZ6@tImEAaIPEFePCUNlMy?G*06rCDK!|K6J> zMC?&~b2E~db=Yr9X=)`LrkCo1|}PS2ZjzoH0Hc?0A^BCnSuNm>!pM~%1^Q?vOVLto#k zB}ezD21^=hr7u&h^cAUAdbSM2bModg`Sy;&>DnUwpSzS#5=rgLcz$eoEo}zjIax_w zNm8`8ZbU+nu;W;y^FkG-p(eD9YK#bdShObeAx*?4^QM-`i_UCZH*&h6np#4nv%*Yi zqCcDFUCaa%=GjEOZU`L`L&WvbtZAgRe5hT|O&aNB$`q0ChVVL`Blg_z-%ePaGR<6b zef{|Ocu3_yLUBD)zh<2nPn#*xtK~Ig3`ck9SyObQhT>r-kB38UK3pk*QXz3_^N`nr zbqAf5f>PqI2QJJW|G9MIP3z{2d}GCI?t|60b3Ti1-wM2CRiFF2@>Sp2hkjkCRtf>@ zdSLrsI;~R0n(}oPN_VVR3hjksf!QIyRaMxhSee4!K%vswYgJnNl#2eT%g>C>wq2<_ zd(F!JzUq`UFcr9T?&Vib2cP#Y91v&y&swov++$I{u|buafSM_)N}^o^Qp zhoesf3vn|%@TpH!oocwW?RRzGxg6N39XbDtH-2JmJRB_4_|;vSxvQq)OH)^qW3#PS zt!Kt7uV1$gy;t?B_1aXxl5gF#nys~u-z-%2_h%D>!GrHB)0keT)`;T3^bT=&w@U|I2jveKE7cS~mum6g4FsH}YU ze1N+Kq$+i5t^J*Y%QpRkWcknF(AyUd;I29Ao#s2&igfuBwlaB`i=XT%k-kO>jGyyt z!+xu?O1mi{JqT{8BFkRc2g`f2VJ^?8hk%=Xe3na`-4kM^fBKDF72Te{&JU= zK|koyUaIsrEqNE*7c>$IN5U=K`xZxG$qNfnv~A0PX5`a)Ryf)z-HhwmF|i>O4s8fG zwPe&0O*ehX=+UkJdO_ZG4(Gmx#Jb+8zxH1t!Tdf`8hVbB<6 z_SOOKSx5zS!$SsKA*vCLPNUF@lO{e6*e%*aGX~A99c2%6blYnZ`g_1PkZlOLa?UNt z@KI``D5%9A=ItHp^-Js>t0?TY(10Cl9`SROT*(FBDez1?(=4(Ps4&YycBPweVg}KS zz@D{+u}*MqwueS&ZKOtgP4vh|h-`5V0x@x)R16bYbM?7*T!9hrbews=9ZuW1a>qF0 ze(bn^PQPNH94t7eXK`*lPBZK?9UG<@JEO4V*wV1gBj@|UTMtg-&I)ugg!ysT>;I2I z6UfdXfrLCEM)SZYLtK%elghd5b86J5a*`w4dt8M3Vicx62m-!3JL3Q zwKYVwfJVN3IYi1hWZXJ(uftf+T+09L1?=}{11_p*X3=B*X{=xc2(Q0KJK=vD;SVD4c zVgW-N(**_wW*;CwCnGg6Mbsxg9w@&B$T!OX3UIZs9tFzp0PM8F`FDVP zp4`NW0tV&)Ad~q8kYLM8%#}>_6-+S(3VZ+>qE?V!T=M@SgAq_pV&V)nMze|gC1hn8 z7&!8O#jpZt#!h}222K!Tu@H#t6P)9oNmdxK-PG5h#X=P>6a`~+XRk^soht-RoIJkP_PWe7IZq`+q@k_m> ze+&L*)cbAD&AlZjRCoWLCA%{Q2g8N=BbqJR;>$ifMfI0nQJHY0-^kOyHiG4L@w mfwGwyd>B4K*(^wESQ%0n?V#dp3|fqfHg9A-%Q(53M-c#^T6)s} literal 3228 zcmbVOYitx%6h1Svvn{j~L6=lp+iL_Ygie>Wt!b-?rBG?8UFen~g5Y#_y1St}v(8St zEg``~<1;>D{9%j_X z-19!)x!L%@K%5rQoutquUEST{$t&(VLqtyz$&K+uQ*77jv2r3M1m5k*oSvt9b?kq~zA~qe=SkTLlFd=r)N{sd zAKbqRd-y27BX1R)>5nM}(E~Ua5`{t}Nz#ghHEJh~gl-nL+E!z~ksck{1Imq+%Gp~>$7;*1KXr z)`?=)$%uZVVAx}D-EEnU=tB*~HGUq~XhA+)DS=XPl{e5vQY5MG>92qOe#PnhnTE6Z zuuEr8MLu<_kN>JZ5`J^#C#7n&6mh?a?EI<6tx(;A;hs{(t&M7_t8^rCdZ^63v~)mq zbEW-}(sFmdyWBmXR&93&4@RbrAARXq{lnqMwy7VwZ-m_?JHISd+;CIY+*5b7Up@TN z8;4KSe03;(bA2i4LPt0c`fkJ7T~oEneePi7 zhK4yQN8#l!1M$#!MpPCNC&==A&LDC@>kbaOK z$0Fc|efcj?=vm-(F?bs>3JqApSS7>*OViWXd+YSm(}!mLRf0>NEUz579=se;GI(W{ zSH3v+3+CwwF9Z|KkI*^rUDfVoaJ(XeS(+aJo z6#*TZC!=C!uMhZPijc`!h898lZMrL9y~v_zMM&jhqg zE6SDxv;z9-fDX~}vbF{D72HHIEgFk8{-B9TC~=dmbPmzXpD}KK)Iu|93AJv&DH1LaRv5)XTj&ib~x+h z${pi~w`0fs^ZS(mlUx#VN&L}iFwk&iD$oXRMwiVvEvjUye@ZB6( z{qGobfb2XX7(hOL&E_!26&*&5MXzq0tuHZx71%@kj8?`e=fV}{+-541z?Af2ANTAt zKISa`fNs=w8&>X2JJ$27Q$Q}< zg*;BV4~*v#tlYIUx)+Cj?}A9?GWok2rC^0`47NOk`ph82pA?=@p5#v8n{Sf@=2&2+ zc#oZTFYEv{fR4t2u>qX!z-d38PTU0pINRju#=#NP1*tw@fHitNn(cDrjPgF(iFFH3 zSca=@AgVbu^7Q2qDdUiF>*FMdN3o{ihvQ^q+K7W|Idjj40zAGo8Lf=l znOlG(`Zwfj7loOGms0_{{*>(ZBC^mo|4zyxF2*9~(TSHa!V&v72;=oa+%)uAjw|Qe T?cx6x{{Ie|{s5Qg1%7`4(E5r* diff --git a/test/api/fonts/SourceSansPro-Regular.ac.nosubrs.nohints.otf b/test/api/fonts/SourceSansPro-Regular.ac.nosubrs.nohints.otf new file mode 100644 index 0000000000000000000000000000000000000000..69e244c8a79a1b27df933930791c3abb6d8d2590 GIT binary patch literal 1540 zcmb7DTWB0r82-})mxp?xS`DvF8^J}8k$s+oZllL@yJu#dsnTJG^nChDiAUzDJXmk)_9#FNydD z*yCx_NCo$ejv{^nc1IeH+LPKm;wNF>owmHmKrej=`wiH2mNA(n-Vc?(iz8qgmf72o z+6wz4U~J4fIj{T`#fY>;#04W&CC1pT2`BF+&4gj+`dz1Wz#Pku8?KCWG_ohCkv+*8 z*;92;PVwz^{Le$B3wIFJIDZUlkZjlbM&eTW{uX)eX&{v`&HQ>XrpKZcXpzYYLwK%{ zGA+YBCY+<9E9D$9MPe%FnO08hwv&#VbzH+UQzByvFKvoJJ0q=x2PewyRK#(GgNQ4V zPTuz1jG5DSI@u{VGnV#5EV?DyBF~tAw*A))&1uiec19wFLP0kq5k2WxkFl`+;b#Lc zJfeM3ycj6nbnx5Kx(6T5*dtA62ejF97iTYru1&{#!= ze(#d@W@dDDZ>ZEzVtVPmQu}qi7!23nmp#o|gWdyX^|pHdFM-dmAugktP2c-Lv1t6Wi3#N-_-tE+oQoVJre zN#%Mu0HCX^K@gjk3G7GZMF@d=qs zG31ZK@1k2By~>{NM~B_`YvRyWBP`cfs$2h2U#W_tZWj&tTyx+rS;|TNjh%+i^EnP-;?9E4LM^*>5w?gI5f%7lxFM0Y;!vFvP literal 0 HcmV?d00001 diff --git a/test/api/fonts/SourceSansPro-Regular.ac.nosubrs.otf b/test/api/fonts/SourceSansPro-Regular.ac.nosubrs.otf new file mode 100644 index 0000000000000000000000000000000000000000..28edf1344be34ab60d20383486555d56d766c8f5 GIT binary patch literal 1632 zcmb7DT}&KR6h3!mclq1WQp8k2_8PUN1_rtX3}_8dim5FuvMuQk0f*fwyOx>R%nmH{ z1s{w*Z8U03*9Q|C3>s{FXpL!!Nt@DOFs7gn+D01N#KssOYGPuRxR&+1vw);ACeGyE z^PRu%o^x_<;J|?Z<r|6VkCD0x;A0+7^<$d z7ln61-vW-UF*9ywz9m0gP4IIj@)%U7cpb-^X(1sD|M!4FvxCxKN zL*|fSTTv~p>^5VgR&*d@bAQc_no66vHeX&$ z89x?ZOm&Zy%w0KqZrb;jr+DPu7u*Y}OP?5DJ^_rY+)&Xflc3*Qy-0$ z%+5@lzu+5~amV!VP;aTf(cUMW3 z_zK68ODB@!$qUKL$#<}O(t0xIK3gtqdF5yN`@DIlyan_5w+iM@d%d?#dp9i2l!(s7 zO_to{4JW3$`ZhlE2g&j;!hC)96z*(RE;lYO=9=;xRGB1U#V1So>}_%*`J{9R`o64W zz2s+)!CK&!WtS{T;#P|@*1qP}mH;)8N+IcP#si`otcVjE7Xj>N={*RJbHrKMRR$y& zgv^I*B^OmddLS9<0aGRe-I19ynenyrys(lJE2OAgU0H%Jw6Y`-FW*@H4e#N7^xBwf zt}!6Q`DE!$I?R@+md%kug!d_`Bg&y8qB>U|@RwLw%%~h%7E4q}cUG`W`|0-;>{=J& zrZ9VU#qOae*#u1y#~ZJq9ax;I*0frnW(t!@{iFd0X_Vq*1M85S_L70VOtL8E?5g7n z!&5;KU>o*Es>YviegzX*WmB9?9lq^UiHrnA5g!5S0)HIKqG9ZUtqtr3yqr3~pu@`f z7F1)>5TZh)@rN*{bvh!0h%}rkI}u|#tOJN2gxx~73VIbiKaCDs@gf62>ls$_v)NVm z9zvJO4*zt9OMm^WgcH?{Dx~d7}UT literal 0 HcmV?d00001 diff --git a/test/api/fonts/SourceSansPro-Regular.ac.otf b/test/api/fonts/SourceSansPro-Regular.ac.otf index 40b938eb6ffb24c2dbaa69522471ccb2179a77f9..a22b1571bfd9b7fa01d809e2c73a07cadbc3fee6 100644 GIT binary patch delta 548 zcmZpXTEkoK9}?ovz{$|Sz|0`v?B=F0eGgwW0|Ubx1_q{1|6qNiXtgp91_tH?pjbk3 zZejsL8`A|K{{WDmlaZR3BI*+#59DhA`DPhF0j?I-qYMlzIzYZkMs7(3n=iv|AU^=e z=gCd1C}3a)F?BtJ3j+Q{n8Qg>!*cll)JdK$if02*gaRa#AeKpEf%% z8#9KpGeiMnijjpAC~*vkA#6qlIUopJOnZ{E6+Sbwvwm$H;;@my#=cdXG)2jHv$X?uiWJ9*sTJ4jdL6fU5O=&g-d*CI zS!TztsFIODKpT}uh2s7|a#aW@RQzbFs);H!O{&mTv<^u0p{6fHgaDx+A)#@ZDCRpe zO zr%I&sgN)=cMNPeEd~N=*jo?c}mER~?WoPksl!WRP>s zb->7tkLfn=v^GlLrAFy{Qls=(48-Hg&X{uTfOn>`()!mS^$SE&*IJ(MU)M-GLC8aO z6pam@p1{%Fmg$H-)KJ_V4rGyJ$Bl zGD&oR&PtKL9=ot`>NV-g8}8rcl`9(-N}p`LR*JfG?P~ljxBlEe)E`98-t~L0UiISc z2l4%X>2YgRcP857)g0KWdR^Yh_`*nqyWV?Lb&KB7xL4;Mb?e+m)!KbCZ+?AZVb`U) zvzJ}-!}X`#p_%x_bI(3^ruqBP^;1tis9thkj=F31zvtC_<*NnraMQB`>WSxGKJjY9 z<+;=Y&0fYy4Bheh^`~1eKKy>uPv49mG@d#C`m4{o+vl3Sh6??V;T&qH-8ge;q56_^ z=3~YE`Aq!6`DaeO*ql4BmWtW&!wt#4w_U}J{N|lMo;o>g|DySYbLuY(!zcDOcxKuY_&-H{g7!-b)GA#hjR^Oiqa&)9Hifzptp(41`J@VP0j8+Y;?Niuw`5az>3Q0}5^0_O`b6dvEECPLe>m6SNIO(AFDVE2vJ&l0_qAfKJmi zmB|5J#44xJg1aB@VhNkI9*$*Ad_nL$L800px z)sQRayaO5T#?zSswbH|qePF$Hm3?59g54e(@?$L{evXnWx$HX+nd4__A{&7U^Pc8c zx*aDL5zP_Uv(_lqDbCIJ&<3sT)P}E}?)?;zt;|6nChn7t;UH_SKKG6*a0D_7XWnjy z3x2NLF^+g2IPPE2uQaFt3&H6o&TYYIwtr?|!!%=O9F`ng0k&o2d^>pS$7$SIflg|e z?+?BH{}^=GgvL_R^ymNCZ_9Yu_je%(0RKw}Imu!r~=t&CI7g)7XtEmbCsTha?Y z<@;xREPL*~$phbl)mUP@@DM8^yZPLuXmsF9hd;*m2xg9R`A#tcx>4H)v2tfRu-;sq zGIHTAl(5TvU_6gu<*wz>y%g+wS4Fa%$$zR*7GC(pV9z6{&k{m{o5DAgZ*nK_&96xs z_gLUgF%Qmv7ajsNh>oU!u|e!Ugxvvrop=idvA4&!O+g~43tD}^09*9MwxZGhJT?n?=kV0>o%{L`Sgx}Uzo0yql1F4>lSRAk_N z6e9z#+&>c)AIF-*IUFY=(?%Rz%cXZ_`DU>VN6EQxZ-aM;_j5Rn-%uMK`M%~Ln}&>E zO-3u@cIg%1i2fJywcEl>+Rv#B+u)WQ^&_&-x8O}GATGut=h2D57~zP67liS8D`^h) XtjCoL{PysFi{O6;EzaW+y~Xd}D8IiO diff --git a/test/api/test-subset-cff1.c b/test/api/test-subset-cff1.c index 8f0c1b609..4aafb8046 100644 --- a/test/api/test-subset-cff1.c +++ b/test/api/test-subset-cff1.c @@ -91,6 +91,53 @@ test_subset_cff1_strip_hints (void) hb_face_destroy (face_ac); } +static void +test_subset_cff1_desubr (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/SourceSansPro-Regular.abc.otf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/SourceSansPro-Regular.ac.nosubrs.otf"); + + hb_set_t *codepoints = hb_set_create (); + hb_subset_input_t *input; + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'c'); + input = hb_subset_test_create_input (codepoints); + hb_subset_input_set_desubroutinize (input, true); + face_abc_subset = hb_subset_test_create_subset (face_abc, input); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('C','F','F',' ')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + +static void +test_subset_cff1_desubr_strip_hints (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/SourceSansPro-Regular.abc.otf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/SourceSansPro-Regular.ac.nosubrs.nohints.otf"); + + hb_set_t *codepoints = hb_set_create (); + hb_subset_input_t *input; + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'c'); + input = hb_subset_test_create_input (codepoints); + hb_subset_input_set_drop_hints (input, true); + hb_subset_input_set_desubroutinize (input, true); + face_abc_subset = hb_subset_test_create_subset (face_abc, input); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('C', 'F', 'F', ' ')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + static void test_subset_cff1_j (void) { @@ -111,6 +158,76 @@ test_subset_cff1_j (void) hb_face_destroy (face_41_4c2e); } +static void +test_subset_cff1_j_strip_hints (void) +{ + hb_face_t *face_41_3041_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf"); + hb_face_t *face_41_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,4C2E.nohints.otf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_41_3041_4c2e_subset; + hb_subset_input_t *input; + hb_set_add (codepoints, 0x41); + hb_set_add (codepoints, 0x4C2E); + input = hb_subset_test_create_input (codepoints); + hb_subset_input_set_drop_hints (input, true); + face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_41_4c2e, face_41_3041_4c2e_subset, HB_TAG ('C','F','F',' ')); + + hb_face_destroy (face_41_3041_4c2e_subset); + hb_face_destroy (face_41_3041_4c2e); + hb_face_destroy (face_41_4c2e); +} + +static void +test_subset_cff1_j_desubr (void) +{ + hb_face_t *face_41_3041_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf"); + hb_face_t *face_41_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,4C2E.nosubrs.otf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_41_3041_4c2e_subset; + hb_subset_input_t *input; + hb_set_add (codepoints, 0x41); + hb_set_add (codepoints, 0x4C2E); + input = hb_subset_test_create_input (codepoints); + hb_subset_input_set_desubroutinize (input, true); + face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_41_4c2e, face_41_3041_4c2e_subset, HB_TAG ('C','F','F',' ')); + + hb_face_destroy (face_41_3041_4c2e_subset); + hb_face_destroy (face_41_3041_4c2e); + hb_face_destroy (face_41_4c2e); +} + +static void +test_subset_cff1_j_desubr_strip_hints (void) +{ + hb_face_t *face_41_3041_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf"); + hb_face_t *face_41_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,4C2E.nosubrs.nohints.otf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_41_3041_4c2e_subset; + hb_subset_input_t *input; + hb_set_add (codepoints, 0x41); + hb_set_add (codepoints, 0x4C2E); + input = hb_subset_test_create_input (codepoints); + hb_subset_input_set_drop_hints (input, true); + hb_subset_input_set_desubroutinize (input, true); + face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_41_4c2e, face_41_3041_4c2e_subset, HB_TAG ('C','F','F',' ')); + + hb_face_destroy (face_41_3041_4c2e_subset); + hb_face_destroy (face_41_3041_4c2e); + hb_face_destroy (face_41_4c2e); +} + static void test_subset_cff1_expert (void) { @@ -139,7 +256,12 @@ main (int argc, char **argv) hb_test_add (test_subset_cff1_noop); hb_test_add (test_subset_cff1); hb_test_add (test_subset_cff1_strip_hints); + hb_test_add (test_subset_cff1_desubr); + hb_test_add (test_subset_cff1_desubr_strip_hints); hb_test_add (test_subset_cff1_j); + hb_test_add (test_subset_cff1_j_strip_hints); + hb_test_add (test_subset_cff1_j_desubr); + hb_test_add (test_subset_cff1_j_desubr_strip_hints); hb_test_add (test_subset_cff1_expert); return hb_test_run ();