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