Tizen 2.0 Release
[framework/graphics/cairo.git] / test / bitmap-font.c
1 /*
2  * Copyright © 2005 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of
9  * Red Hat, Inc. not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior
11  * permission. Red Hat, Inc. makes no representations about the
12  * suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
18  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author: Carl D. Worth <cworth@cworth.org>
24  */
25
26 #include "cairo-test.h"
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #include <cairo-ft.h>
33 #include <fontconfig/fontconfig.h>
34 #include <fontconfig/fcfreetype.h>
35
36 #define FONT "6x13.pcf"
37 #define TEXT_SIZE 13
38
39 static cairo_bool_t
40 font_extents_equal (const cairo_font_extents_t *A,
41                     const cairo_font_extents_t *B)
42 {
43     return
44         CAIRO_TEST_DOUBLE_EQUALS (A->ascent,  B->ascent)  &&
45         CAIRO_TEST_DOUBLE_EQUALS (A->descent, B->descent) &&
46         CAIRO_TEST_DOUBLE_EQUALS (A->height,  B->height)  &&
47         CAIRO_TEST_DOUBLE_EQUALS (A->max_x_advance, B->max_x_advance) &&
48         CAIRO_TEST_DOUBLE_EQUALS (A->max_y_advance, B->max_y_advance);
49 }
50
51 static cairo_test_status_t
52 check_font_extents (const cairo_test_context_t *ctx, cairo_t *cr, const char *comment)
53 {
54     cairo_font_extents_t font_extents, ref_font_extents = {11, 2, 13, 6, 0};
55     cairo_status_t status;
56
57     memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
58     cairo_font_extents (cr, &font_extents);
59
60     status = cairo_status (cr);
61     if (status)
62         return cairo_test_status_from_status (ctx, status);
63
64     if (! font_extents_equal (&font_extents, &ref_font_extents)) {
65         cairo_test_log (ctx, "Error: %s: cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
66                         comment,
67                         font_extents.ascent, font_extents.descent,
68                         font_extents.height,
69                         font_extents.max_x_advance, font_extents.max_y_advance);
70         return CAIRO_TEST_FAILURE;
71     }
72
73     return CAIRO_TEST_SUCCESS;
74 }
75
76 static cairo_test_status_t
77 draw (cairo_t *cr, int width, int height)
78 {
79     const cairo_test_context_t *ctx = cairo_test_get_context (cr);
80     FcPattern *pattern;
81     cairo_font_face_t *font_face;
82     cairo_font_extents_t font_extents;
83     cairo_font_options_t *font_options;
84     cairo_status_t status;
85     char *filename;
86     int face_count;
87     struct stat stat_buf;
88
89     xasprintf (&filename, "%s/%s", ctx->srcdir, FONT);
90
91     if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) {
92         cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename);
93         return CAIRO_TEST_FAILURE;
94     }
95
96     pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count);
97     free (filename);
98     if (! pattern) {
99         cairo_test_log (ctx, "FcFreeTypeQuery failed.\n");
100         return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
101     }
102
103     font_face = cairo_ft_font_face_create_for_pattern (pattern);
104     FcPatternDestroy (pattern);
105
106     status = cairo_font_face_status (font_face);
107     if (status) {
108         cairo_test_log (ctx, "Error creating font face for %s: %s\n",
109                         filename,
110                         cairo_status_to_string (status));
111         return cairo_test_status_from_status (ctx, status);
112     }
113
114     if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
115         cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
116                         cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
117         cairo_font_face_destroy (font_face);
118         return CAIRO_TEST_FAILURE;
119     }
120
121     cairo_set_font_face (cr, font_face);
122     cairo_font_face_destroy (font_face);
123
124     font_options = cairo_font_options_create ();
125
126 #define CHECK_FONT_EXTENTS(comment) do {\
127     cairo_test_status_t test_status; \
128     test_status = check_font_extents (ctx, cr, (comment)); \
129     if (test_status != CAIRO_TEST_SUCCESS) { \
130         cairo_font_options_destroy (font_options); \
131         return test_status; \
132     } \
133 } while (0)
134
135     cairo_font_extents (cr, &font_extents);
136     CHECK_FONT_EXTENTS ("default");
137
138     cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
139     cairo_set_font_options (cr, font_options);
140
141     CHECK_FONT_EXTENTS ("HINT_METRICS_ON");
142
143     cairo_move_to (cr, 1, font_extents.ascent - 1);
144     cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
145
146     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
147     cairo_set_font_options (cr, font_options);
148     CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_NONE");
149     cairo_show_text (cr, "the ");
150
151     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
152     cairo_set_font_options (cr, font_options);
153     CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_SLIGHT");
154     cairo_show_text (cr, "quick ");
155
156     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
157     cairo_set_font_options (cr, font_options);
158     CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_MEDIUM");
159     cairo_show_text (cr, "brown");
160
161     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
162     cairo_set_font_options (cr, font_options);
163     CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_FULL");
164     cairo_show_text (cr, " fox");
165
166     /* Switch from show_text to text_path/fill to exercise bug #7889 */
167     cairo_text_path (cr, " jumps over a lazy dog");
168     cairo_fill (cr);
169
170     /* And test it rotated as well for the sake of bug #7888 */
171
172     cairo_translate (cr, width, height);
173     cairo_rotate (cr, M_PI);
174
175     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT);
176     cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
177     cairo_set_font_options (cr, font_options);
178     CHECK_FONT_EXTENTS ("HINT_METRICS_OFF");
179
180     cairo_move_to (cr, 1, font_extents.height - font_extents.descent - 1);
181
182     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
183     cairo_set_font_options (cr, font_options);
184     CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_NONE");
185     cairo_show_text (cr, "the ");
186
187     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
188     cairo_set_font_options (cr, font_options);
189     CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_SLIGHT");
190     cairo_show_text (cr, "quick");
191
192     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
193     cairo_set_font_options (cr, font_options);
194     CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_MEDIUM");
195     cairo_show_text (cr, " brown");
196
197     cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
198     cairo_set_font_options (cr, font_options);
199     CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_FULL");
200     cairo_show_text (cr, " fox");
201
202     cairo_text_path (cr, " jumps over");
203     cairo_text_path (cr, " a lazy dog");
204     cairo_fill (cr);
205
206     cairo_font_options_destroy (font_options);
207
208     return CAIRO_TEST_SUCCESS;
209 }
210
211 CAIRO_TEST (bitmap_font,
212             "Test drawing with a font consisting only of bitmaps"
213             "\nThe PDF and PS backends embed a slightly distorted font for the rotated case.",
214             "text", /* keywords */
215             "ft", /* requirements */
216             246 + 1, 2 * TEXT_SIZE,
217             NULL, draw)