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 3 : cairo_debug_reset_static_data (void)
61 : {
62 : CAIRO_MUTEX_INITIALIZE ();
63 :
64 3 : _cairo_scaled_font_map_destroy ();
65 :
66 3 : _cairo_toy_font_face_reset_static_data ();
67 :
68 : #if CAIRO_HAS_FT_FONT
69 3 : _cairo_ft_font_reset_static_data ();
70 : #endif
71 :
72 3 : _cairo_intern_string_reset_static_data ();
73 :
74 3 : _cairo_scaled_font_reset_static_data ();
75 :
76 3 : _cairo_pattern_reset_static_data ();
77 :
78 3 : _cairo_clip_reset_static_data ();
79 :
80 3 : _cairo_image_reset_static_data ();
81 :
82 : #if CAIRO_HAS_DRM_SURFACE
83 : _cairo_drm_device_reset_static_data ();
84 : #endif
85 :
86 3 : _cairo_reset_static_data ();
87 :
88 : CAIRO_MUTEX_FINALIZE ();
89 3 : }
90 :
91 : #if HAVE_VALGRIND
92 : void
93 : _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
94 : {
95 : const cairo_image_surface_t *image = (cairo_image_surface_t *) surface;
96 : const uint8_t *bits;
97 : int row, width;
98 :
99 : if (surface == NULL)
100 : return;
101 :
102 : if (! RUNNING_ON_VALGRIND)
103 : return;
104 :
105 : bits = image->data;
106 : switch (image->format) {
107 : case CAIRO_FORMAT_A1:
108 : width = (image->width + 7)/8;
109 : break;
110 : case CAIRO_FORMAT_A8:
111 : width = image->width;
112 : break;
113 : case CAIRO_FORMAT_RGB16_565:
114 : width = image->width*2;
115 : break;
116 : case CAIRO_FORMAT_RGB24:
117 : case CAIRO_FORMAT_ARGB32:
118 : width = image->width*4;
119 : break;
120 : case CAIRO_FORMAT_INVALID:
121 : default:
122 : /* XXX compute width from pixman bpp */
123 : return;
124 : }
125 :
126 : for (row = 0; row < image->height; row++) {
127 : VALGRIND_CHECK_MEM_IS_DEFINED (bits, width);
128 : /* and then silence any future valgrind warnings */
129 : VALGRIND_MAKE_MEM_DEFINED (bits, width);
130 : bits += image->stride;
131 : }
132 : }
133 : #endif
134 :
135 :
136 : #if 0
137 : void
138 : _cairo_image_surface_write_to_ppm (cairo_image_surface_t *isurf, const char *fn)
139 : {
140 : char *fmt;
141 : if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24)
142 : fmt = "P6";
143 : else if (isurf->format == CAIRO_FORMAT_A8)
144 : fmt = "P5";
145 : else
146 : return;
147 :
148 : FILE *fp = fopen(fn, "wb");
149 : if (!fp)
150 : return;
151 :
152 : fprintf (fp, "%s %d %d 255\n", fmt,isurf->width, isurf->height);
153 : for (int j = 0; j < isurf->height; j++) {
154 : unsigned char *row = isurf->data + isurf->stride * j;
155 : for (int i = 0; i < isurf->width; i++) {
156 : if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) {
157 : unsigned char r = *row++;
158 : unsigned char g = *row++;
159 : unsigned char b = *row++;
160 : *row++;
161 : putc(r, fp);
162 : putc(g, fp);
163 : putc(b, fp);
164 : } else {
165 : unsigned char a = *row++;
166 : putc(a, fp);
167 : }
168 : }
169 : }
170 :
171 : fclose (fp);
172 :
173 : fprintf (stderr, "Wrote %s\n", fn);
174 : }
175 : #endif
176 :
177 : static cairo_status_t
178 0 : _print_move_to (void *closure,
179 : const cairo_point_t *point)
180 : {
181 0 : fprintf (closure,
182 : " %f %f m",
183 : _cairo_fixed_to_double (point->x),
184 : _cairo_fixed_to_double (point->y));
185 :
186 0 : return CAIRO_STATUS_SUCCESS;
187 : }
188 :
189 : static cairo_status_t
190 0 : _print_line_to (void *closure,
191 : const cairo_point_t *point)
192 : {
193 0 : fprintf (closure,
194 : " %f %f l",
195 : _cairo_fixed_to_double (point->x),
196 : _cairo_fixed_to_double (point->y));
197 :
198 0 : return CAIRO_STATUS_SUCCESS;
199 : }
200 :
201 : static cairo_status_t
202 0 : _print_curve_to (void *closure,
203 : const cairo_point_t *p1,
204 : const cairo_point_t *p2,
205 : const cairo_point_t *p3)
206 : {
207 0 : fprintf (closure,
208 : " %f %f %f %f %f %f c",
209 : _cairo_fixed_to_double (p1->x),
210 : _cairo_fixed_to_double (p1->y),
211 : _cairo_fixed_to_double (p2->x),
212 : _cairo_fixed_to_double (p2->y),
213 : _cairo_fixed_to_double (p3->x),
214 : _cairo_fixed_to_double (p3->y));
215 :
216 0 : return CAIRO_STATUS_SUCCESS;
217 : }
218 :
219 : static cairo_status_t
220 0 : _print_close (void *closure)
221 : {
222 0 : fprintf (closure, " h");
223 :
224 0 : return CAIRO_STATUS_SUCCESS;
225 : }
226 :
227 : void
228 0 : _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
229 : {
230 : cairo_status_t status;
231 :
232 0 : printf ("path: extents=(%f, %f), (%f, %f)\n",
233 : _cairo_fixed_to_double (path->extents.p1.x),
234 : _cairo_fixed_to_double (path->extents.p1.y),
235 : _cairo_fixed_to_double (path->extents.p2.x),
236 : _cairo_fixed_to_double (path->extents.p2.y));
237 :
238 0 : status = _cairo_path_fixed_interpret (path,
239 : CAIRO_DIRECTION_FORWARD,
240 : _print_move_to,
241 : _print_line_to,
242 : _print_curve_to,
243 : _print_close,
244 : stream);
245 0 : assert (status == CAIRO_STATUS_SUCCESS);
246 :
247 0 : printf ("\n");
248 0 : }
|