chromium/ui/gfx/font_render_params_win_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/font_render_params.h"

#include <limits>

#include "base/check_op.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_reg_util_win.h"
#include "skia/ext/legacy_display_globals.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/font_util_win.h"

namespace gfx {

class FontRenderParamsTest : public testing::Test {
 public:
  FontRenderParamsTest() { ClearFontRenderParamsCacheForTest(); }

  FontRenderParamsTest(const FontRenderParamsTest&) = delete;
  FontRenderParamsTest& operator=(const FontRenderParamsTest&) = delete;

  ~FontRenderParamsTest() override {}

 protected:
  registry_util::RegistryOverrideManager registry_override_manager_;
};

namespace {
// The ranges returned from `IDWriteRenderingParams` differ from the
// registry settings - contrast has a 100x multiplier and gamma has a 1000x
// multiplier.
constexpr float kContrastMultiplier = 100;
constexpr float kGammaMultiplier = 1000;
}  // namespace

TEST_F(FontRenderParamsTest, SystemFontSettingsDisabled) {
  // Ensure that without the feature enabled, the values of `FontRenderParams`
  // match Skia default values.
  FontRenderParams params =
      GetFontRenderParams(FontRenderParamsQuery(), nullptr);
  EXPECT_EQ(params.text_contrast, SK_GAMMA_CONTRAST);
  EXPECT_EQ(params.text_gamma, SK_GAMMA_EXPONENT);
}

TEST_F(FontRenderParamsTest, DefaultRegistryState) {
  // Ensure that with the feature enabled, the values of `FontRenderParams`
  // match the associated registry key values.
  base::test::ScopedFeatureList scoped_features(
      features::kUseGammaContrastRegistrySettings);

  FontRenderParams params =
      GetFontRenderParams(FontRenderParamsQuery(), nullptr);

  base::win::RegKey key = FontUtilWin::GetTextSettingsRegistryKey();
  if (key.Valid()) {
    DWORD contrast;
    ASSERT_EQ(key.ReadValueDW(L"EnhancedContrastLevel", &contrast),
              ERROR_SUCCESS);
    DWORD gamma;
    ASSERT_EQ(key.ReadValueDW(L"GammaLevel", &gamma), ERROR_SUCCESS);

    // Registry values are unbounded, however our code will clamp values to be
    // within Skia's expected range, so we must clamp expected values to match.
    // Handle the exclusive value by subtracting epsilon.
    EXPECT_FLOAT_EQ(params.text_contrast * kContrastMultiplier,
                    FontUtilWin::ClampContrast(contrast));
    EXPECT_FLOAT_EQ(params.text_gamma * kGammaMultiplier,
                    FontUtilWin::ClampGamma(contrast));
  } else {
    // If the registry keys aren't set, we should be using default Skia values
    // for contrast and gamma.
    EXPECT_FLOAT_EQ(params.text_contrast, SK_GAMMA_CONTRAST);
    EXPECT_FLOAT_EQ(params.text_gamma, SK_GAMMA_EXPONENT);
  }

  // Values from `LegacyDisplayGlobals` should match `FontRenderParams`.
  SkSurfaceProps surface_props =
      skia::LegacyDisplayGlobals::GetSkSurfaceProps();
  EXPECT_EQ(surface_props.textContrast(), params.text_contrast);
  EXPECT_EQ(surface_props.textGamma(), params.text_gamma);
}

TEST_F(FontRenderParamsTest, OverrideRegistryValues) {
  // Ensure that the values returned from `GetContrastFromRegistry` and
  // `GetGammaFromRegistry` reflect the state of the registry when
  // `kUseGammaContrastRegistrySettings` is enabled.
  base::test::ScopedFeatureList scoped_features(
      features::kUseGammaContrastRegistrySettings);

  // Override the registry to maintain test machine state.
  ASSERT_NO_FATAL_FAILURE(
      registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));

  base::win::RegKey key = FontUtilWin::GetTextSettingsRegistryKey(KEY_WRITE);

  if (key.Valid()) {
    // Write non-default values for contrast and gamma.
    DWORD contrast = 75;
    ASSERT_EQ(key.WriteValue(L"EnhancedContrastLevel", contrast),
              ERROR_SUCCESS);
    DWORD gamma = 1900;
    ASSERT_EQ(key.WriteValue(L"GammaLevel", gamma), ERROR_SUCCESS);
    key.Close();

    // Verify that the contrast and gamma getters return non-defaults above.
    EXPECT_FLOAT_EQ(
        FontUtilWin::GetContrastFromRegistry() * kContrastMultiplier, contrast);
    EXPECT_FLOAT_EQ(FontUtilWin::GetGammaFromRegistry() * kGammaMultiplier,
                    gamma);
  }
}

TEST_F(FontRenderParamsTest, OverrideRegistryValuesAndIncreaseContrast) {
  // Ensure that registry values have precedence over the increased contrast
  // flag.
  base::test::ScopedFeatureList scoped_features;
  scoped_features.InitWithFeatures(
      {features::kIncreaseWindowsTextContrast,
       features::kUseGammaContrastRegistrySettings},
      {});

  // Override the registry to maintain test machine state.
  ASSERT_NO_FATAL_FAILURE(
      registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));

  base::win::RegKey key = FontUtilWin::GetTextSettingsRegistryKey(KEY_WRITE);

  if (key.Valid()) {
    // Write non-default values for contrast and gamma.
    DWORD contrast = 75;
    ASSERT_EQ(key.WriteValue(L"EnhancedContrastLevel", contrast),
              ERROR_SUCCESS);
    DWORD gamma = 1900;
    ASSERT_EQ(key.WriteValue(L"GammaLevel", gamma), ERROR_SUCCESS);
    key.Close();

    // Verify that the contrast and gamma getters return non-defaults above.
    EXPECT_FLOAT_EQ(
        FontUtilWin::GetContrastFromRegistry() * kContrastMultiplier, contrast);
    EXPECT_FLOAT_EQ(FontUtilWin::GetGammaFromRegistry() * kGammaMultiplier,
                    gamma);
  }
}

TEST_F(FontRenderParamsTest, TextGammaContrast) {
  EXPECT_EQ(FontUtilWin::TextGammaContrast(), SK_GAMMA_CONTRAST);
}

TEST_F(FontRenderParamsTest, IncreasedContrast) {
  base::test::ScopedFeatureList scoped_features(
      features::kIncreaseWindowsTextContrast);
  EXPECT_EQ(FontUtilWin::TextGammaContrast(), 1.0f);
}

}  // namespace gfx