diff options
Diffstat (limited to 'gfx/thebes/gfxFT2FontList.h')
-rw-r--r-- | gfx/thebes/gfxFT2FontList.h | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h new file mode 100644 index 0000000000..269fbf28db --- /dev/null +++ b/gfx/thebes/gfxFT2FontList.h @@ -0,0 +1,262 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_FT2FONTLIST_H +#define GFX_FT2FONTLIST_H + +#include "mozilla/MemoryReporting.h" +#include "gfxFT2FontBase.h" +#include "gfxPlatformFontList.h" +#include "nsTHashSet.h" + +namespace mozilla { +namespace dom { +class SystemFontListEntry; +}; +namespace gfx { +class FTUserFontData; +}; +}; // namespace mozilla + +class FontNameCache; +typedef struct FT_FaceRec_* FT_Face; +class nsZipArchive; +class WillShutdownObserver; + +class FT2FontEntry final : public gfxFT2FontEntryBase { + friend class gfxFT2FontList; + + using FontListEntry = mozilla::dom::SystemFontListEntry; + using FTUserFontData = mozilla::gfx::FTUserFontData; + + public: + explicit FT2FontEntry(const nsACString& aFaceName) + : gfxFT2FontEntryBase(aFaceName), mFTFontIndex(0) {} + + ~FT2FontEntry(); + + gfxFontEntry* Clone() const override; + + const nsCString& GetName() const { return Name(); } + + // create a font entry for a downloaded font + static FT2FontEntry* CreateFontEntry( + const nsACString& aFontName, WeightRange aWeight, StretchRange aStretch, + SlantStyleRange aStyle, const uint8_t* aFontData, uint32_t aLength); + + // create a font entry representing an installed font, identified by + // a FontListEntry; the freetype and cairo faces will not be instantiated + // until actually needed + static FT2FontEntry* CreateFontEntry(const FontListEntry& aFLE); + + // Create a font entry with the given name; if it is an installed font, + // also record the filename and index. + // If a non-null harfbuzz face is passed, also set style/weight/stretch + // properties of the entry from the values in the face. + static FT2FontEntry* CreateFontEntry(const nsACString& aName, + const char* aFilename, uint8_t aIndex, + const hb_face_t* aFace); + + gfxFont* CreateFontInstance(const gfxFontStyle* aStyle) override; + + nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; + + hb_blob_t* GetFontTable(uint32_t aTableTag) override; + + bool HasFontTable(uint32_t aTableTag) override; + nsresult CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>&) override; + + bool HasVariations() override; + void GetVariationAxes( + nsTArray<gfxFontVariationAxis>& aVariationAxes) override; + void GetVariationInstances( + nsTArray<gfxFontVariationInstance>& aInstances) override; + + // Check for various kinds of brokenness, and set flags on the entry + // accordingly so that we avoid using bad font tables + void CheckForBrokenFont(gfxFontFamily* aFamily); + void CheckForBrokenFont(const nsACString& aFamilyKey); + + already_AddRefed<mozilla::gfx::SharedFTFace> GetFTFace(bool aCommit = false); + FTUserFontData* GetUserFontData(); + + FT_MM_Var* GetMMVar() override; + + // Get a harfbuzz face for this font, if possible. The caller is responsible + // to destroy the face when no longer needed. + // This may be a bit expensive, so avoid calling multiple times if the same + // face can be re-used for several purposes instead. + hb_face_t* CreateHBFace() const; + + /** + * Append this face's metadata to aFaceList for storage in the FontNameCache + * (for faster startup). + * The aPSName and aFullName parameters here can in principle be empty, + * but if they are missing for a given face then src:local() lookups will + * not be able to find it when the shared font list is in use. + */ + void AppendToFaceList(nsCString& aFaceList, const nsACString& aFamilyName, + const nsACString& aPSName, const nsACString& aFullName, + FontVisibility aVisibility); + + void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, + FontListSizes* aSizes) const override; + void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, + FontListSizes* aSizes) const override; + + // Strong reference (addref'd), but held in an atomic ptr rather than a + // normal RefPtr. + mozilla::Atomic<mozilla::gfx::SharedFTFace*> mFTFace; + + FT_MM_Var* mMMVar = nullptr; + + nsCString mFilename; + uint8_t mFTFontIndex; + + mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFreeType> mUnscaledFont; + + nsTHashSet<uint32_t> mAvailableTables; + + enum class HasVariationsState : int8_t { + Uninitialized = -1, + No = 0, + Yes = 1, + }; + std::atomic<HasVariationsState> mHasVariations = + HasVariationsState::Uninitialized; + + bool mMMVarInitialized = false; +}; + +class FT2FontFamily final : public gfxFontFamily { + using FontListEntry = mozilla::dom::SystemFontListEntry; + + public: + explicit FT2FontFamily(const nsACString& aName, FontVisibility aVisibility) + : gfxFontFamily(aName, aVisibility) {} + + // Append this family's faces to the IPC fontlist + void AddFacesToFontList(nsTArray<FontListEntry>* aFontList); + + void FinalizeMemberList(bool aSortFaces); +}; + +class gfxFT2FontList final : public gfxPlatformFontList { + using FontListEntry = mozilla::dom::SystemFontListEntry; + + public: + gfxFT2FontList(); + virtual ~gfxFT2FontList(); + + gfxFontEntry* CreateFontEntry( + mozilla::fontlist::Face* aFace, + const mozilla::fontlist::Family* aFamily) override; + + gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext, + const nsACString& aFontName, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) override; + + gfxFontEntry* MakePlatformFont(const nsACString& aFontName, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, + const uint8_t* aFontData, + uint32_t aLength) override; + + void WriteCache(); + + void ReadSystemFontList(mozilla::dom::SystemFontList*); + + static gfxFT2FontList* PlatformFontList() { + return static_cast<gfxFT2FontList*>( + gfxPlatformFontList::PlatformFontList()); + } + + gfxFontFamily* CreateFontFamily(const nsACString& aName, + FontVisibility aVisibility) const override; + + void WillShutdown(); + + protected: + typedef enum { kUnknown, kStandard } StandardFile; + + // initialize font lists + nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override; + + void AppendFaceFromFontListEntry(const FontListEntry& aFLE, + StandardFile aStdFile) MOZ_REQUIRES(mLock); + + void AppendFacesFromBlob(const nsCString& aFileName, StandardFile aStdFile, + hb_blob_t* aBlob, FontNameCache* aCache, + uint32_t aTimestamp, uint32_t aFilesize) + MOZ_REQUIRES(mLock); + + void AppendFacesFromFontFile(const nsCString& aFileName, + FontNameCache* aCache, StandardFile aStdFile) + MOZ_REQUIRES(mLock); + + void AppendFacesFromOmnijarEntry(nsZipArchive* aReader, + const nsCString& aEntryName, + FontNameCache* aCache, bool aJarChanged) + MOZ_REQUIRES(mLock); + + void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override; + void CollectInitData(const FontListEntry& aFLE, const nsCString& aPSName, + const nsCString& aFullName, StandardFile aStdFile); + + /** + * Callback passed to AppendFacesFromCachedFaceList to collect family/face + * information in either the unshared or shared list we're building. + */ + typedef void (*CollectFunc)(const FontListEntry& aFLE, + const nsCString& aPSName, + const nsCString& aFullName, + StandardFile aStdFile); + + /** + * Append faces from the face-list record for a specific file. + * aCollectFace is a callback that will store the face(s) in either the + * unshared mFontFamilies list or the mFamilyInitData/mFaceInitData tables + * that will be used to initialize the shared list. + * Returns true if it is able to read at least one face entry; false if no + * usable face entry was found. + */ + bool AppendFacesFromCachedFaceList(CollectFunc aCollectFace, + const nsCString& aFileName, + const nsCString& aFaceList, + StandardFile aStdFile) MOZ_REQUIRES(mLock); + + void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, + StandardFile aStdFile, hb_face_t* aFace, + nsCString& aFaceList) MOZ_REQUIRES(mLock); + + void FindFonts() MOZ_REQUIRES(mLock); + + void FindFontsInOmnijar(FontNameCache* aCache) MOZ_REQUIRES(mLock); + + void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC) + MOZ_REQUIRES(mLock); + + FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext, + const gfxFontStyle* aStyle, + nsAtom* aLanguage = nullptr) + MOZ_REQUIRES(mLock) override; + + nsTHashSet<nsCString> mSkipSpaceLookupCheckFamilies; + + private: + mozilla::UniquePtr<FontNameCache> mFontNameCache; + int64_t mJarModifiedTime; + RefPtr<WillShutdownObserver> mObserver; + + nsTArray<mozilla::fontlist::Family::InitData> mFamilyInitData; + nsClassHashtable<nsCStringHashKey, + nsTArray<mozilla::fontlist::Face::InitData>> + mFaceInitData; +}; + +#endif /* GFX_FT2FONTLIST_H */ |