Bug 1880704 - Crop more PDF rendering and wait differently for rendering r=mboldan
[gecko.git] / gfx / thebes / gfxFontEntry.h
blob888b85f2c99b025ea27dae59d7ba3fda188973ce
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef GFX_FONTENTRY_H
7 #define GFX_FONTENTRY_H
9 #include <limits>
10 #include <math.h>
11 #include <new>
12 #include <utility>
13 #include "COLRFonts.h"
14 #include "ThebesRLBoxTypes.h"
15 #include "gfxFontUtils.h"
16 #include "gfxFontVariations.h"
17 #include "gfxRect.h"
18 #include "gfxTypes.h"
19 #include "harfbuzz/hb.h"
20 #include "mozilla/AlreadyAddRefed.h"
21 #include "mozilla/Assertions.h"
22 #include "mozilla/FontPropertyTypes.h"
23 #include "mozilla/MemoryReporting.h"
24 #include "mozilla/Mutex.h"
25 #include "mozilla/RefPtr.h"
26 #include "mozilla/RWLock.h"
27 #include "mozilla/TypedEnumBits.h"
28 #include "mozilla/UniquePtr.h"
29 #include "mozilla/intl/UnicodeScriptCodes.h"
30 #include "nsTHashMap.h"
31 #include "nsDebug.h"
32 #include "nsHashKeys.h"
33 #include "nsISupports.h"
34 #include "nsStringFwd.h"
35 #include "nsTArray.h"
36 #include "nscore.h"
38 class FontInfoData;
39 class gfxContext;
40 class gfxFont;
41 class gfxFontFamily;
42 class gfxPlatformFontList;
43 class gfxSVGGlyphs;
44 class gfxUserFontData;
45 class nsAtom;
46 struct FontListSizes;
47 struct gfxFontFeature;
48 struct gfxFontStyle;
49 enum class eFontPresentation : uint8_t;
51 namespace IPC {
52 template <class P>
53 struct ParamTraits;
56 namespace mozilla {
57 class SVGContextPaint;
58 namespace fontlist {
59 struct Face;
60 struct Family;
61 } // namespace fontlist
62 } // namespace mozilla
64 typedef struct gr_face gr_face;
65 typedef struct FT_MM_Var_ FT_MM_Var;
67 #define NO_FONT_LANGUAGE_OVERRIDE 0
69 class gfxCharacterMap : public gfxSparseBitSet {
70 public:
71 // gfxCharacterMap instances may be shared across multiple threads via a
72 // global table managed by gfxPlatformFontList. Once a gfxCharacterMap is
73 // inserted in the global table, its mShared flag will be TRUE, and we
74 // cannot safely delete it except from gfxPlatformFontList (which will
75 // use a lock to ensure entries are removed from its table and deleted
76 // safely).
78 // AddRef() is pretty much standard. We don't return the refcount as our
79 // users don't care about it.
80 void AddRef() {
81 MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(gfxCharacterMap);
82 MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
83 [[maybe_unused]] nsrefcnt count = ++mRefCnt;
84 NS_LOG_ADDREF(this, count, "gfxCharacterMap", sizeof(*this));
87 // Custom Release(): if the object is referenced from the global shared
88 // table, and we're releasing the last *other* reference to it, then we
89 // notify the global table to consider also releasing its ref. (That may
90 // not actually happen, if another thread is racing with us and takes a
91 // new reference, or completes the release first!)
92 void Release() {
93 MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
94 // We can't safely read this after we've decremented mRefCnt, so save it
95 // in a local variable here. Note that the value is never reset to false
96 // once it has been set to true (when recording the cmap in the shared
97 // table), so there's no risk of this resulting in a "false positive" when
98 // tested later. A "false negative" is possible but harmless; it would
99 // just mean we miss an opportunity to release a reference from the shared
100 // cmap table.
101 bool isShared = mShared;
103 // Ensure we only access mRefCnt once, for consistency if the object is
104 // being used by multiple threads.
105 nsrefcnt count = --mRefCnt;
106 NS_LOG_RELEASE(this, count, "gfxCharacterMap");
108 // If isShared was true, this object has been shared across threads. In
109 // that case, if the refcount went to 1, we notify the shared table so
110 // it can drop its reference and delete the object.
111 if (isShared) {
112 MOZ_ASSERT(count > 0);
113 if (count == 1) {
114 NotifyMaybeReleased(this);
116 return;
119 // Otherwise, this object hasn't been shared and we can safely delete it
120 // as we must have been holding the only reference. (Note that if we were
121 // holding the only reference, there's no other owner who can have set
122 // mShared to true since we read it above.)
123 if (count == 0) {
124 delete this;
128 gfxCharacterMap() = default;
130 explicit gfxCharacterMap(const gfxSparseBitSet& aOther)
131 : gfxSparseBitSet(aOther) {}
133 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
134 return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
137 // hash of the cmap bitvector
138 uint32_t mHash = 0;
140 // if cmap is built on the fly it's never shared
141 bool mBuildOnTheFly = false;
143 // Character map is shared globally. This can only be set by the thread that
144 // originally created the map, as no other thread can get a reference until
145 // it has been shared via the global table.
146 bool mShared = false;
148 protected:
149 friend class gfxPlatformFontList;
151 // Destructor should not be called except via Release().
152 // (Note that our "friend" gfxPlatformFontList also accesses this from its
153 // MaybeRemoveCmap method.)
154 ~gfxCharacterMap() = default;
156 nsrefcnt RefCount() const { return mRefCnt; }
158 void CalcHash() { mHash = GetChecksum(); }
160 static void NotifyMaybeReleased(gfxCharacterMap* aCmap);
162 // Only used when clearing the shared-cmap hashtable during shutdown.
163 void ClearSharedFlag() {
164 MOZ_ASSERT(NS_IsMainThread());
165 mShared = false;
168 mozilla::ThreadSafeAutoRefCnt mRefCnt;
170 private:
171 gfxCharacterMap(const gfxCharacterMap&) = delete;
172 gfxCharacterMap& operator=(const gfxCharacterMap&) = delete;
175 // Info on an individual font feature, for reporting available features
176 // to DevTools via the GetFeatureInfo method.
177 struct gfxFontFeatureInfo {
178 uint32_t mTag;
179 uint32_t mScript;
180 uint32_t mLangSys;
183 class gfxFontEntryCallbacks;
185 class gfxFontEntry {
186 public:
187 typedef mozilla::gfx::DrawTarget DrawTarget;
188 typedef mozilla::intl::Script Script;
189 typedef mozilla::FontWeight FontWeight;
190 typedef mozilla::FontSlantStyle FontSlantStyle;
191 typedef mozilla::FontStretch FontStretch;
192 typedef mozilla::WeightRange WeightRange;
193 typedef mozilla::SlantStyleRange SlantStyleRange;
194 typedef mozilla::StretchRange StretchRange;
196 // Used by stylo
197 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry)
199 explicit gfxFontEntry(const nsACString& aName, bool aIsStandardFace = false);
201 gfxFontEntry() = delete;
202 gfxFontEntry(const gfxFontEntry&) = delete;
203 gfxFontEntry& operator=(const gfxFontEntry&) = delete;
205 // Create a new entry that refers to the same font as this, but without
206 // additional state that may have been set up (such as family name).
207 // (This is only to be used for system fonts in the platform font list,
208 // not user fonts.)
209 virtual gfxFontEntry* Clone() const = 0;
211 // unique name for the face, *not* the family; not necessarily the
212 // "real" or user-friendly name, may be an internal identifier
213 const nsCString& Name() const { return mName; }
215 // family name
216 const nsCString& FamilyName() const { return mFamilyName; }
218 // The following two methods may be relatively expensive, as they
219 // will (usually, except on Linux) load and parse the 'name' table;
220 // they are intended only for the font-inspection API, not for
221 // perf-critical layout/drawing work.
223 // The "real" name of the face, if available from the font resource;
224 // returns Name() if nothing better is available.
225 virtual nsCString RealFaceName();
227 WeightRange Weight() const { return mWeightRange; }
228 StretchRange Stretch() const { return mStretchRange; }
229 SlantStyleRange SlantStyle() const { return mStyleRange; }
231 bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; }
232 bool IsLocalUserFont() const { return mIsLocalUserFont; }
233 bool IsFixedPitch() const { return mFixedPitch; }
234 bool IsItalic() const { return SlantStyle().Min().IsItalic(); }
235 bool IsOblique() const { return SlantStyle().Min().IsOblique(); }
236 bool IsUpright() const { return SlantStyle().Min().IsNormal(); }
237 inline bool SupportsItalic(); // defined below, because of RangeFlags use
238 inline bool SupportsBold();
239 inline bool MayUseSyntheticSlant();
240 bool IgnoreGDEF() const { return mIgnoreGDEF; }
241 bool IgnoreGSUB() const { return mIgnoreGSUB; }
243 // Return whether the face corresponds to "normal" CSS style properties:
244 // font-style: normal;
245 // font-weight: normal;
246 // font-stretch: normal;
247 // If this is false, we might want to fall back to a different face and
248 // possibly apply synthetic styling.
249 bool IsNormalStyle() const {
250 return IsUpright() && Weight().Min() <= FontWeight::NORMAL &&
251 Weight().Max() >= FontWeight::NORMAL &&
252 Stretch().Min() <= FontStretch::NORMAL &&
253 Stretch().Max() >= FontStretch::NORMAL;
256 // whether a feature is supported by the font (limited to a small set
257 // of features for which some form of fallback needs to be implemented)
258 virtual bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag);
259 bool SupportsGraphiteFeature(uint32_t aFeatureTag);
261 // returns a set containing all input glyph ids for a given feature
262 const hb_set_t* InputsForOpenTypeFeature(Script aScript,
263 uint32_t aFeatureTag);
265 virtual bool HasFontTable(uint32_t aTableTag);
267 inline bool HasGraphiteTables() {
268 LazyFlag flag = mHasGraphiteTables;
269 if (flag == LazyFlag::Uninitialized) {
270 flag = CheckForGraphiteTables() ? LazyFlag::Yes : LazyFlag::No;
271 mHasGraphiteTables = flag;
273 return flag == LazyFlag::Yes;
276 inline bool HasCmapTable() {
277 if (!mCharacterMap && !mShmemCharacterMap) {
278 ReadCMAP();
279 NS_ASSERTION(mCharacterMap || mShmemCharacterMap,
280 "failed to initialize character map");
282 return mHasCmapTable;
285 inline bool HasCharacter(uint32_t ch) {
286 if (mShmemCharacterMap) {
287 return GetShmemCharacterMap()->test(ch);
289 if (mCharacterMap) {
290 if (mShmemFace && TrySetShmemCharacterMap()) {
291 // Forget our temporary local copy, now we can use the shared cmap
292 auto* oldCmap = mCharacterMap.exchange(nullptr);
293 NS_IF_RELEASE(oldCmap);
294 return GetShmemCharacterMap()->test(ch);
296 if (GetCharacterMap()->test(ch)) {
297 return true;
300 return TestCharacterMap(ch);
303 virtual bool SkipDuringSystemFallback() { return false; }
304 void EnsureUVSMapInitialized();
305 uint16_t GetUVSGlyph(uint32_t aCh, uint32_t aVS);
307 // All concrete gfxFontEntry subclasses (except gfxUserFontEntry) need
308 // to override this, otherwise the font will never be used as it will
309 // be considered to support no characters.
310 // ReadCMAP() must *always* set the mCharacterMap pointer to a valid
311 // gfxCharacterMap, even if empty, as other code assumes this pointer
312 // can be safely dereferenced.
313 virtual nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr);
315 bool TryGetSVGData(const gfxFont* aFont);
316 bool HasSVGGlyph(uint32_t aGlyphId);
317 bool GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId,
318 gfxFloat aSize, gfxRect* aResult);
319 void RenderSVGGlyph(gfxContext* aContext, uint32_t aGlyphId,
320 mozilla::SVGContextPaint* aContextPaint);
321 // Call this when glyph geometry or rendering has changed
322 // (e.g. animated SVG glyphs)
323 void NotifyGlyphsChanged();
325 bool TryGetColorGlyphs();
327 bool HasColorBitmapTable() {
328 LazyFlag flag = mHasColorBitmapTable;
329 if (flag == LazyFlag::Uninitialized) {
330 flag = HasFontTable(TRUETYPE_TAG('C', 'B', 'D', 'T')) ||
331 HasFontTable(TRUETYPE_TAG('s', 'b', 'i', 'x'))
332 ? LazyFlag::Yes
333 : LazyFlag::No;
334 mHasColorBitmapTable = flag;
336 return flag == LazyFlag::Yes;
339 // Access to raw font table data (needed for Harfbuzz):
340 // returns a pointer to data owned by the fontEntry or the OS,
341 // which will remain valid until the blob is destroyed.
342 // The data MUST be treated as read-only; we may be getting a
343 // reference to a shared system font cache.
345 // The default implementation uses CopyFontTable to get the data
346 // into a byte array, and maintains a cache of loaded tables.
348 // Subclasses should override this if they can provide more efficient
349 // access than copying table data into our own buffers.
351 // Get blob that encapsulates a specific font table, or nullptr if
352 // the table doesn't exist in the font.
354 // Caller is responsible to call hb_blob_destroy() on the returned blob
355 // (if non-nullptr) when no longer required. For transient access to a
356 // table, use of AutoTable (below) is generally preferred.
357 virtual hb_blob_t* GetFontTable(uint32_t aTag);
359 // Stack-based utility to return a specified table, automatically releasing
360 // the blob when the AutoTable goes out of scope.
361 class AutoTable {
362 public:
363 AutoTable(gfxFontEntry* aFontEntry, uint32_t aTag) {
364 mBlob = aFontEntry->GetFontTable(aTag);
366 ~AutoTable() { hb_blob_destroy(mBlob); }
367 operator hb_blob_t*() const { return mBlob; }
369 private:
370 hb_blob_t* mBlob;
371 // not implemented:
372 AutoTable(const AutoTable&) = delete;
373 AutoTable& operator=(const AutoTable&) = delete;
376 // Return a font instance for a particular style. This may be a newly-
377 // created instance, or a font already in the global cache.
378 // We can't return a UniquePtr here, because we may be returning a shared
379 // cached instance; but we also don't return already_AddRefed, because
380 // the caller may only need to use the font temporarily and doesn't need
381 // a strong reference.
382 already_AddRefed<gfxFont> FindOrMakeFont(
383 const gfxFontStyle* aStyle, gfxCharacterMap* aUnicodeRangeMap = nullptr);
385 // Get an existing font table cache entry in aBlob if it has been
386 // registered, or return false if not. Callers must call
387 // hb_blob_destroy on aBlob if true is returned.
389 // Note that some gfxFont implementations may not call this at all,
390 // if it is more efficient to get the table from the OS at that level.
391 bool GetExistingFontTable(uint32_t aTag, hb_blob_t** aBlob);
393 // Elements of aTable are transferred (not copied) to and returned in a
394 // new hb_blob_t which is registered on the gfxFontEntry, but the initial
395 // reference is owned by the caller. Removing the last reference
396 // unregisters the table from the font entry.
398 // Pass nullptr for aBuffer to indicate that the table is not present and
399 // nullptr will be returned. Also returns nullptr on OOM.
400 hb_blob_t* ShareFontTableAndGetBlob(uint32_t aTag, nsTArray<uint8_t>* aTable);
402 // Get the font's unitsPerEm from the 'head' table, in the case of an
403 // sfnt resource. Will return kInvalidUPEM for non-sfnt fonts,
404 // if present on the platform.
405 uint16_t UnitsPerEm();
406 enum {
407 kMinUPEM = 16, // Limits on valid unitsPerEm range, from the
408 kMaxUPEM = 16384, // OpenType spec
409 kInvalidUPEM = uint16_t(-1)
412 // Shaper face accessors:
413 // NOTE that harfbuzz and graphite handle ownership/lifetime of the face
414 // object in completely different ways.
416 // Create a HarfBuzz face corresponding to this font file.
417 // Our reference to the underlying hb_face_t will be released when the
418 // returned AutoHBFace goes out of scope, but the hb_face_t itself may
419 // be kept alive by other references (e.g. if an hb_font_t has been
420 // instantiated for it).
421 class MOZ_STACK_CLASS AutoHBFace {
422 public:
423 explicit AutoHBFace(hb_face_t* aFace) : mFace(aFace) {}
424 ~AutoHBFace() { hb_face_destroy(mFace); }
426 operator hb_face_t*() const { return mFace; }
428 // Not default-constructible, not copyable.
429 AutoHBFace() = delete;
430 AutoHBFace(const AutoHBFace&) = delete;
431 AutoHBFace& operator=(const AutoHBFace&) = delete;
433 private:
434 hb_face_t* mFace;
437 AutoHBFace GetHBFace() {
438 return AutoHBFace(hb_face_create_for_tables(HBGetTable, this, nullptr));
441 // Get the sandbox instance that graphite is running in.
442 rlbox_sandbox_gr* GetGrSandbox();
444 // Register and get the callback handle for the glyph advance firefox callback
445 // Since the sandbox instance is shared with multiple test shapers, callback
446 // registration must be handled centrally to ensure multiple instances don't
447 // register the same callback.
448 sandbox_callback_gr<float (*)(const void*, uint16_t)>*
449 GetGrSandboxAdvanceCallbackHandle();
451 // Get Graphite face corresponding to this font file.
452 // Caller must call gfxFontEntry::ReleaseGrFace when finished with it.
453 // Graphite is run in a sandbox
454 tainted_opaque_gr<gr_face*> GetGrFace();
455 void ReleaseGrFace(tainted_opaque_gr<gr_face*> aFace);
457 // Does the font have graphite contextuals that involve the space glyph
458 // (and therefore we should bypass the word cache)?
459 // Since this function inspects data from libGraphite stored in sandbox memory
460 // it can only return a "hint" to the correct return value. This is because
461 // a compromised libGraphite could change the sandbox memory maliciously at
462 // any moment. The caller must ensure the calling code performs safe actions
463 // independent of the value returned, to unwrap this return.
464 tainted_boolean_hint HasGraphiteSpaceContextuals();
466 // Release any SVG-glyphs document this font may have loaded.
467 void DisconnectSVG();
469 // Called to notify that aFont is being destroyed. Needed when we're tracking
470 // the fonts belonging to this font entry.
471 void NotifyFontDestroyed(gfxFont* aFont);
473 // For memory reporting of the platform font list.
474 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
475 FontListSizes* aSizes) const;
476 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
477 FontListSizes* aSizes) const;
479 // Used for reporting on individual font entries in the user font cache,
480 // which are not present in the platform font list.
481 size_t ComputedSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
483 // Used when checking for complex script support, to mask off cmap ranges
484 struct ScriptRange {
485 uint32_t rangeStart;
486 uint32_t rangeEnd;
487 uint32_t numTags; // number of entries in the tags[] array
488 hb_tag_t tags[3]; // up to three OpenType script tags to check
491 bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags, uint32_t aNumTags);
494 * Font-variation query methods.
496 * Font backends that don't support variations should provide empty
497 * implementations.
499 virtual bool HasVariations() = 0;
501 virtual void GetVariationAxes(
502 nsTArray<gfxFontVariationAxis>& aVariationAxes) = 0;
504 virtual void GetVariationInstances(
505 nsTArray<gfxFontVariationInstance>& aInstances) = 0;
507 bool HasBoldVariableWeight();
508 bool HasItalicVariation();
509 bool HasSlantVariation();
510 bool HasOpticalSize();
512 void CheckForVariationAxes();
514 // Set up the entry's weight/stretch/style ranges according to axes found
515 // by GetVariationAxes (for installed fonts; do NOT call this for user
516 // fonts, where the ranges are provided by @font-face descriptors).
517 void SetupVariationRanges();
519 // Get variation axis settings that should be used to implement a particular
520 // font style using this resource.
521 void GetVariationsForStyle(nsTArray<gfxFontVariation>& aResult,
522 const gfxFontStyle& aStyle);
524 // Get the font's list of features (if any) for DevTools support.
525 void GetFeatureInfo(nsTArray<gfxFontFeatureInfo>& aFeatureInfo);
527 // This is only called on platforms where we use FreeType.
528 virtual FT_MM_Var* GetMMVar() { return nullptr; }
530 // Return true if the font has a 'trak' table (and we can successfully
531 // interpret it), otherwise false. This will load and cache the table
532 // the first time it is called.
533 bool HasTrackingTable();
535 // Return the tracking (in font units) to be applied for the given size.
536 // (This is a floating-point number because of possible interpolation.)
537 gfxFloat TrackingForCSSPx(gfxFloat aSize) const;
539 mozilla::gfx::Rect GetFontExtents(float aFUnitScaleFactor) const {
540 // Flip the y-axis here to match the orientation of Gecko's coordinates.
541 return mozilla::gfx::Rect(float(mXMin) * aFUnitScaleFactor,
542 float(-mYMax) * aFUnitScaleFactor,
543 float(mXMax - mXMin) * aFUnitScaleFactor,
544 float(mYMax - mYMin) * aFUnitScaleFactor);
547 nsCString mName;
548 nsCString mFamilyName;
550 // These are mutable so that we can take a read lock within a const method.
551 mutable mozilla::RWLock mLock;
552 mutable mozilla::Mutex mFeatureInfoLock;
554 mozilla::Atomic<gfxCharacterMap*> mCharacterMap; // strong ref
555 gfxCharacterMap* GetCharacterMap() const { return mCharacterMap; }
557 mozilla::fontlist::Face* mShmemFace = nullptr;
558 const mozilla::fontlist::Family* mShmemFamily = nullptr;
560 mozilla::Atomic<const SharedBitSet*> mShmemCharacterMap;
561 const SharedBitSet* GetShmemCharacterMap() const {
562 return mShmemCharacterMap;
565 mozilla::Atomic<const uint8_t*> mUVSData;
566 const uint8_t* GetUVSData() const { return mUVSData; }
568 mozilla::UniquePtr<gfxUserFontData> mUserFontData;
570 mozilla::Atomic<gfxSVGGlyphs*> mSVGGlyphs;
571 gfxSVGGlyphs* GetSVGGlyphs() const { return mSVGGlyphs; }
573 // list of gfxFonts that are using SVG glyphs
574 nsTArray<const gfxFont*> mFontsUsingSVGGlyphs MOZ_GUARDED_BY(mLock);
575 nsTArray<gfxFontFeature> mFeatureSettings;
576 nsTArray<gfxFontVariation> mVariationSettings;
578 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, bool>> mSupportedFeatures
579 MOZ_GUARDED_BY(mFeatureInfoLock);
580 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, hb_set_t*>> mFeatureInputs
581 MOZ_GUARDED_BY(mFeatureInfoLock);
583 // Color Layer font support. These tables are inert once loaded, so we don't
584 // need to hold a lock when reading them.
585 mozilla::Atomic<hb_blob_t*> mCOLR;
586 mozilla::Atomic<hb_blob_t*> mCPAL;
587 hb_blob_t* GetCOLR() const { return mCOLR; }
588 hb_blob_t* GetCPAL() const { return mCPAL; }
590 // bitvector of substitution space features per script, one each
591 // for default and non-default features
592 uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
593 uint32_t
594 mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
596 mozilla::Atomic<uint32_t> mUVSOffset;
598 uint32_t mLanguageOverride = NO_FONT_LANGUAGE_OVERRIDE;
600 WeightRange mWeightRange = WeightRange(FontWeight::FromInt(500));
601 StretchRange mStretchRange = StretchRange(FontStretch::NORMAL);
602 SlantStyleRange mStyleRange = SlantStyleRange(FontSlantStyle::NORMAL);
604 // Font metrics overrides (as multiples of used font size); negative values
605 // indicate no override to be applied.
606 float mAscentOverride = -1.0;
607 float mDescentOverride = -1.0;
608 float mLineGapOverride = -1.0;
610 // Scaling factor to be applied to the font size.
611 float mSizeAdjust = 1.0;
613 // For user fonts (only), we need to record whether or not weight/stretch/
614 // slant variations should be clamped to the range specified in the entry
615 // properties. When the @font-face rule omitted one or more of these
616 // descriptors, it is treated as the initial value for font-matching (and
617 // so that is what we record in the font entry), but when rendering the
618 // range is NOT clamped.
619 enum class RangeFlags : uint16_t {
620 eNoFlags = 0,
621 eAutoWeight = (1 << 0),
622 eAutoStretch = (1 << 1),
623 eAutoSlantStyle = (1 << 2),
625 // Flag to record whether the face has a variable "wght" axis
626 // that supports "bold" values, used to disable the application
627 // of synthetic-bold effects.
628 eBoldVariableWeight = (1 << 3),
629 // Whether the face has an 'ital' axis.
630 eItalicVariation = (1 << 4),
631 // Whether the face has a 'slnt' axis.
632 eSlantVariation = (1 << 5),
634 // Flags to record if the face uses a non-CSS-compatible scale
635 // for weight and/or stretch, in which case we won't map the
636 // properties to the variation axes (though they can still be
637 // explicitly set using font-variation-settings).
638 eNonCSSWeight = (1 << 6),
639 eNonCSSStretch = (1 << 7),
641 // Whether the font has an 'opsz' axis.
642 eOpticalSize = (1 << 8)
644 RangeFlags mRangeFlags = RangeFlags::eNoFlags;
646 bool mFixedPitch : 1;
647 bool mIsBadUnderlineFont : 1;
648 bool mIsUserFontContainer : 1; // userfont entry
649 bool mIsDataUserFont : 1; // platform font entry (data)
650 bool mIsLocalUserFont : 1; // platform font entry (local)
651 bool mStandardFace : 1;
652 bool mIgnoreGDEF : 1;
653 bool mIgnoreGSUB : 1;
654 bool mSkipDefaultFeatureSpaceCheck : 1;
656 mozilla::Atomic<bool> mSVGInitialized;
657 mozilla::Atomic<bool> mHasCmapTable;
658 mozilla::Atomic<bool> mGrFaceInitialized;
659 mozilla::Atomic<bool> mCheckedForColorGlyph;
660 mozilla::Atomic<bool> mCheckedForVariationAxes;
662 // Atomic flags that are lazily evaluated - initially set to UNINITIALIZED,
663 // changed to NO or YES once we determine the actual value.
664 enum class LazyFlag : uint8_t { Uninitialized = 0xff, No = 0, Yes = 1 };
666 std::atomic<LazyFlag> mSpaceGlyphIsInvisible;
667 std::atomic<LazyFlag> mHasGraphiteTables;
668 std::atomic<LazyFlag> mHasGraphiteSpaceContextuals;
669 std::atomic<LazyFlag> mHasColorBitmapTable;
671 enum class SpaceFeatures : uint8_t {
672 Uninitialized = 0xff,
673 None = 0,
674 HasFeatures = 1 << 0,
675 Kerning = 1 << 1,
676 NonKerning = 1 << 2
679 std::atomic<SpaceFeatures> mHasSpaceFeatures;
681 protected:
682 friend class gfxPlatformFontList;
683 friend class gfxFontFamily;
684 friend class gfxUserFontEntry;
686 // Protected destructor, to discourage deletion outside of Release():
687 virtual ~gfxFontEntry();
689 virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) = 0;
691 inline bool CheckForGraphiteTables() {
692 return HasFontTable(TRUETYPE_TAG('S', 'i', 'l', 'f'));
695 // Copy a font table into aBuffer.
696 // The caller will be responsible for ownership of the data.
697 virtual nsresult CopyFontTable(uint32_t aTableTag,
698 nsTArray<uint8_t>& aBuffer) {
699 MOZ_ASSERT_UNREACHABLE(
700 "forgot to override either GetFontTable or "
701 "CopyFontTable?");
702 return NS_ERROR_FAILURE;
705 // Helper for HasTrackingTable; check/parse the table and cache pointers
706 // to the subtables we need. Returns false on failure, in which case the
707 // table is unusable.
708 bool ParseTrakTable() MOZ_REQUIRES(mLock);
710 // lookup the cmap in cached font data
711 virtual already_AddRefed<gfxCharacterMap> GetCMAPFromFontInfo(
712 FontInfoData* aFontInfoData, uint32_t& aUVSOffset);
714 // helper for HasCharacter(), which is what client code should call
715 virtual bool TestCharacterMap(uint32_t aCh);
717 // Try to set mShmemCharacterMap, based on the char map in mShmemFace;
718 // return true if successful, false if it remains null (maybe the parent
719 // hasn't handled our SetCharacterMap message yet).
720 bool TrySetShmemCharacterMap();
722 // Helper for gfxPlatformFontList::CreateFontEntry methods: set properties
723 // of the gfxFontEntry based on shared Face and Family records.
724 void InitializeFrom(mozilla::fontlist::Face* aFace,
725 const mozilla::fontlist::Family* aFamily);
727 // Shaper-specific face objects, shared by all instantiations of the same
728 // physical font, regardless of size.
729 // Usually, only one of these will actually be created for any given font
730 // entry, depending on the font tables that are present.
732 // hb_face_t is refcounted internally, so each shaper that's using it will
733 // bump the ref count when it acquires the face, and "destroy" (release) it
734 // in its destructor. The font entry has only this non-owning reference to
735 // the face; when the face is deleted, it will tell the font entry to forget
736 // it, so that a new face will be created next time it is needed.
737 mozilla::Atomic<hb_face_t*> mHBFace;
739 static hb_blob_t* HBGetTable(hb_face_t* face, uint32_t aTag, void* aUserData);
741 // Callback that the hb_face will use to tell us when it is being deleted.
742 static void HBFaceDeletedCallback(void* aUserData);
744 // All libGraphite functionality is sandboxed in an rlbox sandbox. This
745 // contains data for the sandbox instance.
746 // Currently graphite shaping is only supported on the main thread.
747 struct GrSandboxData;
748 GrSandboxData* mSandboxData = nullptr;
750 // gr_face is -not- refcounted, so it will be owned directly by the font
751 // entry, and we'll keep a count of how many references we've handed out;
752 // each shaper is responsible to call ReleaseGrFace on its entry when
753 // finished with it, so that we know when it can be deleted.
754 tainted_opaque_gr<gr_face*> mGrFace;
756 // For AAT font, a strong reference to the 'trak' table (if present).
757 hb_blob_t* const kTrakTableUninitialized = (hb_blob_t*)(intptr_t(-1));
758 mozilla::Atomic<hb_blob_t*> mTrakTable;
759 hb_blob_t* GetTrakTable() const { return mTrakTable; }
760 bool TrakTableInitialized() const {
761 return mTrakTable != kTrakTableUninitialized;
764 // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
765 // This data is inert once loaded, so locking is not required to read it.
766 const mozilla::AutoSwap_PRInt16* mTrakValues = nullptr;
767 const mozilla::AutoSwap_PRInt32* mTrakSizeTable = nullptr;
769 // number of current users of this entry's mGrFace
770 nsrefcnt mGrFaceRefCnt = 0;
772 friend class gfxFontEntryCallbacks;
774 // For memory reporting: size of user-font data belonging to this entry.
775 // We record this in the font entry because the actual data block may be
776 // handed over to platform APIs, so that it would become difficult (and
777 // platform-specific) to measure it directly at report-gathering time.
778 uint32_t mComputedSizeOfUserFont = 0;
780 // Font's unitsPerEm from the 'head' table, if available (will be set to
781 // kInvalidUPEM for non-sfnt font formats)
782 uint16_t mUnitsPerEm = 0;
784 uint16_t mNumTrakSizes = 0;
786 // Font extents in FUnits. (To be set from the 'head' table; default to
787 // "huge" to avoid any clipping if real extents not available.)
788 int16_t mXMin = std::numeric_limits<int16_t>::min();
789 int16_t mYMin = std::numeric_limits<int16_t>::min();
790 int16_t mXMax = std::numeric_limits<int16_t>::max();
791 int16_t mYMax = std::numeric_limits<int16_t>::max();
793 private:
795 * Font table hashtable, to support GetFontTable for harfbuzz.
797 * The harfbuzz shaper (and potentially other clients) needs access to raw
798 * font table data. This needs to be cached so that it can be used
799 * repeatedly (each time we construct a text run; in some cases, for
800 * each character/glyph within the run) without re-fetching large tables
801 * every time.
803 * Because we may instantiate many gfxFonts for the same physical font
804 * file (at different sizes), we should ensure that they can share a
805 * single cached copy of the font tables. To do this, we implement table
806 * access and sharing on the fontEntry rather than the font itself.
808 * The default implementation uses GetFontTable() to read font table
809 * data into byte arrays, and wraps them in blobs which are registered in
810 * a hashtable. The hashtable can then return pre-existing blobs to
811 * harfbuzz.
813 * Harfbuzz will "destroy" the blobs when it is finished with them. When
814 * the last blob reference is removed, the FontTableBlobData user data
815 * will remove the blob from the hashtable if still registered.
818 class FontTableBlobData;
821 * FontTableHashEntry manages the entries of hb_blob_t's containing font
822 * table data.
824 * This is used to share font tables across fonts with the same
825 * font entry (but different sizes) for use by HarfBuzz. The hashtable
826 * does not own a strong reference to the blob, but keeps a weak pointer,
827 * managed by FontTableBlobData. Similarly FontTableBlobData keeps only a
828 * weak pointer to the hashtable, managed by FontTableHashEntry.
831 class FontTableHashEntry : public nsUint32HashKey {
832 public:
833 // Declarations for nsTHashtable
835 typedef nsUint32HashKey KeyClass;
836 typedef KeyClass::KeyType KeyType;
837 typedef KeyClass::KeyTypePointer KeyTypePointer;
839 explicit FontTableHashEntry(KeyTypePointer aTag)
840 : KeyClass(aTag), mSharedBlobData(nullptr), mBlob(nullptr) {}
842 // NOTE: This assumes the new entry belongs to the same hashtable as
843 // the old, because the mHashtable pointer in mSharedBlobData (if
844 // present) will not be updated.
845 FontTableHashEntry(FontTableHashEntry&& toMove)
846 : KeyClass(std::move(toMove)),
847 mSharedBlobData(std::move(toMove.mSharedBlobData)),
848 mBlob(std::move(toMove.mBlob)) {
849 toMove.mSharedBlobData = nullptr;
850 toMove.mBlob = nullptr;
853 ~FontTableHashEntry() { Clear(); }
855 // FontTable/Blob API
857 // Transfer (not copy) elements of aTable to a new hb_blob_t and
858 // return ownership to the caller. A weak reference to the blob is
859 // recorded in the hashtable entry so that others may use the same
860 // table.
861 hb_blob_t* ShareTableAndGetBlob(
862 nsTArray<uint8_t>&& aTable,
863 nsTHashtable<FontTableHashEntry>* aHashtable);
865 // Return a strong reference to the blob.
866 // Callers must hb_blob_destroy the returned blob.
867 hb_blob_t* GetBlob() const;
869 void Clear();
871 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
873 private:
874 static void DeleteFontTableBlobData(void* aBlobData);
875 // not implemented
876 FontTableHashEntry& operator=(FontTableHashEntry& toCopy);
878 FontTableBlobData* mSharedBlobData;
879 hb_blob_t* mBlob;
882 using FontTableCache = nsTHashtable<FontTableHashEntry>;
883 mozilla::Atomic<FontTableCache*> mFontTableCache;
884 FontTableCache* GetFontTableCache() const { return mFontTableCache; }
887 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxFontEntry::RangeFlags)
888 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxFontEntry::SpaceFeatures)
890 inline bool gfxFontEntry::SupportsItalic() {
891 return SlantStyle().Max().IsItalic() ||
892 ((mRangeFlags & RangeFlags::eAutoSlantStyle) ==
893 RangeFlags::eAutoSlantStyle &&
894 HasItalicVariation());
897 inline bool gfxFontEntry::SupportsBold() {
898 // bold == weights 600 and above
899 // We return true if the face has a max weight descriptor >= 600,
900 // OR if it's a user font with auto-weight (no descriptor) and has
901 // a weight axis that supports values >= 600
902 return Weight().Max().IsBold() ||
903 ((mRangeFlags & RangeFlags::eAutoWeight) == RangeFlags::eAutoWeight &&
904 HasBoldVariableWeight());
907 inline bool gfxFontEntry::MayUseSyntheticSlant() {
908 if (!IsUpright()) {
909 return false; // The resource is already non-upright.
911 if (HasSlantVariation()) {
912 if (mRangeFlags & RangeFlags::eAutoSlantStyle) {
913 return false;
915 if (!SlantStyle().IsSingle()) {
916 return false; // The resource has a 'slnt' axis, and has not been
917 // clamped to just its upright setting.
920 return true;
923 // used when iterating over all fonts looking for a match for a given character
924 struct GlobalFontMatch {
925 GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh,
926 const gfxFontStyle& aStyle, eFontPresentation aPresentation)
927 : mStyle(aStyle),
928 mCh(aCharacter),
929 mNextCh(aNextCh),
930 mPresentation(aPresentation) {}
932 RefPtr<gfxFontEntry> mBestMatch; // current best match
933 RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
934 mozilla::fontlist::Family* mMatchedSharedFamily = nullptr;
935 const gfxFontStyle& mStyle; // style to match
936 const uint32_t mCh; // codepoint to be matched
937 const uint32_t mNextCh; // following codepoint (or zero)
938 eFontPresentation mPresentation;
939 uint32_t mCount = 0; // number of fonts matched
940 uint32_t mCmapsTested = 0; // number of cmaps tested
941 double mMatchDistance = INFINITY; // metric indicating closest match
944 class gfxFontFamily {
945 public:
946 // Used by stylo
947 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFamily)
949 gfxFontFamily(const nsACString& aName, FontVisibility aVisibility)
950 : mName(aName),
951 mLock("gfxFontFamily lock"),
952 mVisibility(aVisibility),
953 mIsSimpleFamily(false),
954 mIsBadUnderlineFamily(false),
955 mSkipDefaultFeatureSpaceCheck(false),
956 mCheckForFallbackFaces(false) {}
958 const nsCString& Name() const { return mName; }
960 virtual void LocalizedName(nsACString& aLocalizedName);
961 virtual bool HasOtherFamilyNames();
963 // See https://bugzilla.mozilla.org/show_bug.cgi?id=835204:
964 // check the font's 'name' table to see if it has a legacy family name
965 // that would have been used by GDI (e.g. to split extra-bold or light
966 // faces in a large family into separate "styled families" because of
967 // GDI's 4-faces-per-family limitation). If found, the styled family
968 // name will be added to the font list's "other family names" table.
969 // Note that the caller must already hold the gfxPlatformFontList lock.
970 bool CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList);
972 // Callers must hold a read-lock for as long as they're using the list.
973 const nsTArray<RefPtr<gfxFontEntry>>& GetFontList()
974 MOZ_REQUIRES_SHARED(mLock) {
975 return mAvailableFonts;
977 void ReadLock() MOZ_ACQUIRE_SHARED(mLock) { mLock.ReadLock(); }
978 void ReadUnlock() MOZ_RELEASE_SHARED(mLock) { mLock.ReadUnlock(); }
980 uint32_t FontListLength() const {
981 mozilla::AutoReadLock lock(mLock);
982 return mAvailableFonts.Length();
985 void AddFontEntry(RefPtr<gfxFontEntry> aFontEntry) {
986 mozilla::AutoWriteLock lock(mLock);
987 AddFontEntryLocked(aFontEntry);
990 void AddFontEntryLocked(RefPtr<gfxFontEntry> aFontEntry) MOZ_REQUIRES(mLock) {
991 // Avoid potentially duplicating entries.
992 if (mAvailableFonts.Contains(aFontEntry)) {
993 return;
995 // bug 589682 - set the IgnoreGDEF flag on entries for Italic faces
996 // of Times New Roman, because of buggy table in those fonts
997 if (aFontEntry->IsItalic() && !aFontEntry->IsUserFont() &&
998 Name().EqualsLiteral("Times New Roman")) {
999 aFontEntry->mIgnoreGDEF = true;
1001 if (aFontEntry->mFamilyName.IsEmpty()) {
1002 aFontEntry->mFamilyName = Name();
1003 } else {
1004 MOZ_ASSERT(aFontEntry->mFamilyName.Equals(Name()));
1006 aFontEntry->mSkipDefaultFeatureSpaceCheck = mSkipDefaultFeatureSpaceCheck;
1007 mAvailableFonts.AppendElement(aFontEntry);
1009 // If we're adding a face to a family that has been marked as "simple",
1010 // we need to ensure any null entries are removed, as well as clearing
1011 // the flag (which may be set again later).
1012 if (mIsSimpleFamily) {
1013 mAvailableFonts.RemoveElementsBy([](const auto& font) { return !font; });
1014 mIsSimpleFamily = false;
1018 // note that the styles for this family have been added
1019 bool HasStyles() const { return mHasStyles; }
1020 void SetHasStyles(bool aHasStyles) { mHasStyles = aHasStyles; }
1022 void SetCheckedForLegacyFamilyNames(bool aChecked) {
1023 mCheckedForLegacyFamilyNames = aChecked;
1026 // choose a specific face to match a style using CSS font matching
1027 // rules (weight matching occurs here). may return a face that doesn't
1028 // precisely match (e.g. normal face when no italic face exists).
1029 gfxFontEntry* FindFontForStyle(const gfxFontStyle& aFontStyle,
1030 bool aIgnoreSizeTolerance = false);
1032 virtual void FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
1033 nsTArray<gfxFontEntry*>& aFontEntryList,
1034 bool aIgnoreSizeTolerance = false);
1036 // Checks for a matching font within the family; used as part of the font
1037 // fallback process.
1038 // Note that when this is called, the caller must already be holding the
1039 // gfxPlatformFontList lock.
1040 void FindFontForChar(GlobalFontMatch* aMatchData);
1042 // checks all fonts for a matching font within the family
1043 void SearchAllFontsForChar(GlobalFontMatch* aMatchData);
1045 // read in other family names, if any, and use functor to add each into cache
1046 virtual void ReadOtherFamilyNames(gfxPlatformFontList* aPlatformFontList);
1048 // set when other family names have been read in
1049 void SetOtherFamilyNamesInitialized() { mOtherFamilyNamesInitialized = true; }
1051 // Read in other localized family names, fullnames and Postscript names
1052 // for all faces and append to lookup tables.
1053 // Note that when this is called, the caller must already be holding the
1054 // gfxPlatformFontList lock.
1055 virtual void ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
1056 bool aNeedFullnamePostscriptNames,
1057 FontInfoData* aFontInfoData = nullptr);
1059 // Find faces belonging to this family (platform implementations override).
1060 // This is a no-op in cases where the family is explicitly populated by other
1061 // means, rather than being asked to find its faces via system API.
1062 virtual void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
1063 MOZ_REQUIRES(mLock){};
1064 void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) {
1065 if (mHasStyles) {
1066 return;
1068 mozilla::AutoWriteLock lock(mLock);
1069 FindStyleVariationsLocked(aFontInfoData);
1072 // search for a specific face using the Postscript name
1073 gfxFontEntry* FindFont(const nsACString& aFontName,
1074 const nsCStringComparator& aCmp) const;
1076 // Read in cmaps for all the faces.
1077 // Note that when this is called, the caller must already be holding the
1078 // gfxPlatformFontList lock.
1079 void ReadAllCMAPs(FontInfoData* aFontInfoData = nullptr);
1081 bool TestCharacterMap(uint32_t aCh) {
1082 if (!mFamilyCharacterMapInitialized) {
1083 ReadAllCMAPs();
1085 mozilla::AutoReadLock lock(mLock);
1086 return mFamilyCharacterMap.test(aCh);
1089 void ResetCharacterMap() MOZ_REQUIRES(mLock) {
1090 mFamilyCharacterMap.reset();
1091 mFamilyCharacterMapInitialized = false;
1094 // mark this family as being in the "bad" underline offset blocklist
1095 void SetBadUnderlineFamily() {
1096 mozilla::AutoWriteLock lock(mLock);
1097 mIsBadUnderlineFamily = true;
1098 if (mHasStyles) {
1099 SetBadUnderlineFonts();
1103 virtual bool IsSingleFaceFamily() const { return false; }
1105 bool IsBadUnderlineFamily() const { return mIsBadUnderlineFamily; }
1106 bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
1108 // sort available fonts to put preferred (standard) faces towards the end
1109 void SortAvailableFonts() MOZ_REQUIRES(mLock);
1111 // check whether the family fits into the simple 4-face model,
1112 // so we can use simplified style-matching;
1113 // if so set the mIsSimpleFamily flag (defaults to False before we've checked)
1114 void CheckForSimpleFamily() MOZ_REQUIRES(mLock);
1116 // For memory reporter
1117 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
1118 FontListSizes* aSizes) const;
1119 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
1120 FontListSizes* aSizes) const;
1122 #ifdef DEBUG
1123 // Only used for debugging checks - does a linear search
1124 bool ContainsFace(gfxFontEntry* aFontEntry);
1125 #endif
1127 void SetSkipSpaceFeatureCheck(bool aSkipCheck) {
1128 mSkipDefaultFeatureSpaceCheck = aSkipCheck;
1131 // Check whether this family is appropriate to include in the Preferences
1132 // font list for the given langGroup and CSS generic, if the platform lets
1133 // us determine this.
1134 // Return true if the family should be included in the list, false to omit.
1135 // Default implementation returns true for everything, so no filtering
1136 // will occur; individual platforms may override.
1137 virtual bool FilterForFontList(nsAtom* aLangGroup,
1138 const nsACString& aGeneric) const {
1139 return true;
1142 FontVisibility Visibility() const { return mVisibility; }
1143 bool IsHidden() const { return Visibility() == FontVisibility::Hidden; }
1144 bool IsWebFontFamily() const {
1145 return Visibility() == FontVisibility::Webfont;
1148 protected:
1149 // Protected destructor, to discourage deletion outside of Release():
1150 virtual ~gfxFontFamily();
1152 bool ReadOtherFamilyNamesForFace(gfxPlatformFontList* aPlatformFontList,
1153 hb_blob_t* aNameTable,
1154 bool useFullName = false);
1156 // set whether this font family is in "bad" underline offset blocklist.
1157 void SetBadUnderlineFonts() MOZ_REQUIRES(mLock) {
1158 for (auto& f : mAvailableFonts) {
1159 if (f) {
1160 f->mIsBadUnderlineFont = true;
1165 nsCString mName;
1166 nsTArray<RefPtr<gfxFontEntry>> mAvailableFonts MOZ_GUARDED_BY(mLock);
1167 gfxSparseBitSet mFamilyCharacterMap MOZ_GUARDED_BY(mLock);
1169 mutable mozilla::RWLock mLock;
1171 FontVisibility mVisibility;
1173 mozilla::Atomic<bool> mOtherFamilyNamesInitialized;
1174 mozilla::Atomic<bool> mFaceNamesInitialized;
1175 mozilla::Atomic<bool> mHasStyles;
1176 mozilla::Atomic<bool> mFamilyCharacterMapInitialized;
1177 mozilla::Atomic<bool> mCheckedForLegacyFamilyNames;
1178 mozilla::Atomic<bool> mHasOtherFamilyNames;
1180 bool mIsSimpleFamily : 1 MOZ_GUARDED_BY(mLock);
1181 bool mIsBadUnderlineFamily : 1;
1182 bool mSkipDefaultFeatureSpaceCheck : 1;
1183 bool mCheckForFallbackFaces : 1; // check other faces for character
1185 enum {
1186 // for "simple" families, the faces are stored in mAvailableFonts
1187 // with fixed positions:
1188 kRegularFaceIndex = 0,
1189 kBoldFaceIndex = 1,
1190 kItalicFaceIndex = 2,
1191 kBoldItalicFaceIndex = 3,
1192 // mask values for selecting face with bold and/or italic attributes
1193 kBoldMask = 0x01,
1194 kItalicMask = 0x02
1198 // Wrapper for either a raw pointer to a mozilla::fontlist::Family in the shared
1199 // font list or a strong pointer to an unshared gfxFontFamily that belongs just
1200 // to the current process.
1201 struct FontFamily {
1202 FontFamily() = default;
1203 FontFamily(const FontFamily& aOther) = default;
1205 explicit FontFamily(RefPtr<gfxFontFamily>&& aFamily)
1206 : mUnshared(std::move(aFamily)) {}
1208 explicit FontFamily(gfxFontFamily* aFamily) : mUnshared(aFamily) {}
1210 explicit FontFamily(mozilla::fontlist::Family* aFamily) : mShared(aFamily) {}
1212 bool operator==(const FontFamily& aOther) const {
1213 return mShared == aOther.mShared && mUnshared == aOther.mUnshared;
1216 bool IsNull() const { return !mShared && !mUnshared; }
1218 RefPtr<gfxFontFamily> mUnshared;
1219 mozilla::fontlist::Family* mShared = nullptr;
1222 // Struct used in the gfxFontGroup font list to keep track of a font family
1223 // together with the CSS generic (if any) that was mapped to it in this
1224 // particular case (so it can be reported to the DevTools font inspector).
1225 struct FamilyAndGeneric final {
1226 FamilyAndGeneric() : mGeneric(mozilla::StyleGenericFontFamily(0)) {}
1227 FamilyAndGeneric(const FamilyAndGeneric& aOther) = default;
1228 explicit FamilyAndGeneric(gfxFontFamily* aFamily,
1229 mozilla::StyleGenericFontFamily aGeneric =
1230 mozilla::StyleGenericFontFamily(0))
1231 : mFamily(aFamily), mGeneric(aGeneric) {}
1232 explicit FamilyAndGeneric(RefPtr<gfxFontFamily>&& aFamily,
1233 mozilla::StyleGenericFontFamily aGeneric =
1234 mozilla::StyleGenericFontFamily(0))
1235 : mFamily(std::move(aFamily)), mGeneric(aGeneric) {}
1236 explicit FamilyAndGeneric(mozilla::fontlist::Family* aFamily,
1237 mozilla::StyleGenericFontFamily aGeneric =
1238 mozilla::StyleGenericFontFamily(0))
1239 : mFamily(aFamily), mGeneric(aGeneric) {}
1240 explicit FamilyAndGeneric(const FontFamily& aFamily,
1241 mozilla::StyleGenericFontFamily aGeneric =
1242 mozilla::StyleGenericFontFamily(0))
1243 : mFamily(aFamily), mGeneric(aGeneric) {}
1245 bool operator==(const FamilyAndGeneric& aOther) const {
1246 return mFamily == aOther.mFamily && mGeneric == aOther.mGeneric;
1249 FontFamily mFamily;
1250 mozilla::StyleGenericFontFamily mGeneric;
1253 #endif