Example #1
0
 def text_height(self, width, pango_context):
     fontn = pango.FontDescription()
     fontn.set_family(self.font_family)
     fontn.set_size(pango.units_from_double(self.font_size))
     pango_context.set_font_description(fontn)
     layout = pango.layout.Layout(pango_context)
     layout.set_width(pango.units_from_double(width))
     layout.set_text(self.text)
     _, raw_height = layout.get_size()
     return pango.units_to_double(raw_height)
Example #2
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)
Example #3
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
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()
Example #5
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)
Example #6
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()
Example #7
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)
Example #8
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)
Example #9
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)
Example #10
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)
Example #11
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])
Example #12
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()
Example #13
0
    def __init__(self, args: Namespace):
        self.width = float(args.width)
        self.height = float(args.height)
        self.margin = float(args.margin)
        self.line_width = float(self.width - 2 * self.margin)
        self.line_height = float(16)
        self.page_height = float(self.height - 2 * self.margin)
        self.pg_gap = float(16)
        self.column_gap = float(10)
        self.min_word_gap = float(5)
        self.indent = float(0)
        self.quote_indent = float(50)
        self.text_align = "justify"
        self.font_size = float(10)

        self.font = "rm"
        self.fonts = {}
        self.fonts["rm"] = pango.FontDescription()
        self.fonts["rm"].set_family(args.font)
        self.fonts["rm"].set_size(pango.units_from_double(10))

        print(f"Paperin koko {self.width}x{self.height}")
        print(f"Piirtoalueen koko {self.line_width}x{self.page_height}")
Example #14
0
 def height(self, x: CanvasUnit):
     self._layout.set_height(pangocffi.units_from_double(x.pt))
Example #15
0
 def addFont(self, varname, fontname):
     print(f"Lisätään fontti {varname} = {repr(fontname)}")
     self.fonts[varname] = pango.FontDescription()
     self.fonts[varname].set_family(fontname)
     self.fonts[varname].set_size(pango.units_from_double(10))
Example #16
0
    def paragraphsToLines(self, paragraphs: List[DocumentObj]):
        all_lines: List[Line] = []
        for i, pg in enumerate(paragraphs):
            print(i + 1, "/", len(paragraphs), end="\r")

            if isinstance(pg, Table):
                if all_lines and all_lines[-1].is_content_line:
                    all_lines.append(
                        ParagraphGap(0, self.params.pg_gap, pg.no_page_break))

                with self._stackFrame():
                    self._getFont().set_size(
                        pango.units_from_double(self.params.font_size))
                    indent = self.params.indent
                    self.params.resetLayout()
                    num_columns = max(len(row) for row in pg.rows)
                    max_line_width = self.params.line_width
                    self.params.line_width = (max_line_width -
                                              self.params.column_gap *
                                              (num_columns - 1)) / num_columns
                    rendered_rows: List[List[List[Line]]] = [
                        [] for _ in range(len(pg.rows))
                    ]
                    for i in range(num_columns):
                        max_width = 0
                        for j in range(len(pg.rows)):
                            if i >= len(pg.rows[j]):
                                pg.rows[j].append(Paragraph.fromText(text=""))

                            rendered_rows[j].append(
                                self.paragraphsToLines([pg.rows[j][i]]))
                            width = rendered_rows[j][i][
                                0].width if rendered_rows[j][i] else 0
                            if width > max_width:
                                max_width = width

                        for rrow in rendered_rows:
                            for line in rrow[i]:
                                line.width = max_width

                        if i != num_columns - 1:
                            self.params.line_width = (
                                max_line_width - max_width -
                                self.params.column_gap *
                                (num_columns - i - 1)) / (num_columns - i - 1)

                    lines = []
                    for rrow in rendered_rows:
                        for i in range(max(len(c) for c in rrow)):
                            column_lines: List[Line] = [
                                c[i] if i < len(c) else Line(
                                    c[0].width if c else 0,
                                    self.params.line_height) for c in rrow
                            ]
                            lines.append(
                                ColumnLine(column_lines,
                                           self.params.column_gap,
                                           indent=indent))
                            lines[-1].no_page_break = pg.no_page_break

            elif isinstance(pg, Paragraph):
                if all_lines and all_lines[-1].is_content_line:
                    all_lines.append(
                        ParagraphGap(0, self.params.pg_gap, pg.no_page_break))

                with self._stackFrame():

                    if pg.type != "text":
                        level, self.params.font_size, self.params.line_height, self.params.text_align = TITLES[
                            pg.type]

                    else:
                        level = -1

                    self._getFont().set_size(
                        pango.units_from_double(self.params.font_size))

                    lines = self.textToLines(pg.text, hyphenate=level < 0)
                    if lines:
                        lines[0].no_page_break = pg.no_page_break
                        if level >= 0:
                            lines[0].outline = (level, pg.text)

                        if "title" in pg.type:
                            for line in lines[1:]:
                                line.no_page_break = True

            elif isinstance(pg, VSpace):
                lines = [
                    Line(self.params.line_width, pg.height
                         or self.params.line_height)
                ]

            elif isinstance(pg, Eval):
                pg.func(self.params)
                lines = []

            elif isinstance(pg, Subenvironment):
                with self._stackFrame():
                    lines = self.paragraphsToLines(pg.paragraphs)

            else:
                print(f"Tuntematon kappaletyyppi {type(pg)}")
                lines = []

            all_lines += lines

        return all_lines
Example #17
0
def test_pdf():
    filename = 'tests/output/extents.pdf'
    pt_per_mm = 72 / 25.4
    width, height = 210 * pt_per_mm, 400 * pt_per_mm  # A4 portrait
    surface = cairocffi.PDFSurface(filename, width, height)
    ctx = cairocffi.Context(surface)
    ctx.translate(width / 2, 10)

    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'
                      'The text layout engine library for displaying '
                      '<span font-weight="bold">multi-language</span> text!')

    translate_y = 110
    label_pos = (-width / 2 + 30, 30)
    label_width = width / 2.5

    _show_layout_logical_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout (logical extents)')
    ctx.translate(0, translate_y)

    _show_layout_ink_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout (ink extents)')
    ctx.translate(0, translate_y)

    _show_layout_line_logical_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout Line (logical extents)')
    ctx.translate(0, translate_y)

    _show_layout_line_ink_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout Line (ink extents)')
    ctx.translate(0, translate_y)

    _show_layout_baseline(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(
        ctx,
        label_pos,
        label_width,
        'y-range (top), Baseline,\ny-range (bottom)'
    )
    ctx.translate(0, translate_y)

    _show_run_logical_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout Run (logical extents)')
    ctx.translate(0, translate_y)

    _show_run_ink_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Layout Run (ink extents)')
    ctx.translate(0, translate_y)

    _show_cluster_logical_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Cluster (logical extents)')
    ctx.translate(0, translate_y)

    _show_cluster_ink_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Cluster (ink extents)')
    ctx.translate(0, translate_y)

    _show_character_extents(ctx, layout)
    _show_layout(ctx, layout)
    _show_label(ctx, label_pos, label_width, 'Character extents')
    ctx.translate(0, translate_y)

    surface.finish()
Example #18
0
def test_context_properties():
    assert pangocffi.units_from_double(0) == 0
    assert pangocffi.units_from_double(0.1201171875) == 123
 def test_pango_scale_is_consistent_with_library(self):
     assert CanvasUnit.from_pt(2).pango == pangocffi.units_from_double(2)
     assert CanvasUnit.from_pango(512).pt == pangocffi.units_to_double(512)
Example #20
0
 def width(self, x: CanvasUnit):
     self._layout.set_width(pangocffi.units_from_double(x.pt))
Example #21
0
def to_pango_units(size: float) -> int:
    return pangocffi.units_from_double(size)
Example #22
0
def test_attributes():
    width = 150
    height = 50
    # CFFIs and Contexts
    context_creator = ContextCreator.create_pdf(
        'tests/acceptance/output/attributes.pdf', width, height)
    pangocairo = context_creator.pangocairo
    cairo_context = context_creator.cairo_context

    text = 'Hi from Παν語! This test is to make sure that text is correctly ' \
           'annotated, and to also highlight functionality that is not ' \
           'available from methods like pango.set_markup(\'...\'). ' \
           'For instance, Attribute.from_shape() allows you to embed a ' \
           'picture or a widget in a layout. Example: Ø.'
    text_utf8 = text.encode('utf-8')

    # Using pangocairocffi, this would be `pangocairocffi.create_layout()` with
    # a cairocffi context object.
    layout = Layout.from_pointer(
        pangocairo.pango_cairo_create_layout(cairo_context))

    layout.set_width(pangocffi.units_from_double(width * 72 / 25.4))
    layout.set_text(text)

    attr_list = AttrList()

    # Example: Handling byte indexes correctly.
    # When handling byte indexes, make sure to always use UTF-8 byte strings.
    # For example , while the string '語' has a length of 1 character in
    # python, in a UTF-8 byte string this is 3 bytes: `0xe8 0xaa 0x9e`. Pango
    # will not like byte indexes that occur in the middle of a character.
    text_to_match = 'Παν語!'.encode('utf-8')
    match_index = text_utf8.index(text_to_match)
    match_index_end = match_index + len(text_to_match)
    attr_list.insert(
        Attribute.from_style(Style.ITALIC, match_index, match_index_end))

    # Example: Color alpha
    # `set_markup()` doesn't appear to have the ability to control color
    # alphas, but it is supported by Attributes! Note that the alpha color for
    # underline and foreground text cannot be controlled separately.
    text_to_match = 'correctly'.encode('utf-8')
    match_index = text_utf8.index(text_to_match)
    match_index_end = match_index + len(text_to_match)
    attr_list.insert(
        Attribute.from_underline(Underline.ERROR, match_index,
                                 match_index_end))
    attr_list.insert(
        Attribute.from_foreground_color(65535, 0, 0, match_index,
                                        match_index_end))
    attr_list.insert(
        Attribute.from_underline_color(0, 0, 65535, match_index,
                                       match_index_end))
    attr_list.insert(
        Attribute.from_background_color(0, 65535, 0, match_index,
                                        match_index_end))
    attr_list.insert(
        Attribute.from_foreground_alpha(32768, match_index, match_index_end))
    attr_list.insert(
        Attribute.from_background_alpha(8192, match_index, match_index_end))

    # Example: Highlight multiple Monospace texts
    markup_texts = ('pango.set_markup(\'...\')', 'Attribute.from_shape()')
    for markup_text in markup_texts:
        text_to_match = markup_text.encode('utf-8')
        match_index = text_utf8.index(text_to_match)
        match_index_end = match_index + len(text_to_match)
        attr_list.insert(
            Attribute.from_family('monospace', match_index, match_index_end))

    # Example: Shape placeholders
    # `Attribute.from_shape()` can be used to insert a box within the layout.
    # In this case, we're inserting a 1cm square that sits on the baseline of
    # the final line. Note the negative y coordinate of the rectangle.
    # Visually, the background color will appear a bit larger, that's because
    # it will also apply a background below the baseline of the font.
    # Once rendered, it should be possible to retrieve the position of the
    # shape using using LayoutIter so that an actual image can be rendered in
    # place should you need to.
    text_to_match = 'Ø'.encode('utf-8')
    match_index = text_utf8.index(text_to_match)
    match_index_end = match_index + len(text_to_match)
    glyph_length = pangocffi.units_from_double(10 * 72 / 25.4)  # 10 mm
    ink = Rectangle(width=glyph_length,
                    height=glyph_length,
                    x=0,
                    y=-glyph_length)
    logical = Rectangle(width=glyph_length,
                        height=glyph_length,
                        x=0,
                        y=-glyph_length)
    attr_list.insert(
        Attribute.from_background_color(65535, 0, 0, match_index,
                                        match_index_end))
    attr_list.insert(
        Attribute.from_background_alpha(8192, match_index, match_index_end))
    attr_list.insert(
        Attribute.from_shape(ink, logical, match_index, match_index_end))

    # Apply all the attributes to the layout
    layout.set_attributes(attr_list)

    # Using pangocairocffi, this would be `pangocairocffi.show_layout(layout)`
    pangocairo.pango_cairo_show_layout(cairo_context, layout.get_pointer())

    context_creator.close()