def get_trafo(self): x0 = self.origin_x.get_point_value() y0 = self.origin_y.get_point_value() sx = self.scale_x.get_value() / 100.0 sy = self.scale_y.get_value() / 100.0 shx = self.shear_x.get_value() shy = self.shear_y.get_value() if shx + shy > 85: if shx == self.transforms[3]: shy = 85 - shx else: shx = 85 - shy shx = math.pi * shx / 180.0 shy = math.pi * shy / 180.0 angle = math.pi * self.rotate.get_value() / 180.0 trafo = [sx, 0.0, 0.0, sy, x0, y0] if angle: trafo2 = [math.cos(angle), math.sin(angle), - math.sin(angle), math.cos(angle), 0.0, 0.0] trafo = libgeom.multiply_trafo(trafo, trafo2) if shx or shy: trafo2 = [1.0, math.tan(shy), math.tan(shx), 1.0, 0.0, 0.0] trafo = libgeom.multiply_trafo(trafo, trafo2) self.transforms = [sx, sy, shx, shy, angle] return trafo, [sx, sy, shx, shy, angle]
def update_trafo(self): wt = [1.0, 0.0, 0.0, 1.0, -self.wx, -self.wy] vt = [1.0, 0.0, 0.0, 1.0, self.vx, self.vy] scale = [float(self.vwidth) / self.wwidth, 0.0, 0.0, float(self.vheight) / self.wheight, 0.0, 0.0] tr = multiply_trafo(multiply_trafo(wt, scale), vt) self.set_trafo(multiply_trafo(tr, self.base_trafo))
def tr_textout(self, chunk): length = get_data('<h', chunk[:2])[0] encoding = self.get_encoding() txt = chunk[8:8 + length].decode(encoding) txt_length = len(txt) txt = txt.encode('utf-8') y, x, = get_data('<hhhh', chunk[8 + length:16 + length]) p = apply_trafo_to_point([x, y], self.get_trafo()) cfg = self.layer.config sk2_style, tags = self.get_text_style() markup = [[tags, (0, txt_length)]] tr = [] + libgeom.NORMAL_TRAFO text = sk2_model.Text(cfg, self.layer, p, txt, -1, tr, sk2_style) text.markup = markup if self.dc.opacity: bg_style = [[], [], [], []] clr = [] + self.dc.bgcolor clr = [uc2const.COLOR_RGB, clr, 1.0, '', ''] bg_style[0] = [sk2_const.FILL_EVENODD, sk2_const.FILL_SOLID, clr] text.update() bbox = [] + text.cache_bbox rect = bbox[:2] + [bbox[2] - bbox[0], bbox[3] - bbox[1]] rect = sk2_model.Rectangle(cfg, self.layer, rect, style=bg_style) self.layer.childs.append(rect) if self.dc.font[-2]: tr = libgeom.trafo_rotate_grad(self.dc.font[-2], p[0], p[1]) text.trafo = libgeom.multiply_trafo(text.trafo, tr) if self.dc.opacity: rect.trafo = libgeom.multiply_trafo(rect.trafo, tr) self.layer.childs.append(text)
def generate_preview(self): wp, hp = self.config.preview_size surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(wp), int(hp)) ctx = cairo.Context(surface) if not self.config.preview_transparent: ctx.set_source_rgb(1.0, 1.0, 1.0) ctx.paint() #---rendering mthds = self.presenter.methods layers = mthds.get_visible_layers(mthds.get_page()) bbox = mthds.count_bbox(layers) if bbox: x, y, x1, y1 = bbox w = abs(x1 - x) h = abs(y1 - y) coef = min(wp / w, hp / h) * 0.99 trafo0 = [1.0, 0.0, 0.0, 1.0, -x - w / 2.0, -y - h / 2.0] trafo1 = [coef, 0.0, 0.0, -coef, 0.0, 0.0] trafo2 = [1.0, 0.0, 0.0, 1.0, wp / 2.0, hp / 2.0] trafo = libgeom.multiply_trafo(trafo0, trafo1) trafo = libgeom.multiply_trafo(trafo, trafo2) ctx.set_matrix(cairo.Matrix(*trafo)) rend = CairoRenderer(self.presenter.cms) rend.antialias_flag = True for item in layers: rend.render(ctx, item.childs) #---rendering image_stream = StringIO() surface.write_to_png(image_stream) return b64encode(image_stream.getvalue())
def apply_trafo(self, trafo): self.cache_cpath = libgeom.apply_trafo(self.cache_cpath, trafo) self.trafo = libgeom.multiply_trafo(self.trafo, trafo) if self.fill_trafo: self.fill_trafo = libgeom.multiply_trafo(self.fill_trafo, trafo) if self.stroke_trafo: self.stroke_trafo = libgeom.multiply_trafo(self.stroke_trafo, trafo) self.update_bbox()
def apply_trafo(self, trafo): for i in self.trafos.keys(): self.trafos[i] = libgeom.multiply_trafo(self.trafos[i], trafo) for i in range(len(self.cache_cpath)): if self.cache_cpath[i] is None: continue self.cache_cpath[i] = libgeom.apply_trafo(self.cache_cpath[i], trafo) self.trafo = libgeom.multiply_trafo(self.trafo, trafo) if self.fill_trafo: self.fill_trafo = libgeom.multiply_trafo(self.fill_trafo, trafo) if self.stroke_trafo: self.stroke_trafo = libgeom.multiply_trafo(self.stroke_trafo, trafo) self.update_bbox()
def translate_ellipse(self, obj, cfg): cx = obj.center_x cy = obj.center_y rx = obj.radius_x ry = obj.radius_y props = dict( rect=[cx - rx, cy - ry, 2.0 * rx, 2.0 * ry], style=self.get_style(obj), ) new_obj = sk2_model.Circle(cfg, **props) trafo_rotate = libgeom.trafo_rotate(-obj.angle, cx, cy) trafo = libgeom.multiply_trafo(new_obj.trafo, trafo_rotate) new_obj.trafo = libgeom.multiply_trafo(trafo, self.trafo) return new_obj
def fill_linear_tr_gradient(self, obj, pdfpath, fill_trafo, gradient): if not fill_trafo: fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] stops = gradient[2] sp, ep = gradient[1] dx, dy = sp l = libgeom.distance(sp, ep) angle = libgeom.get_point_angle(ep, sp) m21 = math.sin(angle) m11 = m22 = math.cos(angle) m12 = -m21 trafo = [m11, m21, m12, m22, dx, dy] inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo), libgeom.invert_trafo(trafo)) cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo) paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo) paths = libgeom.apply_trafo_to_paths(paths, inv_trafo) bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths), [0.0, 0.0, l, 0.0]) bbox = libgeom.normalize_bbox(bbox) y = bbox[1] d = libgeom.distance(*libgeom.apply_trafo_to_points([[0.0, 0.0], [0.0, 1.0]], inv_trafo)) height = bbox[3] - bbox[1] self.canvas.saveState() self.canvas.clipPath(pdfpath, 0, 0) self.canvas.transform(*cv_trafo) self.canvas.setFillColor(self.get_grcolor_at_point(stops, 0.0)) self.canvas.rect(bbox[0], y, 0.0 - bbox[0], height, stroke=0, fill=1) x = 0.0 while x < l: point = x / l self.canvas.setFillColor(self.get_grcolor_at_point(stops, point)) if x + d < l: width = d else: width = l - x self.canvas.rect(x, y, width, height, stroke=0, fill=1) x += d self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0)) self.canvas.rect(l, y, bbox[2] - l, height, stroke=0, fill=1) self.canvas.restoreState()
def apply_trafo_to_selected(self, trafo, final=False): trafos = deepcopy(self.target.trafos) for item in self.selected_points: index = item.index if index in trafos.keys(): trafos[index] = libgeom.multiply_trafo(trafos[index], trafo) else: trafos[index] = libgeom.multiply_trafo(self.target.trafo, trafo) item.apply_trafo(trafo) if not final: self.api.set_temp_text_trafos(self.target, trafos) else: self.api.set_text_trafos(self.target, trafos, self.trafos) self.trafos = {}
def fill_radial_tr_gradient(self, obj, pdfpath, fill_trafo, gradient): if not fill_trafo: fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] stops = gradient[2] sp, ep = gradient[1] dx, dy = sp l = libgeom.distance(sp, ep) trafo = [1.0, 0.0, 0.0, 1.0, dx, dy] inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo), libgeom.invert_trafo(trafo)) cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo) paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo) paths = libgeom.apply_trafo_to_paths(paths, inv_trafo) bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths), [0.0, 0.0, l, 0.0]) bbox = libgeom.normalize_bbox(bbox) d = libgeom.distance(*libgeom.apply_trafo_to_points([[0.0, 0.0], [0.0, 1.0]], inv_trafo)) circle_paths = libgeom.get_circle_paths(0.0, 0.0, sk2_const.ARC_CHORD) trafo = [2.0, 0.0, 0.0, 2.0, -1.0, -1.0] circle_paths = libgeom.apply_trafo_to_paths(circle_paths, trafo) inner_paths = [] r = 0.0 self.canvas.saveState() self.canvas.clipPath(pdfpath, 0, 0) self.canvas.transform(*cv_trafo) while r < l: point = r / l self.canvas.setFillColor(self.get_grcolor_at_point(stops, point)) if r + d < l: coef = (r + d) else: coef = l trafo = [coef, 0.0, 0.0, coef, 0.0, 0.0] paths = libgeom.apply_trafo_to_paths(circle_paths, trafo) ring = self.make_pdfpath(inner_paths + paths)[0] inner_paths = paths self.canvas.drawPath(ring, stroke=0, fill=1) r += d self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0)) r = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) trafo = [2.0 * r, 0.0, 0.0, 2.0 * r, 0.0, 0.0] paths = libgeom.apply_trafo_to_paths(circle_paths, trafo) ring = self.make_pdfpath(inner_paths + paths)[0] self.canvas.drawPath(ring, stroke=0, fill=1) self.canvas.restoreState()
def draw_pattern(self): w, h = self.get_size() pattern = self.fill[2] surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h) ctx = cairo.Context(surface) self.draw_cairo_background(ctx) bmpstr = b64decode(pattern[1]) if self.cms.app.current_doc: config = self.cms.app.current_doc.model.config else: config = sk2_config.SK2_Config() config_file = os.path.join(self.cms.app.appdata.app_config_dir, 'sk2_config.xml') config.load(config_file) image_obj = sk2_model.Pixmap(config) libimg.set_image_data(self.cms, image_obj, bmpstr) libimg.flip_left_to_right(image_obj) if pattern[0] == sk2_const.PATTERN_IMG and len(pattern) > 2: image_obj.style[3] = deepcopy(pattern[2]) libimg.update_image(self.cms, image_obj) sp = cairo.SurfacePattern(image_obj.cache_cdata) sp.set_extend(cairo.EXTEND_REPEAT) trafo = [-1.0, 0.0, 0.0, 1.0, 0.0, 0.0] if len(pattern) > 3: trafo = libgeom.multiply_trafo(pattern[3], trafo) pattern_matrix = cairo.Matrix(*trafo) pattern_matrix.invert() sp.set_matrix(pattern_matrix) ctx.set_source(sp) ctx.rectangle(0, 0, w, h) ctx.fill() image_obj.cache_cdata = None self.gc_draw_bitmap(wal.copy_surface_to_bitmap(surface), 0, 0)
def draw_pattern(self): w, h = self.get_size() pattern = self.fill[2] surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h) ctx = cairo.Context(surface) self.draw_cairo_background(ctx) if self.cms.app.current_doc: cfg = self.cms.app.current_doc.model.config else: cfg = sk2_config.SK2_Config() config_file = os.path.join(self.cms.app.appdata.app_config_dir, 'sk2_config.xml') cfg.load(config_file) image_obj = sk2_model.Pixmap(cfg) hndl = image_obj.handler hndl.load_from_b64str(self.cms, pattern[1]) hndl.flip_left_to_right() if pattern[0] == sk2const.PATTERN_IMG and len(pattern) > 2: image_obj.style[3] = deepcopy(pattern[2]) sp = cairo.SurfacePattern(hndl.get_surface(self.cms)) sp.set_extend(cairo.EXTEND_REPEAT) trafo = [-1.0, 0.0, 0.0, 1.0, 0.0, 0.0] if len(pattern) > 3: trafo = libgeom.multiply_trafo(pattern[3], trafo) pattern_matrix = cairo.Matrix(*trafo) pattern_matrix.invert() sp.set_matrix(pattern_matrix) ctx.set_source(sp) ctx.rectangle(0, 0, w, h) ctx.fill() self.gc_draw_bitmap(wal.copy_surface_to_bitmap(surface), 0, 0)
def translate_circle(self, obj): # obj.update() trafo = libgeom.multiply_trafo(obj.trafo, self.trafo) trafo_split = trafolib.trafo_split(trafo) is_shear = abs(trafo_split['shear']) > EPSILON_SHEAR if is_shear or obj.angle1 != obj.angle2: return self.translate_primitive(obj) center = libgeom.apply_trafo_to_point([0.5, 0.5], trafo) end = libgeom.apply_trafo_to_point([1.0, 1.0], trafo) props = dict( sub_type=fig_const.T_ELLIPSE_BY_RAD, angle=trafo_split['rotate'] - math.pi, center_x=center[0], center_y=center[1], radius_x=trafo_split['scale_x'] / 2.0, radius_y=trafo_split['scale_y'] / 2.0, start_x=center[0], start_y=center[1], end_x=end[0], end_y=end[1], depth=self.current_depth, ) props.update(self.get_fill(obj)) props.update(self.get_stroke(obj)) new_obj = fig_model.FIGEllipse(**props) self.add(new_obj)
def generate_preview(presenter, renderer_cls, size=(100, 100), transparent=False, img_format='PNG', encoded=True): wp, hp = size surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(wp), int(hp)) ctx = cairo.Context(surface) if not transparent: ctx.set_source_rgb(1.0, 1.0, 1.0) ctx.paint() # ---rendering mthds = presenter.methods layers = mthds.get_visible_layers(mthds.get_page()) bbox = mthds.count_bbox(layers) if bbox: x, y, x1, y1 = bbox w = abs(x1 - x) or 1.0 h = abs(y1 - y) or 1.0 coef = min(wp / w, hp / h) * 0.99 trafo0 = [1.0, 0.0, 0.0, 1.0, -x - w / 2.0, -y - h / 2.0] trafo1 = [coef, 0.0, 0.0, -coef, 0.0, 0.0] trafo2 = [1.0, 0.0, 0.0, 1.0, wp / 2.0, hp / 2.0] trafo = libgeom.multiply_trafo(trafo0, trafo1) trafo = libgeom.multiply_trafo(trafo, trafo2) ctx.set_matrix(cairo.Matrix(*trafo)) rend = renderer_cls(presenter.cms) rend.antialias_flag = True for item in layers: rend.render(ctx, item.childs) # ---rendering image_stream = StringIO() surface.write_to_png(image_stream) if not img_format == 'PNG': image_stream.seek(0, 0) image = Image.open(image_stream) image.load() image_stream = StringIO() image.save(image_stream, format=img_format) image_str = image_stream.getvalue() return b64encode(image_str) if encoded else image_str
def translate_primitive(self, obj): curve = obj.to_curve() if curve.is_group: self.translate_group(curve) return curve.update() trafo = libgeom.multiply_trafo(curve.trafo, self.trafo) paths = libgeom.apply_trafo_to_paths(curve.paths, trafo) paths = libgeom.flat_paths(paths) self.translate_paths(obj.style, paths)
def translate_primitive(self, obj): curve = obj.to_curve() if curve.is_group(): self.translate_group(curve) return curve.update() self.translate_style(obj) trafo = libgeom.multiply_trafo(curve.trafo, self.trafo) paths = libgeom.apply_trafo_to_paths(curve.paths, trafo) for item in [] + self.latest_objs: self.delete_obj(item)
def translate_ellipse(self, dest_parent, source_ellipse): trafo = self.get_sk2_trafo(source_ellipse) angle1 = source_ellipse.start_angle angle2 = source_ellipse.end_angle arc_type = SK2_ARC_TYPES[source_ellipse.arc_type] rect = [-1.0, -1.0, 2.0, 2.0] dest_ellipse = sk2_model.Circle(dest_parent.config, dest_parent, rect, angle1, angle2, arc_type) dest_ellipse.trafo = libgeom.multiply_trafo(dest_ellipse.trafo, trafo) dest_ellipse.initial_trafo = [] + dest_ellipse.trafo dest_ellipse.style = get_sk2_style(source_ellipse.properties) return dest_ellipse
def translate_ellipse(self, dest_parent, source_ellipse): trafo = self.get_sk2_trafo(source_ellipse) angle1 = source_ellipse.start_angle angle2 = source_ellipse.end_angle arc_type = SK2_ARC_TYPES[source_ellipse.arc_type] rect = [-1.0, -1.0, 2.0, 2.0] dest_ellipse = sk2_model.Circle(dest_parent.config, dest_parent, rect, angle1, angle2, arc_type) dest_ellipse.trafo = libgeom.multiply_trafo(dest_ellipse.trafo, trafo) dest_ellipse.initial_trafo = [] + dest_ellipse.trafo set_sk2_style(source_ellipse.properties, dest_ellipse) return dest_ellipse
def tr_exttextout(self, chunk): y, x, length = get_data('<hhh', chunk[:6]) dl = 0 if length % 2: length += 1 dl += 1 p = apply_trafo_to_point([x, y], self.get_trafo()) encoding = self.get_encoding() pos = 16 if not len(chunk) - 8 == length else 8 txt = chunk[pos:pos + length - dl].decode(encoding) txt_length = len(txt) txt = txt.encode('utf-8') cfg = self.layer.config sk2_style, tags = self.get_text_style() markup = [[tags, (0, txt_length)]] tr = [] + libgeom.NORMAL_TRAFO text = sk2_model.Text(cfg, self.layer, p, txt, -1, tr, sk2_style) text.markup = markup rect = None if self.dc.opacity: bg_style = [[], [], [], []] clr = [] + self.dc.bgcolor clr = [uc2const.COLOR_RGB, clr, 1.0, '', ''] bg_style[0] = [sk2const.FILL_EVENODD, sk2const.FILL_SOLID, clr] text.update() bbox = [] + text.cache_bbox rect = bbox[:2] + [bbox[2] - bbox[0], bbox[3] - bbox[1]] rect = sk2_model.Rectangle(cfg, self.layer, rect, style=bg_style) rect.trafo = tr self.layer.childs.append(rect) if self.dc.font[-2]: tr = libgeom.trafo_rotate_grad(self.dc.font[-2], p[0], p[1]) text.trafo = libgeom.multiply_trafo(text.trafo, tr) if self.dc.opacity: rect.trafo = libgeom.multiply_trafo(rect.trafo, tr) self.layer.childs.append(text)
def get_svg_trafo(strafo): trafo = [] + libgeom.NORMAL_TRAFO trs = strafo.split(') ') trs.reverse() for tr in trs: tr += ')' tr = tr.replace(', ', ',').replace(' ', ',').replace('))', ')') try: code = compile('tr=trafo_' + tr, '<string>', 'exec') exec code except: continue trafo = libgeom.multiply_trafo(trafo, tr) return trafo
def fill_pattern(self, obj, pdfpath, fill_trafo, pattern): if not fill_trafo: fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] inv_ptrn_trafo = libgeom.invert_trafo(pattern[3]) inv_trafo = libgeom.multiply_trafo( libgeom.invert_trafo(fill_trafo), libgeom.invert_trafo(inv_ptrn_trafo)) paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo) paths = libgeom.apply_trafo_to_paths(paths, inv_trafo) bbox = libgeom.get_paths_bbox(paths) cv_trafo = libgeom.multiply_trafo(pattern[3], fill_trafo) bmpstr = b64decode(pattern[1]) image_obj = sk2_model.Pixmap(obj.config) libimg.set_image_data(self.cms, image_obj, bmpstr) if pattern[0] == sk2const.PATTERN_IMG and \ len(pattern) > 2: image_obj.style[3] = deepcopy(pattern[2]) libimg.update_image(self.cms, image_obj) self.canvas.saveState() self.canvas.clipPath(pdfpath, 0, 0) self.canvas.transform(*cv_trafo) w, h = image_obj.get_size() x = bbox[0] y = bbox[3] while y > bbox[1] - h: while x < bbox[2]: self.canvas.saveState() self.canvas.transform(1.0, 0.0, 0.0, 1.0, x, y) self.draw_pixmap_obj(image_obj) self.canvas.restoreState() x += w y -= h x = bbox[0] self.canvas.restoreState()
def fill_pattern(self, obj, pdfpath, fill_trafo, pattern): if not fill_trafo: fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] inv_ptrn_trafo = libgeom.invert_trafo(pattern[3]) inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo), libgeom.invert_trafo(inv_ptrn_trafo)) paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo) paths = libgeom.apply_trafo_to_paths(paths, inv_trafo) bbox = libgeom.get_paths_bbox(paths) cv_trafo = libgeom.multiply_trafo(pattern[3], fill_trafo) bmpstr = b64decode(pattern[1]) image_obj = sk2_model.Pixmap(obj.config) libimg.set_image_data(self.cms, image_obj, bmpstr) if pattern[0] == sk2_const.PATTERN_IMG and \ len(pattern) > 2: image_obj.style[3] = deepcopy(pattern[2]) libimg.update_image(self.cms, image_obj) self.canvas.saveState() self.canvas.clipPath(pdfpath, 0, 0) self.canvas.transform(*cv_trafo) w, h = image_obj.get_size() x = bbox[0] y = bbox[3] while y > bbox[1] - h: while x < bbox[2]: self.canvas.saveState() self.canvas.transform(1.0, 0.0, 0.0, 1.0, x, y) self.draw_pixmap_obj(image_obj) self.canvas.restoreState() x += w y -= h x = bbox[0] self.canvas.restoreState()
def set_trafo(self, extend): if self.cgm['scale.mode'] == 0: left, bottom = extend[0] right, top = extend[1] width = right - left height = top - bottom sc = 841 / (1.0 * max(abs(width), abs(height))) else: left = bottom = 0 width = height = right = top = 1 sc = self.cgm['scale.metric'] * 72 / 25.4 self.scale = sc tr = [1.0, 0.0, 0.0, 1.0, -(right - left) / 2.0 - left, -(top - bottom) / 2.0 - bottom] scale = [sign(width) * sc, 0.0, 0.0, sign(height) * sc, 0.0, 0.0] self.trafo = libgeom.multiply_trafo(tr, scale)
def translate_primitive(self, obj): obj.update() curve = obj.to_curve() if curve.is_group: return self.translate_group(curve) param = self.get_fill(obj) param.update(self.get_stroke(obj)) trafo = libgeom.multiply_trafo(curve.trafo, self.trafo) paths = libgeom.apply_trafo_to_paths(curve.paths, trafo) # TODO: implement support behind flag for path in paths: if all(map(lambda a: len(a) == 2, path[1])): self.add_polyline(path, **param) else: # TODO: implement translate obj as spline path = libgeom.flat_path(path, tlr=0.05) self.add_polyline(path, **param)
def translate_arc(self, obj, cfg): cx = obj.center_x cy = obj.center_y r = libgeom.distance((cx, cy), (obj.x1, obj.y1)) end_angle = libgeom.get_point_angle((obj.x1, obj.y1), (cx, cy)) start_angle = libgeom.get_point_angle((obj.x3, obj.y3), (cx, cy)) if not obj.direction: start_angle, end_angle = end_angle, start_angle circle_type = FIG_TO_SK2_ARC.get(obj.sub_type, sk2const.ARC_PIE_SLICE) props = dict(circle_type=circle_type, rect=[cx - r, cy - r, 2.0 * r, 2.0 * r], style=self.get_style(obj), angle1=start_angle, angle2=end_angle) new_obj = sk2_model.Circle(cfg, **props) new_obj.trafo = libgeom.multiply_trafo(new_obj.trafo, self.trafo) return new_obj
def translate_text(self, obj, cfg): trafo_rotate = libgeom.trafo_rotate(obj.angle) base_point = libgeom.apply_trafo_to_point([obj.x, obj.y], self.trafo) base_point[1] -= obj.font_size trafo = [72.0 / 90.0, 0.0, 0.0, 72.0 / 90.0] + base_point trafo = libgeom.multiply_trafo(trafo_rotate, trafo) text_style = self.get_text_style(obj) props = dict(point=[0.0, obj.font_size], style=text_style, text=obj.string, trafo=trafo) new_obj = sk2_model.Text(cfg, **props) txt_length = len(obj.string) tags = [] new_obj.markup = [[tags, (0, txt_length)]] return new_obj
def translate_rect(self, dest_parent, source_rect): trafo = self.get_sk2_trafo(source_rect) corners = [0.0, 0.0, 0.0, 0.0] rect = [0.0, 0.0, 1.0, 1.0] if source_rect.radius1 and source_rect.radius2: radius = min(source_rect.radius1, source_rect.radius2) corners = [radius * 2.0] * 4 if source_rect.radius1 > source_rect.radius2: coef = source_rect.radius1 / source_rect.radius2 rect = [0.0, 0.0, 1.0, coef] tr = [1.0, 0.0, 0.0, 1.0 / coef, 0.0, 0.0] else: coef = source_rect.radius2 / source_rect.radius1 rect = [0.0, 0.0, coef, 1.0] tr = [1.0 / coef, 0.0, 0.0, 1.0, 0.0, 0.0] trafo = libgeom.multiply_trafo(tr, trafo) dest_rect = sk2_model.Rectangle(dest_parent.config, dest_parent, rect, trafo, corners=corners) dest_rect.style = get_sk2_style(source_rect.properties) return dest_rect
def translate_rect(self, dest_parent, source_rect): trafo = self.get_sk2_trafo(source_rect) corners = [0.0, 0.0, 0.0, 0.0] rect = [0.0, 0.0, 1.0, 1.0] if source_rect.radius1 and source_rect.radius2: radius = min(source_rect.radius1, source_rect.radius2) corners = [radius * 2.0] * 4 if source_rect.radius1 > source_rect.radius2: coef = source_rect.radius1 / source_rect.radius2 rect = [0.0, 0.0, 1.0, coef] tr = [1.0, 0.0, 0.0, 1.0 / coef, 0.0, 0.0] else: coef = source_rect.radius2 / source_rect.radius1 rect = [0.0, 0.0, coef, 1.0] tr = [1.0 / coef, 0.0, 0.0, 1.0 , 0.0, 0.0] trafo = libgeom.multiply_trafo(tr, trafo) dest_rect = sk2_model.Rectangle(dest_parent.config, dest_parent, rect, trafo, corners=corners) dest_rect.style = get_sk2_style(source_rect.properties) return dest_rect
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 apply_trafo(self, trafo): self.cache_cpath = libgeom.apply_trafo(self.cache_cpath, trafo) self.trafo = libgeom.multiply_trafo(self.trafo, trafo) self.update_bbox()
def translate_trafo(self, page): fig = self.fig_mtds.in_to_fig() width, height = self.sk2_mtds.get_page_size(page) trafo1 = [1.0, 0.0, 0.0, -1.0, width / 2.0, height / 2.0] trafo2 = [fig, 0.0, 0.0, fig, 0.0, 0.0] self.trafo = libgeom.multiply_trafo(trafo1, trafo2)
def get_svg_level_trafo(svg_obj, trafo): tr = [] + libgeom.NORMAL_TRAFO if 'transform' in svg_obj.attrs: tr = get_svg_trafo(svg_obj.attrs['transform']) tr = libgeom.multiply_trafo(tr, trafo) return tr
def parse_svg_path_cmds(pathcmds): index = 0 last = None last_index = 0 cmds = [] pathcmds = re.sub(' *', ' ', pathcmds) for item in pathcmds: if item in 'MmZzLlHhVvCcSsQqTtAa': if last: coords = parse_svg_coords(pathcmds[last_index + 1:index]) cmds.append((last, coords)) last = item last_index = index index += 1 coords = parse_svg_coords(pathcmds[last_index + 1:index]) cmds.append([last, coords]) paths = [] path = [] cpoint = [] rel_flag = False last_cmd = 'M' last_quad = None for cmd in cmds: if cmd[0] in 'Mm': if path: paths.append(path) path = deepcopy(PATH_STUB) rel_flag = cmd[0] == 'm' points = [cmd[1][i:i + 2] for i in range(0, len(cmd[1]), 2)] for point in points: if cpoint and rel_flag: point = add_points(base_point(cpoint), point) if not path[0]: path[0] = point else: path[1].append(point) cpoint = point elif cmd[0] in 'Zz': p0 = [] + base_point(cpoint) p1 = [] + path[0] if not libgeom.is_equal_points(p0, p1, 8): path[1].append([] + path[0]) path[2] = sk2const.CURVE_CLOSED cpoint = [] + path[0] elif cmd[0] in 'Cc': rel_flag = cmd[0] == 'c' points = [cmd[1][i:i + 2] for i in range(0, len(cmd[1]), 2)] points = [points[i:i + 3] for i in range(0, len(points), 3)] for point in points: if rel_flag: point = [ add_points(base_point(cpoint), point[0]), add_points(base_point(cpoint), point[1]), add_points(base_point(cpoint), point[2]) ] qpoint = [] + point qpoint.append(sk2const.NODE_CUSP) path[1].append(qpoint) cpoint = point elif cmd[0] in 'Ll': rel_flag = cmd[0] == 'l' points = [cmd[1][i:i + 2] for i in range(0, len(cmd[1]), 2)] for point in points: if rel_flag: point = add_points(base_point(cpoint), point) path[1].append(point) cpoint = point elif cmd[0] in 'Hh': rel_flag = cmd[0] == 'h' for x in cmd[1]: dx, y = base_point(cpoint) if rel_flag: point = [x + dx, y] else: point = [x, y] path[1].append(point) cpoint = point elif cmd[0] in 'Vv': rel_flag = cmd[0] == 'v' for y in cmd[1]: x, dy = base_point(cpoint) if rel_flag: point = [x, y + dy] else: point = [x, y] path[1].append(point) cpoint = point elif cmd[0] in 'Ss': rel_flag = cmd[0] == 's' points = [cmd[1][i:i + 2] for i in range(0, len(cmd[1]), 2)] points = [points[i:i + 2] for i in range(0, len(points), 2)] for point in points: q = cpoint p = cpoint if len(cpoint) > 2: q = cpoint[1] p = cpoint[2] p1 = sub_points(add_points(p, p), q) if rel_flag: p2 = add_points(base_point(cpoint), point[0]) p3 = add_points(base_point(cpoint), point[1]) else: p2, p3 = point point = [p1, p2, p3] qpoint = [] + point qpoint.append(sk2const.NODE_CUSP) path[1].append(qpoint) cpoint = point elif cmd[0] in 'Qq': rel_flag = cmd[0] == 'q' groups = [cmd[1][i:i + 4] for i in range(0, len(cmd[1]), 4)] for vals in groups: p = base_point(cpoint) if rel_flag: q = add_points(p, [vals[0], vals[1]]) p3 = add_points(p, [vals[2], vals[3]]) else: q = [vals[0], vals[1]] p3 = [vals[2], vals[3]] p1 = add_points(mult_point(p, F13), mult_point(q, F23)) p2 = add_points(mult_point(p3, F13), mult_point(q, F23)) point = [p1, p2, p3] qpoint = [] + point qpoint.append(sk2const.NODE_CUSP) path[1].append(qpoint) cpoint = point last_quad = q elif cmd[0] in 'Tt': rel_flag = cmd[0] == 't' groups = [cmd[1][i:i + 2] for i in range(0, len(cmd[1]), 2)] if last_cmd not in 'QqTt' or last_quad is None: last_quad = base_point(cpoint) for vals in groups: p = base_point(cpoint) q = sub_points(mult_point(p, 2.0), last_quad) if rel_flag: p3 = add_points(p, [vals[0], vals[1]]) else: p3 = [vals[0], vals[1]] p1 = add_points(mult_point(p, F13), mult_point(q, F23)) p2 = add_points(mult_point(p3, F13), mult_point(q, F23)) point = [p1, p2, p3] qpoint = [] + point qpoint.append(sk2const.NODE_CUSP) path[1].append(qpoint) cpoint = point last_quad = q elif cmd[0] in 'Aa': rel_flag = cmd[0] == 'a' arcs = [cmd[1][i:i + 7] for i in range(0, len(cmd[1]), 7)] for arc in arcs: cpoint = base_point(cpoint) rev_flag = False rx, ry, xrot, large_arc_flag, sweep_flag, x, y = arc rx = abs(rx) ry = abs(ry) if rel_flag: x += cpoint[0] y += cpoint[1] if cpoint == [x, y]: continue if not rx or not ry: path[1].append([x, y]) continue vector = [[] + cpoint, [x, y]] if sweep_flag: vector = [[x, y], [] + cpoint] rev_flag = True cpoint = [x, y] dir_tr = libgeom.trafo_rotate_grad(-xrot) if rx > ry: tr = [1.0, 0.0, 0.0, rx / ry, 0.0, 0.0] r = rx else: tr = [ry / rx, 0.0, 0.0, 1.0, 0.0, 0.0] r = ry dir_tr = libgeom.multiply_trafo(dir_tr, tr) vector = libgeom.apply_trafo_to_points(vector, dir_tr) l = libgeom.distance(*vector) if l > 2.0 * r: r = l / 2.0 mp = libgeom.midpoint(*vector) tr0 = libgeom.trafo_rotate(math.pi / 2.0, mp[0], mp[1]) pvector = libgeom.apply_trafo_to_points(vector, tr0) k = math.sqrt(r * r - l * l / 4.0) if large_arc_flag: center = libgeom.midpoint(mp, pvector[1], 2.0 * k / l) else: center = libgeom.midpoint(mp, pvector[0], 2.0 * k / l) angle1 = libgeom.get_point_angle(vector[0], center) angle2 = libgeom.get_point_angle(vector[1], center) da = angle2 - angle1 start = angle1 end = angle2 if large_arc_flag: if -math.pi >= da or da <= math.pi: start = angle2 end = angle1 rev_flag = not rev_flag else: if -math.pi <= da or da >= math.pi: start = angle2 end = angle1 rev_flag = not rev_flag pth = libgeom.get_circle_paths(start, end, sk2const.ARC_ARC)[0] if rev_flag: pth = libgeom.reverse_path(pth) points = pth[1] for point in points: if len(point) == 3: point.append(sk2const.NODE_CUSP) tr0 = [1.0, 0.0, 0.0, 1.0, -0.5, -0.5] points = libgeom.apply_trafo_to_points(points, tr0) tr1 = [2.0 * r, 0.0, 0.0, 2.0 * r, 0.0, 0.0] points = libgeom.apply_trafo_to_points(points, tr1) tr2 = [1.0, 0.0, 0.0, 1.0, center[0], center[1]] points = libgeom.apply_trafo_to_points(points, tr2) tr3 = libgeom.invert_trafo(dir_tr) points = libgeom.apply_trafo_to_points(points, tr3) for point in points: path[1].append(point) last_cmd = cmd[0] if path: paths.append(path) return paths
def translate_trafo(self): trafo1 = self.fig_mtds.get_doc_trafo() width, height = self.fig_mtds.get_page_size() trafo2 = [1.0, 0.0, 0.0, 1.0, -width / 2.0, height / 2.0] self.trafo = libgeom.multiply_trafo(trafo1, trafo2)
def apply_trafo(self, trafo): self.trafo = libgeom.multiply_trafo(self.trafo, trafo)
def make_v1_objects(self, parent_instr, obj): if obj.is_group and obj.childs: kwargs = { 'bbox': (0, 0, 0, 0), 'tail': '\x00\x00', } group_instr = mkinstr(self.cmx_cfg, identifier=cmx_const.BEGIN_GROUP, **kwargs) parent_instr.add(group_instr) for item in obj.childs: self.make_v1_objects(group_instr, item) group_instr.add( mkinstr(self.cmx_cfg, identifier=cmx_const.END_GROUP)) group_instr.data['bbox'] = group_instr.get_bbox() elif obj.is_primitive: curve = obj.to_curve() curve.update() if not curve: return elif curve.is_group: self.make_v1_objects(parent_instr, curve) elif curve.paths: close_flag = False style = curve.style attrs = { 'style_flags': 1 if style[0] else 0, 'fill_type': cmx_const.INSTR_FILL_EMPTY, } attrs['style_flags'] += 2 if style[1] else 0 if style[0] and style[0][1] == sk2const.FILL_SOLID: attrs['fill_type'] = cmx_const.INSTR_FILL_UNIFORM attrs['fill'] = (self._add_color(style[0][2]), 1) close_flag = not style[0][0] & sk2const.FILL_CLOSED_ONLY if style[1]: outline = style[1] if curve.stroke_trafo: points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points( points, obj.stroke_trafo) coef = libgeom.distance(*points) outline = deepcopy(outline) outline[1] *= coef attrs['outline'] = self._add_outline(outline) trafo = libgeom.multiply_trafo( curve.trafo, [self.coef, 0.0, 0.0, self.coef, 0.0, 0.0]) paths = libgeom.apply_trafo_to_paths(curve.paths, trafo) attrs['points'] = [] attrs['nodes'] = [] for path in paths: # Force path closing if close_flag and not path[2] == sk2const.CURVE_CLOSED: path = deepcopy(path) path[2] = sk2const.CURVE_CLOSED p = path[1][-1] if len(path[1][-1]) == 2 \ else path[1][-1][-1] if not path[0] == p: path[1].append([] + path[0]) x, y = path[0] attrs['points'].append((int(x), int(y))) node = cmx_const.NODE_MOVE + cmx_const.NODE_USER if path[2] == sk2const.CURVE_CLOSED: node += cmx_const.NODE_CLOSED attrs['nodes'].append(node) for point in path[1]: if len(point) == 2: x, y = point attrs['points'].append((int(x), int(y))) node = cmx_const.NODE_LINE + cmx_const.NODE_USER attrs['nodes'].append(node) else: p0, p1, p2, flag = point for item in (p0, p1, p2): x, y = item attrs['points'].append((int(x), int(y))) node = cmx_const.NODE_ARC attrs['nodes'].append(node) attrs['nodes'].append(node) node = cmx_const.NODE_CURVE + cmx_const.NODE_USER attrs['nodes'].append(node) if path[2] == sk2const.CURVE_CLOSED: attrs['nodes'][-1] += cmx_const.NODE_CLOSED attrs['bbox'] = self._make_bbox(curve.cache_bbox) attrs['tail'] = '' curve_instr = mkinstr(self.cmx_cfg, identifier=cmx_const.POLYCURVE, **attrs) parent_instr.add(curve_instr)