Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / thebes / gfxGDIFontList.h
blob7fc7f7521b355e356859e349eab37b217dd86c42
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_GDIFONTLIST_H
7 #define GFX_GDIFONTLIST_H
9 #include "mozilla/FontPropertyTypes.h"
10 #include "mozilla/MemoryReporting.h"
11 #include "gfxWindowsPlatform.h"
12 #include "gfxPlatformFontList.h"
13 #include "nsGkAtoms.h"
14 #include "mozilla/gfx/UnscaledFontGDI.h"
16 #include <windows.h>
18 class AutoDC // get the global device context, and auto-release it on
19 // destruction
21 public:
22 AutoDC() { mDC = ::GetDC(nullptr); }
24 ~AutoDC() { ::ReleaseDC(nullptr, mDC); }
26 HDC GetDC() { return mDC; }
28 private:
29 HDC mDC;
32 class AutoSelectFont // select a font into the given DC, and auto-restore
34 public:
35 AutoSelectFont(HDC aDC, LOGFONTW* aLogFont) : mOwnsFont(false) {
36 mFont = ::CreateFontIndirectW(aLogFont);
37 if (mFont) {
38 mOwnsFont = true;
39 mDC = aDC;
40 mOldFont = (HFONT)::SelectObject(aDC, mFont);
41 } else {
42 mOldFont = nullptr;
46 AutoSelectFont(HDC aDC, HFONT aFont) : mOwnsFont(false) {
47 mDC = aDC;
48 mFont = aFont;
49 mOldFont = (HFONT)::SelectObject(aDC, aFont);
52 ~AutoSelectFont() {
53 if (mOldFont) {
54 ::SelectObject(mDC, mOldFont);
55 if (mOwnsFont) {
56 ::DeleteObject(mFont);
61 bool IsValid() const { return mFont != nullptr; }
63 HFONT GetFont() const { return mFont; }
65 private:
66 HDC mDC;
67 HFONT mFont;
68 HFONT mOldFont;
69 bool mOwnsFont;
72 /**
73 * List of different types of fonts we support on Windows.
74 * These can generally be lumped in to 3 categories where we have to
75 * do special things: Really old fonts bitmap and vector fonts (device
76 * and raster), Type 1 fonts, and TrueType/OpenType fonts.
78 * This list is sorted in order from least prefered to most prefered.
79 * We prefer Type1 fonts over OpenType fonts to avoid falling back to
80 * things like Arial (opentype) when you ask for Helvetica (type1)
81 **/
82 enum gfxWindowsFontType {
83 GFX_FONT_TYPE_UNKNOWN = 0,
84 GFX_FONT_TYPE_DEVICE,
85 GFX_FONT_TYPE_RASTER,
86 GFX_FONT_TYPE_TRUETYPE,
87 GFX_FONT_TYPE_PS_OPENTYPE,
88 GFX_FONT_TYPE_TT_OPENTYPE,
89 GFX_FONT_TYPE_TYPE1
92 // A single member of a font family (i.e. a single face, such as Times Italic)
93 // represented as a LOGFONT that will resolve to the correct face.
94 // This replaces FontEntry from gfxWindowsFonts.h/cpp.
95 class GDIFontEntry final : public gfxFontEntry {
96 public:
97 LPLOGFONTW GetLogFont() { return &mLogFont; }
99 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
101 void FillLogFont(LOGFONTW* aLogFont, LONG aWeight, gfxFloat aSize);
103 static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics,
104 DWORD fontType) {
105 gfxWindowsFontType feType;
106 if (metrics.ntmFlags & NTM_TYPE1)
107 feType = GFX_FONT_TYPE_TYPE1;
108 else if (metrics.ntmFlags & NTM_PS_OPENTYPE)
109 feType = GFX_FONT_TYPE_PS_OPENTYPE;
110 else if (metrics.ntmFlags & NTM_TT_OPENTYPE)
111 feType = GFX_FONT_TYPE_TT_OPENTYPE;
112 else if (fontType == TRUETYPE_FONTTYPE)
113 feType = GFX_FONT_TYPE_TRUETYPE;
114 else if (fontType == RASTER_FONTTYPE)
115 feType = GFX_FONT_TYPE_RASTER;
116 else if (fontType == DEVICE_FONTTYPE)
117 feType = GFX_FONT_TYPE_DEVICE;
118 else
119 feType = GFX_FONT_TYPE_UNKNOWN;
121 return feType;
124 bool IsType1() const { return (mFontType == GFX_FONT_TYPE_TYPE1); }
126 bool IsTrueType() const {
127 return (mFontType == GFX_FONT_TYPE_TRUETYPE ||
128 mFontType == GFX_FONT_TYPE_PS_OPENTYPE ||
129 mFontType == GFX_FONT_TYPE_TT_OPENTYPE);
132 bool SkipDuringSystemFallback() override {
133 return !HasCmapTable(); // explicitly skip non-SFNT fonts
136 bool TestCharacterMap(uint32_t aCh) override;
138 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
139 FontListSizes* aSizes) const override;
141 gfxFontEntry* Clone() const override;
143 // GDI backend doesn't support font variations:
144 bool HasVariations() override { return false; }
145 void GetVariationAxes(nsTArray<gfxFontVariationAxis>&) override {}
146 void GetVariationInstances(nsTArray<gfxFontVariationInstance>&) override {}
148 // create a font entry for a font with a given name
149 static GDIFontEntry* CreateFontEntry(const nsACString& aName,
150 gfxWindowsFontType aFontType,
151 SlantStyleRange aStyle,
152 WeightRange aWeight,
153 StretchRange aStretch,
154 gfxUserFontData* aUserFontData);
156 gfxWindowsFontType mFontType;
157 bool mForceGDI;
159 protected:
160 friend class gfxGDIFont;
162 GDIFontEntry(const nsACString& aFaceName, gfxWindowsFontType aFontType,
163 SlantStyleRange aStyle, WeightRange aWeight,
164 StretchRange aStretch, gfxUserFontData* aUserFontData);
166 void InitLogFont(const nsACString& aName, gfxWindowsFontType aFontType);
168 gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
170 virtual nsresult CopyFontTable(uint32_t aTableTag,
171 nsTArray<uint8_t>& aBuffer) override;
173 already_AddRefed<mozilla::gfx::UnscaledFontGDI> LookupUnscaledFont(
174 HFONT aFont);
176 LOGFONTW mLogFont;
178 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontGDI> mUnscaledFont;
181 // a single font family, referencing one or more faces
182 class GDIFontFamily final : public gfxFontFamily {
183 public:
184 GDIFontFamily(const nsACString& aName, FontVisibility aVisibility)
185 : gfxFontFamily(aName, aVisibility),
186 mWindowsFamily(0),
187 mWindowsPitch(0),
188 mCharset() {}
190 void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
191 MOZ_REQUIRES(mLock) override;
193 bool FilterForFontList(nsAtom* aLangGroup,
194 const nsACString& aGeneric) const final {
195 return !IsSymbolFontFamily() && SupportsLangGroup(aLangGroup) &&
196 MatchesGenericFamily(aGeneric);
199 protected:
200 friend class gfxGDIFontList;
202 // helpers for FilterForFontList
203 bool IsSymbolFontFamily() const { return mCharset.test(SYMBOL_CHARSET); }
205 bool MatchesGenericFamily(const nsACString& aGeneric) const {
206 if (aGeneric.IsEmpty()) {
207 return true;
210 // Japanese 'Mincho' fonts do not belong to FF_MODERN even if
211 // they are fixed pitch because they have variable stroke width.
212 if (mWindowsFamily == FF_ROMAN && mWindowsPitch & FIXED_PITCH) {
213 return aGeneric.EqualsLiteral("monospace");
216 // Japanese 'Gothic' fonts do not belong to FF_SWISS even if
217 // they are variable pitch because they have constant stroke width.
218 if (mWindowsFamily == FF_MODERN && mWindowsPitch & VARIABLE_PITCH) {
219 return aGeneric.EqualsLiteral("sans-serif");
222 // All other fonts will be grouped correctly using family...
223 switch (mWindowsFamily) {
224 case FF_DONTCARE:
225 return false;
226 case FF_ROMAN:
227 return aGeneric.EqualsLiteral("serif");
228 case FF_SWISS:
229 return aGeneric.EqualsLiteral("sans-serif");
230 case FF_MODERN:
231 return aGeneric.EqualsLiteral("monospace");
232 case FF_SCRIPT:
233 return aGeneric.EqualsLiteral("cursive");
234 case FF_DECORATIVE:
235 return aGeneric.EqualsLiteral("fantasy");
238 return false;
241 bool SupportsLangGroup(nsAtom* aLangGroup) const {
242 if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
243 return true;
246 int16_t bit = -1;
248 /* map our langgroup names in to Windows charset bits */
249 if (aLangGroup == nsGkAtoms::x_western) {
250 bit = ANSI_CHARSET;
251 } else if (aLangGroup == nsGkAtoms::Japanese) {
252 bit = SHIFTJIS_CHARSET;
253 } else if (aLangGroup == nsGkAtoms::ko) {
254 bit = HANGEUL_CHARSET;
255 } else if (aLangGroup == nsGkAtoms::zh_cn) {
256 bit = GB2312_CHARSET;
257 } else if (aLangGroup == nsGkAtoms::zh_tw) {
258 bit = CHINESEBIG5_CHARSET;
259 } else if (aLangGroup == nsGkAtoms::el) {
260 bit = GREEK_CHARSET;
261 } else if (aLangGroup == nsGkAtoms::he) {
262 bit = HEBREW_CHARSET;
263 } else if (aLangGroup == nsGkAtoms::ar) {
264 bit = ARABIC_CHARSET;
265 } else if (aLangGroup == nsGkAtoms::x_cyrillic) {
266 bit = RUSSIAN_CHARSET;
267 } else if (aLangGroup == nsGkAtoms::th) {
268 bit = THAI_CHARSET;
271 if (bit != -1) {
272 return mCharset.test(bit);
275 return false;
278 uint8_t mWindowsFamily;
279 uint8_t mWindowsPitch;
281 gfxSparseBitSet mCharset;
283 private:
284 static int CALLBACK FamilyAddStylesProc(const ENUMLOGFONTEXW* lpelfe,
285 const NEWTEXTMETRICEXW* nmetrics,
286 DWORD fontType, LPARAM data);
289 class gfxGDIFontList final : public gfxPlatformFontList {
290 public:
291 static gfxGDIFontList* PlatformFontList() {
292 return static_cast<gfxGDIFontList*>(
293 gfxPlatformFontList::PlatformFontList());
296 virtual ~gfxGDIFontList() { AutoLock lock(mLock); }
298 // initialize font lists
299 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override;
301 gfxFontFamily* CreateFontFamily(const nsACString& aName,
302 FontVisibility aVisibility) const override;
304 bool FindAndAddFamiliesLocked(
305 nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
306 const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
307 FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
308 nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
309 MOZ_REQUIRES(mLock) override;
311 gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
312 const nsACString& aFontName,
313 WeightRange aWeightForEntry,
314 StretchRange aStretchForEntry,
315 SlantStyleRange aStyleForEntry) override;
317 gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
318 WeightRange aWeightForEntry,
319 StretchRange aStretchForEntry,
320 SlantStyleRange aStyleForEntry,
321 const uint8_t* aFontData,
322 uint32_t aLength) override;
324 void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
325 FontListSizes* aSizes) const override;
326 void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
327 FontListSizes* aSizes) const override;
329 protected:
330 FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
331 const gfxFontStyle* aStyle,
332 nsAtom* aLanguage = nullptr)
333 MOZ_REQUIRES(mLock) override;
335 nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists()
336 override;
338 private:
339 friend class gfxWindowsPlatform;
341 gfxGDIFontList();
343 nsresult GetFontSubstitutes() MOZ_REQUIRES(mLock);
345 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* lpelfe,
346 NEWTEXTMETRICEXW* lpntme,
347 DWORD fontType, LPARAM lParam);
349 already_AddRefed<FontInfoData> CreateFontInfoData() override;
351 #ifdef MOZ_BUNDLED_FONTS
352 void ActivateBundledFonts();
353 #endif
355 FontFamilyTable mFontSubstitutes;
356 nsTArray<nsCString> mNonExistingFonts;
359 #endif /* GFX_GDIFONTLIST_H */