Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / thebes / gfxDWriteFontList.h
blob357336a12cc0519391c484ca87c9ae8a149ffdf3
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_DWRITEFONTLIST_H
7 #define GFX_DWRITEFONTLIST_H
9 #include "mozilla/FontPropertyTypes.h"
10 #include "mozilla/MathAlgorithms.h"
11 #include "mozilla/MemoryReporting.h"
12 #include "gfxDWriteCommon.h"
13 #include "dwrite_3.h"
15 #include "gfxFont.h"
16 #include "gfxUserFontSet.h"
17 #include "cairo-win32.h"
19 #include "gfxPlatformFontList.h"
20 #include "gfxPlatform.h"
21 #include <algorithm>
23 #include "mozilla/gfx/UnscaledFontDWrite.h"
25 /**
26 * \brief Class representing directwrite font family.
28 * gfxDWriteFontFamily is a class that describes one of the font families on
29 * the user's system. It holds each gfxDWriteFontEntry (maps more directly to
30 * a font face) which holds font type, charset info and character map info.
32 class gfxDWriteFontFamily final : public gfxFontFamily {
33 public:
34 typedef mozilla::FontStretch FontStretch;
35 typedef mozilla::FontSlantStyle FontSlantStyle;
36 typedef mozilla::FontWeight FontWeight;
38 /**
39 * Constructs a new DWriteFont Family.
41 * \param aName Name identifying the family
42 * \param aFamily IDWriteFontFamily object representing the directwrite
43 * family object.
45 gfxDWriteFontFamily(const nsACString& aName, FontVisibility aVisibility,
46 IDWriteFontFamily* aFamily,
47 bool aIsSystemFontFamily = false)
48 : gfxFontFamily(aName, aVisibility),
49 mDWFamily(aFamily),
50 mIsSystemFontFamily(aIsSystemFontFamily),
51 mForceGDIClassic(false) {}
52 virtual ~gfxDWriteFontFamily();
54 void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
55 MOZ_REQUIRES(mLock) final;
57 void LocalizedName(nsACString& aLocalizedName) final;
59 void ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
60 bool aNeedFullnamePostscriptNames,
61 FontInfoData* aFontInfoData = nullptr) final;
63 void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
65 void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
66 FontListSizes* aSizes) const final;
67 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
68 FontListSizes* aSizes) const final;
70 bool FilterForFontList(nsAtom* aLangGroup,
71 const nsACString& aGeneric) const final {
72 return !IsSymbolFontFamily();
75 protected:
76 // helper for FilterForFontList
77 bool IsSymbolFontFamily() const;
79 /** This font family's directwrite fontfamily object */
80 RefPtr<IDWriteFontFamily> mDWFamily;
81 bool mIsSystemFontFamily;
82 bool mForceGDIClassic;
85 /**
86 * \brief Class representing DirectWrite FontEntry (a unique font style/family)
88 class gfxDWriteFontEntry final : public gfxFontEntry {
89 public:
90 /**
91 * Constructs a font entry.
93 * \param aFaceName The name of the corresponding font face.
94 * \param aFont DirectWrite font object
96 gfxDWriteFontEntry(const nsACString& aFaceName, IDWriteFont* aFont,
97 bool aIsSystemFont = false)
98 : gfxFontEntry(aFaceName),
99 mFont(aFont),
100 mFontFile(nullptr),
101 mIsSystemFont(aIsSystemFont),
102 mForceGDIClassic(false),
103 mHasVariations(false),
104 mHasVariationsInitialized(false) {
105 DWRITE_FONT_STYLE dwriteStyle = aFont->GetStyle();
106 FontSlantStyle style = (dwriteStyle == DWRITE_FONT_STYLE_ITALIC
107 ? FontSlantStyle::ITALIC
108 : (dwriteStyle == DWRITE_FONT_STYLE_OBLIQUE
109 ? FontSlantStyle::OBLIQUE
110 : FontSlantStyle::NORMAL));
111 mStyleRange = SlantStyleRange(style);
113 mStretchRange =
114 StretchRange(FontStretchFromDWriteStretch(aFont->GetStretch()));
116 int weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
117 weight = mozilla::Clamp(weight, 100, 900);
118 mWeightRange = WeightRange(FontWeight::FromInt(weight));
120 mIsCJK = UNINITIALIZED_VALUE;
124 * Constructs a font entry using a font. But with custom font values.
125 * This is used for creating correct font entries for @font-face with local
126 * font source.
128 * \param aFaceName The name of the corresponding font face.
129 * \param aFont DirectWrite font object
130 * \param aWeight Weight of the font
131 * \param aStretch Stretch of the font
132 * \param aStyle italic or oblique of font
134 gfxDWriteFontEntry(const nsACString& aFaceName, IDWriteFont* aFont,
135 WeightRange aWeight, StretchRange aStretch,
136 SlantStyleRange aStyle)
137 : gfxFontEntry(aFaceName),
138 mFont(aFont),
139 mFontFile(nullptr),
140 mIsSystemFont(false),
141 mForceGDIClassic(false),
142 mHasVariations(false),
143 mHasVariationsInitialized(false) {
144 mWeightRange = aWeight;
145 mStretchRange = aStretch;
146 mStyleRange = aStyle;
147 mIsLocalUserFont = true;
148 mIsCJK = UNINITIALIZED_VALUE;
152 * Constructs a font entry using a font file.
154 * \param aFaceName The name of the corresponding font face.
155 * \param aFontFile DirectWrite fontfile object
156 * \param aFontFileStream DirectWrite fontfile stream object
157 * \param aWeight Weight of the font
158 * \param aStretch Stretch of the font
159 * \param aStyle italic or oblique of font
161 gfxDWriteFontEntry(const nsACString& aFaceName, IDWriteFontFile* aFontFile,
162 IDWriteFontFileStream* aFontFileStream,
163 WeightRange aWeight, StretchRange aStretch,
164 SlantStyleRange aStyle)
165 : gfxFontEntry(aFaceName),
166 mFont(nullptr),
167 mFontFile(aFontFile),
168 mFontFileStream(aFontFileStream),
169 mIsSystemFont(false),
170 mForceGDIClassic(false),
171 mHasVariations(false),
172 mHasVariationsInitialized(false) {
173 mWeightRange = aWeight;
174 mStretchRange = aStretch;
175 mStyleRange = aStyle;
176 mIsDataUserFont = true;
177 mIsCJK = UNINITIALIZED_VALUE;
180 gfxFontEntry* Clone() const override;
182 virtual ~gfxDWriteFontEntry();
184 hb_blob_t* GetFontTable(uint32_t aTableTag) override;
186 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
188 bool IsCJKFont();
190 bool HasVariations() override;
191 void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes) override;
192 void GetVariationInstances(
193 nsTArray<gfxFontVariationInstance>& aInstances) override;
195 void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
196 bool GetForceGDIClassic() { return mForceGDIClassic; }
198 void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
199 FontListSizes* aSizes) const override;
200 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
201 FontListSizes* aSizes) const override;
203 protected:
204 friend class gfxDWriteFont;
205 friend class gfxDWriteFontList;
206 friend class gfxDWriteFontFamily;
208 virtual nsresult CopyFontTable(uint32_t aTableTag,
209 nsTArray<uint8_t>& aBuffer) override;
211 virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle);
213 nsresult CreateFontFace(
214 IDWriteFontFace** aFontFace, const gfxFontStyle* aFontStyle = nullptr,
215 DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE,
216 const nsTArray<gfxFontVariation>* aVariations = nullptr);
218 static bool InitLogFont(IDWriteFont* aFont, LOGFONTW* aLogFont);
221 * A fontentry only needs to have either of these. If it has both only
222 * the IDWriteFont will be used.
224 RefPtr<IDWriteFont> mFont;
225 RefPtr<IDWriteFontFile> mFontFile;
227 // For custom fonts, we hold a reference to the IDWriteFontFileStream for
228 // for the IDWriteFontFile, so that the data is available.
229 RefPtr<IDWriteFontFileStream> mFontFileStream;
231 // font face corresponding to the mFont/mFontFile *without* any DWrite
232 // style simulations applied
233 RefPtr<IDWriteFontFace> mFontFace;
234 // Extended fontface interface if supported, else null
235 RefPtr<IDWriteFontFace5> mFontFace5;
237 DWRITE_FONT_FACE_TYPE mFaceType;
239 int8_t mIsCJK;
240 bool mIsSystemFont;
241 bool mForceGDIClassic;
242 bool mHasVariations;
243 bool mHasVariationsInitialized;
245 // Set to true only if the font belongs to a "simple" family where the
246 // faces can be reliably identified via a GDI LOGFONT structure.
247 bool mMayUseGDIAccess = false;
249 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFont;
250 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite>
251 mUnscaledFontBold;
254 // custom text renderer used to determine the fallback font for a given char
255 class DWriteFontFallbackRenderer final : public IDWriteTextRenderer {
256 public:
257 explicit DWriteFontFallbackRenderer(IDWriteFactory* aFactory) : mRefCount(0) {
258 HRESULT hr =
259 aFactory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
260 NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
261 (void)hr;
264 ~DWriteFontFallbackRenderer() {}
266 // If we don't have an mSystemFonts pointer, this renderer is unusable.
267 bool IsValid() const { return mSystemFonts; }
269 // IDWriteTextRenderer methods
270 IFACEMETHOD(DrawGlyphRun)
271 (void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY,
272 DWRITE_MEASURING_MODE measuringMode, DWRITE_GLYPH_RUN const* glyphRun,
273 DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
274 IUnknown* clientDrawingEffect);
276 IFACEMETHOD(DrawUnderline)
277 (void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY,
278 DWRITE_UNDERLINE const* underline, IUnknown* clientDrawingEffect) {
279 return E_NOTIMPL;
282 IFACEMETHOD(DrawStrikethrough)
283 (void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY,
284 DWRITE_STRIKETHROUGH const* strikethrough, IUnknown* clientDrawingEffect) {
285 return E_NOTIMPL;
288 IFACEMETHOD(DrawInlineObject)
289 (void* clientDrawingContext, FLOAT originX, FLOAT originY,
290 IDWriteInlineObject* inlineObject, BOOL isSideways, BOOL isRightToLeft,
291 IUnknown* clientDrawingEffect) {
292 return E_NOTIMPL;
295 // IDWritePixelSnapping methods
297 IFACEMETHOD(IsPixelSnappingDisabled)
298 (void* clientDrawingContext, BOOL* isDisabled) {
299 *isDisabled = FALSE;
300 return S_OK;
303 IFACEMETHOD(GetCurrentTransform)
304 (void* clientDrawingContext, DWRITE_MATRIX* transform) {
305 const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
306 *transform = ident;
307 return S_OK;
310 IFACEMETHOD(GetPixelsPerDip)
311 (void* clientDrawingContext, FLOAT* pixelsPerDip) {
312 *pixelsPerDip = 1.0f;
313 return S_OK;
316 // IUnknown methods
318 IFACEMETHOD_(unsigned long, AddRef)() {
319 return InterlockedIncrement(&mRefCount);
322 IFACEMETHOD_(unsigned long, Release)() {
323 unsigned long newCount = InterlockedDecrement(&mRefCount);
324 if (newCount == 0) {
325 delete this;
326 return 0;
329 return newCount;
332 IFACEMETHOD(QueryInterface)(IID const& riid, void** ppvObject) {
333 if (__uuidof(IDWriteTextRenderer) == riid) {
334 *ppvObject = this;
335 } else if (__uuidof(IDWritePixelSnapping) == riid) {
336 *ppvObject = this;
337 } else if (__uuidof(IUnknown) == riid) {
338 *ppvObject = this;
339 } else {
340 *ppvObject = nullptr;
341 return E_FAIL;
344 this->AddRef();
345 return S_OK;
348 const nsCString& FallbackFamilyName() { return mFamilyName; }
350 protected:
351 long mRefCount;
352 RefPtr<IDWriteFontCollection> mSystemFonts;
353 nsCString mFamilyName;
356 class gfxDWriteFontList final : public gfxPlatformFontList {
357 public:
358 gfxDWriteFontList();
359 virtual ~gfxDWriteFontList() { AutoLock lock(mLock); }
361 static gfxDWriteFontList* PlatformFontList() {
362 return static_cast<gfxDWriteFontList*>(
363 gfxPlatformFontList::PlatformFontList());
366 // initialize font lists
367 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override;
368 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override;
370 FontVisibility GetVisibilityForFamily(const nsACString& aName) const;
372 gfxFontFamily* CreateFontFamily(const nsACString& aName,
373 FontVisibility aVisibility) const override;
375 gfxFontEntry* CreateFontEntry(
376 mozilla::fontlist::Face* aFace,
377 const mozilla::fontlist::Family* aFamily) override;
379 void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
380 bool aNeedFullnamePostscriptNames)
381 MOZ_REQUIRES(mLock) override;
383 bool ReadFaceNames(const mozilla::fontlist::Family* aFamily,
384 const mozilla::fontlist::Face* aFace, nsCString& aPSName,
385 nsCString& aFullName) override;
387 void GetFacesInitDataForFamily(
388 const mozilla::fontlist::Family* aFamily,
389 nsTArray<mozilla::fontlist::Face::InitData>& aFaces,
390 bool aLoadCmaps) const override;
392 gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
393 const nsACString& aFontName,
394 WeightRange aWeightForEntry,
395 StretchRange aStretchForEntry,
396 SlantStyleRange aStyleForEntry) override;
398 gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
399 WeightRange aWeightForEntry,
400 StretchRange aStretchForEntry,
401 SlantStyleRange aStyleForEntry,
402 const uint8_t* aFontData,
403 uint32_t aLength) override;
405 IDWriteGdiInterop* GetGDIInterop() { return mGDIInterop; }
406 bool UseGDIFontTableAccess() const;
408 bool FindAndAddFamiliesLocked(
409 nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
410 const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
411 FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
412 nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
413 MOZ_REQUIRES(mLock) override;
415 gfxFloat GetForceGDIClassicMaxFontSize() {
416 return mForceGDIClassicMaxFontSize;
419 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
420 FontListSizes* aSizes) const;
421 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
422 FontListSizes* aSizes) const;
424 protected:
425 FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
426 const gfxFontStyle* aStyle,
427 nsAtom* aLanguage = nullptr)
428 MOZ_REQUIRES(mLock) override;
430 // attempt to use platform-specific fallback for the given character,
431 // return null if no usable result found
432 gfxFontEntry* PlatformGlobalFontFallback(nsPresContext* aPresContext,
433 const uint32_t aCh,
434 Script aRunScript,
435 const gfxFontStyle* aMatchStyle,
436 FontFamily& aMatchedFamily)
437 MOZ_REQUIRES(mLock) override;
439 nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists()
440 override;
442 private:
443 friend class gfxDWriteFontFamily;
445 nsresult GetFontSubstitutes() MOZ_REQUIRES(mLock);
447 void GetDirectWriteSubstitutes() MOZ_REQUIRES(mLock);
449 virtual bool UsesSystemFallback() { return true; }
451 void GetFontsFromCollection(IDWriteFontCollection* aCollection)
452 MOZ_REQUIRES(mLock);
454 void AppendFamiliesFromCollection(
455 IDWriteFontCollection* aCollection,
456 nsTArray<mozilla::fontlist::Family::InitData>& aFamilies,
457 const nsTArray<nsCString>* aForceClassicFams = nullptr)
458 MOZ_REQUIRES(mLock);
460 #ifdef MOZ_BUNDLED_FONTS
461 already_AddRefed<IDWriteFontCollection> CreateBundledFontsCollection(
462 IDWriteFactory* aFactory);
463 #endif
466 * Fonts listed in the registry as substitutes but for which no actual
467 * font family is found.
469 nsTArray<nsCString> mNonExistingFonts;
472 * Table of font substitutes, we grab this from the registry to get
473 * alternative font names.
475 FontFamilyTable mFontSubstitutes;
476 nsClassHashtable<nsCStringHashKey, nsCString> mSubstitutions;
478 virtual already_AddRefed<FontInfoData> CreateFontInfoData();
480 gfxFloat mForceGDIClassicMaxFontSize;
482 // whether to use GDI font table access routines
483 bool mGDIFontTableAccess;
484 RefPtr<IDWriteGdiInterop> mGDIInterop;
486 RefPtr<DWriteFontFallbackRenderer> mFallbackRenderer;
487 RefPtr<IDWriteTextFormat> mFallbackFormat;
489 RefPtr<IDWriteFontCollection> mSystemFonts;
490 #ifdef MOZ_BUNDLED_FONTS
491 RefPtr<IDWriteFontCollection> mBundledFonts;
492 #endif
495 #endif /* GFX_DWRITEFONTLIST_H */