[cairo] Wrong output from cairo_show_glyphs

Marco Botton marco at balsamiq.com
Fri Jun 6 01:48:14 PDT 2014


The following program reproduces the bug. Tested on Ubuntu 12. I am attaching the snapshot too.

I am sure that the bug depends on the combination of FT_Set_Char_Size and cairo_scale. Moving the call to FT_Set_Char_Size to another point or calling it again inside the loop produces different results (different bugs, unfortunately).

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include <ftadvanc.h>
#include <ftsnames.h>
#include <tttables.h>

#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
#include <harfbuzz/hb-glib.h>

#include <cairo/cairo.h>
#include <cairo/cairo-ft.h>

const char *texts[3] = {
    "File", "Edit", "http://"
};

int main () {
    double ptSize      = 13.0;
    int    device_dpi = 72;
    double dpi_scale = device_dpi / 72.;

    FT_Library ft_library;
    assert(!FT_Init_FreeType(&ft_library));

    FT_Face ft_face;
    assert(!FT_New_Face(ft_library, "/usr/share/fonts/truetype/freefont/FreeSans.ttf", 0, &ft_face));
    assert(!FT_Set_Char_Size(ft_face, 0, ptSize*64, device_dpi, device_dpi ));

    cairo_font_face_t *cairo_ft_face;
    cairo_ft_face = cairo_ft_font_face_create_for_ft_face(ft_face, 0);

    hb_font_t *hb_ft_font;
    hb_face_t *hb_ft_face;
    hb_ft_font = hb_ft_font_create(ft_face, NULL);
    hb_ft_face = hb_ft_face_create(ft_face, NULL);

    int width      = 800;
    int height     = 300;

    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
	cairo_t *cr = cairo_create(surface);

    cairo_scale(cr, 2, 2);

    cairo_font_options_t *fontOptions = cairo_font_options_create();
    cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY);
    cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
    cairo_set_font_options(cr, fontOptions);

    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	cairo_paint(cr);

    double x = 10;
    double y = 20;

    int k;
    for (k = 0; k < 3; ++k) {
        x = 10;

        hb_buffer_t *buf = hb_buffer_create();
        hb_buffer_set_unicode_funcs(buf, hb_glib_get_unicode_funcs());
        hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
        hb_buffer_set_script(buf, HB_SCRIPT_LATIN);

        FT_Set_Char_Size(ft_face, 0, ptSize*64, device_dpi, device_dpi );

        hb_buffer_add_utf8(buf, texts[k], strlen(texts[k]), 0, strlen(texts[k]));
        hb_shape(hb_ft_font, buf, NULL, 0);

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info   = hb_buffer_get_glyph_infos(buf, &glyph_count);
        hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions(buf, &glyph_count);
        cairo_glyph_t       *cairo_glyphs = malloc(sizeof(cairo_glyph_t) * glyph_count);

        int j;
        for (j=0; j < glyph_count; ++j) {
            cairo_glyphs[j].index = glyph_info[j].codepoint;
            cairo_glyphs[j].x = (int)(x + (glyph_pos[j].x_offset/64));
            cairo_glyphs[j].y = (int)(y - (glyph_pos[j].y_offset/64));
            x += glyph_pos[j].x_advance/64;
            y -= glyph_pos[j].y_advance/64;
        }

        cairo_set_source_rgba (cr, 0.2, 0.2, 0.2, 1.0);
        cairo_set_font_face(cr, cairo_ft_face);
        cairo_set_font_size(cr, ptSize * dpi_scale);
        cairo_show_glyphs(cr, cairo_glyphs, glyph_count);

        free(cairo_glyphs);
        hb_buffer_destroy(buf);

        y += 36;
    }

    cairo_surface_write_to_png(surface, "./out.png");

    cairo_surface_destroy(surface);
    cairo_destroy(cr);

    cairo_font_face_destroy(cairo_ft_face);
    hb_font_destroy(hb_ft_font);
    hb_face_destroy(hb_ft_face);

    FT_Done_FreeType(ft_library);

    return 0;
}



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20140606/1fe245b2/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-5.png
Type: image/png
Size: 9203 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20140606/1fe245b2/attachment.png>


More information about the cairo mailing list