CoreTextFontList.h (10668B)
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/. */ 5 6 #ifndef CoreTextFontList_H 7 #define CoreTextFontList_H 8 9 #include <CoreFoundation/CoreFoundation.h> 10 11 #include "gfxPlatformFontList.h" 12 #include "gfxPlatformMac.h" 13 14 #include "mozilla/FontPropertyTypes.h" 15 #include "mozilla/gfx/UnscaledFontMac.h" 16 #include "mozilla/LookAndFeel.h" 17 #include "mozilla/MemoryReporting.h" 18 19 #include "nsRefPtrHashtable.h" 20 #include "nsTArray.h" 21 #include "nsUnicharUtils.h" 22 23 // Abstract base class for Core Text/Core Graphics-based platform font list, 24 // which is subclassed to create specific macOS and iOS variants. 25 26 // A single member of a font family (i.e. a single face, such as Times Italic). 27 class CTFontEntry final : public gfxFontEntry { 28 public: 29 friend class CoreTextFontList; 30 friend class gfxMacPlatformFontList; 31 friend class gfxMacFont; 32 33 CTFontEntry(const nsACString& aPostscriptName, WeightRange aWeight, 34 bool aIsStandardFace = false, double aSizeHint = 0.0); 35 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); 40 41 virtual ~CTFontEntry() { ::CGFontRelease(mFontRef); } 42 43 gfxFontEntry* Clone() const override; 44 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 47 // of the entry. 48 // Note that in the case of a broken font, this could return null. 49 CGFontRef GetFontRef(); 50 51 // Return a new reference to our CGFont. Caller is responsible to release 52 // this reference. 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 55 // caller.) 56 // Note that in the case of a broken font, this could return null. 57 CGFontRef CreateOrCopyFontRef() MOZ_REQUIRES_SHARED(mLock); 58 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; 62 63 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 64 FontListSizes* aSizes) const override; 65 66 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; 67 68 bool RequiresAATLayout() const { return mRequiresAAT; } 69 70 bool HasVariations() override; 71 void GetVariationAxes( 72 nsTArray<gfxFontVariationAxis>& aVariationAxes) override; 73 void GetVariationInstances( 74 nsTArray<gfxFontVariationInstance>& aInstances) override; 75 76 bool IsCFF(); 77 78 bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag) override; 79 80 size_t ComputedSizeOfExcludingThis( 81 mozilla::MallocSizeOf aMallocSizeOf) override { 82 return gfxFontEntry::ComputedSizeOfExcludingThis(aMallocSizeOf) + 83 mComputedSizeOfUserFont; 84 } 85 86 protected: 87 gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override; 88 89 bool HasFontTable(uint32_t aTableTag) override; 90 91 static void DestroyBlobFunc(void* aUserData); 92 93 CGFontRef mFontRef MOZ_GUARDED_BY(mLock); // owning reference 94 95 const double mSizeHint; 96 97 bool mFontRefInitialized MOZ_GUARDED_BY(mLock); 98 99 mozilla::Atomic<bool> mRequiresAAT; 100 mozilla::Atomic<bool> mIsCFF; 101 mozilla::Atomic<bool> mIsCFFInitialized; 102 mozilla::Atomic<bool> mHasVariations; 103 mozilla::Atomic<bool> mHasVariationsInitialized; 104 mozilla::Atomic<bool> mHasAATSmallCaps; 105 mozilla::Atomic<bool> mHasAATSmallCapsInitialized; 106 107 // To work around Core Text's mishandling of the default value for 'opsz', 108 // we need to record whether the font has an a optical size axis, what its 109 // range and default values are, and a usable close-to-default alternative. 110 // (See bug 1457417 for details.) 111 // These fields are used by gfxMacFont, but stored in the font entry so 112 // that only a single font instance needs to inspect the available 113 // variations. 114 gfxFontVariationAxis mOpszAxis MOZ_GUARDED_BY(mLock); 115 float mAdjustedDefaultOpsz MOZ_GUARDED_BY(mLock); 116 117 nsTHashtable<nsUint32HashKey> mAvailableTables MOZ_GUARDED_BY(mLock); 118 119 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont; 120 121 size_t mComputedSizeOfUserFont = 0; 122 }; 123 124 class CTFontFamily : public gfxFontFamily { 125 public: 126 CTFontFamily(const nsACString& aName, FontVisibility aVisibility) 127 : gfxFontFamily(aName, aVisibility) {} 128 129 CTFontFamily(const nsACString& aName, CTFontRef aSystemFont) 130 : gfxFontFamily(aName, FontVisibility::Unknown), 131 mForSystemFont(aSystemFont) { 132 // I don't think the system font instance is at much risk of being deleted, 133 // but to be on the safe side let's retain a reference until we're finished 134 // using it for lazy initialization. 135 CFRetain(mForSystemFont); 136 } 137 138 virtual ~CTFontFamily() = default; 139 140 void LocalizedName(nsACString& aLocalizedName) override; 141 142 void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr) 143 MOZ_REQUIRES(mLock) override; 144 145 protected: 146 void AddFace(CTFontDescriptorRef aFace) MOZ_REQUIRES(mLock); 147 148 // If non-null, this is a family representing the system UI font, and should 149 // use the given CTFontRef as the basis for initialization as the normal 150 // font-manager APIs based on family name won't handle it. 151 CTFontRef mForSystemFont = nullptr; 152 }; 153 154 class gfxMacFontFamily final : public CTFontFamily { 155 public: 156 }; 157 158 class CoreTextFontList : public gfxPlatformFontList { 159 using FontFamilyListEntry = mozilla::dom::SystemFontListEntry; 160 161 public: 162 gfxFontFamily* CreateFontFamily(const nsACString& aName, 163 FontVisibility aVisibility) const override; 164 165 static int32_t AppleWeightToCSSWeight(int32_t aAppleWeight); 166 167 gfxFontEntry* LookupLocalFont(FontVisibilityProvider* aFontVisibilityProvider, 168 const nsACString& aFontName, 169 WeightRange aWeightForEntry, 170 StretchRange aStretchForEntry, 171 SlantStyleRange aStyleForEntry) override; 172 173 gfxFontEntry* MakePlatformFont(const nsACString& aFontName, 174 WeightRange aWeightForEntry, 175 StretchRange aStretchForEntry, 176 SlantStyleRange aStyleForEntry, 177 const uint8_t* aFontData, 178 uint32_t aLength) override; 179 180 bool FindAndAddFamiliesLocked( 181 FontVisibilityProvider* aFontVisibilityProvider, 182 mozilla::StyleGenericFontFamily aGeneric, const nsACString& aFamily, 183 nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags, 184 gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr, 185 gfxFloat aDevToCssSize = 1.0) MOZ_REQUIRES(mLock) override; 186 187 // Values for the entryType field in FontFamilyListEntry records passed 188 // from chrome to content process. 189 enum FontFamilyEntryType { 190 kStandardFontFamily = 0, // a standard installed font family 191 kSystemFontFamily = 1, // name of 'system' font 192 }; 193 void ReadSystemFontList(mozilla::dom::SystemFontList*); 194 195 protected: 196 CoreTextFontList(); 197 virtual ~CoreTextFontList(); 198 199 // initialize font lists 200 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override; 201 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override; 202 203 // handle commonly used fonts for which the name table should be loaded at 204 // startup 205 void PreloadNamesList() MOZ_REQUIRES(mLock); 206 207 // initialize system fonts 208 void InitSystemFontNames() MOZ_REQUIRES(mLock); 209 210 // look up a default font to use as fallback 211 FontFamily GetDefaultFontForPlatform( 212 FontVisibilityProvider* aFontVisibilityProvider, 213 const gfxFontStyle* aStyle, nsAtom* aLanguage = nullptr) 214 MOZ_REQUIRES(mLock) override; 215 216 // Hooks for the macOS-specific "single face family" hack (Osaka-mono). 217 virtual void InitSingleFaceList() {} 218 virtual void InitAliasesForSingleFaceList() {} 219 220 virtual bool DeprecatedFamilyIsAvailable(const nsACString& aName) { 221 return false; 222 } 223 224 virtual FontVisibility GetVisibilityForFamily(const nsACString& aName) const { 225 return FontVisibility::Unknown; 226 } 227 228 // helper function to lookup in both hidden system fonts and normal fonts 229 gfxFontFamily* FindSystemFontFamily(const nsACString& aFamily) 230 MOZ_REQUIRES(mLock); 231 232 static void RegisteredFontsChangedNotificationCallback( 233 CFNotificationCenterRef center, void* observer, CFStringRef name, 234 const void* object, CFDictionaryRef userInfo); 235 236 // attempt to use platform-specific fallback for the given character 237 // return null if no usable result found 238 gfxFontEntry* PlatformGlobalFontFallback( 239 FontVisibilityProvider* aFontVisibilityProvider, const uint32_t aCh, 240 Script aRunScript, const gfxFontStyle* aMatchStyle, 241 FontFamily& aMatchedFamily) MOZ_REQUIRES(mLock) override; 242 243 bool UsesSystemFallback() override { return true; } 244 245 already_AddRefed<FontInfoData> CreateFontInfoData() override; 246 247 // Add the specified family to mFontFamilies. 248 void AddFamily(CFStringRef aFamily) MOZ_REQUIRES(mLock); 249 250 void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility) 251 MOZ_REQUIRES(mLock); 252 253 static void ActivateFontsFromDir( 254 const nsACString& aDir, 255 nsTHashSet<nsCStringHashKey>* aLoadedFamilies = nullptr); 256 257 gfxFontEntry* CreateFontEntry( 258 mozilla::fontlist::Face* aFace, 259 const mozilla::fontlist::Family* aFamily) override; 260 261 void GetFacesInitDataForFamily( 262 const mozilla::fontlist::Family* aFamily, 263 nsTArray<mozilla::fontlist::Face::InitData>& aFaces, 264 bool aLoadCmaps) const override; 265 266 static void AddFaceInitData( 267 CTFontDescriptorRef aFontDesc, 268 nsTArray<mozilla::fontlist::Face::InitData>& aFaces, bool aLoadCmaps); 269 270 void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily, 271 bool aNeedFullnamePostscriptNames) 272 MOZ_REQUIRES(mLock) override; 273 274 #ifdef MOZ_BUNDLED_FONTS 275 void ActivateBundledFonts(); 276 #endif 277 278 // default font for use with system-wide font fallback 279 CTFontRef mDefaultFont; 280 281 // Font family that -apple-system maps to 282 nsCString mSystemFontFamilyName; 283 284 nsTArray<nsCString> mPreloadFonts; 285 286 #ifdef MOZ_BUNDLED_FONTS 287 nsTHashSet<nsCStringHashKey> mBundledFamilies; 288 #endif 289 }; 290 291 #endif /* CoreTextFontList_H */