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.

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

mercurial