def primitives(self): if hasattr(self, '_primitives'): return self._primitives # Calculate rectangle and text size font = ImageFont.truetype(self.font) text_size = font.getsize(self.text) if self.wrap is not None and text_size[0] > self.wrap: # TODO: insert the logic here pass # No wrap, simple logic text_size = font.getsize( self.text) # equivalent to text's top left at origin # noqa half_text_size = scale_point(text_size, 0.5) text_position = add_points(self.center, negate(half_text_size)) pad = self.padding, self.padding rect_size = add_points(text_size, pad) rect_top_left = add_points(text_position, negate(pad)) # add padding to bottom point as well rect_bottom_right = add_points(rect_top_left, (add_points(rect_size, pad))) self._primitives = [ Text(self.text, text_position, self.font), Rectangle(rect_top_left, rect_bottom_right) ] return self._primitives
def _get_wired_primitives(self): """The wired primitives consists of 4 90degree arcs at four corners, and four lines""" x1, y1 = self.top_left x2, y2 = self.bottom_right r = self.radius # TODO: check for case of circle or ellipse lines = [ # Horizontal lines Line(add_points((x1, y1), (r, 0)), add_points((x2, y1), (-r, 0))), Line(add_points((x1, y2), (r, 0)), add_points((x2, y2), (-r, 0))), # Vertical lines Line(add_points((x1, y1), (0, r)), add_points((x1, y2), (0, -r))), Line(add_points((x2, y1), (0, r)), add_points((x2, y2), (0, -r))), ] # anti clockwise points starting from top right point anticw_points_from_top_right = [(x2, y1), (x1, y1), (x1, y2), (x2, y2)] # Their differences from center: add them to get corresponding centers center_diffs = [(-r, r), (r, r), (r, -r), (-r, -r)] # Zipped to add them in loop zipped = zip(anticw_points_from_top_right, center_diffs) arcs = [ Arc(add_points(x, y), r, i * math.pi / 2, (i + 1) * math.pi / 2, self.fill) for i, (x, y) in enumerate(zipped) ] return [*lines, *arcs]
def render_object(img, obj): draw = ImageDraw.Draw(img) if obj.type == 'rectangle': draw.rectangle((obj.top_left, obj.bottom_right)) elif obj.type == 'text': draw.text(obj.position, obj.text, font=ImageFont.truetype(obj.font)) elif obj.type == 'line': draw.line(obj.start + obj.end) elif obj.type == 'arc': x0, y0 = add_points(obj.center, (-obj.radius, -obj.radius)) x1, y1 = add_points(obj.center, (obj.radius, obj.radius)) start = rad_to_deg(-obj.end) end = rad_to_deg(-obj.start) draw.arc((x0, y0, x1, y1), start, end) else: [render_object(img, x) for x in obj.primitives]
def primitives(self): if hasattr(self, '_primitives'): return self._primitives arrow_head_length = 7 line_dist = distance(self.start, self.end) factor = arrow_head_length / line_dist # Calculate arrow head lines: # - Take a line from end to start, rotate it 30 deg, and clip it # - Take a line from end to start, rotate it -30 deg, and clip it origin_shifted = add_points(self.start, negate(self.end)) pos_rotated = rotate_point(origin_shifted, math.pi / 6) neg_rotated = rotate_point(origin_shifted, -math.pi / 6) p1 = pos_rotated[0] * factor, pos_rotated[1] * factor p2 = neg_rotated[0] * factor, neg_rotated[1] * factor head1 = add_points(self.end, p1) head2 = add_points(self.end, p2) return [ Line(self.start, self.end), # the main line Line(self.end, head1), Line(self.end, head2), ]
def primitives(self): if hasattr(self, '_primitives'): return self._primitives # No wrap, simple Logic # Calculate text size font = ImageFont.truetype(self.font) text_size = font.getsize( self.text) # equivalent to text's top left at origin # noqa half_text_size = scale_point(text_size, 0.5) text_position = add_points(self.center, negate(half_text_size)) padding = self.padding left = text_position[0] - padding - abs(self.slide) right = text_position[0] + text_size[0] + padding + abs(self.slide) rect_top_left = (left, text_position[1] - padding) rect_bottom_right = (right, text_position[1] + text_size[1] + padding) self._primitives = [ Text(self.text, text_position, self.font), ParalleloGram(rect_top_left, rect_bottom_right, self.slide) ] return self._primitives
def center(self): return scale_point(add_points(self.top_left, self.bottom_right), 0.5)
def center(self): return scale_point(add_points(self.start, self.end), 0.5)