Windows: Add CefEnableHighDPISupport function and fix high-dpi scaling issues (issue #1674)

This commit is contained in:
Marshall Greenblatt
2015-08-07 16:04:03 -04:00
parent 2792d1bb12
commit 9e0d84d94a
9 changed files with 119 additions and 4 deletions

View File

@@ -1,6 +1,13 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
// Copyright 2014 The Chromium Embedded Framework Authors. Portions copyright
// 2011 the Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#include "include/base/cef_build.h"
#if defined(OS_WIN)
#include <windows.h>
#include <shellscalingapi.h>
#endif
#include "include/internal/cef_trace_event_internal.h"
#include "include/internal/cef_logging_internal.h"
@@ -10,6 +17,55 @@
#include "base/threading/platform_thread.h"
#include "base/trace_event/trace_event.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
namespace {
// Implementation from chrome/app/chrome_exe_main_win.cc.
// Win8.1 supports monitor-specific DPI scaling.
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
reinterpret_cast<SetProcessDpiAwarenessPtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDpiAwarenessInternal"));
if (set_process_dpi_awareness_func) {
HRESULT hr = set_process_dpi_awareness_func(value);
if (SUCCEEDED(hr)) {
VLOG(1) << "SetProcessDpiAwareness succeeded.";
return true;
} else if (hr == E_ACCESSDENIED) {
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
"Function called twice, or manifest was used.";
}
}
return false;
}
// This function works for Windows Vista through Win8. Win8.1 must use
// SetProcessDpiAwareness[Wrapper].
BOOL SetProcessDPIAwareWrapper() {
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
SetProcessDPIAwarePtr set_process_dpi_aware_func =
reinterpret_cast<SetProcessDPIAwarePtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDPIAware"));
return set_process_dpi_aware_func &&
set_process_dpi_aware_func();
}
void EnableHighDPISupport() {
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
SetProcessDPIAwareWrapper();
}
}
} // namespace
#endif // defined(OS_WIN)
// The contents of this file are a compilation unit that is not called by other
// functions in the the library. Consiquently MSVS will exclude it during the
// linker stage if we don't call a stub function.
@@ -343,3 +399,13 @@ CEF_EXPORT cef_platform_thread_handle_t
return base::PlatformThread::CurrentHandle().platform_handle();
#endif
}
void CefEnableHighDPISupport() {
#if defined(OS_WIN)
// We don't want to set DPI awareness on pre-Win7 because we don't support
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
EnableHighDPISupport();
#endif
}