Re: Wrong output from cairo_show_glyphs

Marco Botton <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
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;
}

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.