@@ -59,12 +59,10 @@ class IntegrationTest : public ::testing::Test {
5959 iftb_patches_[i].set (blob.get ());
6060 }
6161
62- /*
6362 // Noto Sans JP VF
6463 blob = make_hb_blob (
6564 hb_blob_create_from_file (" ift/testdata/NotoSansJP[wght].subset.ttf" ));
66- face = make_hb_face(hb_face_create(blob.get(), 0));
67- noto_sans_vf_.set(face.get());
65+ noto_sans_vf_.set (blob.get ());
6866
6967 vf_iftb_patches_.resize (5 );
7068 for (int i = 1 ; i <= 4 ; i++) {
@@ -74,7 +72,6 @@ class IntegrationTest : public ::testing::Test {
7472 assert (hb_blob_get_length (blob.get ()) > 0 );
7573 vf_iftb_patches_[i].set (blob.get ());
7674 }
77- */
7875
7976 // Feature Test
8077 blob = make_hb_blob (hb_blob_create_from_file (
@@ -113,18 +110,13 @@ class IntegrationTest : public ::testing::Test {
113110 return absl::OkStatus ();
114111 }
115112
116- /*
117- Status InitEncoderForVfIftb(Encoder& encoder) {
118- encoder.SetUrlTemplate("0x$2$1");
113+ Status InitEncoderForVfMixedMode (Encoder& encoder) {
114+ encoder.SetUrlTemplate (" {id}" );
119115 {
120116 hb_face_t * face = noto_sans_vf_.reference_face ();
121117 encoder.SetFace (face);
122118 hb_face_destroy (face);
123119 }
124- auto sc = encoder.SetId({0x479bb4b0, 0x20226239, 0xa7799c0f, 0x24275be0});
125- if (!sc.ok()) {
126- return sc;
127- }
128120
129121 for (uint i = 1 ; i < vf_iftb_patches_.size (); i++) {
130122 auto sc = encoder.AddExistingIftbPatch (i, vf_iftb_patches_[i]);
@@ -135,7 +127,6 @@ class IntegrationTest : public ::testing::Test {
135127
136128 return absl::OkStatus ();
137129 }
138- */
139130
140131 Status InitEncoderForMixedModeFeatureTest (Encoder& encoder) {
141132 encoder.SetUrlTemplate (" {id}" );
@@ -172,24 +163,6 @@ class IntegrationTest : public ::testing::Test {
172163 return absl::OkStatus ();
173164 }
174165
175- /*
176- Status AddPatches(IFTClient& client, Encoder& encoder) {
177- auto patches = client.PatchesNeeded();
178- for (const auto& id : patches) {
179- FontData patch_data;
180- auto it = encoder.Patches().find(id);
181- if (it == encoder.Patches().end()) {
182- return absl::InternalError(StrCat("Patch ", id, " was not found."));
183- }
184- patch_data.shallow_copy(it->second);
185- client.AddPatch(id, patch_data);
186- }
187-
188- return absl::OkStatus();
189- }
190- */
191-
192- /*
193166 bool GvarHasLongOffsets (const FontData& font) {
194167 auto face = font.face ();
195168 auto gvar_data =
@@ -200,13 +173,12 @@ class IntegrationTest : public ::testing::Test {
200173 uint8_t flags_1 = gvar_data.str ().at (15 );
201174 return flags_1 == 0x01 ;
202175 }
203- */
204176
205177 FontData noto_sans_jp_;
206178 std::vector<FontData> iftb_patches_;
207179
208- // FontData noto_sans_vf_;
209- // std::vector<FontData> vf_iftb_patches_;
180+ FontData noto_sans_vf_;
181+ std::vector<FontData> vf_iftb_patches_;
210182
211183 FontData feature_test_;
212184 std::vector<FontData> feature_test_patches_;
@@ -252,6 +224,31 @@ bool GlyphDataMatches(hb_face_t* a, hb_face_t* b, uint32_t codepoint) {
252224 return *a_data == *b_data;
253225}
254226
227+ bool GvarDataMatches (hb_face_t * a, hb_face_t * b, uint32_t codepoint,
228+ uint32_t ignore_count) {
229+ uint32_t gid_a, gid_b;
230+
231+ hb_font_t * font_a = hb_font_create (a);
232+ hb_font_t * font_b = hb_font_create (b);
233+ bool a_present = hb_font_get_nominal_glyph (font_a, codepoint, &gid_a);
234+ bool b_present = hb_font_get_nominal_glyph (font_b, codepoint, &gid_b);
235+ hb_font_destroy (font_a);
236+ hb_font_destroy (font_b);
237+
238+ if (!a_present && !b_present) {
239+ return true ;
240+ }
241+
242+ if (a_present != b_present) {
243+ return false ;
244+ }
245+
246+ auto a_data = FontHelper::GvarData (a, gid_a);
247+ auto b_data = FontHelper::GvarData (b, gid_b);
248+
249+ return a_data->substr (ignore_count) == b_data->substr (ignore_count);
250+ }
251+
255252// TODO(garretrieger): full expansion test.
256253// TODO(garretrieger): test of a woff2 encoded IFT font.
257254// TODO(garretrieger): add IFTB only test case.
@@ -750,10 +747,9 @@ TEST_F(IntegrationTest, MixedMode_SequentialDependentPatches) {
750747 ASSERT_TRUE (codepoints.contains (chunk4_cp));
751748}
752749
753- /*
754750TEST_F (IntegrationTest, MixedMode_DesignSpaceAugmentation) {
755751 Encoder encoder;
756- auto sc = InitEncoderForVfIftb (encoder);
752+ auto sc = InitEncoderForVfMixedMode (encoder);
757753 ASSERT_TRUE (sc.ok ()) << sc;
758754
759755 // target paritions: {{0, 1}, {2}, {3, 4}} + add wght axis
@@ -763,77 +759,39 @@ TEST_F(IntegrationTest, MixedMode_DesignSpaceAugmentation) {
763759 sc.Update (encoder.AddExtensionSubsetOfIftbPatches ({3 , 4 }));
764760 encoder.AddOptionalDesignSpace ({{kWght , *AxisRange::Range (100 , 900 )}});
765761 encoder.AddIftbUrlTemplateOverride ({{kWght , *AxisRange::Range (100 , 900 )}},
766- "vf-0x$2$1");
767-
762+ " vf-{id}" );
768763 ASSERT_TRUE (sc.ok ()) << sc;
769764
770765 auto encoded = encoder.Encode ();
771766 ASSERT_TRUE (encoded.ok ()) << encoded.status ();
772-
773- auto client = IFTClient::NewClient(std::move(*encoded));
774- ASSERT_TRUE(client.ok()) << client.status();
767+ auto encoded_face = encoded->face ();
775768
776769 // Phase 1: non VF augmentation.
777- client->AddDesiredCodepoints({chunk3_cp, chunk4_cp});
778- auto state = client->Process();
779- ASSERT_TRUE(state.ok()) << state.status();
780- ASSERT_EQ(*state, IFTClient::NEEDS_PATCHES);
781-
782- auto patches = client->PatchesNeeded();
783- flat_hash_set<std::string> expected_patches = {"0x03", "0x04", "0x06"};
784- ASSERT_EQ(patches, expected_patches);
785- sc = AddPatches(*client, encoder);
786- ASSERT_TRUE(sc.ok()) << sc;
787-
788- state = client->Process();
789- ASSERT_TRUE(state.ok()) << state.status();
790- ASSERT_EQ(*state, IFTClient::READY);
770+ auto extended = Extend (encoder, *encoded, {chunk3_cp, chunk4_cp});
771+ ASSERT_TRUE (extended.ok ()) << extended.status ();
772+ auto extended_face = extended->face ();
791773
792774 // Phase 2: VF augmentation.
793- sc = client->AddDesiredDesignSpace(kWght, 100, 900);
794- ASSERT_TRUE(sc.ok()) << sc;
795- state = client->Process();
796- ASSERT_TRUE(state.ok()) << state.status();
797- ASSERT_EQ(*state, IFTClient::NEEDS_PATCHES);
798-
799- patches = client->PatchesNeeded();
800- expected_patches = {
801- "0x0d",
802- };
803- ASSERT_EQ(patches, expected_patches);
804- sc = AddPatches(*client, encoder);
805- ASSERT_TRUE(sc.ok()) << sc;
806-
807- state = client->Process();
808- ASSERT_TRUE(state.ok()) << state.status();
809- ASSERT_EQ(*state, IFTClient::NEEDS_PATCHES);
810-
811- ASSERT_TRUE(GvarHasLongOffsets(client->GetFontData()));
812- hb_face_unique_ptr face = client->GetFontData().face();
813- ASSERT_GT(FontHelper::GvarData(face.get(), chunk0_gid)->size(), 0);
814- ASSERT_GT(FontHelper::GvarData(face.get(), chunk1_gid)->size(), 0);
815- ASSERT_EQ(FontHelper::GvarData(face.get(), chunk2_gid)->size(), 0);
816- ASSERT_EQ(FontHelper::GvarData(face.get(), chunk3_gid)->size(), 0);
817- ASSERT_EQ(FontHelper::GvarData(face.get(), chunk4_gid)->size(), 0);
818-
819- patches = client->PatchesNeeded();
820- expected_patches = {"vf-0x03", "vf-0x04"};
821- ASSERT_EQ(patches, expected_patches);
822- sc = AddPatches(*client, encoder);
823- ASSERT_TRUE(sc.ok()) << sc;
775+ extended = ExtendWithDesignSpace (encoder, *encoded, {chunk3_cp, chunk4_cp},
776+ {}, {{kWght , *AxisRange::Range (100 , 900 )}});
777+ ASSERT_TRUE (extended.ok ()) << extended.status ();
778+ extended_face = extended->face ();
824779
825- state = client->Process();
826- ASSERT_TRUE(state.ok()) << state.status();
827- ASSERT_EQ(*state, IFTClient::READY);
780+ ASSERT_TRUE (GvarHasLongOffsets (*extended));
781+ ASSERT_GT (FontHelper::GvarData (extended_face.get (), chunk0_gid)->size (), 0 );
782+ ASSERT_GT (FontHelper::GvarData (extended_face.get (), chunk1_gid)->size (), 0 );
783+ ASSERT_EQ (FontHelper::GvarData (extended_face.get (), chunk2_gid)->size (), 0 );
784+ ASSERT_GT (FontHelper::GvarData (extended_face.get (), chunk3_gid)->size (), 0 );
785+ ASSERT_GT (FontHelper::GvarData (extended_face.get (), chunk4_gid)->size (), 0 );
828786
829- face = client->GetFontData().face();
830- ASSERT_GT(FontHelper::GvarData(face.get(), chunk0_gid)->size(), 0);
831- ASSERT_GT(FontHelper::GvarData(face.get(), chunk1_gid)->size(), 0);
832- ASSERT_EQ(FontHelper::GvarData(face.get(), chunk2_gid)->size(), 0);
833- ASSERT_GT(FontHelper::GvarData(face.get(), chunk3_gid)->size(), 0);
834- ASSERT_GT(FontHelper::GvarData(face.get(), chunk4_gid)->size(), 0);
787+ auto orig_face = noto_sans_vf_.face ();
788+ // The instancing processes changes some of the flags on the gvar data section
789+ // so ignore diffs in the first 7 bytes
790+ ASSERT_TRUE (
791+ GvarDataMatches (orig_face.get (), extended_face.get (), chunk3_cp, 7 ));
835792}
836793
794+ /*
837795TEST_F(IntegrationTest, MixedMode_DesignSpaceAugmentation_DropsUnusedPatches) {
838796 Encoder encoder;
839797 auto sc = InitEncoderForVfIftb(encoder);
0 commit comments