feat(SublimeText2.EditorPackages): cache packages
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
'''
|
||||
RGBA
|
||||
Licensed under MIT
|
||||
Copyright (c) 2012 Isaac Muse <isaacmuse@gmail.com>
|
||||
'''
|
||||
|
||||
import re
|
||||
from colorsys import rgb_to_hls, hls_to_rgb, rgb_to_hsv, hsv_to_rgb
|
||||
|
||||
RGB_CHANNEL_SCALE = 1.0 / 255.0
|
||||
HUE_SCALE = 1.0 / 360.0
|
||||
|
||||
|
||||
def clamp(value, mn, mx):
|
||||
return max(min(value, mx), mn)
|
||||
|
||||
|
||||
class RGBA(object):
|
||||
r = None
|
||||
g = None
|
||||
b = None
|
||||
a = None
|
||||
color_pattern = re.compile(r"^#(?:([A-Fa-f\d]{6})([A-Fa-f\d]{2})?|([A-Fa-f\d]{3}))")
|
||||
|
||||
def __init__(self, s=None):
|
||||
if s is None:
|
||||
s = "#000000FF"
|
||||
self.r, self.g, self.b, self.a = self._split_channels(s)
|
||||
|
||||
def _split_channels(self, s):
|
||||
def alpha_channel(alpha):
|
||||
return int(alpha, 16) if alpha else 0xFF
|
||||
|
||||
m = self.color_pattern.match(s)
|
||||
assert(m is not None)
|
||||
if m.group(1):
|
||||
return int(s[1:3], 16), int(s[3:5], 16), int(s[5:7], 16), alpha_channel(m.group(2))
|
||||
else:
|
||||
return int(s[1] * 2, 16), int(s[2] * 2, 16), int(s[3] * 2, 16), 0xFF
|
||||
|
||||
def get_rgba(self):
|
||||
return "#%02X%02X%02X%02X" % (self.r, self.g, self.b, self.a)
|
||||
|
||||
def get_rgb(self):
|
||||
return "#%02X%02X%02X" % (self.r, self.g, self.b)
|
||||
|
||||
def apply_alpha(self, background="#000000AA"):
|
||||
def tx_alpha(cf, af, cb, ab):
|
||||
return int(abs(cf * (af / 255.0) + cb * (ab / 255.0) * (1 - (af / 255.0)))) & 0xFF
|
||||
|
||||
if self.a < 0xFF:
|
||||
r, g, b, a = self._split_channels(background)
|
||||
|
||||
self.r, self.g, self.b = (tx_alpha(self.r, self.a, r, a), tx_alpha(self.g, self.a, g, a), tx_alpha(self.b, self.a, b, a))
|
||||
|
||||
return self.get_rgb()
|
||||
|
||||
def luminance(self):
|
||||
return clamp(int(round(0.299 * self.r + 0.587 * self.g + 0.114 * self.b)), 0, 255)
|
||||
|
||||
def tohsv(self):
|
||||
return rgb_to_hsv(self.r * RGB_CHANNEL_SCALE, self.g * RGB_CHANNEL_SCALE, self.b * RGB_CHANNEL_SCALE)
|
||||
|
||||
def fromhsv(self, h, s, v):
|
||||
r, g, b = hsv_to_rgb(h, s, v)
|
||||
self.r = int(round(r * 255)) & 0xFF
|
||||
self.g = int(round(g * 255)) & 0xFF
|
||||
self.b = int(round(b * 255)) & 0xFF
|
||||
|
||||
def tohls(self):
|
||||
return rgb_to_hls(self.r * RGB_CHANNEL_SCALE, self.g * RGB_CHANNEL_SCALE, self.b * RGB_CHANNEL_SCALE)
|
||||
|
||||
def fromhls(self, h, l, s):
|
||||
r, g, b = hls_to_rgb(h, l, s)
|
||||
self.r = int(round(r * 255)) & 0xFF
|
||||
self.g = int(round(g * 255)) & 0xFF
|
||||
self.b = int(round(b * 255)) & 0xFF
|
||||
|
||||
def colorize(self, deg):
|
||||
h, l, s = self.tohls()
|
||||
h = clamp(deg * HUE_SCALE, 0.0, 1.0)
|
||||
self.fromhls(h, l, s)
|
||||
|
||||
def hue(self, deg):
|
||||
d = deg * HUE_SCALE
|
||||
h, l, s = self.tohls()
|
||||
h = h + d
|
||||
while h > 1.0:
|
||||
h -= 1.0
|
||||
while h < 0.0:
|
||||
h += 1.0
|
||||
self.fromhls(h, l, s)
|
||||
|
||||
def invert(self):
|
||||
self.r ^= 0xFF
|
||||
self.g ^= 0xFF
|
||||
self.b ^= 0xFF
|
||||
|
||||
def saturation(self, factor):
|
||||
h, l, s = self.tohls()
|
||||
s = clamp(s * factor, 0.0, 1.0)
|
||||
self.fromhls(h, l, s)
|
||||
|
||||
def grayscale(self):
|
||||
luminance = self.luminance() & 0xFF
|
||||
self.r = luminance
|
||||
self.g = luminance
|
||||
self.b = luminance
|
||||
|
||||
def sepia(self):
|
||||
r = clamp(int((self.r * .393) + (self.g * .769) + (self.b * .189)), 0, 255) & 0xFF
|
||||
g = clamp(int((self.r * .349) + (self.g * .686) + (self.b * .168)), 0, 255) & 0xFF
|
||||
b = clamp(int((self.r * .272) + (self.g * .534) + (self.b * .131)), 0, 255) & 0xFF
|
||||
self.r, self.g, self.b = r, g, b
|
||||
|
||||
def brightness(self, factor):
|
||||
# Caculate brightness based on RGB luminance.
|
||||
# Maybe HLS or HSV brightness adjustment is better?
|
||||
def get_overage(c):
|
||||
if c < 0.0:
|
||||
o = 0.0 + c
|
||||
c = 0.0
|
||||
elif c > 255.0:
|
||||
o = c - 255.0
|
||||
c = 255.0
|
||||
else:
|
||||
o = 0.0
|
||||
return o, c
|
||||
|
||||
def distribute_overage(c, o, s):
|
||||
channels = len(s)
|
||||
if channels == 0:
|
||||
return c
|
||||
parts = o / len(s)
|
||||
if "r" in s and "g" in s:
|
||||
c = c[0] + parts, c[1] + parts, c[2]
|
||||
elif "r" in s and "b" in s:
|
||||
c = c[0] + parts, c[1], c[2] + parts
|
||||
elif "g" in s and "b" in s:
|
||||
c = c[0], c[1] + parts, c[2] + parts
|
||||
elif "r" in s:
|
||||
c = c[0] + parts, c[1], c[2]
|
||||
elif "g" in s:
|
||||
c = c[0], c[1] + parts, c[2]
|
||||
else: # "b" in s:
|
||||
c = c[0], c[1], c[2] + parts
|
||||
return c
|
||||
|
||||
channels = ["r", "g", "b"]
|
||||
total_lumes = clamp(self.luminance() + (255.0 * factor) - 255.0, 0.0, 255.0)
|
||||
|
||||
if total_lumes == 255:
|
||||
# white
|
||||
self.r, self.g, self.b = 0xFF, 0xFF, 0xFF
|
||||
elif total_lumes == 0:
|
||||
# black
|
||||
self.r, self.g, self.b = 0x00, 0x00, 0x00
|
||||
else:
|
||||
# Adjust Brightness
|
||||
pts = (total_lumes - 0.299 * self.r - 0.587 * self.g - 0.114 * self.b)
|
||||
slots = set(channels)
|
||||
components = [float(self.r) + pts, float(self.g) + pts, float(self.b) + pts]
|
||||
count = 0
|
||||
for c in channels:
|
||||
overage, components[count] = get_overage(components[count])
|
||||
if overage:
|
||||
slots.remove(c)
|
||||
components = list(distribute_overage(components, overage, slots))
|
||||
count += 1
|
||||
|
||||
self.r = int(round(components[0])) & 0xFF
|
||||
self.g = int(round(components[1])) & 0xFF
|
||||
self.b = int(round(components[2])) & 0xFF
|
Reference in New Issue
Block a user