summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxMacPlatformFontList.h
blob: dd24eebe695b9277c19401056c9cea3b0b54e85b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef gfxMacPlatformFontList_H_
#define gfxMacPlatformFontList_H_

#include <CoreFoundation/CoreFoundation.h>

#include "mozilla/FontPropertyTypes.h"
#include "mozilla/MemoryReporting.h"
#include "nsRefPtrHashtable.h"

#include "gfxPlatformFontList.h"
#include "gfxPlatform.h"
#include "gfxPlatformMac.h"

#include "nsUnicharUtils.h"
#include "nsTArray.h"
#include "mozilla/LookAndFeel.h"

#include "mozilla/gfx/UnscaledFontMac.h"

class gfxMacPlatformFontList;

// a single member of a font family (i.e. a single face, such as Times Italic)
class MacOSFontEntry final : public gfxFontEntry {
 public:
  friend class gfxMacPlatformFontList;
  friend class gfxMacFont;

  MacOSFontEntry(const nsACString& aPostscriptName, WeightRange aWeight,
                 bool aIsStandardFace = false, double aSizeHint = 0.0);

  // for use with data fonts
  MacOSFontEntry(const nsACString& aPostscriptName, CGFontRef aFontRef,
                 WeightRange aWeight, StretchRange aStretch,
                 SlantStyleRange aStyle, bool aIsDataUserFont, bool aIsLocal);

  virtual ~MacOSFontEntry() { ::CGFontRelease(mFontRef); }

  gfxFontEntry* Clone() const override;

  // Return a non-owning reference to our CGFont; caller must not release it.
  // This will cause the fontEntry to create & retain a CGFont for the life
  // of the entry.
  // Note that in the case of a broken font, this could return null.
  CGFontRef GetFontRef();

  // Return a new reference to our CGFont. Caller is responsible to release
  // this reference.
  // (If the entry has a cached CGFont, this just bumps its refcount and
  // returns it; if not, the instance returned will be owned solely by the
  // caller.)
  // Note that in the case of a broken font, this could return null.
  CGFontRef CreateOrCopyFontRef() MOZ_REQUIRES_SHARED(mLock);

  // override gfxFontEntry table access function to bypass table cache,
  // use CGFontRef API to get direct access to system font data
  hb_blob_t* GetFontTable(uint32_t aTag) override;

  void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                              FontListSizes* aSizes) const override;

  nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;

  bool RequiresAATLayout() const { return mRequiresAAT; }

  bool HasVariations() override;
  void GetVariationAxes(
      nsTArray<gfxFontVariationAxis>& aVariationAxes) override;
  void GetVariationInstances(
      nsTArray<gfxFontVariationInstance>& aInstances) override;

  bool IsCFF();

  bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag) override;

 protected:
  gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;

  bool HasFontTable(uint32_t aTableTag) override;

  static void DestroyBlobFunc(void* aUserData);

  CGFontRef mFontRef MOZ_GUARDED_BY(mLock);  // owning reference

  const double mSizeHint;

  bool mFontRefInitialized MOZ_GUARDED_BY(mLock);

  mozilla::Atomic<bool> mRequiresAAT;
  mozilla::Atomic<bool> mIsCFF;
  mozilla::Atomic<bool> mIsCFFInitialized;
  mozilla::Atomic<bool> mHasVariations;
  mozilla::Atomic<bool> mHasVariationsInitialized;
  mozilla::Atomic<bool> mHasAATSmallCaps;
  mozilla::Atomic<bool> mHasAATSmallCapsInitialized;

  // To work around Core Text's mishandling of the default value for 'opsz',
  // we need to record whether the font has an a optical size axis, what its
  // range and default values are, and a usable close-to-default alternative.
  // (See bug 1457417 for details.)
  // These fields are used by gfxMacFont, but stored in the font entry so
  // that only a single font instance needs to inspect the available
  // variations.
  gfxFontVariationAxis mOpszAxis MOZ_GUARDED_BY(mLock);
  float mAdjustedDefaultOpsz MOZ_GUARDED_BY(mLock);

  nsTHashtable<nsUint32HashKey> mAvailableTables MOZ_GUARDED_BY(mLock);

  mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
};

class gfxMacPlatformFontList final : public gfxPlatformFontList {
  using FontFamilyListEntry = mozilla::dom::SystemFontListEntry;

 public:
  static gfxMacPlatformFontList* PlatformFontList() {
    return static_cast<gfxMacPlatformFontList*>(
        gfxPlatformFontList::PlatformFontList());
  }

  gfxFontFamily* CreateFontFamily(const nsACString& aName,
                                  FontVisibility aVisibility) const override;

  static int32_t AppleWeightToCSSWeight(int32_t aAppleWeight);

  gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
                                const nsACString& aFontName,
                                WeightRange aWeightForEntry,
                                StretchRange aStretchForEntry,
                                SlantStyleRange aStyleForEntry) override;

  gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
                                 WeightRange aWeightForEntry,
                                 StretchRange aStretchForEntry,
                                 SlantStyleRange aStyleForEntry,
                                 const uint8_t* aFontData,
                                 uint32_t aLength) override;

  bool FindAndAddFamiliesLocked(
      nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
      const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
      FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
      nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
      MOZ_REQUIRES(mLock) override;

  // lookup the system font for a particular system font type and set
  // the name and style characteristics
  void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
                        nsACString& aSystemFontName, gfxFontStyle& aFontStyle);

  // Values for the entryType field in FontFamilyListEntry records passed
  // from chrome to content process.
  enum FontFamilyEntryType {
    kStandardFontFamily = 0,          // a standard installed font family
    kTextSizeSystemFontFamily = 1,    // name of 'system' font at text sizes
    kDisplaySizeSystemFontFamily = 2  // 'system' font at display sizes
  };
  void ReadSystemFontList(mozilla::dom::SystemFontList*);

 protected:
  FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
                                       const gfxFontStyle* aStyle,
                                       nsAtom* aLanguage = nullptr)
      MOZ_REQUIRES(mLock) override;

 private:
  friend class gfxPlatformMac;

  gfxMacPlatformFontList();
  virtual ~gfxMacPlatformFontList();

  // initialize font lists
  nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override;
  void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override;

  // handle commonly used fonts for which the name table should be loaded at
  // startup
  void PreloadNamesList() MOZ_REQUIRES(mLock);

  // special case font faces treated as font families (set via prefs)
  void InitSingleFaceList() MOZ_REQUIRES(mLock);
  void InitAliasesForSingleFaceList() MOZ_REQUIRES(mLock);

  // initialize system fonts
  void InitSystemFontNames() MOZ_REQUIRES(mLock);

  // helper function to lookup in both hidden system fonts and normal fonts
  gfxFontFamily* FindSystemFontFamily(const nsACString& aFamily)
      MOZ_REQUIRES(mLock);

  FontVisibility GetVisibilityForFamily(const nsACString& aName) const;

  static void RegisteredFontsChangedNotificationCallback(
      CFNotificationCenterRef center, void* observer, CFStringRef name,
      const void* object, CFDictionaryRef userInfo);

  // attempt to use platform-specific fallback for the given character
  // return null if no usable result found
  gfxFontEntry* PlatformGlobalFontFallback(nsPresContext* aPresContext,
                                           const uint32_t aCh,
                                           Script aRunScript,
                                           const gfxFontStyle* aMatchStyle,
                                           FontFamily& aMatchedFamily)
      MOZ_REQUIRES(mLock) override;

  bool UsesSystemFallback() override { return true; }

  already_AddRefed<FontInfoData> CreateFontInfoData() override;

  // Add the specified family to mFontFamilies.
  // Ideally we'd use NSString* instead of CFStringRef here, but this header
  // file is included in .cpp files, so we can't use objective C classes here.
  // But CFStringRef and NSString* are the same thing anyway (they're
  // toll-free bridged).
  void AddFamily(CFStringRef aFamily) MOZ_REQUIRES(mLock);

  void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility)
      MOZ_REQUIRES(mLock);

  static void ActivateFontsFromDir(
      const nsACString& aDir,
      nsTHashSet<nsCStringHashKey>* aLoadedFamilies = nullptr);

  gfxFontEntry* CreateFontEntry(
      mozilla::fontlist::Face* aFace,
      const mozilla::fontlist::Family* aFamily) override;

  void GetFacesInitDataForFamily(
      const mozilla::fontlist::Family* aFamily,
      nsTArray<mozilla::fontlist::Face::InitData>& aFaces,
      bool aLoadCmaps) const override;

  void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
                              bool aNeedFullnamePostscriptNames)
      MOZ_REQUIRES(mLock) override;

#ifdef MOZ_BUNDLED_FONTS
  void ActivateBundledFonts();
#endif

  enum { kATSGenerationInitial = -1 };

  // default font for use with system-wide font fallback
  CTFontRef mDefaultFont;

  // font families that -apple-system maps to
  // Pre-10.11 this was always a single font family, such as Lucida Grande
  // or Helvetica Neue. For OSX 10.11, Apple uses pair of families
  // for the UI, one for text sizes and another for display sizes
  bool mUseSizeSensitiveSystemFont;
  nsCString mSystemTextFontFamilyName;
  nsCString mSystemDisplayFontFamilyName;  // only used on OSX 10.11

  nsTArray<nsCString> mSingleFaceFonts;
  nsTArray<nsCString> mPreloadFonts;

#ifdef MOZ_BUNDLED_FONTS
  nsTHashSet<nsCStringHashKey> mBundledFamilies;
#endif
};

#endif /* gfxMacPlatformFontList_H_ */