1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include "FontFeatureUtils.h"
20 #include "FontTestUtils.h"
21 #include "minikin/MinikinPaint.h"
22
23 namespace minikin {
24
25 namespace {
26
27 constexpr hb_tag_t chws_tag = HB_TAG('c', 'h', 'w', 's');
28 constexpr hb_tag_t clig_tag = HB_TAG('c', 'l', 'i', 'g');
29 constexpr hb_tag_t halt_tag = HB_TAG('h', 'a', 'l', 't');
30 constexpr hb_tag_t liga_tag = HB_TAG('l', 'i', 'g', 'a');
31 constexpr hb_tag_t palt_tag = HB_TAG('p', 'a', 'l', 't');
32 constexpr hb_tag_t ruby_tag = HB_TAG('r', 'u', 'b', 'y');
33
compareFeatureTag(hb_feature_t l,hb_feature_t r)34 bool compareFeatureTag(hb_feature_t l, hb_feature_t r) {
35 return l.tag < r.tag;
36 }
37
38 } // namespace
39
40 class DefaultFontFeatureTest : public testing::Test {
41 protected:
42 std::shared_ptr<FontCollection> font;
43
SetUp()44 virtual void SetUp() override { font = buildFontCollection("Ascii.ttf"); }
45 };
46
TEST_F(DefaultFontFeatureTest,default)47 TEST_F(DefaultFontFeatureTest, default) {
48 auto f = cleanAndAddDefaultFontFeatures(MinikinPaint(font));
49 EXPECT_EQ(1u, f.size());
50 EXPECT_EQ(chws_tag, f[0].tag);
51 EXPECT_TRUE(f[0].value);
52 }
53
TEST_F(DefaultFontFeatureTest,disable)54 TEST_F(DefaultFontFeatureTest, disable) {
55 auto paint = MinikinPaint(font);
56 paint.fontFeatureSettings = "\"chws\" off";
57
58 auto f = cleanAndAddDefaultFontFeatures(paint);
59 std::sort(f.begin(), f.end(), compareFeatureTag);
60
61 EXPECT_EQ(1u, f.size());
62 EXPECT_EQ(chws_tag, f[0].tag);
63 EXPECT_FALSE(f[0].value);
64 }
65
TEST_F(DefaultFontFeatureTest,preserve)66 TEST_F(DefaultFontFeatureTest, preserve) {
67 auto paint = MinikinPaint(font);
68 paint.fontFeatureSettings = "\"ruby\" on";
69
70 auto f = cleanAndAddDefaultFontFeatures(paint);
71 std::sort(f.begin(), f.end(), compareFeatureTag);
72
73 EXPECT_EQ(2u, f.size());
74 EXPECT_EQ(chws_tag, f[0].tag);
75 EXPECT_TRUE(f[0].value);
76 EXPECT_EQ(ruby_tag, f[1].tag);
77 EXPECT_TRUE(f[1].value);
78 }
79
TEST_F(DefaultFontFeatureTest,large_letter_spacing)80 TEST_F(DefaultFontFeatureTest, large_letter_spacing) {
81 auto paint = MinikinPaint(font);
82 paint.letterSpacing = 1.0; // em
83
84 auto f = cleanAndAddDefaultFontFeatures(paint);
85 std::sort(f.begin(), f.end(), compareFeatureTag);
86
87 EXPECT_EQ(3u, f.size());
88 EXPECT_EQ(chws_tag, f[0].tag);
89 EXPECT_TRUE(f[0].value);
90 EXPECT_EQ(clig_tag, f[1].tag);
91 EXPECT_FALSE(f[1].value);
92 EXPECT_EQ(liga_tag, f[2].tag);
93 EXPECT_FALSE(f[2].value);
94 }
95
TEST_F(DefaultFontFeatureTest,halt_disable_chws)96 TEST_F(DefaultFontFeatureTest, halt_disable_chws) {
97 auto paint = MinikinPaint(font);
98 paint.fontFeatureSettings = "\"halt\" on";
99
100 auto f = cleanAndAddDefaultFontFeatures(paint);
101 EXPECT_EQ(1u, f.size());
102 EXPECT_EQ(halt_tag, f[0].tag);
103 EXPECT_TRUE(f[0].value);
104 }
105
TEST_F(DefaultFontFeatureTest,palt_disable_chws)106 TEST_F(DefaultFontFeatureTest, palt_disable_chws) {
107 auto paint = MinikinPaint(font);
108 paint.fontFeatureSettings = "\"palt\" on";
109
110 auto f = cleanAndAddDefaultFontFeatures(paint);
111 EXPECT_EQ(1u, f.size());
112 EXPECT_EQ(palt_tag, f[0].tag);
113 EXPECT_TRUE(f[0].value);
114 }
115
TEST_F(DefaultFontFeatureTest,halt_disable_chws_large_letter_spacing)116 TEST_F(DefaultFontFeatureTest, halt_disable_chws_large_letter_spacing) {
117 auto paint = MinikinPaint(font);
118 paint.letterSpacing = 1.0; // em
119 paint.fontFeatureSettings = "\"halt\" on";
120
121 auto f = cleanAndAddDefaultFontFeatures(paint);
122 std::sort(f.begin(), f.end(), compareFeatureTag);
123
124 EXPECT_EQ(3u, f.size());
125 EXPECT_EQ(clig_tag, f[0].tag);
126 EXPECT_FALSE(f[0].value);
127 EXPECT_EQ(halt_tag, f[1].tag);
128 EXPECT_TRUE(f[1].value);
129 EXPECT_EQ(liga_tag, f[2].tag);
130 EXPECT_FALSE(f[2].value);
131 }
132
TEST_F(DefaultFontFeatureTest,palt_disable_chws_large_letter_spacing)133 TEST_F(DefaultFontFeatureTest, palt_disable_chws_large_letter_spacing) {
134 auto paint = MinikinPaint(font);
135 paint.letterSpacing = 1.0; // em
136 paint.fontFeatureSettings = "\"palt\" on";
137
138 auto f = cleanAndAddDefaultFontFeatures(paint);
139 std::sort(f.begin(), f.end(), compareFeatureTag);
140
141 EXPECT_EQ(3u, f.size());
142 EXPECT_EQ(clig_tag, f[0].tag);
143 EXPECT_FALSE(f[0].value);
144 EXPECT_EQ(liga_tag, f[1].tag);
145 EXPECT_FALSE(f[1].value);
146 EXPECT_EQ(palt_tag, f[2].tag);
147 EXPECT_TRUE(f[2].value);
148 }
149
150 } // namespace minikin
151