def _calc_right_skew_trafo(self, event): is_centering = event.is_shift() is_constraining = event.is_ctrl() start_point = self.canvas.win_to_doc(self.start) end_point = self.canvas.win_to_doc(self.end) bbox = self.presenter.selection.bbox h = libgeom.bbox_size(bbox)[1] m11, m21, m12, m22, dx, dy = sk2const.NORMAL_TRAFO change_y = end_point[1] - start_point[1] cx = bbox[0] if is_centering: center_offset = self.presenter.selection.center_offset cx = libgeom.add_points(libgeom.bbox_center(bbox), center_offset)[0] if is_constraining: step = math.radians(config.skew_fixed_angle) angle = (math.atan2(change_y, h) + step / 2.0) // step * step m21 = math.tan(angle) else: m21 = change_y / h if h else 1.0 dy = -cx * m21 return [m11 or EPSILON, m21, m12, m22 or EPSILON, dx, dy]
def render(self, sel_flag=False): doc = self.app.current_doc if sel_flag: if not doc.selection.objs: return None w, h = libgeom.bbox_size(doc.selection.bbox) x, y = libgeom.bbox_center(doc.selection.bbox) trafo = (1.0, 0, 0, -1.0, w / 2.0 - x, h / 2.0 + y) else: page = doc.active_page w, h = page.page_format[1] trafo = (1.0, 0, 0, -1.0, w / 2.0, h / 2.0) canvas_matrix = cairo.Matrix(*trafo) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h)) ctx = cairo.Context(surface) ctx.set_matrix(canvas_matrix) rend = crenderer.CairoRenderer(doc.cms) if sel_flag: objs = doc.selection.objs for obj in objs: layer = doc.methods.get_parent_layer(obj) rend.antialias_flag = layer.properties[3] == 1 rend.render(ctx, [obj]) else: layers = doc.methods.get_visible_layers(page) for item in layers: rend.antialias_flag = item.properties[3] == 1 rend.render(ctx, item.childs) image_stream = StringIO() surface.write_to_png(image_stream) return image_stream
def render(objs, cms): bbox = reduce(lambda a, b: libgeom.sum_bbox(a, b.cache_bbox), objs, []) w, h = libgeom.bbox_size(bbox) x, y = libgeom.bbox_center(bbox) trafo = (1.0, 0, 0, -1.0, w / 2.0 - x, h / 2.0 + y) canvas_matrix = cairo.Matrix(*trafo) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h)) ctx = cairo.Context(surface) ctx.set_matrix(canvas_matrix) rend = crenderer.CairoRenderer(cms) rend.antialias_flag = True rend.render(ctx, objs) image_stream = StringIO() surface.write_to_png(image_stream) return image_stream
def translate_pic(self, obj, cfg): if not obj.childs: return pic = obj.childs[0] filename = pic.file if filename: file_dir = os.path.dirname(self.fig_doc.doc_file) image_path = os.path.join(file_dir, filename) image_path = os.path.abspath(image_path) if fsutils.exists(image_path): pixmap = sk2_model.Pixmap(cfg) pixmap.handler.load_from_file(self.sk2_doc.cms, image_path) img_w, img_h = pixmap.size bbox = libgeom.bbox_for_points(obj.points) size = libgeom.bbox_size(bbox) x, y = 1.0 * bbox[0], 1.0 * bbox[1] w, h = 1.0 * size[0], 1.0 * size[1] trafo = [1.0, 0.0, 0.0, 1.0, -img_w / 2.0, -img_h / 2.0] if pic.flipped: trafo_rotate = libgeom.trafo_rotate_grad(90.0) trafo = libgeom.multiply_trafo(trafo, trafo_rotate) trafo_f = [ 1.0 * img_w / img_h, 0.0, 0.0, 1.0 * img_h / img_w, 0.0, 0.0 ] trafo = libgeom.multiply_trafo(trafo, trafo_f) # rotate angle = self.fig_mtds.get_pic_angle(obj) trafo_r = libgeom.trafo_rotate_grad(angle) trafo = libgeom.multiply_trafo(trafo, trafo_r) # scale to box size if angle in [90.0, 270.0]: img_w, img_h = img_h, img_w trafo1 = [w / img_w, 0.0, 0.0, -h / img_h, 0.0, 0.0] trafo = libgeom.multiply_trafo(trafo, trafo1) # move to origin point trafo3 = [1.0, 0.0, 0.0, 1.0, w / 2.0 + x, h / 2.0 + y] trafo = libgeom.multiply_trafo(trafo, trafo3) # applying document trafo trafo = libgeom.multiply_trafo(trafo, self.trafo) pixmap.trafo = trafo return pixmap
def _calc_bottom_scale_trafo(self, event): is_centering = event.is_shift() is_constraining = event.is_ctrl() is_snapping = not is_constraining m11, m21, m12, m22, dx, dy = sk2const.NORMAL_TRAFO start_point = self.canvas.win_to_doc(self.start) end_point = self.canvas.win_to_doc(self.end) bbox = self.presenter.selection.bbox middle_points = libgeom.bbox_middle_points(bbox) point = middle_points[3] base_y = bbox[3] h = libgeom.bbox_size(bbox)[1] if is_centering: shift_y = h / 2.0 + self.selection.center_offset[1] ratio_y = h / shift_y if shift_y else 1.0 ratio_y = ratio_y if abs(ratio_y) < MAX_RATIO_TRAFO else 1.0 shift_y = h - shift_y else: shift_y, ratio_y = 0.0, 1.0 change_y = h + (start_point[1] - end_point[1]) * ratio_y if is_constraining and h and change_y: if -h < change_y < h: change_y = 1.0 / (h // change_y) * h else: change_y = h + (change_y - h / 2) // h * h m22 = change_y / h if h and change_y else 1.0 dy = base_y - base_y * m22 + shift_y * (m22 - 1.0) if is_snapping: trafo = [m11, m21, m12, m22, dx, dy] p = libgeom.apply_trafo_to_point(point, trafo) flag, _wp, end_point = self.snap.snap_point(p, False) start_point = point if flag: change_y = h + (start_point[1] - end_point[1]) * ratio_y m22 = change_y / h if h else 1.0 dy = base_y - base_y * m22 + shift_y * (m22 - 1.0) return [m11 or EPSILON, m21, m12, m22 or EPSILON, dx, dy]
def _calc_left_scale_trafo(self, event): is_centering = event.is_shift() is_constraining = event.is_ctrl() is_snapping = not is_constraining m11, m21, m12, m22, dx, dy = sk2const.NORMAL_TRAFO start_point = self.canvas.win_to_doc(self.start) end_point = self.canvas.win_to_doc(self.end) bbox = self.presenter.selection.bbox middle_points = libgeom.bbox_middle_points(bbox) point = middle_points[0] base_x = bbox[2] w = libgeom.bbox_size(bbox)[0] if is_centering: shift_x = w / 2.0 + self.selection.center_offset[0] ratio_x = w / shift_x if shift_x else 1.0 ratio_x = ratio_x if abs(ratio_x) < MAX_RATIO_TRAFO else 1.0 shift_x = w - shift_x else: shift_x, ratio_x = 0.0, 1.0 change_x = w + (start_point[0] - end_point[0]) * ratio_x if is_constraining and w and change_x: if -w < change_x < w: change_x = 1.0 / (w // change_x) * w else: change_x = w + (change_x - w / 2) // w * w m11 = change_x / w if w and change_x else 1.0 dx = base_x - base_x * m11 + shift_x * (m11 - 1.0) if is_snapping: trafo = [m11, m21, m12, m22, dx, dy] p = libgeom.apply_trafo_to_point(point, trafo) flag, _wp, end_point = self.snap.snap_point(p, False) start_point = point if flag: change_x = w + (start_point[0] - end_point[0]) * ratio_x m11 = change_x / w if w else 1.0 dx = base_x - base_x * m11 + shift_x * (m11 - 1.0) return [m11 or EPSILON, m21, m12, m22 or EPSILON, dx, dy]
def render(self, sel_flag=False): doc = self.app.current_doc if not doc: return if sel_flag: if not doc.selection.objs: return None w, h = libgeom.bbox_size(doc.selection.bbox) x, y = libgeom.bbox_center(doc.selection.bbox) trafo = (1.0, 0, 0, -1.0, w / 2.0 - x, h / 2.0 + y) else: page = doc.active_page w, h = page.page_format[1] trafo = (1.0, 0, 0, -1.0, w / 2.0, h / 2.0) canvas_matrix = cairo.Matrix(*trafo) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h)) ctx = cairo.Context(surface) ctx.set_matrix(canvas_matrix) rend = crenderer.CairoRenderer(doc.cms) if sel_flag: objs = doc.selection.objs for obj in objs: layer = doc.methods.get_parent_layer(obj) rend.antialias_flag = layer.properties[3] == 1 rend.render(ctx, [ obj, ]) else: page = doc.active_page layers = doc.methods.get_visible_layers(page) for item in layers: rend.antialias_flag = item.properties[3] == 1 rend.render(ctx, item.childs) image_stream = StringIO() surface.write_to_png(image_stream) return image_stream
def translate_polyline(self, obj, cfg): tr = self.trafo style = self.get_style(obj) if obj.sub_type in (fig_const.T_ARC_BOX, fig_const.T_PIC_BOX): bbox = libgeom.bbox_for_points(obj.points) bbox_size = libgeom.bbox_size(bbox) rect = [bbox[0], bbox[1], bbox_size[0], bbox_size[1]] corners = sk2const.CORNERS if obj.sub_type == fig_const.T_ARC_BOX: try: wide_side = max(bbox_size) * tr[0] c = obj.radius * 2.0 * self.thickness / wide_side corners = [c, c, c, c] except ZeroDivisionError: pass else: try: pic = self.translate_pic(obj, cfg) if pic: return pic except Exception: pass props = dict(rect=rect, trafo=tr[:], style=style, corners=corners[:]) new_obj = sk2_model.Rectangle(cfg, **props) else: start_point, points = obj.points[0], obj.points[1:] end_marker = points and start_point == points[-1] paths = [[start_point, points, end_marker]] props = dict(paths=paths, trafo=tr[:], style=style) new_obj = sk2_model.Curve(cfg, **props) return new_obj
def set_sk2_style(sk1_style, dest_obj=None): sk2_style = [[], [], [], []] line_pattern = sk1_style.line_pattern fill_pattern = sk1_style.fill_pattern if not line_pattern.is_Empty: sk2_line = [ sk2const.STROKE_MIDDLE, sk1_style.line_width, get_sk2_color(line_pattern.color), list(sk1_style.line_dashes), SK2_LINE_CAP[sk1_style.line_cap], SK2_LINE_JOIN[sk1_style.line_join], 10.0, 0, 0, [] ] sk2_style[1] = sk2_line if fill_pattern.is_Solid: sk2_fill = [] if fill_pattern.is_Solid: sk2_fill = [ sk2const.FILL_EVENODD, sk2const.FILL_SOLID, get_sk2_color(fill_pattern.color) ] sk2_style[0] = sk2_fill elif fill_pattern.is_AxialGradient: stops = get_sk2_stops(fill_pattern.gradient.colors) point = [fill_pattern.direction.x, fill_pattern.direction.y] angle = libgeom.get_point_angle(point, [0.0, 0.0]) points = [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]] m21 = math.sin(-angle) m11 = m22 = math.cos(-angle) m12 = -m21 dx = 0.5 - m11 * 0.5 + m21 * 0.5 dy = 0.5 - m21 * 0.5 - m11 * 0.5 trafo = [m11, m21, m12, m22, dx, dy] points = libgeom.apply_trafo_to_points(points, trafo) bbox = libgeom.bbox_for_points(points) w, h = libgeom.bbox_size(bbox) vector = [[bbox[0], 0.5], [bbox[2], 0.5]] invtrafo = libgeom.invert_trafo(trafo) vector = libgeom.apply_trafo_to_points(vector, invtrafo) dest_obj.update() bbox = dest_obj.cache_bbox w, h = libgeom.bbox_size(bbox) trafo = [w, 0.0, 0.0, h, bbox[0], bbox[1]] vector = libgeom.apply_trafo_to_points(vector, trafo) sk2_fill = [ sk2const.FILL_EVENODD, sk2const.FILL_GRADIENT, [sk2const.GRADIENT_LINEAR, vector, stops] ] sk2_style[0] = sk2_fill dest_obj.fill_trafo = [] + sk2const.NORMAL_TRAFO elif fill_pattern.is_RadialGradient or fill_pattern.is_ConicalGradient: stops = get_sk2_stops(fill_pattern.gradient.colors) dest_obj.update() bbox = dest_obj.cache_bbox cg = [fill_pattern.center.x, fill_pattern.center.y] w, h = libgeom.bbox_size(bbox) start_point = [bbox[0] + w * cg[0], bbox[1] + h * cg[1]] points = libgeom.bbox_points(bbox) r = 0 for point in points: dist = libgeom.distance(point, start_point) r = max(r, dist) end_point = [start_point[0] + r, start_point[1]] sk2_fill = [ sk2const.FILL_EVENODD, sk2const.FILL_GRADIENT, [sk2const.GRADIENT_RADIAL, [start_point, end_point], stops] ] sk2_style[0] = sk2_fill dest_obj.fill_trafo = [] + sk2const.NORMAL_TRAFO dest_obj.style = sk2_style
def _calc_bottom_right_scale_trafo(self, event): is_centering = event.is_shift() is_constraining = event.is_ctrl() is_snapping = True m11, m21, m12, m22, dx, dy = sk2const.NORMAL_TRAFO start_point = self.canvas.win_to_doc(self.start) end_point = self.canvas.win_to_doc(self.end) bbox = self.presenter.selection.bbox bbox_points = libgeom.bbox_points(bbox) point = bbox_points[2] base_x, base_y = bbox_points[1] w, h = libgeom.bbox_size(bbox) if is_centering: shift_x = w / 2.0 - self.selection.center_offset[0] shift_y = h / 2.0 + self.selection.center_offset[1] ratio_x = w / shift_x if shift_x else 1.0 ratio_y = h / shift_y if shift_y else 1.0 ratio_x = ratio_x if abs(ratio_x) < MAX_RATIO_TRAFO else 1.0 ratio_y = ratio_y if abs(ratio_y) < MAX_RATIO_TRAFO else 1.0 shift_x = shift_x - w shift_y = h - shift_y else: shift_x, ratio_x = 0.0, 1.0 shift_y, ratio_y = 0.0, 1.0 change_x = w + (end_point[0] - start_point[0]) * ratio_x change_y = h + (start_point[1] - end_point[1]) * ratio_y if is_constraining: if w < h: m11 = m22 = change_x / w if w and change_x else 1.0 else: m11 = m22 = change_y / h if h and change_y else 1.0 else: m11 = change_x / w if w and change_x else 1.0 m22 = change_y / h if h and change_y else 1.0 dx = base_x - base_x * m11 + shift_x * (m11 - 1.0) dy = base_y - base_y * m22 + shift_y * (m22 - 1.0) if is_snapping: trafo = [m11, m21, m12, m22, dx, dy] p = libgeom.apply_trafo_to_point(point, trafo) flag, _wp, end_point = self.snap.snap_point(p, False) start_point = point if flag: change_x = w + (end_point[0] - start_point[0]) * ratio_x change_y = h + (start_point[1] - end_point[1]) * ratio_y if is_constraining: if self.snap.active_snap[0] is not None: m11 = m22 = change_x / w if w and change_x else 1.0 else: m11 = m22 = change_y / h if h and change_y else 1.0 else: m11 = change_x / w if w and change_x else 1.0 m22 = change_y / h if h and change_y else 1.0 dx = base_x - base_x * m11 + shift_x * (m11 - 1.0) dy = base_y - base_y * m22 + shift_y * (m22 - 1.0) return [m11 or EPSILON, m21, m12, m22 or EPSILON, dx, dy]