Line data Source code
1 : /* cairo - a vector graphics library with display and print output
2 : *
3 : * Copyright © 2005 Red Hat, Inc.
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it either under the terms of the GNU Lesser General Public
7 : * License version 2.1 as published by the Free Software Foundation
8 : * (the "LGPL") or, at your option, under the terms of the Mozilla
9 : * Public License Version 1.1 (the "MPL"). If you do not alter this
10 : * notice, a recipient may use your version of this file under either
11 : * the MPL or the LGPL.
12 : *
13 : * You should have received a copy of the LGPL along with this library
14 : * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 : * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 : * You should have received a copy of the MPL along with this library
17 : * in the file COPYING-MPL-1.1
18 : *
19 : * The contents of this file are subject to the Mozilla Public License
20 : * Version 1.1 (the "License"); you may not use this file except in
21 : * compliance with the License. You may obtain a copy of the License at
22 : * http://www.mozilla.org/MPL/
23 : *
24 : * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 : * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 : * the specific language governing rights and limitations.
27 : *
28 : * The Original Code is the cairo graphics library.
29 : *
30 : * The Initial Developer of the Original Code is Red Hat, Inc.
31 : *
32 : * Contributor(s):
33 : * Carl D. Worth <cworth@cworth.org>
34 : */
35 :
36 : #include "cairoint.h"
37 :
38 : /**
39 : * cairo_debug_reset_static_data:
40 : *
41 : * Resets all static data within cairo to its original state,
42 : * (ie. identical to the state at the time of program invocation). For
43 : * example, all caches within cairo will be flushed empty.
44 : *
45 : * This function is intended to be useful when using memory-checking
46 : * tools such as valgrind. When valgrind's memcheck analyzes a
47 : * cairo-using program without a call to cairo_debug_reset_static_data(),
48 : * it will report all data reachable via cairo's static objects as
49 : * "still reachable". Calling cairo_debug_reset_static_data() just prior
50 : * to program termination will make it easier to get squeaky clean
51 : * reports from valgrind.
52 : *
53 : * WARNING: It is only safe to call this function when there are no
54 : * active cairo objects remaining, (ie. the appropriate destroy
55 : * functions have been called as necessary). If there are active cairo
56 : * objects, this call is likely to cause a crash, (eg. an assertion
57 : * failure due to a hash table being destroyed when non-empty).
58 : **/
59 : void
60 0 : cairo_debug_reset_static_data (void)
61 : {
62 : CAIRO_MUTEX_INITIALIZE ();
63 :
64 0 : _cairo_scaled_font_map_destroy ();
65 :
66 0 : _cairo_toy_font_face_reset_static_data ();
67 :
68 : #if CAIRO_HAS_FT_FONT
69 0 : _cairo_ft_font_reset_static_data ();
70 : #endif
71 :
72 : #if CAIRO_HAS_WIN32_FONT
73 : _cairo_win32_font_reset_static_data ();
74 : #endif
75 :
76 0 : _cairo_intern_string_reset_static_data ();
77 :
78 0 : _cairo_scaled_font_reset_static_data ();
79 :
80 0 : _cairo_pattern_reset_static_data ();
81 :
82 0 : _cairo_clip_reset_static_data ();
83 :
84 0 : _cairo_image_reset_static_data ();
85 :
86 : #if CAIRO_HAS_DRM_SURFACE
87 : _cairo_drm_device_reset_static_data ();
88 : #endif
89 :
90 0 : _cairo_reset_static_data ();
91 :
92 : CAIRO_MUTEX_FINALIZE ();
93 0 : }
94 :
95 : #if HAVE_VALGRIND
96 : void
97 : _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
98 : {
99 : const cairo_image_surface_t *image = (cairo_image_surface_t *) surface;
100 : const uint8_t *bits;
101 : int row, width;
102 :
103 : if (surface == NULL)
104 : return;
105 :
106 : if (! RUNNING_ON_VALGRIND)
107 : return;
108 :
109 : bits = image->data;
110 : switch (image->format) {
111 : case CAIRO_FORMAT_A1:
112 : width = (image->width + 7)/8;
113 : break;
114 : case CAIRO_FORMAT_A8:
115 : width = image->width;
116 : break;
117 : case CAIRO_FORMAT_RGB16_565:
118 : width = image->width*2;
119 : break;
120 : case CAIRO_FORMAT_RGB24:
121 : case CAIRO_FORMAT_ARGB32:
122 : width = image->width*4;
123 : break;
124 : case CAIRO_FORMAT_INVALID:
125 : default:
126 : /* XXX compute width from pixman bpp */
127 : return;
128 : }
129 :
130 : for (row = 0; row < image->height; row++) {
131 : VALGRIND_CHECK_MEM_IS_DEFINED (bits, width);
132 : /* and then silence any future valgrind warnings */
133 : VALGRIND_MAKE_MEM_DEFINED (bits, width);
134 : bits += image->stride;
135 : }
136 : }
137 : #endif
138 :
139 :
140 : #if 0
141 : void
142 : _cairo_image_surface_write_to_ppm (cairo_image_surface_t *isurf, const char *fn)
143 : {
144 : char *fmt;
145 : if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24)
146 : fmt = "P6";
147 : else if (isurf->format == CAIRO_FORMAT_A8)
148 : fmt = "P5";
149 : else
150 : return;
151 :
152 : FILE *fp = fopen(fn, "wb");
153 : if (!fp)
154 : return;
155 :
156 : fprintf (fp, "%s %d %d 255\n", fmt,isurf->width, isurf->height);
157 : for (int j = 0; j < isurf->height; j++) {
158 : unsigned char *row = isurf->data + isurf->stride * j;
159 : for (int i = 0; i < isurf->width; i++) {
160 : if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) {
161 : unsigned char r = *row++;
162 : unsigned char g = *row++;
163 : unsigned char b = *row++;
164 : *row++;
165 : putc(r, fp);
166 : putc(g, fp);
167 : putc(b, fp);
168 : } else {
169 : unsigned char a = *row++;
170 : putc(a, fp);
171 : }
172 : }
173 : }
174 :
175 : fclose (fp);
176 :
177 : fprintf (stderr, "Wrote %s\n", fn);
178 : }
179 : #endif
180 :
181 : static cairo_status_t
182 0 : _print_move_to (void *closure,
183 : const cairo_point_t *point)
184 : {
185 0 : fprintf (closure,
186 : " %f %f m",
187 : _cairo_fixed_to_double (point->x),
188 : _cairo_fixed_to_double (point->y));
189 :
190 0 : return CAIRO_STATUS_SUCCESS;
191 : }
192 :
193 : static cairo_status_t
194 0 : _print_line_to (void *closure,
195 : const cairo_point_t *point)
196 : {
197 0 : fprintf (closure,
198 : " %f %f l",
199 : _cairo_fixed_to_double (point->x),
200 : _cairo_fixed_to_double (point->y));
201 :
202 0 : return CAIRO_STATUS_SUCCESS;
203 : }
204 :
205 : static cairo_status_t
206 0 : _print_curve_to (void *closure,
207 : const cairo_point_t *p1,
208 : const cairo_point_t *p2,
209 : const cairo_point_t *p3)
210 : {
211 0 : fprintf (closure,
212 : " %f %f %f %f %f %f c",
213 : _cairo_fixed_to_double (p1->x),
214 : _cairo_fixed_to_double (p1->y),
215 : _cairo_fixed_to_double (p2->x),
216 : _cairo_fixed_to_double (p2->y),
217 : _cairo_fixed_to_double (p3->x),
218 : _cairo_fixed_to_double (p3->y));
219 :
220 0 : return CAIRO_STATUS_SUCCESS;
221 : }
222 :
223 : static cairo_status_t
224 0 : _print_close (void *closure)
225 : {
226 0 : fprintf (closure, " h");
227 :
228 0 : return CAIRO_STATUS_SUCCESS;
229 : }
230 :
231 : void
232 0 : _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
233 : {
234 : cairo_status_t status;
235 :
236 0 : printf ("path: extents=(%f, %f), (%f, %f)\n",
237 : _cairo_fixed_to_double (path->extents.p1.x),
238 : _cairo_fixed_to_double (path->extents.p1.y),
239 : _cairo_fixed_to_double (path->extents.p2.x),
240 : _cairo_fixed_to_double (path->extents.p2.y));
241 :
242 0 : status = _cairo_path_fixed_interpret (path,
243 : CAIRO_DIRECTION_FORWARD,
244 : _print_move_to,
245 : _print_line_to,
246 : _print_curve_to,
247 : _print_close,
248 : stream);
249 0 : assert (status == CAIRO_STATUS_SUCCESS);
250 :
251 0 : printf ("\n");
252 0 : }
|