diff options
Diffstat (limited to 'test/user-font-color.c')
-rw-r--r-- | test/user-font-color.c | 232 |
1 files changed, 143 insertions, 89 deletions
diff --git a/test/user-font-color.c b/test/user-font-color.c index c35e693be..db8b6a173 100644 --- a/test/user-font-color.c +++ b/test/user-font-color.c @@ -32,16 +32,27 @@ #include "cairo-test.h" +#include <ctype.h> #include <stdlib.h> #include <stdio.h> #define BORDER 10 #define TEXT_SIZE 64 -#define WIDTH (TEXT_SIZE * 12 + 2*BORDER) -#define HEIGHT (TEXT_SIZE + 2*BORDER) +#define WIDTH (TEXT_SIZE * 11 + 2*BORDER) +#define HEIGHT (4*TEXT_SIZE + 5*BORDER) -#define TEXT "abcdefghijkl" +#define TEXT "abcdefghij" + +/* These characters will be drawn twice with a different foreground color */ +#define FG_TEXT "acfh" + +/* Uppercase draws the same text but forces the use of the non-color + * render callback */ +#define TEXT_NO_COLOR "ABCDEFGHIJ" +#define FG_TEXT_NO_COLOR "ACFH" + +#define TEXT_PATH "aabccdeffghhij" static cairo_status_t @@ -55,40 +66,60 @@ test_scaled_font_init (cairo_scaled_font_t *scaled_font, } static void -render_glyph_solid (cairo_t *cr, double width, double height, cairo_bool_t color) +render_glyph_solid (cairo_t *cr, + double width, + double height, + cairo_bool_t color, + cairo_scaled_font_t *scaled_font) { - cairo_pattern_t *pattern = cairo_pattern_reference(cairo_get_source (cr)); - if (color) - cairo_set_source_rgba (cr, 0, 1, 1, 0.5); + cairo_set_source_rgba (cr, 0.7, 0.2, 0.1, 0.9); cairo_rectangle (cr, 0, 0, width/2, height/2); cairo_fill (cr); - /* Draw the middle rectangle using the foreground color */ - if (color) - cairo_set_source (cr, pattern); + if (color) { + if (scaled_font) + cairo_set_source (cr, cairo_user_scaled_font_get_foreground_marker (scaled_font)); + else + cairo_set_source_rgba (cr, 0.2, 0.5, 0.3, 0.9); + } cairo_rectangle (cr, width/4, height/4, width/2, height/2); cairo_fill (cr); if (color) - cairo_set_source_rgba (cr, 1, 1, 0, 0.5); + cairo_set_source_rgba (cr, 0.2, 0.3, 0.5, 0.9); cairo_rectangle (cr, width/2, height/2, width/2, height/2); cairo_fill (cr); - - cairo_pattern_destroy (pattern); } static void -render_glyph_linear (cairo_t *cr, double width, double height, cairo_bool_t color) +render_glyph_linear (cairo_t *cr, + double width, + double height, + cairo_bool_t color, + cairo_scaled_font_t *scaled_font) { cairo_pattern_t *pat; + cairo_pattern_t *fg; pat = cairo_pattern_create_linear (0.0, 0.0, width, height); - cairo_pattern_add_color_stop_rgba (pat, 0, 1, 0, 0, 1); - cairo_pattern_add_color_stop_rgba (pat, 0.5, 0, 1, 0, color ? 0.5 : 1); - cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 1, 1); - cairo_set_source (cr, pat); + if (scaled_font) { + double r, g, b, a; + + fg = cairo_user_scaled_font_get_foreground_source (scaled_font); + if (cairo_pattern_get_rgba (fg, &r, &g, &b, &a) != CAIRO_STATUS_SUCCESS) { + r = g = b = 0; + a = 1; + } + cairo_pattern_add_color_stop_rgba (pat, 0, r, g, b, a); + cairo_pattern_add_color_stop_rgb (pat, 1, 0, 0, 1); + } else { + cairo_pattern_add_color_stop_rgb (pat, 0, 1, 0.4, 0.2); + cairo_pattern_add_color_stop_rgb (pat, 0.5, 0.2, 1, 0.4); + cairo_pattern_add_color_stop_rgb (pat, 1, 0.2, 0.3, 1); + } + cairo_set_source (cr, pat); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); } @@ -102,23 +133,23 @@ render_glyph_text (cairo_t *cr, double width, double height, cairo_bool_t color) cairo_set_font_size(cr, 0.5); if (color) - cairo_set_source_rgb (cr, 0.5, 0.5, 0); + cairo_set_source_rgb (cr, 0.5, 0.7, 0); cairo_move_to (cr, width*0.1, height/2); cairo_show_text (cr, "a"); if (color) - cairo_set_source_rgb (cr, 0, 0.5, 0.5); + cairo_set_source_rgb (cr, 0, 0.5, 0.7); cairo_move_to (cr, width*0.4, height*0.9); cairo_show_text (cr, "z"); } static cairo_status_t -test_scaled_font_render_color_glyph (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *metrics) +test_scaled_font_render_glyph_common (cairo_scaled_font_t *scaled_font, + unsigned long glyph, + cairo_t *cr, + cairo_text_extents_t *metrics, + cairo_bool_t color) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; double width = 0.5; double height = 0.8; @@ -126,102 +157,81 @@ test_scaled_font_render_color_glyph (cairo_scaled_font_t *scaled_font, cairo_translate (cr, 0.125, -0.6); switch (glyph) { case 'a': - render_glyph_solid (cr, width, height, TRUE); + render_glyph_solid (cr, width, height, color, scaled_font); break; case 'b': - render_glyph_linear (cr, width, height, TRUE); + render_glyph_solid (cr, width, height, color, NULL); break; case 'c': - render_glyph_text (cr, width, height, TRUE); + render_glyph_linear (cr, width, height, color, scaled_font); break; - - /* Ensure that the following glyphs are rendered with - * test_scaled_font_render_glyph() even if we draw - * something before returning. - */ case 'd': - render_glyph_solid (cr, width, height, TRUE); - status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; + render_glyph_linear (cr, width, height, color, NULL); break; case 'e': - render_glyph_linear (cr, width, height, TRUE); - status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; + render_glyph_text (cr, width, height, color); break; case 'f': - render_glyph_solid (cr, width, height, TRUE); - status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; + cairo_push_group (cr); + render_glyph_solid (cr, width, height, color, scaled_font); + cairo_pop_group_to_source (cr); + cairo_paint (cr); break; case 'g': cairo_push_group (cr); - render_glyph_solid (cr, width, height, TRUE); + render_glyph_solid (cr, width, height, color, NULL); cairo_pop_group_to_source (cr); cairo_paint (cr); break; case 'h': cairo_push_group (cr); - render_glyph_linear (cr, width, height, TRUE); + render_glyph_linear (cr, width, height, color, scaled_font); cairo_pop_group_to_source (cr); cairo_paint (cr); break; case 'i': cairo_push_group (cr); - render_glyph_text (cr, width, height, TRUE); + render_glyph_linear (cr, width, height, color, NULL); cairo_pop_group_to_source (cr); cairo_paint (cr); break; - default: - status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - } - - return status; -} - -static cairo_status_t -test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *metrics) -{ - double width = 0.5; - double height = 0.8; - metrics->x_advance = 0.75; - cairo_translate (cr, 0.125, -0.6); - switch (glyph) { - case 'd': - render_glyph_solid (cr, width, height, FALSE); - break; - case 'e': - render_glyph_linear (cr, width, height, FALSE); - break; - case 'f': - render_glyph_text (cr, width, height, FALSE); - break; case 'j': cairo_push_group (cr); - render_glyph_solid (cr, width, height, FALSE); - cairo_pop_group_to_source (cr); - cairo_paint (cr); - break; - case 'k': - cairo_push_group (cr); - render_glyph_linear (cr, width, height, FALSE); - cairo_pop_group_to_source (cr); - cairo_paint (cr); - break; - case 'l': - cairo_push_group (cr); - render_glyph_text (cr, width, height, FALSE); + render_glyph_text (cr, width, height, color); cairo_pop_group_to_source (cr); cairo_paint (cr); break; - default: - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; } return CAIRO_STATUS_SUCCESS; } static cairo_status_t +test_scaled_font_render_color_glyph_callback (cairo_scaled_font_t *scaled_font, + unsigned long glyph, + cairo_t *cr, + cairo_text_extents_t *metrics) +{ + if (isupper(glyph)) + return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; + + return test_scaled_font_render_glyph_common (scaled_font, glyph, cr, metrics, TRUE); +} + +static cairo_status_t +test_scaled_font_render_glyph_callback (cairo_scaled_font_t *scaled_font, + unsigned long glyph, + cairo_t *cr, + cairo_text_extents_t *metrics) +{ + int c = glyph; + if (isupper(c)) + c = tolower(c); + + return test_scaled_font_render_glyph_common (scaled_font, c, cr, metrics, FALSE); +} + +static cairo_status_t _user_font_face_create (cairo_font_face_t **out) { @@ -229,13 +239,35 @@ _user_font_face_create (cairo_font_face_t **out) user_font_face = cairo_user_font_face_create (); cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init); - cairo_user_font_face_set_render_color_glyph_func (user_font_face, test_scaled_font_render_color_glyph); - cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph); + cairo_user_font_face_set_render_color_glyph_func (user_font_face, + test_scaled_font_render_color_glyph_callback); + cairo_user_font_face_set_render_glyph_func (user_font_face, + test_scaled_font_render_glyph_callback); *out = user_font_face; return CAIRO_STATUS_SUCCESS; } +/* Any text characters that are in fg_text will be drawn with a different color */ +static void +draw_line (cairo_t *cr, const char *text, const char *fg_text) +{ + char buf[10]; + + for (unsigned i = 0; i < strlen(text); i++) { + buf[0] = text[i]; + buf[1] = 0; + + if (strchr (fg_text, text[i])) { + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_show_text (cr, buf); + } + + cairo_set_source_rgb (cr, 0, 1, 0); + cairo_show_text (cr, buf); + } +} + static cairo_test_status_t draw (cairo_t *cr, int width, int height) { @@ -244,6 +276,7 @@ draw (cairo_t *cr, int width, int height) cairo_font_extents_t font_extents; cairo_text_extents_t extents; cairo_status_t status; + cairo_font_options_t *font_options; cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); @@ -285,10 +318,31 @@ draw (cairo_t *cr, int width, int height) cairo_set_line_width (cr, 2); cairo_stroke (cr); - /* text in color */ - cairo_set_source_rgb (cr, 0, 0.3, 0); + /* Line 1: text in color */ cairo_move_to (cr, BORDER, BORDER + font_extents.ascent); - cairo_show_text (cr, text); + draw_line (cr, TEXT, FG_TEXT); + + /* Line 2: text in non-color (color render callback returns + * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED. + */ + cairo_move_to (cr, BORDER, BORDER + font_extents.height + 1*BORDER + font_extents.ascent); + draw_line (cr, TEXT_NO_COLOR, FG_TEXT_NO_COLOR); + + /* Line 3: Filled version of color text in blue */ + cairo_move_to (cr, BORDER, BORDER + 2*font_extents.height + 2*BORDER + font_extents.ascent); + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_text_path (cr, TEXT_PATH); + cairo_fill (cr); + + /* Line 4: color glyphs with CAIRO_COLOR_MODE_NO_COLOR font option. */ + font_options = cairo_font_options_create (); + cairo_get_font_options (cr, font_options); + cairo_font_options_set_color_mode (font_options, CAIRO_COLOR_MODE_NO_COLOR); + cairo_set_font_options (cr, font_options); + cairo_font_options_destroy (font_options); + + cairo_move_to (cr, BORDER, BORDER + 3*font_extents.height + 3*BORDER + font_extents.ascent); + draw_line (cr, TEXT, FG_TEXT); return CAIRO_TEST_SUCCESS; } |