2 * Copyright © 2008 Adrian Johnson
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Author: Adrian Johnson <ajohnson@redneon.com>
27 #include "cairo-test.h"
33 cairo_glyph_t glyph_list[100];
40 glyph_array_init (glyph_array_t *glyphs, double x, double y)
42 glyphs->num_glyphs = 0;
48 glyph_array_rel_move_to (glyph_array_t *glyphs, double x, double y)
55 glyph_array_show (glyph_array_t *glyphs, cairo_t *cr)
57 cairo_show_glyphs (cr, glyphs->glyph_list, glyphs->num_glyphs);
60 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
63 glyph_array_add_text(glyph_array_t *glyphs, cairo_t *cr, const char *s, double spacing)
65 cairo_scaled_font_t *scaled_font;
66 cairo_status_t status;
68 unsigned long charcode;
70 cairo_text_extents_t extents;
76 scaled_font = cairo_get_scaled_font (cr);
77 status = cairo_scaled_font_status (scaled_font);
81 face = cairo_ft_scaled_font_lock_face (scaled_font);
83 return CAIRO_STATUS_FONT_TYPE_MISMATCH;
89 index = FT_Get_Char_Index (face, charcode);
90 glyphs->glyph_list[glyphs->num_glyphs].index = index;
93 glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->x;
94 glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->y;
96 cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs - 1], 1, &extents);
98 glyphs->glyph_list[glyphs->num_glyphs - 1].index,
99 glyphs->glyph_list[glyphs->num_glyphs].index,
102 kern_x = DOUBLE_FROM_26_6(kerning.x);
103 glyphs->glyph_list[glyphs->num_glyphs].x =
104 glyphs->glyph_list[glyphs->num_glyphs - 1].x + extents.x_advance + kern_x + spacing;
105 glyphs->glyph_list[glyphs->num_glyphs].y =
106 glyphs->glyph_list[glyphs->num_glyphs - 1].y + extents.y_advance;
109 cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs], 1, &extents);
110 glyphs->x = glyphs->glyph_list[glyphs->num_glyphs].x + extents.x_advance + spacing;
111 glyphs->y = glyphs->glyph_list[glyphs->num_glyphs].y + extents.y_advance;
113 glyphs->num_glyphs++;
116 cairo_ft_scaled_font_unlock_face (scaled_font);
117 return CAIRO_STATUS_SUCCESS;
120 static cairo_test_status_t
121 draw (cairo_t *cr, int width, int height)
123 const cairo_test_context_t *ctx = cairo_test_get_context (cr);
124 glyph_array_t glyphs;
125 cairo_font_options_t *font_options;
126 cairo_status_t status;
128 /* paint white so we don't need separate ref images for
129 * RGB24 and ARGB32 */
130 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
133 cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
134 CAIRO_FONT_SLANT_NORMAL,
135 CAIRO_FONT_WEIGHT_NORMAL);
136 cairo_set_font_size (cr, TEXT_SIZE);
138 font_options = cairo_font_options_create ();
139 cairo_get_font_options (cr, font_options);
140 cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
141 cairo_set_font_options (cr, font_options);
142 cairo_font_options_destroy (font_options);
144 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
146 glyph_array_init (&glyphs, 1, TEXT_SIZE);
148 status = glyph_array_add_text(&glyphs, cr, "AWAY again", 0.0);
150 return cairo_test_status_from_status (ctx, status);
152 glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1, 0.0);
153 status = glyph_array_add_text(&glyphs, cr, "character space", TEXT_SIZE*0.3);
155 return cairo_test_status_from_status (ctx, status);
157 glyph_array_show (&glyphs, cr);
160 glyph_array_init (&glyphs, 1, TEXT_SIZE*2 + 4);
162 status = glyph_array_add_text(&glyphs, cr, "Increasing", 0.0);
164 return cairo_test_status_from_status (ctx, status);
166 glyph_array_rel_move_to (&glyphs, TEXT_SIZE*0.5, 0.0);
167 status = glyph_array_add_text(&glyphs, cr, "space", 0.0);
169 return cairo_test_status_from_status (ctx, status);
171 glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.0, 0.0);
172 status = glyph_array_add_text(&glyphs, cr, "between", 0.0);
174 return cairo_test_status_from_status (ctx, status);
176 glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.5, 0.0);
177 status = glyph_array_add_text(&glyphs, cr, "words", 0.0);
179 return cairo_test_status_from_status (ctx, status);
181 glyph_array_show (&glyphs, cr);
183 return CAIRO_TEST_SUCCESS;
186 CAIRO_TEST (ft_show_glyphs_positioning,
187 "Test that the PS/PDF glyph positioning optimizations are correct",
188 "ft, text", /* keywords */
189 NULL, /* requirements */
190 235, (TEXT_SIZE + 4)*2,