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
This commit is contained in:
Bob Owen 2021-08-05 09:13:10 +00:00
parent b81850a8d7
commit 700da072c4
4 changed files with 218 additions and 0 deletions

173
gfx/2d/DWriteSettings.cpp Normal file
View File

@ -0,0 +1,173 @@
/* -*- 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());
}

41
gfx/2d/DWriteSettings.h Normal file
View File

@ -0,0 +1,41 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_2D_DWRITESETTINGS_H_
#define MOZILLA_GFX_2D_DWRITESETTINGS_H_
#include <dwrite.h>
#include "mozilla/AlreadyAddRefed.h"
#include "Types.h"
namespace mozilla {
namespace gfx {
class DWriteSettings final {
public:
static void Initialize();
static DWriteSettings& Get(bool aGDISettings);
Float ClearTypeLevel();
Float EnhancedContrast();
Float Gamma();
DWRITE_PIXEL_GEOMETRY PixelGeometry();
DWRITE_RENDERING_MODE RenderingMode();
DWRITE_MEASURING_MODE MeasuringMode();
already_AddRefed<IDWriteRenderingParams> RenderingParams();
private:
explicit DWriteSettings(bool aUseGDISettings);
const bool mUseGDISettings;
};
} // namespace gfx
} // namespace mozilla
#endif // MOZILLA_GFX_2D_DWRITESETTINGS_H_

View File

@ -76,12 +76,14 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
EXPORTS.mozilla.gfx += [
"dw-extra.h",
"DWriteSettings.h",
"UnscaledFontDWrite.h",
"UnscaledFontGDI.h",
]
SOURCES += [
"ConicGradientEffectD2D1.cpp",
"DrawTargetD2D1.cpp",
"DWriteSettings.cpp",
"ExtendInputEffectD2D1.cpp",
"FilterNodeD2D1.cpp",
"NativeFontResourceDWrite.cpp",

View File

@ -10,6 +10,7 @@
#include "gfxContext.h"
#include "gfxTextRun.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DWriteSettings.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/Preferences.h"
@ -103,6 +104,7 @@ bool gfxDWriteFont::InitDWriteSupport() {
if (XRE_IsParentProcess()) {
UpdateSystemTextVars();
}
DWriteSettings::Initialize();
return true;
}