[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