| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009 Google Inc. | 2 * Copyright 2009 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 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ | 8 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ |
| 9 | 9 |
| 10 #include "SkFontConfigInterfaceDirect.h" |
| 10 #include "SkBuffer.h" | 11 #include "SkBuffer.h" |
| 11 #include "SkDataTable.h" | 12 #include "SkDataTable.h" |
| 12 #include "SkFontConfigInterface.h" | |
| 13 #include "SkFontStyle.h" | 13 #include "SkFontStyle.h" |
| 14 #include "SkMutex.h" | 14 #include "SkMutex.h" |
| 15 #include "SkStream.h" | 15 #include "SkStream.h" |
| 16 #include "SkString.h" | 16 #include "SkString.h" |
| 17 #include "SkTArray.h" | 17 #include "SkTArray.h" |
| 18 #include "SkTDArray.h" | 18 #include "SkTDArray.h" |
| 19 #include "SkTemplates.h" | 19 #include "SkTemplates.h" |
| 20 #include "SkTypeface.h" | 20 #include "SkTypeface.h" |
| 21 #include "SkTypes.h" | 21 #include "SkTypes.h" |
| 22 | 22 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 SkASSERT(iden0 != iden1); | 100 SkASSERT(iden0 != iden1); |
| 101 | 101 |
| 102 make_iden(&iden1); | 102 make_iden(&iden1); |
| 103 SkASSERT(iden0 == iden1); | 103 SkASSERT(iden0 == iden1); |
| 104 | 104 |
| 105 test_writeToMemory(iden0, 0); | 105 test_writeToMemory(iden0, 0); |
| 106 test_writeToMemory(iden0, 0); | 106 test_writeToMemory(iden0, 0); |
| 107 } | 107 } |
| 108 #endif | 108 #endif |
| 109 | 109 |
| 110 class SkFontConfigInterfaceDirect : public SkFontConfigInterface { | |
| 111 public: | |
| 112 SkFontConfigInterfaceDirect(); | |
| 113 virtual ~SkFontConfigInterfaceDirect(); | |
| 114 | |
| 115 virtual bool matchFamilyName(const char familyName[], | |
| 116 SkTypeface::Style requested, | |
| 117 FontIdentity* outFontIdentifier, | |
| 118 SkString* outFamilyName, | |
| 119 SkTypeface::Style* outStyle) override; | |
| 120 SkStreamAsset* openStream(const FontIdentity&) override; | |
| 121 | |
| 122 // new APIs | |
| 123 SkDataTable* getFamilyNames() override; | |
| 124 virtual bool matchFamilySet(const char inFamilyName[], | |
| 125 SkString* outFamilyName, | |
| 126 SkTArray<FontIdentity>*) override; | |
| 127 | |
| 128 private: | |
| 129 SkMutex mutex_; | |
| 130 }; | |
| 131 | |
| 132 SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBase
Mutex* mutex) { | |
| 133 SkAutoMutexAcquire ac(mutex); | |
| 134 static SkFontConfigInterfaceDirect* singleton = nullptr; | |
| 135 if (singleton == nullptr) { | |
| 136 singleton = new SkFontConfigInterfaceDirect; | |
| 137 } | |
| 138 return singleton; | |
| 139 } | |
| 140 | |
| 141 /////////////////////////////////////////////////////////////////////////////// | 110 /////////////////////////////////////////////////////////////////////////////// |
| 142 | 111 |
| 143 // Returns the string from the pattern, or nullptr | 112 // Returns the string from the pattern, or nullptr |
| 144 static const char* get_name(FcPattern* pattern, const char field[], | 113 const char* SkFontConfigInterfaceDirect::GetName(FcPattern* pattern, const char
field[], |
| 145 int index = 0) { | 114 int index) { |
| 146 const char* name; | 115 const char* name; |
| 147 if (FcPatternGetString(pattern, field, index, | 116 if (FcPatternGetString(pattern, field, index, |
| 148 (FcChar8**)&name) != FcResultMatch) { | 117 (FcChar8**)&name) != FcResultMatch) { |
| 149 name = nullptr; | 118 name = nullptr; |
| 150 } | 119 } |
| 151 return name; | 120 return name; |
| 152 } | 121 } |
| 153 | 122 |
| 154 /////////////////////////////////////////////////////////////////////////////// | 123 /////////////////////////////////////////////////////////////////////////////// |
| 155 | 124 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 // basic font names like "Sans", "Serif" or "Monospace". This function | 296 // basic font names like "Sans", "Serif" or "Monospace". This function |
| 328 // tells you whether a given request is for such a fallback. | 297 // tells you whether a given request is for such a fallback. |
| 329 bool IsFallbackFontAllowed(const SkString& family) { | 298 bool IsFallbackFontAllowed(const SkString& family) { |
| 330 const char* family_cstr = family.c_str(); | 299 const char* family_cstr = family.c_str(); |
| 331 return family.isEmpty() || | 300 return family.isEmpty() || |
| 332 strcasecmp(family_cstr, "sans") == 0 || | 301 strcasecmp(family_cstr, "sans") == 0 || |
| 333 strcasecmp(family_cstr, "serif") == 0 || | 302 strcasecmp(family_cstr, "serif") == 0 || |
| 334 strcasecmp(family_cstr, "monospace") == 0; | 303 strcasecmp(family_cstr, "monospace") == 0; |
| 335 } | 304 } |
| 336 | 305 |
| 337 static bool valid_pattern(FcPattern* pattern) { | 306 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. |
| 307 SkTypeface::Style GetFontStyle(FcPattern* font) { |
| 308 int resulting_bold; |
| 309 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) |
| 310 resulting_bold = FC_WEIGHT_NORMAL; |
| 311 |
| 312 int resulting_italic; |
| 313 if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic)) |
| 314 resulting_italic = FC_SLANT_ROMAN; |
| 315 |
| 316 // If we ask for an italic font, fontconfig might take a roman font and set |
| 317 // the undocumented property FC_MATRIX to a skew matrix. It'll then say |
| 318 // that the font is italic or oblique. So, if we see a matrix, we don't |
| 319 // believe that it's italic. |
| 320 FcValue matrix; |
| 321 const bool have_matrix = FcPatternGet(font, FC_MATRIX, 0, &matrix) == 0; |
| 322 |
| 323 // If we ask for an italic font, fontconfig might take a roman font and set |
| 324 // FC_EMBOLDEN. |
| 325 FcValue embolden; |
| 326 const bool have_embolden = FcPatternGet(font, FC_EMBOLDEN, 0, &embolden) ==
0; |
| 327 |
| 328 int styleBits = 0; |
| 329 if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) { |
| 330 styleBits |= SkTypeface::kBold; |
| 331 } |
| 332 if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) { |
| 333 styleBits |= SkTypeface::kItalic; |
| 334 } |
| 335 |
| 336 return (SkTypeface::Style)styleBits; |
| 337 } |
| 338 |
| 339 } // anonymous namespace |
| 340 |
| 341 /////////////////////////////////////////////////////////////////////////////// |
| 342 |
| 343 #define kMaxFontFamilyLength 2048 |
| 344 |
| 345 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { |
| 346 SkAutoMutexAcquire ac(mutex_); |
| 347 |
| 348 FcInit(); |
| 349 |
| 350 SkDEBUGCODE(fontconfiginterface_unittest();) |
| 351 } |
| 352 |
| 353 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { |
| 354 } |
| 355 |
| 356 bool SkFontConfigInterfaceDirect::isValidPattern(FcPattern* pattern) { |
| 338 #ifdef SK_FONT_CONFIG_ONLY_ALLOW_SCALABLE_FONTS | 357 #ifdef SK_FONT_CONFIG_ONLY_ALLOW_SCALABLE_FONTS |
| 339 FcBool is_scalable; | 358 FcBool is_scalable; |
| 340 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch | 359 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch |
| 341 || !is_scalable) { | 360 || !is_scalable) { |
| 342 return false; | 361 return false; |
| 343 } | 362 } |
| 344 #endif | 363 #endif |
| 345 | 364 |
| 346 // fontconfig can also return fonts which are unreadable | 365 // fontconfig can also return fonts which are unreadable |
| 347 const char* c_filename = get_name(pattern, FC_FILE); | 366 const char* c_filename = GetName(pattern, FC_FILE); |
| 348 if (!c_filename) { | 367 if (!c_filename) { |
| 349 return false; | 368 return false; |
| 350 } | 369 } |
| 351 if (access(c_filename, R_OK) != 0) { | 370 if (access(c_filename, R_OK) != 0) { |
| 352 return false; | 371 return false; |
| 353 } | 372 } |
| 373 |
| 354 return true; | 374 return true; |
| 355 } | 375 } |
| 356 | 376 |
| 357 // Find matching font from |font_set| for the given font family. | 377 // Find matching font from |font_set| for the given font family. |
| 358 FcPattern* MatchFont(FcFontSet* font_set, | 378 FcPattern* SkFontConfigInterfaceDirect::MatchFont(FcFontSet* font_set, |
| 359 const char* post_config_family, | 379 const char* post_config_family
, |
| 360 const SkString& family) { | 380 const SkString& family) { |
| 361 // Older versions of fontconfig have a bug where they cannot select | 381 // Older versions of fontconfig have a bug where they cannot select |
| 362 // only scalable fonts so we have to manually filter the results. | 382 // only scalable fonts so we have to manually filter the results. |
| 363 FcPattern* match = nullptr; | 383 FcPattern* match = nullptr; |
| 364 for (int i = 0; i < font_set->nfont; ++i) { | 384 for (int i = 0; i < font_set->nfont; ++i) { |
| 365 FcPattern* current = font_set->fonts[i]; | 385 FcPattern* current = font_set->fonts[i]; |
| 366 if (valid_pattern(current)) { | 386 if (this->isValidPattern(current)) { |
| 367 match = current; | 387 match = current; |
| 368 break; | 388 break; |
| 369 } | 389 } |
| 370 } | 390 } |
| 371 | 391 |
| 372 if (match && !IsFallbackFontAllowed(family)) { | 392 if (match && !IsFallbackFontAllowed(family)) { |
| 373 bool acceptable_substitute = false; | 393 bool acceptable_substitute = false; |
| 374 for (int id = 0; id < 255; ++id) { | 394 for (int id = 0; id < 255; ++id) { |
| 375 const char* post_match_family = get_name(match, FC_FAMILY, id); | 395 const char* post_match_family = GetName(match, FC_FAMILY, id); |
| 376 if (!post_match_family) | 396 if (!post_match_family) |
| 377 break; | 397 break; |
| 378 acceptable_substitute = | 398 acceptable_substitute = |
| 379 (strcasecmp(post_config_family, post_match_family) == 0 || | 399 (strcasecmp(post_config_family, post_match_family) == 0 || |
| 380 // Workaround for Issue 12530: | 400 // Workaround for Issue 12530: |
| 381 // requested family: "Bitstream Vera Sans" | 401 // requested family: "Bitstream Vera Sans" |
| 382 // post_config_family: "Arial" | 402 // post_config_family: "Arial" |
| 383 // post_match_family: "Bitstream Vera Sans" | 403 // post_match_family: "Bitstream Vera Sans" |
| 384 // -> We should treat this case as a good match. | 404 // -> We should treat this case as a good match. |
| 385 strcasecmp(family.c_str(), post_match_family) == 0) || | 405 strcasecmp(family.c_str(), post_match_family) == 0) || |
| 386 IsMetricCompatibleReplacement(family.c_str(), post_match_family); | 406 IsMetricCompatibleReplacement(family.c_str(), post_match_family); |
| 387 if (acceptable_substitute) | 407 if (acceptable_substitute) |
| 388 break; | 408 break; |
| 389 } | 409 } |
| 390 if (!acceptable_substitute) | 410 if (!acceptable_substitute) |
| 391 return nullptr; | 411 return nullptr; |
| 392 } | 412 } |
| 393 | 413 |
| 394 return match; | 414 return match; |
| 395 } | 415 } |
| 396 | 416 |
| 397 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. | |
| 398 SkTypeface::Style GetFontStyle(FcPattern* font) { | |
| 399 int resulting_bold; | |
| 400 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) | |
| 401 resulting_bold = FC_WEIGHT_NORMAL; | |
| 402 | |
| 403 int resulting_italic; | |
| 404 if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic)) | |
| 405 resulting_italic = FC_SLANT_ROMAN; | |
| 406 | |
| 407 // If we ask for an italic font, fontconfig might take a roman font and set | |
| 408 // the undocumented property FC_MATRIX to a skew matrix. It'll then say | |
| 409 // that the font is italic or oblique. So, if we see a matrix, we don't | |
| 410 // believe that it's italic. | |
| 411 FcValue matrix; | |
| 412 const bool have_matrix = FcPatternGet(font, FC_MATRIX, 0, &matrix) == 0; | |
| 413 | |
| 414 // If we ask for an italic font, fontconfig might take a roman font and set | |
| 415 // FC_EMBOLDEN. | |
| 416 FcValue embolden; | |
| 417 const bool have_embolden = FcPatternGet(font, FC_EMBOLDEN, 0, &embolden) ==
0; | |
| 418 | |
| 419 int styleBits = 0; | |
| 420 if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) { | |
| 421 styleBits |= SkTypeface::kBold; | |
| 422 } | |
| 423 if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) { | |
| 424 styleBits |= SkTypeface::kItalic; | |
| 425 } | |
| 426 | |
| 427 return (SkTypeface::Style)styleBits; | |
| 428 } | |
| 429 | |
| 430 } // anonymous namespace | |
| 431 | |
| 432 /////////////////////////////////////////////////////////////////////////////// | |
| 433 | |
| 434 #define kMaxFontFamilyLength 2048 | |
| 435 | |
| 436 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { | |
| 437 SkAutoMutexAcquire ac(mutex_); | |
| 438 | |
| 439 FcInit(); | |
| 440 | |
| 441 SkDEBUGCODE(fontconfiginterface_unittest();) | |
| 442 } | |
| 443 | |
| 444 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { | |
| 445 } | |
| 446 | |
| 447 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], | 417 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], |
| 448 SkTypeface::Style style, | 418 SkTypeface::Style style, |
| 449 FontIdentity* outIdentity, | 419 FontIdentity* outIdentity, |
| 450 SkString* outFamilyName, | 420 SkString* outFamilyName, |
| 451 SkTypeface::Style* outStyle) { | 421 SkTypeface::Style* outStyle) { |
| 452 SkString familyStr(familyName ? familyName : ""); | 422 SkString familyStr(familyName ? familyName : ""); |
| 453 if (familyStr.size() > kMaxFontFamilyLength) { | 423 if (familyStr.size() > kMaxFontFamilyLength) { |
| 454 return false; | 424 return false; |
| 455 } | 425 } |
| 456 | 426 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 // -> good match | 464 // -> good match |
| 495 // | 465 // |
| 496 // and for a missing font: | 466 // and for a missing font: |
| 497 // requested family: "Monaco" | 467 // requested family: "Monaco" |
| 498 // post_config_family: "Monaco" | 468 // post_config_family: "Monaco" |
| 499 // post_match_family: "Times New Roman" | 469 // post_match_family: "Times New Roman" |
| 500 // -> BAD match | 470 // -> BAD match |
| 501 // | 471 // |
| 502 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). | 472 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). |
| 503 | 473 |
| 504 const char* post_config_family = get_name(pattern, FC_FAMILY); | 474 const char* post_config_family = GetName(pattern, FC_FAMILY); |
| 505 if (!post_config_family) { | 475 if (!post_config_family) { |
| 506 // we can just continue with an empty name, e.g. default font | 476 // we can just continue with an empty name, e.g. default font |
| 507 post_config_family = ""; | 477 post_config_family = ""; |
| 508 } | 478 } |
| 509 | 479 |
| 510 FcResult result; | 480 FcResult result; |
| 511 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); | 481 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); |
| 512 if (!font_set) { | 482 if (!font_set) { |
| 513 FcPatternDestroy(pattern); | 483 FcPatternDestroy(pattern); |
| 514 return false; | 484 return false; |
| 515 } | 485 } |
| 516 | 486 |
| 517 FcPattern* match = MatchFont(font_set, post_config_family, familyStr); | 487 FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); |
| 518 if (!match) { | 488 if (!match) { |
| 519 FcPatternDestroy(pattern); | 489 FcPatternDestroy(pattern); |
| 520 FcFontSetDestroy(font_set); | 490 FcFontSetDestroy(font_set); |
| 521 return false; | 491 return false; |
| 522 } | 492 } |
| 523 | 493 |
| 524 FcPatternDestroy(pattern); | 494 FcPatternDestroy(pattern); |
| 525 | 495 |
| 526 // From here out we just extract our results from 'match' | 496 // From here out we just extract our results from 'match' |
| 527 | 497 |
| 528 post_config_family = get_name(match, FC_FAMILY); | 498 post_config_family = GetName(match, FC_FAMILY); |
| 529 if (!post_config_family) { | 499 if (!post_config_family) { |
| 530 FcFontSetDestroy(font_set); | 500 FcFontSetDestroy(font_set); |
| 531 return false; | 501 return false; |
| 532 } | 502 } |
| 533 | 503 |
| 534 const char* c_filename = get_name(match, FC_FILE); | 504 const char* c_filename = GetName(match, FC_FILE); |
| 535 if (!c_filename) { | 505 if (!c_filename) { |
| 536 FcFontSetDestroy(font_set); | 506 FcFontSetDestroy(font_set); |
| 537 return false; | 507 return false; |
| 538 } | 508 } |
| 539 | 509 |
| 540 int face_index; | 510 int face_index; |
| 541 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { | 511 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { |
| 542 FcFontSetDestroy(font_set); | 512 FcFontSetDestroy(font_set); |
| 543 return false; | 513 return false; |
| 544 } | 514 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 FcFontSet* fs = FcFontList(nullptr, pat, os); | 562 FcFontSet* fs = FcFontList(nullptr, pat, os); |
| 593 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); | 563 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); |
| 594 if (nullptr == fs) { | 564 if (nullptr == fs) { |
| 595 return nullptr; | 565 return nullptr; |
| 596 } | 566 } |
| 597 | 567 |
| 598 SkTDArray<const char*> names; | 568 SkTDArray<const char*> names; |
| 599 SkTDArray<size_t> sizes; | 569 SkTDArray<size_t> sizes; |
| 600 for (int i = 0; i < fs->nfont; ++i) { | 570 for (int i = 0; i < fs->nfont; ++i) { |
| 601 FcPattern* match = fs->fonts[i]; | 571 FcPattern* match = fs->fonts[i]; |
| 602 const char* famName = get_name(match, FC_FAMILY); | 572 const char* famName = GetName(match, FC_FAMILY); |
| 603 if (famName && !find_name(names, famName)) { | 573 if (famName && !find_name(names, famName)) { |
| 604 *names.append() = famName; | 574 *names.append() = famName; |
| 605 *sizes.append() = strlen(famName) + 1; | 575 *sizes.append() = strlen(famName) + 1; |
| 606 } | 576 } |
| 607 } | 577 } |
| 608 | 578 |
| 609 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), | 579 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), |
| 610 sizes.begin(), names.count()); | 580 sizes.begin(), names.count()); |
| 611 } | 581 } |
| 612 | 582 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 // -> good match | 625 // -> good match |
| 656 // | 626 // |
| 657 // and for a missing font: | 627 // and for a missing font: |
| 658 // requested family: "Monaco" | 628 // requested family: "Monaco" |
| 659 // post_config_family: "Monaco" | 629 // post_config_family: "Monaco" |
| 660 // post_match_family: "Times New Roman" | 630 // post_match_family: "Times New Roman" |
| 661 // -> BAD match | 631 // -> BAD match |
| 662 // | 632 // |
| 663 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). | 633 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). |
| 664 | 634 |
| 665 const char* post_config_family = get_name(pattern, FC_FAMILY); | 635 const char* post_config_family = GetName(pattern, FC_FAMILY); |
| 666 | 636 |
| 667 FcResult result; | 637 FcResult result; |
| 668 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); | 638 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); |
| 669 if (!font_set) { | 639 if (!font_set) { |
| 670 FcPatternDestroy(pattern); | 640 FcPatternDestroy(pattern); |
| 671 return false; | 641 return false; |
| 672 } | 642 } |
| 673 | 643 |
| 674 FcPattern* match = MatchFont(font_set, post_config_family, familyStr); | 644 FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); |
| 675 if (!match) { | 645 if (!match) { |
| 676 FcPatternDestroy(pattern); | 646 FcPatternDestroy(pattern); |
| 677 FcFontSetDestroy(font_set); | 647 FcFontSetDestroy(font_set); |
| 678 return false; | 648 return false; |
| 679 } | 649 } |
| 680 | 650 |
| 681 FcPatternDestroy(pattern); | 651 FcPatternDestroy(pattern); |
| 682 | 652 |
| 683 // From here out we just extract our results from 'match' | 653 // From here out we just extract our results from 'match' |
| 684 | 654 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 709 outFamilyName->set((const char*)post_config_family); | 679 outFamilyName->set((const char*)post_config_family); |
| 710 } | 680 } |
| 711 if (outStyle) { | 681 if (outStyle) { |
| 712 *outStyle = GetFontStyle(match); | 682 *outStyle = GetFontStyle(match); |
| 713 } | 683 } |
| 714 return true; | 684 return true; |
| 715 | 685 |
| 716 //////////////////// | 686 //////////////////// |
| 717 | 687 |
| 718 int count; | 688 int count; |
| 719 FcPattern** match = MatchFont(font_set, post_config_family, &count); | 689 FcPattern** match = this->MatchFont(font_set, post_config_family, &count
); |
| 720 if (!match) { | 690 if (!match) { |
| 721 FcPatternDestroy(pattern); | 691 FcPatternDestroy(pattern); |
| 722 FcFontSetDestroy(font_set); | 692 FcFontSetDestroy(font_set); |
| 723 return nullptr; | 693 return nullptr; |
| 724 } | 694 } |
| 725 | 695 |
| 726 FcPatternDestroy(pattern); | 696 FcPatternDestroy(pattern); |
| 727 | 697 |
| 728 SkTDArray<FcPattern*> trimmedMatches; | 698 SkTDArray<FcPattern*> trimmedMatches; |
| 729 for (int i = 0; i < count; ++i) { | 699 for (int i = 0; i < count; ++i) { |
| 730 const char* justName = find_just_name(get_name(match[i], FC_FILE)); | 700 const char* justName = find_just_name(GetName(match[i], FC_FILE)); |
| 731 if (!is_lower(*justName)) { | 701 if (!is_lower(*justName)) { |
| 732 *trimmedMatches.append() = match[i]; | 702 *trimmedMatches.append() = match[i]; |
| 733 } | 703 } |
| 734 } | 704 } |
| 735 | 705 |
| 736 SkFontStyleSet_FC* sset = new SkFontStyleSet_FC
(trimmedMatches.begin(),
trimmedMatches.count()); | 706 SkFontStyleSet_FC* sset = new SkFontStyleSet_FC
(trimmedMatches.begin(),
trimmedMatches.count()); |
| 737 #endif | 707 #endif |
| 738 return false; | 708 return false; |
| 739 } | 709 } |
| OLD | NEW |