0

I just came across this article saying that subpixel positioning was added to Pango 1.44 in 2019 - not without its issues though. Apparently it is switched off by default. Both articles go as far as saying that the latest master from cairo is needed. Maybe it has been released in the meantime (?).

Two questions actually:

  • Which version / release of Cairo (or pycairo for that matter) do I need for activating this feature? Or do I (still) need to build cairo from (unreleased) master?
  • How do I activate subpixel positioning with Cairo (pycairo) / pangocairo?

There are multiple Python bindings to pangocairo. I am using the following approach in Python 3:

import cairo

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

My text rendering looks about as follows:

_alignments = {
    'tl': lambda width, height: (0.0, 0.0), # top left
    'tc': lambda width, height: (-width / 2, 0.0), # top center
    'tr': lambda width, height: (-width, 0.0), # top right
    'cl': lambda width, height: (0.0, -height / 2), # center left
    'cc': lambda width, height: (-width / 2, -height / 2), # center center
    'cr': lambda width, height: (-width, -height / 2), # center right
    'bl': lambda width, height: (0.0, -height), # bottom left
    'bc': lambda width, height: (-width / 2, -height), # bottom center
    'br': lambda width, height: (-width, -height), # bottom right
}

def make_font(family, size):
    return Pango.font_description_from_string(f'{family:s} {size:.2f}')

font = make_font('Arial', 10.0)
x = 0.0
y = 0.0
angle = 0.0
font_color = (1.0, 0.0, 0.0, 0.5)
text = 'test'

_ctx.save() # _ctx is a cairo.Context object

layout = PangoCairo.create_layout(_ctx)
layout.set_font_description(font)
layout.set_markup(text, -1)

_ctx.set_source_rgba(*font_color)

_, text_extents = layout.get_pixel_extents()
text_width, text_height = text_extents.width, text_extents.height

_ctx.translate(x, y)
if angle != 0.0:
    _ctx.rotate(angle)
_ctx.translate(*self._alignments[alignment](text_width, text_height))
_ctx.move_to(0.0, 0.0)

PangoCairo.show_layout(_ctx, layout)

_ctx.restore()
s-m-e
  • 3,433
  • 2
  • 34
  • 71

1 Answers1

1

Which version / release of Cairo (or pycairo for that matter) do I need for activating this feature? Or do I (still) need to build cairo from (unreleased) master?

Random guess: This is related to src/cairo-ft-font.c in cairo, so I took a quick look at the output of git log src/cairo-ft-font.c. The third entry sounds like what you are looking for:

commit ea9329215d3431ded51a71b724baf0edc25ad633
Author: Matthias Clasen <mclasen@redhat.com>
Date:   Sat Jul 28 12:25:47 2018 +0000

    image compositor: Support subpixel positioning

    Support subpixel positioning with a 4x4 subpixel grid.

    When compositing glyphs in the image compositor,
    we store the subpixel phases in the high bits of the
    glyph index. The _cairo_scaled_glyph_index() macro
    has been updated to discard these bits. By storing
    the phases in the glyph index, the glyph cache just
    keeps working. When loading a glyph, the Freetype
    font backend shifts the outline according to the
    phases.

So, what is the first release that contains this commit?

$ git describe --contains ea9329215d3431ded51a71b724baf0edc25ad633
fatal: cannot describe 'ea9329215d3431ded51a71b724baf0edc25ad633'

Hm, doesn't seem to be in any release, so you need master.

How do I activate subpixel positioning with Cairo (pycairo) / pangocairo?

You don't. As I understand it, it is automatically activated. The question then is: How do I deactivate it? And the answer to that also seems to be "you don't".

Edit: According to https://blogs.gnome.org/mclasen/2019/08/07/pango-1-44-wrap-up/, the answer seems to be (partially) in the function pango_context_set_round_glyph_positions. This seems to handle the Pango and PangoCairo part of the support.

Uli Schlachter
  • 9,337
  • 1
  • 23
  • 39
  • One of the blog posts explicitly says "To address this problem, subpixel positioning is now optional, and off by default". I have also tested this in much length against the latest *releases* of all involved libraries: There is no subpixel positioning for text in my described workflow ... – s-m-e May 07 '20 at 13:51
  • Are you referring to the blog post that says in the next sentence after your quote: "Use pango_context_set_round_glyph_positions (context, FALSE) to turn it on." If so, that seems like an answer to your question. (And, of course, one still needs a cairo version with this support, which is not the latest release) – Uli Schlachter May 07 '20 at 14:04
  • Yep. I need to setup a test system and compile the stuff from scratch. Let's see how far I can get ... – s-m-e May 07 '20 at 14:17
  • From experience, the pycairo API looks a little different in a few places, so it is sometimes hard to figure out the equivalent strategy for pycairo. – s-m-e May 07 '20 at 14:18