summaryrefslogtreecommitdiff
path: root/test/user-font-color.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/user-font-color.c')
-rw-r--r--test/user-font-color.c232
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;
}