odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

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