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/. */
5 
6 #ifndef GFX_FT2FONTLIST_H
7 #define GFX_FT2FONTLIST_H
8 
9 #include "mozilla/MemoryReporting.h"
10 #include "gfxPlatformFontList.h"
11 
12 namespace mozilla {
13     namespace dom {
14         class FontListEntry;
15     };
16 };
17 using mozilla::dom::FontListEntry;
18 
19 class FontNameCache;
20 typedef struct FT_FaceRec_* FT_Face;
21 class nsZipArchive;
22 
23 class FT2FontEntry : public gfxFontEntry
24 {
25 public:
FT2FontEntry(const nsAString & aFaceName)26     FT2FontEntry(const nsAString& aFaceName) :
27         gfxFontEntry(aFaceName),
28         mFTFace(nullptr),
29         mFontFace(nullptr),
30         mFTFontIndex(0)
31     {
32     }
33 
34     ~FT2FontEntry();
35 
GetName()36     const nsString& GetName() const {
37         return Name();
38     }
39 
40     // create a font entry for a downloaded font
41     static FT2FontEntry*
42     CreateFontEntry(const nsAString& aFontName,
43                     uint16_t aWeight,
44                     int16_t aStretch,
45                     uint8_t aStyle,
46                     const uint8_t* aFontData,
47                     uint32_t aLength);
48 
49     // create a font entry representing an installed font, identified by
50     // a FontListEntry; the freetype and cairo faces will not be instantiated
51     // until actually needed
52     static FT2FontEntry*
53     CreateFontEntry(const FontListEntry& aFLE);
54 
55     // Create a font entry for a given freetype face; if it is an installed font,
56     // also record the filename and index.
57     // aFontData (if non-nullptr) is NS_Malloc'ed data that aFace depends on,
58     // to be freed after the face is destroyed
59     static FT2FontEntry*
60     CreateFontEntry(FT_Face aFace,
61                     const char *aFilename, uint8_t aIndex,
62                     const nsAString& aName,
63                     const uint8_t* aFontData = nullptr);
64 
65     virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
66                                         bool aNeedsBold) override;
67 
68     // Create (if necessary) and return the cairo_font_face for this font.
69     // This may fail and return null, so caller must be prepared to handle this.
70     cairo_font_face_t *CairoFontFace();
71 
72     // Create a cairo_scaled_font for this face, with the given style.
73     // This may fail and return null, so caller must be prepared to handle this.
74     cairo_scaled_font_t *CreateScaledFont(const gfxFontStyle *aStyle);
75 
76     nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override;
77 
78     virtual hb_blob_t* GetFontTable(uint32_t aTableTag) override;
79 
80     virtual nsresult CopyFontTable(uint32_t aTableTag,
81                                    nsTArray<uint8_t>& aBuffer) override;
82 
83     // Check for various kinds of brokenness, and set flags on the entry
84     // accordingly so that we avoid using bad font tables
85     void CheckForBrokenFont(gfxFontFamily *aFamily);
86 
87     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
88                                         FontListSizes* aSizes) const override;
89     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
90                                         FontListSizes* aSizes) const override;
91 
92     FT_Face mFTFace;
93     cairo_font_face_t *mFontFace;
94 
95     nsCString mFilename;
96     uint8_t   mFTFontIndex;
97 };
98 
99 class FT2FontFamily : public gfxFontFamily
100 {
101 public:
102     // Flags to indicate whether a font should be "visible" in the global
103     // font list (available for use in font-family), or "hidden" (available
104     // only to support a matching data: URI used in @font-face).
105     typedef enum {
106         kVisible,
107         kHidden
108     } Visibility;
109 
FT2FontFamily(const nsAString & aName)110     FT2FontFamily(const nsAString& aName) :
111         gfxFontFamily(aName) { }
112 
113     // Append this family's faces to the IPC fontlist
114     void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList,
115                             Visibility aVisibility);
116 };
117 
118 class gfxFT2FontList : public gfxPlatformFontList
119 {
120 public:
121     gfxFT2FontList();
122     virtual ~gfxFT2FontList();
123 
124     virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
125                                           uint16_t aWeight,
126                                           int16_t aStretch,
127                                           uint8_t aStyle);
128 
129     virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
130                                            uint16_t aWeight,
131                                            int16_t aStretch,
132                                            uint8_t aStyle,
133                                            const uint8_t* aFontData,
134                                            uint32_t aLength);
135 
136     void GetSystemFontList(InfallibleTArray<FontListEntry>* retValue);
137 
PlatformFontList()138     static gfxFT2FontList* PlatformFontList() {
139         return static_cast<gfxFT2FontList*>(gfxPlatformFontList::PlatformFontList());
140     }
141 
142     virtual void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray);
143 
144     void WillShutdown();
145 
146 protected:
147     typedef enum {
148         kUnknown,
149         kStandard
150     } StandardFile;
151 
152     // initialize font lists
153     virtual nsresult InitFontListForPlatform() override;
154 
155     void AppendFaceFromFontListEntry(const FontListEntry& aFLE,
156                                      StandardFile aStdFile);
157 
158     void AppendFacesFromFontFile(const nsCString& aFileName,
159                                  FontNameCache *aCache,
160                                  StandardFile aStdFile,
161                                  FT2FontFamily::Visibility aVisibility);
162 
163     void AppendFacesFromOmnijarEntry(nsZipArchive *aReader,
164                                      const nsCString& aEntryName,
165                                      FontNameCache *aCache,
166                                      bool aJarChanged);
167 
168     // the defaults here are suitable for reading bundled fonts from omnijar
169     void AppendFacesFromCachedFaceList(const nsCString& aFileName,
170                                        const nsCString& aFaceList,
171                                        StandardFile aStdFile = kStandard,
172                                        FT2FontFamily::Visibility aVisibility =
173                                            FT2FontFamily::kVisible);
174 
175     void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
176                        StandardFile aStdFile,
177                        FT2FontFamily::Visibility aVisibility,
178                        FT_Face aFace, nsCString& aFaceList);
179 
180     void FindFonts();
181 
182     void FindFontsInOmnijar(FontNameCache *aCache);
183 
184     void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC,
185                         FT2FontFamily::Visibility aVisibility);
186 
187     virtual gfxFontFamily*
188     GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
189 
190     nsTHashtable<nsStringHashKey> mSkipSpaceLookupCheckFamilies;
191 
192 private:
193     FontFamilyTable mHiddenFontFamilies;
194 
195     mozilla::UniquePtr<FontNameCache> mFontNameCache;
196     int64_t mJarModifiedTime;
197     nsCOMPtr<nsIObserver> mObserver;
198 };
199 
200 #endif /* GFX_FT2FONTLIST_H */
201