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 CoreTextFontList_H
7 #define CoreTextFontList_H
9 #include <CoreFoundation/CoreFoundation.h>
11 #include "gfxPlatformFontList.h"
12 #include "gfxPlatformMac.h"
14 #include "mozilla/FontPropertyTypes.h"
15 #include "mozilla/gfx/UnscaledFontMac.h"
16 #include "mozilla/LookAndFeel.h"
17 #include "mozilla/MemoryReporting.h"
19 #include "nsRefPtrHashtable.h"
21 #include "nsUnicharUtils.h"
23 // Abstract base class for Core Text/Core Graphics-based platform font list,
24 // which is subclassed to create specific macOS and iOS variants.
26 // A single member of a font family (i.e. a single face, such as Times Italic).
27 class CTFontEntry final
: public gfxFontEntry
{
29 friend class CoreTextFontList
;
30 friend class gfxMacPlatformFontList
;
31 friend class gfxMacFont
;
33 CTFontEntry(const nsACString
& aPostscriptName
, WeightRange aWeight
,
34 bool aIsStandardFace
= false, double aSizeHint
= 0.0);
36 // for use with data fonts
37 CTFontEntry(const nsACString
& aPostscriptName
, CGFontRef aFontRef
,
38 WeightRange aWeight
, StretchRange aStretch
,
39 SlantStyleRange aStyle
, bool aIsDataUserFont
, bool aIsLocal
);
41 virtual ~CTFontEntry() { ::CGFontRelease(mFontRef
); }
43 gfxFontEntry
* Clone() const override
;
45 // Return a non-owning reference to our CGFont; caller must not release it.
46 // This will cause the fontEntry to create & retain a CGFont for the life
48 // Note that in the case of a broken font, this could return null.
49 CGFontRef
GetFontRef();
51 // Return a new reference to our CGFont. Caller is responsible to release
53 // (If the entry has a cached CGFont, this just bumps its refcount and
54 // returns it; if not, the instance returned will be owned solely by the
56 // Note that in the case of a broken font, this could return null.
57 CGFontRef
CreateOrCopyFontRef() MOZ_REQUIRES_SHARED(mLock
);
59 // override gfxFontEntry table access function to bypass table cache,
60 // use CGFontRef API to get direct access to system font data
61 hb_blob_t
* GetFontTable(uint32_t aTag
) override
;
63 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
,
64 FontListSizes
* aSizes
) const override
;
66 nsresult
ReadCMAP(FontInfoData
* aFontInfoData
= nullptr) override
;
68 bool RequiresAATLayout() const { return mRequiresAAT
; }
70 bool HasVariations() override
;
71 void GetVariationAxes(
72 nsTArray
<gfxFontVariationAxis
>& aVariationAxes
) override
;
73 void GetVariationInstances(
74 nsTArray
<gfxFontVariationInstance
>& aInstances
) override
;
78 bool SupportsOpenTypeFeature(Script aScript
, uint32_t aFeatureTag
) override
;
81 gfxFont
* CreateFontInstance(const gfxFontStyle
* aFontStyle
) override
;
83 bool HasFontTable(uint32_t aTableTag
) override
;
85 static void DestroyBlobFunc(void* aUserData
);
87 CGFontRef mFontRef
MOZ_GUARDED_BY(mLock
); // owning reference
89 const double mSizeHint
;
91 bool mFontRefInitialized
MOZ_GUARDED_BY(mLock
);
93 mozilla::Atomic
<bool> mRequiresAAT
;
94 mozilla::Atomic
<bool> mIsCFF
;
95 mozilla::Atomic
<bool> mIsCFFInitialized
;
96 mozilla::Atomic
<bool> mHasVariations
;
97 mozilla::Atomic
<bool> mHasVariationsInitialized
;
98 mozilla::Atomic
<bool> mHasAATSmallCaps
;
99 mozilla::Atomic
<bool> mHasAATSmallCapsInitialized
;
101 // To work around Core Text's mishandling of the default value for 'opsz',
102 // we need to record whether the font has an a optical size axis, what its
103 // range and default values are, and a usable close-to-default alternative.
104 // (See bug 1457417 for details.)
105 // These fields are used by gfxMacFont, but stored in the font entry so
106 // that only a single font instance needs to inspect the available
108 gfxFontVariationAxis mOpszAxis
MOZ_GUARDED_BY(mLock
);
109 float mAdjustedDefaultOpsz
MOZ_GUARDED_BY(mLock
);
111 nsTHashtable
<nsUint32HashKey
> mAvailableTables
MOZ_GUARDED_BY(mLock
);
113 mozilla::ThreadSafeWeakPtr
<mozilla::gfx::UnscaledFontMac
> mUnscaledFont
;
116 class CTFontFamily
: public gfxFontFamily
{
118 CTFontFamily(const nsACString
& aName
, FontVisibility aVisibility
)
119 : gfxFontFamily(aName
, aVisibility
) {}
121 CTFontFamily(const nsACString
& aName
, CTFontRef aSystemFont
)
122 : gfxFontFamily(aName
, FontVisibility::Unknown
),
123 mForSystemFont(aSystemFont
) {
124 // I don't think the system font instance is at much risk of being deleted,
125 // but to be on the safe side let's retain a reference until we're finished
126 // using it for lazy initialization.
127 CFRetain(mForSystemFont
);
130 virtual ~CTFontFamily() = default;
132 void LocalizedName(nsACString
& aLocalizedName
) override
;
134 void FindStyleVariationsLocked(FontInfoData
* aFontInfoData
= nullptr)
135 MOZ_REQUIRES(mLock
) override
;
138 void AddFace(CTFontDescriptorRef aFace
) MOZ_REQUIRES(mLock
);
140 // If non-null, this is a family representing the system UI font, and should
141 // use the given CTFontRef as the basis for initialization as the normal
142 // font-manager APIs based on family name won't handle it.
143 CTFontRef mForSystemFont
= nullptr;
146 class gfxMacFontFamily final
: public CTFontFamily
{
150 class CoreTextFontList
: public gfxPlatformFontList
{
151 using FontFamilyListEntry
= mozilla::dom::SystemFontListEntry
;
154 gfxFontFamily
* CreateFontFamily(const nsACString
& aName
,
155 FontVisibility aVisibility
) const override
;
157 static int32_t AppleWeightToCSSWeight(int32_t aAppleWeight
);
159 gfxFontEntry
* LookupLocalFont(nsPresContext
* aPresContext
,
160 const nsACString
& aFontName
,
161 WeightRange aWeightForEntry
,
162 StretchRange aStretchForEntry
,
163 SlantStyleRange aStyleForEntry
) override
;
165 gfxFontEntry
* MakePlatformFont(const nsACString
& aFontName
,
166 WeightRange aWeightForEntry
,
167 StretchRange aStretchForEntry
,
168 SlantStyleRange aStyleForEntry
,
169 const uint8_t* aFontData
,
170 uint32_t aLength
) override
;
172 bool FindAndAddFamiliesLocked(
173 nsPresContext
* aPresContext
, mozilla::StyleGenericFontFamily aGeneric
,
174 const nsACString
& aFamily
, nsTArray
<FamilyAndGeneric
>* aOutput
,
175 FindFamiliesFlags aFlags
, gfxFontStyle
* aStyle
= nullptr,
176 nsAtom
* aLanguage
= nullptr, gfxFloat aDevToCssSize
= 1.0)
177 MOZ_REQUIRES(mLock
) override
;
179 // Values for the entryType field in FontFamilyListEntry records passed
180 // from chrome to content process.
181 enum FontFamilyEntryType
{
182 kStandardFontFamily
= 0, // a standard installed font family
183 kSystemFontFamily
= 1, // name of 'system' font
185 void ReadSystemFontList(mozilla::dom::SystemFontList
*);
189 virtual ~CoreTextFontList();
191 // initialize font lists
192 nsresult
InitFontListForPlatform() MOZ_REQUIRES(mLock
) override
;
193 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock
) override
;
195 // handle commonly used fonts for which the name table should be loaded at
197 void PreloadNamesList() MOZ_REQUIRES(mLock
);
199 // initialize system fonts
200 void InitSystemFontNames() MOZ_REQUIRES(mLock
);
202 // look up a default font to use as fallback
203 FontFamily
GetDefaultFontForPlatform(nsPresContext
* aPresContext
,
204 const gfxFontStyle
* aStyle
,
205 nsAtom
* aLanguage
= nullptr)
206 MOZ_REQUIRES(mLock
) override
;
208 // Hooks for the macOS-specific "single face family" hack (Osaka-mono).
209 virtual void InitSingleFaceList() {}
210 virtual void InitAliasesForSingleFaceList() {}
212 virtual bool DeprecatedFamilyIsAvailable(const nsACString
& aName
) {
216 virtual FontVisibility
GetVisibilityForFamily(const nsACString
& aName
) const {
217 return FontVisibility::Unknown
;
220 // helper function to lookup in both hidden system fonts and normal fonts
221 gfxFontFamily
* FindSystemFontFamily(const nsACString
& aFamily
)
224 static void RegisteredFontsChangedNotificationCallback(
225 CFNotificationCenterRef center
, void* observer
, CFStringRef name
,
226 const void* object
, CFDictionaryRef userInfo
);
228 // attempt to use platform-specific fallback for the given character
229 // return null if no usable result found
230 gfxFontEntry
* PlatformGlobalFontFallback(nsPresContext
* aPresContext
,
233 const gfxFontStyle
* aMatchStyle
,
234 FontFamily
& aMatchedFamily
)
235 MOZ_REQUIRES(mLock
) override
;
237 bool UsesSystemFallback() override
{ return true; }
239 already_AddRefed
<FontInfoData
> CreateFontInfoData() override
;
241 // Add the specified family to mFontFamilies.
242 void AddFamily(CFStringRef aFamily
) MOZ_REQUIRES(mLock
);
244 void AddFamily(const nsACString
& aFamilyName
, FontVisibility aVisibility
)
247 static void ActivateFontsFromDir(
248 const nsACString
& aDir
,
249 nsTHashSet
<nsCStringHashKey
>* aLoadedFamilies
= nullptr);
251 gfxFontEntry
* CreateFontEntry(
252 mozilla::fontlist::Face
* aFace
,
253 const mozilla::fontlist::Family
* aFamily
) override
;
255 void GetFacesInitDataForFamily(
256 const mozilla::fontlist::Family
* aFamily
,
257 nsTArray
<mozilla::fontlist::Face::InitData
>& aFaces
,
258 bool aLoadCmaps
) const override
;
260 static void AddFaceInitData(
261 CTFontDescriptorRef aFontDesc
,
262 nsTArray
<mozilla::fontlist::Face::InitData
>& aFaces
, bool aLoadCmaps
);
264 void ReadFaceNamesForFamily(mozilla::fontlist::Family
* aFamily
,
265 bool aNeedFullnamePostscriptNames
)
266 MOZ_REQUIRES(mLock
) override
;
268 #ifdef MOZ_BUNDLED_FONTS
269 void ActivateBundledFonts();
272 // default font for use with system-wide font fallback
273 CTFontRef mDefaultFont
;
275 // Font family that -apple-system maps to
276 nsCString mSystemFontFamilyName
;
278 nsTArray
<nsCString
> mPreloadFonts
;
280 #ifdef MOZ_BUNDLED_FONTS
281 nsTHashSet
<nsCStringHashKey
> mBundledFamilies
;
285 #endif /* CoreTextFontList_H */