Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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_DWRITEFONTLIST_H
7 #define GFX_DWRITEFONTLIST_H
9 #include "mozilla/MemoryReporting.h"
10 #include "gfxDWriteCommon.h"
12 #include "gfxFont.h"
13 #include "gfxUserFontSet.h"
14 #include "cairo-win32.h"
16 #include "gfxPlatformFontList.h"
17 #include "gfxPlatform.h"
18 #include <algorithm>
21 /**
22 * gfxDWriteFontFamily is a class that describes one of the fonts on the
23 * users system. It holds each gfxDWriteFontEntry (maps more directly to
24 * a font face) which holds font type, charset info and character map info.
25 */
26 class gfxDWriteFontEntry;
28 /**
29 * \brief Class representing directwrite font family.
30 */
31 class gfxDWriteFontFamily : public gfxFontFamily
32 {
33 public:
34 /**
35 * Constructs a new DWriteFont Family.
36 *
37 * \param aName Name identifying the family
38 * \param aFamily IDWriteFontFamily object representing the directwrite
39 * family object.
40 */
41 gfxDWriteFontFamily(const nsAString& aName,
42 IDWriteFontFamily *aFamily)
43 : gfxFontFamily(aName), mDWFamily(aFamily), mForceGDIClassic(false) {}
44 virtual ~gfxDWriteFontFamily();
46 virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr);
48 virtual void LocalizedName(nsAString& aLocalizedName);
50 virtual void ReadFaceNames(gfxPlatformFontList *aPlatformFontList,
51 bool aNeedFullnamePostscriptNames);
53 void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
55 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
56 FontListSizes* aSizes) const;
57 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
58 FontListSizes* aSizes) const;
60 protected:
61 /** This font family's directwrite fontfamily object */
62 nsRefPtr<IDWriteFontFamily> mDWFamily;
63 bool mForceGDIClassic;
64 };
66 /**
67 * \brief Class representing DirectWrite FontEntry (a unique font style/family)
68 */
69 class gfxDWriteFontEntry : public gfxFontEntry
70 {
71 public:
72 /**
73 * Constructs a font entry.
74 *
75 * \param aFaceName The name of the corresponding font face.
76 * \param aFont DirectWrite font object
77 */
78 gfxDWriteFontEntry(const nsAString& aFaceName,
79 IDWriteFont *aFont)
80 : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
81 mForceGDIClassic(false)
82 {
83 mItalic = (aFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC ||
84 aFont->GetStyle() == DWRITE_FONT_STYLE_OBLIQUE);
85 mStretch = FontStretchFromDWriteStretch(aFont->GetStretch());
86 uint16_t weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
88 weight = std::max<uint16_t>(100, weight);
89 weight = std::min<uint16_t>(900, weight);
90 mWeight = weight;
92 mIsCJK = UNINITIALIZED_VALUE;
93 }
95 /**
96 * Constructs a font entry using a font. But with custom font values.
97 * This is used for creating correct font entries for @font-face with local
98 * font source.
99 *
100 * \param aFaceName The name of the corresponding font face.
101 * \param aFont DirectWrite font object
102 * \param aWeight Weight of the font
103 * \param aStretch Stretch of the font
104 * \param aItalic True if italic
105 */
106 gfxDWriteFontEntry(const nsAString& aFaceName,
107 IDWriteFont *aFont,
108 uint16_t aWeight,
109 int16_t aStretch,
110 bool aItalic)
111 : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
112 mForceGDIClassic(false)
113 {
114 mWeight = aWeight;
115 mStretch = aStretch;
116 mItalic = aItalic;
117 mIsUserFont = true;
118 mIsLocalUserFont = true;
119 mIsCJK = UNINITIALIZED_VALUE;
120 }
122 /**
123 * Constructs a font entry using a font file.
124 *
125 * \param aFaceName The name of the corresponding font face.
126 * \param aFontFile DirectWrite fontfile object
127 * \param aWeight Weight of the font
128 * \param aStretch Stretch of the font
129 * \param aItalic True if italic
130 */
131 gfxDWriteFontEntry(const nsAString& aFaceName,
132 IDWriteFontFile *aFontFile,
133 uint16_t aWeight,
134 int16_t aStretch,
135 bool aItalic)
136 : gfxFontEntry(aFaceName), mFont(nullptr), mFontFile(aFontFile),
137 mForceGDIClassic(false)
138 {
139 mWeight = aWeight;
140 mStretch = aStretch;
141 mItalic = aItalic;
142 mIsUserFont = true;
143 mIsCJK = UNINITIALIZED_VALUE;
144 }
146 virtual ~gfxDWriteFontEntry();
148 virtual bool IsSymbolFont();
150 virtual hb_blob_t* GetFontTable(uint32_t aTableTag) MOZ_OVERRIDE;
152 nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr);
154 bool IsCJKFont();
156 void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
157 bool GetForceGDIClassic() { return mForceGDIClassic; }
159 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
160 FontListSizes* aSizes) const;
161 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
162 FontListSizes* aSizes) const;
164 protected:
165 friend class gfxDWriteFont;
166 friend class gfxDWriteFontList;
168 virtual nsresult CopyFontTable(uint32_t aTableTag,
169 FallibleTArray<uint8_t>& aBuffer) MOZ_OVERRIDE;
171 virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
172 bool aNeedsBold);
174 nsresult CreateFontFace(
175 IDWriteFontFace **aFontFace,
176 DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE);
178 static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont);
180 /**
181 * A fontentry only needs to have either of these. If it has both only
182 * the IDWriteFont will be used.
183 */
184 nsRefPtr<IDWriteFont> mFont;
185 nsRefPtr<IDWriteFontFile> mFontFile;
187 // font face corresponding to the mFont/mFontFile *without* any DWrite
188 // style simulations applied
189 nsRefPtr<IDWriteFontFace> mFontFace;
191 DWRITE_FONT_FACE_TYPE mFaceType;
193 int8_t mIsCJK;
194 bool mForceGDIClassic;
195 };
197 // custom text renderer used to determine the fallback font for a given char
198 class FontFallbackRenderer MOZ_FINAL : public IDWriteTextRenderer
199 {
200 public:
201 FontFallbackRenderer(IDWriteFactory *aFactory)
202 : mRefCount(0)
203 {
204 HRESULT hr = S_OK;
206 hr = aFactory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
207 NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
208 }
210 ~FontFallbackRenderer()
211 {}
213 // IDWriteTextRenderer methods
214 IFACEMETHOD(DrawGlyphRun)(
215 void* clientDrawingContext,
216 FLOAT baselineOriginX,
217 FLOAT baselineOriginY,
218 DWRITE_MEASURING_MODE measuringMode,
219 DWRITE_GLYPH_RUN const* glyphRun,
220 DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
221 IUnknown* clientDrawingEffect
222 );
224 IFACEMETHOD(DrawUnderline)(
225 void* clientDrawingContext,
226 FLOAT baselineOriginX,
227 FLOAT baselineOriginY,
228 DWRITE_UNDERLINE const* underline,
229 IUnknown* clientDrawingEffect
230 )
231 {
232 return E_NOTIMPL;
233 }
236 IFACEMETHOD(DrawStrikethrough)(
237 void* clientDrawingContext,
238 FLOAT baselineOriginX,
239 FLOAT baselineOriginY,
240 DWRITE_STRIKETHROUGH const* strikethrough,
241 IUnknown* clientDrawingEffect
242 )
243 {
244 return E_NOTIMPL;
245 }
248 IFACEMETHOD(DrawInlineObject)(
249 void* clientDrawingContext,
250 FLOAT originX,
251 FLOAT originY,
252 IDWriteInlineObject* inlineObject,
253 BOOL isSideways,
254 BOOL isRightToLeft,
255 IUnknown* clientDrawingEffect
256 )
257 {
258 return E_NOTIMPL;
259 }
261 // IDWritePixelSnapping methods
263 IFACEMETHOD(IsPixelSnappingDisabled)(
264 void* clientDrawingContext,
265 BOOL* isDisabled
266 )
267 {
268 *isDisabled = FALSE;
269 return S_OK;
270 }
272 IFACEMETHOD(GetCurrentTransform)(
273 void* clientDrawingContext,
274 DWRITE_MATRIX* transform
275 )
276 {
277 const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
278 *transform = ident;
279 return S_OK;
280 }
282 IFACEMETHOD(GetPixelsPerDip)(
283 void* clientDrawingContext,
284 FLOAT* pixelsPerDip
285 )
286 {
287 *pixelsPerDip = 1.0f;
288 return S_OK;
289 }
291 // IUnknown methods
293 IFACEMETHOD_(unsigned long, AddRef) ()
294 {
295 return InterlockedIncrement(&mRefCount);
296 }
298 IFACEMETHOD_(unsigned long, Release) ()
299 {
300 unsigned long newCount = InterlockedDecrement(&mRefCount);
301 if (newCount == 0)
302 {
303 delete this;
304 return 0;
305 }
307 return newCount;
308 }
310 IFACEMETHOD(QueryInterface) (IID const& riid, void** ppvObject)
311 {
312 if (__uuidof(IDWriteTextRenderer) == riid) {
313 *ppvObject = this;
314 } else if (__uuidof(IDWritePixelSnapping) == riid) {
315 *ppvObject = this;
316 } else if (__uuidof(IUnknown) == riid) {
317 *ppvObject = this;
318 } else {
319 *ppvObject = nullptr;
320 return E_FAIL;
321 }
323 this->AddRef();
324 return S_OK;
325 }
327 const nsString& FallbackFamilyName() { return mFamilyName; }
329 protected:
330 long mRefCount;
331 nsRefPtr<IDWriteFontCollection> mSystemFonts;
332 nsString mFamilyName;
333 };
337 class gfxDWriteFontList : public gfxPlatformFontList {
338 public:
339 gfxDWriteFontList();
341 static gfxDWriteFontList* PlatformFontList() {
342 return static_cast<gfxDWriteFontList*>(sPlatformFontList);
343 }
345 // initialize font lists
346 virtual nsresult InitFontList();
348 virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
350 virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
351 const nsAString& aFontName);
353 virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
354 const uint8_t *aFontData,
355 uint32_t aLength);
357 virtual bool ResolveFontName(const nsAString& aFontName,
358 nsAString& aResolvedFontName);
360 bool GetStandardFamilyName(const nsAString& aFontName,
361 nsAString& aFamilyName);
363 IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; }
364 bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
366 virtual gfxFontFamily* FindFamily(const nsAString& aFamily);
368 virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
370 gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
372 virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
373 FontListSizes* aSizes) const;
374 virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
375 FontListSizes* aSizes) const;
377 private:
378 friend class gfxDWriteFontFamily;
380 nsresult GetFontSubstitutes();
382 void GetDirectWriteSubstitutes();
384 // search fonts system-wide for a given character, null otherwise
385 virtual gfxFontEntry* GlobalFontFallback(const uint32_t aCh,
386 int32_t aRunScript,
387 const gfxFontStyle* aMatchStyle,
388 uint32_t& aCmapCount,
389 gfxFontFamily** aMatchedFamily);
391 virtual bool UsesSystemFallback() { return true; }
393 /**
394 * Fonts listed in the registry as substitutes but for which no actual
395 * font family is found.
396 */
397 nsTArray<nsString> mNonExistingFonts;
399 typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontTable;
401 /**
402 * Table of font substitutes, we grab this from the registry to get
403 * alternative font names.
404 */
405 FontTable mFontSubstitutes;
407 bool mInitialized;
408 virtual nsresult DelayedInitFontList();
410 virtual already_AddRefed<FontInfoData> CreateFontInfoData();
412 gfxFloat mForceGDIClassicMaxFontSize;
414 // whether to use GDI font table access routines
415 bool mGDIFontTableAccess;
416 nsRefPtr<IDWriteGdiInterop> mGDIInterop;
418 nsRefPtr<FontFallbackRenderer> mFallbackRenderer;
419 nsRefPtr<IDWriteTextFormat> mFallbackFormat;
420 };
423 #endif /* GFX_DWRITEFONTLIST_H */