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

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

Issue 1673373003: Add support for caching font files in the Android SkFontMgr. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 4 years, 10 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 "SkTypes.h" 8 #include "SkTypes.h"
9 9
10 #include "SkData.h"
10 #include "SkFixed.h" 11 #include "SkFixed.h"
11 #include "SkFontDescriptor.h" 12 #include "SkFontDescriptor.h"
12 #include "SkFontHost_FreeType_common.h" 13 #include "SkFontHost_FreeType_common.h"
13 #include "SkFontMgr.h" 14 #include "SkFontMgr.h"
14 #include "SkFontMgr_android.h" 15 #include "SkFontMgr_android.h"
15 #include "SkFontMgr_android_parser.h" 16 #include "SkFontMgr_android_parser.h"
16 #include "SkFontStyle.h" 17 #include "SkFontStyle.h"
18 #include "SkOSFile.h"
17 #include "SkPaint.h" 19 #include "SkPaint.h"
18 #include "SkRefCnt.h" 20 #include "SkRefCnt.h"
19 #include "SkString.h" 21 #include "SkString.h"
20 #include "SkStream.h" 22 #include "SkStream.h"
21 #include "SkTArray.h" 23 #include "SkTArray.h"
22 #include "SkTDArray.h" 24 #include "SkTDArray.h"
23 #include "SkTSearch.h" 25 #include "SkTSearch.h"
24 #include "SkTemplates.h" 26 #include "SkTemplates.h"
25 #include "SkTypefaceCache.h" 27 #include "SkTypefaceCache.h"
26 28
(...skipping 17 matching lines...) Expand all
44 46
45 SkString fFamilyName; 47 SkString fFamilyName;
46 48
47 private: 49 private:
48 typedef SkTypeface_FreeType INHERITED; 50 typedef SkTypeface_FreeType INHERITED;
49 }; 51 };
50 52
51 class SkTypeface_AndroidSystem : public SkTypeface_Android { 53 class SkTypeface_AndroidSystem : public SkTypeface_Android {
52 public: 54 public:
53 SkTypeface_AndroidSystem(const SkString& pathName, 55 SkTypeface_AndroidSystem(const SkString& pathName,
56 const bool cacheFontFiles,
54 int index, 57 int index,
55 const SkFixed* axes, int axesCount, 58 const SkFixed* axes, int axesCount,
56 const SkFontStyle& style, 59 const SkFontStyle& style,
57 bool isFixedPitch, 60 bool isFixedPitch,
58 const SkString& familyName, 61 const SkString& familyName,
59 const SkLanguage& lang, 62 const SkLanguage& lang,
60 FontVariant variantStyle) 63 FontVariant variantStyle)
61 : INHERITED(style, isFixedPitch, familyName) 64 : INHERITED(style, isFixedPitch, familyName)
62 , fPathName(pathName) 65 , fPathName(pathName)
66 , fCacheFontFiles(cacheFontFiles)
63 , fIndex(index) 67 , fIndex(index)
64 , fAxes(axes, axesCount) 68 , fAxes(axes, axesCount)
65 , fLang(lang) 69 , fLang(lang)
66 , fVariantStyle(variantStyle) { } 70 , fVariantStyle(variantStyle) {
71 if (fCacheFontFiles) {
72 fFile = sk_fopen(fPathName.c_str(), kRead_SkFILE_Flag);
bungeman-skia 2016/02/08 22:11:56 This should just be handled in the init list with
Khushal 2016/02/09 00:53:40 I wanted to add an assert here. It might as well f
73 SkASSERT(fFile);
74 }
75 }
76
77 ~SkTypeface_AndroidSystem() {
78 if (fCacheFontFiles)
79 sk_fclose(fFile);
80 }
81
82 SkStreamAsset* onOpenStream() const {
bungeman-skia 2016/02/08 22:11:56 The 'on' part of the name indicates that this is a
Khushal 2016/02/09 00:53:40 Done.
83 if (fCacheFontFiles) {
84 SkData* data = SkData::NewFromFILE(fFile);
85 return data ? new SkMemoryStream(data) : nullptr;
86 }
87 return SkStream::NewFromFile(fPathName.c_str());
88 }
67 89
68 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) co nst override { 90 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) co nst override {
69 SkASSERT(desc); 91 SkASSERT(desc);
70 SkASSERT(serialize); 92 SkASSERT(serialize);
71 desc->setFamilyName(fFamilyName.c_str()); 93 desc->setFamilyName(fFamilyName.c_str());
72 *serialize = false; 94 *serialize = false;
73 } 95 }
74 SkStreamAsset* onOpenStream(int* ttcIndex) const override { 96 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
75 *ttcIndex = fIndex; 97 *ttcIndex = fIndex;
76 return SkStream::NewFromFile(fPathName.c_str()); 98 return this->onOpenStream();
77 } 99 }
78 SkFontData* onCreateFontData() const override { 100 SkFontData* onCreateFontData() const override {
79 return new SkFontData(SkStream::NewFromFile(fPathName.c_str()), fIndex, 101 return new SkFontData(this->onOpenStream(), fIndex,
80 fAxes.begin(), fAxes.count()); 102 fAxes.begin(), fAxes.count());
81 } 103 }
82 104
83 const SkString fPathName; 105 const SkString fPathName;
106 const bool fCacheFontFiles;
bungeman-skia 2016/02/08 22:11:56 This seems redundant with fFile being nullptr or n
Khushal 2016/02/09 00:53:40 Removed.
84 int fIndex; 107 int fIndex;
85 const SkSTArray<4, SkFixed, true> fAxes; 108 const SkSTArray<4, SkFixed, true> fAxes;
86 const SkLanguage fLang; 109 const SkLanguage fLang;
87 const FontVariant fVariantStyle; 110 const FontVariant fVariantStyle;
111 FILE* fFile;
bungeman-skia 2016/02/08 22:11:56 This should be SkAutoCallVProc<FILE, sk_fclose> so
Khushal 2016/02/09 00:53:40 Done.
88 112
89 typedef SkTypeface_Android INHERITED; 113 typedef SkTypeface_Android INHERITED;
90 }; 114 };
91 115
92 class SkTypeface_AndroidStream : public SkTypeface_Android { 116 class SkTypeface_AndroidStream : public SkTypeface_Android {
93 public: 117 public:
94 SkTypeface_AndroidStream(SkFontData* data, 118 SkTypeface_AndroidStream(SkFontData* data,
95 const SkFontStyle& style, 119 const SkFontStyle& style,
96 bool isFixedPitch, 120 bool isFixedPitch,
97 const SkString& familyName) 121 const SkString& familyName)
(...skipping 20 matching lines...) Expand all
118 142
119 private: 143 private:
120 const SkAutoTDelete<const SkFontData> fData; 144 const SkAutoTDelete<const SkFontData> fData;
121 typedef SkTypeface_Android INHERITED; 145 typedef SkTypeface_Android INHERITED;
122 }; 146 };
123 147
124 class SkFontStyleSet_Android : public SkFontStyleSet { 148 class SkFontStyleSet_Android : public SkFontStyleSet {
125 typedef SkTypeface_FreeType::Scanner Scanner; 149 typedef SkTypeface_FreeType::Scanner Scanner;
126 150
127 public: 151 public:
128 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& sca nner) { 152 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& sca nner, const bool cacheFontFiles) {
bungeman-skia 2016/02/08 22:11:56 Skia has a 100 character limit (there are a few in
Khushal 2016/02/09 00:53:40 Done.
129 const SkString* cannonicalFamilyName = nullptr; 153 const SkString* cannonicalFamilyName = nullptr;
130 if (family.fNames.count() > 0) { 154 if (family.fNames.count() > 0) {
131 cannonicalFamilyName = &family.fNames[0]; 155 cannonicalFamilyName = &family.fNames[0];
132 } 156 }
133 // TODO? make this lazy 157 // TODO? make this lazy
134 for (int i = 0; i < family.fFonts.count(); ++i) { 158 for (int i = 0; i < family.fFonts.count(); ++i) {
135 const FontFileInfo& fontFile = family.fFonts[i]; 159 const FontFileInfo& fontFile = family.fFonts[i];
136 160
137 SkString pathName(family.fBasePath); 161 SkString pathName(family.fBasePath);
138 pathName.append(fontFile.fFileName); 162 pathName.append(fontFile.fFileName);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 243 }
220 if (!found) { 244 if (!found) {
221 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\ n", 245 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\ n",
222 familyName.c_str(), (skTag >> 24) & 0xFF, 246 familyName.c_str(), (skTag >> 24) & 0xFF,
223 (skTag >> 16) & 0xFF, (skTag >> 8) & 0xFF, ( skTag)&0xFF)); 247 (skTag >> 16) & 0xFF, (skTag >> 8) & 0xFF, ( skTag)&0xFF));
224 } 248 }
225 } 249 }
226 ) 250 )
227 251
228 fStyles.push_back().reset(new SkTypeface_AndroidSystem( 252 fStyles.push_back().reset(new SkTypeface_AndroidSystem(
229 pathName, ttcIndex, axisValues.get(), axisDefinitions.count( ), style, 253 pathName, cacheFontFiles, ttcIndex, axisValues.get(), axisDe finitions.count(), style,
230 isFixedWidth, familyName, lang, variant)); 254 isFixedWidth, familyName, lang, variant));
231 } 255 }
232 } 256 }
233 257
234 int count() override { 258 int count() override {
235 return fStyles.count(); 259 return fStyles.count();
236 } 260 }
237 void getStyle(int index, SkFontStyle* style, SkString* name) override { 261 void getStyle(int index, SkFontStyle* style, SkString* name) override {
238 if (index < 0 || fStyles.count() <= index) { 262 if (index < 0 || fStyles.count() <= index) {
239 return; 263 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 * (non-replicated) set of typefaces. 322 * (non-replicated) set of typefaces.
299 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping. 323 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
300 */ 324 */
301 struct NameToFamily { 325 struct NameToFamily {
302 SkString name; 326 SkString name;
303 SkFontStyleSet_Android* styleSet; 327 SkFontStyleSet_Android* styleSet;
304 }; 328 };
305 329
306 class SkFontMgr_Android : public SkFontMgr { 330 class SkFontMgr_Android : public SkFontMgr {
307 public: 331 public:
308 SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom) { 332 SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom)
333 : fCacheFontFiles(custom ? custom->fCacheFontFiles : false) {
bungeman-skia 2016/02/08 22:11:56 The '{' should go on the next line, four spaces in
Khushal 2016/02/09 00:53:40 Done.
309 SkTDArray<FontFamily*> families; 334 SkTDArray<FontFamily*> families;
310 if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fS ystemFontUse) { 335 if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fS ystemFontUse) {
311 SkString base(custom->fBasePath); 336 SkString base(custom->fBasePath);
312 SkFontMgr_Android_Parser::GetCustomFontFamilies( 337 SkFontMgr_Android_Parser::GetCustomFontFamilies(
313 families, base, custom->fFontsXml, custom->fFallbackFontsXml); 338 families, base, custom->fFontsXml, custom->fFallbackFontsXml);
314 } 339 }
315 if (!custom || 340 if (!custom ||
316 (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSy stemFontUse)) 341 (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSy stemFontUse))
317 { 342 {
318 SkFontMgr_Android_Parser::GetSystemFontFamilies(families); 343 SkFontMgr_Android_Parser::GetSystemFontFamilies(families);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 538
514 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 539 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
515 unsigned styleBits) const overrid e { 540 unsigned styleBits) const overrid e {
516 SkFontStyle style = SkFontStyle(styleBits); 541 SkFontStyle style = SkFontStyle(styleBits);
517 542
518 if (familyName) { 543 if (familyName) {
519 // On Android, we must return nullptr when we can't find the request ed 544 // On Android, we must return nullptr when we can't find the request ed
520 // named typeface so that the system/app can provide their own recov ery 545 // named typeface so that the system/app can provide their own recov ery
521 // mechanism. On other platforms we'd provide a typeface from the 546 // mechanism. On other platforms we'd provide a typeface from the
522 // default family instead. 547 // default family instead.
523 return this->onMatchFamilyStyle(familyName, style); 548 // We only return the default family when the font manager is cachin g
bungeman-skia 2016/02/08 22:11:56 Why this change? Does blink on Linux do bad things
Khushal 2016/02/09 00:53:39 It just crashes. Because like the comment above sa
549 // font families.
550 SkTypeface* typeface = this->onMatchFamilyStyle(familyName, style);
551 if (typeface || !fCacheFontFiles)
552 return typeface;
524 } 553 }
525 return fDefaultFamily->matchStyle(style); 554 return fDefaultFamily->matchStyle(style);
526 } 555 }
527 556
528 557
529 private: 558 private:
530 559
531 SkTypeface_FreeType::Scanner fScanner; 560 SkTypeface_FreeType::Scanner fScanner;
532 561
533 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; 562 SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets;
534 SkFontStyleSet* fDefaultFamily; 563 SkFontStyleSet* fDefaultFamily;
535 SkTypeface* fDefaultTypeface; 564 SkTypeface* fDefaultTypeface;
536 565
537 SkTDArray<NameToFamily> fNameToFamilyMap; 566 SkTDArray<NameToFamily> fNameToFamilyMap;
538 SkTDArray<NameToFamily> fFallbackNameToFamilyMap; 567 SkTDArray<NameToFamily> fFallbackNameToFamilyMap;
539 568
569 const bool fCacheFontFiles;
570
540 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { 571 void buildNameToFamilyMap(SkTDArray<FontFamily*> families) {
541 for (int i = 0; i < families.count(); i++) { 572 for (int i = 0; i < families.count(); i++) {
542 FontFamily& family = *families[i]; 573 FontFamily& family = *families[i];
543 574
544 SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap; 575 SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap;
545 if (family.fIsFallbackFont) { 576 if (family.fIsFallbackFont) {
546 nameToFamily = &fFallbackNameToFamilyMap; 577 nameToFamily = &fFallbackNameToFamilyMap;
547 578
548 if (0 == family.fNames.count()) { 579 if (0 == family.fNames.count()) {
549 SkString& fallbackName = family.fNames.push_back(); 580 SkString& fallbackName = family.fNames.push_back();
550 fallbackName.printf("%.2x##fallback", i); 581 fallbackName.printf("%.2x##fallback", i);
551 } 582 }
552 } 583 }
553 584
554 SkFontStyleSet_Android* newSet = new SkFontStyleSet_Android(family, fScanner); 585 SkFontStyleSet_Android* newSet = new SkFontStyleSet_Android(family, fScanner, fCacheFontFiles);
555 if (0 == newSet->count()) { 586 if (0 == newSet->count()) {
556 delete newSet; 587 delete newSet;
557 continue; 588 continue;
558 } 589 }
559 fFontStyleSets.push_back().reset(newSet); 590 fFontStyleSets.push_back().reset(newSet);
560 591
561 for (int j = 0; j < family.fNames.count(); j++) { 592 for (int j = 0; j < family.fNames.count(); j++) {
562 NameToFamily* nextEntry = nameToFamily->append(); 593 NameToFamily* nextEntry = nameToFamily->append();
563 new (&nextEntry->name) SkString(family.fNames[j]); 594 new (&nextEntry->name) SkString(family.fNames[j]);
564 nextEntry->styleSet = newSet; 595 nextEntry->styleSet = newSet;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings)) ; 636 SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings)) ;
606 SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n" , 637 SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n" ,
607 gSystemFontUseStrings[custom->fSystemFontUse], 638 gSystemFontUseStrings[custom->fSystemFontUse],
608 custom->fBasePath, 639 custom->fBasePath,
609 custom->fFontsXml, 640 custom->fFontsXml,
610 custom->fFallbackFontsXml)); 641 custom->fFallbackFontsXml));
611 } 642 }
612 643
613 return new SkFontMgr_Android(custom); 644 return new SkFontMgr_Android(custom);
614 } 645 }
OLDNEW
« include/ports/SkFontMgr_android.h ('K') | « include/ports/SkFontMgr_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698