gfx/thebes/gfxGDIFontList.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef GFX_GDIFONTLIST_H
michael@0 7 #define GFX_GDIFONTLIST_H
michael@0 8
michael@0 9 #include "mozilla/MemoryReporting.h"
michael@0 10 #include "gfxWindowsPlatform.h"
michael@0 11 #include "gfxPlatformFontList.h"
michael@0 12 #include "nsGkAtoms.h"
michael@0 13
michael@0 14 #include <windows.h>
michael@0 15
michael@0 16 class AutoDC // get the global device context, and auto-release it on destruction
michael@0 17 {
michael@0 18 public:
michael@0 19 AutoDC() {
michael@0 20 mDC = ::GetDC(nullptr);
michael@0 21 }
michael@0 22
michael@0 23 ~AutoDC() {
michael@0 24 ::ReleaseDC(nullptr, mDC);
michael@0 25 }
michael@0 26
michael@0 27 HDC GetDC() {
michael@0 28 return mDC;
michael@0 29 }
michael@0 30
michael@0 31 private:
michael@0 32 HDC mDC;
michael@0 33 };
michael@0 34
michael@0 35 class AutoSelectFont // select a font into the given DC, and auto-restore
michael@0 36 {
michael@0 37 public:
michael@0 38 AutoSelectFont(HDC aDC, LOGFONTW *aLogFont)
michael@0 39 : mOwnsFont(false)
michael@0 40 {
michael@0 41 mFont = ::CreateFontIndirectW(aLogFont);
michael@0 42 if (mFont) {
michael@0 43 mOwnsFont = true;
michael@0 44 mDC = aDC;
michael@0 45 mOldFont = (HFONT)::SelectObject(aDC, mFont);
michael@0 46 } else {
michael@0 47 mOldFont = nullptr;
michael@0 48 }
michael@0 49 }
michael@0 50
michael@0 51 AutoSelectFont(HDC aDC, HFONT aFont)
michael@0 52 : mOwnsFont(false)
michael@0 53 {
michael@0 54 mDC = aDC;
michael@0 55 mFont = aFont;
michael@0 56 mOldFont = (HFONT)::SelectObject(aDC, aFont);
michael@0 57 }
michael@0 58
michael@0 59 ~AutoSelectFont() {
michael@0 60 if (mOldFont) {
michael@0 61 ::SelectObject(mDC, mOldFont);
michael@0 62 if (mOwnsFont) {
michael@0 63 ::DeleteObject(mFont);
michael@0 64 }
michael@0 65 }
michael@0 66 }
michael@0 67
michael@0 68 bool IsValid() const {
michael@0 69 return mFont != nullptr;
michael@0 70 }
michael@0 71
michael@0 72 HFONT GetFont() const {
michael@0 73 return mFont;
michael@0 74 }
michael@0 75
michael@0 76 private:
michael@0 77 HDC mDC;
michael@0 78 HFONT mFont;
michael@0 79 HFONT mOldFont;
michael@0 80 bool mOwnsFont;
michael@0 81 };
michael@0 82
michael@0 83 /**
michael@0 84 * List of different types of fonts we support on Windows.
michael@0 85 * These can generally be lumped in to 3 categories where we have to
michael@0 86 * do special things: Really old fonts bitmap and vector fonts (device
michael@0 87 * and raster), Type 1 fonts, and TrueType/OpenType fonts.
michael@0 88 *
michael@0 89 * This list is sorted in order from least prefered to most prefered.
michael@0 90 * We prefer Type1 fonts over OpenType fonts to avoid falling back to
michael@0 91 * things like Arial (opentype) when you ask for Helvetica (type1)
michael@0 92 **/
michael@0 93 enum gfxWindowsFontType {
michael@0 94 GFX_FONT_TYPE_UNKNOWN = 0,
michael@0 95 GFX_FONT_TYPE_DEVICE,
michael@0 96 GFX_FONT_TYPE_RASTER,
michael@0 97 GFX_FONT_TYPE_TRUETYPE,
michael@0 98 GFX_FONT_TYPE_PS_OPENTYPE,
michael@0 99 GFX_FONT_TYPE_TT_OPENTYPE,
michael@0 100 GFX_FONT_TYPE_TYPE1
michael@0 101 };
michael@0 102
michael@0 103 // A single member of a font family (i.e. a single face, such as Times Italic)
michael@0 104 // represented as a LOGFONT that will resolve to the correct face.
michael@0 105 // This replaces FontEntry from gfxWindowsFonts.h/cpp.
michael@0 106 class GDIFontEntry : public gfxFontEntry
michael@0 107 {
michael@0 108 public:
michael@0 109 LPLOGFONTW GetLogFont() { return &mLogFont; }
michael@0 110
michael@0 111 nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr);
michael@0 112
michael@0 113 virtual bool IsSymbolFont();
michael@0 114
michael@0 115 void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize,
michael@0 116 bool aUseCleartype);
michael@0 117
michael@0 118 static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics,
michael@0 119 DWORD fontType)
michael@0 120 {
michael@0 121 gfxWindowsFontType feType;
michael@0 122 if (metrics.ntmFlags & NTM_TYPE1)
michael@0 123 feType = GFX_FONT_TYPE_TYPE1;
michael@0 124 else if (metrics.ntmFlags & NTM_PS_OPENTYPE)
michael@0 125 feType = GFX_FONT_TYPE_PS_OPENTYPE;
michael@0 126 else if (metrics.ntmFlags & NTM_TT_OPENTYPE)
michael@0 127 feType = GFX_FONT_TYPE_TT_OPENTYPE;
michael@0 128 else if (fontType == TRUETYPE_FONTTYPE)
michael@0 129 feType = GFX_FONT_TYPE_TRUETYPE;
michael@0 130 else if (fontType == RASTER_FONTTYPE)
michael@0 131 feType = GFX_FONT_TYPE_RASTER;
michael@0 132 else if (fontType == DEVICE_FONTTYPE)
michael@0 133 feType = GFX_FONT_TYPE_DEVICE;
michael@0 134 else
michael@0 135 feType = GFX_FONT_TYPE_UNKNOWN;
michael@0 136
michael@0 137 return feType;
michael@0 138 }
michael@0 139
michael@0 140 bool IsType1() const {
michael@0 141 return (mFontType == GFX_FONT_TYPE_TYPE1);
michael@0 142 }
michael@0 143
michael@0 144 bool IsTrueType() const {
michael@0 145 return (mFontType == GFX_FONT_TYPE_TRUETYPE ||
michael@0 146 mFontType == GFX_FONT_TYPE_PS_OPENTYPE ||
michael@0 147 mFontType == GFX_FONT_TYPE_TT_OPENTYPE);
michael@0 148 }
michael@0 149
michael@0 150 virtual bool MatchesGenericFamily(const nsACString& aGeneric) const {
michael@0 151 if (aGeneric.IsEmpty()) {
michael@0 152 return true;
michael@0 153 }
michael@0 154
michael@0 155 // Japanese 'Mincho' fonts do not belong to FF_MODERN even if
michael@0 156 // they are fixed pitch because they have variable stroke width.
michael@0 157 if (mWindowsFamily == FF_ROMAN && mWindowsPitch & FIXED_PITCH) {
michael@0 158 return aGeneric.EqualsLiteral("monospace");
michael@0 159 }
michael@0 160
michael@0 161 // Japanese 'Gothic' fonts do not belong to FF_SWISS even if
michael@0 162 // they are variable pitch because they have constant stroke width.
michael@0 163 if (mWindowsFamily == FF_MODERN && mWindowsPitch & VARIABLE_PITCH) {
michael@0 164 return aGeneric.EqualsLiteral("sans-serif");
michael@0 165 }
michael@0 166
michael@0 167 // All other fonts will be grouped correctly using family...
michael@0 168 switch (mWindowsFamily) {
michael@0 169 case FF_DONTCARE:
michael@0 170 return false;
michael@0 171 case FF_ROMAN:
michael@0 172 return aGeneric.EqualsLiteral("serif");
michael@0 173 case FF_SWISS:
michael@0 174 return aGeneric.EqualsLiteral("sans-serif");
michael@0 175 case FF_MODERN:
michael@0 176 return aGeneric.EqualsLiteral("monospace");
michael@0 177 case FF_SCRIPT:
michael@0 178 return aGeneric.EqualsLiteral("cursive");
michael@0 179 case FF_DECORATIVE:
michael@0 180 return aGeneric.EqualsLiteral("fantasy");
michael@0 181 }
michael@0 182
michael@0 183 return false;
michael@0 184 }
michael@0 185
michael@0 186 virtual bool SupportsLangGroup(nsIAtom* aLangGroup) const {
michael@0 187 if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
michael@0 188 return true;
michael@0 189 }
michael@0 190
michael@0 191 int16_t bit = -1;
michael@0 192
michael@0 193 /* map our langgroup names in to Windows charset bits */
michael@0 194 if (aLangGroup == nsGkAtoms::x_western) {
michael@0 195 bit = ANSI_CHARSET;
michael@0 196 } else if (aLangGroup == nsGkAtoms::Japanese) {
michael@0 197 bit = SHIFTJIS_CHARSET;
michael@0 198 } else if (aLangGroup == nsGkAtoms::ko) {
michael@0 199 bit = HANGEUL_CHARSET;
michael@0 200 } else if (aLangGroup == nsGkAtoms::ko_xxx) {
michael@0 201 bit = JOHAB_CHARSET;
michael@0 202 } else if (aLangGroup == nsGkAtoms::zh_cn) {
michael@0 203 bit = GB2312_CHARSET;
michael@0 204 } else if (aLangGroup == nsGkAtoms::zh_tw) {
michael@0 205 bit = CHINESEBIG5_CHARSET;
michael@0 206 } else if (aLangGroup == nsGkAtoms::el_) {
michael@0 207 bit = GREEK_CHARSET;
michael@0 208 } else if (aLangGroup == nsGkAtoms::tr) {
michael@0 209 bit = TURKISH_CHARSET;
michael@0 210 } else if (aLangGroup == nsGkAtoms::he) {
michael@0 211 bit = HEBREW_CHARSET;
michael@0 212 } else if (aLangGroup == nsGkAtoms::ar) {
michael@0 213 bit = ARABIC_CHARSET;
michael@0 214 } else if (aLangGroup == nsGkAtoms::x_baltic) {
michael@0 215 bit = BALTIC_CHARSET;
michael@0 216 } else if (aLangGroup == nsGkAtoms::x_cyrillic) {
michael@0 217 bit = RUSSIAN_CHARSET;
michael@0 218 } else if (aLangGroup == nsGkAtoms::th) {
michael@0 219 bit = THAI_CHARSET;
michael@0 220 } else if (aLangGroup == nsGkAtoms::x_central_euro) {
michael@0 221 bit = EASTEUROPE_CHARSET;
michael@0 222 } else if (aLangGroup == nsGkAtoms::x_symbol) {
michael@0 223 bit = SYMBOL_CHARSET;
michael@0 224 }
michael@0 225
michael@0 226 if (bit != -1) {
michael@0 227 return mCharset.test(bit);
michael@0 228 }
michael@0 229
michael@0 230 return false;
michael@0 231 }
michael@0 232
michael@0 233 virtual bool SupportsRange(uint8_t range) {
michael@0 234 return mUnicodeRanges.test(range);
michael@0 235 }
michael@0 236
michael@0 237 virtual bool SkipDuringSystemFallback() {
michael@0 238 return !HasCmapTable(); // explicitly skip non-SFNT fonts
michael@0 239 }
michael@0 240
michael@0 241 virtual bool TestCharacterMap(uint32_t aCh);
michael@0 242
michael@0 243 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
michael@0 244 FontListSizes* aSizes) const;
michael@0 245
michael@0 246 // create a font entry for a font with a given name
michael@0 247 static GDIFontEntry* CreateFontEntry(const nsAString& aName,
michael@0 248 gfxWindowsFontType aFontType,
michael@0 249 bool aItalic,
michael@0 250 uint16_t aWeight, int16_t aStretch,
michael@0 251 gfxUserFontData* aUserFontData,
michael@0 252 bool aFamilyHasItalicFace);
michael@0 253
michael@0 254 // create a font entry for a font referenced by its fullname
michael@0 255 static GDIFontEntry* LoadLocalFont(const gfxProxyFontEntry &aProxyEntry,
michael@0 256 const nsAString& aFullname);
michael@0 257
michael@0 258 uint8_t mWindowsFamily;
michael@0 259 uint8_t mWindowsPitch;
michael@0 260
michael@0 261 gfxWindowsFontType mFontType;
michael@0 262 bool mForceGDI : 1;
michael@0 263
michael@0 264 // For src:local user-fonts, we keep track of whether the platform family
michael@0 265 // contains an italic face, because in this case we can't safely ask GDI
michael@0 266 // to create synthetic italics (oblique) via the LOGFONT.
michael@0 267 // (For other types of font, this is just set to false.)
michael@0 268 bool mFamilyHasItalicFace : 1;
michael@0 269
michael@0 270 gfxSparseBitSet mCharset;
michael@0 271 gfxSparseBitSet mUnicodeRanges;
michael@0 272
michael@0 273 protected:
michael@0 274 friend class gfxWindowsFont;
michael@0 275
michael@0 276 GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
michael@0 277 bool aItalic, uint16_t aWeight, int16_t aStretch,
michael@0 278 gfxUserFontData *aUserFontData, bool aFamilyHasItalicFace);
michael@0 279
michael@0 280 void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType);
michael@0 281
michael@0 282 virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold);
michael@0 283
michael@0 284 virtual nsresult CopyFontTable(uint32_t aTableTag,
michael@0 285 FallibleTArray<uint8_t>& aBuffer) MOZ_OVERRIDE;
michael@0 286
michael@0 287 LOGFONTW mLogFont;
michael@0 288 };
michael@0 289
michael@0 290 // a single font family, referencing one or more faces
michael@0 291 class GDIFontFamily : public gfxFontFamily
michael@0 292 {
michael@0 293 public:
michael@0 294 GDIFontFamily(nsAString &aName) :
michael@0 295 gfxFontFamily(aName) {}
michael@0 296
michael@0 297 virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr);
michael@0 298
michael@0 299 private:
michael@0 300 static int CALLBACK FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
michael@0 301 const NEWTEXTMETRICEXW *nmetrics,
michael@0 302 DWORD fontType, LPARAM data);
michael@0 303 };
michael@0 304
michael@0 305 class gfxGDIFontList : public gfxPlatformFontList {
michael@0 306 public:
michael@0 307 static gfxGDIFontList* PlatformFontList() {
michael@0 308 return static_cast<gfxGDIFontList*>(sPlatformFontList);
michael@0 309 }
michael@0 310
michael@0 311 // initialize font lists
michael@0 312 virtual nsresult InitFontList();
michael@0 313
michael@0 314 virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
michael@0 315
michael@0 316 virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
michael@0 317 const nsAString& aFontName);
michael@0 318
michael@0 319 virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
michael@0 320 const uint8_t *aFontData, uint32_t aLength);
michael@0 321
michael@0 322 virtual bool ResolveFontName(const nsAString& aFontName,
michael@0 323 nsAString& aResolvedFontName);
michael@0 324
michael@0 325 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
michael@0 326 FontListSizes* aSizes) const;
michael@0 327 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
michael@0 328 FontListSizes* aSizes) const;
michael@0 329
michael@0 330 private:
michael@0 331 friend class gfxWindowsPlatform;
michael@0 332
michael@0 333 gfxGDIFontList();
michael@0 334
michael@0 335 nsresult GetFontSubstitutes();
michael@0 336
michael@0 337 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
michael@0 338 NEWTEXTMETRICEXW *lpntme,
michael@0 339 DWORD fontType,
michael@0 340 LPARAM lParam);
michael@0 341
michael@0 342 virtual already_AddRefed<FontInfoData> CreateFontInfoData();
michael@0 343
michael@0 344 typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontTable;
michael@0 345
michael@0 346 FontTable mFontSubstitutes;
michael@0 347 nsTArray<nsString> mNonExistingFonts;
michael@0 348 };
michael@0 349
michael@0 350 #endif /* GFX_GDIFONTLIST_H */

mercurial