Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/color_profile.h" | 5 #include "ui/gfx/color_profile.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
| 15 | 15 |
| 16 namespace gfx { | 16 namespace gfx { |
| 17 | 17 |
| 18 namespace { | |
| 19 | |
| 18 class ColorProfileCache { | 20 class ColorProfileCache { |
| 19 public: | 21 public: |
| 20 // A thread-safe cache of color profiles keyed by windows device name. | 22 // A thread-safe cache of color profiles keyed by windows device name. |
| 21 ColorProfileCache() {} | 23 ColorProfileCache() {} |
| 22 | 24 |
| 23 bool Find(const std::wstring& device, std::vector<char>* profile) { | 25 bool Find(const std::wstring& device, std::vector<char>* profile) { |
| 24 base::AutoLock lock(lock_); | 26 base::AutoLock lock(lock_); |
| 25 DeviceColorProfile::const_iterator it = cache_.find(device); | 27 DeviceColorProfile::const_iterator it = cache_.find(device); |
| 26 if (it == cache_.end()) | 28 if (it == cache_.end()) |
| 27 return false; | 29 return false; |
| 28 *profile = it->second; | 30 *profile = it->second; |
| 29 return true; | 31 return true; |
| 30 } | 32 } |
| 31 | 33 |
| 32 void Insert(const std::wstring& device, const std::vector<char>& profile) { | 34 void Insert(const std::wstring& device) { |
| 33 base::AutoLock lock(lock_); | 35 std::vector<char> profile; |
| 34 cache_[device] = profile; | 36 |
| 37 { | |
| 38 base::AutoLock lock(lock_); | |
| 39 if (cache_.find(device) != cache_.end()) | |
| 40 return; | |
| 41 } | |
| 42 | |
| 43 HDC hdc = ::CreateDC(device.c_str(), NULL, NULL, NULL); | |
| 44 DWORD path_length = MAX_PATH; | |
| 45 WCHAR path[MAX_PATH + 1]; | |
| 46 BOOL get_icm_result = ::GetICMProfile(hdc, &path_length, path); | |
| 47 ::DeleteDC(hdc); | |
| 48 if (get_icm_result) { | |
| 49 base::FilePath file_name = base::FilePath(path).BaseName(); | |
| 50 // TODO(ccameron): This should skip reading sRGB color profiles, but | |
| 51 // pre-existing behavior is to read them, and the fix for that will | |
|
Noel Gordon
2016/06/01 06:08:25
Looking at code-diff left at line 91, I see
if (f
| |
| 52 // require rebaselining several layout tests. | |
| 53 std::string data; | |
| 54 if (base::ReadFileToString(base::FilePath(path), &data)) | |
| 55 profile.assign(data.data(), data.data() + data.size()); | |
| 56 size_t length = profile.size(); | |
| 57 if (gfx::InvalidColorProfileLength(length)) | |
| 58 profile.clear(); | |
| 59 } | |
| 60 | |
| 61 { | |
| 62 base::AutoLock lock(lock_); | |
| 63 cache_[device] = profile; | |
| 64 } | |
| 35 } | 65 } |
| 36 | 66 |
| 37 bool Erase(const std::wstring& device) { | 67 bool Erase(const std::wstring& device) { |
| 38 base::AutoLock lock(lock_); | 68 base::AutoLock lock(lock_); |
| 39 DeviceColorProfile::iterator it = cache_.find(device); | 69 DeviceColorProfile::iterator it = cache_.find(device); |
| 40 if (it == cache_.end()) | 70 if (it == cache_.end()) |
| 41 return false; | 71 return false; |
| 42 cache_.erase(device); | 72 cache_.erase(device); |
| 43 return true; | 73 return true; |
| 44 } | 74 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 57 DISALLOW_COPY_AND_ASSIGN(ColorProfileCache); | 87 DISALLOW_COPY_AND_ASSIGN(ColorProfileCache); |
| 58 }; | 88 }; |
| 59 | 89 |
| 60 base::LazyInstance<ColorProfileCache>::Leaky g_color_profile_cache = | 90 base::LazyInstance<ColorProfileCache>::Leaky g_color_profile_cache = |
| 61 LAZY_INSTANCE_INITIALIZER; | 91 LAZY_INSTANCE_INITIALIZER; |
| 62 | 92 |
| 63 inline ColorProfileCache& GetColorProfileCache() { | 93 inline ColorProfileCache& GetColorProfileCache() { |
| 64 return g_color_profile_cache.Get(); | 94 return g_color_profile_cache.Get(); |
| 65 } | 95 } |
| 66 | 96 |
| 97 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, | |
| 98 HDC hdc, | |
| 99 LPRECT rect, | |
| 100 LPARAM data) { | |
| 101 | |
| 102 MONITORINFOEX monitor_info; | |
| 103 monitor_info.cbSize = sizeof(MONITORINFOEX); | |
| 104 if (::GetMonitorInfo(monitor, &monitor_info)) | |
| 105 GetColorProfileCache().Insert(monitor_info.szDevice); | |
| 106 return TRUE; | |
| 107 } | |
| 108 | |
| 109 } // namespace | |
| 110 | |
| 111 void UpdateDisplayColorProfileCache() { | |
| 112 EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback, 0); | |
| 113 } | |
| 114 | |
| 67 bool GetDisplayColorProfile(const gfx::Rect& bounds, | 115 bool GetDisplayColorProfile(const gfx::Rect& bounds, |
| 68 std::vector<char>* profile) { | 116 std::vector<char>* profile) { |
| 69 DCHECK(profile->empty()); | 117 DCHECK(profile->empty()); |
| 70 | 118 |
| 71 RECT rect = bounds.ToRECT(); | 119 RECT rect = bounds.ToRECT(); |
| 72 HMONITOR handle = ::MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); | 120 HMONITOR handle = ::MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); |
| 73 if (bounds.IsEmpty() || !handle) | 121 if (bounds.IsEmpty() || !handle) |
| 74 return false; | 122 return false; |
| 75 | 123 |
| 76 MONITORINFOEX monitor; | 124 MONITORINFOEX monitor; |
| 77 monitor.cbSize = sizeof(MONITORINFOEX); | 125 monitor.cbSize = sizeof(MONITORINFOEX); |
| 78 CHECK(::GetMonitorInfo(handle, &monitor)); | 126 if (::GetMonitorInfo(handle, &monitor)) |
| 79 if (GetColorProfileCache().Find(monitor.szDevice, profile)) | 127 return GetColorProfileCache().Find(monitor.szDevice, profile); |
| 80 return true; | 128 return false; |
| 81 | |
| 82 HDC hdc = ::CreateDC(monitor.szDevice, NULL, NULL, NULL); | |
| 83 DWORD path_length = MAX_PATH; | |
| 84 WCHAR path[MAX_PATH + 1]; | |
| 85 BOOL result = ::GetICMProfile(hdc, &path_length, path); | |
| 86 ::DeleteDC(hdc); | |
| 87 if (!result) | |
| 88 return false; | |
| 89 | |
| 90 base::FilePath file_name = base::FilePath(path).BaseName(); | |
| 91 if (file_name != base::FilePath(L"sRGB Color Space Profile.icm")) { | |
| 92 std::string data; | |
| 93 if (base::ReadFileToString(base::FilePath(path), &data)) | |
| 94 profile->assign(data.data(), data.data() + data.size()); | |
| 95 size_t length = profile->size(); | |
| 96 if (gfx::InvalidColorProfileLength(length)) | |
| 97 profile->clear(); | |
| 98 } | |
| 99 | |
| 100 GetColorProfileCache().Insert(monitor.szDevice, *profile); | |
| 101 return true; | |
| 102 } | 129 } |
| 103 | 130 |
| 104 void ReadColorProfile(std::vector<char>* profile) { | 131 void ReadColorProfile(std::vector<char>* profile) { |
| 105 // TODO: support multiple monitors. | 132 // TODO: This function should be named to reflect that it is querying the |
| 106 HDC screen_dc = GetDC(NULL); | 133 // primary monitor. |
| 107 DWORD path_len = MAX_PATH; | 134 POINT point = {0, 0}; |
| 108 WCHAR path[MAX_PATH + 1]; | 135 HMONITOR handle = ::MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY); |
| 136 if (!handle) | |
| 137 return; | |
| 109 | 138 |
| 110 BOOL result = GetICMProfile(screen_dc, &path_len, path); | 139 MONITORINFOEX monitor; |
| 111 ReleaseDC(NULL, screen_dc); | 140 monitor.cbSize = sizeof(MONITORINFOEX); |
| 112 if (!result) | 141 if (::GetMonitorInfo(handle, &monitor)) |
| 113 return; | 142 GetColorProfileCache().Find(monitor.szDevice, profile); |
| 114 std::string profileData; | |
| 115 if (!base::ReadFileToString(base::FilePath(path), &profileData)) | |
| 116 return; | |
| 117 size_t length = profileData.size(); | |
| 118 if (gfx::InvalidColorProfileLength(length)) | |
| 119 return; | |
| 120 profile->assign(profileData.data(), profileData.data() + length); | |
| 121 } | 143 } |
| 122 | 144 |
| 123 } // namespace gfx | 145 } // namespace gfx |
| OLD | NEW |