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

Side by Side Diff: src/ports/SkFontMgr_android.cpp

Issue 1027373002: Font variations. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Android and tests. Created 5 years, 7 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
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 "SkFontConfigParser_android.h" 8 #include "SkFontConfigParser_android.h"
9 #include "SkFontDescriptor.h" 9 #include "SkFontDescriptor.h"
10 #include "SkFontHost_FreeType_common.h" 10 #include "SkFontHost_FreeType_common.h"
(...skipping 10 matching lines...) Expand all
21 #include <limits> 21 #include <limits>
22 22
23 // For test only. 23 // For test only.
24 static const char* gTestFontsXml = NULL; 24 static const char* gTestFontsXml = NULL;
25 static const char* gTestFallbackFontsXml = NULL; 25 static const char* gTestFallbackFontsXml = NULL;
26 static const char* gTestBasePath = NULL; 26 static const char* gTestBasePath = NULL;
27 27
28 class SkTypeface_Android : public SkTypeface_FreeType { 28 class SkTypeface_Android : public SkTypeface_FreeType {
29 public: 29 public:
30 SkTypeface_Android(int index, 30 SkTypeface_Android(int index,
31 const SkFixed* axes, int axesCount,
31 const SkFontStyle& style, 32 const SkFontStyle& style,
32 bool isFixedPitch, 33 bool isFixedPitch,
33 const SkString& familyName) 34 const SkString& familyName)
34 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) 35 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
35 , fIndex(index) 36 , fIndex(index)
36 , fFamilyName(familyName) { } 37 , fFamilyName(familyName)
38 , fAxes(axes, axesCount)
39 { }
37 40
38 protected: 41 protected:
39 void onGetFamilyName(SkString* familyName) const override { 42 void onGetFamilyName(SkString* familyName) const override {
40 *familyName = fFamilyName; 43 *familyName = fFamilyName;
41 } 44 }
42 45
43 int fIndex; 46 int fIndex;
44 SkString fFamilyName; 47 SkString fFamilyName;
48 const SkSTArray<4, SkFixed, true> fAxes;
45 49
46 private: 50 private:
47 typedef SkTypeface_FreeType INHERITED; 51 typedef SkTypeface_FreeType INHERITED;
48 }; 52 };
49 53
50 class SkTypeface_AndroidSystem : public SkTypeface_Android { 54 class SkTypeface_AndroidSystem : public SkTypeface_Android {
51 public: 55 public:
52 SkTypeface_AndroidSystem(const SkString& pathName, 56 SkTypeface_AndroidSystem(const SkString& pathName,
53 int index, 57 int index,
58 const SkFixed* axes, int axesCount,
54 const SkFontStyle& style, 59 const SkFontStyle& style,
55 bool isFixedPitch, 60 bool isFixedPitch,
56 const SkString& familyName, 61 const SkString& familyName,
57 const SkLanguage& lang, 62 const SkLanguage& lang,
58 FontVariant variantStyle) 63 FontVariant variantStyle)
59 : INHERITED(index, style, isFixedPitch, familyName) 64 : INHERITED(index, axes, axesCount, style, isFixedPitch, familyName)
60 , fPathName(pathName) 65 , fPathName(pathName)
61 , fLang(lang) 66 , fLang(lang)
62 , fVariantStyle(variantStyle) { } 67 , fVariantStyle(variantStyle) { }
63 68
64 virtual void onGetFontDescriptor(SkFontDescriptor* desc, 69 virtual void onGetFontDescriptor(SkFontDescriptor* desc,
65 bool* serialize) const override { 70 bool* serialize) const override {
66 SkASSERT(desc); 71 SkASSERT(desc);
67 SkASSERT(serialize); 72 SkASSERT(serialize);
68 desc->setFamilyName(fFamilyName.c_str()); 73 desc->setFamilyName(fFamilyName.c_str());
69 desc->setFontIndex(fIndex);
70 *serialize = false; 74 *serialize = false;
71 } 75 }
72 SkStreamAsset* onOpenStream(int* ttcIndex) const override { 76 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
73 *ttcIndex = fIndex; 77 *ttcIndex = fIndex;
74 return SkStream::NewFromFile(fPathName.c_str()); 78 return SkStream::NewFromFile(fPathName.c_str());
75 } 79 }
80 SkFontData* onCreateFontData() const override {
81 return new SkFontData(SkStream::NewFromFile(fPathName.c_str()), fIndex,
82 fAxes.count(), fAxes.begin());
83 }
76 84
77 const SkString fPathName; 85 const SkString fPathName;
78 const SkLanguage fLang; 86 const SkLanguage fLang;
79 const FontVariant fVariantStyle; 87 const FontVariant fVariantStyle;
80 88
81 typedef SkTypeface_Android INHERITED; 89 typedef SkTypeface_Android INHERITED;
82 }; 90 };
83 91
84 class SkTypeface_AndroidStream : public SkTypeface_Android { 92 class SkTypeface_AndroidStream : public SkTypeface_Android {
85 public: 93 public:
86 SkTypeface_AndroidStream(SkStreamAsset* stream, 94 SkTypeface_AndroidStream(SkStreamAsset* stream,
87 int index, 95 int index,
96 const SkFixed* axes, int axesCount,
88 const SkFontStyle& style, 97 const SkFontStyle& style,
89 bool isFixedPitch, 98 bool isFixedPitch,
90 const SkString& familyName) 99 const SkString& familyName)
91 : INHERITED(index, style, isFixedPitch, familyName) 100 : INHERITED(index, axes, axesCount, style, isFixedPitch, familyName)
92 , fStream(stream) { } 101 , fStream(stream) { }
93 102
94 virtual void onGetFontDescriptor(SkFontDescriptor* desc, 103 virtual void onGetFontDescriptor(SkFontDescriptor* desc,
95 bool* serialize) const override { 104 bool* serialize) const override {
96 SkASSERT(desc); 105 SkASSERT(desc);
97 SkASSERT(serialize); 106 SkASSERT(serialize);
98 desc->setFamilyName(fFamilyName.c_str()); 107 desc->setFamilyName(fFamilyName.c_str());
99 *serialize = true; 108 *serialize = true;
100 } 109 }
101 110
102 SkStreamAsset* onOpenStream(int* ttcIndex) const override { 111 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
103 *ttcIndex = fIndex; 112 *ttcIndex = fIndex;
104 return fStream->duplicate(); 113 return fStream->duplicate();
105 } 114 }
106 115
116 SkFontData* onCreateFontData() const override {
117 return new SkFontData(fStream->duplicate(), fIndex, fAxes.count(), fAxes .begin());
118 }
119
107 private: 120 private:
108 SkAutoTDelete<SkStreamAsset> fStream; 121 SkAutoTDelete<SkStreamAsset> fStream;
109 122
110 typedef SkTypeface_Android INHERITED; 123 typedef SkTypeface_Android INHERITED;
111 }; 124 };
112 125
113 class SkFontStyleSet_Android : public SkFontStyleSet { 126 class SkFontStyleSet_Android : public SkFontStyleSet {
127 typedef SkTypeface_FreeType::Scanner Scanner;
128
114 public: 129 public:
115 explicit SkFontStyleSet_Android(const FontFamily& family, 130 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& sca nner) {
116 const SkTypeface_FreeType::Scanner& scanner)
117 {
118 const SkString* cannonicalFamilyName = NULL; 131 const SkString* cannonicalFamilyName = NULL;
119 if (family.fNames.count() > 0) { 132 if (family.fNames.count() > 0) {
120 cannonicalFamilyName = &family.fNames[0]; 133 cannonicalFamilyName = &family.fNames[0];
121 } 134 }
122 // TODO? make this lazy 135 // TODO? make this lazy
123 for (int i = 0; i < family.fFonts.count(); ++i) { 136 for (int i = 0; i < family.fFonts.count(); ++i) {
124 const FontFileInfo& fontFile = family.fFonts[i]; 137 const FontFileInfo& fontFile = family.fFonts[i];
125 138
126 SkString pathName(family.fBasePath); 139 SkString pathName(family.fBasePath);
127 pathName.append(fontFile.fFileName); 140 pathName.append(fontFile.fFileName);
128 141
129 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str( ))); 142 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str( )));
130 if (!stream.get()) { 143 if (!stream.get()) {
131 SkDEBUGF(("Requested font file %s does not exist or cannot be op ened.\n", 144 SkDEBUGF(("Requested font file %s does not exist or cannot be op ened.\n",
132 pathName.c_str())); 145 pathName.c_str()));
133 continue; 146 continue;
134 } 147 }
135 148
136 const int ttcIndex = fontFile.fIndex; 149 const int ttcIndex = fontFile.fIndex;
137 SkString familyName; 150 SkString familyName;
138 SkFontStyle style; 151 SkFontStyle style;
139 bool isFixedWidth; 152 bool isFixedWidth;
140 if (!scanner.scanFont(stream.get(), ttcIndex, &familyName, &style, & isFixedWidth)) { 153 Scanner::AxisDefinitions axisDefinitions;
154 if (!scanner.scanFont(stream.get(), ttcIndex,
155 &familyName, &style, &isFixedWidth, &axisDefin itions))
156 {
141 SkDEBUGF(("Requested font file %s exists, but is not a valid fon t.\n", 157 SkDEBUGF(("Requested font file %s exists, but is not a valid fon t.\n",
142 pathName.c_str())); 158 pathName.c_str()));
143 continue; 159 continue;
144 } 160 }
145 161
146 int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight (); 162 int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight ();
147 SkFontStyle::Slant slant = style.slant(); 163 SkFontStyle::Slant slant = style.slant();
148 switch (fontFile.fStyle) { 164 switch (fontFile.fStyle) {
149 case FontFileInfo::Style::kAuto: slant = style.slant(); break; 165 case FontFileInfo::Style::kAuto: slant = style.slant(); break;
150 case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright _Slant; break; 166 case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright _Slant; break;
151 case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_ Slant; break; 167 case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_ Slant; break;
152 default: SkASSERT(false); break; 168 default: SkASSERT(false); break;
153 } 169 }
154 style = SkFontStyle(weight, style.width(), slant); 170 style = SkFontStyle(weight, style.width(), slant);
155 171
156 const SkLanguage& lang = family.fLanguage; 172 const SkLanguage& lang = family.fLanguage;
157 uint32_t variant = family.fVariant; 173 uint32_t variant = family.fVariant;
158 if (kDefault_FontVariant == variant) { 174 if (kDefault_FontVariant == variant) {
159 variant = kCompact_FontVariant | kElegant_FontVariant; 175 variant = kCompact_FontVariant | kElegant_FontVariant;
160 } 176 }
161 177
162 // The first specified family name overrides the family name found i n the font. 178 // The first specified family name overrides the family name found i n the font.
163 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return 179 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
164 // all of the specified family names in addition to the names found in the font. 180 // all of the specified family names in addition to the names found in the font.
165 if (cannonicalFamilyName != NULL) { 181 if (cannonicalFamilyName != NULL) {
166 familyName = *cannonicalFamilyName; 182 familyName = *cannonicalFamilyName;
167 } 183 }
168 184
185 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
186 for (int i = 0; i < axisDefinitions.count(); ++i) {
187 const Scanner::AxisDefinition& axisDefinition = axisDefinitions[ i];
188 axisValues[i] = axisDefinition.fDefault;
189 for (int j = 0; j < fontFile.fAxes.count(); ++j) {
190 const FontFileInfo::Axis& axisSpecified = fontFile.fAxes[j];
191 if (axisDefinition.fTag == axisSpecified.fTag) {
192 axisValues[i] = SkTPin(axisSpecified.fValue, axisDefinit ion.fMinimum,
193 axisDefinit ion.fMaximum);
194 if (axisValues[i] != axisSpecified.fValue) {
195 SkDEBUGF(("Requested font axis value out of range: "
196 "%s '%c%c%c%c' %f; pinned to %f.\n",
197 familyName.c_str(),
198 (axisDefinition.fTag >> 24) & 0xFF,
199 (axisDefinition.fTag >> 16) & 0xFF,
200 (axisDefinition.fTag >> 8) & 0xFF,
201 (axisDefinition.fTag ) & 0xFF,
202 SkFixedToDouble(axisSpecified.fValue),
203 SkFixedToDouble(axisValues[i])));
204 }
205 break;
206 }
207 }
208 // TODO: warn on defaulted axis?
209 }
210
211 SkDEBUGCODE (
212 // Check for axis specified, but not matched in font.
213 for (int i = 0; i < fontFile.fAxes.count(); ++i) {
214 SkFourByteTag skTag = fontFile.fAxes[i].fTag;
215 bool found = false;
216 for (int j = 0; j < axisDefinitions.count(); ++j) {
217 if (skTag == axisDefinitions[j].fTag) {
218 found = true;
219 break;
220 }
221 }
222 if (!found) {
223 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\ n",
224 familyName.c_str(),
225 (skTag >> 24) & 0xFF,
226 (skTag >> 16) & 0xFF,
227 (skTag >> 8) & 0xFF,
228 (skTag ) & 0xFF));
229 }
230 }
231 )
232
169 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, 233 fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem,
170 (pathName, ttcIndex, 234 (pathName, ttcIndex,
235 axisValues.get(), axisDefiniti ons.count(),
171 style, isFixedWidth, familyNam e, 236 style, isFixedWidth, familyNam e,
172 lang, variant))); 237 lang, variant)));
173 } 238 }
174 } 239 }
175 240
176 int count() override { 241 int count() override {
177 return fStyles.count(); 242 return fStyles.count();
178 } 243 }
179 void getStyle(int index, SkFontStyle* style, SkString* name) override { 244 void getStyle(int index, SkFontStyle* style, SkString* name) override {
180 if (index < 0 || fStyles.count() <= index) { 245 if (index < 0 || fStyles.count() <= index) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 469 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
405 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); 470 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path));
406 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL; 471 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL;
407 } 472 }
408 473
409 SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons t override { 474 SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons t override {
410 SkAutoTDelete<SkStreamAsset> stream(bareStream); 475 SkAutoTDelete<SkStreamAsset> stream(bareStream);
411 bool isFixedPitch; 476 bool isFixedPitch;
412 SkFontStyle style; 477 SkFontStyle style;
413 SkString name; 478 SkString name;
414 if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) { 479 if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch, N ULL)) {
415 return NULL; 480 return NULL;
416 } 481 }
417 return SkNEW_ARGS(SkTypeface_AndroidStream, (stream.detach(), ttcIndex, 482 return SkNEW_ARGS(SkTypeface_AndroidStream, (stream.detach(), ttcIndex, NULL, 0,
418 style, isFixedPitch, name)) ; 483 style, isFixedPitch, name)) ;
419 } 484 }
420 485
486 SkTypeface* onCreateFromFontData(SkFontData* data) const override {
487 SkAutoTDelete<SkStreamAsset> stream(data->detachStream());
488 bool isFixedPitch;
489 SkFontStyle style;
490 SkString name;
491 if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixed Pitch, NULL)) {
492 return NULL;
493 }
494 return SkNEW_ARGS(SkTypeface_AndroidStream, (stream.detach(), data->getI ndex(),
495 data->getAxis(), data->getA xisCount(),
496 style, isFixedPitch, name)) ;
497 }
498
421 499
422 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 500 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
423 unsigned styleBits) const overrid e { 501 unsigned styleBits) const overrid e {
424 SkFontStyle style = SkFontStyle(styleBits); 502 SkFontStyle style = SkFontStyle(styleBits);
425 503
426 if (familyName) { 504 if (familyName) {
427 // On Android, we must return NULL when we can't find the requested 505 // On Android, we must return NULL when we can't find the requested
428 // named typeface so that the system/app can provide their own recov ery 506 // named typeface so that the system/app can provide their own recov ery
429 // mechanism. On other platforms we'd provide a typeface from the 507 // mechanism. On other platforms we'd provide a typeface from the
430 // default family instead. 508 // default family instead.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 { 622 {
545 gTestFontsXml = fontsXml; 623 gTestFontsXml = fontsXml;
546 gTestFallbackFontsXml = fallbackFontsXml; 624 gTestFallbackFontsXml = fallbackFontsXml;
547 gTestBasePath = basePath; 625 gTestBasePath = basePath;
548 SkASSERT(gTestFontsXml); 626 SkASSERT(gTestFontsXml);
549 SkASSERT(gTestFallbackFontsXml); 627 SkASSERT(gTestFallbackFontsXml);
550 SkASSERT(gTestBasePath); 628 SkASSERT(gTestBasePath);
551 SkDEBUGF(("Test BasePath: %s Fonts: %s FallbackFonts: %s\n", 629 SkDEBUGF(("Test BasePath: %s Fonts: %s FallbackFonts: %s\n",
552 gTestBasePath, gTestFontsXml, gTestFallbackFontsXml)); 630 gTestBasePath, gTestFontsXml, gTestFallbackFontsXml));
553 } 631 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698