def arrow_trafos(path, properties): dir1, dir2 = arrow_vectors(path, properties.line_arrow1, properties.line_arrow2) width = properties.line_width if width < 1.0: width = 1.0 scale = Scale(width) t1 = t2 = None if dir1 is not None: t1 = Translation(path.Node(0))(Rotation(dir1.polar()[1]))(scale) if dir2 is not None: t2 = Translation(path.Node(-1))(Rotation(dir2.polar()[1]))(scale) return t1, t2
def read_text(self, line): args = tokenize(line, 12) # don't tokenize the text itself if len(args) != 13: # including the unparsed rest of the line raise SketchLoadError('Invalid text specification') sub_type, color, depth, pen_style, font, size, angle, flags, \ height, length, x, y, rest = args self.fill(color, None) self.font(font, size * 0.9, flags) if len(rest) > 2: #at least a space and a newline # read the actual text. This implementation may fail in # certain cases! string = rest[1:] while string[-5:] != '\\001\n': line = self.readline() if not line: raise SketchLoadError('Premature end of string') string = string + line globals = {'__builtins__': {}} try: # using eval here might be a security hole! string = eval('"""' + string[:-5] + '"""', globals) except: string = eval("'''" + string[:-5] + "'''", globals) else: raise SketchLoadError('Invalid text string') trafo = Translation(self.trafo(x, y))(Rotation(angle)) self.simple_text(string, trafo = trafo, halign = align[sub_type]) self.set_depth(depth)
def write_gradient(self, gradient, style): pattern, rect = gradient key = self.gradient_id(pattern) write = self.file.write #write('Bb\n') if pattern.is_AxialGradient: vx, vy = pattern.Direction() angle = atan2(vy, vx) - pi / 2 center = rect.center() rot = Rotation(angle, center) left, bottom, right, top = rot(rect) height = (top - bottom) * (1.0 - pattern.Border()) trafo = rot(Translation(center)) start = trafo(0, height / 2) write("1 %s %g %g %g %g 1 0 0 1 0 0 Bg\n" % (key[0], start.x, start.y, atan2(-vy, -vx) * 180.0 / pi, height)) elif pattern.is_RadialGradient: cx, cy = pattern.Center() cx = cx * rect.right + (1 - cx) * rect.left cy = cy * rect.top + (1 - cy) * rect.bottom radius = max(hypot(rect.left - cx, rect.top - cy), hypot(rect.right - cx, rect.top - cy), hypot(rect.right - cx, rect.bottom - cy), hypot(rect.left - cx, rect.bottom - cy)) radius = radius * (1.0 - pattern.Border()) write("0 0 0 0 Bh\n") write("1 %s %g %g 0 %g 1 0 0 1 0 0 Bg\n" % (key[0], cx, cy, radius))
def compute_trafo(self, state=0): sel = self.selection if sel in self.selTurn: # rotation vec = self.drag_cur - self.center angle = math.atan2(vec.y, vec.x) angle = angle - self.start_angle + 2 * math.pi if state & const.ConstraintMask: pi12 = math.pi / 12 angle = pi12 * int(angle / pi12 + 0.5) self.trafo = Rotation(angle, self.center) self.trafo_desc = (1, angle) elif sel in self.selShear: if sel in (2, 6): # horiz. shear height = self.drag_start.y - self.reference if height: ratio = self.off.x / height self.trafo = Trafo(1, 0, ratio, 1, -ratio * self.reference, 0) self.trafo_desc = (2, ratio) else: # vert. shear width = self.drag_start.x - self.reference if width: ratio = self.off.y / width self.trafo = Trafo(1, ratio, 0, 1, 0, -ratio * self.reference) self.trafo_desc = (3, ratio)
def Execute(self, device, rect): left, bottom, right, top = rect dy = self.spacing if dy > 0: device.SetFillColor(self.background) device.FillRectangle(left, top, right, bottom) device.PushTrafo() vx, vy = self.direction angle = atan2(vy, vx) center = rect.center() rot = Rotation(angle, center) left, bottom, right, top = rot(rect) device.Concat(rot) device.Translate(center) height = top - bottom width = right - left steps = int(height / dy + 1) y = height / 2 x = width / 2 device.SetLineColor(self.foreground) device.SetLineAttributes(self.width) drawline = device.DrawLineXY for i in range(steps): drawline(-x, y, +x, y) y = y - dy device.PopTrafo() else: device.SetFillColor(self.foreground) device.FillRectangle(left, bottom, right, top)
def Execute(self, device, rect): if device.has_axial_gradient: self.execute_axial_gradient(device, rect) return SetFillColor = device.SetFillColor FillRectangle = device.FillRectangle steps = device.gradient_steps colors = self.gradient.Sample(steps) SetFillColor(colors[0]) apply(device.FillRectangle, tuple(rect)) device.PushTrafo() vx, vy = self.direction angle = atan2(vy, vx) - pi / 2 center = rect.center() rot = Rotation(angle, center) left, bottom, right, top = rot(rect) device.Concat(rot) device.Translate(center) height = top - bottom miny = -height / 2 height = height * (1.0 - self.border) width = right - left dy = height / steps y = height / 2 x = width / 2 for i in range(steps): SetFillColor(colors[i]) FillRectangle(-x, y, +x, miny) y = y - dy device.PopTrafo()
def parse_transform(self, trafo_string): trafo = self.trafo trafo_string = as_latin1(trafo_string) while trafo_string: match = rx_trafo.match(trafo_string) if match: function = match.group(1) args = argsf = string.translate(match.group(2), commatospace) args = map(str, split(args)) trafo_string = trafo_string[match.end(0):] if function == 'matrix': args = map(float, split(argsf)) trafo = trafo(apply(Trafo, tuple(args))) elif function == 'scale': if len(args) == 1: sx = sy = args[0] else: sx, sy = args sx, sy = self.user_point(sx, sy) trafo = trafo(Scale(sx, sy)) elif function == 'translate': if len(args) == 1: dx, dy = args[0], '0' else: dx, dy = args dx, dy = self.user_point(dx, dy) trafo = trafo(Translation(dx, dy)) elif function == 'rotate': if len(args) == 1: trafo = trafo(Rotation(float(args[0]) * degrees)) else: angle, cx, cy = args cx, cy = self.user_point(cx, cy) trafo = trafo( Rotation(float(angle) * degrees, Point(cx, cy))) elif function == 'skewX': trafo = trafo( Trafo(1, 0, tan(float(args[0]) * degrees), 1, 0, 0)) elif function == 'skewY': trafo = trafo( Trafo(1, tan(float(args[0]) * degrees), 0, 1, 0, 0)) else: trafo_string = '' self.trafo = trafo
def execute_axial_gradient(self, device, rect): vx, vy = self.direction angle = atan2(vy, vx) - pi / 2 center = rect.center() rot = Rotation(angle, center) left, bottom, right, top = rot(rect) height = (top - bottom) * (1.0 - self.border) trafo = rot(Translation(center)) device.AxialGradient(self.gradient, trafo(0, height / 2), trafo(0, -height / 2))
def RotateSelected(self, angle, cnt=None): text = _("Rotation") if self.document.selection: self.document.begin_transaction(text) try: try: if cnt is None: cnt = self.document.selection.coord_rect.center() angle = angle * degrees trafo = Rotation(angle, cnt) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction()
def load_insert(self): param = { '2': None, # Block name '10': 0.0, # X coordinat '20': 0.0, # Y coordinat #'30': 0.0, # Z coordinat '41': 1.0, # X scale factor '42': 1.0, # Y scale factor #'43': 1.0, # Z scale factor '50': 0.0, # Rotation angle '66': 0, # Attributes-follow flag } param = self.read_param(param) block_name = self.default_block = param['2'] if block_name: self.stack += ['POP_TRAFO', '0' ] + self.block_dict[block_name]['data'] self.push_trafo() x = param['10'] y = param['20'] block_x = self.block_dict[block_name]['10'] block_y = self.block_dict[block_name]['20'] scale_x = param['41'] * self.trafo.m11 scale_y = param['42'] * self.trafo.m22 angle = param['50'] * degrees translate = self.trafo(x, y) trafo = Trafo(1, 0, 0, 1, -block_x, -block_y) trafo = Scale(scale_x, scale_y)(trafo) trafo = Rotation(angle)(trafo) trafo = Translation(translate)(trafo) self.trafo = trafo if param['66'] != 0: line1, line2 = self.read_record() while line1 or line2: if line1 == '0' and line2 == 'SEQEND': break else: if line1 == '0': self.run(line2) line1, line2 = self.read_record()
def load_text(self): param = { '10': 0.0, '20': 0.0, '40': None, # Text height '1': '', # Default value '50': 0, # Text rotation '41': 1, # Relative X scale factor—width # '8': self.default_layer, # Layer name '7': self.default_style, # Style name '72': 0, #Horizontal text justification type } param.update(self.general_param) param = self.read_param(param) x = param['10'] y = param['20'] scale_x = param['41'] scale_y = 1 angle = param['50'] * pi / 180 font_size = param['40'] * self.trafo.m11 halign = [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, \ ALIGN_LEFT, ALIGN_LEFT, ALIGN_LEFT][param['72']] text = unicode_decoder(param['1'], self.DWGCODEPAGE) #style = self.style_dict[param['7']] # print style style_text = self.curstyle.Duplicate() style_text.line_pattern = EmptyPattern style_text.fill_pattern = self.get_pattern(param['62']) style_name = upper(param['7']) style = self.style_dict[style_name] font_name = style['1000'] if font_name == 'Arial': # XXX font_name = 'ArialMT' style_text.font = GetFont(font_name) # print style_text.font style_text.font_size = font_size trafo_text = Translation(self.trafo(x, y))(Rotation(angle))(Scale( scale_x, scale_y)) self.prop_stack.AddStyle(style_text.Duplicate()) self.simple_text(strip(text), trafo_text, halign=halign)
def axial_gradient(self, properties, rect): pattern = properties.fill_pattern vx, vy = pattern.Direction() angle = atan2(vy, vx) - pi / 2 center = rect.center() rot = Rotation(angle, center) left, bottom, right, top = rot(rect) trafo = rot(Translation(center)) image = PIL.Image.new('RGB', (1, 200)) border = int(round(100 * pattern.Border())) _sketch.fill_axial_gradient(image.im, pattern.Gradient().Colors(), 0, border, 0, 200 - border) self.pdf.saveState() apply(self.pdf.transform, trafo.coeff()) self.pdf.drawInlineImage(image, (left - right) / 2, (bottom - top) / 2, right - left, top - bottom) self.pdf.restoreState()
def read_ellipse(self, line): readline = self.readline; tokenize = skread.tokenize_line args = tokenize(line) if len(args) != 19: raise SketchLoadError('Invalid Ellipse specification') sub_type, line_style, thickness, pen_color, fill_color, depth, \ pen_style, area_fill, style, direction, angle, \ cx, cy, rx, ry, sx, sy, ex, ey = args self.fill(fill_color, area_fill) self.line(pen_color, thickness, const.JoinMiter, const.CapButt, line_style, style) center = self.trafo(cx, cy); radius = self.trafo.DTransform(rx, ry) trafo = Trafo(radius.x, 0, 0, radius.y) trafo = Rotation(angle)(trafo) trafo = Translation(center)(trafo) apply(self.ellipse, trafo.coeff()) self.set_depth(depth)
def Execute(self, device, rect): if device.has_conical_gradient: self.execute_conical(device, rect) return steps = device.gradient_steps cx, cy = self.center left, bottom, right, top = rect cx = cx * right + (1 - cx) * left cy = cy * top + (1 - cy) * bottom vx, vy = self.direction angle = atan2(vy, vx) rot = Rotation(angle, cx, cy) radius = max(hypot(left - cx, top - cy), hypot(right - cx, top - cy), hypot(right - cx, bottom - cy), hypot(left - cx, bottom - cy)) + 10 device.PushTrafo() device.Concat(rot) device.Translate(cx, cy) device.Scale(radius) colors = self.gradient.Sample(steps) SetFillColor = device.SetFillColor FillPolygon = device.FillPolygon da = pi / steps points = [(1, 0)] for i in range(steps): a = da * (i + 1) x = cos(a) y = sin(a) points.insert(0, (x, y)) points.append((x, -y)) colors.reverse() SetFillColor(colors[0]) FillPolygon(points) points.insert(0, (0, 0)) for i in range(steps): SetFillColor(colors[i]) del points[1] del points[-1] FillPolygon(points) device.PopTrafo()
def load_ellips(self): param = { '10': 0.0, # X coordinat center '20': 0.0, # Y coordinat center #'30': 0.0, # Z coordinat center '11': 0.0, # Endpoint of major axis, relative to the center '21': 0.0, #'31': 0.0, '40': 0.0, # Ratio of minor axis to major axis '41': 0.0, # Start parameter (this value is 0.0 for a full ellipse) '42': 0.0, # End parameter (this value is 2pi for a full ellipse) } param.update(self.general_param) param = self.read_param(param) cx = param['10'] cy = param['20'] rx = sqrt(param['21']**2 + param['11']**2) ry = rx * param['40'] start_angle = param['41'] end_angle = param['42'] angle = atan2(param['21'], param['11']) center = self.trafo(cx, cy) radius = self.trafo.DTransform(rx, ry) trafo = Trafo(radius.x, 0, 0, radius.y) trafo = Rotation(angle)(trafo) trafo = Translation(center)(trafo) rx, w1, w2, ry, cx, cy = trafo.coeff() style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) apply(self.ellipse, (rx, w1, w2, ry, cx, cy, start_angle, end_angle, ArcArc))
def CreatedObject(self): trafo = Translation(self.start) r, phi = (self.drag_cur - self.start).polar() if r: trafo = trafo(Rotation(phi)) return SimpleText(trafo=trafo, properties=DefaultTextProperties())