LCOV - code coverage report
Current view: top level - gfx/thebes - gfxFontEntry.h (source / functions) Hit Total Coverage
Test: output.info Lines: 52 113 46.0 %
Date: 2017-07-14 16:53:18 Functions: 29 49 59.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       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_FONTENTRY_H
       7             : #define GFX_FONTENTRY_H
       8             : 
       9             : #include "gfxTypes.h"
      10             : #include "nsString.h"
      11             : #include "gfxFontConstants.h"
      12             : #include "gfxFontFeatures.h"
      13             : #include "gfxFontUtils.h"
      14             : #include "nsTArray.h"
      15             : #include "nsTHashtable.h"
      16             : #include "mozilla/HashFunctions.h"
      17             : #include "mozilla/MemoryReporting.h"
      18             : #include "MainThreadUtils.h"
      19             : #include "nsUnicodeScriptCodes.h"
      20             : #include "nsDataHashtable.h"
      21             : #include "harfbuzz/hb.h"
      22             : #include "mozilla/gfx/2D.h"
      23             : #include "mozilla/UniquePtr.h"
      24             : #include "mozilla/WeakPtr.h"
      25             : 
      26             : typedef struct gr_face gr_face;
      27             : 
      28             : #ifdef DEBUG
      29             : #include <stdio.h>
      30             : #endif
      31             : 
      32             : struct gfxFontStyle;
      33             : class gfxContext;
      34             : class gfxFont;
      35             : class gfxFontFamily;
      36             : class gfxUserFontData;
      37             : class gfxSVGGlyphs;
      38             : class FontInfoData;
      39             : struct FontListSizes;
      40             : class nsIAtom;
      41             : 
      42             : namespace mozilla {
      43             : class SVGContextPaint;
      44             : };
      45             : 
      46           0 : class gfxCharacterMap : public gfxSparseBitSet {
      47             : public:
      48           0 :     nsrefcnt AddRef() {
      49           0 :         NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
      50           0 :         ++mRefCnt;
      51           0 :         NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
      52           0 :         return mRefCnt;
      53             :     }
      54             : 
      55           0 :     nsrefcnt Release() {
      56           0 :         NS_PRECONDITION(0 != mRefCnt, "dup release");
      57           0 :         --mRefCnt;
      58           0 :         NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
      59           0 :         if (mRefCnt == 0) {
      60           0 :             NotifyReleased();
      61             :             // |this| has been deleted.
      62           0 :             return 0;
      63             :         }
      64           0 :         return mRefCnt;
      65             :     }
      66             : 
      67           0 :     gfxCharacterMap() :
      68           0 :         mHash(0), mBuildOnTheFly(false), mShared(false)
      69           0 :     { }
      70             : 
      71             :     explicit gfxCharacterMap(const gfxSparseBitSet& aOther) :
      72             :         gfxSparseBitSet(aOther),
      73             :         mHash(0), mBuildOnTheFly(false), mShared(false)
      74             :     { }
      75             : 
      76           0 :     void CalcHash() { mHash = GetChecksum(); }
      77             : 
      78             :     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
      79             :         return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
      80             :     }
      81             : 
      82             :     // hash of the cmap bitvector
      83             :     uint32_t mHash;
      84             : 
      85             :     // if cmap is built on the fly it's never shared
      86             :     bool mBuildOnTheFly;
      87             : 
      88             :     // cmap is shared globally
      89             :     bool mShared;
      90             : 
      91             : protected:
      92             :     void NotifyReleased();
      93             : 
      94             :     nsAutoRefCnt mRefCnt;
      95             : 
      96             : private:
      97             :     gfxCharacterMap(const gfxCharacterMap&);
      98             :     gfxCharacterMap& operator=(const gfxCharacterMap&);
      99             : };
     100             : 
     101             : class gfxFontEntry {
     102             : public:
     103             :     typedef mozilla::gfx::DrawTarget DrawTarget;
     104             :     typedef mozilla::unicode::Script Script;
     105             : 
     106             :     // Used by stylo
     107         401 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry)
     108             : 
     109             :     explicit gfxFontEntry(const nsAString& aName, bool aIsStandardFace = false);
     110             : 
     111             :     // unique name for the face, *not* the family; not necessarily the
     112             :     // "real" or user-friendly name, may be an internal identifier
     113           0 :     const nsString& Name() const { return mName; }
     114             : 
     115             :     // family name
     116          34 :     const nsString& FamilyName() const { return mFamilyName; }
     117             : 
     118             :     // The following two methods may be relatively expensive, as they
     119             :     // will (usually, except on Linux) load and parse the 'name' table;
     120             :     // they are intended only for the font-inspection API, not for
     121             :     // perf-critical layout/drawing work.
     122             : 
     123             :     // The "real" name of the face, if available from the font resource;
     124             :     // returns Name() if nothing better is available.
     125             :     virtual nsString RealFaceName();
     126             : 
     127         179 :     uint16_t Weight() const { return mWeight; }
     128          41 :     int16_t Stretch() const { return mStretch; }
     129             : 
     130         126 :     bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; }
     131           0 :     bool IsLocalUserFont() const { return mIsLocalUserFont; }
     132           0 :     bool IsFixedPitch() const { return mFixedPitch; }
     133         114 :     bool IsItalic() const { return mStyle == NS_FONT_STYLE_ITALIC; }
     134          10 :     bool IsOblique() const { return mStyle == NS_FONT_STYLE_OBLIQUE; }
     135         115 :     bool IsUpright() const { return mStyle == NS_FONT_STYLE_NORMAL; }
     136          14 :     bool IsBold() const { return mWeight >= 600; } // bold == weights 600 and above
     137           4 :     bool IgnoreGDEF() const { return mIgnoreGDEF; }
     138           4 :     bool IgnoreGSUB() const { return mIgnoreGSUB; }
     139             : 
     140             :     // whether a feature is supported by the font (limited to a small set
     141             :     // of features for which some form of fallback needs to be implemented)
     142             :     bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag);
     143             :     bool SupportsGraphiteFeature(uint32_t aFeatureTag);
     144             : 
     145             :     // returns a set containing all input glyph ids for a given feature
     146             :     const hb_set_t*
     147             :     InputsForOpenTypeFeature(Script aScript, uint32_t aFeatureTag);
     148             : 
     149             :     virtual bool IsSymbolFont();
     150             : 
     151             :     virtual bool HasFontTable(uint32_t aTableTag);
     152             : 
     153         105 :     inline bool HasGraphiteTables() {
     154         105 :         if (!mCheckedForGraphiteTables) {
     155           2 :             CheckForGraphiteTables();
     156           2 :             mCheckedForGraphiteTables = true;
     157             :         }
     158         105 :         return mHasGraphiteTables;
     159             :     }
     160             : 
     161           0 :     inline bool HasCmapTable() {
     162           0 :         if (!mCharacterMap) {
     163           0 :             ReadCMAP();
     164           0 :             NS_ASSERTION(mCharacterMap, "failed to initialize character map");
     165             :         }
     166           0 :         return mHasCmapTable;
     167             :     }
     168             : 
     169         860 :     inline bool HasCharacter(uint32_t ch) {
     170         860 :         if (mCharacterMap && mCharacterMap->test(ch)) {
     171           0 :             return true;
     172             :         }
     173         860 :         return TestCharacterMap(ch);
     174             :     }
     175             : 
     176           0 :     virtual bool SkipDuringSystemFallback() { return false; }
     177             :     nsresult InitializeUVSMap();
     178             :     uint16_t GetUVSGlyph(uint32_t aCh, uint32_t aVS);
     179             : 
     180             :     // All concrete gfxFontEntry subclasses (except gfxUserFontEntry) need
     181             :     // to override this, otherwise the font will never be used as it will
     182             :     // be considered to support no characters.
     183             :     // ReadCMAP() must *always* set the mCharacterMap pointer to a valid
     184             :     // gfxCharacterMap, even if empty, as other code assumes this pointer
     185             :     // can be safely dereferenced.
     186             :     virtual nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr);
     187             : 
     188             :     bool TryGetSVGData(gfxFont* aFont);
     189             :     bool HasSVGGlyph(uint32_t aGlyphId);
     190             :     bool GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId,
     191             :                             gfxRect *aResult);
     192             :     void RenderSVGGlyph(gfxContext *aContext, uint32_t aGlyphId,
     193             :                         mozilla::SVGContextPaint* aContextPaint);
     194             :     // Call this when glyph geometry or rendering has changed
     195             :     // (e.g. animated SVG glyphs)
     196             :     void NotifyGlyphsChanged();
     197             : 
     198             :     bool     TryGetColorGlyphs();
     199             :     bool     GetColorLayersInfo(uint32_t aGlyphId,
     200             :                                 const mozilla::gfx::Color& aDefaultColor,
     201             :                                 nsTArray<uint16_t>& layerGlyphs,
     202             :                                 nsTArray<mozilla::gfx::Color>& layerColors);
     203             : 
     204           0 :     virtual bool MatchesGenericFamily(const nsACString& aGeneric) const {
     205           0 :         return true;
     206             :     }
     207           0 :     virtual bool SupportsLangGroup(nsIAtom *aLangGroup) const {
     208           0 :         return true;
     209             :     }
     210             : 
     211             :     // Access to raw font table data (needed for Harfbuzz):
     212             :     // returns a pointer to data owned by the fontEntry or the OS,
     213             :     // which will remain valid until the blob is destroyed.
     214             :     // The data MUST be treated as read-only; we may be getting a
     215             :     // reference to a shared system font cache.
     216             :     //
     217             :     // The default implementation uses CopyFontTable to get the data
     218             :     // into a byte array, and maintains a cache of loaded tables.
     219             :     //
     220             :     // Subclasses should override this if they can provide more efficient
     221             :     // access than copying table data into our own buffers.
     222             :     //
     223             :     // Get blob that encapsulates a specific font table, or nullptr if
     224             :     // the table doesn't exist in the font.
     225             :     //
     226             :     // Caller is responsible to call hb_blob_destroy() on the returned blob
     227             :     // (if non-nullptr) when no longer required. For transient access to a
     228             :     // table, use of AutoTable (below) is generally preferred.
     229             :     virtual hb_blob_t *GetFontTable(uint32_t aTag);
     230             : 
     231             :     // Stack-based utility to return a specified table, automatically releasing
     232             :     // the blob when the AutoTable goes out of scope.
     233             :     class AutoTable {
     234             :     public:
     235           4 :         AutoTable(gfxFontEntry* aFontEntry, uint32_t aTag)
     236           4 :         {
     237           4 :             mBlob = aFontEntry->GetFontTable(aTag);
     238           4 :         }
     239           8 :         ~AutoTable() {
     240           4 :             if (mBlob) {
     241           2 :                 hb_blob_destroy(mBlob);
     242             :             }
     243           4 :         }
     244           6 :         operator hb_blob_t*() const { return mBlob; }
     245             :     private:
     246             :         hb_blob_t* mBlob;
     247             :         // not implemented:
     248             :         AutoTable(const AutoTable&) = delete;
     249             :         AutoTable& operator=(const AutoTable&) = delete;
     250             :     };
     251             : 
     252             :     // Return a font instance for a particular style. This may be a newly-
     253             :     // created instance, or a font already in the global cache.
     254             :     // We can't return a UniquePtr here, because we may be returning a shared
     255             :     // cached instance; but we also don't return already_AddRefed, because
     256             :     // the caller may only need to use the font temporarily and doesn't need
     257             :     // a strong reference.
     258             :     gfxFont* FindOrMakeFont(const gfxFontStyle *aStyle,
     259             :                             bool aNeedsBold,
     260             :                             gfxCharacterMap* aUnicodeRangeMap = nullptr);
     261             : 
     262             :     // Get an existing font table cache entry in aBlob if it has been
     263             :     // registered, or return false if not.  Callers must call
     264             :     // hb_blob_destroy on aBlob if true is returned.
     265             :     //
     266             :     // Note that some gfxFont implementations may not call this at all,
     267             :     // if it is more efficient to get the table from the OS at that level.
     268             :     bool GetExistingFontTable(uint32_t aTag, hb_blob_t** aBlob);
     269             : 
     270             :     // Elements of aTable are transferred (not copied) to and returned in a
     271             :     // new hb_blob_t which is registered on the gfxFontEntry, but the initial
     272             :     // reference is owned by the caller.  Removing the last reference
     273             :     // unregisters the table from the font entry.
     274             :     //
     275             :     // Pass nullptr for aBuffer to indicate that the table is not present and
     276             :     // nullptr will be returned.  Also returns nullptr on OOM.
     277             :     hb_blob_t *ShareFontTableAndGetBlob(uint32_t aTag,
     278             :                                         nsTArray<uint8_t>* aTable);
     279             : 
     280             :     // Get the font's unitsPerEm from the 'head' table, in the case of an
     281             :     // sfnt resource. Will return kInvalidUPEM for non-sfnt fonts,
     282             :     // if present on the platform.
     283             :     uint16_t UnitsPerEm();
     284             :     enum {
     285             :         kMinUPEM = 16,    // Limits on valid unitsPerEm range, from the
     286             :         kMaxUPEM = 16384, // OpenType spec
     287             :         kInvalidUPEM = uint16_t(-1)
     288             :     };
     289             : 
     290             :     // Shaper face accessors:
     291             :     // NOTE that harfbuzz and graphite handle ownership/lifetime of the face
     292             :     // object in completely different ways.
     293             : 
     294             :     // Get HarfBuzz face corresponding to this font file.
     295             :     // Caller must release with hb_face_destroy() when finished with it,
     296             :     // and the font entry will be notified via ForgetHBFace.
     297             :     hb_face_t* GetHBFace();
     298             :     virtual void ForgetHBFace();
     299             : 
     300             :     // Get Graphite face corresponding to this font file.
     301             :     // Caller must call gfxFontEntry::ReleaseGrFace when finished with it.
     302             :     gr_face* GetGrFace();
     303             :     virtual void ReleaseGrFace(gr_face* aFace);
     304             : 
     305             :     // Does the font have graphite contextuals that involve the space glyph
     306             :     // (and therefore we should bypass the word cache)?
     307             :     bool HasGraphiteSpaceContextuals();
     308             : 
     309             :     // Release any SVG-glyphs document this font may have loaded.
     310             :     void DisconnectSVG();
     311             : 
     312             :     // Called to notify that aFont is being destroyed. Needed when we're tracking
     313             :     // the fonts belonging to this font entry.
     314             :     void NotifyFontDestroyed(gfxFont* aFont);
     315             : 
     316             :     // For memory reporting of the platform font list.
     317             :     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
     318             :                                         FontListSizes* aSizes) const;
     319             :     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
     320             :                                         FontListSizes* aSizes) const;
     321             : 
     322             :     // Used for reporting on individual font entries in the user font cache,
     323             :     // which are not present in the platform font list.
     324             :     size_t
     325             :     ComputedSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     326             : 
     327             :     // Used when checking for complex script support, to mask off cmap ranges
     328             :     struct ScriptRange {
     329             :         uint32_t         rangeStart;
     330             :         uint32_t         rangeEnd;
     331             :         hb_tag_t         tags[3]; // one or two OpenType script tags to check,
     332             :                                   // plus a NULL terminator
     333             :     };
     334             : 
     335             :     bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags);
     336             : 
     337             :     nsString         mName;
     338             :     nsString         mFamilyName;
     339             : 
     340             :     uint8_t          mStyle       : 2; // italic/oblique
     341             :     bool             mFixedPitch  : 1;
     342             :     bool             mIsValid     : 1;
     343             :     bool             mIsBadUnderlineFont : 1;
     344             :     bool             mIsUserFontContainer : 1; // userfont entry
     345             :     bool             mIsDataUserFont : 1;      // platform font entry (data)
     346             :     bool             mIsLocalUserFont : 1;     // platform font entry (local)
     347             :     bool             mStandardFace : 1;
     348             :     bool             mSymbolFont  : 1;
     349             :     bool             mIgnoreGDEF  : 1;
     350             :     bool             mIgnoreGSUB  : 1;
     351             :     bool             mSVGInitialized : 1;
     352             :     bool             mHasSpaceFeaturesInitialized : 1;
     353             :     bool             mHasSpaceFeatures : 1;
     354             :     bool             mHasSpaceFeaturesKerning : 1;
     355             :     bool             mHasSpaceFeaturesNonKerning : 1;
     356             :     bool             mSkipDefaultFeatureSpaceCheck : 1;
     357             :     bool             mGraphiteSpaceContextualsInitialized : 1;
     358             :     bool             mHasGraphiteSpaceContextuals : 1;
     359             :     bool             mSpaceGlyphIsInvisible : 1;
     360             :     bool             mSpaceGlyphIsInvisibleInitialized : 1;
     361             :     bool             mHasGraphiteTables : 1;
     362             :     bool             mCheckedForGraphiteTables : 1;
     363             :     bool             mHasCmapTable : 1;
     364             :     bool             mGrFaceInitialized : 1;
     365             :     bool             mCheckedForColorGlyph : 1;
     366             : 
     367             :     // bitvector of substitution space features per script, one each
     368             :     // for default and non-default features
     369             :     uint32_t         mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
     370             :     uint32_t         mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
     371             : 
     372             :     uint16_t         mWeight;
     373             :     int16_t          mStretch;
     374             : 
     375             :     RefPtr<gfxCharacterMap> mCharacterMap;
     376             :     uint32_t         mUVSOffset;
     377             :     mozilla::UniquePtr<uint8_t[]> mUVSData;
     378             :     mozilla::UniquePtr<gfxUserFontData> mUserFontData;
     379             :     mozilla::UniquePtr<gfxSVGGlyphs> mSVGGlyphs;
     380             :     // list of gfxFonts that are using SVG glyphs
     381             :     nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
     382             :     nsTArray<gfxFontFeature> mFeatureSettings;
     383             :     mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey,bool>> mSupportedFeatures;
     384             :     mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey,hb_set_t*>> mFeatureInputs;
     385             :     uint32_t         mLanguageOverride;
     386             : 
     387             :     // Color Layer font support
     388             :     hb_blob_t*       mCOLR;
     389             :     hb_blob_t*       mCPAL;
     390             : 
     391             : protected:
     392             :     friend class gfxPlatformFontList;
     393             :     friend class gfxMacPlatformFontList;
     394             :     friend class gfxUserFcFontEntry;
     395             :     friend class gfxFontFamily;
     396             :     friend class gfxSingleFaceMacFontFamily;
     397             :     friend class gfxUserFontEntry;
     398             : 
     399             :     gfxFontEntry();
     400             : 
     401             :     // Protected destructor, to discourage deletion outside of Release():
     402             :     virtual ~gfxFontEntry();
     403             : 
     404             :     virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
     405             :                                         bool aNeedsBold) = 0;
     406             : 
     407             :     virtual void CheckForGraphiteTables();
     408             : 
     409             :     // Copy a font table into aBuffer.
     410             :     // The caller will be responsible for ownership of the data.
     411           0 :     virtual nsresult CopyFontTable(uint32_t aTableTag,
     412             :                                    nsTArray<uint8_t>& aBuffer) {
     413           0 :         NS_NOTREACHED("forgot to override either GetFontTable or CopyFontTable?");
     414           0 :         return NS_ERROR_FAILURE;
     415             :     }
     416             : 
     417             :     // lookup the cmap in cached font data
     418             :     virtual already_AddRefed<gfxCharacterMap>
     419             :     GetCMAPFromFontInfo(FontInfoData *aFontInfoData,
     420             :                         uint32_t& aUVSOffset,
     421             :                         bool& aSymbolFont);
     422             : 
     423             :     // helper for HasCharacter(), which is what client code should call
     424             :     virtual bool TestCharacterMap(uint32_t aCh);
     425             : 
     426             :     // Font's unitsPerEm from the 'head' table, if available (will be set to
     427             :     // kInvalidUPEM for non-sfnt font formats)
     428             :     uint16_t mUnitsPerEm;
     429             : 
     430             :     // Shaper-specific face objects, shared by all instantiations of the same
     431             :     // physical font, regardless of size.
     432             :     // Usually, only one of these will actually be created for any given font
     433             :     // entry, depending on the font tables that are present.
     434             : 
     435             :     // hb_face_t is refcounted internally, so each shaper that's using it will
     436             :     // bump the ref count when it acquires the face, and "destroy" (release) it
     437             :     // in its destructor. The font entry has only this non-owning reference to
     438             :     // the face; when the face is deleted, it will tell the font entry to forget
     439             :     // it, so that a new face will be created next time it is needed.
     440             :     hb_face_t* mHBFace;
     441             : 
     442             :     static hb_blob_t* HBGetTable(hb_face_t *face, uint32_t aTag, void *aUserData);
     443             : 
     444             :     // Callback that the hb_face will use to tell us when it is being deleted.
     445             :     static void HBFaceDeletedCallback(void *aUserData);
     446             : 
     447             :     // gr_face is -not- refcounted, so it will be owned directly by the font
     448             :     // entry, and we'll keep a count of how many references we've handed out;
     449             :     // each shaper is responsible to call ReleaseGrFace on its entry when
     450             :     // finished with it, so that we know when it can be deleted.
     451             :     gr_face*   mGrFace;
     452             : 
     453             :     // hashtable to map raw table data ptr back to its owning blob, for use by
     454             :     // graphite table-release callback
     455             :     nsDataHashtable<nsPtrHashKey<const void>,void*>* mGrTableMap;
     456             : 
     457             :     // number of current users of this entry's mGrFace
     458             :     nsrefcnt mGrFaceRefCnt;
     459             : 
     460             :     static const void* GrGetTable(const void *aAppFaceHandle,
     461             :                                   unsigned int aName,
     462             :                                   size_t *aLen);
     463             :     static void GrReleaseTable(const void *aAppFaceHandle,
     464             :                                const void *aTableBuffer);
     465             : 
     466             :     // For memory reporting: size of user-font data belonging to this entry.
     467             :     // We record this in the font entry because the actual data block may be
     468             :     // handed over to platform APIs, so that it would become difficult (and
     469             :     // platform-specific) to measure it directly at report-gathering time.
     470             :     uint32_t mComputedSizeOfUserFont;
     471             : 
     472             : private:
     473             :     /**
     474             :      * Font table hashtable, to support GetFontTable for harfbuzz.
     475             :      *
     476             :      * The harfbuzz shaper (and potentially other clients) needs access to raw
     477             :      * font table data. This needs to be cached so that it can be used
     478             :      * repeatedly (each time we construct a text run; in some cases, for
     479             :      * each character/glyph within the run) without re-fetching large tables
     480             :      * every time.
     481             :      * 
     482             :      * Because we may instantiate many gfxFonts for the same physical font
     483             :      * file (at different sizes), we should ensure that they can share a
     484             :      * single cached copy of the font tables. To do this, we implement table
     485             :      * access and sharing on the fontEntry rather than the font itself.
     486             :      *
     487             :      * The default implementation uses GetFontTable() to read font table
     488             :      * data into byte arrays, and wraps them in blobs which are registered in
     489             :      * a hashtable.  The hashtable can then return pre-existing blobs to
     490             :      * harfbuzz.
     491             :      *
     492             :      * Harfbuzz will "destroy" the blobs when it is finished with them.  When
     493             :      * the last blob reference is removed, the FontTableBlobData user data
     494             :      * will remove the blob from the hashtable if still registered.
     495             :      */
     496             : 
     497             :     class FontTableBlobData;
     498             : 
     499             :     /**
     500             :      * FontTableHashEntry manages the entries of hb_blob_t's containing font
     501             :      * table data.
     502             :      *
     503             :      * This is used to share font tables across fonts with the same
     504             :      * font entry (but different sizes) for use by HarfBuzz.  The hashtable
     505             :      * does not own a strong reference to the blob, but keeps a weak pointer,
     506             :      * managed by FontTableBlobData.  Similarly FontTableBlobData keeps only a
     507             :      * weak pointer to the hashtable, managed by FontTableHashEntry.
     508             :      */
     509             : 
     510             :     class FontTableHashEntry : public nsUint32HashKey
     511             :     {
     512             :     public:
     513             :         // Declarations for nsTHashtable
     514             : 
     515             :         typedef nsUint32HashKey KeyClass;
     516             :         typedef KeyClass::KeyType KeyType;
     517             :         typedef KeyClass::KeyTypePointer KeyTypePointer;
     518             : 
     519          21 :         explicit FontTableHashEntry(KeyTypePointer aTag)
     520          21 :             : KeyClass(aTag)
     521             :             , mSharedBlobData(nullptr)
     522          21 :             , mBlob(nullptr)
     523          21 :         { }
     524             : 
     525             :         // NOTE: This assumes the new entry belongs to the same hashtable as
     526             :         // the old, because the mHashtable pointer in mSharedBlobData (if
     527             :         // present) will not be updated.
     528             :         FontTableHashEntry(FontTableHashEntry&& toMove)
     529             :             : KeyClass(mozilla::Move(toMove))
     530             :             , mSharedBlobData(mozilla::Move(toMove.mSharedBlobData))
     531             :             , mBlob(mozilla::Move(toMove.mBlob))
     532             :         {
     533             :             toMove.mSharedBlobData = nullptr;
     534             :             toMove.mBlob = nullptr;
     535             :         }
     536             : 
     537           9 :         ~FontTableHashEntry() { Clear(); }
     538             : 
     539             :         // FontTable/Blob API
     540             : 
     541             :         // Transfer (not copy) elements of aTable to a new hb_blob_t and
     542             :         // return ownership to the caller.  A weak reference to the blob is
     543             :         // recorded in the hashtable entry so that others may use the same
     544             :         // table.
     545             :         hb_blob_t *
     546             :         ShareTableAndGetBlob(nsTArray<uint8_t>&& aTable,
     547             :                              nsTHashtable<FontTableHashEntry> *aHashtable);
     548             : 
     549             :         // Return a strong reference to the blob.
     550             :         // Callers must hb_blob_destroy the returned blob.
     551             :         hb_blob_t *GetBlob() const;
     552             : 
     553             :         void Clear();
     554             : 
     555             :         size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     556             : 
     557             :     private:
     558             :         static void DeleteFontTableBlobData(void *aBlobData);
     559             :         // not implemented
     560             :         FontTableHashEntry& operator=(FontTableHashEntry& toCopy);
     561             : 
     562             :         FontTableBlobData *mSharedBlobData;
     563             :         hb_blob_t *mBlob;
     564             :     };
     565             : 
     566             :     mozilla::UniquePtr<nsTHashtable<FontTableHashEntry> > mFontTableCache;
     567             : 
     568             :     gfxFontEntry(const gfxFontEntry&);
     569             :     gfxFontEntry& operator=(const gfxFontEntry&);
     570             : };
     571             : 
     572             : 
     573             : // used when iterating over all fonts looking for a match for a given character
     574           0 : struct GlobalFontMatch {
     575           0 :     GlobalFontMatch(const uint32_t aCharacter,
     576             :                     mozilla::unicode::Script aRunScript,
     577           0 :                     const gfxFontStyle *aStyle) :
     578             :         mCh(aCharacter), mRunScript(aRunScript), mStyle(aStyle),
     579           0 :         mMatchRank(0), mCount(0), mCmapsTested(0)
     580             :         {
     581             : 
     582           0 :         }
     583             : 
     584             :     const uint32_t         mCh;          // codepoint to be matched
     585             :     mozilla::unicode::Script mRunScript;   // Unicode script for the codepoint
     586             :     const gfxFontStyle*    mStyle;       // style to match
     587             :     int32_t                mMatchRank;   // metric indicating closest match
     588             :     RefPtr<gfxFontEntry> mBestMatch;   // current best match
     589             :     RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
     590             :     uint32_t               mCount;       // number of fonts matched
     591             :     uint32_t               mCmapsTested; // number of cmaps tested
     592             : };
     593             : 
     594             : class gfxFontFamily {
     595             : public:
     596             :     // Used by stylo
     597        2170 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFamily)
     598             : 
     599         558 :     explicit gfxFontFamily(const nsAString& aName) :
     600             :         mName(aName),
     601             :         mOtherFamilyNamesInitialized(false),
     602             :         mHasOtherFamilyNames(false),
     603             :         mFaceNamesInitialized(false),
     604             :         mHasStyles(false),
     605             :         mIsSimpleFamily(false),
     606             :         mIsBadUnderlineFamily(false),
     607             :         mFamilyCharacterMapInitialized(false),
     608             :         mSkipDefaultFeatureSpaceCheck(false),
     609         558 :         mCheckForFallbackFaces(false)
     610         558 :         { }
     611             : 
     612         139 :     const nsString& Name() { return mName; }
     613             : 
     614             :     virtual void LocalizedName(nsAString& aLocalizedName);
     615             :     virtual bool HasOtherFamilyNames();
     616             :     
     617          65 :     nsTArray<RefPtr<gfxFontEntry> >& GetFontList() { return mAvailableFonts; }
     618             :     
     619         107 :     void AddFontEntry(RefPtr<gfxFontEntry> aFontEntry) {
     620             :         // bug 589682 - set the IgnoreGDEF flag on entries for Italic faces
     621             :         // of Times New Roman, because of buggy table in those fonts
     622         139 :         if (aFontEntry->IsItalic() && !aFontEntry->IsUserFont() &&
     623          32 :             Name().EqualsLiteral("Times New Roman"))
     624             :         {
     625           8 :             aFontEntry->mIgnoreGDEF = true;
     626             :         }
     627         107 :         if (aFontEntry->mFamilyName.IsEmpty()) {
     628         107 :             aFontEntry->mFamilyName = Name();
     629             :         } else {
     630           0 :             MOZ_ASSERT(aFontEntry->mFamilyName.Equals(Name()));
     631             :         }
     632         107 :         aFontEntry->mSkipDefaultFeatureSpaceCheck = mSkipDefaultFeatureSpaceCheck;
     633         107 :         mAvailableFonts.AppendElement(aFontEntry);
     634         107 :     }
     635             : 
     636             :     // note that the styles for this family have been added
     637          65 :     bool HasStyles() { return mHasStyles; }
     638          16 :     void SetHasStyles(bool aHasStyles) { mHasStyles = aHasStyles; }
     639             : 
     640             :     // choose a specific face to match a style using CSS font matching
     641             :     // rules (weight matching occurs here).  may return a face that doesn't
     642             :     // precisely match (e.g. normal face when no italic face exists).
     643             :     // aNeedsSyntheticBold is set to true when synthetic bolding is
     644             :     // needed, false otherwise
     645             :     gfxFontEntry *FindFontForStyle(const gfxFontStyle& aFontStyle, 
     646             :                                    bool& aNeedsSyntheticBold);
     647             : 
     648             :     virtual void
     649             :     FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
     650             :                          nsTArray<gfxFontEntry*>& aFontEntryList,
     651             :                          bool& aNeedsSyntheticBold);
     652             : 
     653             :     // checks for a matching font within the family
     654             :     // used as part of the font fallback process
     655             :     void FindFontForChar(GlobalFontMatch *aMatchData);
     656             : 
     657             :     // checks all fonts for a matching font within the family
     658             :     void SearchAllFontsForChar(GlobalFontMatch *aMatchData);
     659             : 
     660             :     // read in other family names, if any, and use functor to add each into cache
     661             :     virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList);
     662             : 
     663             :     // helper method for reading localized family names from the name table
     664             :     // of a single face
     665             :     static void ReadOtherFamilyNamesForFace(const nsAString& aFamilyName,
     666             :                                             const char *aNameData,
     667             :                                             uint32_t aDataLength,
     668             :                                             nsTArray<nsString>& aOtherFamilyNames,
     669             :                                             bool useFullName);
     670             : 
     671             :     // set when other family names have been read in
     672             :     void SetOtherFamilyNamesInitialized() {
     673             :         mOtherFamilyNamesInitialized = true;
     674             :     }
     675             : 
     676             :     // read in other localized family names, fullnames and Postscript names
     677             :     // for all faces and append to lookup tables
     678             :     virtual void ReadFaceNames(gfxPlatformFontList *aPlatformFontList,
     679             :                                bool aNeedFullnamePostscriptNames,
     680             :                                FontInfoData *aFontInfoData = nullptr);
     681             : 
     682             :     // find faces belonging to this family (platform implementations override this;
     683             :     // should be made pure virtual once all subclasses have been updated)
     684           0 :     virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) { }
     685             : 
     686             :     // search for a specific face using the Postscript name
     687             :     gfxFontEntry* FindFont(const nsAString& aPostscriptName);
     688             : 
     689             :     // read in cmaps for all the faces
     690             :     void ReadAllCMAPs(FontInfoData *aFontInfoData = nullptr);
     691             : 
     692           0 :     bool TestCharacterMap(uint32_t aCh) {
     693           0 :         if (!mFamilyCharacterMapInitialized) {
     694           0 :             ReadAllCMAPs();
     695             :         }
     696           0 :         return mFamilyCharacterMap.test(aCh);
     697             :     }
     698             : 
     699           0 :     void ResetCharacterMap() {
     700           0 :         mFamilyCharacterMap.reset();
     701           0 :         mFamilyCharacterMapInitialized = false;
     702           0 :     }
     703             : 
     704             :     // mark this family as being in the "bad" underline offset blacklist
     705           0 :     void SetBadUnderlineFamily() {
     706           0 :         mIsBadUnderlineFamily = true;
     707           0 :         if (mHasStyles) {
     708           0 :             SetBadUnderlineFonts();
     709             :         }
     710           0 :     }
     711             : 
     712          13 :     bool IsBadUnderlineFamily() const { return mIsBadUnderlineFamily; }
     713          16 :     bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
     714             : 
     715             :     // sort available fonts to put preferred (standard) faces towards the end
     716             :     void SortAvailableFonts();
     717             : 
     718             :     // check whether the family fits into the simple 4-face model,
     719             :     // so we can use simplified style-matching;
     720             :     // if so set the mIsSimpleFamily flag (defaults to False before we've checked)
     721             :     void CheckForSimpleFamily();
     722             : 
     723             :     // For memory reporter
     724             :     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
     725             :                                         FontListSizes* aSizes) const;
     726             :     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
     727             :                                         FontListSizes* aSizes) const;
     728             : 
     729             : #ifdef DEBUG
     730             :     // Only used for debugging checks - does a linear search
     731             :     bool ContainsFace(gfxFontEntry* aFontEntry);
     732             : #endif
     733             : 
     734             :     void SetSkipSpaceFeatureCheck(bool aSkipCheck) {
     735             :         mSkipDefaultFeatureSpaceCheck = aSkipCheck;
     736             :     }
     737             : 
     738             : protected:
     739             :     // Protected destructor, to discourage deletion outside of Release():
     740             :     virtual ~gfxFontFamily();
     741             : 
     742             :     bool ReadOtherFamilyNamesForFace(gfxPlatformFontList *aPlatformFontList,
     743             :                                      hb_blob_t           *aNameTable,
     744             :                                      bool                 useFullName = false);
     745             : 
     746             :     // set whether this font family is in "bad" underline offset blacklist.
     747           0 :     void SetBadUnderlineFonts() {
     748           0 :         uint32_t i, numFonts = mAvailableFonts.Length();
     749           0 :         for (i = 0; i < numFonts; i++) {
     750           0 :             if (mAvailableFonts[i]) {
     751           0 :                 mAvailableFonts[i]->mIsBadUnderlineFont = true;
     752             :             }
     753             :         }
     754           0 :     }
     755             : 
     756             :     nsString mName;
     757             :     nsTArray<RefPtr<gfxFontEntry> >  mAvailableFonts;
     758             :     gfxSparseBitSet mFamilyCharacterMap;
     759             :     bool mOtherFamilyNamesInitialized : 1;
     760             :     bool mHasOtherFamilyNames : 1;
     761             :     bool mFaceNamesInitialized : 1;
     762             :     bool mHasStyles : 1;
     763             :     bool mIsSimpleFamily : 1;
     764             :     bool mIsBadUnderlineFamily : 1;
     765             :     bool mFamilyCharacterMapInitialized : 1;
     766             :     bool mSkipDefaultFeatureSpaceCheck : 1;
     767             :     bool mCheckForFallbackFaces : 1;  // check other faces for character
     768             : 
     769             :     enum {
     770             :         // for "simple" families, the faces are stored in mAvailableFonts
     771             :         // with fixed positions:
     772             :         kRegularFaceIndex    = 0,
     773             :         kBoldFaceIndex       = 1,
     774             :         kItalicFaceIndex     = 2,
     775             :         kBoldItalicFaceIndex = 3,
     776             :         // mask values for selecting face with bold and/or italic attributes
     777             :         kBoldMask   = 0x01,
     778             :         kItalicMask = 0x02
     779             :     };
     780             : };
     781             : 
     782             : #endif

Generated by: LCOV version 1.13