0

On a C++ game, we're using Pango to render text with cairo and from there to an OpenGL texture. I noticed this problem recently while working on implementing text-wrapping via Pango.

What I'm doing is calculating the width by translating our own coordinate system to pixels and then using that as a fraction of the window width in PANGO UNITS, or in code:

        float screenEdge = _w * m * static_cast<float>(PANGO_SCALE);
        float tempMaxWidth = _owner->m_wrapping.m_maxWidth;
        tempMaxWidth = std::min(_owner->m_wrapping.m_maxWidth, (0.48f - _owner->dimensions().x1()));
        float wrapWidth = screenEdge * tempMaxWidth;
        maxWidth = static_cast<int>(std::round(wrapWidth));
        pango_layout_set_width(_owner->m_pangoLayout.get(), maxWidth);

Then we get a rectangle from the layout an pass that to cairo with:

        float border = 2.0f;
        PangoRectangle lRec;
        pango_layout_get_pixel_extents(_owner->m_pangoLayout.get(), nullptr, &lRec);
        m_width = (lRec.width + border);  // Add twice half a border for margins
        m_height = (lRec.height + border);
    std::unique_ptr<cairo_surface_t, decltype(&cairo_surface_destroy)> m_cairoSurface(
      cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_width, m_height),
      &cairo_surface_destroy);
    std::unique_ptr<cairo_t, decltype(&cairo_destroy)> m_cairoDc(
      cairo_create(m_cairoSurface.get()),
      &cairo_destroy);
    cairo_set_antialias(m_cairoDc.get(), CAIRO_ANTIALIAS_FAST);
    cairo_push_group_with_content (m_cairoDc.get(), CAIRO_CONTENT_COLOR_ALPHA);
    cairo_set_operator(m_cairoDc.get(), CAIRO_OPERATOR_SOURCE);
    // Add Pango line and path to proper position on the DC
    cairo_move_to(m_cairoDc.get(), (0.5f * border), (0.5f * border));  // Margins needed for border stroke to fit in

But the output, as you can see below, is cut-off; this does not happen if I use PANGO_ALIGN_LEFT Searching around here, I found Cairo + Pango layout non-left alignment

Which appears related to my issue but does not quite provide a solution (or I didn't get it properly); what I tried was to calculate the different between the x and y coordinates of the logical and ink rectangles and adding that to cairo_move_to but that made no real difference in the output, so I just pasted the original code here.

Texture output (should be "Done Loading! Loaded 24 Songs.")

  • You don't happen to have a small, self-contained example program to experiment with, right? All I can guess from your code example is that `m_width` and `m_maxWidth` do not agree with each other, but I cannot really follow the math here, sorry. – Uli Schlachter Dec 18 '20 at 16:19
  • I don't but actually I think I might have found the issue(s); 1) My math was wrong in substracting the offsets but also, there was some old code I'd forgotten about for some home-made alignment by manipulating texture placement directly, so center-aligned text was actually being rendered as if right-aligned. – Gregorio Litenstein Dec 18 '20 at 16:34

0 Answers0