Chromium Code Reviews| Index: ui/gfx/color_profile_win.cc |
| diff --git a/ui/gfx/color_profile_win.cc b/ui/gfx/color_profile_win.cc |
| index 030e8a63f019808d6778d127329421bb9aec02f8..6ffa7547eccc27dbed0cd5ada253f242d17a60f5 100644 |
| --- a/ui/gfx/color_profile_win.cc |
| +++ b/ui/gfx/color_profile_win.cc |
| @@ -4,8 +4,8 @@ |
| #include "ui/gfx/color_profile.h" |
| -#include <windows.h> |
| #include <stddef.h> |
| +#include <windows.h> |
|
Avi (use Gerrit)
2016/03/15 16:20:38
It's probably OK here, but in general leave the wi
|
| #include <map> |
| #include "base/files/file_util.h" |
| @@ -15,6 +15,8 @@ |
| namespace gfx { |
| +namespace { |
| + |
| class ColorProfileCache { |
| public: |
| // A thread-safe cache of color profiles keyed by windows device name. |
| @@ -29,9 +31,36 @@ class ColorProfileCache { |
| return true; |
| } |
| - void Insert(const std::wstring& device, const std::vector<char>& profile) { |
| - base::AutoLock lock(lock_); |
| - cache_[device] = profile; |
| + void Insert(const std::wstring& device) { |
| + std::vector<char> profile; |
| + |
| + { |
| + base::AutoLock lock(lock_); |
| + if (cache_.find(device) != cache_.end()) |
| + return; |
| + } |
| + |
| + HDC hdc = ::CreateDC(device.c_str(), NULL, NULL, NULL); |
| + DWORD path_length = MAX_PATH; |
| + WCHAR path[MAX_PATH + 1]; |
| + BOOL get_icm_result = ::GetICMProfile(hdc, &path_length, path); |
| + ::DeleteDC(hdc); |
| + if (get_icm_result) { |
| + base::FilePath file_name = base::FilePath(path).BaseName(); |
| + if (file_name != base::FilePath(L"sRGB Color Space Profile.icm")) { |
| + std::string data; |
| + if (base::ReadFileToString(base::FilePath(path), &data)) |
| + profile.assign(data.data(), data.data() + data.size()); |
| + size_t length = profile.size(); |
| + if (gfx::InvalidColorProfileLength(length)) |
| + profile.clear(); |
| + } |
| + } |
| + |
| + { |
| + base::AutoLock lock(lock_); |
| + cache_[device] = profile; |
| + } |
| } |
| bool Erase(const std::wstring& device) { |
| @@ -64,6 +93,24 @@ inline ColorProfileCache& GetColorProfileCache() { |
| return g_color_profile_cache.Get(); |
| } |
| +BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, |
| + HDC hdc, |
| + LPRECT rect, |
| + LPARAM data) { |
| + |
| + MONITORINFOEX monitor_info; |
| + monitor_info.cbSize = sizeof(MONITORINFOEX); |
| + if (::GetMonitorInfo(monitor, &monitor_info)) |
| + GetColorProfileCache().Insert(monitor_info.szDevice); |
| + return TRUE; |
| +} |
| + |
| +} // namespace |
| + |
| +void UpdateDisplayColorProfileCache() { |
| + EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback, 0); |
| +} |
| + |
| bool GetDisplayColorProfile(const gfx::Rect& bounds, |
| std::vector<char>* profile) { |
| DCHECK(profile->empty()); |
| @@ -75,49 +122,23 @@ bool GetDisplayColorProfile(const gfx::Rect& bounds, |
| MONITORINFOEX monitor; |
| monitor.cbSize = sizeof(MONITORINFOEX); |
| - CHECK(::GetMonitorInfo(handle, &monitor)); |
| - if (GetColorProfileCache().Find(monitor.szDevice, profile)) |
| - return true; |
| - |
| - HDC hdc = ::CreateDC(monitor.szDevice, NULL, NULL, NULL); |
| - DWORD path_length = MAX_PATH; |
| - WCHAR path[MAX_PATH + 1]; |
| - BOOL result = ::GetICMProfile(hdc, &path_length, path); |
| - ::DeleteDC(hdc); |
| - if (!result) |
| - return false; |
| - |
| - base::FilePath file_name = base::FilePath(path).BaseName(); |
| - if (file_name != base::FilePath(L"sRGB Color Space Profile.icm")) { |
| - std::string data; |
| - if (base::ReadFileToString(base::FilePath(path), &data)) |
| - profile->assign(data.data(), data.data() + data.size()); |
| - size_t length = profile->size(); |
| - if (gfx::InvalidColorProfileLength(length)) |
| - profile->clear(); |
| - } |
| - |
| - GetColorProfileCache().Insert(monitor.szDevice, *profile); |
| - return true; |
| + if (::GetMonitorInfo(handle, &monitor)) |
| + return GetColorProfileCache().Find(monitor.szDevice, profile); |
| + return false; |
| } |
| void ReadColorProfile(std::vector<char>* profile) { |
| - // TODO: support multiple monitors. |
| - HDC screen_dc = GetDC(NULL); |
| - DWORD path_len = MAX_PATH; |
| - WCHAR path[MAX_PATH + 1]; |
| - |
| - BOOL result = GetICMProfile(screen_dc, &path_len, path); |
| - ReleaseDC(NULL, screen_dc); |
| - if (!result) |
| + // TODO: This function should be named to reflect that it is querying the |
| + // primary monitor. |
| + POINT point = {0, 0}; |
| + HMONITOR handle = ::MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY); |
| + if (!handle) |
| return; |
| - std::string profileData; |
| - if (!base::ReadFileToString(base::FilePath(path), &profileData)) |
| - return; |
| - size_t length = profileData.size(); |
| - if (gfx::InvalidColorProfileLength(length)) |
| - return; |
| - profile->assign(profileData.data(), profileData.data() + length); |
| + |
| + MONITORINFOEX monitor; |
| + monitor.cbSize = sizeof(MONITORINFOEX); |
| + if (::GetMonitorInfo(handle, &monitor)) |
| + GetColorProfileCache().Find(monitor.szDevice, profile); |
| } |
| } // namespace gfx |