Exemple #1
0
    def test_layout_iter_properties():
        context = Context()
        layout = Layout(context)
        layout_iter = layout.get_iter()

        assert layout_iter.next_run() is False
        assert layout_iter.next_char() is False
        assert layout_iter.next_cluster() is False
        assert layout_iter.next_line() is False
        assert layout_iter.at_last_line() is True
        assert layout_iter.get_index() == 0
        assert layout_iter.get_baseline() == 0

        assert isinstance(layout_iter.get_char_extents(), Rectangle)

        cluster_ink, cluster_logical = layout_iter.get_cluster_extents()
        assert isinstance(cluster_ink, Rectangle)
        assert isinstance(cluster_logical, Rectangle)

        run_ink, run_logical = layout_iter.get_run_extents()
        assert isinstance(run_ink, Rectangle)
        assert isinstance(run_logical, Rectangle)

        y0, y1 = layout_iter.get_line_yrange()
        assert y0 == 0
        assert y1 == 0

        line_ink, line_logical = layout_iter.get_line_extents()
        assert isinstance(line_ink, Rectangle)
        assert isinstance(line_logical, Rectangle)

        layout_ink, layout_logical = layout_iter.get_layout_extents()
        assert isinstance(layout_ink, Rectangle)
        assert isinstance(layout_logical, Rectangle)
Exemple #2
0
    def test_glyph_item_iterator(self):
        text = 'Hi from Παν語'
        layout = Layout(self.pango_context)
        layout.set_text(text)
        layout_iter = layout.get_iter()

        glyph_item_iter = GlyphItemIter()
        assert isinstance(glyph_item_iter.get_pointer(), ffi.CData)

        assert glyph_item_iter.init_start(
            layout_iter.get_run(),
            text
        )

        assert isinstance(glyph_item_iter.glyph_item, GlyphItem)
        assert glyph_item_iter.text == text

        # Verify first cluster
        assert glyph_item_iter.start_glyph == 0
        assert glyph_item_iter.start_index == 0
        assert glyph_item_iter.start_char == 0
        assert glyph_item_iter.end_glyph == 1
        assert glyph_item_iter.end_index == 1
        assert glyph_item_iter.end_char == 1

        assert not glyph_item_iter.prev_cluster()
        assert glyph_item_iter.next_cluster()

        # Verify second cluster
        assert glyph_item_iter.start_glyph == 1
        assert glyph_item_iter.start_index == 1
        assert glyph_item_iter.start_char == 1
        assert glyph_item_iter.end_glyph == 2
        assert glyph_item_iter.end_index == 2
        assert glyph_item_iter.end_char == 2

        assert glyph_item_iter.init_end(
            layout_iter.get_run(),
            text
        )

        # Verify last cluster
        assert glyph_item_iter.start_glyph == 7
        assert glyph_item_iter.start_index == 7
        assert glyph_item_iter.start_char == 7
        assert glyph_item_iter.end_glyph == 8
        assert glyph_item_iter.end_index == 8
        assert glyph_item_iter.end_char == 8

        assert not glyph_item_iter.next_cluster()
        assert glyph_item_iter.prev_cluster()

        # Verify second to last cluster
        assert glyph_item_iter.start_glyph == 6
        assert glyph_item_iter.start_index == 6
        assert glyph_item_iter.start_char == 6
        assert glyph_item_iter.end_glyph == 7
        assert glyph_item_iter.end_index == 7
        assert glyph_item_iter.end_char == 7
    def test_layout_run_properties(self):
        layout = Layout(self.pango_context)
        layout.set_text('Hello World')
        layout_iter = layout.get_iter()

        layout_run = layout_iter.get_run()
        layout_run_item = layout_run.item
        assert isinstance(layout_run_item, Item)
    def test_glyph_item_copies(self):
        text = 'Hi from Παν語'
        layout = Layout(self.pango_context)
        layout.set_text(text)
        layout_iter = layout.get_iter()
        layout_run = layout_iter.get_run()

        assert layout_run.copy().get_pointer() != layout_run.get_pointer()
    def test_layout_run_from_pointer(self):
        layout = Layout(self.pango_context)
        layout.set_text('Hello World')
        layout_iter = layout.get_iter()

        layout_run = layout_iter.get_run()
        same_layout = LayoutRun.from_pointer(layout_run.get_pointer())

        assert isinstance(same_layout, LayoutRun)
    def test_glyph_item_get_logical_widths(self):
        text = 'Hi from Παν語'
        layout = Layout(self.pango_context)
        layout.set_text(text)
        layout_iter = layout.get_iter()
        layout_run = layout_iter.get_run()
        logical_widths = layout_run.get_logical_widths(text)

        assert len(logical_widths) == 8
        assert isinstance(logical_widths[0], int)
Exemple #7
0
    def test_layout_iter_pointer(self):
        layout = Layout(self.pango_context)
        layout_iter = layout.get_iter()
        assert isinstance(layout_iter, LayoutIter)
        assert isinstance(layout_iter.get_pointer(), ffi.CData)

        pointer_shallow_copy = layout_iter.get_pointer()
        layout_iter_shallow_copy = LayoutIter.from_pointer(
            pointer_shallow_copy
        )
        assert isinstance(layout_iter_shallow_copy, LayoutIter)
        assert isinstance(layout_iter_shallow_copy.get_pointer(), ffi.CData)
Exemple #8
0
def render_cluster_glyph_items(
        ctx: cairocffi.Context,
        layout: pangocffi.Layout
):
    """
    Renders each cluster within a layout with a unique rotation and color.

    Warning: Does not support bidirectional text.

    :param ctx:
        a Cairo context
    :param layout:
        a Pango layout
    """
    layout_run_iter = layout.get_iter()
    layout_cluster_iter = layout.get_iter()
    layout_text = layout.get_text()

    alternate = False
    while True:

        layout_run = layout_run_iter.get_run()
        layout_line_baseline = layout_run_iter.get_baseline()

        if layout_run is None:
            if not layout_run_iter.next_run():
                break
            continue

        clusters = get_clusters_from_glyph_item(layout_run, layout_text)
        for cluster in clusters:
            cluster_extents = layout_cluster_iter.get_cluster_extents()[1]
            layout_cluster_iter.next_cluster()
            alternate = not alternate
            ctx.set_source_rgba(0.5, 0, 1 if alternate else 0.5, 0.9)
            ctx.save()
            ctx.translate(
                pangocffi.units_to_double(cluster_extents.x),
                pangocffi.units_to_double(layout_line_baseline)
            )
            ctx.rotate(-0.05 if alternate else 0.05)
            pangocairocffi.show_glyph_item(
                ctx,
                layout_text,
                cluster
            )
            ctx.restore()

        if not layout_run_iter.next_run():
            break
    def test_glyph_item_splits(self):
        text = 'Hi from Παν語'
        layout = Layout(self.pango_context)
        layout.set_text(text)
        layout_iter = layout.get_iter()
        layout_run = layout_iter.get_run()
        layout_run_hi = layout_run.split(text, 3)

        # Substring "Hi "
        assert layout_run_hi.item.num_chars == 3
        assert layout_run_hi.item.offset == 0

        # Substring "from "
        assert layout_run.item.num_chars == 5
        assert layout_run.item.offset == 3
    def test_layout_setting_text(self):
        layout = Layout(self.pango_context)

        layout.set_text('Hi from Παν語')
        assert layout.get_text() == 'Hi from Παν語'

        layout.set_markup('<span font="italic 30">Hello from Παν語</span>')
        assert layout.get_text() == 'Hello from Παν語'
Exemple #11
0
    def test_layout_setting_text():
        context = Context()
        layout = Layout(context)

        layout.set_width(300)

        layout.set_text('Hi from Pango')
        layout.set_markup('<span font="italic 30">Hi from Παν語</span>')
Exemple #12
0
    def __init__(self, line_string: LineString, layout: Layout):
        if layout.get_line_count() > 1:
            raise ValueError('layout cannot be more than one line.')

        self._layout = layout
        self._input_line_string = line_string

        self._layout_text = layout.get_text()

        self._alignment = Alignment.LEFT
        self._start_offset = 0
        self._vertical_offset = 0
        self._side = Side.LEFT

        self._layout_clusters = LayoutClusters(self._layout)
        self._layout_engine_class = SvgLayoutEngine
        self._layout_engine = None
    def test_item_properties(self):
        layout = Layout(self.pango_context)
        layout.set_text('Hi from Παν語')
        layout_iter = layout.get_iter()

        layout_run = layout_iter.get_run()
        layout_run_item = layout_run.item

        assert layout_run_item.length == 8
        assert layout_run_item.offset == 0
        assert layout_run_item.num_chars == 8
        assert isinstance(layout_run_item.get_pointer(), ffi.CData)

        assert layout_iter.next_run()
        layout_run = layout_iter.get_run()
        layout_run_item = layout_run.item

        assert layout_run_item.length == 6
        assert layout_run_item.offset == 8
        assert layout_run_item.num_chars == 3
        assert isinstance(layout_run_item.get_pointer(), ffi.CData)
Exemple #14
0
def render_run_glyph_items(
        ctx: cairocffi.Context,
        layout: pangocffi.Layout
) -> None:
    """
    Renders each layout run within a layout with a unique rotation and color.

    :param ctx:
        a Cairo context
    :param layout:
        a Pango layout
    """
    layout_iter = layout.get_iter()
    layout_text = layout.get_text()

    alternate = False
    while True:
        layout_run = layout_iter.get_run()
        layout_run_extents = layout_iter.get_run_extents()[1]
        layout_line_baseline = layout_iter.get_baseline()

        if layout_run is None:
            if not layout_iter.next_run():
                break
            continue

        alternate = not alternate
        ctx.set_source_rgba(0, 0.5, 1 if alternate else 0.5, 0.9)
        ctx.save()
        ctx.translate(
            pangocffi.units_to_double(layout_run_extents.x),
            pangocffi.units_to_double(layout_line_baseline)
        )
        ctx.rotate(0.05 if alternate else -0.05)
        pangocairocffi.show_glyph_item(ctx, layout_text, layout_run)
        ctx.restore()

        if not layout_iter.next_run():
            break
Exemple #15
0
def update_layout(cairo_context: cairocffi.Context,
                  layout: pangocffi.Layout) -> None:
    """
    Updates the private Pango ``Context`` of a Pango ``Layout`` created with
    :meth:`create_layout()` to match the current transformation and target
    surface of a Cairo context.

    :param cairo_context:
        a Cairo context
    :param layout:
        a Pango layout
    """
    cairo_t_pointer = _get_cairo_t_from_cairo_ctx(cairo_context)
    pangocairo.pango_cairo_update_layout(cairo_t_pointer, layout.get_pointer())
Exemple #16
0
def show_layout(cairo_context: cairocffi.Context,
                layout: pangocffi.Layout) -> None:
    """
    Draws a Pango Layout in the specified cairo context. The top-left corner
    of the PangoLayout will be drawn at the current point of the cairo context.

    :param cairo_context:
        a Cairo context
    :param layout:
        a Pango layout
    """
    cairo_context_pointer = _get_cairo_t_from_cairo_ctx(cairo_context)
    pangocairo.pango_cairo_show_layout(cairo_context_pointer,
                                       layout.get_pointer())
Exemple #17
0
    def test_layout_iter_properties(self):
        layout = Layout(self.pango_context)
        layout_iter = layout.get_iter()

        assert layout_iter.next_run() is False
        assert layout_iter.next_char() is False
        assert layout_iter.next_cluster() is False
        assert layout_iter.next_line() is False
        assert layout_iter.at_last_line() is True
        assert layout_iter.get_index() == 0
        # Even with no text in the layout, the layout will still have a
        # baseline corresponding to the selected font description.
        assert layout_iter.get_baseline() > 0

        assert isinstance(layout_iter.get_char_extents(), Rectangle)

        cluster_ink, cluster_logical = layout_iter.get_cluster_extents()
        assert isinstance(cluster_ink, Rectangle)
        assert isinstance(cluster_logical, Rectangle)

        run_ink, run_logical = layout_iter.get_run_extents()
        assert isinstance(run_ink, Rectangle)
        assert isinstance(run_logical, Rectangle)

        y0, y1 = layout_iter.get_line_yrange()
        assert y0 == 0
        # Even with no text in the layout, the layout will still have a
        # y-range corresponding to the selected font description.
        assert y1 > 0

        line_ink, line_logical = layout_iter.get_line_extents()
        assert isinstance(line_ink, Rectangle)
        assert isinstance(line_logical, Rectangle)

        layout_ink, layout_logical = layout_iter.get_layout_extents()
        assert isinstance(layout_ink, Rectangle)
        assert isinstance(layout_logical, Rectangle)
Exemple #18
0
def compute_subtext_extents(layout: Layout, parsed_text,
                            id_index: int) -> Tuple[float, float]:
    """
    Returns the x coordinate and width of a subtext of a single line.
    """
    assert layout.get_line_count() == 1
    (start, end) = get_byte_range(parsed_text, id_index)
    iter = layout.get_iter()
    x = None
    width = 0

    while True:
        byte_offset = iter.get_index()
        if start <= byte_offset < end:
            extents = from_pango_rect(iter.get_char_extents())
            if x is None:
                assert start == byte_offset
                x = extents.x
            width += extents.width

        if byte_offset >= end or not iter.next_char():
            break
    assert x is not None
    return (x, width)
Exemple #19
0
def layout_path(cairo_context: cairocffi.Context,
                layout: pangocffi.Layout) -> None:
    """
    Adds the text in a ``Pango.Layout`` to the current path in the specified
    cairo context. The top-left corner of the ``Pango.Layout`` will be at the
    current point of the cairo context.

    :param cairo_context:
        a Cairo context
    :param layout:
        a Pango layout
    """
    cairo_context_pointer = _get_cairo_t_from_cairo_ctx(cairo_context)
    pangocairo.pango_cairo_layout_path(cairo_context_pointer,
                                       layout.get_pointer())
Exemple #20
0
def _show_layout_baseline(
        context: cairocffi.Context,
        layout: pangocffi.Layout
):
    layout_iter = layout.get_iter()
    context.set_line_width(0.5)
    context.set_dash([1, 1])
    while True:
        extents = layout_iter.get_line_extents()
        baseline = layout_iter.get_baseline()
        y_ranges = layout_iter.get_line_yrange()

        context.set_source_rgba(1, 0, 0, 0.9)
        context.move_to(
            pangocffi.units_to_double(extents[0].x),
            pangocffi.units_to_double(y_ranges[0])
        )
        context.line_to(
            pangocffi.units_to_double(extents[0].x + extents[0].width),
            pangocffi.units_to_double(y_ranges[0])
        )
        context.stroke()

        context.set_source_rgba(0, 1, 0, 0.9)
        context.stroke()
        context.move_to(
            pangocffi.units_to_double(extents[0].x),
            pangocffi.units_to_double(baseline)
        )
        context.line_to(
            pangocffi.units_to_double(extents[0].x + extents[0].width),
            pangocffi.units_to_double(baseline)
        )
        context.stroke()

        context.set_source_rgba(0, 0, 1, 0.9)
        context.move_to(
            pangocffi.units_to_double(extents[0].x),
            pangocffi.units_to_double(y_ranges[1])
        )
        context.line_to(
            pangocffi.units_to_double(extents[0].x + extents[0].width),
            pangocffi.units_to_double(y_ranges[1])
        )
        context.stroke()

        if not layout_iter.next_run():
            break
Exemple #21
0
    def test_layout_setting_font_description():
        context = Context()
        layout = Layout(context)

        # Assert that the font description is not set
        assert layout.get_font_description() is None

        # Creating the font description
        desc = FontDescription()
        desc.set_family('sans-serif')
        layout.set_font_description(desc)

        # Verifying the font description was set
        same_desc = layout.get_font_description()
        assert same_desc.get_family() == desc.get_family()

        # Changing the font description
        desc.set_family('serif')
        assert same_desc.get_family() != desc.get_family()

        # Resetting the font description
        layout.set_font_description(None)
        assert layout.get_font_description() is None
Exemple #22
0
def _show_layout_line_logical_extents(
        context: cairocffi.Context,
        layout: pangocffi.Layout
):
    layout_iter = layout.get_iter()
    context.set_line_width(0.5)
    context.set_dash([1, 1])
    alternate = True
    while True:
        alternate = not alternate
        extents = layout_iter.get_line_extents()
        context.set_source_rgba(0, 0, 1 if alternate else 0.5, 0.9)
        _rectangle_path(context, extents[1])
        context.stroke()
        _coordinate_path(context, (extents[1].x, extents[1].y))
        context.fill()

        if not layout_iter.next_run():
            break
Exemple #23
0
def _show_layout_y_ranges(
        context: cairocffi.Context,
        layout: pangocffi.Layout
):
    layout_iter = layout.get_iter()
    context.set_line_width(0.5)
    context.set_dash([1, 1])
    alternate = True
    while True:
        alternate = not alternate
        extents = layout_iter.get_line_extents()
        y_ranges = layout_iter.get_line_yrange()

        context.set_source_rgba(0, 0, 1 if alternate else 0.5, 0.9)
        context.move_to(
            pangocffi.units_to_double(extents[0].x),
            pangocffi.units_to_double(y_ranges[0])
        )
        context.line_to(
            pangocffi.units_to_double(extents[0].x + extents[0].width),
            pangocffi.units_to_double(y_ranges[0])
        )
        context.stroke()

        context.move_to(
            pangocffi.units_to_double(extents[0].x),
            pangocffi.units_to_double(y_ranges[1])
        )
        context.line_to(
            pangocffi.units_to_double(extents[0].x + extents[0].width),
            pangocffi.units_to_double(y_ranges[1])
        )
        context.stroke()

        if not layout_iter.next_run():
            break
Exemple #24
0
def getLayoutExtent(layout: pango.Layout) -> Tuple[float, float, float, float]:
    e = layout.get_extents()
    return (pango.units_to_double(e[1].x), pango.units_to_double(e[1].y),
            pango.units_to_double(e[1].width),
            pango.units_to_double(e[1].height))
Exemple #25
0
def get_extents(layout: pangocffi.Layout, ink=True) -> Rect:
    rect_logical, rect_ink = layout.get_extents()
    return from_pango_rect(rect_ink if ink else rect_logical)
Exemple #26
0
 def test_layout_get_pointer_returns_identical_layout():
     context = Context()
     layout = Layout(context)
     identical_layout = Layout.from_pointer(layout.get_pointer())
     assert identical_layout.get_pointer() == layout.get_pointer()
Exemple #27
0
 def test_layout_not_implemented_equality(self):
     context = Context()
     layout = Layout(context)
     assert ('not an object' != layout)
Exemple #28
0
 def test_layout_returns_identical_context():
     context = Context()
     layout = Layout(context)
     identical_context = layout.get_context()
     assert identical_context.get_pointer() == context.get_pointer()
Exemple #29
0
    def test_layout_setting_properties():
        context = Context()
        layout = Layout(context)

        layout.set_width(300)
        assert layout.get_width() == 300

        layout.set_height(400)
        assert layout.get_height() == 400

        assert layout.get_spacing() == 0
        layout.set_spacing(30)
        assert layout.get_spacing() == 30

        layout.set_alignment(Alignment.CENTER)
        assert layout.get_alignment() is Alignment.CENTER

        layout.set_ellipsize(EllipsizeMode.MIDDLE)
        assert layout.get_ellipsize() is EllipsizeMode.MIDDLE

        ink_rect, logical_rect = layout.get_extents()
        assert logical_rect.width == 0
        assert logical_rect.height == 0

        width, height = layout.get_size()
        assert width == 0
        assert height == 0

        baseline = layout.get_baseline()
        assert baseline == 0

        line_count = layout.get_line_count()
        assert line_count == 1
Exemple #30
0
 def test_layout_returns_null_from_null_pointer(self):
     with self.assertRaises(ValueError):
         Layout.from_pointer(ffi.NULL)