class ChooseRGBXY(ChooseComponent): def __init__(self, master, width, height, xcomp=0, ycomp=1, color=(0, 0, 0), **kw): self.xcomp = xcomp self.ycomp = ycomp self.win_to_color = Trafo(1 / float(width - 1), 0, 0, -1 / float(height - 1), 0, 1) self.color_to_win = self.win_to_color.inverse() apply(ChooseComponent.__init__, (self, master, width, height, color), kw) def SetColor(self, color): color = apply(rgb_to_hsv, tuple(color)) otheridx = 3 - self.xcomp - self.ycomp if color[otheridx] != self.color[otheridx]: self.UpdateWhenIdle() self.hide_mark() self.color = color self.show_mark() def update_ramp(self): _sketch.fill_hsv_xy(self.image.im, self.xcomp, self.ycomp, self.color) self.set_image(self.image) def move_to(self, p, state): x, y = p if state & ConstraintMask: sx = self.drag_start[self.xcomp] sy = self.drag_start[self.ycomp] if abs(sx - x) < abs(sy - y): x = sx else: y = sy if x < 0: x = 0 elif x >= 1.0: x = 1.0 if y < 0: y = 0 elif y >= 1.0: y = 1.0 color = list(self.color) color[self.xcomp] = x color[self.ycomp] = y self.hide_mark() self.color = tuple(color) self.show_mark() self.issue(CHANGED, self.RGBColor()) def draw_mark(self): color = self.color w, h = self.image.size x, y = self.color_to_win(color[self.xcomp], color[self.ycomp]) x = int(x) y = int(y) self.invgc.DrawLine(x, 0, x, h) self.invgc.DrawLine(0, y, w, y)
class ChooseRGBXY(ChooseComponent): def __init__(self, master, callback, width, height, xcomp=0, ycomp=1, color=(0, 0, 0), **kw): self.callback = callback self.xcomp = xcomp self.ycomp = ycomp self.win_to_color = Trafo(1 / float(width - 1), 0, 0, -1 / float(height - 1), 0, 1) self.color_to_win = self.win_to_color.inverse() apply(ChooseComponent.__init__, (self, master, width, height, color), kw) def SetColor(self, color): color = apply(rgb_to_hsv, tuple(color)) otheridx = 3 - self.xcomp - self.ycomp if color[otheridx] != self.color[otheridx]: self.UpdateWhenIdle() self.hide_mark() self.color = color self.show_mark() def update_ramp(self): _sketch.fill_hsv_xy(self.image.im, self.xcomp, self.ycomp, self.color) self.set_image(self.image) def move_to(self, p, state): x, y = p if state & ConstraintMask: sx = self.drag_start[self.xcomp] sy = self.drag_start[self.ycomp] if abs(sx - x) < abs(sy - y): x = sx else: y = sy if x < 0: x = 0 elif x >= 1.0: x = 1.0 if y < 0: y = 0 elif y >= 1.0: y = 1.0 color = list(self.color) color[self.xcomp] = x color[self.ycomp] = y self.hide_mark() self.color = tuple(color) self.show_mark() self.callback(self.getRGB()) # self.issue(CHANGED, self.RGBColor()) def draw_mark(self): color = self.color w, h = self.image.size x, y = self.color_to_win(color[self.xcomp], color[self.ycomp]) x = int(x) y = int(y) self.invgc.DrawLine(x, 0, x, h) self.invgc.DrawLine(0, y, w, y)
def make_gradient_pattern(self): name, trafo, start, end = self.gradient_geo self.gradient_geo = None type, array = self.gradients[name] array = array[:] if type == 0: # linear (axial) gradient origdir = end - start start = trafo(start) end = trafo(end) dir = end - start try: # adjust endpoint to accomodate trafo v = trafo.DTransform(origdir.y, -origdir.x).normalized() v = Point(v.y, -v.x) # rotate 90 degrees end = start + (v * dir) * v dir = end - start except ZeroDivisionError: pass trafo2 = Trafo(dir.x, dir.y, dir.y, -dir.x, start.x, start.y) trafo2 = trafo2.inverse() left, bottom, right, top = trafo2(self.current_bounding_rect()) if right > left: factor = 1 / (right - left) offset = -left * factor else: factor = 1 offset = 0 array = fix_gradient(array, factor, offset) pattern = LinearGradient(MultiGradient(array), (start - end).normalized()) elif type == 1: # radial gradient start = trafo(start) end = trafo(end) left, bottom, right, top = self.current_bounding_rect() if left == right or top == bottom: # an empty coord_rect???? center = Point(0, 0) else: center = Point((start.x - left) / (right - left), (start.y - bottom) / (top - bottom)) radius = max(hypot(left - start.x, top - start.y), hypot(right - start.x, top - start.y), hypot(right - start.x, bottom - start.y), hypot(left - start.x, bottom - start.y)) if radius: factor = -abs(start - end) / radius array = fix_gradient(array, factor, 1) pattern = RadialGradient(MultiGradient(array), center) else: self.add_message(_("Unknown gradient type %d"), type) pattern = EmptyPattern return pattern
def Snap(self, p): try: x, y = self.trafo.inverse()(p) minx = self.radius1 maxx = 1 - self.radius1 miny = self.radius2 maxy = 1 - self.radius2 if minx < x < maxx: if miny < y < maxy: ratio = hypot(self.trafo.m11, self.trafo.m21) \ / hypot(self.trafo.m12, self.trafo.m22) if x < 0.5: dx = x else: dx = 1 - x if y < 0.5: dy = y else: dy = 1 - y if dy / dx > ratio: x = round(x) else: y = round(y) elif y > maxy: y = 1 else: y = 0 elif miny < y < maxy: if x > maxx: x = 1 else: x = 0 elif minx > 0 and miny > 0: # the round corners if x < 0.5: cx = minx else: cx = maxx if y < 0.5: cy = miny else: cy = maxy trafo = Trafo(minx, 0, 0, miny, cx, cy) r, phi = trafo.inverse()(x, y).polar() x, y = trafo(Polar(1, phi)) else: # normal corners x = round(min(max(x, 0), 1)) y = round(min(max(y, 0), 1)) p2 = self.trafo(x, y) return (abs(p - p2), p2) except SingularMatrix: return (1e200, p)
class ChooseRGBZ(ChooseComponent): def __init__(self, master, callback, width, height, comp=1, color=(0, 0, 0), **kw): self.callback = callback self.comp = comp self.win_to_color = Trafo(1, 0, 0, -1 / float(height - 1), 0, 1) self.color_to_win = self.win_to_color.inverse() apply(ChooseComponent.__init__, (self, master, width, height, color), kw) def SetColor(self, color): c = self.color color = apply(rgb_to_hsv, tuple(color)) if ((self.comp == 0 and (color[1] != c[1] or color[2] != c[2])) or (self.comp == 1 and (color[0] != c[0] or color[2] != c[2])) or (self.comp == 2 and (color[0] != c[0] or color[1] != c[1]))): self.hide_mark() self.color = color self.show_mark() self.UpdateWhenIdle() def update_ramp(self): _sketch.fill_hsv_z(self.image.im, self.comp, self.color) self.set_image(self.image) def move_to(self, p, state): y = p.y if y < 0: y = 0 elif y >= 1.0: y = 1.0 color = list(self.color) color[self.comp] = y self.hide_mark() self.color = tuple(color) self.show_mark() self.callback(self.getRGB()) # self.issue(CHANGED, self.RGBColor()) def draw_mark(self): w, h = self.image.size x, y = self.color_to_win(0, self.color[self.comp]) x = int(x) y = int(y) self.invgc.DrawLine(0, y, w, y)
class ChooseRGBZ(ChooseComponent): def __init__(self, master, callback, width, height, comp=1, color=(0, 0, 0), **kw): self.callback = callback self.comp = comp self.win_to_color = Trafo(1, 0, 0, -1 / float(height - 1), 0, 1) self.color_to_win = self.win_to_color.inverse() apply(ChooseComponent.__init__, (self, master, width, height, color), kw) def SetColor(self, color): c = self.color; color = apply(rgb_to_hsv, tuple(color)) if ((self.comp == 0 and (color[1] != c[1] or color[2] != c[2])) or (self.comp == 1 and (color[0] != c[0] or color[2] != c[2])) or (self.comp == 2 and (color[0] != c[0] or color[1] != c[1]))): self.hide_mark() self.color = color self.show_mark() self.UpdateWhenIdle() def update_ramp(self): _sketch.fill_hsv_z(self.image.im, self.comp, self.color) self.set_image(self.image) def move_to(self, p, state): y = p.y if y < 0: y = 0 elif y >= 1.0: y = 1.0 color = list(self.color) color[self.comp] = y self.hide_mark() self.color = tuple(color) self.show_mark() self.callback(self.getRGB()) # self.issue(CHANGED, self.RGBColor()) def draw_mark(self): w, h = self.image.size x, y = self.color_to_win(0, self.color[self.comp]) x = int(x) y = int(y) self.invgc.DrawLine(0, y, w, y)
def resize(self): code = self.selection.x_code trafo = self.trafo; radius1 = self.radius1; radius2 = self.radius2 if code < 0: # a special handle that has to be treated as a normal handle # depending on the direction of the drag width = hypot(trafo.m11, trafo.m21) height = hypot(trafo.m12, trafo.m22) t = Trafo(trafo.m11 / width, trafo.m21 / width, trafo.m12 / height, trafo.m22 / height, 0, 0) dx, dy = t.inverse()(self.off) #print code, dx, dy if code > -5: # one of the corners in a rectangle with sharp corners if abs(dx) > abs(dy): code = 4 - code else: code = (12, 10, 11, 9)[code] else: # the edge handle and the round corner handles coincide if code >= -7: # horizontal edges if abs(dx) > abs(dy): if dx < 0: code = -code else: code = -code + 1 else: code = -4 - code else: # vertical edges if abs(dx) > abs(dy): code = code + 13 else: if dy < 0: code = -code else: code = -code + 1 # # code is now a normal handle # #print '->', code x, y = trafo.inverse()(self.drag_cur) width = hypot(trafo.m11, trafo.m21) height = hypot(trafo.m12, trafo.m22) if code <= 4: # drag one of the edges if code == 1: t = Trafo(1, 0, 0, 1 - y, 0, y) if y != 1: radius2 = radius2 / abs(1 - y) else: radius1 = radius2 = 0 elif code == 2: t = Trafo(x, 0, 0, 1, 0, 0) if x != 0: radius1 = radius1 / abs(x) else: radius1 = radius2 = 0 elif code == 3: t = Trafo(1, 0, 0, y, 0, 0) if y != 0: radius2 = radius2 / abs(y) else: radius1 = radius2 = 0 elif code == 4: t = Trafo(1 - x, 0, 0, 1, x, 0) if x != 1: radius1 = radius1 / abs(1 - x) else: radius1 = radius2 = 0 trafo = trafo(t) if radius1 != 0 or radius2 != 0: ratio = radius1 / radius2 if radius1 > 0.5: radius1 = 0.5 radius2 = radius1 / ratio if radius2 > 0.5: radius2 = 0.5 radius1 = radius2 * ratio else: # modify the round corners if radius1 == radius2 == 0: ratio = height / width else: ratio = radius1 / radius2 if ratio > 1: max1 = 0.5 max2 = max1 / ratio else: max2 = 0.5 max1 = max2 * ratio if code < 9: if code == 6 or code == 8: x = 1 - x radius1 = max(min(x, max1), 0) radius2 = radius1 / ratio else: if code == 10 or code == 12: y = 1 - y radius2 = max(min(y, max2), 0) radius1 = radius2 * ratio return trafo, radius1, radius2
# arrays to convert AI join and cap to Sketch's join and cap. In AI # files they're given as small ints so we just use a tuple where we can # use the AI cap/join value as index to get the corresponding value in # Sketch. _ai_join = (const.JoinMiter, const.JoinRound, const.JoinBevel) _ai_cap = (const.CapButt, const.CapRound, const.CapProjecting) # The same for text alignment. The last two values are two variants of # justified text, which Sketch doesn't have, so we're just using # centered for now. _ai_text_align = (text.ALIGN_LEFT, text.ALIGN_CENTER, text.ALIGN_RIGHT, text.ALIGN_CENTER, text.ALIGN_CENTER) artboard_trafo = Trafo(1, 0, 0, -1, 4014, 4716) artboard_trafo_inv = artboard_trafo.inverse() class FontInfo: def __init__(self, psname, newname, encoding): self.psname = psname self.newname = newname self.encoding = encoding self.reencoder = None def Reencode(self, text): if self.reencoder is None: self.reencoder = encoding.Reencoder(self.encoding, encoding.iso_latin_1) return self.reencoder(text)