Skip to content

Commit 028c322

Browse files
committed
Allow gamut mapping method to be configurable
1 parent 2dee7bc commit 028c322

File tree

12 files changed

+47
-21
lines changed

12 files changed

+47
-21
lines changed

CHANGES.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
## 6.2.0
44

5-
- **NEW**: Upgrade ColorAide to 2.0.1.
5+
- **NEW**: Since browsers do not and may not introduce Color Level 4
6+
gamut mapping at until some future spec, make gamut mapping approach
7+
configurable. Use clipping by default to match browsers as this is
8+
likely what people expect even if it is not an ideal approach. Use
9+
`gamut_map` option to manually control the approach.
10+
- **NEW**: Upgrade ColorAide to 2.0.2.
611
- **FIX**: Fix regression where contrast logic could not adjust to a
712
given contrast due to a property access.
813

ch_mixin.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def setup_gamut_style(self):
2323
ch_settings = sublime.load_settings('color_helper.sublime-settings')
2424
self.show_out_of_gamut_preview = ch_settings.get('show_out_of_gamut_preview', True)
2525
self.gamut_space = ch_settings.get('gamut_space', 'srgb')
26+
self.gamut_map = ch_settings.get('gamut_map', 'lch-chroma')
2627
if self.gamut_space not in GAMUT_SPACES:
2728
self.gamut_space = 'srgb'
2829

@@ -34,7 +35,7 @@ def setup_image_border(self):
3435
if border_color is not None:
3536
try:
3637
border_color = self.base(border_color)
37-
border_color.fit(self.gamut_space)
38+
border_color.fit(self.gamut_space, method=self.gamut_map)
3839
except Exception:
3940
border_color = None
4041

@@ -187,15 +188,15 @@ def get_preview(self, color):
187188
if not color.in_gamut(check_space):
188189
message = 'preview out of gamut'
189190
if self.show_out_of_gamut_preview:
190-
pcolor = color.convert(self.gamut_space, fit=True)
191+
pcolor = color.convert(self.gamut_space, fit=self.gamut_map)
191192
preview1 = pcolor.clone().set('alpha', 1)
192193
preview2 = pcolor
193194
else:
194195
preview1 = self.out_of_gamut
195196
preview2 = self.out_of_gamut
196197
preview_border = self.out_of_gamut_border
197198
else:
198-
pcolor = color.convert(self.gamut_space, fit=True)
199+
pcolor = color.convert(self.gamut_space, fit=self.gamut_map)
199200
preview1 = pcolor.clone().set('alpha', 1)
200201
preview2 = pcolor
201202

ch_panel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def color_picker(self, color):
245245

246246
if self.os_color_picker:
247247
self.view.hide_popup()
248-
new_color = native_picker(self.base(color).convert("srgb", fit=True))
248+
new_color = native_picker(self.base(color).convert("srgb", fit=self.gamut_map))
249249
if new_color is not None:
250250
sublime.set_timeout(
251251
lambda c=new_color.to_string(**util.COLOR_FULL_PREC): self.view.run_command(

ch_picker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def setup(self, color, mode, controls, on_done, on_cancel):
6969
self.setup_controls(controls)
7070
color.convert(self.mode, in_place=True)
7171
if not color.in_gamut():
72-
color.fit()
72+
color.fit(method=self.gamut_map)
7373
else:
7474
color.clip()
7575
# Ensure hue is between 0 - 360.

ch_preview.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ def setup_gamut_options(self):
271271

272272
self.show_out_of_gamut_preview = ch_settings.get('show_out_of_gamut_preview', True)
273273
self.gamut_space = ch_settings.get('gamut_space', 'srgb')
274+
self.gamut_map = ch_settings.get('gamut_map', 'lch-chroma')
274275
if self.gamut_space not in util.GAMUT_SPACES:
275276
self.gamut_space = 'srgb'
276277
self.out_of_gamut = self.base("transparent").convert(self.gamut_space)
@@ -423,7 +424,7 @@ def do_search(self, force=False):
423424
mdpopups.scope2style(self.view, self.view.scope_name(pt))['background']
424425
).convert("hsl")
425426
hsl['lightness'] = hsl['lightness'] + (0.3 if hsl.luminance() < 0.5 else -0.3)
426-
preview_border = hsl.convert(self.gamut_space, fit=True).set('alpha', 1)
427+
preview_border = hsl.convert(self.gamut_space, fit=self.gamut_map).set('alpha', 1)
427428

428429
color = self.base(obj.color)
429430
title = ''
@@ -434,15 +435,15 @@ def do_search(self, force=False):
434435
if not color.in_gamut(check_space):
435436
title = ' title="Preview out of gamut"'
436437
if self.show_out_of_gamut_preview:
437-
pcolor = color.convert(self.gamut_space, fit=True)
438+
pcolor = color.convert(self.gamut_space, fit=self.gamut_map)
438439
preview1 = pcolor.clone().set('alpha', 1)
439440
preview2 = pcolor
440441
else:
441442
preview1 = self.out_of_gamut
442443
preview2 = self.out_of_gamut
443444
preview_border = self.out_of_gamut_border
444445
else:
445-
pcolor = color.convert(self.gamut_space, fit=True)
446+
pcolor = color.convert(self.gamut_space, fit=self.gamut_map)
446447
preview1 = pcolor.clone().set('alpha', 1)
447448
preview2 = pcolor
448449

ch_tool_blend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ def preview(self, text):
185185
else:
186186
check_space = self.gamut_space
187187
if not pcolor.in_gamut(check_space):
188-
pcolor.fit(self.gamut_space)
188+
pcolor.fit(self.gamut_space, method=self.gamut_map)
189189
message = '<br><em style="font-size: 0.9em;">* preview out of gamut</em>'
190190
color_string = "<strong>Gamut Mapped</strong>: {}<br>".format(pcolor.to_string())
191-
pcolor.convert(self.gamut_space, fit=True, in_place=True)
191+
pcolor.convert(self.gamut_space, fit=self.gamut_map, in_place=True)
192192
color_string += "<strong>Color</strong>: {}".format(color.to_string(**util.DEFAULT))
193193
preview = pcolor.clone().set('alpha', 1)
194194
preview_alpha = pcolor

ch_tool_colormod.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def preview(self, text):
106106
check_space = self.gamut_space
107107
if not pcolor.in_gamut(check_space):
108108
message = '<br><em style="font-size: 0.9em;">* preview out of gamut</em>'
109-
pcolor.convert(self.gamut_space, fit=True, in_place=True)
109+
pcolor.convert(self.gamut_space, fit=self.gamut_map, in_place=True)
110110
preview = pcolor.clone().set('alpha', 1)
111111
preview_alpha = pcolor
112112
preview_border = self.default_border

ch_tool_contrast.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def parse_color(base, string, start=0, second=False):
8383
return color, ratio, more
8484

8585

86-
def evaluate(base, string):
86+
def evaluate(base, string, gamut_map):
8787
"""Evaluate color."""
8888

8989
colors = []
@@ -114,11 +114,11 @@ def evaluate(base, string):
114114

115115
# Package up the color, or the two reference colors along with the mixed.
116116
if first:
117-
colors.append(first.fit('srgb'))
117+
colors.append(first.fit('srgb', method=gamut_map))
118118
if second:
119119
if second[-1] < 1.0:
120120
second[-1] = 1.0
121-
colors.append(second.fit('srgb'))
121+
colors.append(second.fit('srgb', method=gamut_map))
122122
if ratio:
123123
if first[-1] < 1.0:
124124
first = first.compose(second, space="srgb", out_space=first.space())
@@ -193,7 +193,7 @@ def preview(self, text):
193193
style = self.get_html_style()
194194

195195
try:
196-
colors = evaluate(self.base, text)
196+
colors = evaluate(self.base, text, self.gamut_map)
197197
html = mdpopups.md2html(self.view, DEF_RATIO.format(style))
198198
if len(colors) >= 3:
199199
lum2 = colors[1].luminance()

ch_tool_diff.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def evaluate(base, string):
112112
if method == 'euclidean':
113113
delta = 'Distance: {}'.format(colors[0].distance(colors[1]))
114114
else:
115-
delta = 'Delta E {}: {}'.format(method, colors[0].delta_e(colors[1].to_string(), method=method))
115+
delta = 'Delta E {}: {}'.format(method, colors[0].delta_e(colors[1], method=method))
116116

117117
except Exception:
118118
delta = 'Delta E 2000: 0'
@@ -186,10 +186,10 @@ def preview(self, text):
186186
else:
187187
check_space = self.gamut_space
188188
if not orig.in_gamut(check_space):
189-
orig.fit(self.gamut_space)
189+
orig.fit(self.gamut_space, method=self.gamut_map)
190190
message = '<br><em style="font-size: 0.9em;">* preview out of gamut</em>'
191191
color_string = "<strong>Gamut Mapped</strong>: {}<br>".format(orig.to_string())
192-
orig.convert(self.gamut_space, fit=True, in_place=True)
192+
orig.convert(self.gamut_space, fit=self.gamut_map, in_place=True)
193193
color_string += "<strong>Color</strong>: {}".format(color.to_string(**util.DEFAULT))
194194
preview = orig.clone().set('alpha', 1)
195195
preview_alpha = orig

ch_tool_edit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ def preview(self, text):
222222
else:
223223
check_space = self.gamut_space
224224
if not pcolor.in_gamut(check_space):
225-
pcolor.fit(self.gamut_space)
225+
pcolor.fit(self.gamut_space, method=self.gamut_map)
226226
message = '<br><em style="font-size: 0.9em;">* preview out of gamut</em>'
227227
color_string = "<strong>Gamut Mapped</strong>: {}<br>".format(pcolor.to_string())
228-
pcolor.convert(self.gamut_space, fit=True, in_place=True)
228+
pcolor.convert(self.gamut_space, fit=self.gamut_map, in_place=True)
229229
color_string += "<strong>Color</strong>: {}".format(color.to_string(**util.DEFAULT))
230230
preview = pcolor.clone().set('alpha', 1)
231231
preview_alpha = pcolor

0 commit comments

Comments
 (0)