gecko-dev/gfx/2d/DWriteSettings.cpp
Bob Owen 700da072c4 Bug 1698946 p2: Add DWriteSettings to be used to retrieve font settings. r=jfkthame
This provides settings, which are populated from gfxVars retrieved in the
parent, so that they can be used in all processes.
IDWriteRenderingParams are created lazily, so that we don't try and create them
in processes that have win32k locked down where the API calls will fail.

Differential Revision: https://phabricator.services.mozilla.com/D120597
2021-08-05 09:13:10 +00:00

174 lines
5.4 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "DWriteSettings.h"
#include "mozilla/DataMutex.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/gfxVars.h"
using namespace mozilla;
using namespace mozilla::gfx;
static std::atomic<Float> sClearTypeLevel{1.0f};
static std::atomic<Float> sEnhancedContrast{1.0f};
static std::atomic<Float> sGamma{2.2f};
static Atomic<DWRITE_PIXEL_GEOMETRY> sPixelGeometry;
static Atomic<DWRITE_RENDERING_MODE> sRenderingMode;
static Atomic<DWRITE_MEASURING_MODE> sMeasuringMode;
static std::atomic<Float> sGDIGamma{1.4f};
StaticDataMutex<StaticRefPtr<IDWriteRenderingParams>> sStandardRenderingParams(
"StandardRenderingParams");
StaticDataMutex<StaticRefPtr<IDWriteRenderingParams>> sGDIRenderingParams(
"GDIRenderingParams");
static void ClearStandardRenderingParams() {
auto lockedParams = sStandardRenderingParams.Lock();
lockedParams.ref() = nullptr;
}
static void ClearGDIRenderingParams() {
auto lockedParams = sGDIRenderingParams.Lock();
lockedParams.ref() = nullptr;
}
static void UpdateClearTypeLevel() {
sClearTypeLevel = gfxVars::SystemTextClearTypeLevel();
}
static void ClearTypeLevelVarUpdated() {
UpdateClearTypeLevel();
ClearStandardRenderingParams();
ClearGDIRenderingParams();
}
static void UpdateEnhancedContrast() {
sEnhancedContrast = gfxVars::SystemTextEnhancedContrast();
}
static void EnhancedContrastVarUpdated() {
UpdateEnhancedContrast();
ClearStandardRenderingParams();
}
static void UpdateGamma() { sGamma = gfxVars::SystemTextGamma(); }
static void GammaVarUpdated() {
UpdateGamma();
ClearStandardRenderingParams();
}
static void UpdateGDIGamma() { sGDIGamma = gfxVars::SystemGDIGamma(); }
static void GDIGammaVarUpdated() {
UpdateGDIGamma();
ClearGDIRenderingParams();
}
static void UpdatePixelGeometry() {
sPixelGeometry =
static_cast<DWRITE_PIXEL_GEOMETRY>(gfxVars::SystemTextPixelGeometry());
Factory::SetBGRSubpixelOrder(sPixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR);
}
static void PixelGeometryVarUpdated() {
UpdatePixelGeometry();
ClearStandardRenderingParams();
ClearGDIRenderingParams();
}
static void UpdateRenderingMode() {
sRenderingMode =
static_cast<DWRITE_RENDERING_MODE>(gfxVars::SystemTextRenderingMode());
switch (sRenderingMode) {
case DWRITE_RENDERING_MODE_ALIASED:
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC:
sMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
break;
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL:
sMeasuringMode = DWRITE_MEASURING_MODE_GDI_NATURAL;
break;
default:
sMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
break;
}
}
static void RenderingModeVarUpdated() {
UpdateRenderingMode();
ClearStandardRenderingParams();
}
DWriteSettings::DWriteSettings(bool aUseGDISettings)
: mUseGDISettings(aUseGDISettings) {}
/* static */
void DWriteSettings::Initialize() {
UpdateClearTypeLevel();
gfxVars::SetSystemTextClearTypeLevelListener(ClearTypeLevelVarUpdated);
UpdateEnhancedContrast();
gfxVars::SetSystemTextEnhancedContrastListener(EnhancedContrastVarUpdated);
UpdateGamma();
gfxVars::SetSystemTextGammaListener(GammaVarUpdated);
UpdateGDIGamma();
gfxVars::SetSystemGDIGammaListener(GDIGammaVarUpdated);
UpdateRenderingMode();
gfxVars::SetSystemTextRenderingModeListener(RenderingModeVarUpdated);
UpdatePixelGeometry();
gfxVars::SetSystemTextPixelGeometryListener(PixelGeometryVarUpdated);
}
/* static */
DWriteSettings& DWriteSettings::Get(bool aGDISettings) {
DWriteSettings* settings;
if (aGDISettings) {
static DWriteSettings* sGDISettings =
new DWriteSettings(/* aUseGDISettings */ true);
settings = sGDISettings;
} else {
static DWriteSettings* sStandardSettings =
new DWriteSettings(/* aUseGDISettings */ false);
settings = sStandardSettings;
}
return *settings;
}
Float DWriteSettings::ClearTypeLevel() { return sClearTypeLevel; }
Float DWriteSettings::EnhancedContrast() {
return mUseGDISettings ? 0.0f : sEnhancedContrast.load();
}
Float DWriteSettings::Gamma() { return mUseGDISettings ? sGDIGamma : sGamma; }
DWRITE_PIXEL_GEOMETRY DWriteSettings::PixelGeometry() { return sPixelGeometry; }
DWRITE_RENDERING_MODE DWriteSettings::RenderingMode() {
return mUseGDISettings ? DWRITE_RENDERING_MODE_GDI_CLASSIC : sRenderingMode;
}
DWRITE_MEASURING_MODE DWriteSettings::MeasuringMode() {
return mUseGDISettings ? DWRITE_MEASURING_MODE_GDI_CLASSIC : sMeasuringMode;
}
already_AddRefed<IDWriteRenderingParams> DWriteSettings::RenderingParams() {
auto lockedParams = mUseGDISettings ? sGDIRenderingParams.Lock()
: sStandardRenderingParams.Lock();
if (!lockedParams.ref()) {
RefPtr<IDWriteRenderingParams> params;
HRESULT hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams(
Gamma(), EnhancedContrast(), ClearTypeLevel(), PixelGeometry(),
RenderingMode(), getter_AddRefs(params));
if (SUCCEEDED(hr)) {
lockedParams.ref() = params.forget();
} else {
gfxWarning() << "Failed to create DWrite custom rendering params.";
}
}
return do_AddRef(lockedParams.ref());
}