1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxDWriteFontList.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,423 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_DWRITEFONTLIST_H 1.10 +#define GFX_DWRITEFONTLIST_H 1.11 + 1.12 +#include "mozilla/MemoryReporting.h" 1.13 +#include "gfxDWriteCommon.h" 1.14 + 1.15 +#include "gfxFont.h" 1.16 +#include "gfxUserFontSet.h" 1.17 +#include "cairo-win32.h" 1.18 + 1.19 +#include "gfxPlatformFontList.h" 1.20 +#include "gfxPlatform.h" 1.21 +#include <algorithm> 1.22 + 1.23 + 1.24 +/** 1.25 + * gfxDWriteFontFamily is a class that describes one of the fonts on the 1.26 + * users system. It holds each gfxDWriteFontEntry (maps more directly to 1.27 + * a font face) which holds font type, charset info and character map info. 1.28 + */ 1.29 +class gfxDWriteFontEntry; 1.30 + 1.31 +/** 1.32 + * \brief Class representing directwrite font family. 1.33 + */ 1.34 +class gfxDWriteFontFamily : public gfxFontFamily 1.35 +{ 1.36 +public: 1.37 + /** 1.38 + * Constructs a new DWriteFont Family. 1.39 + * 1.40 + * \param aName Name identifying the family 1.41 + * \param aFamily IDWriteFontFamily object representing the directwrite 1.42 + * family object. 1.43 + */ 1.44 + gfxDWriteFontFamily(const nsAString& aName, 1.45 + IDWriteFontFamily *aFamily) 1.46 + : gfxFontFamily(aName), mDWFamily(aFamily), mForceGDIClassic(false) {} 1.47 + virtual ~gfxDWriteFontFamily(); 1.48 + 1.49 + virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr); 1.50 + 1.51 + virtual void LocalizedName(nsAString& aLocalizedName); 1.52 + 1.53 + virtual void ReadFaceNames(gfxPlatformFontList *aPlatformFontList, 1.54 + bool aNeedFullnamePostscriptNames); 1.55 + 1.56 + void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; } 1.57 + 1.58 + virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.59 + FontListSizes* aSizes) const; 1.60 + virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.61 + FontListSizes* aSizes) const; 1.62 + 1.63 +protected: 1.64 + /** This font family's directwrite fontfamily object */ 1.65 + nsRefPtr<IDWriteFontFamily> mDWFamily; 1.66 + bool mForceGDIClassic; 1.67 +}; 1.68 + 1.69 +/** 1.70 + * \brief Class representing DirectWrite FontEntry (a unique font style/family) 1.71 + */ 1.72 +class gfxDWriteFontEntry : public gfxFontEntry 1.73 +{ 1.74 +public: 1.75 + /** 1.76 + * Constructs a font entry. 1.77 + * 1.78 + * \param aFaceName The name of the corresponding font face. 1.79 + * \param aFont DirectWrite font object 1.80 + */ 1.81 + gfxDWriteFontEntry(const nsAString& aFaceName, 1.82 + IDWriteFont *aFont) 1.83 + : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr), 1.84 + mForceGDIClassic(false) 1.85 + { 1.86 + mItalic = (aFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC || 1.87 + aFont->GetStyle() == DWRITE_FONT_STYLE_OBLIQUE); 1.88 + mStretch = FontStretchFromDWriteStretch(aFont->GetStretch()); 1.89 + uint16_t weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100); 1.90 + 1.91 + weight = std::max<uint16_t>(100, weight); 1.92 + weight = std::min<uint16_t>(900, weight); 1.93 + mWeight = weight; 1.94 + 1.95 + mIsCJK = UNINITIALIZED_VALUE; 1.96 + } 1.97 + 1.98 + /** 1.99 + * Constructs a font entry using a font. But with custom font values. 1.100 + * This is used for creating correct font entries for @font-face with local 1.101 + * font source. 1.102 + * 1.103 + * \param aFaceName The name of the corresponding font face. 1.104 + * \param aFont DirectWrite font object 1.105 + * \param aWeight Weight of the font 1.106 + * \param aStretch Stretch of the font 1.107 + * \param aItalic True if italic 1.108 + */ 1.109 + gfxDWriteFontEntry(const nsAString& aFaceName, 1.110 + IDWriteFont *aFont, 1.111 + uint16_t aWeight, 1.112 + int16_t aStretch, 1.113 + bool aItalic) 1.114 + : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr), 1.115 + mForceGDIClassic(false) 1.116 + { 1.117 + mWeight = aWeight; 1.118 + mStretch = aStretch; 1.119 + mItalic = aItalic; 1.120 + mIsUserFont = true; 1.121 + mIsLocalUserFont = true; 1.122 + mIsCJK = UNINITIALIZED_VALUE; 1.123 + } 1.124 + 1.125 + /** 1.126 + * Constructs a font entry using a font file. 1.127 + * 1.128 + * \param aFaceName The name of the corresponding font face. 1.129 + * \param aFontFile DirectWrite fontfile object 1.130 + * \param aWeight Weight of the font 1.131 + * \param aStretch Stretch of the font 1.132 + * \param aItalic True if italic 1.133 + */ 1.134 + gfxDWriteFontEntry(const nsAString& aFaceName, 1.135 + IDWriteFontFile *aFontFile, 1.136 + uint16_t aWeight, 1.137 + int16_t aStretch, 1.138 + bool aItalic) 1.139 + : gfxFontEntry(aFaceName), mFont(nullptr), mFontFile(aFontFile), 1.140 + mForceGDIClassic(false) 1.141 + { 1.142 + mWeight = aWeight; 1.143 + mStretch = aStretch; 1.144 + mItalic = aItalic; 1.145 + mIsUserFont = true; 1.146 + mIsCJK = UNINITIALIZED_VALUE; 1.147 + } 1.148 + 1.149 + virtual ~gfxDWriteFontEntry(); 1.150 + 1.151 + virtual bool IsSymbolFont(); 1.152 + 1.153 + virtual hb_blob_t* GetFontTable(uint32_t aTableTag) MOZ_OVERRIDE; 1.154 + 1.155 + nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr); 1.156 + 1.157 + bool IsCJKFont(); 1.158 + 1.159 + void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; } 1.160 + bool GetForceGDIClassic() { return mForceGDIClassic; } 1.161 + 1.162 + virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.163 + FontListSizes* aSizes) const; 1.164 + virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.165 + FontListSizes* aSizes) const; 1.166 + 1.167 +protected: 1.168 + friend class gfxDWriteFont; 1.169 + friend class gfxDWriteFontList; 1.170 + 1.171 + virtual nsresult CopyFontTable(uint32_t aTableTag, 1.172 + FallibleTArray<uint8_t>& aBuffer) MOZ_OVERRIDE; 1.173 + 1.174 + virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, 1.175 + bool aNeedsBold); 1.176 + 1.177 + nsresult CreateFontFace( 1.178 + IDWriteFontFace **aFontFace, 1.179 + DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE); 1.180 + 1.181 + static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont); 1.182 + 1.183 + /** 1.184 + * A fontentry only needs to have either of these. If it has both only 1.185 + * the IDWriteFont will be used. 1.186 + */ 1.187 + nsRefPtr<IDWriteFont> mFont; 1.188 + nsRefPtr<IDWriteFontFile> mFontFile; 1.189 + 1.190 + // font face corresponding to the mFont/mFontFile *without* any DWrite 1.191 + // style simulations applied 1.192 + nsRefPtr<IDWriteFontFace> mFontFace; 1.193 + 1.194 + DWRITE_FONT_FACE_TYPE mFaceType; 1.195 + 1.196 + int8_t mIsCJK; 1.197 + bool mForceGDIClassic; 1.198 +}; 1.199 + 1.200 +// custom text renderer used to determine the fallback font for a given char 1.201 +class FontFallbackRenderer MOZ_FINAL : public IDWriteTextRenderer 1.202 +{ 1.203 +public: 1.204 + FontFallbackRenderer(IDWriteFactory *aFactory) 1.205 + : mRefCount(0) 1.206 + { 1.207 + HRESULT hr = S_OK; 1.208 + 1.209 + hr = aFactory->GetSystemFontCollection(getter_AddRefs(mSystemFonts)); 1.210 + NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!"); 1.211 + } 1.212 + 1.213 + ~FontFallbackRenderer() 1.214 + {} 1.215 + 1.216 + // IDWriteTextRenderer methods 1.217 + IFACEMETHOD(DrawGlyphRun)( 1.218 + void* clientDrawingContext, 1.219 + FLOAT baselineOriginX, 1.220 + FLOAT baselineOriginY, 1.221 + DWRITE_MEASURING_MODE measuringMode, 1.222 + DWRITE_GLYPH_RUN const* glyphRun, 1.223 + DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, 1.224 + IUnknown* clientDrawingEffect 1.225 + ); 1.226 + 1.227 + IFACEMETHOD(DrawUnderline)( 1.228 + void* clientDrawingContext, 1.229 + FLOAT baselineOriginX, 1.230 + FLOAT baselineOriginY, 1.231 + DWRITE_UNDERLINE const* underline, 1.232 + IUnknown* clientDrawingEffect 1.233 + ) 1.234 + { 1.235 + return E_NOTIMPL; 1.236 + } 1.237 + 1.238 + 1.239 + IFACEMETHOD(DrawStrikethrough)( 1.240 + void* clientDrawingContext, 1.241 + FLOAT baselineOriginX, 1.242 + FLOAT baselineOriginY, 1.243 + DWRITE_STRIKETHROUGH const* strikethrough, 1.244 + IUnknown* clientDrawingEffect 1.245 + ) 1.246 + { 1.247 + return E_NOTIMPL; 1.248 + } 1.249 + 1.250 + 1.251 + IFACEMETHOD(DrawInlineObject)( 1.252 + void* clientDrawingContext, 1.253 + FLOAT originX, 1.254 + FLOAT originY, 1.255 + IDWriteInlineObject* inlineObject, 1.256 + BOOL isSideways, 1.257 + BOOL isRightToLeft, 1.258 + IUnknown* clientDrawingEffect 1.259 + ) 1.260 + { 1.261 + return E_NOTIMPL; 1.262 + } 1.263 + 1.264 + // IDWritePixelSnapping methods 1.265 + 1.266 + IFACEMETHOD(IsPixelSnappingDisabled)( 1.267 + void* clientDrawingContext, 1.268 + BOOL* isDisabled 1.269 + ) 1.270 + { 1.271 + *isDisabled = FALSE; 1.272 + return S_OK; 1.273 + } 1.274 + 1.275 + IFACEMETHOD(GetCurrentTransform)( 1.276 + void* clientDrawingContext, 1.277 + DWRITE_MATRIX* transform 1.278 + ) 1.279 + { 1.280 + const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; 1.281 + *transform = ident; 1.282 + return S_OK; 1.283 + } 1.284 + 1.285 + IFACEMETHOD(GetPixelsPerDip)( 1.286 + void* clientDrawingContext, 1.287 + FLOAT* pixelsPerDip 1.288 + ) 1.289 + { 1.290 + *pixelsPerDip = 1.0f; 1.291 + return S_OK; 1.292 + } 1.293 + 1.294 + // IUnknown methods 1.295 + 1.296 + IFACEMETHOD_(unsigned long, AddRef) () 1.297 + { 1.298 + return InterlockedIncrement(&mRefCount); 1.299 + } 1.300 + 1.301 + IFACEMETHOD_(unsigned long, Release) () 1.302 + { 1.303 + unsigned long newCount = InterlockedDecrement(&mRefCount); 1.304 + if (newCount == 0) 1.305 + { 1.306 + delete this; 1.307 + return 0; 1.308 + } 1.309 + 1.310 + return newCount; 1.311 + } 1.312 + 1.313 + IFACEMETHOD(QueryInterface) (IID const& riid, void** ppvObject) 1.314 + { 1.315 + if (__uuidof(IDWriteTextRenderer) == riid) { 1.316 + *ppvObject = this; 1.317 + } else if (__uuidof(IDWritePixelSnapping) == riid) { 1.318 + *ppvObject = this; 1.319 + } else if (__uuidof(IUnknown) == riid) { 1.320 + *ppvObject = this; 1.321 + } else { 1.322 + *ppvObject = nullptr; 1.323 + return E_FAIL; 1.324 + } 1.325 + 1.326 + this->AddRef(); 1.327 + return S_OK; 1.328 + } 1.329 + 1.330 + const nsString& FallbackFamilyName() { return mFamilyName; } 1.331 + 1.332 +protected: 1.333 + long mRefCount; 1.334 + nsRefPtr<IDWriteFontCollection> mSystemFonts; 1.335 + nsString mFamilyName; 1.336 +}; 1.337 + 1.338 + 1.339 + 1.340 +class gfxDWriteFontList : public gfxPlatformFontList { 1.341 +public: 1.342 + gfxDWriteFontList(); 1.343 + 1.344 + static gfxDWriteFontList* PlatformFontList() { 1.345 + return static_cast<gfxDWriteFontList*>(sPlatformFontList); 1.346 + } 1.347 + 1.348 + // initialize font lists 1.349 + virtual nsresult InitFontList(); 1.350 + 1.351 + virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle); 1.352 + 1.353 + virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, 1.354 + const nsAString& aFontName); 1.355 + 1.356 + virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, 1.357 + const uint8_t *aFontData, 1.358 + uint32_t aLength); 1.359 + 1.360 + virtual bool ResolveFontName(const nsAString& aFontName, 1.361 + nsAString& aResolvedFontName); 1.362 + 1.363 + bool GetStandardFamilyName(const nsAString& aFontName, 1.364 + nsAString& aFamilyName); 1.365 + 1.366 + IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; } 1.367 + bool UseGDIFontTableAccess() { return mGDIFontTableAccess; } 1.368 + 1.369 + virtual gfxFontFamily* FindFamily(const nsAString& aFamily); 1.370 + 1.371 + virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray); 1.372 + 1.373 + gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; } 1.374 + 1.375 + virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.376 + FontListSizes* aSizes) const; 1.377 + virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.378 + FontListSizes* aSizes) const; 1.379 + 1.380 +private: 1.381 + friend class gfxDWriteFontFamily; 1.382 + 1.383 + nsresult GetFontSubstitutes(); 1.384 + 1.385 + void GetDirectWriteSubstitutes(); 1.386 + 1.387 + // search fonts system-wide for a given character, null otherwise 1.388 + virtual gfxFontEntry* GlobalFontFallback(const uint32_t aCh, 1.389 + int32_t aRunScript, 1.390 + const gfxFontStyle* aMatchStyle, 1.391 + uint32_t& aCmapCount, 1.392 + gfxFontFamily** aMatchedFamily); 1.393 + 1.394 + virtual bool UsesSystemFallback() { return true; } 1.395 + 1.396 + /** 1.397 + * Fonts listed in the registry as substitutes but for which no actual 1.398 + * font family is found. 1.399 + */ 1.400 + nsTArray<nsString> mNonExistingFonts; 1.401 + 1.402 + typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontTable; 1.403 + 1.404 + /** 1.405 + * Table of font substitutes, we grab this from the registry to get 1.406 + * alternative font names. 1.407 + */ 1.408 + FontTable mFontSubstitutes; 1.409 + 1.410 + bool mInitialized; 1.411 + virtual nsresult DelayedInitFontList(); 1.412 + 1.413 + virtual already_AddRefed<FontInfoData> CreateFontInfoData(); 1.414 + 1.415 + gfxFloat mForceGDIClassicMaxFontSize; 1.416 + 1.417 + // whether to use GDI font table access routines 1.418 + bool mGDIFontTableAccess; 1.419 + nsRefPtr<IDWriteGdiInterop> mGDIInterop; 1.420 + 1.421 + nsRefPtr<FontFallbackRenderer> mFallbackRenderer; 1.422 + nsRefPtr<IDWriteTextFormat> mFallbackFormat; 1.423 +}; 1.424 + 1.425 + 1.426 +#endif /* GFX_DWRITEFONTLIST_H */