1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_FT2FONTLIST_H 7 #define GFX_FT2FONTLIST_H 8 9 #include "mozilla/MemoryReporting.h" 10 #include "gfxFT2FontBase.h" 11 #include "gfxPlatformFontList.h" 12 13 namespace mozilla { 14 namespace dom { 15 class SystemFontListEntry; 16 }; 17 }; // namespace mozilla 18 19 class FontNameCache; 20 typedef struct FT_FaceRec_* FT_Face; 21 class nsZipArchive; 22 class WillShutdownObserver; 23 class FTUserFontData; 24 25 class FT2FontEntry final : public gfxFT2FontEntryBase { 26 using FontListEntry = mozilla::dom::SystemFontListEntry; 27 28 public: FT2FontEntry(const nsACString & aFaceName)29 explicit FT2FontEntry(const nsACString& aFaceName) 30 : gfxFT2FontEntryBase(aFaceName), mFTFontIndex(0) {} 31 32 ~FT2FontEntry(); 33 34 gfxFontEntry* Clone() const override; 35 GetName()36 const nsCString& GetName() const { return Name(); } 37 38 // create a font entry for a downloaded font 39 static FT2FontEntry* CreateFontEntry( 40 const nsACString& aFontName, WeightRange aWeight, StretchRange aStretch, 41 SlantStyleRange aStyle, const uint8_t* aFontData, uint32_t aLength); 42 43 // create a font entry representing an installed font, identified by 44 // a FontListEntry; the freetype and cairo faces will not be instantiated 45 // until actually needed 46 static FT2FontEntry* CreateFontEntry(const FontListEntry& aFLE); 47 48 // Create a font entry with the given name; if it is an installed font, 49 // also record the filename and index. 50 // If a non-null harfbuzz face is passed, also set style/weight/stretch 51 // properties of the entry from the values in the face. 52 static FT2FontEntry* CreateFontEntry(const nsACString& aName, 53 const char* aFilename, uint8_t aIndex, 54 const hb_face_t* aFace); 55 56 gfxFont* CreateFontInstance(const gfxFontStyle* aStyle) override; 57 58 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; 59 60 hb_blob_t* GetFontTable(uint32_t aTableTag) override; 61 62 nsresult CopyFontTable(uint32_t aTableTag, 63 nsTArray<uint8_t>& aBuffer) override; 64 65 bool HasVariations() override; 66 void GetVariationAxes( 67 nsTArray<gfxFontVariationAxis>& aVariationAxes) override; 68 void GetVariationInstances( 69 nsTArray<gfxFontVariationInstance>& aInstances) override; 70 71 // Check for various kinds of brokenness, and set flags on the entry 72 // accordingly so that we avoid using bad font tables 73 void CheckForBrokenFont(gfxFontFamily* aFamily); 74 void CheckForBrokenFont(const nsACString& aFamilyKey); 75 76 already_AddRefed<mozilla::gfx::SharedFTFace> GetFTFace(bool aCommit = false); 77 FTUserFontData* GetUserFontData(); 78 79 FT_MM_Var* GetMMVar() override; 80 81 /** 82 * Append this face's metadata to aFaceList for storage in the FontNameCache 83 * (for faster startup). 84 * The aPSName and aFullName parameters here can in principle be empty, 85 * but if they are missing for a given face then src:local() lookups will 86 * not be able to find it when the shared font list is in use. 87 */ 88 void AppendToFaceList(nsCString& aFaceList, const nsACString& aFamilyName, 89 const nsACString& aPSName, const nsACString& aFullName, 90 FontVisibility aVisibility); 91 92 void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 93 FontListSizes* aSizes) const override; 94 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 95 FontListSizes* aSizes) const override; 96 97 RefPtr<mozilla::gfx::SharedFTFace> mFTFace; 98 99 FT_MM_Var* mMMVar = nullptr; 100 101 nsCString mFilename; 102 uint8_t mFTFontIndex; 103 104 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFreeType> mUnscaledFont; 105 106 bool mHasVariations = false; 107 bool mHasVariationsInitialized = false; 108 bool mMMVarInitialized = false; 109 }; 110 111 class FT2FontFamily final : public gfxFontFamily { 112 using FontListEntry = mozilla::dom::SystemFontListEntry; 113 114 public: FT2FontFamily(const nsACString & aName,FontVisibility aVisibility)115 explicit FT2FontFamily(const nsACString& aName, FontVisibility aVisibility) 116 : gfxFontFamily(aName, aVisibility) {} 117 118 // Append this family's faces to the IPC fontlist 119 void AddFacesToFontList(nsTArray<FontListEntry>* aFontList); 120 }; 121 122 class gfxFT2FontList final : public gfxPlatformFontList { 123 using FontListEntry = mozilla::dom::SystemFontListEntry; 124 125 public: 126 gfxFT2FontList(); 127 virtual ~gfxFT2FontList(); 128 129 gfxFontEntry* CreateFontEntry( 130 mozilla::fontlist::Face* aFace, 131 const mozilla::fontlist::Family* aFamily) override; 132 133 gfxFontEntry* LookupLocalFont(const nsACString& aFontName, 134 WeightRange aWeightForEntry, 135 StretchRange aStretchForEntry, 136 SlantStyleRange aStyleForEntry) override; 137 138 gfxFontEntry* MakePlatformFont(const nsACString& aFontName, 139 WeightRange aWeightForEntry, 140 StretchRange aStretchForEntry, 141 SlantStyleRange aStyleForEntry, 142 const uint8_t* aFontData, 143 uint32_t aLength) override; 144 145 void WriteCache(); 146 147 void ReadSystemFontList(nsTArray<FontListEntry>* aList); 148 PlatformFontList()149 static gfxFT2FontList* PlatformFontList() { 150 return static_cast<gfxFT2FontList*>( 151 gfxPlatformFontList::PlatformFontList()); 152 } 153 154 gfxFontFamily* CreateFontFamily(const nsACString& aName, 155 FontVisibility aVisibility) const override; 156 157 void WillShutdown(); 158 159 protected: 160 typedef enum { kUnknown, kStandard } StandardFile; 161 162 // initialize font lists 163 nsresult InitFontListForPlatform() override; 164 165 void AppendFaceFromFontListEntry(const FontListEntry& aFLE, 166 StandardFile aStdFile); 167 168 void AppendFacesFromBlob(const nsCString& aFileName, StandardFile aStdFile, 169 hb_blob_t* aBlob, FontNameCache* aCache, 170 uint32_t aTimestamp, uint32_t aFilesize); 171 172 void AppendFacesFromFontFile(const nsCString& aFileName, 173 FontNameCache* aCache, StandardFile aStdFile); 174 175 void AppendFacesFromOmnijarEntry(nsZipArchive* aReader, 176 const nsCString& aEntryName, 177 FontNameCache* aCache, bool aJarChanged); 178 179 void InitSharedFontListForPlatform() override; 180 void CollectInitData(const FontListEntry& aFLE, const nsCString& aPSName, 181 const nsCString& aFullName, StandardFile aStdFile); 182 183 /** 184 * Callback passed to AppendFacesFromCachedFaceList to collect family/face 185 * information in either the unshared or shared list we're building. 186 */ 187 typedef void (*CollectFunc)(const FontListEntry& aFLE, 188 const nsCString& aPSName, 189 const nsCString& aFullName, 190 StandardFile aStdFile); 191 192 /** 193 * Append faces from the face-list record for a specific file. 194 * aCollectFace is a callback that will store the face(s) in either the 195 * unshared mFontFamilies list or the mFamilyInitData/mFaceInitData tables 196 * that will be used to initialize the shared list. 197 * Returns true if it is able to read at least one face entry; false if no 198 * usable face entry was found. 199 */ 200 bool AppendFacesFromCachedFaceList(CollectFunc aCollectFace, 201 const nsCString& aFileName, 202 const nsCString& aFaceList, 203 StandardFile aStdFile); 204 205 void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, 206 StandardFile aStdFile, hb_face_t* aFace, 207 nsCString& aFaceList); 208 209 void FindFonts(); 210 211 void FindFontsInOmnijar(FontNameCache* aCache); 212 213 void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC); 214 215 FontFamily GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override; 216 217 nsTHashtable<nsCStringHashKey> mSkipSpaceLookupCheckFamilies; 218 219 private: 220 mozilla::UniquePtr<FontNameCache> mFontNameCache; 221 int64_t mJarModifiedTime; 222 RefPtr<WillShutdownObserver> mObserver; 223 224 nsTArray<mozilla::fontlist::Family::InitData> mFamilyInitData; 225 nsClassHashtable<nsCStringHashKey, 226 nsTArray<mozilla::fontlist::Face::InitData>> 227 mFaceInitData; 228 }; 229 230 #endif /* GFX_FT2FONTLIST_H */ 231