Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
system.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 *
7 * Copyright (C) 2018 Authors
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10
11#include "system.h"
12
13#include <glibmm.h> // home-dir and filename building
14#include <iomanip>
15
16#include "io/resource.h"
17#include "profile.h"
18#include "transform.h"
19
20// clang-format off
21#ifdef _WIN32
22#undef NOGDI
23#include <windows.h>
24#include <icm.h>
25#endif
26// clang-format on
27
28namespace Inkscape::Colors::CMS {
29
31{
33 _prefs_observer = prefs->createObserver("/options/displayprofile", [this]() {
34 _display_profile.reset();
35 _display_transform.reset();
36 });
37}
38
43{
44 _profiles.clear(); // Allows us to refresh list if necessary.
45
46 // Get list of all possible file directories, with flag if they are "home" directories or not.
47 // Look for icc files in specified directories.
48 for (auto const &directory_path : getDirectoryPaths()) {
50 for (auto &&filename : get_filenames(directory_path.first, {".icc", ".icm"})) {
51 // Check if files are ICC files and extract out basic information, add to list.
52 if (!Profile::isIccFile(filename)) {
53 g_warning("System::load_profiles: '%s' is not an ICC file!", filename.c_str());
54 continue;
55 }
56
57 auto profile = Profile::create_from_uri(std::move(filename), directory_path.second);
58
59 for (auto const &other : _profiles) {
60 if (other->getName() == profile->getName() && other->getId() != profile->getId()) {
61 std::cerr << "System::load_profiles: Different ICC profile with duplicate name: "
62 << profile->getName() << ":" << std::endl;
63 std::cerr << " " << profile->getPath() << " (" << profile->getId() << ")" << std::endl;
64 std::cerr << " " << other->getPath() << " (" << other->getId() << ")" << std::endl;
65 return;
66 }
67 }
68 _profiles.emplace_back(std::move(profile));
69 }
70 }
71}
72
74{
76
77 // First try user's local directory.
78 paths.emplace_back(Glib::build_filename(Glib::get_user_data_dir(), "color", "icc"), true);
79
80 // See
81 // https://github.com/hughsie/colord/blob/fe10f76536bb27614ced04e0ff944dc6fb4625c0/lib/colord/cd-icc-store.c#L590
82
83 // User store
84 paths.emplace_back(Glib::build_filename(Glib::get_user_data_dir(), "icc"), true);
85 paths.emplace_back(Glib::build_filename(Glib::get_home_dir(), ".color", "icc"), true);
86
87 // System store
88 paths.emplace_back("/var/lib/color/icc", false);
89 paths.emplace_back("/var/lib/colord/icc", false);
90
91 auto data_directories = Glib::get_system_data_dirs();
92 for (auto const &data_directory : data_directories) {
93 paths.emplace_back(Glib::build_filename(data_directory, "color", "icc"), false);
94 }
95
96#ifdef __APPLE__
97 paths.emplace_back("/System/Library/ColorSync/Profiles", false);
98 paths.emplace_back("/Library/ColorSync/Profiles", false);
99
100 paths.emplace_back(Glib::build_filename(Glib::get_home_dir(), "Library", "ColorSync", "Profiles"), true);
101#endif // __APPLE__
102
103#ifdef _WIN32
104 wchar_t pathBuf[MAX_PATH + 1];
105 pathBuf[0] = 0;
106 DWORD pathSize = sizeof(pathBuf);
107 g_assert(sizeof(wchar_t) == sizeof(gunichar2));
108 if (GetColorDirectoryW(NULL, pathBuf, &pathSize)) {
109 auto utf8Path = g_utf16_to_utf8((gunichar2 *)(&pathBuf[0]), -1, NULL, NULL, NULL);
110 if (!g_utf8_validate(utf8Path, -1, NULL)) {
111 g_warning("GetColorDirectoryW() resulted in invalid UTF-8");
112 } else {
113 paths.emplace_back(utf8Path, false);
114 }
115 g_free(utf8Path);
116 }
117#endif // _WIN32
118
119 return paths;
120}
121
126{
127 if (_paths.empty()) {
129 }
130 return _paths;
131}
132
137{
138 _paths.clear();
139}
140
144void System::addDirectoryPath(std::string path, bool is_user)
145{
146 _paths.emplace_back(std::move(path), is_user);
147}
148
152std::vector<std::shared_ptr<Profile>> System::getProfiles() const
153{
154 auto result = _profiles; // copy
155 std::sort(result.begin(), result.end(), Profile::sortByName);
156 return result;
157}
158
162const std::shared_ptr<Profile> &System::getDisplayProfile(bool &updated)
163{
165 std::string uri = prefs->getString("/options/displayprofile/uri");
166
167 if (!uri.empty() && (!_display_profile || _display_profile->getPath() != uri)) {
168 auto profile = Profile::create_from_uri(uri, false);
169 if (!profile->isForDisplay()) {
170 g_warning("System::get_display_profile: Not a display (display) profile: %s", uri.c_str());
171 } else {
172 updated = true;
173 _display_profile = profile;
174 }
175 }
176 return _display_profile;
177}
178
182std::vector<std::shared_ptr<Profile>> System::getDisplayProfiles() const
183{
184 std::vector<std::shared_ptr<Profile>> result;
185 result.reserve(_profiles.size());
186
187 for (auto const &profile : _profiles) {
188 if (profile->isForDisplay()) {
189 result.push_back(profile);
190 }
191 }
192 std::sort(result.begin(), result.end(), Profile::sortByName);
193 return result;
194}
195
199std::vector<std::shared_ptr<Profile>> System::getOutputProfiles() const
200{
201 std::vector<std::shared_ptr<Profile>> result;
202 result.reserve(_profiles.size());
203
204 for (auto const &profile : _profiles) {
205 if (profile->getProfileClass() == cmsSigOutputClass) {
206 result.push_back(profile);
207 }
208 }
209 std::sort(result.begin(), result.end(), Profile::sortByName);
210 return result;
211}
212
221const std::shared_ptr<Profile> &System::getProfile(std::string const &name) const
222{
223 for (auto const &profile : _profiles) {
224 if (name == profile->getName() || name == profile->getId() || name == profile->getPath()) {
225 return profile;
226 }
227 }
228 static std::shared_ptr<Profile> not_found;
229 return not_found;
230}
231
240const std::shared_ptr<Transform> &System::getDisplayTransform()
241{
242 bool need_to_update = false;
243
245 bool display = prefs->getIntLimited("/options/displayprofile/enabled", false);
246 int display_intent = prefs->getIntLimited("/options/displayprofile/intent", 0, 0, 3);
247
248 if (_display != display || _display_intent != display_intent) {
249 need_to_update = true;
250 _display = display;
251 _display_intent = display_intent;
252 }
253
254 auto display_profile = display ? getDisplayProfile(need_to_update) : nullptr;
255
256 if (need_to_update) {
257 if (display_profile) {
259 } else {
260 _display_transform = nullptr;
261 }
262 }
263 return _display_transform;
264}
265
266} // namespace Inkscape::Colors::CMS
267
268/*
269 Local Variables:
270 mode:c++
271 c-file-style:"stroustrup"
272 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
273 indent-tabs-mode:nil
274 fill-column:99
275 End:
276*/
277// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
@ not_found
Definition LivarotDefs.h:43
static bool isIccFile(std::string const &filepath)
Definition profile.cpp:172
static bool sortByName(std::shared_ptr< Profile > const &p1, std::shared_ptr< Profile > const &p2)
Definition profile.h:28
static std::shared_ptr< Profile > create_srgb()
Construct the default lcms sRGB color profile and return.
Definition profile.cpp:58
static std::shared_ptr< Profile > create_from_uri(std::string path, bool in_home=false)
Construct a color profile object from a uri.
Definition profile.cpp:38
Inkscape::PrefObserver _prefs_observer
Definition system.h:75
void addDirectoryPath(std::string path, bool is_user)
Replace all generated profile paths with this single path, useful for testing.
Definition system.cpp:144
const std::shared_ptr< Profile > & getProfile(std::string const &name) const
Return the profile object which is matched by the given name, id or path.
Definition system.cpp:221
void clearDirectoryPaths()
Remove all directory paths that might have been generated (useful for refreshing)
Definition system.cpp:136
std::vector< std::shared_ptr< Profile > > getDisplayProfiles() const
Returns a list of profiles that can apply to the display (display), sorted by their internal names.
Definition system.cpp:182
std::vector< std::shared_ptr< Profile > > getOutputProfiles() const
Return vector of profiles which can be used for cms output.
Definition system.cpp:199
std::vector< std::shared_ptr< Profile > > getProfiles() const
Returns a list of profiles sorted by their internal names.
Definition system.cpp:152
const std::shared_ptr< Profile > & getDisplayProfile(bool &updated)
Get the user set display profile, if set.
Definition system.cpp:162
std::shared_ptr< Profile > _display_profile
Definition system.h:70
DirPaths const & getDirectoryPaths()
Create list of all directories where ICC profiles are expected to be found.
Definition system.cpp:125
const std::shared_ptr< Transform > & getDisplayTransform()
Get the color managed trasform for the screen.
Definition system.cpp:240
std::vector< std::shared_ptr< Profile > > _profiles
Definition system.h:64
std::shared_ptr< Transform > _display_transform
Definition system.h:71
void refreshProfiles()
Search for system ICC profile files and add them to list.
Definition system.cpp:42
static std::shared_ptr< Transform > const create_for_cairo(std::shared_ptr< Profile > const &from, std::shared_ptr< Profile > const &to, std::shared_ptr< Profile > const &proof=nullptr, RenderingIntent proof_intent=RenderingIntent::AUTO, bool with_gamut_warn=false)
Construct a transformation suitable for display conversion in a cairo buffer.
Definition transform.cpp:38
Preference storage class.
Definition preferences.h:66
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
static Preferences * get()
Access the singleton Preferences object.
std::unique_ptr< PreferencesObserver > createObserver(Glib::ustring path, std::function< void(const Preferences::Entry &new_value)> callback)
Create an observer watching preference 'path' and calling provided function when preference changes.
int getIntLimited(Glib::ustring const &pref_path, int def=0, int min=INT_MIN, int max=INT_MAX)
Retrieve a limited integer.
std::vector< std::pair< std::string, bool > > DirPaths
Definition system.h:21
Css & result
vector< vector< Point > > paths
Definition metro.cpp:36
static DirPaths get_directory_paths()
Definition system.cpp:73
std::vector< std::string > get_filenames(Type type, std::vector< const char * > const &extensions, std::vector< const char * > const &exclusions)
Definition resource.cpp:267
Authors: see git history.
Inkscape::IO::Resource - simple resource API.
Glib::ustring name
Definition toolbars.cpp:55