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 "SkDataTable.h" | 8 #include "SkDataTable.h" |
9 #include "SkFontMgr.h" | 9 #include "SkFontMgr.h" |
10 #include "SkFontMgr_indirect.h" | 10 #include "SkFontMgr_indirect.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 SkTypeface* createTypeface(int index) override { | 45 SkTypeface* createTypeface(int index) override { |
46 return fOwner->createTypefaceFromFontId(fData->at(index)); | 46 return fOwner->createTypefaceFromFontId(fData->at(index)); |
47 } | 47 } |
48 | 48 |
49 SkTypeface* matchStyle(const SkFontStyle& pattern) override { | 49 SkTypeface* matchStyle(const SkFontStyle& pattern) override { |
50 if (fFamilyIndex >= 0) { | 50 if (fFamilyIndex >= 0) { |
51 SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pa
ttern); | 51 SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pa
ttern); |
52 return fOwner->createTypefaceFromFontId(id); | 52 return fOwner->createTypefaceFromFontId(id); |
53 } | 53 } |
54 | 54 |
55 // If this SkStyleSet was created via onMatchFamily we would need a call
like | 55 return this->matchStyleCSS3(pattern); |
56 // fOwner->fProxy->matchNameStyle(fFamilyName, pattern); | |
57 // but would not activate fonts (only consider fonts which would come ba
ck from matchName). | |
58 | |
59 // CSS policy sounds good. | |
60 struct Score { | |
61 int score; | |
62 int index; | |
63 }; | |
64 | |
65 // Width has the greatest priority. | |
66 // If the value of pattern.width is 5 (normal) or less, | |
67 // narrower width values are checked first, then wider values. | |
68 // If the value of pattern.width is greater than 5 (normal), | |
69 // wider values are checked first, followed by narrower values. | |
70 | |
71 // Italic/Oblique has the next highest priority. | |
72 // If italic requested and there is some italic font, use it. | |
73 // If oblique requested and there is some oblique font, use it. | |
74 // If italic requested and there is some oblique font, use it. | |
75 // If oblique requested and there is some italic font, use it. | |
76 | |
77 // Exact match. | |
78 // If pattern.weight < 400, weights below pattern.weight are checked | |
79 // in descending order followed by weights above pattern.weight | |
80 // in ascending order until a match is found. | |
81 // If pattern.weight > 500, weights above pattern.weight are checked | |
82 // in ascending order followed by weights below pattern.weight | |
83 // in descending order until a match is found. | |
84 // If pattern.weight is 400, 500 is checked first | |
85 // and then the rule for pattern.weight < 400 is used. | |
86 // If pattern.weight is 500, 400 is checked first | |
87 // and then the rule for pattern.weight < 400 is used | |
88 | |
89 Score maxScore = { 0, 0 }; | |
90 for (int i = 0; i < fData->count(); ++i) { | |
91 const SkFontStyle& current = fData->at(i).fFontStyle; | |
92 Score currentScore = { 0, i }; | |
93 | |
94 // CSS stretch. (This is the width.) | |
95 // This has the highest priority. | |
96 if (pattern.width() <= SkFontStyle::kNormal_Width) { | |
97 if (current.width() <= pattern.width()) { | |
98 currentScore.score += 10 - pattern.width() + current.width()
; | |
99 } else { | |
100 currentScore.score += 10 - current.width(); | |
101 } | |
102 } else { | |
103 if (current.width() > pattern.width()) { | |
104 currentScore.score += 10 + pattern.width() - current.width()
; | |
105 } else { | |
106 currentScore.score += current.width(); | |
107 } | |
108 } | |
109 currentScore.score *= 1002; | |
110 | |
111 // CSS style (italic/oblique) | |
112 // Being italic trumps all valid weights which are not italic. | |
113 // Note that newer specs differentiate between italic and oblique. | |
114 if (pattern.isItalic() && current.isItalic()) { | |
115 currentScore.score += 1001; | |
116 } | |
117 | |
118 // Synthetics (weight/style) [no stretch synthetic?] | |
119 | |
120 // The 'closer' to the target weight, the higher the score. | |
121 // 1000 is the 'heaviest' recognized weight | |
122 if (pattern.weight() == current.weight()) { | |
123 currentScore.score += 1000; | |
124 } else if (pattern.weight() <= 500) { | |
125 if (pattern.weight() >= 400 && pattern.weight() < 450) { | |
126 if (current.weight() >= 450 && current.weight() <= 500) { | |
127 // Artificially boost the 500 weight. | |
128 // TODO: determine correct number to use. | |
129 currentScore.score += 500; | |
130 } | |
131 } | |
132 if (current.weight() <= pattern.weight()) { | |
133 currentScore.score += 1000 - pattern.weight() + current.weig
ht(); | |
134 } else { | |
135 currentScore.score += 1000 - current.weight(); | |
136 } | |
137 } else if (pattern.weight() > 500) { | |
138 if (current.weight() > pattern.weight()) { | |
139 currentScore.score += 1000 + pattern.weight() - current.weig
ht(); | |
140 } else { | |
141 currentScore.score += current.weight(); | |
142 } | |
143 } | |
144 | |
145 if (currentScore.score > maxScore.score) { | |
146 maxScore = currentScore; | |
147 } | |
148 } | |
149 | |
150 return this->createTypeface(maxScore.index); | |
151 } | 56 } |
152 private: | 57 private: |
153 SkAutoTUnref<const SkFontMgr_Indirect> fOwner; | 58 SkAutoTUnref<const SkFontMgr_Indirect> fOwner; |
154 int fFamilyIndex; | 59 int fFamilyIndex; |
155 SkAutoTUnref<SkRemotableFontIdentitySet> fData; | 60 SkAutoTUnref<SkRemotableFontIdentitySet> fData; |
156 }; | 61 }; |
157 | 62 |
158 void SkFontMgr_Indirect::set_up_family_names(const SkFontMgr_Indirect* self) { | 63 void SkFontMgr_Indirect::set_up_family_names(const SkFontMgr_Indirect* self) { |
159 self->fFamilyNames.reset(self->fProxy->getFamilyNames()); | 64 self->fFamilyNames.reset(self->fProxy->getFamilyNames()); |
160 } | 65 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 face.reset(this->matchFamilyStyle(nullptr, style)); | 200 face.reset(this->matchFamilyStyle(nullptr, style)); |
296 } | 201 } |
297 | 202 |
298 if (nullptr == face.get()) { | 203 if (nullptr == face.get()) { |
299 SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); | 204 SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); |
300 face.reset(this->createTypefaceFromFontId(fontId)); | 205 face.reset(this->createTypefaceFromFontId(fontId)); |
301 } | 206 } |
302 | 207 |
303 return face.detach(); | 208 return face.detach(); |
304 } | 209 } |
OLD | NEW |