/* * Derived from: * ft-text-vertical-layout-type1.c * cairo_snippets_image.c * cairo_snippets_pdf.c * cairo_snippets_ps.c * Original Author: * Jinghua Luo * Carl D. Worth * Øyvind Kolås * Usage: gcc `pkg-config --cflags cairo freetype2` `pkg-config --libs cairo freetype2` cairo_bitmap_font_scale.c -o cairo_bitmap_font_scale */ #define WIDTH 600 #define HEIGHT 400 #define TEXT "Text" #include #include #include #include #include static cairo_status_t create_scaled_font (cairo_t * cr, cairo_scaled_font_t **out) { FcPattern *pattern, *resolved; FcResult result; cairo_font_face_t *font_face; cairo_scaled_font_t *scaled_font; cairo_font_options_t *font_options; cairo_matrix_t font_matrix, ctm; cairo_status_t status; double pixel_size; font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); pattern = FcPatternCreate (); if (pattern == NULL) return CAIRO_STATUS_NO_MEMORY; FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)"Courier"); FcPatternAddDouble (pattern, FC_PIXEL_SIZE, 30); FcConfigSubstitute (NULL, pattern, FcMatchPattern); cairo_ft_font_options_substitute (font_options, pattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (NULL, pattern, &result); if (resolved == NULL) { FcPatternDestroy (pattern); return CAIRO_STATUS_NO_MEMORY; } /* set layout to vertical */ FcPatternDel (resolved, FC_VERTICAL_LAYOUT); FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue); FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size); font_face = cairo_ft_font_face_create_for_pattern (resolved); cairo_matrix_init_translate (&font_matrix, 10, 30); cairo_matrix_rotate (&font_matrix, M_PI_2/3); cairo_matrix_scale (&font_matrix, pixel_size, pixel_size); cairo_get_matrix (cr, &ctm); scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, font_options); cairo_font_options_destroy (font_options); cairo_font_face_destroy (font_face); FcPatternDestroy (pattern); FcPatternDestroy (resolved); status = cairo_scaled_font_status (scaled_font); if (status) { cairo_scaled_font_destroy (scaled_font); return status; } *out = scaled_font; return CAIRO_STATUS_SUCCESS; } void show_text (cairo_t *cr, double x, double y, double scale) { double line_width; cairo_text_extents_t extents; line_width = cairo_get_line_width (cr); cairo_save (cr); cairo_scale(cr, scale, scale); cairo_move_to (cr, x, y); cairo_show_text (cr, TEXT); cairo_text_extents (cr, TEXT, &extents); cairo_rectangle (cr, x + extents.x_bearing - line_width / 2, y + extents.y_bearing - line_width / 2, extents.width + line_width, extents.height + line_width); cairo_stroke (cr); cairo_restore (cr); } void draw (cairo_t *cr) { cairo_scaled_font_t *scaled_font; cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); create_scaled_font (cr, &scaled_font); cairo_set_scaled_font (cr, scaled_font); cairo_set_source_rgb (cr, 0, 0, 0); /* black */ show_text(cr, 100.0, 0.0, 1.0); show_text(cr, 100.0, 0.0, 2.0); show_text(cr, 1000.0, 0.0, 0.3); cairo_scaled_font_destroy (scaled_font); } int main () { cairo_t *cr; cairo_surface_t *surface; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); cr = cairo_create (surface); cairo_save (cr); draw (cr); cairo_surface_write_to_png (surface, "mytest.png"); cairo_restore (cr); cairo_destroy (cr); cairo_surface_destroy (surface); surface = cairo_pdf_surface_create ("mytest.pdf", WIDTH, HEIGHT); cr = cairo_create (surface); cairo_save (cr); draw (cr); cairo_show_page (cr); cairo_restore (cr); cairo_destroy (cr); cairo_surface_destroy (surface); surface = cairo_ps_surface_create ("mytest.ps", WIDTH, HEIGHT); cr = cairo_create (surface); cairo_save (cr); draw (cr); cairo_show_page (cr); cairo_restore (cr); cairo_destroy (cr); cairo_surface_destroy (surface); return 0; }