summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxFontEntry.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes/gfxFontEntry.h')
-rw-r--r--gfx/thebes/gfxFontEntry.h777
1 files changed, 777 insertions, 0 deletions
diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h
new file mode 100644
index 000000000..7f0e7215b
--- /dev/null
+++ b/gfx/thebes/gfxFontEntry.h
@@ -0,0 +1,777 @@
+/* -*- 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 "nsUnicodeScriptCodes.h"
+#include "nsDataHashtable.h"
+#include "harfbuzz/hb.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/UniquePtr.h"
+
+typedef struct gr_face gr_face;
+
+#ifdef DEBUG
+#include <stdio.h>
+#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;
+
+ NS_INLINE_DECL_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<uint16_t>& layerGlyphs,
+ nsTArray<mozilla::gfx::Color>& 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<gfxFont>
+ 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<uint8_t>* 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<gfxCharacterMap> mCharacterMap;
+ uint32_t mUVSOffset;
+ mozilla::UniquePtr<uint8_t[]> mUVSData;
+ mozilla::UniquePtr<gfxUserFontData> mUserFontData;
+ mozilla::UniquePtr<gfxSVGGlyphs> mSVGGlyphs;
+ // list of gfxFonts that are using SVG glyphs
+ nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
+ nsTArray<gfxFontFeature> mFeatureSettings;
+ mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey,bool>> mSupportedFeatures;
+ mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey,hb_set_t*>> 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<uint8_t>& aBuffer) {
+ NS_NOTREACHED("forgot to override either GetFontTable or CopyFontTable?");
+ return NS_ERROR_FAILURE;
+ }
+
+ // lookup the cmap in cached font data
+ virtual already_AddRefed<gfxCharacterMap>
+ 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<nsPtrHashKey<const void>,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<uint8_t>&& aTable,
+ nsTHashtable<FontTableHashEntry> *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<nsTHashtable<FontTableHashEntry> > 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<gfxFontEntry> mBestMatch; // current best match
+ RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
+ uint32_t mCount; // number of fonts matched
+ uint32_t mCmapsTested; // number of cmaps tested
+};
+
+class gfxFontFamily {
+public:
+ NS_INLINE_DECL_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<RefPtr<gfxFontEntry> >& GetFontList() { return mAvailableFonts; }
+
+ void AddFontEntry(RefPtr<gfxFontEntry> 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<gfxFontEntry*>& 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<nsString>& 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<RefPtr<gfxFontEntry> > 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