1 /*
2  * Copyright (C) 2019 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 /**
18  * @addtogroup Font
19  * @{
20  */
21 
22 /**
23  * @file font_matcher.h
24  * @brief Provides the font matching logic with various inputs.
25  *
26  * You can use this class for deciding what font is to be used for drawing text.
27  *
28  * A matcher is created from text style, locales and UI compatibility. The match function for
29  * matcher object can be called multiple times until close function is called.
30  *
31  * Even if no font can render the given text, the match function will return a non-null result for
32  * drawing Tofu character.
33  *
34  * Examples:
35  * \code{.cpp}
36  *  // Simple font query for the ASCII character.
37  *  std::vector<uint16_t> text = { 'A' };
38  *  AFontMatcher* matcher = AFontMatcher_create("sans-serif");
39  *  ASystemFont* font = AFontMatcher_match(text.data(), text.length(), &runLength);
40  *  // runLength will be 1 and the font will points a valid font file.
41  *  AFontMatcher_destroy(matcher);
42  *
43  *  // Querying font for CJK characters
44  *  std::vector<uint16_t> text = { 0x9AA8 };
45  *  AFontMatcher* matcher = AFontMatcher_create("sans-serif");
46  *  AFontMatcher_setLocales(matcher, "zh-CN,ja-JP");
47  *  ASystemFont* font = AFontMatcher_match(text.data(), text.length(), &runLength);
48  *  // runLength will be 1 and the font will points a Simplified Chinese font.
49  *  AFontMatcher_setLocales(matcher, "ja-JP,zh-CN");
50  *  ASystemFont* font = AFontMatcher_match(text.data(), text.length(), &runLength);
51  *  // runLength will be 1 and the font will points a Japanese font.
52  *  AFontMatcher_destroy(matcher);
53  *
54  *  // Querying font for text/color emoji
55  *  std::vector<uint16_t> text = { 0xD83D, 0xDC68, 0x200D, 0x2764, 0xFE0F, 0x200D, 0xD83D, 0xDC68 };
56  *  AFontMatcher* matcher = AFontMatcher_create("sans-serif");
57  *  ASystemFont* font = AFontMatcher_match(text.data(), text.length(), &runLength);
58  *  // runLength will be 8 and the font will points a color emoji font.
59  *  AFontMatcher_destroy(matcher);
60  *
61  *  // Mixture of multiple script of characters.
62  *  // 0x05D0 is a Hebrew character and 0x0E01 is a Thai character.
63  *  std::vector<uint16_t> text = { 0x05D0, 0x0E01 };
64  *  AFontMatcher* matcher = AFontMatcher_create("sans-serif");
65  *  ASystemFont* font = AFontMatcher_match(text.data(), text.length(), &runLength);
66  *  // runLength will be 1 and the font will points a Hebrew font.
67  *  AFontMatcher_destroy(matcher);
68  * \endcode
69  *
70  * Available since API level 29.
71  */
72 
73 #ifndef ANDROID_FONT_MATCHER_H
74 #define ANDROID_FONT_MATCHER_H
75 
76 #include <stdbool.h>
77 #include <stddef.h>
78 #include <sys/cdefs.h>
79 
80 #include <android/font.h>
81 
82 /******************************************************************
83  *
84  * IMPORTANT NOTICE:
85  *
86  *   This file is part of Android's set of stable system headers
87  *   exposed by the Android NDK (Native Development Kit).
88  *
89  *   Third-party source AND binary code relies on the definitions
90  *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
91  *
92  *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
93  *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
94  *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
95  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
96  */
97 
98 __BEGIN_DECLS
99 
100 #if __ANDROID_API__ >= 29
101 
102 enum {
103     /** A family variant value for the system default variant. */
104     AFAMILY_VARIANT_DEFAULT = 0,
105 
106     /**
107      * A family variant value for the compact font family variant.
108      *
109      * The compact font family has Latin-based vertical metrics.
110      */
111     AFAMILY_VARIANT_COMPACT = 1,
112 
113     /**
114      * A family variant value for the elegant font family variant.
115      *
116      * The elegant font family may have larger vertical metrics than Latin font.
117      */
118     AFAMILY_VARIANT_ELEGANT = 2,
119 };
120 
121 /**
122  * AFontMatcher performs match operation on given parameters and available font files.
123  * This matcher is not a thread-safe object. Do not pass this matcher to other threads.
124  */
125 struct AFontMatcher;
126 
127 /**
128  * Select the best font from given parameters.
129  *
130  */
131 
132 /**
133  * Creates a new AFontMatcher object.
134  *
135  * Available since API level 29.
136  */
137 AFontMatcher* _Nonnull AFontMatcher_create() __INTRODUCED_IN(29);
138 
139 /**
140  * Destroy the matcher object.
141  *
142  * Available since API level 29.
143  *
144  * \param matcher a matcher object. Passing NULL is not allowed.
145  */
146 void AFontMatcher_destroy(AFontMatcher* _Nonnull matcher) __INTRODUCED_IN(29);
147 
148 /**
149  * Set font style to matcher.
150  *
151  * If this function is not called, the matcher performs with {@link ASYSTEM_FONT_WEIGHT_NORMAL}
152  * with non-italic style.
153  *
154  * Available since API level 29.
155  *
156  * \param matcher a matcher object. Passing NULL is not allowed.
157  * \param weight a font weight value. Only from 0 to 1000 value is valid
158  * \param italic true if italic, otherwise false.
159  */
160 void AFontMatcher_setStyle(
161         AFontMatcher* _Nonnull matcher,
162         uint16_t weight,
163         bool italic) __INTRODUCED_IN(29);
164 
165 /**
166  * Set font locales to matcher.
167  *
168  * If this function is not called, the matcher performs with empty locale list.
169  *
170  * Available since API level 29.
171  *
172  * \param matcher a matcher object. Passing NULL is not allowed.
173  * \param languageTags a null character terminated comma separated IETF BCP47 compliant language
174  *                     tags.
175  */
176 void AFontMatcher_setLocales(
177         AFontMatcher* _Nonnull matcher,
178         const char* _Nonnull languageTags) __INTRODUCED_IN(29);
179 
180 /**
181  * Set family variant to matcher.
182  *
183  * If this function is not called, the matcher performs with {@link AFAMILY_VARIANT_DEFAULT}.
184  *
185  * Available since API level 29.
186  *
187  * \param matcher a matcher object. Passing NULL is not allowed.
188  * \param familyVariant Must be one of {@link AFAMILY_VARIANT_DEFAULT},
189  *                      {@link AFAMILY_VARIANT_COMPACT} or {@link AFAMILY_VARIANT_ELEGANT} is valid.
190  */
191 void AFontMatcher_setFamilyVariant(
192         AFontMatcher* _Nonnull matcher,
193         uint32_t familyVariant) __INTRODUCED_IN(29);
194 
195 /**
196  * Performs the matching from the generic font family for the text and select one font.
197  *
198  * For more information about generic font families, read [W3C spec](https://www.w3.org/TR/css-fonts-4/#generic-font-families)
199  *
200  * Even if no font can render the given text, this function will return a non-null result for
201  * drawing Tofu character.
202  *
203  * Available since API level 29.
204  *
205  * \param matcher a matcher object. Passing NULL is not allowed.
206  * \param familyName a null character terminated font family name
207  * \param text a UTF-16 encoded text buffer to be rendered. Do not pass empty string.
208  * \param textLength a length of the given text buffer. This must not be zero.
209  * \param runLengthOut if not null, the font run length will be filled.
210  * \return a font to be used for given text and params. You need to release the returned font by
211  *         ASystemFont_close when it is no longer needed.
212  */
213 AFont* _Nonnull AFontMatcher_match(
214         const AFontMatcher* _Nonnull matcher,
215         const char* _Nonnull familyName,
216         const uint16_t* _Nonnull text,
217         const uint32_t textLength,
218         uint32_t* _Nullable runLengthOut) __INTRODUCED_IN(29);
219 
220 #endif // __ANDROID_API__ >= 29
221 
222 __END_DECLS
223 
224 #endif // ANDROID_FONT_MATCHER_H
225 
226 /** @} */
227