| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 private: | 52 private: |
| 53 typedef SkTypeface_FreeType INHERITED; | 53 typedef SkTypeface_FreeType INHERITED; |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 class SkTypeface_AndroidSystem : public SkTypeface_Android { | 56 class SkTypeface_AndroidSystem : public SkTypeface_Android { |
| 57 public: | 57 public: |
| 58 SkTypeface_AndroidSystem(const SkString pathName, | 58 SkTypeface_AndroidSystem(const SkString pathName, |
| 59 int index, | 59 int index, |
| 60 Style style, | 60 Style style, |
| 61 bool isFixedPitch, | 61 bool isFixedPitch, |
| 62 const SkString familyName) | 62 const SkString familyName, |
| 63 const SkLanguage& lang, |
| 64 uint32_t variantStyle) |
| 63 : INHERITED(index, style, isFixedPitch, familyName) | 65 : INHERITED(index, style, isFixedPitch, familyName) |
| 64 , fPathName(pathName) { } | 66 , fPathName(pathName) |
| 67 , fLang(lang) |
| 68 , fVariantStyle(variantStyle) { } |
| 65 | 69 |
| 66 virtual void onGetFontDescriptor(SkFontDescriptor* desc, | 70 virtual void onGetFontDescriptor(SkFontDescriptor* desc, |
| 67 bool* serialize) const SK_OVERRIDE { | 71 bool* serialize) const SK_OVERRIDE { |
| 68 SkASSERT(desc); | 72 SkASSERT(desc); |
| 69 SkASSERT(serialize); | 73 SkASSERT(serialize); |
| 70 desc->setFamilyName(fFamilyName.c_str()); | 74 desc->setFamilyName(fFamilyName.c_str()); |
| 71 desc->setFontFileName(fPathName.c_str()); | 75 desc->setFontFileName(fPathName.c_str()); |
| 72 *serialize = false; | 76 *serialize = false; |
| 73 } | 77 } |
| 74 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { | 78 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { |
| 75 *ttcIndex = fIndex; | 79 *ttcIndex = fIndex; |
| 76 return SkStream::NewFromFile(fPathName.c_str()); | 80 return SkStream::NewFromFile(fPathName.c_str()); |
| 77 } | 81 } |
| 78 | 82 |
| 79 private: | 83 const SkString fPathName; |
| 80 SkString fPathName; | 84 const SkLanguage fLang; |
| 85 const uint32_t fVariantStyle; |
| 81 | 86 |
| 82 typedef SkTypeface_Android INHERITED; | 87 typedef SkTypeface_Android INHERITED; |
| 83 }; | 88 }; |
| 84 | 89 |
| 85 class SkTypeface_AndroidStream : public SkTypeface_Android { | 90 class SkTypeface_AndroidStream : public SkTypeface_Android { |
| 86 public: | 91 public: |
| 87 SkTypeface_AndroidStream(SkStream* stream, | 92 SkTypeface_AndroidStream(SkStream* stream, |
| 88 int index, | 93 int index, |
| 89 Style style, | 94 Style style, |
| 90 bool isFixedPitch, | 95 bool isFixedPitch, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 113 }; | 118 }; |
| 114 | 119 |
| 115 void get_path_for_sys_fonts(SkString* full, const SkString& name) { | 120 void get_path_for_sys_fonts(SkString* full, const SkString& name) { |
| 116 full->set(getenv("ANDROID_ROOT")); | 121 full->set(getenv("ANDROID_ROOT")); |
| 117 full->append(SK_FONT_FILE_PREFIX); | 122 full->append(SK_FONT_FILE_PREFIX); |
| 118 full->append(name); | 123 full->append(name); |
| 119 } | 124 } |
| 120 | 125 |
| 121 class SkFontStyleSet_Android : public SkFontStyleSet { | 126 class SkFontStyleSet_Android : public SkFontStyleSet { |
| 122 public: | 127 public: |
| 123 explicit SkFontStyleSet_Android(FontFamily* family) { | 128 explicit SkFontStyleSet_Android(const FontFamily& family) { |
| 129 const SkString* cannonicalFamilyName = NULL; |
| 130 if (family.fNames.count() > 0) { |
| 131 cannonicalFamilyName = &family.fNames[0]; |
| 132 } |
| 124 // TODO? make this lazy | 133 // TODO? make this lazy |
| 125 for (int i = 0; i < family->fFontFiles.count(); ++i) { | 134 for (int i = 0; i < family.fFontFiles.count(); ++i) { |
| 126 const SkString& fileName = family->fFontFiles[i].fFileName; | 135 const FontFileInfo& fontFile = family.fFontFiles[i]; |
| 127 | 136 |
| 128 SkString pathName; | 137 SkString pathName; |
| 129 get_path_for_sys_fonts(&pathName, fileName); | 138 get_path_for_sys_fonts(&pathName, fontFile.fFileName); |
| 130 | 139 |
| 131 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str()
)); | 140 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str()
)); |
| 132 if (!stream.get()) { | 141 if (!stream.get()) { |
| 133 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, fileN
ame.c_str())); | 142 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathN
ame.c_str())); |
| 134 continue; | 143 continue; |
| 135 } | 144 } |
| 136 | 145 |
| 137 const int ttcIndex = family->fFontFiles[i].fIndex; | 146 const int ttcIndex = fontFile.fIndex; |
| 138 SkString fontName; | 147 SkString familyName; |
| 139 SkTypeface::Style style; | 148 SkTypeface::Style style; |
| 140 bool isFixedWidth; | 149 bool isFixedWidth; |
| 141 if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex, | 150 if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex, |
| 142 &fontName, &style, &isFixedWidth)
) { | 151 &familyName, &style, &isFixedWidt
h)) { |
| 143 DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, fileNam
e.c_str())); | 152 DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, pathNam
e.c_str())); |
| 144 continue; | 153 continue; |
| 145 } | 154 } |
| 146 | 155 |
| 156 const SkLanguage& lang = fontFile.fPaintOptions.getLanguage(); |
| 157 uint32_t variant = fontFile.fPaintOptions.getFontVariant(); |
| 158 if (SkPaintOptionsAndroid::kDefault_Variant == variant) { |
| 159 variant = SkPaintOptionsAndroid::kCompact_Variant | |
| 160 SkPaintOptionsAndroid::kElegant_Variant; |
| 161 } |
| 162 |
| 163 // The first specified family name overrides the family name found i
n the font. |
| 164 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should
return |
| 165 // all of the specified family names in addition to the names found
in the font. |
| 166 if (cannonicalFamilyName != NULL) { |
| 167 familyName = *cannonicalFamilyName; |
| 168 } |
| 169 |
| 147 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, | 170 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, |
| 148 (pathName, ttcIndex, | 171 (pathName, ttcIndex, |
| 149 style, isFixedWidth, fontName)
)); | 172 style, isFixedWidth, familyNam
e, |
| 173 lang, variant))); |
| 150 } | 174 } |
| 151 } | 175 } |
| 152 | 176 |
| 153 virtual int count() SK_OVERRIDE { | 177 virtual int count() SK_OVERRIDE { |
| 154 return fStyles.count(); | 178 return fStyles.count(); |
| 155 } | 179 } |
| 156 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { | 180 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { |
| 157 if (index < 0 || fStyles.count() <= index) { | 181 if (index < 0 || fStyles.count() <= index) { |
| 158 return; | 182 return; |
| 159 } | 183 } |
| 160 if (style) { | 184 if (style) { |
| 161 *style = this->style(index); | 185 *style = this->style(index); |
| 162 } | 186 } |
| 163 if (name) { | 187 if (name) { |
| 164 name->reset(); | 188 name->reset(); |
| 165 } | 189 } |
| 166 } | 190 } |
| 167 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 191 virtual SkTypeface_AndroidSystem* createTypeface(int index) SK_OVERRIDE { |
| 168 if (index < 0 || fStyles.count() <= index) { | 192 if (index < 0 || fStyles.count() <= index) { |
| 169 return NULL; | 193 return NULL; |
| 170 } | 194 } |
| 171 return SkRef(fStyles[index].get()); | 195 return SkRef(fStyles[index].get()); |
| 172 } | 196 } |
| 173 | 197 |
| 174 /** Find the typeface in this style set that most closely matches the given
pattern. | 198 /** Find the typeface in this style set that most closely matches the given
pattern. |
| 175 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); | 199 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); |
| 176 * this simpler version using match_score() passes all our tests. | 200 * this simpler version using match_score() passes all our tests. |
| 177 */ | 201 */ |
| 178 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { | 202 virtual SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) SK_
OVERRIDE { |
| 179 if (0 == fStyles.count()) { | 203 if (0 == fStyles.count()) { |
| 180 return NULL; | 204 return NULL; |
| 181 } | 205 } |
| 182 SkTypeface* closest = fStyles[0]; | 206 SkTypeface_AndroidSystem* closest = fStyles[0]; |
| 183 int minScore = std::numeric_limits<int>::max(); | 207 int minScore = std::numeric_limits<int>::max(); |
| 184 for (int i = 0; i < fStyles.count(); ++i) { | 208 for (int i = 0; i < fStyles.count(); ++i) { |
| 185 SkFontStyle style = this->style(i); | 209 SkFontStyle style = this->style(i); |
| 186 int score = match_score(pattern, style); | 210 int score = match_score(pattern, style); |
| 187 if (score < minScore) { | 211 if (score < minScore) { |
| 188 closest = fStyles[i]; | 212 closest = fStyles[i]; |
| 189 minScore = score; | 213 minScore = score; |
| 190 } | 214 } |
| 191 } | 215 } |
| 192 return SkRef(closest); | 216 return SkRef(closest); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 206 return SkFontStyle::kUpright_Slant; | 230 return SkFontStyle::kUpright_Slant; |
| 207 } | 231 } |
| 208 static int match_score(const SkFontStyle& pattern, const SkFontStyle& candid
ate) { | 232 static int match_score(const SkFontStyle& pattern, const SkFontStyle& candid
ate) { |
| 209 int score = 0; | 233 int score = 0; |
| 210 score += abs((pattern.width() - candidate.width()) * 100); | 234 score += abs((pattern.width() - candidate.width()) * 100); |
| 211 score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000); | 235 score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000); |
| 212 score += abs(pattern.weight() - candidate.weight()); | 236 score += abs(pattern.weight() - candidate.weight()); |
| 213 return score; | 237 return score; |
| 214 } | 238 } |
| 215 | 239 |
| 216 SkTArray<SkAutoTUnref<SkTypeface>, true> fStyles; | 240 SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles; |
| 217 | 241 |
| 218 friend struct NameToFamily; | 242 friend struct NameToFamily; |
| 219 friend class SkFontMgr_Android; | 243 friend class SkFontMgr_Android; |
| 220 | 244 |
| 221 typedef SkFontStyleSet INHERITED; | 245 typedef SkFontStyleSet INHERITED; |
| 222 }; | 246 }; |
| 223 | 247 |
| 224 /** On Android a single family can have many names, but our API assumes unique n
ames. | 248 /** 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 | 249 * Map names to the back end so that all names for a given family refer to the
same |
| 226 * (non-replicated) set of typefaces. | 250 * (non-replicated) set of typefaces. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
RIDE { | 290 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
RIDE { |
| 267 if (!familyName) { | 291 if (!familyName) { |
| 268 return NULL; | 292 return NULL; |
| 269 } | 293 } |
| 270 SkAutoAsciiToLC tolc(familyName); | 294 SkAutoAsciiToLC tolc(familyName); |
| 271 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { | 295 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { |
| 272 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { | 296 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { |
| 273 return SkRef(fNameToFamilyMap[i].styleSet); | 297 return SkRef(fNameToFamilyMap[i].styleSet); |
| 274 } | 298 } |
| 275 } | 299 } |
| 300 // TODO: eventually we should not need to name fallback families. |
| 301 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { |
| 302 if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { |
| 303 return SkRef(fFallbackNameToFamilyMap[i].styleSet); |
| 304 } |
| 305 } |
| 276 return NULL; | 306 return NULL; |
| 277 } | 307 } |
| 278 | 308 |
| 279 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 309 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
| 280 const SkFontStyle& style) const SK_OV
ERRIDE { | 310 const SkFontStyle& style) const SK_OV
ERRIDE { |
| 281 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 311 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); |
| 282 return sset->matchStyle(style); | 312 return sset->matchStyle(style); |
| 283 } | 313 } |
| 284 | 314 |
| 285 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, | 315 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, |
| 286 const SkFontStyle& style) const SK_OVER
RIDE { | 316 const SkFontStyle& style) const SK_OVER
RIDE { |
| 287 for (int i = 0; i < fFontStyleSets.count(); ++i) { | 317 for (int i = 0; i < fFontStyleSets.count(); ++i) { |
| 288 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { | 318 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { |
| 289 if (fFontStyleSets[i]->fStyles[j] == typeface) { | 319 if (fFontStyleSets[i]->fStyles[j] == typeface) { |
| 290 return fFontStyleSets[i]->matchStyle(style); | 320 return fFontStyleSets[i]->matchStyle(style); |
| 291 } | 321 } |
| 292 } | 322 } |
| 293 } | 323 } |
| 294 return NULL; | 324 return NULL; |
| 295 } | 325 } |
| 296 | 326 |
| 327 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
| 328 const SkFontStyle& style, |
| 329 const char bpc47[], |
| 330 uint32_t character) const SK
_OVERRIDE |
| 331 { |
| 332 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. |
| 333 // The variant 'default' means 'compact and elegant'. |
| 334 // As a result, it is not possible to know the variant context from the
font alone. |
| 335 // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. |
| 336 |
| 337 // For compatibility, try 'elegant' fonts first in fallback. |
| 338 uint32_t variantMask = SkPaintOptionsAndroid::kElegant_Variant; |
| 339 |
| 340 // The first time match anything in the mask, second time anything not i
n the mask. |
| 341 for (bool maskMatches = true; maskMatches != false; maskMatches = false)
{ |
| 342 SkLanguage lang(bpc47); |
| 343 // Match against the language, removing a segment each time. |
| 344 // The last time through the loop, the language will be empty. |
| 345 // The empty language is special, and matches all languages. |
| 346 do { |
| 347 const SkString& langTag = lang.getTag(); |
| 348 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { |
| 349 SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i]
.styleSet; |
| 350 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchSty
le(style)); |
| 351 |
| 352 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { |
| 353 continue; |
| 354 } |
| 355 |
| 356 if (SkToBool(face->fVariantStyle & variantMask) != maskMatch
es) { |
| 357 continue; |
| 358 } |
| 359 |
| 360 SkPaint paint; |
| 361 paint.setTypeface(face); |
| 362 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
| 363 |
| 364 uint16_t glyphID; |
| 365 paint.textToGlyphs(&character, sizeof(character), &glyphID); |
| 366 if (glyphID != 0) { |
| 367 return face.detach(); |
| 368 } |
| 369 } |
| 370 } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true)
); |
| 371 } |
| 372 return NULL; |
| 373 } |
| 374 |
| 297 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { | 375 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { |
| 298 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); | 376 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); |
| 299 return this->createFromStream(stream, ttcIndex); | 377 return this->createFromStream(stream, ttcIndex); |
| 300 } | 378 } |
| 301 | 379 |
| 302 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { | 380 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { |
| 303 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 381 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 304 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; | 382 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; |
| 305 } | 383 } |
| 306 | 384 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 418 } |
| 341 | 419 |
| 342 | 420 |
| 343 private: | 421 private: |
| 344 | 422 |
| 345 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; | 423 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; |
| 346 SkFontStyleSet* fDefaultFamily; | 424 SkFontStyleSet* fDefaultFamily; |
| 347 SkTypeface* fDefaultTypeface; | 425 SkTypeface* fDefaultTypeface; |
| 348 | 426 |
| 349 SkTDArray<NameToFamily> fNameToFamilyMap; | 427 SkTDArray<NameToFamily> fNameToFamilyMap; |
| 428 SkTDArray<NameToFamily> fFallbackNameToFamilyMap; |
| 350 | 429 |
| 351 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { | 430 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { |
| 352 for (int i = 0; i < families.count(); i++) { | 431 for (int i = 0; i < families.count(); i++) { |
| 353 fFontStyleSets.push_back().reset( | 432 FontFamily& family = *families[i]; |
| 354 SkNEW_ARGS(SkFontStyleSet_Android, (families[i]))); | 433 |
| 355 for (int j = 0; j < families[i]->fNames.count(); j++) { | 434 SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap; |
| 356 NameToFamily* nextEntry = fNameToFamilyMap.append(); | 435 if (family.fIsFallbackFont) { |
| 357 SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (families[i]->f
Names[j])); | 436 nameToFamily = &fFallbackNameToFamilyMap; |
| 358 nextEntry->styleSet = fFontStyleSets.back().get(); | 437 |
| 438 if (0 == family.fNames.count()) { |
| 439 SkString& fallbackName = family.fNames.push_back(); |
| 440 fallbackName.printf("%.2x##fallback", i); |
| 441 } |
| 442 } |
| 443 |
| 444 SkFontStyleSet_Android* newSet = SkNEW_ARGS(SkFontStyleSet_Android,
(family)); |
| 445 if (0 == newSet->count()) { |
| 446 SkDELETE(newSet); |
| 447 continue; |
| 448 } |
| 449 fFontStyleSets.push_back().reset(newSet); |
| 450 |
| 451 for (int j = 0; j < family.fNames.count(); j++) { |
| 452 NameToFamily* nextEntry = nameToFamily->append(); |
| 453 SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (family.fNames[
j])); |
| 454 nextEntry->styleSet = newSet; |
| 359 } | 455 } |
| 360 } | 456 } |
| 361 } | 457 } |
| 362 | 458 |
| 363 void findDefaultFont() { | 459 void findDefaultFont() { |
| 364 SkASSERT(!fFontStyleSets.empty()); | 460 SkASSERT(!fFontStyleSets.empty()); |
| 365 | 461 |
| 366 static const char* gDefaultNames[] = { "sans-serif" }; | 462 static const char* gDefaultNames[] = { "sans-serif" }; |
| 367 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { | 463 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { |
| 368 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); | 464 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 386 } | 482 } |
| 387 | 483 |
| 388 typedef SkFontMgr INHERITED; | 484 typedef SkFontMgr INHERITED; |
| 389 }; | 485 }; |
| 390 | 486 |
| 391 /////////////////////////////////////////////////////////////////////////////// | 487 /////////////////////////////////////////////////////////////////////////////// |
| 392 | 488 |
| 393 SkFontMgr* SkFontMgr::Factory() { | 489 SkFontMgr* SkFontMgr::Factory() { |
| 394 return SkNEW(SkFontMgr_Android); | 490 return SkNEW(SkFontMgr_Android); |
| 395 } | 491 } |
| OLD | NEW |