Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkFontConfigParser_android.h" | 8 #include "SkFontConfigParser_android.h" |
| 9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
| 10 #include "SkFontHost_FreeType_common.h" | 10 #include "SkFontHost_FreeType_common.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #ifndef SK_DEBUG_FONTS | 26 #ifndef SK_DEBUG_FONTS |
| 27 #define SK_DEBUG_FONTS 0 | 27 #define SK_DEBUG_FONTS 0 |
| 28 #endif | 28 #endif |
| 29 | 29 |
| 30 #if SK_DEBUG_FONTS | 30 #if SK_DEBUG_FONTS |
| 31 # define DEBUG_FONT(args) SkDebugf args | 31 # define DEBUG_FONT(args) SkDebugf args |
| 32 #else | 32 #else |
| 33 # define DEBUG_FONT(args) | 33 # define DEBUG_FONT(args) |
| 34 #endif | 34 #endif |
| 35 | 35 |
| 36 //SkTypeface* SkAndroidNextLogicalTypeface(SkFontID, SkFontID, SkPaintOptionsAnd roid const&) { | |
|
djsollen
2014/07/31 14:51:37
drop this
bungeman-skia
2014/07/31 22:15:53
As soon as https://codereview.chromium.org/4346230
| |
| 37 // return NULL; | |
| 38 //} | |
| 39 | |
| 36 class SkTypeface_Android : public SkTypeface_FreeType { | 40 class SkTypeface_Android : public SkTypeface_FreeType { |
| 37 public: | 41 public: |
| 38 SkTypeface_Android(int index, | 42 SkTypeface_Android(int index, |
| 39 Style style, | 43 Style style, |
| 40 bool isFixedPitch, | 44 bool isFixedPitch, |
| 41 const SkString familyName) | 45 const SkString familyName) |
| 42 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) | 46 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) |
| 43 , fIndex(index) | 47 , fIndex(index) |
| 44 , fFamilyName(familyName) { } | 48 , fFamilyName(familyName) { } |
| 45 | 49 |
| 46 const SkString& name() const { return fFamilyName; } | 50 const SkString& name() const { return fFamilyName; } |
| 47 | 51 |
| 48 protected: | 52 protected: |
| 49 int fIndex; | 53 int fIndex; |
| 50 SkString fFamilyName; | 54 SkString fFamilyName; |
| 51 | 55 |
| 52 private: | 56 private: |
| 53 typedef SkTypeface_FreeType INHERITED; | 57 typedef SkTypeface_FreeType INHERITED; |
| 54 }; | 58 }; |
| 55 | 59 |
| 56 class SkTypeface_AndroidSystem : public SkTypeface_Android { | 60 class SkTypeface_AndroidSystem : public SkTypeface_Android { |
| 57 public: | 61 public: |
| 58 SkTypeface_AndroidSystem(const SkString pathName, | 62 SkTypeface_AndroidSystem(const SkString pathName, |
| 59 int index, | 63 int index, |
| 60 Style style, | 64 Style style, |
| 61 bool isFixedPitch, | 65 bool isFixedPitch, |
| 62 const SkString familyName) | 66 const SkString familyName, |
| 67 const SkLanguage& lang) | |
| 63 : INHERITED(index, style, isFixedPitch, familyName) | 68 : INHERITED(index, style, isFixedPitch, familyName) |
| 64 , fPathName(pathName) { } | 69 , fPathName(pathName) |
| 70 , fLang(lang) { } | |
| 65 | 71 |
| 66 virtual void onGetFontDescriptor(SkFontDescriptor* desc, | 72 virtual void onGetFontDescriptor(SkFontDescriptor* desc, |
| 67 bool* serialize) const SK_OVERRIDE { | 73 bool* serialize) const SK_OVERRIDE { |
| 68 SkASSERT(desc); | 74 SkASSERT(desc); |
| 69 SkASSERT(serialize); | 75 SkASSERT(serialize); |
| 70 desc->setFamilyName(fFamilyName.c_str()); | 76 desc->setFamilyName(fFamilyName.c_str()); |
| 71 desc->setFontFileName(fPathName.c_str()); | 77 desc->setFontFileName(fPathName.c_str()); |
| 72 *serialize = false; | 78 *serialize = false; |
| 73 } | 79 } |
| 74 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { | 80 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { |
| 75 *ttcIndex = fIndex; | 81 *ttcIndex = fIndex; |
| 76 return SkStream::NewFromFile(fPathName.c_str()); | 82 return SkStream::NewFromFile(fPathName.c_str()); |
| 77 } | 83 } |
| 78 | 84 |
| 79 private: | 85 private: |
| 80 SkString fPathName; | 86 const SkString fPathName; |
| 87 const SkLanguage fLang; | |
| 81 | 88 |
| 89 friend class SkFontMgr_Android; | |
|
djsollen
2014/07/31 14:51:37
why!! A simple get function makes it clear that y
bungeman-skia
2014/07/31 22:15:53
As discussed since this is all hidden away in the
| |
| 82 typedef SkTypeface_Android INHERITED; | 90 typedef SkTypeface_Android INHERITED; |
| 83 }; | 91 }; |
| 84 | 92 |
| 85 class SkTypeface_AndroidStream : public SkTypeface_Android { | 93 class SkTypeface_AndroidStream : public SkTypeface_Android { |
| 86 public: | 94 public: |
| 87 SkTypeface_AndroidStream(SkStream* stream, | 95 SkTypeface_AndroidStream(SkStream* stream, |
| 88 int index, | 96 int index, |
| 89 Style style, | 97 Style style, |
| 90 bool isFixedPitch, | 98 bool isFixedPitch, |
| 91 const SkString familyName) | 99 const SkString familyName) |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 113 }; | 121 }; |
| 114 | 122 |
| 115 void get_path_for_sys_fonts(SkString* full, const SkString& name) { | 123 void get_path_for_sys_fonts(SkString* full, const SkString& name) { |
| 116 full->set(getenv("ANDROID_ROOT")); | 124 full->set(getenv("ANDROID_ROOT")); |
| 117 full->append(SK_FONT_FILE_PREFIX); | 125 full->append(SK_FONT_FILE_PREFIX); |
| 118 full->append(name); | 126 full->append(name); |
| 119 } | 127 } |
| 120 | 128 |
| 121 class SkFontStyleSet_Android : public SkFontStyleSet { | 129 class SkFontStyleSet_Android : public SkFontStyleSet { |
| 122 public: | 130 public: |
| 123 explicit SkFontStyleSet_Android(FontFamily* family) { | 131 explicit SkFontStyleSet_Android(const FontFamily& family) { |
| 132 const SkString* cannonicalName = NULL; | |
| 133 if (family.fNames.count() > 0) { | |
| 134 cannonicalName = &family.fNames[0]; | |
| 135 } | |
| 124 // TODO? make this lazy | 136 // TODO? make this lazy |
| 125 for (int i = 0; i < family->fFontFiles.count(); ++i) { | 137 for (int i = 0; i < family.fFontFiles.count(); ++i) { |
| 126 const SkString& fileName = family->fFontFiles[i].fFileName; | 138 const FontFileInfo& fontFile = family.fFontFiles[i]; |
| 127 | 139 |
| 128 SkString pathName; | 140 SkString pathName; |
| 129 get_path_for_sys_fonts(&pathName, fileName); | 141 get_path_for_sys_fonts(&pathName, fontFile.fFileName); |
| 130 | 142 |
| 131 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str() )); | 143 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str() )); |
| 132 if (!stream.get()) { | 144 if (!stream.get()) { |
| 133 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, fileN ame.c_str())); | 145 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathN ame.c_str())); |
| 134 continue; | 146 continue; |
| 135 } | 147 } |
| 136 | 148 |
| 137 const int ttcIndex = family->fFontFiles[i].fIndex; | 149 const int ttcIndex = family.fFontFiles[i].fIndex; |
| 138 SkString fontName; | 150 SkString fontName; |
| 139 SkTypeface::Style style; | 151 SkTypeface::Style style; |
| 140 bool isFixedWidth; | 152 bool isFixedWidth; |
| 141 if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex, | 153 if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex, |
| 142 &fontName, &style, &isFixedWidth) ) { | 154 &fontName, &style, &isFixedWidth) ) { |
| 143 DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, fileNam e.c_str())); | 155 DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, pathNam e.c_str())); |
| 144 continue; | 156 continue; |
| 145 } | 157 } |
| 146 | 158 |
| 159 const SkLanguage& lang = family.fFontFiles[i].fPaintOptions.getLangu age(); | |
| 160 | |
| 161 if (cannonicalName != NULL) { | |
| 162 fontName = *cannonicalName; | |
|
djsollen
2014/07/31 14:51:37
what is the benefit of passing the same name for e
bungeman-skia
2014/07/31 22:15:53
The name is the family name as specified by the Fo
| |
| 163 } | |
| 164 | |
| 147 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, | 165 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, |
| 148 (pathName, ttcIndex, | 166 (pathName, ttcIndex, |
| 149 style, isFixedWidth, fontName) )); | 167 style, isFixedWidth, fontName, lang))); |
| 150 } | 168 } |
| 151 } | 169 } |
| 152 | 170 |
| 153 virtual int count() SK_OVERRIDE { | 171 virtual int count() SK_OVERRIDE { |
| 154 return fStyles.count(); | 172 return fStyles.count(); |
| 155 } | 173 } |
| 156 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER RIDE { | 174 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER RIDE { |
| 157 if (index < 0 || fStyles.count() <= index) { | 175 if (index < 0 || fStyles.count() <= index) { |
| 158 return; | 176 return; |
| 159 } | 177 } |
| 160 if (style) { | 178 if (style) { |
| 161 *style = this->style(index); | 179 *style = this->style(index); |
| 162 } | 180 } |
| 163 if (name) { | 181 if (name) { |
| 164 name->reset(); | 182 name->reset(); |
| 165 } | 183 } |
| 166 } | 184 } |
| 167 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 185 virtual SkTypeface_AndroidSystem* createTypeface(int index) SK_OVERRIDE { |
| 168 if (index < 0 || fStyles.count() <= index) { | 186 if (index < 0 || fStyles.count() <= index) { |
| 169 return NULL; | 187 return NULL; |
| 170 } | 188 } |
| 171 return SkRef(fStyles[index].get()); | 189 return SkRef(fStyles[index].get()); |
| 172 } | 190 } |
| 173 | 191 |
| 174 /** Find the typeface in this style set that most closely matches the given pattern. | 192 /** Find the typeface in this style set that most closely matches the given pattern. |
| 175 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); | 193 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); |
| 176 * this simpler version using match_score() passes all our tests. | 194 * this simpler version using match_score() passes all our tests. |
| 177 */ | 195 */ |
| 178 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { | 196 virtual SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) SK_ OVERRIDE { |
| 179 if (0 == fStyles.count()) { | 197 if (0 == fStyles.count()) { |
| 180 return NULL; | 198 return NULL; |
| 181 } | 199 } |
| 182 SkTypeface* closest = fStyles[0]; | 200 SkTypeface_AndroidSystem* closest = fStyles[0]; |
| 183 int minScore = std::numeric_limits<int>::max(); | 201 int minScore = std::numeric_limits<int>::max(); |
| 184 for (int i = 0; i < fStyles.count(); ++i) { | 202 for (int i = 0; i < fStyles.count(); ++i) { |
| 185 SkFontStyle style = this->style(i); | 203 SkFontStyle style = this->style(i); |
| 186 int score = match_score(pattern, style); | 204 int score = match_score(pattern, style); |
| 187 if (score < minScore) { | 205 if (score < minScore) { |
| 188 closest = fStyles[i]; | 206 closest = fStyles[i]; |
| 189 minScore = score; | 207 minScore = score; |
| 190 } | 208 } |
| 191 } | 209 } |
| 192 return SkRef(closest); | 210 return SkRef(closest); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 206 return SkFontStyle::kUpright_Slant; | 224 return SkFontStyle::kUpright_Slant; |
| 207 } | 225 } |
| 208 static int match_score(const SkFontStyle& pattern, const SkFontStyle& candid ate) { | 226 static int match_score(const SkFontStyle& pattern, const SkFontStyle& candid ate) { |
| 209 int score = 0; | 227 int score = 0; |
| 210 score += abs((pattern.width() - candidate.width()) * 100); | 228 score += abs((pattern.width() - candidate.width()) * 100); |
| 211 score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000); | 229 score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000); |
| 212 score += abs(pattern.weight() - candidate.weight()); | 230 score += abs(pattern.weight() - candidate.weight()); |
| 213 return score; | 231 return score; |
| 214 } | 232 } |
| 215 | 233 |
| 216 SkTArray<SkAutoTUnref<SkTypeface>, true> fStyles; | 234 SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles; |
| 217 | 235 |
| 218 friend struct NameToFamily; | 236 friend struct NameToFamily; |
| 219 friend class SkFontMgr_Android; | 237 friend class SkFontMgr_Android; |
| 220 | 238 |
| 221 typedef SkFontStyleSet INHERITED; | 239 typedef SkFontStyleSet INHERITED; |
| 222 }; | 240 }; |
| 223 | 241 |
| 224 /** On Android a single family can have many names, but our API assumes unique n ames. | 242 /** On Android a single family can have many names, but our API assumes unique n ames. |
| 225 * Map names to the back end so that all names for a given family refer to the same | 243 * Map names to the back end so that all names for a given family refer to the same |
| 226 * (non-replicated) set of typefaces. | 244 * (non-replicated) set of typefaces. |
| 227 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping. | 245 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping. |
| 228 */ | 246 */ |
| 229 struct NameToFamily { | 247 struct NameToFamily { |
| 230 SkString name; | 248 SkString name; |
| 231 SkFontStyleSet_Android* styleSet; | 249 SkFontStyleSet_Android* styleSet; |
| 232 }; | 250 }; |
| 233 | 251 |
| 234 class SkFontMgr_Android : public SkFontMgr { | 252 class SkFontMgr_Android : public SkFontMgr { |
| 235 public: | 253 public: |
| 236 SkFontMgr_Android() { | 254 SkFontMgr_Android() { |
| 237 SkTDArray<FontFamily*> fontFamilies; | 255 SkTDArray<FontFamily*> fontFamilies; |
| 238 SkFontConfigParser::GetFontFamilies(fontFamilies); | 256 SkFontConfigParser::GetFontFamilies(fontFamilies, |
| 257 SkPaintOptionsAndroid::kCompact_Vari ant); | |
|
djsollen
2014/07/31 14:51:37
document why we ignore the compact variant for fal
bungeman-skia
2014/07/31 22:15:53
Eck, I don't think we want to. Now that I've done
| |
| 239 this->buildNameToFamilyMap(fontFamilies); | 258 this->buildNameToFamilyMap(fontFamilies); |
| 240 this->findDefaultFont(); | 259 this->findDefaultFont(); |
| 241 } | 260 } |
| 242 | 261 |
| 243 protected: | 262 protected: |
| 244 /** Returns not how many families we have, but how many unique names | 263 /** Returns not how many families we have, but how many unique names |
| 245 * exist among the families. | 264 * exist among the families. |
| 246 */ | 265 */ |
| 247 virtual int onCountFamilies() const SK_OVERRIDE { | 266 virtual int onCountFamilies() const SK_OVERRIDE { |
| 248 return fNameToFamilyMap.count(); | 267 return fNameToFamilyMap.count(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 266 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE { | 285 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE { |
| 267 if (!familyName) { | 286 if (!familyName) { |
| 268 return NULL; | 287 return NULL; |
| 269 } | 288 } |
| 270 SkAutoAsciiToLC tolc(familyName); | 289 SkAutoAsciiToLC tolc(familyName); |
| 271 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { | 290 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { |
| 272 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { | 291 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { |
| 273 return SkRef(fNameToFamilyMap[i].styleSet); | 292 return SkRef(fNameToFamilyMap[i].styleSet); |
| 274 } | 293 } |
| 275 } | 294 } |
| 295 // TODO: eventually we should not need to name fallback families. | |
| 296 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { | |
| 297 if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { | |
| 298 return SkRef(fFallbackNameToFamilyMap[i].styleSet); | |
| 299 } | |
| 300 } | |
| 276 return NULL; | 301 return NULL; |
| 277 } | 302 } |
| 278 | 303 |
| 279 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 304 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
| 280 const SkFontStyle& style) const SK_OV ERRIDE { | 305 const SkFontStyle& style) const SK_OV ERRIDE { |
| 281 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 306 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); |
| 282 return sset->matchStyle(style); | 307 return sset->matchStyle(style); |
| 283 } | 308 } |
| 284 | 309 |
| 285 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, | 310 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, |
| 286 const SkFontStyle& style) const SK_OVER RIDE { | 311 const SkFontStyle& style) const SK_OVER RIDE { |
| 287 for (int i = 0; i < fFontStyleSets.count(); ++i) { | 312 for (int i = 0; i < fFontStyleSets.count(); ++i) { |
| 288 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { | 313 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { |
| 289 if (fFontStyleSets[i]->fStyles[j] == typeface) { | 314 if (fFontStyleSets[i]->fStyles[j] == typeface) { |
| 290 return fFontStyleSets[i]->matchStyle(style); | 315 return fFontStyleSets[i]->matchStyle(style); |
| 291 } | 316 } |
| 292 } | 317 } |
| 293 } | 318 } |
| 294 return NULL; | 319 return NULL; |
| 295 } | 320 } |
| 296 | 321 |
| 322 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], | |
| 323 const SkFontStyle& style, | |
| 324 const char bpc47[], | |
| 325 uint32_t character) const SK _OVERRIDE | |
| 326 { | |
| 327 SkLanguage lang(bpc47); | |
| 328 do { | |
| 329 const SkString& langTag = lang.getTag(); | |
| 330 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { | |
| 331 SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i].sty leSet; | |
| 332 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(s tyle)); | |
| 333 | |
| 334 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { | |
| 335 continue; | |
| 336 } | |
| 337 | |
| 338 SkPaint paint; | |
| 339 paint.setTypeface(face); | |
| 340 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); | |
| 341 | |
| 342 uint16_t glyphID; | |
| 343 paint.textToGlyphs(&character, sizeof(character), &glyphID); | |
| 344 if (glyphID != 0) { | |
| 345 return face.detach(); | |
| 346 } | |
| 347 } | |
| 348 } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true)); | |
| 349 return NULL; | |
| 350 } | |
| 351 | |
| 297 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE { | 352 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE { |
| 298 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); | 353 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); |
| 299 return this->createFromStream(stream, ttcIndex); | 354 return this->createFromStream(stream, ttcIndex); |
| 300 } | 355 } |
| 301 | 356 |
| 302 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { | 357 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { |
| 303 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 358 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 304 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; | 359 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; |
| 305 } | 360 } |
| 306 | 361 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 } | 395 } |
| 341 | 396 |
| 342 | 397 |
| 343 private: | 398 private: |
| 344 | 399 |
| 345 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; | 400 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; |
| 346 SkFontStyleSet* fDefaultFamily; | 401 SkFontStyleSet* fDefaultFamily; |
| 347 SkTypeface* fDefaultTypeface; | 402 SkTypeface* fDefaultTypeface; |
| 348 | 403 |
| 349 SkTDArray<NameToFamily> fNameToFamilyMap; | 404 SkTDArray<NameToFamily> fNameToFamilyMap; |
| 405 SkTDArray<NameToFamily> fFallbackNameToFamilyMap; | |
| 350 | 406 |
| 351 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { | 407 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { |
| 352 for (int i = 0; i < families.count(); i++) { | 408 for (int i = 0; i < families.count(); i++) { |
| 353 fFontStyleSets.push_back().reset( | 409 FontFamily& family = *families[i]; |
| 354 SkNEW_ARGS(SkFontStyleSet_Android, (families[i]))); | 410 |
| 355 for (int j = 0; j < families[i]->fNames.count(); j++) { | 411 SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap; |
| 356 NameToFamily* nextEntry = fNameToFamilyMap.append(); | 412 if (family.fIsFallbackFont) { |
| 357 SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (families[i]->f Names[j])); | 413 nameToFamily = &fFallbackNameToFamilyMap; |
| 358 nextEntry->styleSet = fFontStyleSets.back().get(); | 414 |
| 415 if (0 == family.fNames.count()) { | |
| 416 SkString& fallbackName = family.fNames.push_back(); | |
| 417 fallbackName.printf("%.2x##fallback", i); | |
| 418 } | |
| 419 } | |
| 420 | |
| 421 SkFontStyleSet_Android* newSet = SkNEW_ARGS(SkFontStyleSet_Android, (family)); | |
| 422 if (0 == newSet->count()) { | |
| 423 SkDELETE(newSet); | |
| 424 continue; | |
| 425 } | |
| 426 fFontStyleSets.push_back().reset(newSet); | |
| 427 | |
| 428 for (int j = 0; j < family.fNames.count(); j++) { | |
| 429 NameToFamily* nextEntry = nameToFamily->append(); | |
| 430 SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (family.fNames[ j])); | |
| 431 nextEntry->styleSet = newSet; | |
| 359 } | 432 } |
| 360 } | 433 } |
| 361 } | 434 } |
| 362 | 435 |
| 363 void findDefaultFont() { | 436 void findDefaultFont() { |
| 364 SkASSERT(!fFontStyleSets.empty()); | 437 SkASSERT(!fFontStyleSets.empty()); |
| 365 | 438 |
| 366 static const char* gDefaultNames[] = { "sans-serif" }; | 439 static const char* gDefaultNames[] = { "sans-serif" }; |
| 367 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { | 440 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { |
| 368 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); | 441 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 386 } | 459 } |
| 387 | 460 |
| 388 typedef SkFontMgr INHERITED; | 461 typedef SkFontMgr INHERITED; |
| 389 }; | 462 }; |
| 390 | 463 |
| 391 /////////////////////////////////////////////////////////////////////////////// | 464 /////////////////////////////////////////////////////////////////////////////// |
| 392 | 465 |
| 393 SkFontMgr* SkFontMgr::Factory() { | 466 SkFontMgr* SkFontMgr::Factory() { |
| 394 return SkNEW(SkFontMgr_Android); | 467 return SkNEW(SkFontMgr_Android); |
| 395 } | 468 } |
| OLD | NEW |