| 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 |