def _calc_bottom_left_rotate_trafo(self, event): is_centering = not 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 if is_centering: bbox_center = libgeom.bbox_center(bbox) center_offset = self.selection.center_offset center = libgeom.add_points(bbox_center, center_offset) else: center = libgeom.bbox_points(bbox)[3] a1 = libgeom.get_point_angle(start_point, center) a2 = libgeom.get_point_angle(end_point, center) angle = a2 - a1 if is_constraining: step = math.radians(config.rotation_step) angle = (angle + step / 2.0) // step * step return libgeom.trafo_rotate(angle, center[0], center[1])
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]