gfxFT2FontList.h (9935B)
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 #include "nsTHashSet.h" 13 14 namespace mozilla { 15 namespace dom { 16 class SystemFontListEntry; 17 }; 18 namespace gfx { 19 class FTUserFontData; 20 }; 21 }; // namespace mozilla 22 23 class FontNameCache; 24 typedef struct FT_FaceRec_* FT_Face; 25 class nsZipArchive; 26 class WillShutdownObserver; 27 28 class FT2FontEntry final : public gfxFT2FontEntryBase { 29 friend class gfxFT2FontList; 30 31 using FontListEntry = mozilla::dom::SystemFontListEntry; 32 using FTUserFontData = mozilla::gfx::FTUserFontData; 33 34 public: 35 explicit FT2FontEntry(const nsACString& aFaceName) 36 : gfxFT2FontEntryBase(aFaceName), mFTFontIndex(0) {} 37 38 ~FT2FontEntry(); 39 40 gfxFontEntry* Clone() const override; 41 42 const nsCString& GetName() const { return Name(); } 43 44 // create a font entry for a downloaded font 45 static FT2FontEntry* CreateFontEntry( 46 const nsACString& aFontName, WeightRange aWeight, StretchRange aStretch, 47 SlantStyleRange aStyle, const uint8_t* aFontData, uint32_t aLength); 48 49 // create a font entry representing an installed font, identified by 50 // a FontListEntry; the freetype and cairo faces will not be instantiated 51 // until actually needed 52 static FT2FontEntry* CreateFontEntry(const FontListEntry& aFLE); 53 54 // Create a font entry with the given name; if it is an installed font, 55 // also record the filename and index. 56 // If a non-null harfbuzz face is passed, also set style/weight/stretch 57 // properties of the entry from the values in the face. 58 static FT2FontEntry* CreateFontEntry(const nsACString& aName, 59 const char* aFilename, uint8_t aIndex, 60 const hb_face_t* aFace); 61 62 gfxFont* CreateFontInstance(const gfxFontStyle* aStyle) override; 63 64 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; 65 66 hb_blob_t* GetFontTable(uint32_t aTableTag) override; 67 68 bool HasFontTable(uint32_t aTableTag) override; 69 nsresult CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>&) override; 70 71 bool HasVariations() override; 72 void GetVariationAxes( 73 nsTArray<gfxFontVariationAxis>& aVariationAxes) override; 74 void GetVariationInstances( 75 nsTArray<gfxFontVariationInstance>& aInstances) override; 76 77 // Check for various kinds of brokenness, and set flags on the entry 78 // accordingly so that we avoid using bad font tables 79 void CheckForBrokenFont(gfxFontFamily* aFamily); 80 void CheckForBrokenFont(const nsACString& aFamilyKey); 81 82 already_AddRefed<mozilla::gfx::SharedFTFace> GetFTFace(bool aCommit = false); 83 FTUserFontData* GetUserFontData() override; 84 85 FT_MM_Var* GetMMVar() override; 86 87 // Get a harfbuzz face for this font, if possible. The caller is responsible 88 // to destroy the face when no longer needed. 89 // This may be a bit expensive, so avoid calling multiple times if the same 90 // face can be re-used for several purposes instead. 91 hb_face_t* CreateHBFace() const; 92 93 /** 94 * Append this face's metadata to aFaceList for storage in the FontNameCache 95 * (for faster startup). 96 * The aPSName and aFullName parameters here can in principle be empty, 97 * but if they are missing for a given face then src:local() lookups will 98 * not be able to find it when the shared font list is in use. 99 */ 100 void AppendToFaceList(nsCString& aFaceList, const nsACString& aFamilyName, 101 const nsACString& aPSName, const nsACString& aFullName, 102 FontVisibility aVisibility); 103 104 void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 105 FontListSizes* aSizes) const override; 106 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 107 FontListSizes* aSizes) const override; 108 109 // Strong reference (addref'd), but held in an atomic ptr rather than a 110 // normal RefPtr. 111 mozilla::Atomic<mozilla::gfx::SharedFTFace*> mFTFace; 112 113 FT_MM_Var* mMMVar = nullptr; 114 115 nsCString mFilename; 116 uint8_t mFTFontIndex; 117 118 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFreeType> mUnscaledFont; 119 120 nsTHashSet<uint32_t> mAvailableTables; 121 122 enum class HasVariationsState : int8_t { 123 Uninitialized = -1, 124 No = 0, 125 Yes = 1, 126 }; 127 std::atomic<HasVariationsState> mHasVariations = 128 HasVariationsState::Uninitialized; 129 130 bool mMMVarInitialized = false; 131 }; 132 133 class FT2FontFamily final : public gfxFontFamily { 134 using FontListEntry = mozilla::dom::SystemFontListEntry; 135 136 public: 137 explicit FT2FontFamily(const nsACString& aName, FontVisibility aVisibility) 138 : gfxFontFamily(aName, aVisibility) {} 139 140 // Append this family's faces to the IPC fontlist 141 void AddFacesToFontList(nsTArray<FontListEntry>* aFontList); 142 143 void FinalizeMemberList(bool aSortFaces); 144 }; 145 146 class gfxFT2FontList final : public gfxPlatformFontList { 147 using FontListEntry = mozilla::dom::SystemFontListEntry; 148 149 public: 150 gfxFT2FontList(); 151 virtual ~gfxFT2FontList(); 152 153 gfxFontEntry* CreateFontEntry( 154 mozilla::fontlist::Face* aFace, 155 const mozilla::fontlist::Family* aFamily) override; 156 157 gfxFontEntry* LookupLocalFont(FontVisibilityProvider* aFontVisibilityProvider, 158 const nsACString& aFontName, 159 WeightRange aWeightForEntry, 160 StretchRange aStretchForEntry, 161 SlantStyleRange aStyleForEntry) override; 162 163 gfxFontEntry* MakePlatformFont(const nsACString& aFontName, 164 WeightRange aWeightForEntry, 165 StretchRange aStretchForEntry, 166 SlantStyleRange aStyleForEntry, 167 const uint8_t* aFontData, 168 uint32_t aLength) override; 169 170 void WriteCache(); 171 172 void ReadSystemFontList(mozilla::dom::SystemFontList*); 173 174 static gfxFT2FontList* PlatformFontList() { 175 return static_cast<gfxFT2FontList*>( 176 gfxPlatformFontList::PlatformFontList()); 177 } 178 179 gfxFontFamily* CreateFontFamily(const nsACString& aName, 180 FontVisibility aVisibility) const override; 181 182 void WillShutdown(); 183 184 protected: 185 typedef enum { kUnknown, kStandard } StandardFile; 186 187 // initialize font lists 188 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override; 189 190 FontVisibility GetVisibilityForFamily(const nsACString& aName) const; 191 192 void AppendFaceFromFontListEntry(const FontListEntry& aFLE, 193 StandardFile aStdFile) MOZ_REQUIRES(mLock); 194 195 void AppendFacesFromBlob(const nsCString& aFileName, StandardFile aStdFile, 196 hb_blob_t* aBlob, FontNameCache* aCache, 197 uint32_t aTimestamp, uint32_t aFilesize) 198 MOZ_REQUIRES(mLock); 199 200 void AppendFacesFromFontFile(const nsCString& aFileName, 201 FontNameCache* aCache, StandardFile aStdFile) 202 MOZ_REQUIRES(mLock); 203 204 void AppendFacesFromOmnijarEntry(nsZipArchive* aReader, 205 const nsCString& aEntryName, 206 FontNameCache* aCache, bool aJarChanged) 207 MOZ_REQUIRES(mLock); 208 209 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override; 210 void CollectInitData(const FontListEntry& aFLE, const nsCString& aPSName, 211 const nsCString& aFullName, StandardFile aStdFile) 212 MOZ_REQUIRES(mLock); 213 214 nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() 215 override; 216 217 /** 218 * Callback passed to AppendFacesFromCachedFaceList to collect family/face 219 * information in either the unshared or shared list we're building. 220 */ 221 typedef void (*CollectFunc)(const FontListEntry& aFLE, 222 const nsCString& aPSName, 223 const nsCString& aFullName, 224 StandardFile aStdFile); 225 226 /** 227 * Append faces from the face-list record for a specific file. 228 * aCollectFace is a callback that will store the face(s) in either the 229 * unshared mFontFamilies list or the mFamilyInitData/mFaceInitData tables 230 * that will be used to initialize the shared list. 231 * Returns true if it is able to read at least one face entry; false if no 232 * usable face entry was found. 233 */ 234 bool AppendFacesFromCachedFaceList(CollectFunc aCollectFace, 235 const nsCString& aFileName, 236 const nsCString& aFaceList, 237 StandardFile aStdFile) MOZ_REQUIRES(mLock); 238 239 void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, 240 StandardFile aStdFile, hb_face_t* aFace, 241 nsCString& aFaceList) MOZ_REQUIRES(mLock); 242 243 void FindFonts() MOZ_REQUIRES(mLock); 244 245 void FindFontsInOmnijar(FontNameCache* aCache) MOZ_REQUIRES(mLock); 246 247 void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC) 248 MOZ_REQUIRES(mLock); 249 250 FontFamily GetDefaultFontForPlatform( 251 FontVisibilityProvider* aFontVisibilityProvider, 252 const gfxFontStyle* aStyle, nsAtom* aLanguage = nullptr) 253 MOZ_REQUIRES(mLock) override; 254 255 nsTHashSet<nsCString> mSkipSpaceLookupCheckFamilies; 256 257 private: 258 mozilla::UniquePtr<FontNameCache> mFontNameCache; 259 int64_t mJarModifiedTime; 260 RefPtr<WillShutdownObserver> mObserver; 261 262 nsTArray<mozilla::fontlist::Family::InitData> mFamilyInitData; 263 nsClassHashtable<nsCStringHashKey, 264 nsTArray<mozilla::fontlist::Face::InitData>> 265 mFaceInitData; 266 }; 267 268 #endif /* GFX_FT2FONTLIST_H */