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 "SkFixed.h" | 8 #include "SkFixed.h" |
9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
10 #include "SkFontHost_FreeType_common.h" | 10 #include "SkFontHost_FreeType_common.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 private: | 117 private: |
118 const SkAutoTDelete<const SkFontData> fData; | 118 const SkAutoTDelete<const SkFontData> fData; |
119 typedef SkTypeface_Android INHERITED; | 119 typedef SkTypeface_Android INHERITED; |
120 }; | 120 }; |
121 | 121 |
122 class SkFontStyleSet_Android : public SkFontStyleSet { | 122 class SkFontStyleSet_Android : public SkFontStyleSet { |
123 typedef SkTypeface_FreeType::Scanner Scanner; | 123 typedef SkTypeface_FreeType::Scanner Scanner; |
124 | 124 |
125 public: | 125 public: |
126 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& sca
nner) { | 126 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& sca
nner) { |
127 const SkString* cannonicalFamilyName = NULL; | 127 const SkString* cannonicalFamilyName = nullptr; |
128 if (family.fNames.count() > 0) { | 128 if (family.fNames.count() > 0) { |
129 cannonicalFamilyName = &family.fNames[0]; | 129 cannonicalFamilyName = &family.fNames[0]; |
130 } | 130 } |
131 // TODO? make this lazy | 131 // TODO? make this lazy |
132 for (int i = 0; i < family.fFonts.count(); ++i) { | 132 for (int i = 0; i < family.fFonts.count(); ++i) { |
133 const FontFileInfo& fontFile = family.fFonts[i]; | 133 const FontFileInfo& fontFile = family.fFonts[i]; |
134 | 134 |
135 SkString pathName(family.fBasePath); | 135 SkString pathName(family.fBasePath); |
136 pathName.append(fontFile.fFileName); | 136 pathName.append(fontFile.fFileName); |
137 | 137 |
(...skipping 29 matching lines...) Expand all Loading... |
167 | 167 |
168 const SkLanguage& lang = family.fLanguage; | 168 const SkLanguage& lang = family.fLanguage; |
169 uint32_t variant = family.fVariant; | 169 uint32_t variant = family.fVariant; |
170 if (kDefault_FontVariant == variant) { | 170 if (kDefault_FontVariant == variant) { |
171 variant = kCompact_FontVariant | kElegant_FontVariant; | 171 variant = kCompact_FontVariant | kElegant_FontVariant; |
172 } | 172 } |
173 | 173 |
174 // The first specified family name overrides the family name found i
n the font. | 174 // The first specified family name overrides the family name found i
n the font. |
175 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should
return | 175 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should
return |
176 // all of the specified family names in addition to the names found
in the font. | 176 // all of the specified family names in addition to the names found
in the font. |
177 if (cannonicalFamilyName != NULL) { | 177 if (cannonicalFamilyName != nullptr) { |
178 familyName = *cannonicalFamilyName; | 178 familyName = *cannonicalFamilyName; |
179 } | 179 } |
180 | 180 |
181 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); | 181 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); |
182 for (int i = 0; i < axisDefinitions.count(); ++i) { | 182 for (int i = 0; i < axisDefinitions.count(); ++i) { |
183 const Scanner::AxisDefinition& axisDefinition = axisDefinitions[
i]; | 183 const Scanner::AxisDefinition& axisDefinition = axisDefinitions[
i]; |
184 axisValues[i] = axisDefinition.fDefault; | 184 axisValues[i] = axisDefinition.fDefault; |
185 for (int j = 0; j < fontFile.fAxes.count(); ++j) { | 185 for (int j = 0; j < fontFile.fAxes.count(); ++j) { |
186 const FontFileInfo::Axis& axisSpecified = fontFile.fAxes[j]; | 186 const FontFileInfo::Axis& axisSpecified = fontFile.fAxes[j]; |
187 if (axisDefinition.fTag == axisSpecified.fTag) { | 187 if (axisDefinition.fTag == axisSpecified.fTag) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 } | 237 } |
238 if (style) { | 238 if (style) { |
239 *style = this->style(index); | 239 *style = this->style(index); |
240 } | 240 } |
241 if (name) { | 241 if (name) { |
242 name->reset(); | 242 name->reset(); |
243 } | 243 } |
244 } | 244 } |
245 SkTypeface_AndroidSystem* createTypeface(int index) override { | 245 SkTypeface_AndroidSystem* createTypeface(int index) override { |
246 if (index < 0 || fStyles.count() <= index) { | 246 if (index < 0 || fStyles.count() <= index) { |
247 return NULL; | 247 return nullptr; |
248 } | 248 } |
249 return SkRef(fStyles[index].get()); | 249 return SkRef(fStyles[index].get()); |
250 } | 250 } |
251 | 251 |
252 /** Find the typeface in this style set that most closely matches the given
pattern. | 252 /** Find the typeface in this style set that most closely matches the given
pattern. |
253 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); | 253 * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); |
254 * this simpler version using match_score() passes all our tests. | 254 * this simpler version using match_score() passes all our tests. |
255 */ | 255 */ |
256 SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) override { | 256 SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) override { |
257 if (0 == fStyles.count()) { | 257 if (0 == fStyles.count()) { |
258 return NULL; | 258 return nullptr; |
259 } | 259 } |
260 SkTypeface_AndroidSystem* closest = fStyles[0]; | 260 SkTypeface_AndroidSystem* closest = fStyles[0]; |
261 int minScore = std::numeric_limits<int>::max(); | 261 int minScore = std::numeric_limits<int>::max(); |
262 for (int i = 0; i < fStyles.count(); ++i) { | 262 for (int i = 0; i < fStyles.count(); ++i) { |
263 SkFontStyle style = this->style(i); | 263 SkFontStyle style = this->style(i); |
264 int score = match_score(pattern, style); | 264 int score = match_score(pattern, style); |
265 if (score < minScore) { | 265 if (score < minScore) { |
266 closest = fStyles[i]; | 266 closest = fStyles[i]; |
267 minScore = score; | 267 minScore = score; |
268 } | 268 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 void onGetFamilyName(int index, SkString* familyName) const override { | 335 void onGetFamilyName(int index, SkString* familyName) const override { |
336 if (index < 0 || fNameToFamilyMap.count() <= index) { | 336 if (index < 0 || fNameToFamilyMap.count() <= index) { |
337 familyName->reset(); | 337 familyName->reset(); |
338 return; | 338 return; |
339 } | 339 } |
340 familyName->set(fNameToFamilyMap[index].name); | 340 familyName->set(fNameToFamilyMap[index].name); |
341 } | 341 } |
342 | 342 |
343 SkFontStyleSet* onCreateStyleSet(int index) const override { | 343 SkFontStyleSet* onCreateStyleSet(int index) const override { |
344 if (index < 0 || fNameToFamilyMap.count() <= index) { | 344 if (index < 0 || fNameToFamilyMap.count() <= index) { |
345 return NULL; | 345 return nullptr; |
346 } | 346 } |
347 return SkRef(fNameToFamilyMap[index].styleSet); | 347 return SkRef(fNameToFamilyMap[index].styleSet); |
348 } | 348 } |
349 | 349 |
350 SkFontStyleSet* onMatchFamily(const char familyName[]) const override { | 350 SkFontStyleSet* onMatchFamily(const char familyName[]) const override { |
351 if (!familyName) { | 351 if (!familyName) { |
352 return NULL; | 352 return nullptr; |
353 } | 353 } |
354 SkAutoAsciiToLC tolc(familyName); | 354 SkAutoAsciiToLC tolc(familyName); |
355 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { | 355 for (int i = 0; i < fNameToFamilyMap.count(); ++i) { |
356 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { | 356 if (fNameToFamilyMap[i].name.equals(tolc.lc())) { |
357 return SkRef(fNameToFamilyMap[i].styleSet); | 357 return SkRef(fNameToFamilyMap[i].styleSet); |
358 } | 358 } |
359 } | 359 } |
360 // TODO: eventually we should not need to name fallback families. | 360 // TODO: eventually we should not need to name fallback families. |
361 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { | 361 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { |
362 if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { | 362 if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { |
363 return SkRef(fFallbackNameToFamilyMap[i].styleSet); | 363 return SkRef(fFallbackNameToFamilyMap[i].styleSet); |
364 } | 364 } |
365 } | 365 } |
366 return NULL; | 366 return nullptr; |
367 } | 367 } |
368 | 368 |
369 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 369 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
370 const SkFontStyle& style) const overr
ide { | 370 const SkFontStyle& style) const overr
ide { |
371 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 371 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); |
372 return sset->matchStyle(style); | 372 return sset->matchStyle(style); |
373 } | 373 } |
374 | 374 |
375 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, | 375 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, |
376 const SkFontStyle& style) const overrid
e { | 376 const SkFontStyle& style) const overrid
e { |
377 for (int i = 0; i < fFontStyleSets.count(); ++i) { | 377 for (int i = 0; i < fFontStyleSets.count(); ++i) { |
378 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { | 378 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { |
379 if (fFontStyleSets[i]->fStyles[j] == typeface) { | 379 if (fFontStyleSets[i]->fStyles[j] == typeface) { |
380 return fFontStyleSets[i]->matchStyle(style); | 380 return fFontStyleSets[i]->matchStyle(style); |
381 } | 381 } |
382 } | 382 } |
383 } | 383 } |
384 return NULL; | 384 return nullptr; |
385 } | 385 } |
386 | 386 |
387 static SkTypeface_AndroidSystem* find_family_style_character( | 387 static SkTypeface_AndroidSystem* find_family_style_character( |
388 const SkTDArray<NameToFamily>& fallbackNameToFamilyMap, | 388 const SkTDArray<NameToFamily>& fallbackNameToFamilyMap, |
389 const SkFontStyle& style, bool elegant, | 389 const SkFontStyle& style, bool elegant, |
390 const SkString& langTag, SkUnichar character) | 390 const SkString& langTag, SkUnichar character) |
391 { | 391 { |
392 for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) { | 392 for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) { |
393 SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet
; | 393 SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet
; |
394 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style
)); | 394 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style
)); |
395 | 395 |
396 if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c
_str())) { | 396 if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c
_str())) { |
397 continue; | 397 continue; |
398 } | 398 } |
399 | 399 |
400 if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant)
{ | 400 if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant)
{ |
401 continue; | 401 continue; |
402 } | 402 } |
403 | 403 |
404 SkPaint paint; | 404 SkPaint paint; |
405 paint.setTypeface(face); | 405 paint.setTypeface(face); |
406 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); | 406 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
407 | 407 |
408 uint16_t glyphID; | 408 uint16_t glyphID; |
409 paint.textToGlyphs(&character, sizeof(character), &glyphID); | 409 paint.textToGlyphs(&character, sizeof(character), &glyphID); |
410 if (glyphID != 0) { | 410 if (glyphID != 0) { |
411 return face.detach(); | 411 return face.detach(); |
412 } | 412 } |
413 } | 413 } |
414 return NULL; | 414 return nullptr; |
415 } | 415 } |
416 | 416 |
417 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], | 417 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
418 const SkFontStyle& style, | 418 const SkFontStyle& style, |
419 const char* bcp47[], | 419 const char* bcp47[], |
420 int bcp47Count, | 420 int bcp47Count, |
421 SkUnichar character) const o
verride | 421 SkUnichar character) const o
verride |
422 { | 422 { |
423 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. | 423 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. |
424 // The variant 'default' means 'compact and elegant'. | 424 // The variant 'default' means 'compact and elegant'. |
(...skipping 17 matching lines...) Expand all Loading... |
442 } | 442 } |
443 } | 443 } |
444 SkTypeface_AndroidSystem* matchingTypeface = | 444 SkTypeface_AndroidSystem* matchingTypeface = |
445 find_family_style_character(fFallbackNameToFamilyMap, | 445 find_family_style_character(fFallbackNameToFamilyMap, |
446 style, SkToBool(elegant), | 446 style, SkToBool(elegant), |
447 SkString(), character); | 447 SkString(), character); |
448 if (matchingTypeface) { | 448 if (matchingTypeface) { |
449 return matchingTypeface; | 449 return matchingTypeface; |
450 } | 450 } |
451 } | 451 } |
452 return NULL; | 452 return nullptr; |
453 } | 453 } |
454 | 454 |
455 SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { | 455 SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { |
456 return this->createFromStream(new SkMemoryStream(data), ttcIndex); | 456 return this->createFromStream(new SkMemoryStream(data), ttcIndex); |
457 } | 457 } |
458 | 458 |
459 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ | 459 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ |
460 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); | 460 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); |
461 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex)
: NULL; | 461 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex)
: nullptr; |
462 } | 462 } |
463 | 463 |
464 SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons
t override { | 464 SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons
t override { |
465 SkAutoTDelete<SkStreamAsset> stream(bareStream); | 465 SkAutoTDelete<SkStreamAsset> stream(bareStream); |
466 bool isFixedPitch; | 466 bool isFixedPitch; |
467 SkFontStyle style; | 467 SkFontStyle style; |
468 SkString name; | 468 SkString name; |
469 if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch, N
ULL)) { | 469 if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch, n
ullptr)) { |
470 return NULL; | 470 return nullptr; |
471 } | 471 } |
472 SkFontData* data(new SkFontData(stream.detach(), ttcIndex, NULL, 0)); | 472 SkFontData* data(new SkFontData(stream.detach(), ttcIndex, nullptr, 0)); |
473 return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); | 473 return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); |
474 } | 474 } |
475 | 475 |
476 SkTypeface* onCreateFromFontData(SkFontData* data) const override { | 476 SkTypeface* onCreateFromFontData(SkFontData* data) const override { |
477 SkStreamAsset* stream(data->getStream()); | 477 SkStreamAsset* stream(data->getStream()); |
478 bool isFixedPitch; | 478 bool isFixedPitch; |
479 SkFontStyle style; | 479 SkFontStyle style; |
480 SkString name; | 480 SkString name; |
481 if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixed
Pitch, NULL)) { | 481 if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixed
Pitch, nullptr)) { |
482 return NULL; | 482 return nullptr; |
483 } | 483 } |
484 return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); | 484 return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); |
485 } | 485 } |
486 | 486 |
487 | 487 |
488 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 488 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
489 unsigned styleBits) const overrid
e { | 489 unsigned styleBits) const overrid
e { |
490 SkFontStyle style = SkFontStyle(styleBits); | 490 SkFontStyle style = SkFontStyle(styleBits); |
491 | 491 |
492 if (familyName) { | 492 if (familyName) { |
493 // On Android, we must return NULL when we can't find the requested | 493 // On Android, we must return nullptr when we can't find the request
ed |
494 // named typeface so that the system/app can provide their own recov
ery | 494 // named typeface so that the system/app can provide their own recov
ery |
495 // mechanism. On other platforms we'd provide a typeface from the | 495 // mechanism. On other platforms we'd provide a typeface from the |
496 // default family instead. | 496 // default family instead. |
497 return this->onMatchFamilyStyle(familyName, style); | 497 return this->onMatchFamilyStyle(familyName, style); |
498 } | 498 } |
499 return fDefaultFamily->matchStyle(style); | 499 return fDefaultFamily->matchStyle(style); |
500 } | 500 } |
501 | 501 |
502 | 502 |
503 private: | 503 private: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 } | 539 } |
540 } | 540 } |
541 } | 541 } |
542 | 542 |
543 void findDefaultFont() { | 543 void findDefaultFont() { |
544 SkASSERT(!fFontStyleSets.empty()); | 544 SkASSERT(!fFontStyleSets.empty()); |
545 | 545 |
546 static const char* gDefaultNames[] = { "sans-serif" }; | 546 static const char* gDefaultNames[] = { "sans-serif" }; |
547 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { | 547 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { |
548 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); | 548 SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); |
549 if (NULL == set) { | 549 if (nullptr == set) { |
550 continue; | 550 continue; |
551 } | 551 } |
552 SkTypeface* tf = set->matchStyle(SkFontStyle()); | 552 SkTypeface* tf = set->matchStyle(SkFontStyle()); |
553 if (NULL == tf) { | 553 if (nullptr == tf) { |
554 continue; | 554 continue; |
555 } | 555 } |
556 fDefaultFamily = set; | 556 fDefaultFamily = set; |
557 fDefaultTypeface = tf; | 557 fDefaultTypeface = tf; |
558 break; | 558 break; |
559 } | 559 } |
560 if (NULL == fDefaultTypeface) { | 560 if (nullptr == fDefaultTypeface) { |
561 fDefaultFamily = fFontStyleSets[0]; | 561 fDefaultFamily = fFontStyleSets[0]; |
562 fDefaultTypeface = fDefaultFamily->createTypeface(0); | 562 fDefaultTypeface = fDefaultFamily->createTypeface(0); |
563 } | 563 } |
564 SkASSERT(fDefaultFamily); | 564 SkASSERT(fDefaultFamily); |
565 SkASSERT(fDefaultTypeface); | 565 SkASSERT(fDefaultTypeface); |
566 } | 566 } |
567 | 567 |
568 typedef SkFontMgr INHERITED; | 568 typedef SkFontMgr INHERITED; |
569 }; | 569 }; |
570 | 570 |
571 #ifdef SK_DEBUG | 571 #ifdef SK_DEBUG |
572 static char const * const gSystemFontUseStrings[] = { | 572 static char const * const gSystemFontUseStrings[] = { |
573 "OnlyCustom", "PreferCustom", "PreferSystem" | 573 "OnlyCustom", "PreferCustom", "PreferSystem" |
574 }; | 574 }; |
575 #endif | 575 #endif |
576 SkFontMgr* SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) { | 576 SkFontMgr* SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) { |
577 if (custom) { | 577 if (custom) { |
578 SkASSERT(0 <= custom->fSystemFontUse); | 578 SkASSERT(0 <= custom->fSystemFontUse); |
579 SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings))
; | 579 SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings))
; |
580 SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n"
, | 580 SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n"
, |
581 gSystemFontUseStrings[custom->fSystemFontUse], | 581 gSystemFontUseStrings[custom->fSystemFontUse], |
582 custom->fBasePath, | 582 custom->fBasePath, |
583 custom->fFontsXml, | 583 custom->fFontsXml, |
584 custom->fFallbackFontsXml)); | 584 custom->fFallbackFontsXml)); |
585 } | 585 } |
586 | 586 |
587 return new SkFontMgr_Android(custom); | 587 return new SkFontMgr_Android(custom); |
588 } | 588 } |
OLD | NEW |