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

Side by Side Diff: src/fonts/SkFontMgr_indirect.cpp

Issue 1438113002: Factor CSS3 matching rules. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Tests can use C++11. Created 5 years, 1 month 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
« no previous file with comments | « src/core/SkFontMgr.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | 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 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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkFontMgr.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698