DWriteSettings.cpp (5642B)
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/. */ 6 7 #include "DWriteSettings.h" 8 9 #include "mozilla/DataMutex.h" 10 #include "mozilla/gfx/2D.h" 11 #include "mozilla/gfx/Logging.h" 12 #include "mozilla/gfx/gfxVars.h" 13 14 using namespace mozilla; 15 using namespace mozilla::gfx; 16 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"); 28 29 static void ClearStandardRenderingParams() { 30 auto lockedParams = sStandardRenderingParams.Lock(); 31 lockedParams.ref() = nullptr; 32 } 33 34 static void ClearGDIRenderingParams() { 35 auto lockedParams = sGDIRenderingParams.Lock(); 36 lockedParams.ref() = nullptr; 37 } 38 39 static void UpdateClearTypeLevel() { 40 sClearTypeLevel = gfxVars::SystemTextClearTypeLevel(); 41 } 42 static void ClearTypeLevelVarUpdated() { 43 UpdateClearTypeLevel(); 44 ClearStandardRenderingParams(); 45 ClearGDIRenderingParams(); 46 } 47 48 static void UpdateEnhancedContrast() { 49 sEnhancedContrast = gfxVars::SystemTextEnhancedContrast(); 50 } 51 static void EnhancedContrastVarUpdated() { 52 UpdateEnhancedContrast(); 53 ClearStandardRenderingParams(); 54 } 55 56 static void UpdateGamma() { sGamma = gfxVars::SystemTextGamma(); } 57 static void GammaVarUpdated() { 58 UpdateGamma(); 59 ClearStandardRenderingParams(); 60 } 61 62 static void UpdateGDIGamma() { sGDIGamma = gfxVars::SystemGDIGamma(); } 63 static void GDIGammaVarUpdated() { 64 UpdateGDIGamma(); 65 ClearGDIRenderingParams(); 66 } 67 68 static void UpdatePixelGeometry() { 69 sPixelGeometry = 70 static_cast<DWRITE_PIXEL_GEOMETRY>(gfxVars::SystemTextPixelGeometry()); 71 Factory::SetSubpixelOrder(sPixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR 72 ? SubpixelOrder::BGR 73 : SubpixelOrder::RGB); 74 } 75 static void PixelGeometryVarUpdated() { 76 UpdatePixelGeometry(); 77 ClearStandardRenderingParams(); 78 ClearGDIRenderingParams(); 79 } 80 81 static void UpdateRenderingMode() { 82 sRenderingMode = 83 static_cast<DWRITE_RENDERING_MODE>(gfxVars::SystemTextRenderingMode()); 84 switch (sRenderingMode) { 85 case DWRITE_RENDERING_MODE_ALIASED: 86 case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC: 87 sMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC; 88 break; 89 case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL: 90 sMeasuringMode = DWRITE_MEASURING_MODE_GDI_NATURAL; 91 break; 92 default: 93 sMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; 94 break; 95 } 96 } 97 static void RenderingModeVarUpdated() { 98 UpdateRenderingMode(); 99 ClearStandardRenderingParams(); 100 } 101 102 DWriteSettings::DWriteSettings(bool aUseGDISettings) 103 : mUseGDISettings(aUseGDISettings) {} 104 105 /* static */ 106 void DWriteSettings::Initialize() { 107 UpdateClearTypeLevel(); 108 gfxVars::SetSystemTextClearTypeLevelListener(ClearTypeLevelVarUpdated); 109 110 UpdateEnhancedContrast(); 111 gfxVars::SetSystemTextEnhancedContrastListener(EnhancedContrastVarUpdated); 112 113 UpdateGamma(); 114 gfxVars::SetSystemTextGammaListener(GammaVarUpdated); 115 116 UpdateGDIGamma(); 117 gfxVars::SetSystemGDIGammaListener(GDIGammaVarUpdated); 118 119 UpdateRenderingMode(); 120 gfxVars::SetSystemTextRenderingModeListener(RenderingModeVarUpdated); 121 122 UpdatePixelGeometry(); 123 gfxVars::SetSystemTextPixelGeometryListener(PixelGeometryVarUpdated); 124 } 125 126 /* static */ 127 DWriteSettings& DWriteSettings::Get(bool aGDISettings) { 128 DWriteSettings* settings; 129 if (aGDISettings) { 130 static DWriteSettings* sGDISettings = 131 new DWriteSettings(/* aUseGDISettings */ true); 132 settings = sGDISettings; 133 } else { 134 static DWriteSettings* sStandardSettings = 135 new DWriteSettings(/* aUseGDISettings */ false); 136 settings = sStandardSettings; 137 } 138 return *settings; 139 } 140 141 Float DWriteSettings::ClearTypeLevel() { return sClearTypeLevel; } 142 143 Float DWriteSettings::EnhancedContrast() { 144 return mUseGDISettings ? 0.0f : sEnhancedContrast.load(); 145 } 146 147 Float DWriteSettings::Gamma() { return mUseGDISettings ? sGDIGamma : sGamma; } 148 149 DWRITE_PIXEL_GEOMETRY DWriteSettings::PixelGeometry() { return sPixelGeometry; } 150 151 DWRITE_RENDERING_MODE DWriteSettings::RenderingMode() { 152 return mUseGDISettings ? DWRITE_RENDERING_MODE_GDI_CLASSIC : sRenderingMode; 153 } 154 155 DWRITE_MEASURING_MODE DWriteSettings::MeasuringMode() { 156 return mUseGDISettings ? DWRITE_MEASURING_MODE_GDI_CLASSIC : sMeasuringMode; 157 } 158 159 already_AddRefed<IDWriteRenderingParams> DWriteSettings::RenderingParams() { 160 auto lockedParams = mUseGDISettings ? sGDIRenderingParams.Lock() 161 : sStandardRenderingParams.Lock(); 162 if (!lockedParams.ref()) { 163 RefPtr<IDWriteRenderingParams> params; 164 HRESULT hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( 165 Gamma(), EnhancedContrast(), ClearTypeLevel(), PixelGeometry(), 166 RenderingMode(), getter_AddRefs(params)); 167 if (SUCCEEDED(hr)) { 168 lockedParams.ref() = params.forget(); 169 } else { 170 gfxWarning() << "Failed to create DWrite custom rendering params."; 171 } 172 } 173 174 return do_AddRef(lockedParams.ref()); 175 }