66"""
77from __future__ import absolute_import
88import sublime
9- from .st_colormod import Color
10- from mdpopups .coloraide import util
9+ from mdpopups .st_colormod import Color
10+ from mdpopups .coloraide import algebra as alg
1111import re
1212
1313NEW_SCHEMES = int (sublime .version ()) >= 3150
1818 r'''(?x)
1919 ^(?:
2020 (brightness|saturation|hue|contrast|colorize|glow)\((-?[\d]+|[\d]*\.[\d]+)\)|
21- (sepia|grayscale|invert)
21+ (sepia|grayscale|invert|protan|deutan|tritan )
2222 )
2323 (?:@(fg|bg))?$
2424 '''
@@ -107,60 +107,78 @@ def hue(color, deg):
107107 def contrast (color , factor ):
108108 """Adjust contrast."""
109109
110- r , g , b = [util .round_half_up (util .clamp (c * 255 , 0 , 255 )) for c in util . no_nan (color . coords () )]
110+ r , g , b = [alg .round_half_up (alg .clamp (c * 255 , 0 , 255 )) for c in alg . no_nans (color [: - 1 ] )]
111111 # Algorithm can't handle any thing beyond +/-255 (or a factor from 0 - 2)
112112 # Convert factor between (-255, 255)
113- f = (util .clamp (factor , 0.0 , 2.0 ) - 1.0 ) * 255.0
113+ f = (alg .clamp (factor , 0.0 , 2.0 ) - 1.0 ) * 255.0
114114 f = (259 * (f + 255 )) / (255 * (259 - f ))
115115
116116 # Increase/decrease contrast accordingly.
117- r = util .clamp (util .round_half_up ((f * (r - 128 )) + 128 ), 0 , 255 )
118- g = util .clamp (util .round_half_up ((f * (g - 128 )) + 128 ), 0 , 255 )
119- b = util .clamp (util .round_half_up ((f * (b - 128 )) + 128 ), 0 , 255 )
120- color .red = r / 255
121- color .green = g / 255
122- color .blue = b / 255
117+ r = alg .clamp (alg .round_half_up ((f * (r - 128 )) + 128 ), 0 , 255 )
118+ g = alg .clamp (alg .round_half_up ((f * (g - 128 )) + 128 ), 0 , 255 )
119+ b = alg .clamp (alg .round_half_up ((f * (b - 128 )) + 128 ), 0 , 255 )
120+ color ['red' ] = r / 255
121+ color ['green' ] = g / 255
122+ color ['blue' ] = b / 255
123+
124+ @staticmethod
125+ def protan (color ):
126+ """Invert the color."""
127+
128+ color .filter ('protan' , in_place = True )
129+
130+ @staticmethod
131+ def deutan (color ):
132+ """Invert the color."""
133+
134+ color .filter ('deutan' , in_place = True )
135+
136+ @staticmethod
137+ def tritan (color ):
138+ """Invert the color."""
139+
140+ color .filter ('tritan' , in_place = True )
123141
124142 @staticmethod
125143 def invert (color ):
126144 """Invert the color."""
127145
128- r , g , b = [int (util .round_half_up (util .clamp (c * 255 , 0 , 255 ))) for c in util . no_nan (color . coords () )]
146+ r , g , b = [int (alg .round_half_up (alg .clamp (c * 255 , 0 , 255 ))) for c in alg . no_nans (color [: - 1 ] )]
129147 r ^= 0xFF
130148 g ^= 0xFF
131149 b ^= 0xFF
132- color . red = r / 255
133- color . green = g / 255
134- color . blue = b / 255
150+ color [ ' red' ] = r / 255
151+ color [ ' green' ] = g / 255
152+ color [ ' blue' ] = b / 255
135153
136154 @staticmethod
137155 def saturation (color , factor ):
138156 """Saturate or unsaturate the color by the given factor."""
139157
140- s = util .no_nan (color .get ('hsl.saturation' )) / 100.0
141- s = util .clamp (s + factor - 1.0 , 0.0 , 1.0 )
158+ s = alg .no_nan (color .get ('hsl.saturation' )) / 100.0
159+ s = alg .clamp (s + factor - 1.0 , 0.0 , 1.0 )
142160 color .set ('hsl.saturation' , s * 100 )
143161
144162 @staticmethod
145163 def grayscale (color ):
146164 """Convert the color with a grayscale filter."""
147165
148166 luminance = color .luminance ()
149- color . red = luminance
150- color . green = luminance
151- color . blue = luminance
167+ color [ ' red' ] = luminance
168+ color [ ' green' ] = luminance
169+ color [ ' blue' ] = luminance
152170
153171 @staticmethod
154172 def sepia (color ):
155173 """Apply a sepia filter to the color."""
156174
157- red , green , blue = util . no_nan (color . coords () )
158- r = util .clamp ((red * .393 ) + (green * .769 ) + (blue * .189 ), 0 , 1 )
159- g = util .clamp ((red * .349 ) + (green * .686 ) + (blue * .168 ), 0 , 1 )
160- b = util .clamp ((red * .272 ) + (green * .534 ) + (blue * .131 ), 0 , 1 )
161- color . red = r
162- color . green = g
163- color . blue = b
175+ red , green , blue = alg . no_nans (color [: - 1 ] )
176+ r = alg .clamp ((red * .393 ) + (green * .769 ) + (blue * .189 ), 0 , 1 )
177+ g = alg .clamp ((red * .349 ) + (green * .686 ) + (blue * .168 ), 0 , 1 )
178+ b = alg .clamp ((red * .272 ) + (green * .534 ) + (blue * .131 ), 0 , 1 )
179+ color [ ' red' ] = r
180+ color [ ' green' ] = g
181+ color [ ' blue' ] = b
164182
165183 @staticmethod
166184 def _get_overage (c ):
@@ -206,9 +224,9 @@ def brightness(cls, color, factor):
206224 Brightness is determined by perceived luminance.
207225 """
208226
209- red , green , blue = [util .round_half_up (util .clamp (c * 255 , 0 , 255 )) for c in util . no_nan (color . coords () )]
227+ red , green , blue = [alg .round_half_up (alg .clamp (c * 255 , 0 , 255 )) for c in alg . no_nans (color [: - 1 ] )]
210228 channels = ["r" , "g" , "b" ]
211- total_lumes = util .clamp (util .clamp (color .luminance (), 0 , 1 ) * 255 + (255.0 * factor ) - 255.0 , 0.0 , 255.0 )
229+ total_lumes = alg .clamp (alg .clamp (color .luminance (), 0 , 1 ) * 255 + (255.0 * factor ) - 255.0 , 0.0 , 255.0 )
212230
213231 if total_lumes == 255.0 :
214232 # white
@@ -218,7 +236,7 @@ def brightness(cls, color, factor):
218236 r , g , b = 0 , 0 , 0
219237 else :
220238 # Adjust Brightness
221- pts = (total_lumes - util .clamp (color .luminance (), 0 , 1 ) * 255 )
239+ pts = (total_lumes - alg .clamp (color .luminance (), 0 , 1 ) * 255 )
222240 slots = set (channels )
223241 components = [float (red ) + pts , float (green ) + pts , float (blue ) + pts ]
224242 count = 0
@@ -229,12 +247,12 @@ def brightness(cls, color, factor):
229247 components = list (cls ._distribute_overage (components , overage , slots ))
230248 count += 1
231249
232- r = util .clamp (util .round_half_up (components [0 ]), 0 , 255 ) / 255.0
233- g = util .clamp (util .round_half_up (components [1 ]), 0 , 255 ) / 255.0
234- b = util .clamp (util .round_half_up (components [2 ]), 0 , 255 ) / 255.0
235- color . red = r
236- color . green = g
237- color . blue = b
250+ r = alg .clamp (alg .round_half_up (components [0 ]), 0 , 255 ) / 255.0
251+ g = alg .clamp (alg .round_half_up (components [1 ]), 0 , 255 ) / 255.0
252+ b = alg .clamp (alg .round_half_up (components [2 ]), 0 , 255 ) / 255.0
253+ color [ ' red' ] = r
254+ color [ ' green' ] = g
255+ color [ ' blue' ] = b
238256
239257
240258class ColorTweaker (object ):
@@ -292,7 +310,7 @@ def _filter_colors(self, *args, **kwargs):
292310 name = f [0 ]
293311 value = f [1 ]
294312 context = f [2 ]
295- if name in ("grayscale" , "sepia" , "invert" ):
313+ if name in ("grayscale" , "sepia" , "invert" , "tritan" , "protan" , "deutan" ):
296314 if context != "bg" :
297315 self ._apply_filter (rgba_fg , name )
298316 if context != "fg" :
@@ -358,7 +376,7 @@ def get_filters(self):
358376
359377 filters = []
360378 for f in self .filters :
361- if f [0 ] in ("invert" , "grayscale" , "sepia" ):
379+ if f [0 ] in ("invert" , "grayscale" , "sepia" , "tritan" , "protan" , "deutan" ):
362380 filters .append (f [0 ])
363381 elif f [0 ] in ("hue" , "colorize" ):
364382 filters .append (f [0 ] + "(%d)" % int (f [1 ]))
@@ -416,7 +434,7 @@ def _filter_colors(self, *args, **kwargs):
416434 name = f [0 ]
417435 value = f [1 ]
418436 context = f [2 ]
419- if name in ("grayscale" , "sepia" , "invert" ):
437+ if name in ("grayscale" , "sepia" , "invert" , "tritan" , "protan" , "deutan" ):
420438 if context != "bg" :
421439 self ._apply_filter (rgba_fg , name )
422440 if context != "fg" :
@@ -516,7 +534,7 @@ def get_filters(self):
516534
517535 filters = []
518536 for f in self .filters :
519- if f [0 ] in ("invert" , "grayscale" , "sepia" ):
537+ if f [0 ] in ("invert" , "grayscale" , "sepia" , "tritan" , "protan" , "deutan" ):
520538 filters .append (f [0 ])
521539 elif f [0 ] in ("hue" , "colorize" ):
522540 filters .append (f [0 ] + "(%d)" % int (f [1 ]))
0 commit comments