def _snap(self, bbox, trafo): result = [] + trafo points = libgeom.bbox_middle_points(bbox) tr_points = libgeom.apply_trafo_to_points(points, trafo) active_snap = [None, None] shift_x = [] snap_x = [] for point in [tr_points[0], tr_points[2], tr_points[1]]: flag, wp, dp = self.snap.snap_point(point, False, snap_y=False) if flag: shift_x.append(dp[0] - point[0]) snap_x.append(dp[0]) if shift_x: if len(shift_x) > 1: if abs(shift_x[0]) < abs(shift_x[1]): dx = shift_x[0] active_snap[0] = snap_x[0] else: dx = shift_x[1] active_snap[0] = snap_x[1] else: dx = shift_x[0] active_snap[0] = snap_x[0] result[4] += dx shift_y = [] snap_y = [] pnts = [tr_points[1], tr_points[3], tr_points[2]] if len(self.selection.objs) == 1 and self.selection.objs[0].is_text: line_points = self.selection.objs[0].get_line_points() pnts = libgeom.apply_trafo_to_points(line_points, trafo) + pnts for point in pnts: flag, wp, dp = self.snap.snap_point(point, False, snap_x=False) if flag: shift_y.append(dp[1] - point[1]) snap_y.append(dp[1]) if shift_y: if len(shift_y) > 1: if abs(shift_y[0]) < abs(shift_y[1]): dy = shift_y[0] active_snap[1] = snap_y[0] else: dy = shift_y[1] active_snap[1] = snap_y[1] else: dy = shift_y[0] active_snap[1] = snap_y[0] result[5] += dy self.snap.active_snap = [] + active_snap return result
def _snap(self, bbox, trafo): result = [] + trafo points = libgeom.bbox_middle_points(bbox) tr_points = libgeom.apply_trafo_to_points(points, trafo) active_snap = [None, None] shift_x = [] snap_x = [] for point in [tr_points[0], tr_points[2], tr_points[1]]: flag, wp, dp = self.snap.snap_point(point, False, snap_y=False) if flag: shift_x.append(dp[0] - point[0]) snap_x.append(dp[0]) if shift_x: if len(shift_x) > 1: if abs(shift_x[0]) < abs(shift_x[1]): dx = shift_x[0] active_snap[0] = snap_x[0] else: dx = shift_x[1] active_snap[0] = snap_x[1] else: dx = shift_x[0] active_snap[0] = snap_x[0] result[4] += dx shift_y = [] snap_y = [] pnts = [tr_points[1], tr_points[3], tr_points[2]] if len(self.selection.objs) == 1 and self.selection.objs[0].is_text(): line_points = self.selection.objs[0].get_line_points() pnts = libgeom.apply_trafo_to_points(line_points, trafo) + pnts for point in pnts: flag, wp, dp = self.snap.snap_point(point, False, snap_x=False) if flag: shift_y.append(dp[1] - point[1]) snap_y.append(dp[1]) if shift_y: if len(shift_y) > 1: if abs(shift_y[0]) < abs(shift_y[1]): dy = shift_y[0] active_snap[1] = snap_y[0] else: dy = shift_y[1] active_snap[1] = snap_y[1] else: dy = shift_y[0] active_snap[1] = snap_y[0] result[5] += dy self.snap.active_snap = [] + active_snap return result
def process_stroke(self, ctx, obj, style=None): if style: stroke = style[1] else: stroke = obj.style[1] #FIXME: add stroke style #Line width if not stroke[8]: line_width = stroke[1] if obj and obj.stroke_trafo: obj.stroke_trafo = [] else: if obj and not obj.stroke_trafo: obj.stroke_trafo = [] + sk2_const.NORMAL_TRAFO points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points(points, obj.stroke_trafo) coef = libgeom.distance(*points) line_width = stroke[1] * coef ctx.set_line_width(line_width) #Line color ctx.set_source_rgba(*self.get_color(stroke[2])) #Dashes dash = [] for item in stroke[3]:dash.append(item * line_width) ctx.set_dash(dash) ctx.set_line_cap(CAPS[stroke[4]]) ctx.set_line_join(JOINS[stroke[5]]) ctx.set_miter_limit(stroke[6])
def _get_doc_vector(self, style): ret = [] vector = style[0][2][1] vector = libgeom.apply_trafo_to_points(vector, self.target.fill_trafo) for item in vector: ret.append(VectorPoint(self.canvas, item)) return ret
def stroke_pdfpath(self, pdfpath, stroke_style, stroke_trafo=[]): width = stroke_style[1] if not stroke_style[8]: width = stroke_style[1] else: if not stroke_trafo: stroke_trafo = [] + sk2const.NORMAL_TRAFO points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points(points, stroke_trafo) coef = libgeom.distance(*points) width = stroke_style[1] * coef self.canvas.setStrokeColor(self.get_pdfcolor(stroke_style[2])) dash = stroke_style[3] caps = stroke_style[4] joint = stroke_style[5] miter = stroke_style[6] self.canvas.setLineWidth(width) self.canvas.setLineCap(caps - 1) self.canvas.setLineJoin(joint) dashes = [] if dash: dashes = list(dash) w = width if w < 1.0: w = 1.0 for i in range(len(dashes)): dashes[i] = w * dashes[i] self.canvas.setDash(dashes) self.canvas.setMiterLimit(miter) self.canvas.drawPath(pdfpath, 1, 0) self.canvas.setStrokeAlpha(1.0)
def process_stroke(self, ctx, obj, style=None): if style: stroke = style[1] else: stroke = obj.style[1] # Line width if not stroke[8]: line_width = stroke[1] if obj and obj.stroke_trafo: obj.stroke_trafo = [] else: if obj and not obj.stroke_trafo: obj.stroke_trafo = [] + sk2const.NORMAL_TRAFO points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points(points, obj.stroke_trafo) coef = libgeom.distance(*points) line_width = stroke[1] * coef ctx.set_line_width(line_width) # Line color ctx.set_source_rgba(*self.get_color(stroke[2])) # Dashes dash = [] for item in stroke[3]: dash.append(item * line_width) ctx.set_dash(dash) ctx.set_line_cap(CAPS[stroke[4]]) ctx.set_line_join(JOINS[stroke[5]]) ctx.set_miter_limit(stroke[6])
def stroke_pdfpath(self, pdfpath, stroke_style, stroke_trafo=[]): width = stroke_style[1] if not stroke_style[8]: width = stroke_style[1] else: if not stroke_trafo: stroke_trafo = [] + sk2_const.NORMAL_TRAFO points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points(points, stroke_trafo) coef = libgeom.distance(*points) width = stroke_style[1] * coef self.canvas.setStrokeColor(self.get_pdfcolor(stroke_style[2])) dash = stroke_style[3] caps = stroke_style[4] joint = stroke_style[5] miter = stroke_style[6] self.canvas.setLineWidth(width) self.canvas.setLineCap(caps - 1) self.canvas.setLineJoin(joint) dashes = [] if dash: dashes = list(dash) w = width if w < 1.0: w = 1.0 for i in range(len(dashes)): dashes[i] = w * dashes[i] self.canvas.setDash(dashes) self.canvas.setMiterLimit(miter) self.canvas.drawPath(pdfpath, 1, 0) self.canvas.setStrokeAlpha(1.0)
def _circular_arc_3_point_close(self, element): p1, chunk = self.read_point(element.params) p2, chunk = self.read_point(chunk) p3, chunk = self.read_point(chunk) flag = self.read_enum(chunk)[0] p1, p2, p3 = libgeom.apply_trafo_to_points([p1, p2, p3], self.get_trafo()) center = libgeom.circle_center_by_3points(p1, p2, p3) if not center: return r = libgeom.distance(center, p1) angle1 = libgeom.get_point_angle(p3, center) angle2 = libgeom.get_point_angle(p1, center) x, y = center rect = [x - r, y - r, 2 * r, 2 * r] flag = { 0: sk2const.ARC_PIE_SLICE, 1: sk2const.ARC_CHORD }.get(flag, sk2const.ARC_CHORD) circle = sk2_model.Circle(self.layer.config, self.layer, rect, angle1=angle1, angle2=angle2, circle_type=flag, style=self.get_style(fill=True)) self.layer.childs.append(circle)
def _set_target_vector(self, temp=True): itrafo = libgeom.invert_trafo(self.target.fill_trafo) vector = [self.vector[0].point, self.vector[1].point] self.new_style[0][2][1] = libgeom.apply_trafo_to_points(vector, itrafo) if temp: self.api.set_temp_style(self.target, self.new_style) else: self.api.set_fill_style(deepcopy(self.new_style[0])) events.emit(events.APP_STATUS, self.msg)
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, sk2const.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 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 update_stroke(self): stroke = self.style[1] if not stroke: return if not stroke[8]: self.cache_line_width = stroke[1] self.stroke_trafo = [] else: if not self.stroke_trafo: self.stroke_trafo = [] + sk2const.NORMAL_TRAFO points = [[0.0, 0.0], [1.0, 0.0]] points = libgeom.apply_trafo_to_points(points, self.stroke_trafo) coef = libgeom.distance(*points) self.cache_line_width = stroke[1] * coef self.update_arrows()
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 _circular_arc_centre(self, element): center, chunk = self.read_point(element.params) p1, chunk = self.read_point(chunk) p2, chunk = self.read_point(chunk) center, p1, p2 = libgeom.apply_trafo_to_points( [center, p1, p2], self.get_trafo()) r = self.read_vdc(chunk)[0] * self.scale angle1 = libgeom.get_point_angle(p1, center) angle2 = libgeom.get_point_angle(p2, center) x, y = center rect = [x - r, y - r, 2 * r, 2 * r] circle = sk2_model.Circle(self.layer.config, self.layer, rect, angle1=angle1, angle2=angle2, circle_type=sk2const.ARC_ARC, style=self.get_style(stroke=True)) self.layer.childs.append(circle)
def translate_pixmap(self, obj): obj.update() doc_id = urlsafe_b64encode(self.fig_doc.doc_id) idx = len(self.fig_doc.resources) filename = '{}-{}.png'.format(doc_id, idx) image_stream = crenderer.render([obj], self.sk2_doc.cms) self.fig_doc.resources[filename] = image_stream.getvalue() x0, y0, x1, y1 = obj.cache_bbox points = [[x0, y1], [x1, y1], [x1, y0], [x0, y0], [x0, y1]] points = libgeom.apply_trafo_to_points(points, self.trafo) props = dict( sub_type=fig_const.T_PIC_BOX, childs=[fig_model.FIGPicture(file=filename)], npoints=len(points), points=points, depth=self.current_depth, ) self.add(fig_model.FIGPolyline(**props))
def paint_cursor(self): if self.text_cursor < len(self.target.cache_layout_data): data = self.target.cache_layout_data[self.text_cursor] p0 = [data[0], data[1]] p1 = [data[0], data[1] - data[3]] else: data = self.target.cache_layout_data[-1] if self.text[-1] == '\n': p0 = [0.0, data[1] - data[3]] p1 = [0.0, data[1] - 2.0 * data[3]] else: p0 = [data[0] + data[2], data[1]] p1 = [data[0] + data[2], data[1] - data[3]] trafo = self.target.trafo if self.text_cursor in self.trafos: trafo = self.trafos[self.text_cursor] p0, p1 = libgeom.apply_trafo_to_points([p0, p1], trafo) p0 = self.canvas.point_doc_to_win(p0) p1 = self.canvas.point_doc_to_win(p1) self.canvas.renderer.draw_text_cursor(p0, p1)
def _circular_arc_centre_close(self, element): center, chunk = self.read_point(element.params) p1, chunk = self.read_point(chunk) p2, chunk = self.read_point(chunk) flag = self.read_enum(chunk)[0] center, p1, p2 = libgeom.apply_trafo_to_points( [center, p1, p2], self.get_trafo()) r = self.read_vdc(chunk)[0] * self.scale angle1 = libgeom.get_point_angle(p1, center) angle2 = libgeom.get_point_angle(p2, center) x, y = center rect = [x - r, y - r, 2 * r, 2 * r] flag = {0: sk2const.ARC_PIE_SLICE, 1: sk2const.ARC_CHORD}.get(flag, sk2const.ARC_CHORD) circle = sk2_model.Circle(self.layer.config, self.layer, rect, angle1=angle1, angle2=angle2, circle_type=flag, style=self.get_style(fill=True)) self.layer.childs.append(circle)
def _circular_arc_3_point(self, element): p1, chunk = self.read_point(element.params) p2, chunk = self.read_point(chunk) p3, chunk = self.read_point(chunk) p1, p2, p3 = libgeom.apply_trafo_to_points( [p1, p2, p3], self.get_trafo()) center = libgeom.circle_center_by_3points(p1, p2, p3) if not center: return r = libgeom.distance(center, p1) angle1 = libgeom.get_point_angle(p3, center) angle2 = libgeom.get_point_angle(p1, center) x, y = center rect = [x - r, y - r, 2 * r, 2 * r] circle = sk2_model.Circle(self.layer.config, self.layer, rect, angle1=angle1, angle2=angle2, circle_type=sk2const.ARC_ARC, style=self.get_style(stroke=True)) self.layer.childs.append(circle)
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 _get_win_vector(self, style): vector = style[0][2][1] vector = libgeom.apply_trafo_to_points(vector, self.target.fill_trafo) p0 = self.canvas.point_doc_to_win(vector[0]) p1 = self.canvas.point_doc_to_win(vector[1]) return p0, p1
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)
def get_line_points(self): return libgeom.apply_trafo_to_points(self.cache_line_points, self.trafo)
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