|
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_WINDOWS_PLATFORM_H |
|
7 #define GFX_WINDOWS_PLATFORM_H |
|
8 |
|
9 |
|
10 /** |
|
11 * XXX to get CAIRO_HAS_D2D_SURFACE, CAIRO_HAS_DWRITE_FONT |
|
12 * and cairo_win32_scaled_font_select_font |
|
13 */ |
|
14 #include "cairo-win32.h" |
|
15 |
|
16 #include "gfxFontUtils.h" |
|
17 #include "gfxWindowsSurface.h" |
|
18 #include "gfxFont.h" |
|
19 #ifdef CAIRO_HAS_DWRITE_FONT |
|
20 #include "gfxDWriteFonts.h" |
|
21 #endif |
|
22 #include "gfxPlatform.h" |
|
23 #include "gfxContext.h" |
|
24 |
|
25 #include "nsTArray.h" |
|
26 #include "nsDataHashtable.h" |
|
27 |
|
28 #include "mozilla/RefPtr.h" |
|
29 |
|
30 #include <windows.h> |
|
31 #include <objbase.h> |
|
32 |
|
33 #ifdef CAIRO_HAS_D2D_SURFACE |
|
34 #include <dxgi.h> |
|
35 #endif |
|
36 |
|
37 // This header is available in the June 2010 SDK and in the Win8 SDK |
|
38 #include <d3dcommon.h> |
|
39 // Win 8.0 SDK types we'll need when building using older sdks. |
|
40 #if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only |
|
41 #define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100) |
|
42 #define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048 |
|
43 #define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 |
|
44 #endif |
|
45 |
|
46 namespace mozilla { |
|
47 namespace layers { |
|
48 class DeviceManagerD3D9; |
|
49 } |
|
50 } |
|
51 class IDirect3DDevice9; |
|
52 class ID3D11Device; |
|
53 class IDXGIAdapter1; |
|
54 |
|
55 class nsIMemoryReporter; |
|
56 |
|
57 // Utility to get a Windows HDC from a thebes context, |
|
58 // used by both GDI and Uniscribe font shapers |
|
59 struct DCFromContext { |
|
60 DCFromContext(gfxContext *aContext) { |
|
61 dc = nullptr; |
|
62 nsRefPtr<gfxASurface> aSurface = aContext->CurrentSurface(); |
|
63 NS_ASSERTION(aSurface || !aContext->IsCairo(), "DCFromContext: null surface"); |
|
64 if (aSurface && |
|
65 (aSurface->GetType() == gfxSurfaceType::Win32 || |
|
66 aSurface->GetType() == gfxSurfaceType::Win32Printing)) |
|
67 { |
|
68 dc = static_cast<gfxWindowsSurface*>(aSurface.get())->GetDC(); |
|
69 needsRelease = false; |
|
70 SaveDC(dc); |
|
71 cairo_scaled_font_t* scaled = |
|
72 cairo_get_scaled_font(aContext->GetCairo()); |
|
73 cairo_win32_scaled_font_select_font(scaled, dc); |
|
74 } |
|
75 if (!dc) { |
|
76 dc = GetDC(nullptr); |
|
77 SetGraphicsMode(dc, GM_ADVANCED); |
|
78 needsRelease = true; |
|
79 } |
|
80 } |
|
81 |
|
82 ~DCFromContext() { |
|
83 if (needsRelease) { |
|
84 ReleaseDC(nullptr, dc); |
|
85 } else { |
|
86 RestoreDC(dc, -1); |
|
87 } |
|
88 } |
|
89 |
|
90 operator HDC () { |
|
91 return dc; |
|
92 } |
|
93 |
|
94 HDC dc; |
|
95 bool needsRelease; |
|
96 }; |
|
97 |
|
98 // ClearType parameters set by running ClearType tuner |
|
99 struct ClearTypeParameterInfo { |
|
100 ClearTypeParameterInfo() : |
|
101 gamma(-1), pixelStructure(-1), clearTypeLevel(-1), enhancedContrast(-1) |
|
102 { } |
|
103 |
|
104 nsString displayName; // typically just 'DISPLAY1' |
|
105 int32_t gamma; |
|
106 int32_t pixelStructure; |
|
107 int32_t clearTypeLevel; |
|
108 int32_t enhancedContrast; |
|
109 }; |
|
110 |
|
111 class gfxWindowsPlatform : public gfxPlatform { |
|
112 public: |
|
113 enum TextRenderingMode { |
|
114 TEXT_RENDERING_NO_CLEARTYPE, |
|
115 TEXT_RENDERING_NORMAL, |
|
116 TEXT_RENDERING_GDI_CLASSIC, |
|
117 TEXT_RENDERING_COUNT |
|
118 }; |
|
119 |
|
120 gfxWindowsPlatform(); |
|
121 virtual ~gfxWindowsPlatform(); |
|
122 static gfxWindowsPlatform *GetPlatform() { |
|
123 return (gfxWindowsPlatform*) gfxPlatform::GetPlatform(); |
|
124 } |
|
125 |
|
126 virtual gfxPlatformFontList* CreatePlatformFontList(); |
|
127 |
|
128 virtual already_AddRefed<gfxASurface> |
|
129 CreateOffscreenSurface(const IntSize& size, |
|
130 gfxContentType contentType) MOZ_OVERRIDE; |
|
131 virtual already_AddRefed<gfxASurface> |
|
132 CreateOffscreenImageSurface(const gfxIntSize& aSize, |
|
133 gfxContentType aContentType); |
|
134 |
|
135 virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont> |
|
136 GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont); |
|
137 virtual already_AddRefed<gfxASurface> |
|
138 GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget); |
|
139 |
|
140 enum RenderMode { |
|
141 /* Use GDI and windows surfaces */ |
|
142 RENDER_GDI = 0, |
|
143 |
|
144 /* Use 32bpp image surfaces and call StretchDIBits */ |
|
145 RENDER_IMAGE_STRETCH32, |
|
146 |
|
147 /* Use 32bpp image surfaces, and do 32->24 conversion before calling StretchDIBits */ |
|
148 RENDER_IMAGE_STRETCH24, |
|
149 |
|
150 /* Use Direct2D rendering */ |
|
151 RENDER_DIRECT2D, |
|
152 |
|
153 /* max */ |
|
154 RENDER_MODE_MAX |
|
155 }; |
|
156 |
|
157 int GetScreenDepth() const; |
|
158 |
|
159 RenderMode GetRenderMode() { return mRenderMode; } |
|
160 void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; } |
|
161 |
|
162 /** |
|
163 * Updates render mode with relation to the current preferences and |
|
164 * available devices. |
|
165 */ |
|
166 void UpdateRenderMode(); |
|
167 |
|
168 /** |
|
169 * Verifies a D2D device is present and working, will attempt to create one |
|
170 * it is non-functional or non-existant. |
|
171 * |
|
172 * \param aAttemptForce Attempt to force D2D cairo device creation by using |
|
173 * cairo device creation routines. |
|
174 */ |
|
175 void VerifyD2DDevice(bool aAttemptForce); |
|
176 |
|
177 #ifdef CAIRO_HAS_D2D_SURFACE |
|
178 HRESULT CreateDevice(nsRefPtr<IDXGIAdapter1> &adapter1, int featureLevelIndex); |
|
179 #endif |
|
180 |
|
181 /** |
|
182 * Return the resolution scaling factor to convert between "logical" or |
|
183 * "screen" pixels as used by Windows (dependent on the DPI scaling option |
|
184 * in the Display control panel) and actual device pixels. |
|
185 */ |
|
186 double GetDPIScale(); |
|
187 |
|
188 nsresult GetFontList(nsIAtom *aLangGroup, |
|
189 const nsACString& aGenericFamily, |
|
190 nsTArray<nsString>& aListOfFonts); |
|
191 |
|
192 nsresult UpdateFontList(); |
|
193 |
|
194 virtual void GetCommonFallbackFonts(const uint32_t aCh, |
|
195 int32_t aRunScript, |
|
196 nsTArray<const char*>& aFontList); |
|
197 |
|
198 nsresult ResolveFontName(const nsAString& aFontName, |
|
199 FontResolverCallback aCallback, |
|
200 void *aClosure, bool& aAborted); |
|
201 |
|
202 nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName); |
|
203 |
|
204 gfxFontGroup *CreateFontGroup(const nsAString &aFamilies, |
|
205 const gfxFontStyle *aStyle, |
|
206 gfxUserFontSet *aUserFontSet); |
|
207 |
|
208 /** |
|
209 * Look up a local platform font using the full font face name (needed to support @font-face src local() ) |
|
210 */ |
|
211 virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, |
|
212 const nsAString& aFontName); |
|
213 |
|
214 /** |
|
215 * Activate a platform font (needed to support @font-face src url() ) |
|
216 */ |
|
217 virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, |
|
218 const uint8_t *aFontData, |
|
219 uint32_t aLength); |
|
220 |
|
221 /** |
|
222 * Check whether format is supported on a platform or not (if unclear, returns true) |
|
223 */ |
|
224 virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags); |
|
225 |
|
226 /* Find a FontFamily/FontEntry object that represents a font on your system given a name */ |
|
227 gfxFontFamily *FindFontFamily(const nsAString& aName); |
|
228 gfxFontEntry *FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle); |
|
229 |
|
230 bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *array); |
|
231 void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& array); |
|
232 |
|
233 void ClearPrefFonts() { mPrefFonts.Clear(); } |
|
234 |
|
235 // ClearType is not always enabled even when available (e.g. Windows XP) |
|
236 // if either of these prefs are enabled and apply, use ClearType rendering |
|
237 bool UseClearTypeForDownloadableFonts(); |
|
238 bool UseClearTypeAlways(); |
|
239 |
|
240 static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion); |
|
241 |
|
242 // returns ClearType tuning information for each display |
|
243 static void GetCleartypeParams(nsTArray<ClearTypeParameterInfo>& aParams); |
|
244 |
|
245 virtual void FontsPrefsChanged(const char *aPref); |
|
246 |
|
247 void SetupClearTypeParams(); |
|
248 |
|
249 #ifdef CAIRO_HAS_DWRITE_FONT |
|
250 IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; } |
|
251 inline bool DWriteEnabled() { return mUseDirectWrite; } |
|
252 inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } |
|
253 IDWriteTextAnalyzer *GetDWriteAnalyzer() { return mDWriteAnalyzer; } |
|
254 |
|
255 IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) |
|
256 { return mRenderingParams[aRenderMode]; } |
|
257 #else |
|
258 inline bool DWriteEnabled() { return false; } |
|
259 #endif |
|
260 void OnDeviceManagerDestroy(mozilla::layers::DeviceManagerD3D9* aDeviceManager); |
|
261 mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager(); |
|
262 IDirect3DDevice9* GetD3D9Device(); |
|
263 #ifdef CAIRO_HAS_D2D_SURFACE |
|
264 cairo_device_t *GetD2DDevice() { return mD2DDevice; } |
|
265 ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; } |
|
266 #endif |
|
267 ID3D11Device *GetD3D11Device(); |
|
268 |
|
269 static bool IsOptimus(); |
|
270 |
|
271 protected: |
|
272 RenderMode mRenderMode; |
|
273 |
|
274 int8_t mUseClearTypeForDownloadableFonts; |
|
275 int8_t mUseClearTypeAlways; |
|
276 |
|
277 private: |
|
278 void Init(); |
|
279 IDXGIAdapter1 *GetDXGIAdapter(); |
|
280 |
|
281 bool mUseDirectWrite; |
|
282 bool mUsingGDIFonts; |
|
283 |
|
284 #ifdef CAIRO_HAS_DWRITE_FONT |
|
285 nsRefPtr<IDWriteFactory> mDWriteFactory; |
|
286 nsRefPtr<IDWriteTextAnalyzer> mDWriteAnalyzer; |
|
287 nsRefPtr<IDWriteRenderingParams> mRenderingParams[TEXT_RENDERING_COUNT]; |
|
288 DWRITE_MEASURING_MODE mMeasuringMode; |
|
289 #endif |
|
290 #ifdef CAIRO_HAS_D2D_SURFACE |
|
291 cairo_device_t *mD2DDevice; |
|
292 #endif |
|
293 mozilla::RefPtr<IDXGIAdapter1> mAdapter; |
|
294 nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager; |
|
295 mozilla::RefPtr<ID3D11Device> mD3D11Device; |
|
296 bool mD3D11DeviceInitialized; |
|
297 |
|
298 virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size); |
|
299 |
|
300 // TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList |
|
301 nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts; |
|
302 }; |
|
303 |
|
304 #endif /* GFX_WINDOWS_PLATFORM_H */ |