| 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 <string> | 10 #include <string> |
| 11 #include <unistd.h> | 11 #include <unistd.h> |
| 12 #include <fcntl.h> | 12 #include <fcntl.h> |
| 13 | 13 |
| 14 #include <fontconfig/fontconfig.h> | 14 #include <fontconfig/fontconfig.h> |
| 15 | 15 |
| 16 #include "SkBuffer.h" |
| 16 #include "SkFontConfigInterface.h" | 17 #include "SkFontConfigInterface.h" |
| 17 #include "SkStream.h" | 18 #include "SkStream.h" |
| 18 | 19 |
| 20 size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const { |
| 21 size_t size = sizeof(fID) + sizeof(fTTCIndex); |
| 22 size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, widt
h, italic |
| 23 size += sizeof(int32_t) + fString.size(); // store length+data |
| 24 if (addr) { |
| 25 SkWBuffer buffer(addr, size); |
| 26 |
| 27 buffer.write32(fID); |
| 28 buffer.write32(fTTCIndex); |
| 29 buffer.write32(fString.size()); |
| 30 buffer.write32(fStyle.weight()); |
| 31 buffer.write32(fStyle.width()); |
| 32 buffer.write8(fStyle.slant()); |
| 33 buffer.write(fString.c_str(), fString.size()); |
| 34 buffer.padToAlign4(); |
| 35 |
| 36 SkASSERT(buffer.pos() == size); |
| 37 } |
| 38 return size; |
| 39 } |
| 40 |
| 41 size_t SkFontConfigInterface::FontIdentity::readFromMemory(const void* addr, |
| 42 size_t size) { |
| 43 SkRBuffer buffer(addr, size); |
| 44 |
| 45 fID = buffer.readU32(); |
| 46 fTTCIndex = buffer.readU32(); |
| 47 size_t strLen = buffer.readU32(); |
| 48 int weight = buffer.readU32(); |
| 49 int width = buffer.readU32(); |
| 50 SkFontStyle::Slant slant = (SkFontStyle::Slant)buffer.readU8(); |
| 51 fStyle = SkFontStyle(weight, width, slant); |
| 52 fString.resize(strLen); |
| 53 buffer.read(fString.writable_str(), strLen); |
| 54 buffer.skipToAlign4(); |
| 55 |
| 56 return buffer.pos(); // the actual number of bytes read |
| 57 } |
| 58 |
| 59 #ifdef SK_DEBUG |
| 60 static void make_iden(SkFontConfigInterface::FontIdentity* iden) { |
| 61 iden->fID = 10; |
| 62 iden->fTTCIndex = 2; |
| 63 iden->fString.set("Hello world"); |
| 64 iden->fStyle = SkFontStyle(300, 6, SkFontStyle::kItalic_Slant); |
| 65 } |
| 66 |
| 67 static void test_writeToMemory(const SkFontConfigInterface::FontIdentity& iden0, |
| 68 int initValue) { |
| 69 SkFontConfigInterface::FontIdentity iden1; |
| 70 |
| 71 size_t size0 = iden0.writeToMemory(NULL); |
| 72 |
| 73 SkAutoMalloc storage(size0); |
| 74 memset(storage.get(), initValue, size0); |
| 75 |
| 76 size_t size1 = iden0.writeToMemory(storage.get()); |
| 77 SkASSERT(size0 == size1); |
| 78 |
| 79 SkASSERT(iden0 != iden1); |
| 80 size_t size2 = iden1.readFromMemory(storage.get(), size1); |
| 81 SkASSERT(size2 == size1); |
| 82 SkASSERT(iden0 == iden1); |
| 83 } |
| 84 |
| 85 static void fontconfiginterface_unittest() { |
| 86 SkFontConfigInterface::FontIdentity iden0, iden1; |
| 87 |
| 88 SkASSERT(iden0 == iden1); |
| 89 |
| 90 make_iden(&iden0); |
| 91 SkASSERT(iden0 != iden1); |
| 92 |
| 93 make_iden(&iden1); |
| 94 SkASSERT(iden0 == iden1); |
| 95 |
| 96 test_writeToMemory(iden0, 0); |
| 97 test_writeToMemory(iden0, 0); |
| 98 } |
| 99 #endif |
| 100 |
| 19 class SkFontConfigInterfaceDirect : public SkFontConfigInterface { | 101 class SkFontConfigInterfaceDirect : public SkFontConfigInterface { |
| 20 public: | 102 public: |
| 21 SkFontConfigInterfaceDirect(); | 103 SkFontConfigInterfaceDirect(); |
| 22 virtual ~SkFontConfigInterfaceDirect(); | 104 virtual ~SkFontConfigInterfaceDirect(); |
| 23 | 105 |
| 24 virtual bool matchFamilyName(const char familyName[], | 106 virtual bool matchFamilyName(const char familyName[], |
| 25 SkTypeface::Style requested, | 107 SkTypeface::Style requested, |
| 26 FontIdentity* outFontIdentifier, | 108 FontIdentity* outFontIdentifier, |
| 27 SkString* outFamilyName, | 109 SkString* outFamilyName, |
| 28 SkTypeface::Style* outStyle) SK_OVERRIDE; | 110 SkTypeface::Style* outStyle) SK_OVERRIDE; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 44 static SkMutex gMutex; | 126 static SkMutex gMutex; |
| 45 SkAutoMutexAcquire ac(gMutex); | 127 SkAutoMutexAcquire ac(gMutex); |
| 46 | 128 |
| 47 if (NULL == gDirect) { | 129 if (NULL == gDirect) { |
| 48 gDirect = new SkFontConfigInterfaceDirect; | 130 gDirect = new SkFontConfigInterfaceDirect; |
| 49 } | 131 } |
| 50 } | 132 } |
| 51 return gDirect; | 133 return gDirect; |
| 52 } | 134 } |
| 53 | 135 |
| 54 #if 0 | |
| 55 int SkFontConfigInterface::countFamilies() { return 0; } | |
| 56 | |
| 57 int SkFontConfigInterface::getFamilySet(int index, SkString* outFamilyName, | |
| 58 FontIdentity outIdentities[], | |
| 59 int maxCount) { | |
| 60 return 0; | |
| 61 } | |
| 62 | |
| 63 int SkFontConfigInterface::matchFamilySet(const char familyName[], | |
| 64 SkString* outFamilyName, | |
| 65 FontIdentity outIdentities[], | |
| 66 int maxCount) { | |
| 67 return 0; | |
| 68 } | |
| 69 #endif | |
| 70 | |
| 71 /////////////////////////////////////////////////////////////////////////////// | 136 /////////////////////////////////////////////////////////////////////////////// |
| 72 | 137 |
| 73 // Returns the string from the pattern, or NULL | 138 // Returns the string from the pattern, or NULL |
| 74 static const char* get_name(FcPattern* pattern, const char field[], | 139 static const char* get_name(FcPattern* pattern, const char field[], |
| 75 int index = 0) { | 140 int index = 0) { |
| 76 const char* name; | 141 const char* name; |
| 77 if (FcPatternGetString(pattern, field, index, | 142 if (FcPatternGetString(pattern, field, index, |
| 78 (FcChar8**)&name) != FcResultMatch) { | 143 (FcChar8**)&name) != FcResultMatch) { |
| 79 name = NULL; | 144 name = NULL; |
| 80 } | 145 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 return (SkTypeface::Style)styleBits; | 412 return (SkTypeface::Style)styleBits; |
| 348 } | 413 } |
| 349 | 414 |
| 350 } // anonymous namespace | 415 } // anonymous namespace |
| 351 | 416 |
| 352 /////////////////////////////////////////////////////////////////////////////// | 417 /////////////////////////////////////////////////////////////////////////////// |
| 353 | 418 |
| 354 #define kMaxFontFamilyLength 2048 | 419 #define kMaxFontFamilyLength 2048 |
| 355 | 420 |
| 356 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { | 421 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { |
| 422 SkAutoMutexAcquire ac(mutex_); |
| 423 |
| 357 FcInit(); | 424 FcInit(); |
| 425 |
| 426 SkDEBUGCODE(fontconfiginterface_unittest();) |
| 358 } | 427 } |
| 359 | 428 |
| 360 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { | 429 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { |
| 361 } | 430 } |
| 362 | 431 |
| 363 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], | 432 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], |
| 364 SkTypeface::Style style, | 433 SkTypeface::Style style, |
| 365 FontIdentity* outIdentity, | 434 FontIdentity* outIdentity, |
| 366 SkString* outFamilyName, | 435 SkString* outFamilyName, |
| 367 SkTypeface::Style* outStyle) { | 436 SkTypeface::Style* outStyle) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 int count = list.count(); | 552 int count = list.count(); |
| 484 for (int i = 0; i < count; ++i) { | 553 for (int i = 0; i < count; ++i) { |
| 485 if (!strcmp(list[i], str)) { | 554 if (!strcmp(list[i], str)) { |
| 486 return true; | 555 return true; |
| 487 } | 556 } |
| 488 } | 557 } |
| 489 return false; | 558 return false; |
| 490 } | 559 } |
| 491 | 560 |
| 492 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { | 561 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { |
| 562 SkAutoMutexAcquire ac(mutex_); |
| 563 |
| 493 FcPattern* pat = FcPatternCreate(); | 564 FcPattern* pat = FcPatternCreate(); |
| 494 FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0); | 565 FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0); |
| 495 if (NULL == os) { | 566 if (NULL == os) { |
| 496 return NULL; | 567 return NULL; |
| 497 } | 568 } |
| 498 FcFontSet* fs = FcFontList(NULL, pat, os); | 569 FcFontSet* fs = FcFontList(NULL, pat, os); |
| 499 if (NULL == fs) { | 570 if (NULL == fs) { |
| 500 FcObjectSetDestroy(os); | 571 FcObjectSetDestroy(os); |
| 501 return NULL; | 572 return NULL; |
| 502 } | 573 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 516 FcObjectSetDestroy(os); | 587 FcObjectSetDestroy(os); |
| 517 FcPatternDestroy(pat); | 588 FcPatternDestroy(pat); |
| 518 | 589 |
| 519 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), | 590 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), |
| 520 sizes.begin(), names.count()); | 591 sizes.begin(), names.count()); |
| 521 } | 592 } |
| 522 | 593 |
| 523 bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], | 594 bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], |
| 524 SkString* outFamilyName, | 595 SkString* outFamilyName, |
| 525 SkTArray<FontIdentity>* ids) { | 596 SkTArray<FontIdentity>* ids) { |
| 597 SkAutoMutexAcquire ac(mutex_); |
| 598 |
| 599 #if 0 |
| 600 std::string familyStr(familyName ? familyName : ""); |
| 601 if (familyStr.length() > kMaxFontFamilyLength) { |
| 602 return false; |
| 603 } |
| 604 |
| 605 SkAutoMutexAcquire ac(mutex_); |
| 606 |
| 607 FcPattern* pattern = FcPatternCreate(); |
| 608 |
| 609 if (familyName) { |
| 610 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| 611 } |
| 612 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); |
| 613 |
| 614 FcConfigSubstitute(NULL, pattern, FcMatchPattern); |
| 615 FcDefaultSubstitute(pattern); |
| 616 |
| 617 // Font matching: |
| 618 // CSS often specifies a fallback list of families: |
| 619 // font-family: a, b, c, serif; |
| 620 // However, fontconfig will always do its best to find *a* font when asked |
| 621 // for something so we need a way to tell if the match which it has found is |
| 622 // "good enough" for us. Otherwise, we can return NULL which gets piped up |
| 623 // and lets WebKit know to try the next CSS family name. However, fontconfig |
| 624 // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we |
| 625 // wish to support that. |
| 626 // |
| 627 // Thus, if a specific family is requested we set @family_requested. Then we |
| 628 // record two strings: the family name after config processing and the |
| 629 // family name after resolving. If the two are equal, it's a good match. |
| 630 // |
| 631 // So consider the case where a user has mapped Arial to Helvetica in their |
| 632 // config. |
| 633 // requested family: "Arial" |
| 634 // post_config_family: "Helvetica" |
| 635 // post_match_family: "Helvetica" |
| 636 // -> good match |
| 637 // |
| 638 // and for a missing font: |
| 639 // requested family: "Monaco" |
| 640 // post_config_family: "Monaco" |
| 641 // post_match_family: "Times New Roman" |
| 642 // -> BAD match |
| 643 // |
| 644 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). |
| 645 |
| 646 const char* post_config_family = get_name(pattern, FC_FAMILY); |
| 647 |
| 648 FcResult result; |
| 649 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); |
| 650 if (!font_set) { |
| 651 FcPatternDestroy(pattern); |
| 652 return false; |
| 653 } |
| 654 |
| 655 FcPattern* match = MatchFont(font_set, post_config_family, familyStr); |
| 656 if (!match) { |
| 657 FcPatternDestroy(pattern); |
| 658 FcFontSetDestroy(font_set); |
| 659 return false; |
| 660 } |
| 661 |
| 662 FcPatternDestroy(pattern); |
| 663 |
| 664 // From here out we just extract our results from 'match' |
| 665 |
| 666 if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResult
Match) { |
| 667 FcFontSetDestroy(font_set); |
| 668 return false; |
| 669 } |
| 670 |
| 671 FcChar8* c_filename; |
| 672 if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) { |
| 673 FcFontSetDestroy(font_set); |
| 674 return false; |
| 675 } |
| 676 |
| 677 int face_index; |
| 678 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { |
| 679 FcFontSetDestroy(font_set); |
| 680 return false; |
| 681 } |
| 682 |
| 683 FcFontSetDestroy(font_set); |
| 684 |
| 685 if (outIdentity) { |
| 686 outIdentity->fTTCIndex = face_index; |
| 687 outIdentity->fString.set((const char*)c_filename); |
| 688 } |
| 689 if (outFamilyName) { |
| 690 outFamilyName->set((const char*)post_config_family); |
| 691 } |
| 692 if (outStyle) { |
| 693 *outStyle = GetFontStyle(match); |
| 694 } |
| 695 return true; |
| 696 |
| 697 //////////////////// |
| 698 |
| 699 int count; |
| 700 FcPattern** match = MatchFont(font_set, post_config_family, &count); |
| 701 if (!match) { |
| 702 FcPatternDestroy(pattern); |
| 703 FcFontSetDestroy(font_set); |
| 704 return NULL; |
| 705 } |
| 706 |
| 707 FcPatternDestroy(pattern); |
| 708 |
| 709 SkTDArray<FcPattern*> trimmedMatches; |
| 710 for (int i = 0; i < count; ++i) { |
| 711 const char* justName = find_just_name(get_name(match[i], FC_FILE)); |
| 712 if (!is_lower(*justName)) { |
| 713 *trimmedMatches.append() = match[i]; |
| 714 } |
| 715 } |
| 716 |
| 717 SkFontStyleSet_FC* sset = SkNEW_ARGS(SkFontStyleSet_FC, |
| 718 (trimmedMatches.begin(), |
| 719 trimmedMatches.count())); |
| 720 #endif |
| 526 return false; | 721 return false; |
| 527 } | 722 } |
| 723 |
| OLD | NEW |