OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2011 The Android Open Source Project | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #ifndef SKFONTCONFIGPARSER_ANDROID_H_ | |
9 #define SKFONTCONFIGPARSER_ANDROID_H_ | |
10 | |
11 #include "SkFontMgr_android.h" | |
12 #include "SkString.h" | |
13 #include "SkTDArray.h" | |
14 | |
15 #include <climits> | |
16 #include <limits> | |
17 | |
18 /** \class SkLanguage | |
19 | |
20 The SkLanguage class represents a human written language, and is used by | |
21 text draw operations to determine which glyph to draw when drawing | |
22 characters with variants (ie Han-derived characters). | |
23 */ | |
24 class SkLanguage { | |
25 public: | |
26 SkLanguage() { } | |
27 SkLanguage(const SkString& tag) : fTag(tag) { } | |
28 SkLanguage(const char* tag) : fTag(tag) { } | |
29 SkLanguage(const char* tag, size_t len) : fTag(tag, len) { } | |
30 SkLanguage(const SkLanguage& b) : fTag(b.fTag) { } | |
31 | |
32 /** Gets a BCP 47 language identifier for this SkLanguage. | |
33 @return a BCP 47 language identifier representing this language | |
34 */ | |
35 const SkString& getTag() const { return fTag; } | |
36 | |
37 /** Performs BCP 47 fallback to return an SkLanguage one step more general. | |
38 @return an SkLanguage one step more general | |
39 */ | |
40 SkLanguage getParent() const; | |
41 | |
42 bool operator==(const SkLanguage& b) const { | |
43 return fTag == b.fTag; | |
44 } | |
45 bool operator!=(const SkLanguage& b) const { | |
46 return fTag != b.fTag; | |
47 } | |
48 SkLanguage& operator=(const SkLanguage& b) { | |
49 fTag = b.fTag; | |
50 return *this; | |
51 } | |
52 | |
53 private: | |
54 //! BCP 47 language identifier | |
55 SkString fTag; | |
56 }; | |
57 | |
58 enum FontVariants { | |
59 kDefault_FontVariant = 0x01, | |
60 kCompact_FontVariant = 0x02, | |
61 kElegant_FontVariant = 0x04, | |
62 kLast_FontVariant = kElegant_FontVariant, | |
63 }; | |
64 typedef uint32_t FontVariant; | |
65 | |
66 // Must remain trivially movable (can be memmoved). | |
67 struct FontFileInfo { | |
68 FontFileInfo() : fIndex(0), fWeight(0), fStyle(Style::kAuto) { } | |
69 | |
70 SkString fFileName; | |
71 int fIndex; | |
72 int fWeight; | |
73 enum class Style { kAuto, kNormal, kItalic } fStyle; | |
74 struct Axis { | |
75 Axis() : fTag(SkSetFourByteTag('\0','\0','\0','\0')), fValue(0) { } | |
76 SkFourByteTag fTag; | |
77 SkFixed fValue; | |
78 }; | |
79 SkTArray<Axis, true> fAxes; | |
80 }; | |
81 | |
82 /** | |
83 * A font family provides one or more names for a collection of fonts, each of | |
84 * which has a different style (normal, italic) or weight (thin, light, bold, | |
85 * etc). | |
86 * Some fonts may occur in compact variants for use in the user interface. | |
87 * Android distinguishes "fallback" fonts to support non-ASCII character sets. | |
88 */ | |
89 struct FontFamily { | |
90 FontFamily(const SkString& basePath, bool isFallbackFont) | |
91 : fVariant(kDefault_FontVariant) | |
92 , fOrder(-1) | |
93 , fIsFallbackFont(isFallbackFont) | |
94 , fBasePath(basePath) | |
95 { } | |
96 | |
97 SkTArray<SkString, true> fNames; | |
98 SkTArray<FontFileInfo, true> fFonts; | |
99 SkLanguage fLanguage; | |
100 FontVariant fVariant; | |
101 int fOrder; // internal to SkFontConfigParser | |
102 bool fIsFallbackFont; | |
103 const SkString fBasePath; | |
104 }; | |
105 | |
106 namespace SkFontConfigParser { | |
107 | |
108 /** Parses system font configuration files and appends result to fontFamilies. *
/ | |
109 void GetSystemFontFamilies(SkTDArray<FontFamily*>& fontFamilies); | |
110 | |
111 /** Parses font configuration files and appends result to fontFamilies. */ | |
112 void GetCustomFontFamilies(SkTDArray<FontFamily*>& fontFamilies, | |
113 const SkString& basePath, | |
114 const char* fontsXml, | |
115 const char* fallbackFontsXml, | |
116 const char* langFallbackFontsDir = NULL); | |
117 | |
118 } // SkFontConfigParser namespace | |
119 | |
120 | |
121 /** Parses a null terminated string into an integer type, checking for overflow. | |
122 * http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega
tive-def | |
123 * | |
124 * If the string cannot be parsed into 'value', returns false and does not chan
ge 'value'. | |
125 */ | |
126 template <typename T> static bool parse_non_negative_integer(const char* s, T* v
alue) { | |
127 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); | |
128 | |
129 if (*s == '\0') { | |
130 return false; | |
131 } | |
132 | |
133 const T nMax = std::numeric_limits<T>::max() / 10; | |
134 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); | |
135 T n = 0; | |
136 for (; *s; ++s) { | |
137 // Check if digit | |
138 if (*s < '0' || '9' < *s) { | |
139 return false; | |
140 } | |
141 T d = *s - '0'; | |
142 // Check for overflow | |
143 if (n > nMax || (n == nMax && d > dMax)) { | |
144 return false; | |
145 } | |
146 n = (n * 10) + d; | |
147 } | |
148 *value = n; | |
149 return true; | |
150 } | |
151 | |
152 /** Parses a null terminated string into a signed fixed point value with bias N. | |
153 * | |
154 * Like http://www.w3.org/TR/html-markup/datatypes.html#common.data.float-def , | |
155 * but may start with '.' and does not support 'e'. '-?((:digit:+(.:digit:+)?)|
(.:digit:+))' | |
156 * | |
157 * Checks for overflow. | |
158 * Low bit rounding is not defined (is currently truncate). | |
159 * Bias (N) required to allow for the sign bit and 4 bits of integer. | |
160 * | |
161 * If the string cannot be parsed into 'value', returns false and does not chan
ge 'value'. | |
162 */ | |
163 template <int N, typename T> static bool parse_fixed(const char* s, T* value) { | |
164 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); | |
165 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_signed, T_must_be_signed); | |
166 SK_COMPILE_ASSERT(sizeof(T) * CHAR_BIT - N >= 5, N_must_leave_four_bits_plus
_sign); | |
167 | |
168 bool negate = false; | |
169 if (*s == '-') { | |
170 ++s; | |
171 negate = true; | |
172 } | |
173 if (*s == '\0') { | |
174 return false; | |
175 } | |
176 | |
177 const T nMax = (std::numeric_limits<T>::max() >> N) / 10; | |
178 const T dMax = (std::numeric_limits<T>::max() >> N) - (nMax * 10); | |
179 T n = 0; | |
180 T frac = 0; | |
181 for (; *s; ++s) { | |
182 // Check if digit | |
183 if (*s < '0' || '9' < *s) { | |
184 // If it wasn't a digit, check if it is a '.' followed by something. | |
185 if (*s != '.' || s[1] == '\0') { | |
186 return false; | |
187 } | |
188 // Find the end, verify digits. | |
189 for (++s; *s; ++s) { | |
190 if (*s < '0' || '9' < *s) { | |
191 return false; | |
192 } | |
193 } | |
194 // Read back toward the '.'. | |
195 for (--s; *s != '.'; --s) { | |
196 T d = *s - '0'; | |
197 frac = (frac + (d << N)) / 10; // This requires four bits overhe
ad. | |
198 } | |
199 break; | |
200 } | |
201 T d = *s - '0'; | |
202 // Check for overflow | |
203 if (n > nMax || (n == nMax && d > dMax)) { | |
204 return false; | |
205 } | |
206 n = (n * 10) + d; | |
207 } | |
208 if (negate) { | |
209 n = -n; | |
210 frac = -frac; | |
211 } | |
212 *value = (n << N) + frac; | |
213 return true; | |
214 } | |
215 | |
216 #endif /* SKFONTCONFIGPARSER_ANDROID_H_ */ | |
OLD | NEW |