Tt text causes lines to be shifted vertically
This is a bit of a weird issue. The basic gist is that if you have regular text in Gentium 10 pt and add some text with the tt
attribute, Pango selects Noto Sans Mono, which is a lot taller and causes the entire line to be pushed downwards.
Here is a sample image showing the issue.
The same in PDF is here. pangocairotest.pdf
The code that generates it is this:
#include <pango/pangocairo.h>
#include <cairo-pdf.h>
#include <locale.h>
#include <assert.h>
double mm2pt(const double x) { return x * 2.8346456693; }
double pt2mm(const double x) { return x / 2.8346456693; }
int main() {
setlocale(LC_ALL, "");
// cairo_status_t status;
cairo_surface_t *surface = cairo_pdf_surface_create("pangocairotest.pdf", 595, 842);
cairo_t *cr = cairo_create(surface);
// cairo_set_source_rgb(cr, 1.0, 0.2, 0.1);
printf("PANGO_SCALE = %d\n", PANGO_SCALE);
PangoLayout *layout = pango_cairo_create_layout(cr);
PangoFontDescription *desc;
desc = pango_font_description_from_string("Gentium");
assert(desc);
pango_font_description_set_absolute_size(desc, 10 * PANGO_SCALE);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
cairo_move_to(cr, 72, 72);
pango_layout_set_markup(layout, "This is a line of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 1 * 12);
pango_layout_set_markup(layout, "This is a line of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 2 * 12);
pango_layout_set_markup(layout, "This is a <tt>line</tt> of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 3 * 12);
pango_layout_set_markup(layout, "This is a line of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 4 * 12);
pango_layout_set_markup(
layout, "This is a <span font=\"Noto Sans Mono\" size=\"6pt\">line</span> of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 5 * 12);
pango_layout_set_markup(layout, "This is a line of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 6 * 12);
pango_layout_set_markup(
layout, "This is a <span font=\"Liberation Mono\">line</span> of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_move_to(cr, 72, 72 + 7 * 12);
pango_layout_set_markup(layout, "This is a line of text.", -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
pango_layout_set_attributes(layout, NULL);
cairo_surface_destroy(surface);
cairo_destroy(cr);
return 0;
}
The only way to work around this that I could find was to use span
and manually set the font smaller until it no longer pushed the rest of the line down.
There are many issues to talk about here:
- is it possible to specify what font Pango uses for
tt
(could not find this in the docs) - can you tell Pango to do baseline alignment instead of top alignment, that is, tell it to ignore the height of things inside
tt
(and possibly other) blocks - alternatively can you tell pango that the point where we have
cairo_move_to
d should be the baseline and not the top left corner - can you calculate the extra offset that
tt
adds compared to not using it and compensate for it from the outside (i.e. usingcairo_move_to(cr, x, y - extra_height_from_tt);
- can you ask Pango "how small would I have to make the text inside
tt
so it would not cause line height to change" - are there other, better ways of fixing this
Basically what I (and I'd guess most people) would want is that if you create lines at constant y-offsets then their baselines would be at exactly those offsets and nowhere else.