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"
18 class AutoDC
// get the global device context, and auto-release it on
22 AutoDC() { mDC
= ::GetDC(nullptr); }
24 ~AutoDC() { ::ReleaseDC(nullptr, mDC
); }
26 HDC
GetDC() { return mDC
; }
32 class AutoSelectFont
// select a font into the given DC, and auto-restore
35 AutoSelectFont(HDC aDC
, LOGFONTW
* aLogFont
) : mOwnsFont(false) {
36 mFont
= ::CreateFontIndirectW(aLogFont
);
40 mOldFont
= (HFONT
)::SelectObject(aDC
, mFont
);
46 AutoSelectFont(HDC aDC
, HFONT aFont
) : mOwnsFont(false) {
49 mOldFont
= (HFONT
)::SelectObject(aDC
, aFont
);
54 ::SelectObject(mDC
, mOldFont
);
56 ::DeleteObject(mFont
);
61 bool IsValid() const { return mFont
!= nullptr; }
63 HFONT
GetFont() const { return mFont
; }
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)
82 enum gfxWindowsFontType
{
83 GFX_FONT_TYPE_UNKNOWN
= 0,
86 GFX_FONT_TYPE_TRUETYPE
,
87 GFX_FONT_TYPE_PS_OPENTYPE
,
88 GFX_FONT_TYPE_TT_OPENTYPE
,
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
{
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
,
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
;
119 feType
= GFX_FONT_TYPE_UNKNOWN
;
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
,
153 StretchRange aStretch
,
154 gfxUserFontData
* aUserFontData
);
156 gfxWindowsFontType mFontType
;
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(
178 mozilla::ThreadSafeWeakPtr
<mozilla::gfx::UnscaledFontGDI
> mUnscaledFont
;
181 // a single font family, referencing one or more faces
182 class GDIFontFamily final
: public gfxFontFamily
{
184 GDIFontFamily(const nsACString
& aName
, FontVisibility aVisibility
)
185 : gfxFontFamily(aName
, aVisibility
),
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
);
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()) {
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
) {
227 return aGeneric
.EqualsLiteral("serif");
229 return aGeneric
.EqualsLiteral("sans-serif");
231 return aGeneric
.EqualsLiteral("monospace");
233 return aGeneric
.EqualsLiteral("cursive");
235 return aGeneric
.EqualsLiteral("fantasy");
241 bool SupportsLangGroup(nsAtom
* aLangGroup
) const {
242 if (!aLangGroup
|| aLangGroup
== nsGkAtoms::Unicode
) {
248 /* map our langgroup names in to Windows charset bits */
249 if (aLangGroup
== nsGkAtoms::x_western
) {
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
) {
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
) {
272 return mCharset
.test(bit
);
278 uint8_t mWindowsFamily
;
279 uint8_t mWindowsPitch
;
281 gfxSparseBitSet mCharset
;
284 static int CALLBACK
FamilyAddStylesProc(const ENUMLOGFONTEXW
* lpelfe
,
285 const NEWTEXTMETRICEXW
* nmetrics
,
286 DWORD fontType
, LPARAM data
);
289 class gfxGDIFontList final
: public gfxPlatformFontList
{
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
;
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()
339 friend class gfxWindowsPlatform
;
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();
355 FontFamilyTable mFontSubstitutes
;
356 nsTArray
<nsCString
> mNonExistingFonts
;
359 #endif /* GFX_GDIFONTLIST_H */