fontvariationsettings_test.cpp (6287B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 #include "api-build_test_p.h" 7 #if defined(BL_TEST) 8 9 #include "fonttagdata_p.h" 10 #include "fontvariationsettings_p.h" 11 #include "object_p.h" 12 #include "support/math_p.h" 13 14 // bl::FontVariationSettings - Tests 15 // ================================= 16 17 namespace bl { 18 namespace Tests { 19 20 static void verify_font_variation_settings(const BLFontVariationSettings& ffs) noexcept { 21 BLFontVariationSettingsView view; 22 ffs.get_view(&view); 23 24 if (view.size == 0) 25 return; 26 27 uint32_t prev_tag = view.data[0].tag; 28 for (size_t i = 1; i < view.size; i++) { 29 EXPECT_LT(prev_tag, view.data[i].tag) 30 .message("BLFontVariationSettings is corrupted - previous tag 0x%08X is not less than current tag 0x%08X at [%zu]", prev_tag, view.data[i].tag, i); 31 } 32 } 33 34 UNIT(font_variation_settings_allocation_strategy, BL_TEST_GROUP_TEXT_CONTAINERS) { 35 BLFontVariationSettings ffs; 36 size_t capacity = ffs.capacity(); 37 38 constexpr uint32_t kCharRange = FontTagData::kCharRangeInTag; 39 constexpr uint32_t kNumItems = FontTagData::kUniqueTagCount / 100; 40 41 for (uint32_t i = 0; i < kNumItems; i++) { 42 BLTag tag = BL_MAKE_TAG( 43 uint32_t(' ') + (i / (kCharRange * kCharRange * kCharRange)), 44 uint32_t(' ') + (i / (kCharRange * kCharRange)) % kCharRange, 45 uint32_t(' ') + (i / (kCharRange)) % kCharRange, 46 uint32_t(' ') + (i % kCharRange)); 47 48 ffs.set_value(tag, float(i & 0xFFFFu)); 49 if (capacity != ffs.capacity()) { 50 size_t impl_size = FontVariationSettingsInternal::impl_size_from_capacity(ffs.capacity()).value(); 51 INFO("Capacity increased from %zu to %zu [ImplSize=%zu]\n", capacity, ffs.capacity(), impl_size); 52 capacity = ffs.capacity(); 53 } 54 } 55 56 verify_font_variation_settings(ffs); 57 } 58 59 UNIT(font_variation_settings, BL_TEST_GROUP_TEXT_CONTAINERS) { 60 // These are not sorted on purpose - we want BLFontVariationSettings to sort them. 61 static const uint32_t sso_tags[] = { 62 BL_MAKE_TAG('w', 'g', 'h', 't'), 63 BL_MAKE_TAG('i', 't', 'a', 'l'), 64 BL_MAKE_TAG('w', 'd', 't', 'h') 65 }; 66 67 static const uint32_t dynamic_tags[] = { 68 BL_MAKE_TAG('w', 'g', 'h', 't'), 69 BL_MAKE_TAG('i', 't', 'a', 'l'), 70 BL_MAKE_TAG('w', 'd', 't', 'h'), 71 BL_MAKE_TAG('s', 'l', 'n', 't'), 72 BL_MAKE_TAG('o', 'p', 's', 'z') 73 }; 74 75 INFO("SSO representation"); 76 { 77 BLFontVariationSettings ffs; 78 79 EXPECT_TRUE(ffs._d.sso()); 80 EXPECT_TRUE(ffs.is_empty()); 81 EXPECT_EQ(ffs.size(), 0u); 82 EXPECT_EQ(ffs.capacity(), BLFontVariationSettings::kSSOCapacity); 83 84 // Getting an unknown tag should return invalid value. 85 EXPECT_TRUE(Math::is_nan(ffs.get_value(BL_MAKE_TAG('-', '-', '-', '-')))); 86 87 for (uint32_t i = 0; i < BL_ARRAY_SIZE(sso_tags); i++) { 88 EXPECT_SUCCESS(ffs.set_value(sso_tags[i], 1u)); 89 EXPECT_EQ(ffs.get_value(sso_tags[i]), float(1)); 90 EXPECT_EQ(ffs.size(), i + 1); 91 EXPECT_TRUE(ffs._d.sso()); 92 verify_font_variation_settings(ffs); 93 } 94 95 for (uint32_t i = 0; i < BL_ARRAY_SIZE(sso_tags); i++) { 96 EXPECT_SUCCESS(ffs.set_value(sso_tags[i], 0u)); 97 EXPECT_EQ(ffs.get_value(sso_tags[i]), float(0)); 98 EXPECT_EQ(ffs.size(), BL_ARRAY_SIZE(sso_tags)); 99 EXPECT_TRUE(ffs._d.sso()); 100 verify_font_variation_settings(ffs); 101 } 102 103 for (uint32_t i = 0; i < BL_ARRAY_SIZE(sso_tags); i++) { 104 EXPECT_SUCCESS(ffs.remove_value(sso_tags[i])); 105 EXPECT_TRUE(Math::is_nan(ffs.get_value(sso_tags[i]))); 106 EXPECT_EQ(ffs.size(), BL_ARRAY_SIZE(sso_tags) - i - 1); 107 EXPECT_TRUE(ffs._d.sso()); 108 verify_font_variation_settings(ffs); 109 } 110 } 111 112 INFO("SSO border cases"); 113 { 114 // First veriation ids use R/I bits, which is used for reference counted dynamic objects. 115 // What we want to test here is that this bit is not checked when destroying SSO instances. 116 BLFontVariationSettings settings; 117 settings.set_value(FontTagData::variation_id_to_tag_table[0], 0.5f); 118 settings.set_value(FontTagData::variation_id_to_tag_table[1], 0.5f); 119 } 120 121 INFO("Dynamic representation"); 122 { 123 BLFontVariationSettings ffs; 124 125 EXPECT_TRUE(ffs._d.sso()); 126 EXPECT_TRUE(ffs.is_empty()); 127 EXPECT_EQ(ffs.size(), 0u); 128 EXPECT_EQ(ffs.capacity(), BLFontVariationSettings::kSSOCapacity); 129 130 // Getting an unknown tag should return invalid value. 131 EXPECT_TRUE(Math::is_nan(ffs.get_value(BL_MAKE_TAG('-', '-', '-', '-')))); 132 133 for (uint32_t i = 0; i < BL_ARRAY_SIZE(dynamic_tags); i++) { 134 EXPECT_SUCCESS(ffs.set_value(dynamic_tags[i], 1u)); 135 EXPECT_EQ(ffs.get_value(dynamic_tags[i]), float(1)); 136 EXPECT_EQ(ffs.size(), i + 1); 137 verify_font_variation_settings(ffs); 138 } 139 140 EXPECT_FALSE(ffs._d.sso()); 141 142 for (uint32_t i = 0; i < BL_ARRAY_SIZE(dynamic_tags); i++) { 143 EXPECT_SUCCESS(ffs.set_value(dynamic_tags[i], 0u)); 144 EXPECT_EQ(ffs.get_value(dynamic_tags[i]), float(0)); 145 EXPECT_EQ(ffs.size(), BL_ARRAY_SIZE(dynamic_tags)); 146 verify_font_variation_settings(ffs); 147 } 148 149 EXPECT_FALSE(ffs._d.sso()); 150 151 for (uint32_t i = 0; i < BL_ARRAY_SIZE(dynamic_tags); i++) { 152 EXPECT_SUCCESS(ffs.remove_value(dynamic_tags[i])); 153 EXPECT_TRUE(Math::is_nan(ffs.get_value(dynamic_tags[i]))); 154 EXPECT_EQ(ffs.size(), BL_ARRAY_SIZE(dynamic_tags) - i - 1); 155 verify_font_variation_settings(ffs); 156 } 157 158 EXPECT_FALSE(ffs._d.sso()); 159 } 160 161 INFO("Equality"); 162 { 163 BLFontVariationSettings ffs1; 164 BLFontVariationSettings ffs2; 165 166 for (uint32_t i = 0; i < BL_ARRAY_SIZE(sso_tags); i++) { 167 EXPECT_SUCCESS(ffs1.set_value(sso_tags[i], 1u)); 168 EXPECT_SUCCESS(ffs2.set_value(sso_tags[BL_ARRAY_SIZE(sso_tags) - i - 1], 1u)); 169 } 170 171 EXPECT_TRUE(ffs1.equals(ffs2)); 172 173 // Make ffs1 go out of SSO mode. 174 EXPECT_SUCCESS(ffs1.set_value(BL_MAKE_TAG('a', 'a', 'a', 'a'), 1)); 175 EXPECT_SUCCESS(ffs1.remove_value(BL_MAKE_TAG('a', 'a', 'a', 'a'))); 176 EXPECT_TRUE(ffs1.equals(ffs2)); 177 178 // Make ffs2 go out of SSO mode. 179 EXPECT_SUCCESS(ffs2.set_value(BL_MAKE_TAG('a', 'a', 'a', 'a'), 1)); 180 EXPECT_SUCCESS(ffs2.remove_value(BL_MAKE_TAG('a', 'a', 'a', 'a'))); 181 EXPECT_TRUE(ffs1.equals(ffs2)); 182 } 183 } 184 185 } // {Tests} 186 } // {bl} 187 188 #endif // BL_TEST