Upload Tizen2.0 source
[framework/graphics/cairo.git] / test / ft-font-create-for-ft-face.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 #include <cairo-ft.h>
28
29 static void
30 _stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl);
31
32 static cairo_font_face_t *
33 _load_font (FT_Face ft_face, int flags, cairo_t *cr, int lvl)
34 {
35     cairo_font_face_t *font_face;
36     cairo_font_extents_t font_extents;
37
38     _stress_font_cache (ft_face, cr, lvl+1);
39
40     font_face = cairo_ft_font_face_create_for_ft_face (ft_face, flags);
41
42     cairo_set_font_face (cr, font_face);
43     cairo_font_extents (cr, &font_extents);
44
45     _stress_font_cache (ft_face, cr, lvl+1);
46
47     return font_face;
48 }
49
50 static void
51 _stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl)
52 {
53 #define A _load_font (ft_face, 0, cr, lvl)
54 #define B _load_font (ft_face, FT_LOAD_NO_BITMAP, cr, lvl)
55 #define C _load_font (ft_face, FT_LOAD_NO_RECURSE, cr, lvl)
56 #define D _load_font (ft_face, FT_LOAD_FORCE_AUTOHINT, cr, lvl)
57
58     cairo_font_face_t *font_face[4];
59
60     while (lvl++ < 5) {
61         font_face[0] = A; font_face[1] = A;
62         font_face[2] = A; font_face[3] = A;
63         cairo_font_face_destroy (font_face[0]);
64         cairo_font_face_destroy (font_face[1]);
65         cairo_font_face_destroy (font_face[2]);
66         cairo_font_face_destroy (font_face[3]);
67
68         font_face[0] = A; font_face[1] = B;
69         font_face[2] = C; font_face[3] = D;
70         cairo_font_face_destroy (font_face[0]);
71         cairo_font_face_destroy (font_face[1]);
72         cairo_font_face_destroy (font_face[2]);
73         cairo_font_face_destroy (font_face[3]);
74
75         font_face[0] = A; font_face[1] = B;
76         font_face[2] = C; font_face[3] = D;
77         cairo_font_face_destroy (font_face[3]);
78         cairo_font_face_destroy (font_face[2]);
79         cairo_font_face_destroy (font_face[1]);
80         cairo_font_face_destroy (font_face[0]);
81
82         font_face[0] = A;
83         font_face[1] = A;
84         cairo_font_face_destroy (font_face[0]);
85         font_face[2] = A;
86         cairo_font_face_destroy (font_face[1]);
87         font_face[3] = A;
88         cairo_font_face_destroy (font_face[2]);
89         cairo_font_face_destroy (font_face[3]);
90
91         font_face[0] = A;
92         font_face[1] = B;
93         cairo_font_face_destroy (font_face[0]);
94         font_face[2] = C;
95         cairo_font_face_destroy (font_face[1]);
96         font_face[3] = D;
97         cairo_font_face_destroy (font_face[2]);
98         cairo_font_face_destroy (font_face[3]);
99     }
100
101 #undef A
102 #undef B
103 #undef C
104 #undef D
105 }
106
107 static cairo_test_status_t
108 draw (cairo_t *cr, int width, int height)
109 {
110     const cairo_test_context_t *ctx = cairo_test_get_context (cr);
111     FcPattern *pattern, *resolved;
112     FcResult result;
113     cairo_font_face_t *font_face;
114     cairo_scaled_font_t *scaled_font;
115     cairo_font_options_t *font_options;
116     cairo_font_extents_t font_extents;
117     cairo_matrix_t font_matrix, ctm;
118     FT_Face ft_face;
119
120     /* We're trying here to get our hands on _some_ FT_Face but we do
121      * not at all care which one. So we start with an empty pattern
122      * and do the minimal substitution on it in order to get a valid
123      * pattern.
124      *
125      * Do not use this in production code! */
126     pattern = FcPatternCreate ();
127     if (! pattern) {
128         cairo_test_log (ctx, "FcPatternCreate failed.\n");
129         return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
130     }
131
132     FcConfigSubstitute (NULL, pattern, FcMatchPattern);
133     FcDefaultSubstitute (pattern);
134     resolved = FcFontMatch (NULL, pattern, &result);
135     if (! resolved) {
136         FcPatternDestroy (pattern);
137         cairo_test_log (ctx, "FcFontMatch failed.\n");
138         return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
139     }
140
141     font_face = cairo_ft_font_face_create_for_pattern (resolved);
142     if (cairo_font_face_status (font_face)) {
143         FcPatternDestroy (resolved);
144         FcPatternDestroy (pattern);
145         return cairo_test_status_from_status (ctx, cairo_font_face_status (font_face));
146     }
147
148     if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
149         cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
150                         cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
151         cairo_font_face_destroy (font_face);
152         FcPatternDestroy (resolved);
153         FcPatternDestroy (pattern);
154         return CAIRO_TEST_FAILURE;
155     }
156
157     cairo_matrix_init_identity (&font_matrix);
158
159     cairo_get_matrix (cr, &ctm);
160
161     font_options = cairo_font_options_create ();
162
163     cairo_get_font_options (cr, font_options);
164
165     scaled_font = cairo_scaled_font_create (font_face,
166                                             &font_matrix,
167                                             &ctm,
168                                             font_options);
169
170     cairo_font_options_destroy (font_options);
171     cairo_font_face_destroy (font_face);
172     FcPatternDestroy (pattern);
173     FcPatternDestroy (resolved);
174
175     if (cairo_scaled_font_status (scaled_font)) {
176         return cairo_test_status_from_status (ctx,
177                                               cairo_scaled_font_status (scaled_font));
178     }
179
180     if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) {
181         cairo_test_log (ctx, "Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n",
182                         cairo_scaled_font_get_type (scaled_font), CAIRO_FONT_TYPE_FT);
183         cairo_scaled_font_destroy (scaled_font);
184         return CAIRO_TEST_FAILURE;
185     }
186
187     ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
188     if (ft_face == NULL) {
189         cairo_test_log (ctx, "Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n");
190         cairo_scaled_font_destroy (scaled_font);
191         return CAIRO_TEST_FAILURE;
192     }
193
194     /* phew, that was a lot of work. But at least we didn't ever have
195      * to call freetype directly, nor did we have to make many (any?)
196      * assumptions about the current system.
197      *
198      * Now, on to the simple thing we actually want to test.
199      */
200
201     cairo_save (cr);
202
203     /* First we want to test caching behaviour */
204     _stress_font_cache (ft_face, cr, 0);
205
206     /* Set the font_face and force cairo to actually use it for
207      * something. */
208     font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
209     cairo_set_font_face (cr, font_face);
210     cairo_font_extents (cr, &font_extents);
211
212     cairo_restore (cr);
213
214     /* Finally, even more cleanup */
215     cairo_font_face_destroy (font_face);
216     cairo_ft_scaled_font_unlock_face (scaled_font);
217     cairo_scaled_font_destroy (scaled_font);
218
219     return CAIRO_TEST_SUCCESS;
220 }
221
222 CAIRO_TEST (ft_font_create_for_ft_face,
223             "Simple test to verify that cairo_ft_font_create_for_ft_face doesn't crash.",
224             "ft, font", /* keywords */
225             NULL, /* requirements */
226             0, 0,
227             NULL, draw)
228