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

Side by Side Diff: trunk/src/ports/SkFontConfigInterface_direct.cpp

Issue 14305007: check-point for linux fontmgr impl (Closed) Base URL: http://skia.googlecode.com/svn/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « trunk/include/ports/SkFontStyle.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « trunk/include/ports/SkFontStyle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698