Hi.
I’m working on a 3D OpenGL application that runs on Windows. I’m attempting to use pango to render rich formatted text to an transparent 32-bit offscreen bitmap which can then be plonked onto a 3D surface as an OpenGL texture.
I wrote the following test code to generate a 100x100 test bitmap.
#include <vector>
#include <functional>
#include <glib.h>
#include <pango/pangocairo.h>
#include <gsl/gsl>
int main(int argc, char **argv)
{
const int cx = 100;
const int cy = 100;
// Create Cairo surface.
const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, cx);
std::vector<unsigned char> buffer(static_cast<size_t>(stride * cy), 0);
cairo_surface_t *surface = cairo_image_surface_create_for_data(buffer.data(), CAIRO_FORMAT_ARGB32,
cx, cy, stride);
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
return 1;
auto destroySurface = gsl::finally([surface]() { cairo_surface_destroy(surface); });
cairo_t *cairo = cairo_create(surface);
if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS)
return 1;
auto destroyCairo = gsl::finally([cairo]() { cairo_destroy(cairo); });
// Setup Pango using Cairo renderer.
PangoLayout *layout = pango_cairo_create_layout(cairo);
if (!layout)
return 1;
auto releaseLayout = gsl::finally([layout]() { g_object_unref(layout); });
pango_layout_set_width(layout, cx * PANGO_SCALE); // Set max width for layout before it wraps.
static const char *markupText =
"<span font_desc=\"Dejavu Sans 12\"><span foreground=\"#ff8040\">Pango</span> + <span foreground=\"#4080ff\">Cairo</span> Test Text</span>";
pango_layout_set_markup(layout, markupText, -1);
// Update/layout the pango layout and render with Cairo to our bitmap.
pango_cairo_update_layout(cairo, layout);
pango_cairo_show_layout(cairo, layout);
cairo_surface_write_to_png(surface, "test.png");
return 0;
}
I chose a low resolution initially to ensure the anti-aliasing looked okay (per-pixel alpha). I would of course want something higher quality eventually. Since I am rendering to an offscreen bitmap sub-pixel rendering isn’t desirable. I’m hoping this whole idea makes sense.
Unfortunately I immediately noticed some green discolouration around the edges of the coloured text. Using cairo_surface_write_to_png
to write the surface to a png I get the following:
https://imgur.com/Eat1w5X
On an Arch Linux machine running the exact same code I get the following:
https://imgur.com/XdGzFJo
On Windows I am using pango 1.50.7 and cairo 1.17.6 from vcpkg. On Arch Linux I am using pango 1.50.8 and cairo 1.17.6 from the Arch repos.
Am I doing something wrong here, or have I stumbled across a bug?