예제 #1
0
    def draw_text(
        self,
        rect,
        x,
        y,
        parsed_text,
        style: TextStyle,
        styles,
        rotation=None,
        scale=None,
        **kwargs,
    ):
        # TODO: try basic Cairo text API
        with ctx_scope(self.ctx):
            layout = build_layout(
                self.reference_ctx,
                self.pctx,
                parsed_text,
                style,
                styles,
                resolution_scale=RESOLUTION_SCALE,
                spacing_scale=self.line_scaling,
                text_scale=scale,
            )
            layout.set_width(to_pango_units(rect.width))
            baseline = from_pango_units(layout.get_baseline())

            if rotation is not None:
                transform(self.ctx, rect.mid_point, rotation=rotation)
            self.ctx.move_to(rect.x, y - baseline)
            pangocairocffi.show_layout(self.ctx, layout)
예제 #2
0
def test_pdf():
    filename = 'tests/output/glyph_item.pdf'
    pt_per_mm = 72 / 25.4
    width, height = 210 * pt_per_mm, 297 * pt_per_mm  # A4 portrait
    surface = cairocffi.PDFSurface(filename, width, height)
    ctx = cairocffi.Context(surface)
    ctx.translate(width / 4, 100)

    layout = pangocairocffi.create_layout(ctx)
    layout.set_width(pangocffi.units_from_double(width / 2))
    layout.set_alignment(pangocffi.Alignment.CENTER)
    layout.set_markup(
        '<span font="italic 30">Hi from Παν語</span>\n'
        '<span font="sans-serif">The text layout engine library for '
        'displaying <span font-weight="bold">multi-language</span> text!\n'
        'Arabic: السَّلام عليكُم\n'
        'Hebrew: שלום\n'
        'Hindi नमस्ते, नमस्कार।\n'
        'Russian: Здравствуйте!\n'
        'Japanese: こんにちは, コンニチハ</span>'
    )

    y_diff = 200
    pangocairocffi.show_layout(ctx, layout)
    ctx.translate(0, y_diff)
    render_run_glyph_items(ctx, layout)
    ctx.translate(0, y_diff)
    render_cluster_glyph_items(ctx, layout)

    surface.finish()
def test_pdf():
    filename = 'tests/output/error_underline.pdf'
    pt_per_mm = 72 / 25.4
    width, height = 45 * pt_per_mm, 10 * pt_per_mm  # A4 portrait
    surface = cairocffi.PDFSurface(filename, width, height)
    ctx = cairocffi.Context(surface)

    layout = pangocairocffi.create_layout(ctx)
    layout.set_width(pangocffi.units_from_double(width))
    layout.set_alignment(pangocffi.Alignment.CENTER)
    layout.set_markup('Hi from Παν語')

    layout_logical_extent = layout.get_extents()[1]
    layout_baseline = pangocffi.units_to_double(layout.get_baseline())
    layout_logical_extent_pixels = _convert_rectangle_to_pixels(
        layout_logical_extent)

    pangocairocffi.show_layout(ctx, layout)

    ctx.set_source_rgb(0.8, 0, 0)
    pangocairocffi.show_error_underline(ctx, layout_logical_extent_pixels[0],
                                        layout_baseline,
                                        layout_logical_extent_pixels[2], 2)

    surface.finish()
예제 #4
0
 def draw(self, canvas: Canvas):
     for pango_object in self.pango_objects:
         canvas.context.save()
         canvas.context.translate(*pango_object.position.pt)
         canvas.context.set_source_rgba(*pango_object.color)
         pangocairocffi.show_layout(canvas.context,
                                    pango_object.pango_layout)
         canvas.context.restore()
예제 #5
0
 def draw(text, width=-1):
     text = html.escape(text)
     if bold:
         text = f'<b>{text}</b>'
     layout.set_width(
         (width - COLUMN_MARGIN) * 1000)  # pixel = 1000 pango units
     layout.set_markup(text, -1)
     PangoCairo.show_layout(context, layout)
     context.rel_move_to(width, 0)
예제 #6
0
def write_text(ctx, text, start_x, start_y):
    ctx.move_to(start_x, start_y)
    layout = pangocairocffi.create_layout(ctx)
    layout.set_width(pangocffi.units_from_double(width))
    #layout.set_alignment(pangocffi.Alignment.CENTER)
    fontdesc = pangocffi.FontDescription()
    fontdesc.set_size(pangocffi.units_from_double(3))
    fontdesc.set_family(font_family)
    layout.set_font_description(fontdesc)
    layout.set_text(text)
    pangocairocffi.show_layout(ctx, layout)
예제 #7
0
def _show_label(
        context: cairocffi.Context,
        position: Tuple[float, float],
        width: float,
        text: str
):
    context.translate(position[0], position[1])
    label = pangocairocffi.create_layout(context)
    label.set_width(pangocffi.units_from_double(width))
    label.set_alignment(pangocffi.Alignment.LEFT)
    label.set_markup('<span font-family="sans-serif">%s</span>' % text)
    pangocairocffi.show_layout(context, label)
    context.translate(-position[0], -position[1])
예제 #8
0
 def text2svg(self):
     """Internally used function.
     Convert the text to SVG using Pango
     """
     size = self.size * 10
     line_spacing = self.line_spacing * 10
     dir_name = config.get_dir("text_dir")
     disable_liga = self.disable_ligatures
     if not os.path.exists(dir_name):
         os.makedirs(dir_name)
     hash_name = self.text2hash()
     file_name = os.path.join(dir_name, hash_name) + ".svg"
     if os.path.exists(file_name):
         return file_name
     surface = cairocffi.SVGSurface(file_name, 600, 400)
     context = cairocffi.Context(surface)
     context.move_to(START_X, START_Y)
     settings = self.text2settings()
     offset_x = 0
     last_line_num = 0
     layout = pangocairocffi.create_layout(context)
     layout.set_width(pangocffi.units_from_double(600))
     for setting in settings:
         family = setting.font
         style = self.str2style(setting.slant)
         weight = self.str2weight(setting.weight)
         text = self.text[setting.start : setting.end].replace("\n", " ")
         fontdesc = pangocffi.FontDescription()
         fontdesc.set_size(pangocffi.units_from_double(size))
         if family:
             fontdesc.set_family(family)
         fontdesc.set_style(style)
         fontdesc.set_weight(weight)
         layout.set_font_description(fontdesc)
         if setting.line_num != last_line_num:
             offset_x = 0
             last_line_num = setting.line_num
         context.move_to(
             START_X + offset_x, START_Y + line_spacing * setting.line_num
         )
         pangocairocffi.update_layout(context, layout)
         if disable_liga:
             text = escape(text)
             layout.set_markup(f"<span font_features='liga=0'>{text}</span>")
         else:
             layout.set_text(text)
         logger.debug(f"Setting Text {text}")
         pangocairocffi.show_layout(context, layout)
         offset_x += pangocffi.units_to_double(layout.get_size()[0])
     surface.finish()
     return file_name
예제 #9
0
 def render_text(self, content: FormattedText, width):
     fontn = pango.FontDescription()
     fontn.set_family(content.font_family)
     fontn.set_size(pango.units_from_double(content.font_size))
     self.pango_context.set_font_description(fontn)
     layout = pango.layout.Layout(self.pango_context)
     layout.set_text(content.text)
     if content.alignment == 'l':
         layout.set_alignment(pango.Alignment.LEFT)
     elif content.alignment == 'c':
         layout.set_alignment(pango.Alignment.CENTER)
     elif content.alignment == 'r':
         layout.set_alignment(pango.Alignment.RIGHT)
     layout.set_width(pango.units_from_double(width))
     pc.update_layout(self.cairo_context, layout)
     pc.show_layout(self.cairo_context, layout)
예제 #10
0
def test_t2s() -> None:
    size = 1
    temp_pango_text = Text("Helloworld", t2s={"world": ITALIC})
    surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH)
    context = cairocffi.Context(surface)
    context.move_to(START_X, START_Y)
    layout = pangocairocffi.create_layout(context)
    layout.set_width(pangocffi.units_from_double(WIDTH))
    fontdesc = pangocffi.FontDescription()
    fontdesc.set_size(pangocffi.units_from_double(size * 10))
    layout.set_font_description(fontdesc)
    layout.set_markup(
        'Hello<span style="italic">world</span>')  # yay, pango markup
    pangocairocffi.show_layout(context, layout)
    surface.finish()
    assert compare_SVGObject_with_PangoText(temp_pango_text, filename)
예제 #11
0
def test_pdf():
    filename = 'tests/output/test.pdf'
    pt_per_mm = 72 / 25.4
    width, height = 210 * pt_per_mm, 297 * pt_per_mm  # A4 portrait
    surface = cairocffi.PDFSurface(filename, width, height)
    context = cairocffi.Context(surface)
    context.translate(0, height / 2)
    context.rotate(-0.1)

    layout = pangocairocffi.create_layout(context)
    layout.set_width(pangocffi.units_from_double(width))
    layout.set_alignment(pangocffi.Alignment.CENTER)
    layout.set_markup('<span font="italic 30">Hi from Παν語</span>')

    pangocairocffi.show_layout(context, layout)

    surface.finish()
예제 #12
0
def test_tabs_replace() -> None:
    """Checks whether are there in end svg image.
    Pango should handle tabs and line breaks."""
    size = 1
    temp_pango_text = Text("hello\thi\nf")
    assert temp_pango_text.text == "hellohif"
    surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH)
    context = cairocffi.Context(surface)
    context.move_to(START_X, START_Y)
    layout = pangocairocffi.create_layout(context)
    layout.set_width(pangocffi.units_from_double(WIDTH))
    fontdesc = pangocffi.FontDescription()
    fontdesc.set_size(pangocffi.units_from_double(size * 10))
    layout.set_font_description(fontdesc)
    layout.set_text("hellohif")
    pangocairocffi.show_layout(context, layout)
    surface.finish()
    assert compare_SVGObject_with_PangoText(temp_pango_text, filename)
예제 #13
0
def test_rtl_text_to_svgobject() -> None:
    """Checks number of submobjects generated when directly
    called using ``SVGMobject``"""
    size = 1
    text = RTL_TEXT.replace("\n", "")
    temp_pango_text = Text(text, size=1)
    surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH)
    context = cairocffi.Context(surface)
    context.move_to(START_X, START_Y)
    layout = pangocairocffi.create_layout(context)
    layout.set_width(pangocffi.units_from_double(WIDTH))
    fontdesc = pangocffi.FontDescription()
    fontdesc.set_size(pangocffi.units_from_double(size * 10))
    layout.set_font_description(fontdesc)
    layout.set_text(text)
    pangocairocffi.show_layout(context, layout)
    surface.finish()
    assert compare_SVGObject_with_PangoText(temp_pango_text, filename)
예제 #14
0
    def paint_foreground(self, ctx: Context):
        layout = self.font.get_layout(self.text, ctx, self.foreground, self.escape)
        if self.h_alignment == TextWidget.HAlignment.LEFT:
            layout.set_alignment(Alignment.LEFT)
        else:
            layout.set_width(round(self.width * 1000))
            if self.h_alignment == TextWidget.HAlignment.CENTER:
                layout.set_alignment(Alignment.CENTER)
            elif self.h_alignment == TextWidget.HAlignment.RIGHT:
                layout.set_alignment(Alignment.RIGHT)

        y = -layout.get_extents()[0].y / 1000
        if self.v_alignment == TextWidget.VAlignment.BOTTOM:
            y += self.height - layout.get_extents()[0].height / 1000
        elif self.v_alignment == TextWidget.VAlignment.CENTER:
            y += (self.height - layout.get_extents()[0].height / 1000) / 2

        ctx.move_to(0, y)
        pangocairo.show_layout(ctx, layout)
예제 #15
0
def test_font_face() -> None:
    """Checks font face using submobject len"""
    size = 1
    text = RTL_TEXT.replace("\n", "")
    font_face = "sans"
    temp_pango_text = Text(text, size=1, font=font_face)
    surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH)
    context = cairocffi.Context(surface)
    context.move_to(START_X, START_Y)
    layout = pangocairocffi.create_layout(context)
    layout.set_width(pangocffi.units_from_double(WIDTH))
    fontdesc = pangocffi.FontDescription()
    fontdesc.set_family(font_face)
    fontdesc.set_size(pangocffi.units_from_double(size * 10))
    layout.set_font_description(fontdesc)
    layout.set_text(text)
    pangocairocffi.show_layout(context, layout)
    surface.finish()
    assert compare_SVGObject_with_PangoText(temp_pango_text, filename)
예제 #16
0
def _show_layout(
        context: cairocffi.Context,
        layout: pangocffi.Layout
):
    context.set_source_rgba(0, 0, 0, 0.9)
    pangocairocffi.show_layout(context, layout)
예제 #17
0
    def textWithoutNewlinesToLines(self,
                                   text: str,
                                   equal_widths=True,
                                   hyphenate=True) -> List[Line]:
        if text.strip() == "":
            return [Line(0, self.params.line_height)]

        ans = []
        layouts = [(word, self.createLayout(word)) for word in text.split(" ")]

        while layouts:
            surf = cairo.RecordingSurface(cairo.CONTENT_ALPHA, None)
            context = cairo.Context(surf)
            context.set_source_rgb(0, 0, 0)

            i = 0
            il = []
            wsum = 0
            for word, layout in layouts:
                _, _, w, h = getLayoutExtent(layout)
                w, h = self._fixXY(w, h)
                if wsum + len(
                        il
                ) * self.params.min_word_gap + w > self.params.line_width:
                    if hyphenate and voikko and "-" not in word:
                        syllables = re.split(r"-", voikko.hyphenate(word))
                        for j in range(len(syllables), 0, -1):
                            text = "".join(syllables[0:j])
                            if len(stripMarkup(text)) <= 1:
                                break

                            new_l = self.createLayout(text + "-")
                            _, _, new_w, new_h = getLayoutExtent(new_l)
                            new_w, new_h = self._fixXY(new_w, new_h)
                            if wsum + len(
                                    il
                            ) * self.params.min_word_gap + new_w <= self.params.line_width:
                                il.append(new_l)
                                wsum += new_w
                                layout.set_markup(
                                    fixMarkup("".join(syllables[j:])))
                                break

                    word_gap = (self.params.line_width - wsum) / (
                        len(il) -
                        1) if len(il) > 1 else self.params.min_word_gap
                    break

                il.append(layout)
                wsum += w
                i += 1

            else:
                word_gap = self.params.min_word_gap

            if i == 0:
                _, _, w, h = getLayoutExtent(layouts[0][1])
                w, h = self._fixXY(w, h)
                il.append(layouts[0][1])
                wsum = w
                i += 1

            x = 0

            if self.params.text_align == "center":
                word_gap = self.params.min_word_gap
                x = (self.params.line_width - wsum -
                     len(il) * self.params.min_word_gap) / 2

            width = -word_gap
            height = self.params.line_height
            for l in il:
                context.translate(*self._fixXY(x, 0))
                #pangocairo.update_context(context, l.get_context())
                pangocairo.show_layout(context, l)
                context.translate(*self._fixXY(-x, 0))
                _, _, w, h = getLayoutExtent(l)
                w, h = self._fixXY(w, h)
                x += word_gap + w
                width += word_gap + w
                if h > height:
                    height = h

            if self.params.text_align == "center":
                width = self.params.line_width

            del layouts[:i]

            if height != self.params.line_height:
                print(f"Liian pitkä rivi: {height} {repr(text)}")

            ans.append(TextLine(surf, width, height,
                                indent=self.params.indent))

        # Aseta rivien leveystiedot yhdenmukaiseksi sarakealgoritmia varten
        if equal_widths:
            width = max(line.width for line in ans)
            for line in ans:
                line.width = width

        return ans