/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- * 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_FONTENTRY_H #define GFX_FONTENTRY_H #include "gfxTypes.h" #include "nsString.h" #include "gfxFontConstants.h" #include "gfxFontFeatures.h" #include "gfxFontUtils.h" #include "nsTArray.h" #include "nsTHashtable.h" #include "mozilla/HashFunctions.h" #include "mozilla/MemoryReporting.h" #include "MainThreadUtils.h" #include "nsUnicodeScriptCodes.h" #include "nsDataHashtable.h" #include "harfbuzz/hb.h" #include "mozilla/gfx/2D.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" typedef struct gr_face gr_face; #ifdef DEBUG #include #endif struct gfxFontStyle; class gfxContext; class gfxFont; class gfxFontFamily; class gfxUserFontData; class gfxSVGGlyphs; class FontInfoData; struct FontListSizes; class nsIAtom; namespace mozilla { class SVGContextPaint; }; class gfxCharacterMap : public gfxSparseBitSet { public: nsrefcnt AddRef() { NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); ++mRefCnt; NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this)); return mRefCnt; } nsrefcnt Release() { NS_PRECONDITION(0 != mRefCnt, "dup release"); --mRefCnt; NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap"); if (mRefCnt == 0) { NotifyReleased(); // |this| has been deleted. return 0; } return mRefCnt; } gfxCharacterMap() : mHash(0), mBuildOnTheFly(false), mShared(false) { } explicit gfxCharacterMap(const gfxSparseBitSet& aOther) : gfxSparseBitSet(aOther), mHash(0), mBuildOnTheFly(false), mShared(false) { } void CalcHash() { mHash = GetChecksum(); } size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf); } // hash of the cmap bitvector uint32_t mHash; // if cmap is built on the fly it's never shared bool mBuildOnTheFly; // cmap is shared globally bool mShared; protected: void NotifyReleased(); nsAutoRefCnt mRefCnt; private: gfxCharacterMap(const gfxCharacterMap&); gfxCharacterMap& operator=(const gfxCharacterMap&); }; class gfxFontEntry { public: typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::unicode::Script Script; // Used by stylo NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry) explicit gfxFontEntry(const nsAString& aName, bool aIsStandardFace = false); // unique name for the face, *not* the family; not necessarily the // "real" or user-friendly name, may be an internal identifier const nsString& Name() const { return mName; } // family name const nsString& FamilyName() const { return mFamilyName; } // The following two methods may be relatively expensive, as they // will (usually, except on Linux) load and parse the 'name' table; // they are intended only for the font-inspection API, not for // perf-critical layout/drawing work. // The "real" name of the face, if available from the font resource; // returns Name() if nothing better is available. virtual nsString RealFaceName(); uint16_t Weight() const { return mWeight; } int16_t Stretch() const { return mStretch; } bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; } bool IsLocalUserFont() const { return mIsLocalUserFont; } bool IsFixedPitch() const { return mFixedPitch; } bool IsItalic() const { return mStyle == NS_FONT_STYLE_ITALIC; } bool IsOblique() const { return mStyle == NS_FONT_STYLE_OBLIQUE; } bool IsUpright() const { return mStyle == NS_FONT_STYLE_NORMAL; } bool IsBold() const { return mWeight >= 600; } // bold == weights 600 and above bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGSUB() const { return mIgnoreGSUB; } // whether a feature is supported by the font (limited to a small set // of features for which some form of fallback needs to be implemented) bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag); bool SupportsGraphiteFeature(uint32_t aFeatureTag); // returns a set containing all input glyph ids for a given feature const hb_set_t* InputsForOpenTypeFeature(Script aScript, uint32_t aFeatureTag); virtual bool IsSymbolFont(); virtual bool HasFontTable(uint32_t aTableTag); inline bool HasGraphiteTables() { if (!mCheckedForGraphiteTables) { CheckForGraphiteTables(); mCheckedForGraphiteTables = true; } return mHasGraphiteTables; } inline bool HasCmapTable() { if (!mCharacterMap) { ReadCMAP(); NS_ASSERTION(mCharacterMap, "failed to initialize character map"); } return mHasCmapTable; } inline bool HasCharacter(uint32_t ch) { if (mCharacterMap && mCharacterMap->test(ch)) { return true; } return TestCharacterMap(ch); } virtual bool SkipDuringSystemFallback() { return false; } nsresult InitializeUVSMap(); uint16_t GetUVSGlyph(uint32_t aCh, uint32_t aVS); // All concrete gfxFontEntry subclasses (except gfxUserFontEntry) need // to override this, otherwise the font will never be used as it will // be considered to support no characters. // ReadCMAP() must *always* set the mCharacterMap pointer to a valid // gfxCharacterMap, even if empty, as other code assumes this pointer // can be safely dereferenced. virtual nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr); bool TryGetSVGData(gfxFont* aFont); bool HasSVGGlyph(uint32_t aGlyphId); bool GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId, gfxRect *aResult); bool RenderSVGGlyph(gfxContext *aContext, uint32_t aGlyphId, mozilla::SVGContextPaint* aContextPaint); // Call this when glyph geometry or rendering has changed // (e.g. animated SVG glyphs) void NotifyGlyphsChanged(); bool TryGetColorGlyphs(); bool GetColorLayersInfo(uint32_t aGlyphId, const mozilla::gfx::Color& aDefaultColor, nsTArray& layerGlyphs, nsTArray& layerColors); virtual bool MatchesGenericFamily(const nsACString& aGeneric) const { return true; } virtual bool SupportsLangGroup(nsIAtom *aLangGroup) const { return true; } // Access to raw font table data (needed for Harfbuzz): // returns a pointer to data owned by the fontEntry or the OS, // which will remain valid until the blob is destroyed. // The data MUST be treated as read-only; we may be getting a // reference to a shared system font cache. // // The default implementation uses CopyFontTable to get the data // into a byte array, and maintains a cache of loaded tables. // // Subclasses should override this if they can provide more efficient // access than copying table data into our own buffers. // // Get blob that encapsulates a specific font table, or nullptr if // the table doesn't exist in the font. // // Caller is responsible to call hb_blob_destroy() on the returned blob // (if non-nullptr) when no longer required. For transient access to a // table, use of AutoTable (below) is generally preferred. virtual hb_blob_t *GetFontTable(uint32_t aTag); // Stack-based utility to return a specified table, automatically releasing // the blob when the AutoTable goes out of scope. class AutoTable { public: AutoTable(gfxFontEntry* aFontEntry, uint32_t aTag) { mBlob = aFontEntry->GetFontTable(aTag); } ~AutoTable() { if (mBlob) { hb_blob_destroy(mBlob); } } operator hb_blob_t*() const { return mBlob; } private: hb_blob_t* mBlob; // not implemented: AutoTable(const AutoTable&) = delete; AutoTable& operator=(const AutoTable&) = delete; }; already_AddRefed FindOrMakeFont(const gfxFontStyle *aStyle, bool aNeedsBold, gfxCharacterMap* aUnicodeRangeMap = nullptr); // Get an existing font table cache entry in aBlob if it has been // registered, or return false if not. Callers must call // hb_blob_destroy on aBlob if true is returned. // // Note that some gfxFont implementations may not call this at all, // if it is more efficient to get the table from the OS at that level. bool GetExistingFontTable(uint32_t aTag, hb_blob_t** aBlob); // Elements of aTable are transferred (not copied) to and returned in a // new hb_blob_t which is registered on the gfxFontEntry, but the initial // reference is owned by the caller. Removing the last reference // unregisters the table from the font entry. // // Pass nullptr for aBuffer to indicate that the table is not present and // nullptr will be returned. Also returns nullptr on OOM. hb_blob_t *ShareFontTableAndGetBlob(uint32_t aTag, nsTArray* aTable); // Get the font's unitsPerEm from the 'head' table, in the case of an // sfnt resource. Will return kInvalidUPEM for non-sfnt fonts, // if present on the platform. uint16_t UnitsPerEm(); enum { kMinUPEM = 16, // Limits on valid unitsPerEm range, from the kMaxUPEM = 16384, // OpenType spec kInvalidUPEM = uint16_t(-1) }; // Shaper face accessors: // NOTE that harfbuzz and graphite handle ownership/lifetime of the face // object in completely different ways. // Get HarfBuzz face corresponding to this font file. // Caller must release with hb_face_destroy() when finished with it, // and the font entry will be notified via ForgetHBFace. hb_face_t* GetHBFace(); virtual void ForgetHBFace(); // Get Graphite face corresponding to this font file. // Caller must call gfxFontEntry::ReleaseGrFace when finished with it. gr_face* GetGrFace(); virtual void ReleaseGrFace(gr_face* aFace); // Does the font have graphite contextuals that involve the space glyph // (and therefore we should bypass the word cache)? bool HasGraphiteSpaceContextuals(); // Release any SVG-glyphs document this font may have loaded. void DisconnectSVG(); // Called to notify that aFont is being destroyed. Needed when we're tracking // the fonts belonging to this font entry. void NotifyFontDestroyed(gfxFont* aFont); // For memory reporting of the platform font list. virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; // Used for reporting on individual font entries in the user font cache, // which are not present in the platform font list. size_t ComputedSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; // Used when checking for complex script support, to mask off cmap ranges struct ScriptRange { uint32_t rangeStart; uint32_t rangeEnd; hb_tag_t tags[3]; // one or two OpenType script tags to check, // plus a NULL terminator }; bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags); nsString mName; nsString mFamilyName; uint8_t mStyle : 2; // italic/oblique bool mFixedPitch : 1; bool mIsValid : 1; bool mIsBadUnderlineFont : 1; bool mIsUserFontContainer : 1; // userfont entry bool mIsDataUserFont : 1; // platform font entry (data) bool mIsLocalUserFont : 1; // platform font entry (local) bool mStandardFace : 1; bool mSymbolFont : 1; bool mIgnoreGDEF : 1; bool mIgnoreGSUB : 1; bool mSVGInitialized : 1; bool mHasSpaceFeaturesInitialized : 1; bool mHasSpaceFeatures : 1; bool mHasSpaceFeaturesKerning : 1; bool mHasSpaceFeaturesNonKerning : 1; bool mSkipDefaultFeatureSpaceCheck : 1; bool mGraphiteSpaceContextualsInitialized : 1; bool mHasGraphiteSpaceContextuals : 1; bool mSpaceGlyphIsInvisible : 1; bool mSpaceGlyphIsInvisibleInitialized : 1; bool mHasGraphiteTables : 1; bool mCheckedForGraphiteTables : 1; bool mHasCmapTable : 1; bool mGrFaceInitialized : 1; bool mCheckedForColorGlyph : 1; // bitvector of substitution space features per script, one each // for default and non-default features uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; uint32_t mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; uint16_t mWeight; int16_t mStretch; RefPtr mCharacterMap; uint32_t mUVSOffset; mozilla::UniquePtr mUVSData; mozilla::UniquePtr mUserFontData; mozilla::UniquePtr mSVGGlyphs; // list of gfxFonts that are using SVG glyphs nsTArray mFontsUsingSVGGlyphs; nsTArray mFeatureSettings; mozilla::UniquePtr> mSupportedFeatures; mozilla::UniquePtr> mFeatureInputs; uint32_t mLanguageOverride; // Color Layer font support hb_blob_t* mCOLR; hb_blob_t* mCPAL; protected: friend class gfxPlatformFontList; friend class gfxMacPlatformFontList; friend class gfxUserFcFontEntry; friend class gfxFontFamily; friend class gfxSingleFaceMacFontFamily; friend class gfxUserFontEntry; gfxFontEntry(); // Protected destructor, to discourage deletion outside of Release(): virtual ~gfxFontEntry(); virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) { NS_NOTREACHED("oops, somebody didn't override CreateFontInstance"); return nullptr; } virtual void CheckForGraphiteTables(); // Copy a font table into aBuffer. // The caller will be responsible for ownership of the data. virtual nsresult CopyFontTable(uint32_t aTableTag, nsTArray& aBuffer) { NS_NOTREACHED("forgot to override either GetFontTable or CopyFontTable?"); return NS_ERROR_FAILURE; } // lookup the cmap in cached font data virtual already_AddRefed GetCMAPFromFontInfo(FontInfoData *aFontInfoData, uint32_t& aUVSOffset, bool& aSymbolFont); // helper for HasCharacter(), which is what client code should call virtual bool TestCharacterMap(uint32_t aCh); // Font's unitsPerEm from the 'head' table, if available (will be set to // kInvalidUPEM for non-sfnt font formats) uint16_t mUnitsPerEm; // Shaper-specific face objects, shared by all instantiations of the same // physical font, regardless of size. // Usually, only one of these will actually be created for any given font // entry, depending on the font tables that are present. // hb_face_t is refcounted internally, so each shaper that's using it will // bump the ref count when it acquires the face, and "destroy" (release) it // in its destructor. The font entry has only this non-owning reference to // the face; when the face is deleted, it will tell the font entry to forget // it, so that a new face will be created next time it is needed. hb_face_t* mHBFace; static hb_blob_t* HBGetTable(hb_face_t *face, uint32_t aTag, void *aUserData); // Callback that the hb_face will use to tell us when it is being deleted. static void HBFaceDeletedCallback(void *aUserData); // gr_face is -not- refcounted, so it will be owned directly by the font // entry, and we'll keep a count of how many references we've handed out; // each shaper is responsible to call ReleaseGrFace on its entry when // finished with it, so that we know when it can be deleted. gr_face* mGrFace; // hashtable to map raw table data ptr back to its owning blob, for use by // graphite table-release callback nsDataHashtable,void*>* mGrTableMap; // number of current users of this entry's mGrFace nsrefcnt mGrFaceRefCnt; static const void* GrGetTable(const void *aAppFaceHandle, unsigned int aName, size_t *aLen); static void GrReleaseTable(const void *aAppFaceHandle, const void *aTableBuffer); // For memory reporting: size of user-font data belonging to this entry. // We record this in the font entry because the actual data block may be // handed over to platform APIs, so that it would become difficult (and // platform-specific) to measure it directly at report-gathering time. uint32_t mComputedSizeOfUserFont; private: /** * Font table hashtable, to support GetFontTable for harfbuzz. * * The harfbuzz shaper (and potentially other clients) needs access to raw * font table data. This needs to be cached so that it can be used * repeatedly (each time we construct a text run; in some cases, for * each character/glyph within the run) without re-fetching large tables * every time. * * Because we may instantiate many gfxFonts for the same physical font * file (at different sizes), we should ensure that they can share a * single cached copy of the font tables. To do this, we implement table * access and sharing on the fontEntry rather than the font itself. * * The default implementation uses GetFontTable() to read font table * data into byte arrays, and wraps them in blobs which are registered in * a hashtable. The hashtable can then return pre-existing blobs to * harfbuzz. * * Harfbuzz will "destroy" the blobs when it is finished with them. When * the last blob reference is removed, the FontTableBlobData user data * will remove the blob from the hashtable if still registered. */ class FontTableBlobData; /** * FontTableHashEntry manages the entries of hb_blob_t's containing font * table data. * * This is used to share font tables across fonts with the same * font entry (but different sizes) for use by HarfBuzz. The hashtable * does not own a strong reference to the blob, but keeps a weak pointer, * managed by FontTableBlobData. Similarly FontTableBlobData keeps only a * weak pointer to the hashtable, managed by FontTableHashEntry. */ class FontTableHashEntry : public nsUint32HashKey { public: // Declarations for nsTHashtable typedef nsUint32HashKey KeyClass; typedef KeyClass::KeyType KeyType; typedef KeyClass::KeyTypePointer KeyTypePointer; explicit FontTableHashEntry(KeyTypePointer aTag) : KeyClass(aTag) , mSharedBlobData(nullptr) , mBlob(nullptr) { } // NOTE: This assumes the new entry belongs to the same hashtable as // the old, because the mHashtable pointer in mSharedBlobData (if // present) will not be updated. FontTableHashEntry(FontTableHashEntry&& toMove) : KeyClass(mozilla::Move(toMove)) , mSharedBlobData(mozilla::Move(toMove.mSharedBlobData)) , mBlob(mozilla::Move(toMove.mBlob)) { toMove.mSharedBlobData = nullptr; toMove.mBlob = nullptr; } ~FontTableHashEntry() { Clear(); } // FontTable/Blob API // Transfer (not copy) elements of aTable to a new hb_blob_t and // return ownership to the caller. A weak reference to the blob is // recorded in the hashtable entry so that others may use the same // table. hb_blob_t * ShareTableAndGetBlob(nsTArray&& aTable, nsTHashtable *aHashtable); // Return a strong reference to the blob. // Callers must hb_blob_destroy the returned blob. hb_blob_t *GetBlob() const; void Clear(); size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; private: static void DeleteFontTableBlobData(void *aBlobData); // not implemented FontTableHashEntry& operator=(FontTableHashEntry& toCopy); FontTableBlobData *mSharedBlobData; hb_blob_t *mBlob; }; mozilla::UniquePtr > mFontTableCache; gfxFontEntry(const gfxFontEntry&); gfxFontEntry& operator=(const gfxFontEntry&); }; // used when iterating over all fonts looking for a match for a given character struct GlobalFontMatch { GlobalFontMatch(const uint32_t aCharacter, mozilla::unicode::Script aRunScript, const gfxFontStyle *aStyle) : mCh(aCharacter), mRunScript(aRunScript), mStyle(aStyle), mMatchRank(0), mCount(0), mCmapsTested(0) { } const uint32_t mCh; // codepoint to be matched mozilla::unicode::Script mRunScript; // Unicode script for the codepoint const gfxFontStyle* mStyle; // style to match int32_t mMatchRank; // metric indicating closest match RefPtr mBestMatch; // current best match RefPtr mMatchedFamily; // the family it belongs to uint32_t mCount; // number of fonts matched uint32_t mCmapsTested; // number of cmaps tested }; class gfxFontFamily { public: // Used by stylo NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFamily) explicit gfxFontFamily(const nsAString& aName) : mName(aName), mOtherFamilyNamesInitialized(false), mHasOtherFamilyNames(false), mFaceNamesInitialized(false), mHasStyles(false), mIsSimpleFamily(false), mIsBadUnderlineFamily(false), mFamilyCharacterMapInitialized(false), mSkipDefaultFeatureSpaceCheck(false), mCheckForFallbackFaces(false) { } const nsString& Name() { return mName; } virtual void LocalizedName(nsAString& aLocalizedName); virtual bool HasOtherFamilyNames(); nsTArray >& GetFontList() { return mAvailableFonts; } void AddFontEntry(RefPtr aFontEntry) { // bug 589682 - set the IgnoreGDEF flag on entries for Italic faces // of Times New Roman, because of buggy table in those fonts if (aFontEntry->IsItalic() && !aFontEntry->IsUserFont() && Name().EqualsLiteral("Times New Roman")) { aFontEntry->mIgnoreGDEF = true; } if (aFontEntry->mFamilyName.IsEmpty()) { aFontEntry->mFamilyName = Name(); } else { MOZ_ASSERT(aFontEntry->mFamilyName.Equals(Name())); } aFontEntry->mSkipDefaultFeatureSpaceCheck = mSkipDefaultFeatureSpaceCheck; mAvailableFonts.AppendElement(aFontEntry); } // note that the styles for this family have been added bool HasStyles() { return mHasStyles; } void SetHasStyles(bool aHasStyles) { mHasStyles = aHasStyles; } // choose a specific face to match a style using CSS font matching // rules (weight matching occurs here). may return a face that doesn't // precisely match (e.g. normal face when no italic face exists). // aNeedsSyntheticBold is set to true when synthetic bolding is // needed, false otherwise gfxFontEntry *FindFontForStyle(const gfxFontStyle& aFontStyle, bool& aNeedsSyntheticBold); virtual void FindAllFontsForStyle(const gfxFontStyle& aFontStyle, nsTArray& aFontEntryList, bool& aNeedsSyntheticBold); // checks for a matching font within the family // used as part of the font fallback process void FindFontForChar(GlobalFontMatch *aMatchData); // checks all fonts for a matching font within the family void SearchAllFontsForChar(GlobalFontMatch *aMatchData); // read in other family names, if any, and use functor to add each into cache virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList); // helper method for reading localized family names from the name table // of a single face static void ReadOtherFamilyNamesForFace(const nsAString& aFamilyName, const char *aNameData, uint32_t aDataLength, nsTArray& aOtherFamilyNames, bool useFullName); // set when other family names have been read in void SetOtherFamilyNamesInitialized() { mOtherFamilyNamesInitialized = true; } // read in other localized family names, fullnames and Postscript names // for all faces and append to lookup tables virtual void ReadFaceNames(gfxPlatformFontList *aPlatformFontList, bool aNeedFullnamePostscriptNames, FontInfoData *aFontInfoData = nullptr); // find faces belonging to this family (platform implementations override this; // should be made pure virtual once all subclasses have been updated) virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) { } // search for a specific face using the Postscript name gfxFontEntry* FindFont(const nsAString& aPostscriptName); // read in cmaps for all the faces void ReadAllCMAPs(FontInfoData *aFontInfoData = nullptr); bool TestCharacterMap(uint32_t aCh) { if (!mFamilyCharacterMapInitialized) { ReadAllCMAPs(); } return mFamilyCharacterMap.test(aCh); } void ResetCharacterMap() { mFamilyCharacterMap.reset(); mFamilyCharacterMapInitialized = false; } // mark this family as being in the "bad" underline offset blacklist void SetBadUnderlineFamily() { mIsBadUnderlineFamily = true; if (mHasStyles) { SetBadUnderlineFonts(); } } bool IsBadUnderlineFamily() const { return mIsBadUnderlineFamily; } bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; } // sort available fonts to put preferred (standard) faces towards the end void SortAvailableFonts(); // check whether the family fits into the simple 4-face model, // so we can use simplified style-matching; // if so set the mIsSimpleFamily flag (defaults to False before we've checked) void CheckForSimpleFamily(); // For memory reporter virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; #ifdef DEBUG // Only used for debugging checks - does a linear search bool ContainsFace(gfxFontEntry* aFontEntry); #endif void SetSkipSpaceFeatureCheck(bool aSkipCheck) { mSkipDefaultFeatureSpaceCheck = aSkipCheck; } protected: // Protected destructor, to discourage deletion outside of Release(): virtual ~gfxFontFamily(); bool ReadOtherFamilyNamesForFace(gfxPlatformFontList *aPlatformFontList, hb_blob_t *aNameTable, bool useFullName = false); // set whether this font family is in "bad" underline offset blacklist. void SetBadUnderlineFonts() { uint32_t i, numFonts = mAvailableFonts.Length(); for (i = 0; i < numFonts; i++) { if (mAvailableFonts[i]) { mAvailableFonts[i]->mIsBadUnderlineFont = true; } } } nsString mName; nsTArray > mAvailableFonts; gfxSparseBitSet mFamilyCharacterMap; bool mOtherFamilyNamesInitialized : 1; bool mHasOtherFamilyNames : 1; bool mFaceNamesInitialized : 1; bool mHasStyles : 1; bool mIsSimpleFamily : 1; bool mIsBadUnderlineFamily : 1; bool mFamilyCharacterMapInitialized : 1; bool mSkipDefaultFeatureSpaceCheck : 1; bool mCheckForFallbackFaces : 1; // check other faces for character enum { // for "simple" families, the faces are stored in mAvailableFonts // with fixed positions: kRegularFaceIndex = 0, kBoldFaceIndex = 1, kItalicFaceIndex = 2, kBoldItalicFaceIndex = 3, // mask values for selecting face with bold and/or italic attributes kBoldMask = 0x01, kItalicMask = 0x02 }; }; #endif