예제 #1
0
    def draw_component(self, g: Graphics, component: Canvas) -> None:
        super().draw_component(g, component)

        if component.image == Nothing:
            return

        image = component.image.unwrap()
        padding = component.resolve_insets(StyleKeys.Padding).value_or(
            Insets(0, 0, 0, 0)) + component.padding

        (x, y, w, h) = component.bounds.tuple

        bounds = Bounds(x + padding.left, y + padding.top,
                        max(w - padding.left - padding.right, 0),
                        max(h - padding.top - padding.bottom, 0))

        (iw, ih) = image.size.tuple
        (w, h) = bounds.size.tuple

        if iw == 0 or ih == 0 or w == 0 or h == 0:
            return

        (x, y) = bounds.location.tuple

        sw = w / iw
        sh = h / ih

        sx = x / sw
        sy = y / sh

        g.scale(sw, sh)
        g.set_source_surface(image.surface, sx, sy)
        g.paint()
예제 #2
0
파일: draw.py 프로젝트: spirali/elsie
def apply_viewbox(ctx: cairo.Context, width: float, height: float,
                  viewbox) -> float:
    viewbox_width = viewbox[2]
    viewbox_height = viewbox[3]
    scale = min(width / viewbox_width, height / viewbox_height)
    ctx.translate(-viewbox[0] * scale, -viewbox[1] * scale)
    ctx.scale(scale, scale)
    translate_x = (width / scale - viewbox_width) / 2
    translate_y = (height / scale - viewbox_height) / 2
    ctx.translate(translate_x, translate_y)
    return scale
예제 #3
0
 def draw(self, ctx: Context, surface: Surface):
     ctx.save()
     ctx.translate(self.translate_x, self.translate_y)
     ctx.rotate(self.rotation)
     ctx.scale(self.width / self.svg_width, self.height / self.svg_height)
     ctx.translate(-self.origin_x, -self.origin_y)
     CairoSVGSurface(self.tree,
                     None,
                     96,
                     output_cairo=surface,
                     output_cairo_context=ctx)
     ctx.restore()
예제 #4
0
    def draw(self, ctx: Context):

        text_baseline = self.get_text_baseline(ctx)

        default_font_max_height = ctx.get_scaled_font().extents()[0]

        text_max_length = float('inf')
        line_string_bottom_length = text_baseline.length

        trimmed = False
        while text_max_length > line_string_bottom_length:
            text_max_length = ctx.text_extents(self.text)[4] / default_font_max_height * self.text_height + \
                              (len(self.text)-1) * self.text_spacing
            if text_max_length > line_string_bottom_length:
                self.text = self.text[:-1].strip()
                trimmed = True

        text_start_interp_pos_min = 0
        text_start_interp_pos_max = line_string_bottom_length - text_max_length
        if self.text_alignment == 'left':
            text_start_interp_pos = self.text_alignment_offset
        elif self.text_alignment == 'center':
            text_start_interp_pos = line_string_bottom_length / 2 - text_max_length / 2 - self.text_alignment_offset
        else:
            text_start_interp_pos = line_string_bottom_length - text_max_length - self.text_alignment_offset
        text_start_interp_pos = min(
            text_start_interp_pos_max,
            max(text_start_interp_pos_min, text_start_interp_pos))

        text_interp_pos = text_start_interp_pos
        for char in self.text:
            char_pos_origin = text_baseline.interpolate(text_interp_pos)
            char_advance_x = ctx.text_extents(
                char)[4] / default_font_max_height * self.text_height
            char_pos_end = text_baseline.interpolate(text_interp_pos +
                                                     char_advance_x)

            ctx.save()
            ctx.translate(char_pos_origin.x, char_pos_origin.y)
            text_angle = math.atan2(char_pos_end.y - char_pos_origin.y,
                                    char_pos_end.x - char_pos_origin.x)
            ctx.rotate(text_angle)
            ctx.scale(1 / default_font_max_height * self.text_height)
            if not trimmed:
                ctx.set_source_rgba(0, 0, 0, 1)
            else:
                ctx.set_source_rgba(0, 0, 0.2, 1)
            ctx.show_text(char)
            ctx.fill()
            ctx.restore()

            text_interp_pos += char_advance_x + self.text_spacing
예제 #5
0
파일: draw.py 프로젝트: spirali/elsie
def transform(
    ctx: cairo.Context,
    point: Tuple[float, float],
    rotation: float = None,
    scale_x=1.0,
    scale_y=1.0,
):
    ctx.translate(point[0], point[1])
    if rotation is not None:
        ctx.rotate(math.radians(rotation))
    if scale_x != 1.0 or scale_y != 1.0:
        ctx.scale(sx=scale_x, sy=scale_y)
    ctx.translate(-point[0], -point[1])
예제 #6
0
 def paint_foreground(self, ctx: Context):
     if self._image:
         sx = self.width / self._image.get_width()
         sy = self.height / self._image.get_height()
         s = min(sx, sy)
         sw = self._image.get_width() * s
         sh = self._image.get_height() * s
         ctx.scale(s, s)
         x = 0
         y = 0
         if self.alignment == Anchor.TOP_LEFT:
             x = 0
             y = 0
         elif self.alignment == Anchor.TOP_CENTER:
             x = (self.width - sw) / 2
             y = 0
         elif self.alignment == Anchor.TOP_RIGHT:
             x = self.width - sw
             y = 0
         elif self.alignment == Anchor.CENTER_LEFT:
             x = 0
             y = (self.height - sh) / 2
         elif self.alignment == Anchor.CENTER_CENTER:
             x = (self.width - sw) / 2
             y = (self.height - sh) / 2
         elif self.alignment == Anchor.CENTER_RIGHT:
             x = (self.width - sw)
             y = (self.height - sh) / 2
         elif self.alignment == Anchor.BOTTOM_LEFT:
             x = 0
             y = self.height - sh
         elif self.alignment == Anchor.BOTTOM_CENTER:
             x = (self.width - sw) / 2
             y = self.height - sh
         elif self.alignment == Anchor.BOTTOM_RIGHT:
             x = self.width - sw
             y = self.height - sh
         x /= s
         y /= s
         ctx.set_source_surface(self._image, x, y)
         ctx.paint()
     else:
         ctx.move_to(0, 0)
         ctx.line_to(self.size.width, self.size.height)
         ctx.stroke()
         ctx.move_to(0, self.size.height)
         ctx.line_to(self.size.width, 0)
         ctx.stroke()
 def _generate_layer(self, transcription, page, layer):
     surface = PDFSurface(layer, *page.page_size)
     context = Context(surface)
     # context.select_font_face('Georgia')
     context.set_source_rgba(1, 1, 1, 1 / 256)  # almost invisible
     context.set_font_size(2)
     for line_ink, line_transcription in zip(page.lines, transcription):
         ink, transformation = writing.normalized(line_ink)
         context.save()
         context.transform(
             Matrix(*(Transformation.translation(
                 0, page.page_size[1]).parameter)))
         context.transform(Matrix(*(Transformation.mirror(0).parameter)))
         context.transform(Matrix(*((~transformation).parameter)))
         context.transform(Matrix(*(Transformation.mirror(0).parameter)))
         HANDWRITING_WIDTH = ink.boundary_box[1]
         TYPEWRITING_WIDTH = context.text_extents(line_transcription)[2]
         context.scale(HANDWRITING_WIDTH / TYPEWRITING_WIDTH, 1)
         context.move_to(0, 0)
         context.show_text(line_transcription)
         context.restore()
     context.stroke()
     context.show_page()
     surface.flush()
예제 #8
0
파일: cairo.py 프로젝트: draustin/otk
def _(d: Scaling, ctx: cairo.Context, scale: float):
    ctx.save()
    ctx.scale(d.x, d.y)
    draw(d.child, ctx, scale)
    ctx.restore()
예제 #9
0
 def draw_text(ctx: Context, text: str, x: float, y: float, scale: float):
     original = ctx.get_matrix()
     ctx.translate(x, y)
     ctx.scale(scale / 10)  # Default font size is 10 mm (1cm)
     ctx.show_text(text)
     ctx.set_matrix(original)
예제 #10
0
 def draw(self, ctx: Context, surface: Surface):
     ctx.save()
     ctx.translate(self.position_x, self.position_y)
     ctx.scale(self.width / self.svg_width, self.height / self.svg_height)
     CairoSVGSurface(self.tree, surface, ctx, 96)
     ctx.restore()