Bug 1708193 - Remove mozapps/extensions/internal/Content.js r=rpl
[gecko.git] / gfx / thebes / gfxFontEntry.h
blob33eb8d83ce44b9874af745c3daa9828c76e54dc4
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 <math.h>
10 #include <new>
11 #include <utility>
12 #include "ThebesRLBoxTypes.h"
13 #include "gfxFontUtils.h"
14 #include "gfxFontVariations.h"
15 #include "gfxRect.h"
16 #include "gfxTypes.h"
17 #include "harfbuzz/hb.h"
18 #include "ipc/EnumSerializer.h"
19 #include "mozilla/AlreadyAddRefed.h"
20 #include "mozilla/Assertions.h"
21 #include "mozilla/FontPropertyTypes.h"
22 #include "mozilla/MemoryReporting.h"
23 #include "mozilla/RefPtr.h"
24 #include "mozilla/TypedEnumBits.h"
25 #include "mozilla/UniquePtr.h"
26 #include "nsTHashMap.h"
27 #include "nsDebug.h"
28 #include "nsHashKeys.h"
29 #include "nsISupports.h"
30 #include "nsStringFwd.h"
31 #include "nsTArray.h"
32 #include "nsUnicodeScriptCodes.h"
33 #include "nscore.h"
35 class FontInfoData;
36 class gfxContext;
37 class gfxFont;
38 class gfxFontFamily;
39 class gfxPlatformFontList;
40 class gfxSVGGlyphs;
41 class gfxUserFontData;
42 class nsAtom;
43 struct FontListSizes;
44 struct gfxFontFeature;
45 struct gfxFontStyle;
46 enum class eFontPresentation : uint8_t;
48 namespace IPC {
49 template <class P>
50 struct ParamTraits;
53 namespace mozilla {
54 class SVGContextPaint;
55 namespace fontlist {
56 struct Face;
57 struct Family;
58 } // namespace fontlist
59 namespace gfx {
60 struct DeviceColor;
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 nsrefcnt AddRef() {
72 MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
73 ++mRefCnt;
74 NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
75 return mRefCnt;
78 nsrefcnt Release() {
79 MOZ_ASSERT(0 != mRefCnt, "dup release");
80 --mRefCnt;
81 NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
82 if (mRefCnt == 0) {
83 NotifyReleased();
84 // |this| has been deleted.
85 return 0;
87 return mRefCnt;
90 gfxCharacterMap() : mHash(0), mBuildOnTheFly(false), mShared(false) {}
92 explicit gfxCharacterMap(const gfxSparseBitSet& aOther)
93 : gfxSparseBitSet(aOther),
94 mHash(0),
95 mBuildOnTheFly(false),
96 mShared(false) {}
98 void CalcHash() { mHash = GetChecksum(); }
100 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
101 return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
104 // hash of the cmap bitvector
105 uint32_t mHash;
107 // if cmap is built on the fly it's never shared
108 bool mBuildOnTheFly;
110 // cmap is shared globally
111 bool mShared;
113 protected:
114 void NotifyReleased();
116 nsAutoRefCnt mRefCnt;
118 private:
119 gfxCharacterMap(const gfxCharacterMap&);
120 gfxCharacterMap& operator=(const gfxCharacterMap&);
123 // Info on an individual font feature, for reporting available features
124 // to DevTools via the GetFeatureInfo method.
125 struct gfxFontFeatureInfo {
126 uint32_t mTag;
127 uint32_t mScript;
128 uint32_t mLangSys;
131 class gfxFontEntry {
132 public:
133 typedef mozilla::gfx::DrawTarget DrawTarget;
134 typedef mozilla::unicode::Script Script;
135 typedef mozilla::FontWeight FontWeight;
136 typedef mozilla::FontSlantStyle FontSlantStyle;
137 typedef mozilla::FontStretch FontStretch;
138 typedef mozilla::WeightRange WeightRange;
139 typedef mozilla::SlantStyleRange SlantStyleRange;
140 typedef mozilla::StretchRange StretchRange;
142 // Used by stylo
143 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry)
145 explicit gfxFontEntry(const nsACString& aName, bool aIsStandardFace = false);
147 // Create a new entry that refers to the same font as this, but without
148 // additional state that may have been set up (such as family name).
149 // (This is only to be used for system fonts in the platform font list,
150 // not user fonts.)
151 virtual gfxFontEntry* Clone() const = 0;
153 // unique name for the face, *not* the family; not necessarily the
154 // "real" or user-friendly name, may be an internal identifier
155 const nsCString& Name() const { return mName; }
157 // family name
158 const nsCString& FamilyName() const { return mFamilyName; }
160 // The following two methods may be relatively expensive, as they
161 // will (usually, except on Linux) load and parse the 'name' table;
162 // they are intended only for the font-inspection API, not for
163 // perf-critical layout/drawing work.
165 // The "real" name of the face, if available from the font resource;
166 // returns Name() if nothing better is available.
167 virtual nsCString RealFaceName();
169 WeightRange Weight() const { return mWeightRange; }
170 StretchRange Stretch() const { return mStretchRange; }
171 SlantStyleRange SlantStyle() const { return mStyleRange; }
173 bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; }
174 bool IsLocalUserFont() const { return mIsLocalUserFont; }
175 bool IsFixedPitch() const { return mFixedPitch; }
176 bool IsItalic() const { return SlantStyle().Min().IsItalic(); }
177 bool IsOblique() const { return SlantStyle().Min().IsOblique(); }
178 bool IsUpright() const { return SlantStyle().Min().IsNormal(); }
179 inline bool SupportsItalic();
180 inline bool SupportsBold(); // defined below, because of RangeFlags use
181 bool IgnoreGDEF() const { return mIgnoreGDEF; }
182 bool IgnoreGSUB() const { return mIgnoreGSUB; }
184 // Return whether the face corresponds to "normal" CSS style properties:
185 // font-style: normal;
186 // font-weight: normal;
187 // font-stretch: normal;
188 // If this is false, we might want to fall back to a different face and
189 // possibly apply synthetic styling.
190 bool IsNormalStyle() const {
191 return IsUpright() && Weight().Min() <= FontWeight::Normal() &&
192 Weight().Max() >= FontWeight::Normal() &&
193 Stretch().Min() <= FontStretch::Normal() &&
194 Stretch().Max() >= FontStretch::Normal();
197 // whether a feature is supported by the font (limited to a small set
198 // of features for which some form of fallback needs to be implemented)
199 virtual bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag);
200 bool SupportsGraphiteFeature(uint32_t aFeatureTag);
202 // returns a set containing all input glyph ids for a given feature
203 const hb_set_t* InputsForOpenTypeFeature(Script aScript,
204 uint32_t aFeatureTag);
206 virtual bool HasFontTable(uint32_t aTableTag);
208 inline bool HasGraphiteTables() {
209 if (!mCheckedForGraphiteTables) {
210 CheckForGraphiteTables();
211 mCheckedForGraphiteTables = true;
213 return mHasGraphiteTables;
216 inline bool HasCmapTable() {
217 if (!mCharacterMap && !mShmemCharacterMap) {
218 ReadCMAP();
219 NS_ASSERTION(mCharacterMap || mShmemCharacterMap,
220 "failed to initialize character map");
222 return mHasCmapTable;
225 inline bool HasCharacter(uint32_t ch) {
226 if (mShmemCharacterMap) {
227 return mShmemCharacterMap->test(ch);
229 if (mCharacterMap) {
230 if (mShmemFace && TrySetShmemCharacterMap()) {
231 // Forget our temporary local copy, now we can use the shared cmap
232 mCharacterMap = nullptr;
233 return mShmemCharacterMap->test(ch);
235 if (mCharacterMap->test(ch)) {
236 return true;
239 return TestCharacterMap(ch);
242 virtual bool SkipDuringSystemFallback() { return false; }
243 nsresult InitializeUVSMap();
244 uint16_t GetUVSGlyph(uint32_t aCh, uint32_t aVS);
246 // All concrete gfxFontEntry subclasses (except gfxUserFontEntry) need
247 // to override this, otherwise the font will never be used as it will
248 // be considered to support no characters.
249 // ReadCMAP() must *always* set the mCharacterMap pointer to a valid
250 // gfxCharacterMap, even if empty, as other code assumes this pointer
251 // can be safely dereferenced.
252 virtual nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr);
254 bool TryGetSVGData(gfxFont* aFont);
255 bool HasSVGGlyph(uint32_t aGlyphId);
256 bool GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId,
257 gfxFloat aSize, gfxRect* aResult);
258 void RenderSVGGlyph(gfxContext* aContext, uint32_t aGlyphId,
259 mozilla::SVGContextPaint* aContextPaint);
260 // Call this when glyph geometry or rendering has changed
261 // (e.g. animated SVG glyphs)
262 void NotifyGlyphsChanged();
264 bool TryGetColorGlyphs();
265 bool GetColorLayersInfo(uint32_t aGlyphId,
266 const mozilla::gfx::DeviceColor& aDefaultColor,
267 nsTArray<uint16_t>& layerGlyphs,
268 nsTArray<mozilla::gfx::DeviceColor>& layerColors);
269 bool HasColorLayersForGlyph(uint32_t aGlyphId) {
270 MOZ_ASSERT(mCOLR);
271 return gfxFontUtils::HasColorLayersForGlyph(mCOLR, aGlyphId);
274 bool HasColorBitmapTable() {
275 if (!mCheckedForColorBitmapTables) {
276 mHasColorBitmapTable = HasFontTable(TRUETYPE_TAG('C', 'B', 'D', 'T')) ||
277 HasFontTable(TRUETYPE_TAG('s', 'b', 'i', 'x'));
278 mCheckedForColorBitmapTables = true;
280 return mHasColorBitmapTable;
283 // Access to raw font table data (needed for Harfbuzz):
284 // returns a pointer to data owned by the fontEntry or the OS,
285 // which will remain valid until the blob is destroyed.
286 // The data MUST be treated as read-only; we may be getting a
287 // reference to a shared system font cache.
289 // The default implementation uses CopyFontTable to get the data
290 // into a byte array, and maintains a cache of loaded tables.
292 // Subclasses should override this if they can provide more efficient
293 // access than copying table data into our own buffers.
295 // Get blob that encapsulates a specific font table, or nullptr if
296 // the table doesn't exist in the font.
298 // Caller is responsible to call hb_blob_destroy() on the returned blob
299 // (if non-nullptr) when no longer required. For transient access to a
300 // table, use of AutoTable (below) is generally preferred.
301 virtual hb_blob_t* GetFontTable(uint32_t aTag);
303 // Stack-based utility to return a specified table, automatically releasing
304 // the blob when the AutoTable goes out of scope.
305 class AutoTable {
306 public:
307 AutoTable(gfxFontEntry* aFontEntry, uint32_t aTag) {
308 mBlob = aFontEntry->GetFontTable(aTag);
310 ~AutoTable() { hb_blob_destroy(mBlob); }
311 operator hb_blob_t*() const { return mBlob; }
313 private:
314 hb_blob_t* mBlob;
315 // not implemented:
316 AutoTable(const AutoTable&) = delete;
317 AutoTable& operator=(const AutoTable&) = delete;
320 // Return a font instance for a particular style. This may be a newly-
321 // created instance, or a font already in the global cache.
322 // We can't return a UniquePtr here, because we may be returning a shared
323 // cached instance; but we also don't return already_AddRefed, because
324 // the caller may only need to use the font temporarily and doesn't need
325 // a strong reference.
326 gfxFont* FindOrMakeFont(const gfxFontStyle* aStyle,
327 gfxCharacterMap* aUnicodeRangeMap = nullptr);
329 // Get an existing font table cache entry in aBlob if it has been
330 // registered, or return false if not. Callers must call
331 // hb_blob_destroy on aBlob if true is returned.
333 // Note that some gfxFont implementations may not call this at all,
334 // if it is more efficient to get the table from the OS at that level.
335 bool GetExistingFontTable(uint32_t aTag, hb_blob_t** aBlob);
337 // Elements of aTable are transferred (not copied) to and returned in a
338 // new hb_blob_t which is registered on the gfxFontEntry, but the initial
339 // reference is owned by the caller. Removing the last reference
340 // unregisters the table from the font entry.
342 // Pass nullptr for aBuffer to indicate that the table is not present and
343 // nullptr will be returned. Also returns nullptr on OOM.
344 hb_blob_t* ShareFontTableAndGetBlob(uint32_t aTag, nsTArray<uint8_t>* aTable);
346 // Get the font's unitsPerEm from the 'head' table, in the case of an
347 // sfnt resource. Will return kInvalidUPEM for non-sfnt fonts,
348 // if present on the platform.
349 uint16_t UnitsPerEm();
350 enum {
351 kMinUPEM = 16, // Limits on valid unitsPerEm range, from the
352 kMaxUPEM = 16384, // OpenType spec
353 kInvalidUPEM = uint16_t(-1)
356 // Shaper face accessors:
357 // NOTE that harfbuzz and graphite handle ownership/lifetime of the face
358 // object in completely different ways.
360 // Get HarfBuzz face corresponding to this font file.
361 // Caller must release with hb_face_destroy() when finished with it,
362 // and the font entry will be notified via ForgetHBFace.
363 hb_face_t* GetHBFace();
364 void ForgetHBFace();
366 // Get the sandbox instance that graphite is running in.
367 rlbox_sandbox_gr* GetGrSandbox();
369 // Register and get the callback handle for the glyph advance firefox callback
370 // Since the sandbox instance is shared with multiple test shapers, callback
371 // registration must be handled centrally to ensure multiple instances don't
372 // register the same callback.
373 sandbox_callback_gr<float (*)(const void*, uint16_t)>*
374 GetGrSandboxAdvanceCallbackHandle();
376 // Get Graphite face corresponding to this font file.
377 // Caller must call gfxFontEntry::ReleaseGrFace when finished with it.
378 // Graphite is run in a sandbox
379 tainted_opaque_gr<gr_face*> GetGrFace();
380 void ReleaseGrFace(tainted_opaque_gr<gr_face*> aFace);
382 // Does the font have graphite contextuals that involve the space glyph
383 // (and therefore we should bypass the word cache)?
384 // Since this function inspects data from libGraphite stored in sandbox memory
385 // it can only return a "hint" to the correct return value. This is because
386 // a compromised libGraphite could change the sandbox memory maliciously at
387 // any moment. The caller must ensure the calling code performs safe actions
388 // independent of the value returned, to unwrap this return.
389 tainted_boolean_hint HasGraphiteSpaceContextuals();
391 // Release any SVG-glyphs document this font may have loaded.
392 void DisconnectSVG();
394 // Called to notify that aFont is being destroyed. Needed when we're tracking
395 // the fonts belonging to this font entry.
396 void NotifyFontDestroyed(gfxFont* aFont);
398 // For memory reporting of the platform font list.
399 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
400 FontListSizes* aSizes) const;
401 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
402 FontListSizes* aSizes) const;
404 // Used for reporting on individual font entries in the user font cache,
405 // which are not present in the platform font list.
406 size_t ComputedSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
408 // Used when checking for complex script support, to mask off cmap ranges
409 struct ScriptRange {
410 uint32_t rangeStart;
411 uint32_t rangeEnd;
412 uint32_t numTags; // number of entries in the tags[] array
413 hb_tag_t tags[3]; // up to three OpenType script tags to check
416 bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags, uint32_t aNumTags);
419 * Font-variation query methods.
421 * Font backends that don't support variations should provide empty
422 * implementations.
424 virtual bool HasVariations() = 0;
426 virtual void GetVariationAxes(
427 nsTArray<gfxFontVariationAxis>& aVariationAxes) = 0;
429 virtual void GetVariationInstances(
430 nsTArray<gfxFontVariationInstance>& aInstances) = 0;
432 bool HasBoldVariableWeight();
433 bool HasItalicVariation();
434 bool HasOpticalSize();
436 void CheckForVariationAxes();
438 // Set up the entry's weight/stretch/style ranges according to axes found
439 // by GetVariationAxes (for installed fonts; do NOT call this for user
440 // fonts, where the ranges are provided by @font-face descriptors).
441 void SetupVariationRanges();
443 // Get variation axis settings that should be used to implement a particular
444 // font style using this resource.
445 void GetVariationsForStyle(nsTArray<gfxFontVariation>& aResult,
446 const gfxFontStyle& aStyle);
448 // Get the font's list of features (if any) for DevTools support.
449 void GetFeatureInfo(nsTArray<gfxFontFeatureInfo>& aFeatureInfo);
451 // This is only called on platforms where we use FreeType.
452 virtual FT_MM_Var* GetMMVar() { return nullptr; }
454 // Return true if the font has a 'trak' table (and we can successfully
455 // interpret it), otherwise false. This will load and cache the table
456 // the first time it is called.
457 bool HasTrackingTable();
459 // Return the tracking (in font units) to be applied for the given size.
460 // (This is a floating-point number because of possible interpolation.)
461 float TrackingForCSSPx(float aSize) const;
463 nsCString mName;
464 nsCString mFamilyName;
466 RefPtr<gfxCharacterMap> mCharacterMap;
468 mozilla::fontlist::Face* mShmemFace = nullptr;
469 const SharedBitSet* mShmemCharacterMap = nullptr;
471 mozilla::UniquePtr<uint8_t[]> mUVSData;
472 mozilla::UniquePtr<gfxUserFontData> mUserFontData;
473 mozilla::UniquePtr<gfxSVGGlyphs> mSVGGlyphs;
474 // list of gfxFonts that are using SVG glyphs
475 nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
476 nsTArray<gfxFontFeature> mFeatureSettings;
477 nsTArray<gfxFontVariation> mVariationSettings;
478 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, bool>> mSupportedFeatures;
479 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, hb_set_t*>> mFeatureInputs;
481 // Color Layer font support
482 hb_blob_t* mCOLR = nullptr;
483 hb_blob_t* mCPAL = nullptr;
485 // bitvector of substitution space features per script, one each
486 // for default and non-default features
487 uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
488 uint32_t
489 mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
491 uint32_t mUVSOffset = 0;
493 uint32_t mLanguageOverride = NO_FONT_LANGUAGE_OVERRIDE;
495 WeightRange mWeightRange = WeightRange(FontWeight(500));
496 StretchRange mStretchRange = StretchRange(FontStretch::Normal());
497 SlantStyleRange mStyleRange = SlantStyleRange(FontSlantStyle::Normal());
499 // Font metrics overrides (as multiples of used font size); negative values
500 // indicate no override to be applied.
501 float mAscentOverride = -1.0;
502 float mDescentOverride = -1.0;
503 float mLineGapOverride = -1.0;
505 // Scaling factor to be applied to the font size.
506 float mSizeAdjust = 1.0;
508 // For user fonts (only), we need to record whether or not weight/stretch/
509 // slant variations should be clamped to the range specified in the entry
510 // properties. When the @font-face rule omitted one or more of these
511 // descriptors, it is treated as the initial value for font-matching (and
512 // so that is what we record in the font entry), but when rendering the
513 // range is NOT clamped.
514 enum class RangeFlags : uint8_t {
515 eNoFlags = 0,
516 eAutoWeight = (1 << 0),
517 eAutoStretch = (1 << 1),
518 eAutoSlantStyle = (1 << 2),
520 // Flag to record whether the face has a variable "wght" axis
521 // that supports "bold" values, used to disable the application
522 // of synthetic-bold effects.
523 eBoldVariableWeight = (1 << 3),
524 // Whether the face has an 'ital' axis.
525 eItalicVariation = (1 << 4),
527 // Flags to record if the face uses a non-CSS-compatible scale
528 // for weight and/or stretch, in which case we won't map the
529 // properties to the variation axes (though they can still be
530 // explicitly set using font-variation-settings).
531 eNonCSSWeight = (1 << 5),
532 eNonCSSStretch = (1 << 6),
534 // Whether the font has an 'opsz' axis.
535 eOpticalSize = (1 << 7)
537 RangeFlags mRangeFlags = RangeFlags::eNoFlags;
539 bool mFixedPitch : 1;
540 bool mIsBadUnderlineFont : 1;
541 bool mIsUserFontContainer : 1; // userfont entry
542 bool mIsDataUserFont : 1; // platform font entry (data)
543 bool mIsLocalUserFont : 1; // platform font entry (local)
544 bool mStandardFace : 1;
545 bool mIgnoreGDEF : 1;
546 bool mIgnoreGSUB : 1;
547 bool mSVGInitialized : 1;
548 bool mHasSpaceFeaturesInitialized : 1;
549 bool mHasSpaceFeatures : 1;
550 bool mHasSpaceFeaturesKerning : 1;
551 bool mHasSpaceFeaturesNonKerning : 1;
552 bool mSkipDefaultFeatureSpaceCheck : 1;
553 bool mGraphiteSpaceContextualsInitialized : 1;
554 bool mHasGraphiteSpaceContextuals : 1;
555 bool mSpaceGlyphIsInvisible : 1;
556 bool mSpaceGlyphIsInvisibleInitialized : 1;
557 bool mHasGraphiteTables : 1;
558 bool mCheckedForGraphiteTables : 1;
559 bool mHasCmapTable : 1;
560 bool mGrFaceInitialized : 1;
561 bool mCheckedForColorGlyph : 1;
562 bool mCheckedForVariationAxes : 1;
563 bool mHasColorBitmapTable : 1;
564 bool mCheckedForColorBitmapTables : 1;
566 protected:
567 friend class gfxPlatformFontList;
568 friend class gfxFontFamily;
569 friend class gfxUserFontEntry;
571 gfxFontEntry();
573 // Protected destructor, to discourage deletion outside of Release():
574 virtual ~gfxFontEntry();
576 virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) = 0;
578 virtual void CheckForGraphiteTables();
580 // Copy a font table into aBuffer.
581 // The caller will be responsible for ownership of the data.
582 virtual nsresult CopyFontTable(uint32_t aTableTag,
583 nsTArray<uint8_t>& aBuffer) {
584 MOZ_ASSERT_UNREACHABLE(
585 "forgot to override either GetFontTable or "
586 "CopyFontTable?");
587 return NS_ERROR_FAILURE;
590 // Helper for HasTrackingTable; check/parse the table and cache pointers
591 // to the subtables we need. Returns false on failure, in which case the
592 // table is unusable.
593 bool ParseTrakTable();
595 // lookup the cmap in cached font data
596 virtual already_AddRefed<gfxCharacterMap> GetCMAPFromFontInfo(
597 FontInfoData* aFontInfoData, uint32_t& aUVSOffset);
599 // helper for HasCharacter(), which is what client code should call
600 virtual bool TestCharacterMap(uint32_t aCh);
602 // Try to set mShmemCharacterMap, based on the char map in mShmemFace;
603 // return true if successful, false if it remains null (maybe the parent
604 // hasn't handled our SetCharacterMap message yet).
605 bool TrySetShmemCharacterMap();
607 // Helper for gfxPlatformFontList::CreateFontEntry methods: set properties
608 // of the gfxFontEntry based on shared Face and Family records.
609 void InitializeFrom(mozilla::fontlist::Face* aFace,
610 const mozilla::fontlist::Family* aFamily);
612 // Shaper-specific face objects, shared by all instantiations of the same
613 // physical font, regardless of size.
614 // Usually, only one of these will actually be created for any given font
615 // entry, depending on the font tables that are present.
617 // hb_face_t is refcounted internally, so each shaper that's using it will
618 // bump the ref count when it acquires the face, and "destroy" (release) it
619 // in its destructor. The font entry has only this non-owning reference to
620 // the face; when the face is deleted, it will tell the font entry to forget
621 // it, so that a new face will be created next time it is needed.
622 hb_face_t* mHBFace = nullptr;
624 static hb_blob_t* HBGetTable(hb_face_t* face, uint32_t aTag, void* aUserData);
626 // Callback that the hb_face will use to tell us when it is being deleted.
627 static void HBFaceDeletedCallback(void* aUserData);
629 // All libGraphite functionality is sandboxed in an rlbox sandbox. This
630 // contains data for the sandbox instance.
631 struct GrSandboxData;
632 GrSandboxData* mSandboxData = nullptr;
634 // gr_face is -not- refcounted, so it will be owned directly by the font
635 // entry, and we'll keep a count of how many references we've handed out;
636 // each shaper is responsible to call ReleaseGrFace on its entry when
637 // finished with it, so that we know when it can be deleted.
638 tainted_opaque_gr<gr_face*> mGrFace;
640 // For AAT font, a strong reference to the 'trak' table (if present).
641 hb_blob_t* const kTrakTableUninitialized = (hb_blob_t*)(intptr_t(-1));
642 hb_blob_t* mTrakTable = kTrakTableUninitialized;
643 bool TrakTableInitialized() const {
644 return mTrakTable != kTrakTableUninitialized;
647 // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
648 const mozilla::AutoSwap_PRInt16* mTrakValues;
649 const mozilla::AutoSwap_PRInt32* mTrakSizeTable;
651 // number of current users of this entry's mGrFace
652 nsrefcnt mGrFaceRefCnt = 0;
654 static tainted_opaque_gr<const void*> GrGetTable(
655 rlbox_sandbox_gr& sandbox, tainted_opaque_gr<const void*> aAppFaceHandle,
656 tainted_opaque_gr<unsigned int> aName,
657 tainted_opaque_gr<unsigned int*> aLen);
658 static void GrReleaseTable(rlbox_sandbox_gr& sandbox,
659 tainted_opaque_gr<const void*> aAppFaceHandle,
660 tainted_opaque_gr<const void*> aTableBuffer);
662 // For memory reporting: size of user-font data belonging to this entry.
663 // We record this in the font entry because the actual data block may be
664 // handed over to platform APIs, so that it would become difficult (and
665 // platform-specific) to measure it directly at report-gathering time.
666 uint32_t mComputedSizeOfUserFont = 0;
668 // Font's unitsPerEm from the 'head' table, if available (will be set to
669 // kInvalidUPEM for non-sfnt font formats)
670 uint16_t mUnitsPerEm = 0;
672 uint16_t mNumTrakSizes;
674 private:
676 * Font table hashtable, to support GetFontTable for harfbuzz.
678 * The harfbuzz shaper (and potentially other clients) needs access to raw
679 * font table data. This needs to be cached so that it can be used
680 * repeatedly (each time we construct a text run; in some cases, for
681 * each character/glyph within the run) without re-fetching large tables
682 * every time.
684 * Because we may instantiate many gfxFonts for the same physical font
685 * file (at different sizes), we should ensure that they can share a
686 * single cached copy of the font tables. To do this, we implement table
687 * access and sharing on the fontEntry rather than the font itself.
689 * The default implementation uses GetFontTable() to read font table
690 * data into byte arrays, and wraps them in blobs which are registered in
691 * a hashtable. The hashtable can then return pre-existing blobs to
692 * harfbuzz.
694 * Harfbuzz will "destroy" the blobs when it is finished with them. When
695 * the last blob reference is removed, the FontTableBlobData user data
696 * will remove the blob from the hashtable if still registered.
699 class FontTableBlobData;
702 * FontTableHashEntry manages the entries of hb_blob_t's containing font
703 * table data.
705 * This is used to share font tables across fonts with the same
706 * font entry (but different sizes) for use by HarfBuzz. The hashtable
707 * does not own a strong reference to the blob, but keeps a weak pointer,
708 * managed by FontTableBlobData. Similarly FontTableBlobData keeps only a
709 * weak pointer to the hashtable, managed by FontTableHashEntry.
712 class FontTableHashEntry : public nsUint32HashKey {
713 public:
714 // Declarations for nsTHashtable
716 typedef nsUint32HashKey KeyClass;
717 typedef KeyClass::KeyType KeyType;
718 typedef KeyClass::KeyTypePointer KeyTypePointer;
720 explicit FontTableHashEntry(KeyTypePointer aTag)
721 : KeyClass(aTag), mSharedBlobData(nullptr), mBlob(nullptr) {}
723 // NOTE: This assumes the new entry belongs to the same hashtable as
724 // the old, because the mHashtable pointer in mSharedBlobData (if
725 // present) will not be updated.
726 FontTableHashEntry(FontTableHashEntry&& toMove)
727 : KeyClass(std::move(toMove)),
728 mSharedBlobData(std::move(toMove.mSharedBlobData)),
729 mBlob(std::move(toMove.mBlob)) {
730 toMove.mSharedBlobData = nullptr;
731 toMove.mBlob = nullptr;
734 ~FontTableHashEntry() { Clear(); }
736 // FontTable/Blob API
738 // Transfer (not copy) elements of aTable to a new hb_blob_t and
739 // return ownership to the caller. A weak reference to the blob is
740 // recorded in the hashtable entry so that others may use the same
741 // table.
742 hb_blob_t* ShareTableAndGetBlob(
743 nsTArray<uint8_t>&& aTable,
744 nsTHashtable<FontTableHashEntry>* aHashtable);
746 // Return a strong reference to the blob.
747 // Callers must hb_blob_destroy the returned blob.
748 hb_blob_t* GetBlob() const;
750 void Clear();
752 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
754 private:
755 static void DeleteFontTableBlobData(void* aBlobData);
756 // not implemented
757 FontTableHashEntry& operator=(FontTableHashEntry& toCopy);
759 FontTableBlobData* mSharedBlobData;
760 hb_blob_t* mBlob;
763 mozilla::UniquePtr<nsTHashtable<FontTableHashEntry>> mFontTableCache;
765 gfxFontEntry(const gfxFontEntry&);
766 gfxFontEntry& operator=(const gfxFontEntry&);
769 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxFontEntry::RangeFlags)
771 inline bool gfxFontEntry::SupportsItalic() {
772 return SlantStyle().Max().IsItalic() ||
773 ((mRangeFlags & RangeFlags::eAutoSlantStyle) ==
774 RangeFlags::eAutoSlantStyle &&
775 HasItalicVariation());
778 inline bool gfxFontEntry::SupportsBold() {
779 // bold == weights 600 and above
780 // We return true if the face has a max weight descriptor >= 600,
781 // OR if it's a user font with auto-weight (no descriptor) and has
782 // a weight axis that supports values >= 600
783 return Weight().Max().IsBold() ||
784 ((mRangeFlags & RangeFlags::eAutoWeight) == RangeFlags::eAutoWeight &&
785 HasBoldVariableWeight());
788 // used when iterating over all fonts looking for a match for a given character
789 struct GlobalFontMatch {
790 GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh,
791 const gfxFontStyle& aStyle, eFontPresentation aPresentation)
792 : mStyle(aStyle),
793 mCh(aCharacter),
794 mNextCh(aNextCh),
795 mPresentation(aPresentation) {}
797 RefPtr<gfxFontEntry> mBestMatch; // current best match
798 RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
799 mozilla::fontlist::Family* mMatchedSharedFamily = nullptr;
800 const gfxFontStyle& mStyle; // style to match
801 const uint32_t mCh; // codepoint to be matched
802 const uint32_t mNextCh; // following codepoint (or zero)
803 eFontPresentation mPresentation;
804 uint32_t mCount = 0; // number of fonts matched
805 uint32_t mCmapsTested = 0; // number of cmaps tested
806 double mMatchDistance = INFINITY; // metric indicating closest match
809 // The actual FontVisibility enum is defined in gfxTypes.h
810 namespace IPC {
811 template <>
812 struct ParamTraits<FontVisibility>
813 : public ContiguousEnumSerializer<FontVisibility, FontVisibility::Unknown,
814 FontVisibility::Count> {};
815 } // namespace IPC
817 class gfxFontFamily {
818 public:
819 // Used by stylo
820 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFamily)
822 gfxFontFamily(const nsACString& aName, FontVisibility aVisibility)
823 : mName(aName),
824 mVisibility(aVisibility),
825 mOtherFamilyNamesInitialized(false),
826 mHasOtherFamilyNames(false),
827 mFaceNamesInitialized(false),
828 mHasStyles(false),
829 mIsSimpleFamily(false),
830 mIsBadUnderlineFamily(false),
831 mFamilyCharacterMapInitialized(false),
832 mSkipDefaultFeatureSpaceCheck(false),
833 mCheckForFallbackFaces(false),
834 mCheckedForLegacyFamilyNames(false) {}
836 const nsCString& Name() const { return mName; }
838 virtual void LocalizedName(nsACString& aLocalizedName);
839 virtual bool HasOtherFamilyNames();
841 // See https://bugzilla.mozilla.org/show_bug.cgi?id=835204:
842 // check the font's 'name' table to see if it has a legacy family name
843 // that would have been used by GDI (e.g. to split extra-bold or light
844 // faces in a large family into separate "styled families" because of
845 // GDI's 4-faces-per-family limitation). If found, the styled family
846 // name will be added to the font list's "other family names" table.
847 bool CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList);
849 nsTArray<RefPtr<gfxFontEntry>>& GetFontList() { return mAvailableFonts; }
851 void AddFontEntry(RefPtr<gfxFontEntry> aFontEntry) {
852 // bug 589682 - set the IgnoreGDEF flag on entries for Italic faces
853 // of Times New Roman, because of buggy table in those fonts
854 if (aFontEntry->IsItalic() && !aFontEntry->IsUserFont() &&
855 Name().EqualsLiteral("Times New Roman")) {
856 aFontEntry->mIgnoreGDEF = true;
858 if (aFontEntry->mFamilyName.IsEmpty()) {
859 aFontEntry->mFamilyName = Name();
860 } else {
861 MOZ_ASSERT(aFontEntry->mFamilyName.Equals(Name()));
863 aFontEntry->mSkipDefaultFeatureSpaceCheck = mSkipDefaultFeatureSpaceCheck;
864 mAvailableFonts.AppendElement(aFontEntry);
866 // If we're adding a face to a family that has been marked as "simple",
867 // we need to ensure any null entries are removed, as well as clearing
868 // the flag (which may be set again later).
869 if (mIsSimpleFamily) {
870 mAvailableFonts.RemoveElementsBy([](const auto& font) { return !font; });
871 mIsSimpleFamily = false;
875 // note that the styles for this family have been added
876 bool HasStyles() { return mHasStyles; }
877 void SetHasStyles(bool aHasStyles) { mHasStyles = aHasStyles; }
879 // choose a specific face to match a style using CSS font matching
880 // rules (weight matching occurs here). may return a face that doesn't
881 // precisely match (e.g. normal face when no italic face exists).
882 gfxFontEntry* FindFontForStyle(const gfxFontStyle& aFontStyle,
883 bool aIgnoreSizeTolerance = false);
885 virtual void FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
886 nsTArray<gfxFontEntry*>& aFontEntryList,
887 bool aIgnoreSizeTolerance = false);
889 // checks for a matching font within the family
890 // used as part of the font fallback process
891 void FindFontForChar(GlobalFontMatch* aMatchData);
893 // checks all fonts for a matching font within the family
894 void SearchAllFontsForChar(GlobalFontMatch* aMatchData);
896 // read in other family names, if any, and use functor to add each into cache
897 virtual void ReadOtherFamilyNames(gfxPlatformFontList* aPlatformFontList);
899 // set when other family names have been read in
900 void SetOtherFamilyNamesInitialized() { mOtherFamilyNamesInitialized = true; }
902 // read in other localized family names, fullnames and Postscript names
903 // for all faces and append to lookup tables
904 virtual void ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
905 bool aNeedFullnamePostscriptNames,
906 FontInfoData* aFontInfoData = nullptr);
908 // find faces belonging to this family (platform implementations override
909 // this; should be made pure virtual once all subclasses have been updated)
910 virtual void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) {}
912 // search for a specific face using the Postscript name
913 gfxFontEntry* FindFont(const nsACString& aPostscriptName);
915 // read in cmaps for all the faces
916 void ReadAllCMAPs(FontInfoData* aFontInfoData = nullptr);
918 bool TestCharacterMap(uint32_t aCh) {
919 if (!mFamilyCharacterMapInitialized) {
920 ReadAllCMAPs();
922 return mFamilyCharacterMap.test(aCh);
925 void ResetCharacterMap() {
926 mFamilyCharacterMap.reset();
927 mFamilyCharacterMapInitialized = false;
930 // mark this family as being in the "bad" underline offset blocklist
931 void SetBadUnderlineFamily() {
932 mIsBadUnderlineFamily = true;
933 if (mHasStyles) {
934 SetBadUnderlineFonts();
938 virtual bool IsSingleFaceFamily() const { return false; }
940 bool IsBadUnderlineFamily() const { return mIsBadUnderlineFamily; }
941 bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
943 // sort available fonts to put preferred (standard) faces towards the end
944 void SortAvailableFonts();
946 // check whether the family fits into the simple 4-face model,
947 // so we can use simplified style-matching;
948 // if so set the mIsSimpleFamily flag (defaults to False before we've checked)
949 void CheckForSimpleFamily();
951 // For memory reporter
952 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
953 FontListSizes* aSizes) const;
954 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
955 FontListSizes* aSizes) const;
957 #ifdef DEBUG
958 // Only used for debugging checks - does a linear search
959 bool ContainsFace(gfxFontEntry* aFontEntry);
960 #endif
962 void SetSkipSpaceFeatureCheck(bool aSkipCheck) {
963 mSkipDefaultFeatureSpaceCheck = aSkipCheck;
966 // Check whether this family is appropriate to include in the Preferences
967 // font list for the given langGroup and CSS generic, if the platform lets
968 // us determine this.
969 // Return true if the family should be included in the list, false to omit.
970 // Default implementation returns true for everything, so no filtering
971 // will occur; individual platforms may override.
972 virtual bool FilterForFontList(nsAtom* aLangGroup,
973 const nsACString& aGeneric) const {
974 return true;
977 FontVisibility Visibility() const { return mVisibility; }
978 bool IsHidden() const { return Visibility() == FontVisibility::Hidden; }
979 bool IsWebFontFamily() const {
980 return Visibility() == FontVisibility::Webfont;
983 protected:
984 // Protected destructor, to discourage deletion outside of Release():
985 virtual ~gfxFontFamily();
987 bool ReadOtherFamilyNamesForFace(gfxPlatformFontList* aPlatformFontList,
988 hb_blob_t* aNameTable,
989 bool useFullName = false);
991 // set whether this font family is in "bad" underline offset blocklist.
992 void SetBadUnderlineFonts() {
993 uint32_t i, numFonts = mAvailableFonts.Length();
994 for (i = 0; i < numFonts; i++) {
995 if (mAvailableFonts[i]) {
996 mAvailableFonts[i]->mIsBadUnderlineFont = true;
1001 nsCString mName;
1002 nsTArray<RefPtr<gfxFontEntry>> mAvailableFonts;
1003 gfxSparseBitSet mFamilyCharacterMap;
1005 FontVisibility mVisibility;
1007 bool mOtherFamilyNamesInitialized : 1;
1008 bool mHasOtherFamilyNames : 1;
1009 bool mFaceNamesInitialized : 1;
1010 bool mHasStyles : 1;
1011 bool mIsSimpleFamily : 1;
1012 bool mIsBadUnderlineFamily : 1;
1013 bool mFamilyCharacterMapInitialized : 1;
1014 bool mSkipDefaultFeatureSpaceCheck : 1;
1015 bool mCheckForFallbackFaces : 1; // check other faces for character
1016 bool mCheckedForLegacyFamilyNames : 1;
1018 enum {
1019 // for "simple" families, the faces are stored in mAvailableFonts
1020 // with fixed positions:
1021 kRegularFaceIndex = 0,
1022 kBoldFaceIndex = 1,
1023 kItalicFaceIndex = 2,
1024 kBoldItalicFaceIndex = 3,
1025 // mask values for selecting face with bold and/or italic attributes
1026 kBoldMask = 0x01,
1027 kItalicMask = 0x02
1031 // Wrapper for either a mozilla::fontlist::Family in the shared font list or an
1032 // unshared gfxFontFamily that belongs just to the current process. This does
1033 // not own a reference, it just wraps a raw pointer and records the type.
1034 struct FontFamily {
1035 FontFamily() : mUnshared(nullptr), mIsShared(false) {}
1037 FontFamily(const FontFamily& aOther) = default;
1039 explicit FontFamily(gfxFontFamily* aFamily)
1040 : mUnshared(aFamily), mIsShared(false) {}
1042 explicit FontFamily(mozilla::fontlist::Family* aFamily)
1043 : mShared(aFamily), mIsShared(true) {}
1045 bool operator==(const FontFamily& aOther) const {
1046 return mIsShared == aOther.mIsShared &&
1047 (mIsShared ? mShared == aOther.mShared
1048 : mUnshared == aOther.mUnshared);
1051 bool IsNull() const { return mIsShared ? !mShared : !mUnshared; }
1053 union {
1054 gfxFontFamily* mUnshared;
1055 mozilla::fontlist::Family* mShared;
1057 bool mIsShared;
1060 // Struct used in the gfxFontGroup font list to keep track of a font family
1061 // together with the CSS generic (if any) that was mapped to it in this
1062 // particular case (so it can be reported to the DevTools font inspector).
1063 struct FamilyAndGeneric final {
1064 FamilyAndGeneric()
1065 : mFamily(), mGeneric(mozilla::StyleGenericFontFamily(0)) {}
1066 FamilyAndGeneric(const FamilyAndGeneric& aOther) = default;
1067 explicit FamilyAndGeneric(gfxFontFamily* aFamily,
1068 mozilla::StyleGenericFontFamily aGeneric =
1069 mozilla::StyleGenericFontFamily(0))
1070 : mFamily(aFamily), mGeneric(aGeneric) {}
1071 explicit FamilyAndGeneric(mozilla::fontlist::Family* aFamily,
1072 mozilla::StyleGenericFontFamily aGeneric =
1073 mozilla::StyleGenericFontFamily(0))
1074 : mFamily(aFamily), mGeneric(aGeneric) {}
1075 explicit FamilyAndGeneric(const FontFamily& aFamily,
1076 mozilla::StyleGenericFontFamily aGeneric =
1077 mozilla::StyleGenericFontFamily(0))
1078 : mFamily(aFamily), mGeneric(aGeneric) {}
1080 bool operator==(const FamilyAndGeneric& aOther) const {
1081 return mFamily == aOther.mFamily && mGeneric == aOther.mGeneric;
1084 FontFamily mFamily;
1085 mozilla::StyleGenericFontFamily mGeneric;
1088 #endif