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 <com_android_text_flags.h>
18 #include <flag_macros.h>
19 #include <gtest/gtest.h>
20
21 #include "FontTestUtils.h"
22 #include "minikin/FontFeature.h"
23 #include "minikin/MinikinPaint.h"
24
25 namespace minikin {
26
27 namespace {
28
29 constexpr hb_tag_t chws_tag = HB_TAG('c', 'h', 'w', 's');
30 constexpr hb_tag_t clig_tag = HB_TAG('c', 'l', 'i', 'g');
31 constexpr hb_tag_t halt_tag = HB_TAG('h', 'a', 'l', 't');
32 constexpr hb_tag_t liga_tag = HB_TAG('l', 'i', 'g', 'a');
33 constexpr hb_tag_t palt_tag = HB_TAG('p', 'a', 'l', 't');
34 constexpr hb_tag_t ruby_tag = HB_TAG('r', 'u', 'b', 'y');
35
compareFeatureTag(hb_feature_t l,hb_feature_t r)36 bool compareFeatureTag(hb_feature_t l, hb_feature_t r) {
37 return l.tag < r.tag;
38 }
39
40 } // namespace
41
42 class DefaultFontFeatureTest : public testing::Test {
43 protected:
44 std::shared_ptr<FontCollection> font;
45
SetUp()46 virtual void SetUp() override { font = buildFontCollection("Ascii.ttf"); }
47 };
48
TEST_F(DefaultFontFeatureTest,default)49 TEST_F(DefaultFontFeatureTest, default) {
50 auto f = cleanAndAddDefaultFontFeatures(MinikinPaint(font));
51 EXPECT_EQ(1u, f.size());
52 EXPECT_EQ(chws_tag, f[0].tag);
53 EXPECT_TRUE(f[0].value);
54 }
55
TEST_F(DefaultFontFeatureTest,disable)56 TEST_F(DefaultFontFeatureTest, disable) {
57 auto paint = MinikinPaint(font);
58 paint.fontFeatureSettings = FontFeature::parse("\"chws\" off");
59
60 auto f = cleanAndAddDefaultFontFeatures(paint);
61 std::sort(f.begin(), f.end(), compareFeatureTag);
62
63 EXPECT_EQ(1u, f.size());
64 EXPECT_EQ(chws_tag, f[0].tag);
65 EXPECT_FALSE(f[0].value);
66 }
67
TEST_F(DefaultFontFeatureTest,preserve)68 TEST_F(DefaultFontFeatureTest, preserve) {
69 auto paint = MinikinPaint(font);
70 paint.fontFeatureSettings = FontFeature::parse("\"ruby\" on");
71
72 auto f = cleanAndAddDefaultFontFeatures(paint);
73 std::sort(f.begin(), f.end(), compareFeatureTag);
74
75 EXPECT_EQ(2u, f.size());
76 EXPECT_EQ(chws_tag, f[0].tag);
77 EXPECT_TRUE(f[0].value);
78 EXPECT_EQ(ruby_tag, f[1].tag);
79 EXPECT_TRUE(f[1].value);
80 }
81
TEST_F(DefaultFontFeatureTest,large_letter_spacing)82 TEST_F(DefaultFontFeatureTest, large_letter_spacing) {
83 auto paint = MinikinPaint(font);
84 paint.letterSpacing = 1.0; // em
85
86 auto f = cleanAndAddDefaultFontFeatures(paint);
87 std::sort(f.begin(), f.end(), compareFeatureTag);
88
89 EXPECT_EQ(3u, f.size());
90 EXPECT_EQ(chws_tag, f[0].tag);
91 EXPECT_TRUE(f[0].value);
92 EXPECT_EQ(clig_tag, f[1].tag);
93 EXPECT_FALSE(f[1].value);
94 EXPECT_EQ(liga_tag, f[2].tag);
95 EXPECT_FALSE(f[2].value);
96 }
97
TEST_F(DefaultFontFeatureTest,halt_disable_chws)98 TEST_F(DefaultFontFeatureTest, halt_disable_chws) {
99 auto paint = MinikinPaint(font);
100 paint.fontFeatureSettings = FontFeature::parse("\"halt\" on");
101
102 auto f = cleanAndAddDefaultFontFeatures(paint);
103 EXPECT_EQ(1u, f.size());
104 EXPECT_EQ(halt_tag, f[0].tag);
105 EXPECT_TRUE(f[0].value);
106 }
107
TEST_F(DefaultFontFeatureTest,palt_disable_chws)108 TEST_F(DefaultFontFeatureTest, palt_disable_chws) {
109 auto paint = MinikinPaint(font);
110 paint.fontFeatureSettings = FontFeature::parse("\"palt\" on");
111
112 auto f = cleanAndAddDefaultFontFeatures(paint);
113 EXPECT_EQ(1u, f.size());
114 EXPECT_EQ(palt_tag, f[0].tag);
115 EXPECT_TRUE(f[0].value);
116 }
117
TEST_F(DefaultFontFeatureTest,halt_disable_chws_large_letter_spacing)118 TEST_F(DefaultFontFeatureTest, halt_disable_chws_large_letter_spacing) {
119 auto paint = MinikinPaint(font);
120 paint.letterSpacing = 1.0; // em
121 paint.fontFeatureSettings = FontFeature::parse("\"halt\" on");
122
123 auto f = cleanAndAddDefaultFontFeatures(paint);
124 std::sort(f.begin(), f.end(), compareFeatureTag);
125
126 EXPECT_EQ(3u, f.size());
127 EXPECT_EQ(clig_tag, f[0].tag);
128 EXPECT_FALSE(f[0].value);
129 EXPECT_EQ(halt_tag, f[1].tag);
130 EXPECT_TRUE(f[1].value);
131 EXPECT_EQ(liga_tag, f[2].tag);
132 EXPECT_FALSE(f[2].value);
133 }
134
TEST_F(DefaultFontFeatureTest,palt_disable_chws_large_letter_spacing)135 TEST_F(DefaultFontFeatureTest, palt_disable_chws_large_letter_spacing) {
136 auto paint = MinikinPaint(font);
137 paint.letterSpacing = 1.0; // em
138 paint.fontFeatureSettings = FontFeature::parse("\"palt\" on");
139
140 auto f = cleanAndAddDefaultFontFeatures(paint);
141 std::sort(f.begin(), f.end(), compareFeatureTag);
142
143 EXPECT_EQ(3u, f.size());
144 EXPECT_EQ(clig_tag, f[0].tag);
145 EXPECT_FALSE(f[0].value);
146 EXPECT_EQ(liga_tag, f[1].tag);
147 EXPECT_FALSE(f[1].value);
148 EXPECT_EQ(palt_tag, f[2].tag);
149 EXPECT_TRUE(f[2].value);
150 }
151
152 class FontFeatureTest : public testing::Test {
153 protected:
154 std::shared_ptr<FontCollection> font;
155
SetUp()156 virtual void SetUp() override { font = buildFontCollection("Ascii.ttf"); }
157 };
158
159 } // namespace minikin
160