Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: src/ports/SkFontMgr_android.cpp

Issue 427293003: Implement SkFontMgr_Android::onMatchFamilyStyleCharacter. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments, move mask to parser. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW
« src/ports/SkFontConfigParser_android.cpp ('K') | « src/ports/SkFontConfigParser_android.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698