18ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner/* 28ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner * Copyright 2017 Google Inc. 38ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner * 48ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner * Use of this source code is governed by a BSD-style license that can be 58ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner * found in the LICENSE file. 68ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner */ 78ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 88ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner#include "SkFontMgr_custom.h" 98ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner#include "SkFontMgr_directory.h" 108ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner#include "SkOSFile.h" 118ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner#include "SkOSPath.h" 128ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner#include "SkStream.h" 138ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 148ab590f17fed097758b209c3b82fc1e4d802768eBen Wagnerclass DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader { 158ab590f17fed097758b209c3b82fc1e4d802768eBen Wagnerpublic: 168ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { } 178ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 188ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner, 198ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkFontMgr_Custom::Families* families) const override 208ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner { 218ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner load_directory_fonts(scanner, fBaseDirectory, ".ttf", families); 228ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner load_directory_fonts(scanner, fBaseDirectory, ".ttc", families); 238ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner load_directory_fonts(scanner, fBaseDirectory, ".otf", families); 248ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner load_directory_fonts(scanner, fBaseDirectory, ".pfb", families); 258ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 268ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (families->empty()) { 278ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString()); 288ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner families->push_back().reset(family); 298ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner family->appendTypeface(sk_make_sp<SkTypeface_Empty>()); 308ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 318ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 328ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 338ab590f17fed097758b209c3b82fc1e4d802768eBen Wagnerprivate: 348ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families, 358ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner const char familyName[]) 368ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner { 378ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner for (int i = 0; i < families.count(); ++i) { 388ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (families[i]->getFamilyName().equals(familyName)) { 398ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner return families[i].get(); 408ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 418ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 428ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner return nullptr; 438ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 448ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 458ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner, 468ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner const SkString& directory, const char* suffix, 478ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkFontMgr_Custom::Families* families) 488ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner { 498ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkOSFile::Iter iter(directory.c_str(), suffix); 508ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkString name; 518ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 528ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner while (iter.next(&name, false)) { 538ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkString filename(SkOSPath::Join(directory.c_str(), name.c_str())); 548ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(filename.c_str()); 558ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (!stream) { 568ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkDebugf("---- failed to open <%s>\n", filename.c_str()); 578ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner continue; 588ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 598ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 608ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner int numFaces; 618ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (!scanner.recognizedFont(stream.get(), &numFaces)) { 628ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkDebugf("---- failed to open <%s> as a font\n", filename.c_str()); 638ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner continue; 648ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 658ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 668ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) { 678ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner bool isFixedPitch; 688ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkString realname; 698ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkFontStyle style = SkFontStyle(); // avoid uninitialized warning 708ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (!scanner.scanFont(stream.get(), faceIndex, 718ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner &realname, &style, &isFixedPitch, nullptr)) 728ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner { 738ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkDebugf("---- failed to open <%s> <%d> as a font\n", 748ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner filename.c_str(), faceIndex); 758ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner continue; 768ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 778ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 788ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str()); 798ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (nullptr == addTo) { 808ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner addTo = new SkFontStyleSet_Custom(realname); 818ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner families->push_back().reset(addTo); 828ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 838ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner addTo->appendTypeface(sk_make_sp<SkTypeface_File>(style, isFixedPitch, true, 848ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner realname, filename.c_str(), 858ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner faceIndex)); 868ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 878ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 888ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 898ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkOSFile::Iter dirIter(directory.c_str()); 908ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner while (dirIter.next(&name, true)) { 918ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner if (name.startsWith(".")) { 928ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner continue; 938ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 948ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str())); 958ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner load_directory_fonts(scanner, dirname, suffix, families); 968ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 978ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner } 988ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 998ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner SkString fBaseDirectory; 1008ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner}; 1018ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner 1028ab590f17fed097758b209c3b82fc1e4d802768eBen WagnerSK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir) { 1038ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner return sk_make_sp<SkFontMgr_Custom>(DirectorySystemFontLoader(dir)); 1048ab590f17fed097758b209c3b82fc1e4d802768eBen Wagner} 105