[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