1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
7 #include "DWriteSettings.h"
9 #include "mozilla/DataMutex.h"
10 #include "mozilla/gfx/2D.h"
11 #include "mozilla/gfx/Logging.h"
12 #include "mozilla/gfx/gfxVars.h"
14 using namespace mozilla
;
15 using namespace mozilla::gfx
;
17 static std::atomic
<Float
> sClearTypeLevel
{1.0f
};
18 static std::atomic
<Float
> sEnhancedContrast
{1.0f
};
19 static std::atomic
<Float
> sGamma
{2.2f
};
20 static Atomic
<DWRITE_PIXEL_GEOMETRY
> sPixelGeometry
;
21 static Atomic
<DWRITE_RENDERING_MODE
> sRenderingMode
;
22 static Atomic
<DWRITE_MEASURING_MODE
> sMeasuringMode
;
23 static std::atomic
<Float
> sGDIGamma
{1.4f
};
24 MOZ_RUNINIT StaticDataMutex
<StaticRefPtr
<IDWriteRenderingParams
>>
25 sStandardRenderingParams("StandardRenderingParams");
26 MOZ_RUNINIT StaticDataMutex
<StaticRefPtr
<IDWriteRenderingParams
>>
27 sGDIRenderingParams("GDIRenderingParams");
29 static void ClearStandardRenderingParams() {
30 auto lockedParams
= sStandardRenderingParams
.Lock();
31 lockedParams
.ref() = nullptr;
34 static void ClearGDIRenderingParams() {
35 auto lockedParams
= sGDIRenderingParams
.Lock();
36 lockedParams
.ref() = nullptr;
39 static void UpdateClearTypeLevel() {
40 sClearTypeLevel
= gfxVars::SystemTextClearTypeLevel();
42 static void ClearTypeLevelVarUpdated() {
43 UpdateClearTypeLevel();
44 ClearStandardRenderingParams();
45 ClearGDIRenderingParams();
48 static void UpdateEnhancedContrast() {
49 sEnhancedContrast
= gfxVars::SystemTextEnhancedContrast();
51 static void EnhancedContrastVarUpdated() {
52 UpdateEnhancedContrast();
53 ClearStandardRenderingParams();
56 static void UpdateGamma() { sGamma
= gfxVars::SystemTextGamma(); }
57 static void GammaVarUpdated() {
59 ClearStandardRenderingParams();
62 static void UpdateGDIGamma() { sGDIGamma
= gfxVars::SystemGDIGamma(); }
63 static void GDIGammaVarUpdated() {
65 ClearGDIRenderingParams();
68 static void UpdatePixelGeometry() {
70 static_cast<DWRITE_PIXEL_GEOMETRY
>(gfxVars::SystemTextPixelGeometry());
71 Factory::SetBGRSubpixelOrder(sPixelGeometry
== DWRITE_PIXEL_GEOMETRY_BGR
);
73 static void PixelGeometryVarUpdated() {
74 UpdatePixelGeometry();
75 ClearStandardRenderingParams();
76 ClearGDIRenderingParams();
79 static void UpdateRenderingMode() {
81 static_cast<DWRITE_RENDERING_MODE
>(gfxVars::SystemTextRenderingMode());
82 switch (sRenderingMode
) {
83 case DWRITE_RENDERING_MODE_ALIASED
:
84 case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC
:
85 sMeasuringMode
= DWRITE_MEASURING_MODE_GDI_CLASSIC
;
87 case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL
:
88 sMeasuringMode
= DWRITE_MEASURING_MODE_GDI_NATURAL
;
91 sMeasuringMode
= DWRITE_MEASURING_MODE_NATURAL
;
95 static void RenderingModeVarUpdated() {
96 UpdateRenderingMode();
97 ClearStandardRenderingParams();
100 DWriteSettings::DWriteSettings(bool aUseGDISettings
)
101 : mUseGDISettings(aUseGDISettings
) {}
104 void DWriteSettings::Initialize() {
105 UpdateClearTypeLevel();
106 gfxVars::SetSystemTextClearTypeLevelListener(ClearTypeLevelVarUpdated
);
108 UpdateEnhancedContrast();
109 gfxVars::SetSystemTextEnhancedContrastListener(EnhancedContrastVarUpdated
);
112 gfxVars::SetSystemTextGammaListener(GammaVarUpdated
);
115 gfxVars::SetSystemGDIGammaListener(GDIGammaVarUpdated
);
117 UpdateRenderingMode();
118 gfxVars::SetSystemTextRenderingModeListener(RenderingModeVarUpdated
);
120 UpdatePixelGeometry();
121 gfxVars::SetSystemTextPixelGeometryListener(PixelGeometryVarUpdated
);
125 DWriteSettings
& DWriteSettings::Get(bool aGDISettings
) {
126 DWriteSettings
* settings
;
128 static DWriteSettings
* sGDISettings
=
129 new DWriteSettings(/* aUseGDISettings */ true);
130 settings
= sGDISettings
;
132 static DWriteSettings
* sStandardSettings
=
133 new DWriteSettings(/* aUseGDISettings */ false);
134 settings
= sStandardSettings
;
139 Float
DWriteSettings::ClearTypeLevel() { return sClearTypeLevel
; }
141 Float
DWriteSettings::EnhancedContrast() {
142 return mUseGDISettings
? 0.0f
: sEnhancedContrast
.load();
145 Float
DWriteSettings::Gamma() { return mUseGDISettings
? sGDIGamma
: sGamma
; }
147 DWRITE_PIXEL_GEOMETRY
DWriteSettings::PixelGeometry() { return sPixelGeometry
; }
149 DWRITE_RENDERING_MODE
DWriteSettings::RenderingMode() {
150 return mUseGDISettings
? DWRITE_RENDERING_MODE_GDI_CLASSIC
: sRenderingMode
;
153 DWRITE_MEASURING_MODE
DWriteSettings::MeasuringMode() {
154 return mUseGDISettings
? DWRITE_MEASURING_MODE_GDI_CLASSIC
: sMeasuringMode
;
157 already_AddRefed
<IDWriteRenderingParams
> DWriteSettings::RenderingParams() {
158 auto lockedParams
= mUseGDISettings
? sGDIRenderingParams
.Lock()
159 : sStandardRenderingParams
.Lock();
160 if (!lockedParams
.ref()) {
161 RefPtr
<IDWriteRenderingParams
> params
;
162 HRESULT hr
= Factory::GetDWriteFactory()->CreateCustomRenderingParams(
163 Gamma(), EnhancedContrast(), ClearTypeLevel(), PixelGeometry(),
164 RenderingMode(), getter_AddRefs(params
));
166 lockedParams
.ref() = params
.forget();
168 gfxWarning() << "Failed to create DWrite custom rendering params.";
172 return do_AddRef(lockedParams
.ref());