[cairo] Trouble using scaled fonts with Xlib backend
cecashon at aol.com
cecashon at aol.com
Wed Feb 5 22:35:14 UTC 2020
Hi Johann,
Have you tested on another back end? If so, are the results different?
I gave it a try and got similar results.
cairo_scaled_font_create() says
"Creates a cairo_scaled_font_t object from a font face and matrices that describe the size of the font and the environment in which it will be used."
Then cairo_set_scaled_font() says
"the current CTM of the cairo_t should be the same as that of the cairo_scaled_font_t, which can be accessed using cairo_scaled_font_get_ctm()."
It sounds like you should get the ctm from the cairo_scaled_font_t pointer and this does work. It is confusing though when you don't get a ctm back with a cairo_set_scaled_font()/cairo_get_scaled_font() pair. Seems like a bug to me.
Eric
/*
Test a scaled font. A problem getting the scaled font ctm back with a cairo_set_scaled_font()
cairo_get_scaled_font() pair.
gcc -Wall -g font_scale1.c -o font_scale1 -I/usr/include/freetype2 `pkg-config --cflags --libs cairo fontconfig` -lfreetype
Tested on Ubuntu18.04
*/
#include<cairo.h>
#include<cairo-ft.h>
#include<stdio.h>
#include<ft2build.h>
#include FT_FREETYPE_H
#include<fontconfig/fontconfig.h>
static double width=500.0;
static double height=500.0;
static void draw_font(cairo_t *cr, double scale_ctm_x, double scale_ctm_y, cairo_scaled_font_t *sf);
int main()
{
//Starting font.
char *font="/usr/share/fonts/truetype/freefont/FreeSansBold.ttf";
FT_Error error;
FT_Library library;
FT_Face face;
error=FT_Init_FreeType(&library);
if(error) printf("Init_FreeType Error\n");
error=FT_New_Face(library, font, 0, &face);
if(error==FT_Err_Ok) printf("New font face.\n");
else printf("Cannot open font.\n");
cairo_surface_t *surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cr=cairo_create(surface);
//Paint the background.
cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
cairo_paint(cr);
//Cartesian coordinates.
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_move_to(cr, 0.0, height/2.0);
cairo_line_to(cr, width, height/2.0);
cairo_stroke(cr);
cairo_move_to(cr, width/2.0, 0.0);
cairo_line_to(cr, width/2.0, height);
cairo_stroke(cr);
//Test changing the scale values for the scaled font.
cairo_matrix_t fm, cm, sm;
double scale_ctm_x=1.5;
double scale_ctm_y=1.5;
cairo_matrix_init_scale(&fm, 30.0, 30.0);
cairo_matrix_init_scale(&cm, scale_ctm_x, scale_ctm_y);
cairo_font_options_t *fo=cairo_font_options_create();
cairo_font_face_t *ff=cairo_ft_font_face_create_for_ft_face(face, 0);
cairo_scaled_font_t *sf=cairo_scaled_font_create(ff, &fm, &cm, fo);
//Draw the scaled font.
cairo_save(cr);
cairo_translate(cr, width/2.0, height/2.0);
cairo_set_scaled_font(cr, sf);
cairo_transform(cr, &cm);
cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 1.0);
cairo_text_extents_t ex;
cairo_text_extents(cr, "Scaled Font", &ex);
cairo_move_to(cr, -0.5*ex.width, 0.0);
cairo_show_text(cr, "Scaled Font");
cairo_restore(cr);
//Look at the matrices.
printf("font matrix1 %f %f %f %f %f %f\n", fm.xx, fm.xy, fm.x0, fm.yx, fm.yy, fm.y0);
printf("current matrix2 %f %f %f %f %f %f\n", cm.xx, cm.xy, cm.x0, cm.yx, cm.yy, cm.y0);
cairo_matrix_multiply(&sm, &fm, &cm);
printf("scale matrix3 %f %f %f %f %f %f\n", sm.xx, sm.xy, sm.x0, sm.yx, sm.yy, sm.y0);
//Draw some extra text.
draw_font(cr, scale_ctm_x, scale_ctm_y, sf);
//Output the results.
printf("Output to font_scale1.png\n");
cairo_surface_write_to_png(surface, "font_scale1.png");
//Clean up.
cairo_font_options_destroy(fo);
cairo_font_face_destroy(ff);
cairo_scaled_font_destroy(sf);
cairo_destroy(cr);
cairo_surface_destroy(surface);
if(face!=NULL) FT_Done_Face(face);
if(library!=NULL) FT_Done_FreeType(library);
//Clear some caches for valgrind.
cairo_debug_reset_static_data();
FcFini();
return 0;
}
static void draw_font(cairo_t *cr, double scale_ctm_x, double scale_ctm_y, cairo_scaled_font_t *sf)
{
//Use sf pointer to get the matrices.
cairo_matrix_t fm, cm, sm;
cairo_scaled_font_get_font_matrix(sf, &fm);
cairo_scaled_font_get_ctm(sf, &cm);
cairo_scaled_font_get_scale_matrix(sf, &sm);
printf("font matrix2 %f %f %f %f %f %f\n", fm.xx, fm.xy, fm.x0, fm.yx, fm.yy, fm.y0);
printf("current matrix2 %f %f %f %f %f %f\n", cm.xx, cm.xy, cm.x0, cm.yx, cm.yy, cm.y0);
printf("scale matrix2 %f %f %f %f %f %f\n", sm.xx, sm.xy, sm.x0, sm.yx, sm.yy, sm.y0);
cairo_save(cr);
cairo_text_extents_t ex;
cairo_translate(cr, width/2.0, height/2.0);
cairo_set_scaled_font(cr, sf);
cairo_transform(cr, &cm);
cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 1.0);
cairo_text_extents(cr, "Scaled Font", &ex);
cairo_move_to(cr, -0.5*ex.width, ex.height);
cairo_show_text(cr, "Scaled Font");
cairo_restore(cr);
//Set the scaled font and then get it back. This doesn't get the scaled font ctm.
cairo_set_scaled_font(cr, sf);
cairo_scaled_font_t* sf2=cairo_get_scaled_font(cr);
cairo_scaled_font_get_font_matrix(sf2, &fm);
cairo_scaled_font_get_ctm(sf2, &cm);
cairo_scaled_font_get_scale_matrix(sf2, &sm);
printf("font matrix3 %f %f %f %f %f %f\n", fm.xx, fm.xy, fm.x0, fm.yx, fm.yy, fm.y0);
printf("current matrix3 %f %f %f %f %f %f\n", cm.xx, cm.xy, cm.x0, cm.yx, cm.yy, cm.y0);
printf("scale matrix3 %f %f %f %f %f %f\n", sm.xx, sm.xy, sm.x0, sm.yx, sm.yy, sm.y0);
cairo_translate(cr, width/2.0, height/2.0);
cairo_set_scaled_font(cr, sf);
cairo_transform(cr, &cm);
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, "Scaled Font", &ex);
cairo_move_to(cr, -0.5*ex.width, 3.0*ex.height);
cairo_show_text(cr, "Scaled Font");
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20200205/bfa3c716/attachment.htm>
More information about the cairo
mailing list