0

I have been chasing a problem between PyCairo and PangoCairo. The following code illustrates it:

import math
import cairo
import gi
gi.require_version('Pango', '1.0')
gi.require_version('PangoCairo', '1.0')
from gi.repository import Pango, PangoCairo

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 400)
ctx = cairo.Context(surface)

# TOP LEFT CIRCLE
ctx.save()
ctx.arc(100.0, 100.0, 50, 0, 2 * math.pi)
ctx.set_source_rgba(0.0, 0.0, 1.0, 1.0)
ctx.set_line_width(2.0)
ctx.stroke()
ctx.restore()

# CENTER TEXT
ctx.save()
layout = PangoCairo.create_layout(ctx)
layout.set_font_description(Pango.font_description_from_string('Arial 10.0'))
layout.set_markup('<b>Foo Bar</b>', -1)
ctx.set_source_rgba(0.0, 1.0, 0.0, 1.0)
_, text_extents = layout.get_pixel_extents()
text_width, text_height = text_extents.width, text_extents.height
ctx.translate(200.0, 200.0)
ctx.translate(-text_width / 2, -text_height / 2)
ctx.move_to(0.0, 0.0)
PangoCairo.show_layout(ctx, layout)
# ctx.stroke() # WHY?
ctx.restore()

# BOTTOM RIGHT CIRCLE
ctx.save()
ctx.arc(300.0, 300.0, 50, 0, 2 * math.pi)
ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
ctx.set_line_width(2.0)
ctx.stroke()
ctx.restore()

surface.write_to_png('test.png')

It results in the following picture:

two circles and text

My intention is to draw two circles and text. The line between the text and the bottom right circle is not intended to exist. I can make the line disappear by adding / uncommenting the ctx.stroke() call directly underneath PangoCairo.show_layout in the center text code block.

It works, but it does not feel right. The text does not require a line stroke. What is going wrong? Is the stroke actually required or have I made another mistake?

s-m-e
  • 3,433
  • 2
  • 34
  • 71

1 Answers1

1

Try ctx.new_path() instead of ctx.stroke().

Showing the layout seems to set the current point and thus the following line_to that arc does implicitly at its beginning actually shows a line.

Uli Schlachter
  • 9,337
  • 1
  • 23
  • 39
  • Yep, this does in fact help - thanks! Is is an "intentional feature" of the layout or rather some kind of bug? – s-m-e Jun 15 '20 at 18:04
  • 1
    I think this is what you call "intentional feature". Look e.g. at `cairo_show_text()`. It only gets the text as an argument. The position that the text is set by a previous call to `cairo_move_to()`. Also, the function moves the current point to "after the text", which is e.g. useful if you want to display more text next. What you are seeing is an interaction between "current point used for drawing text" and "current point used for drawing shapes", which IMO makes sense. – Uli Schlachter Jun 16 '20 at 15:05