Commit | Line | Data |
---|---|---|
019754da WJ |
1 | /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. |
2 | Distributed by Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of Ghostscript. | |
5 | ||
6 | Ghostscript is distributed in the hope that it will be useful, but | |
7 | WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | to anyone for the consequences of using it or for whether it serves any | |
9 | particular purpose or works at all, unless he says so in writing. Refer | |
10 | to the Ghostscript General Public License for full details. | |
11 | ||
12 | Everyone is granted permission to copy, modify and redistribute | |
13 | Ghostscript, but only under the conditions described in the Ghostscript | |
14 | General Public License. A copy of this license is supposed to have been | |
15 | given to you along with Ghostscript so you can know your rights and | |
16 | responsibilities. It should be in a file named COPYING. Among other | |
17 | things, the copyright notice and this notice must be preserved on all | |
18 | copies. */ | |
19 | ||
20 | /* gstdev.c */ | |
21 | /* Device tracing for Ghostscript library */ | |
22 | #include "gx.h" | |
23 | #include "gxfixed.h" /* for gxmatrix.h */ | |
24 | #include "gxmatrix.h" /* for gxdevice.h */ | |
25 | #include "gxdevice.h" | |
26 | ||
27 | #ifdef DEBUG | |
28 | ||
29 | /* ------ Tracing 'device' ------*/ | |
30 | ||
31 | /* To avoid unpleasant interactions with copydevice, */ | |
32 | /* the tracing 'device' uses an external linked list to keep track of */ | |
33 | /* the real procedures that were replaced in the procedure vector. */ | |
34 | ||
35 | typedef struct trace_record_s trace_record; | |
36 | struct trace_record_s { | |
37 | trace_record *next; | |
38 | gx_device_procs *tprocs; | |
39 | gx_device_procs procs; | |
40 | int index; | |
41 | }; | |
42 | ||
43 | private gx_device *trace_cache_device = NULL; | |
44 | private gx_device_procs *trace_cache_procs; | |
45 | private trace_record *trace_list = NULL; | |
46 | private int trace_next_index = 0; | |
47 | ||
48 | #define rprocs\ | |
49 | (dev == trace_cache_device ? trace_cache_procs :\ | |
50 | trace_find_procs(dev)) | |
51 | ||
52 | /* Procedure structure */ | |
53 | private dev_proc_open_device(trace_open_device); | |
54 | private dev_proc_get_initial_matrix(trace_get_initial_matrix); | |
55 | private dev_proc_sync_output(trace_sync_output); | |
56 | private dev_proc_output_page(trace_output_page); | |
57 | private dev_proc_close_device(trace_close_device); | |
58 | private dev_proc_map_rgb_color(trace_map_rgb_color); | |
59 | private dev_proc_map_color_rgb(trace_map_color_rgb); | |
60 | private dev_proc_fill_rectangle(trace_fill_rectangle); | |
61 | private dev_proc_tile_rectangle(trace_tile_rectangle); | |
62 | private dev_proc_copy_mono(trace_copy_mono); | |
63 | private dev_proc_copy_color(trace_copy_color); | |
64 | private dev_proc_draw_line(trace_draw_line); | |
65 | private dev_proc_get_bits(trace_get_bits); | |
66 | private dev_proc_get_props(trace_get_props); | |
67 | private dev_proc_put_props(trace_put_props); | |
68 | ||
69 | private gx_device_procs trace_procs = { | |
70 | trace_open_device, | |
71 | trace_get_initial_matrix, | |
72 | trace_sync_output, | |
73 | trace_output_page, | |
74 | trace_close_device, | |
75 | trace_map_rgb_color, | |
76 | trace_map_color_rgb, | |
77 | trace_fill_rectangle, | |
78 | trace_tile_rectangle, | |
79 | trace_copy_mono, | |
80 | trace_copy_color, | |
81 | trace_draw_line, | |
82 | trace_get_bits, | |
83 | trace_get_props, | |
84 | trace_put_props | |
85 | }; | |
86 | ||
87 | /* Find the real procedures for a traced device */ | |
88 | private gx_device_procs * | |
89 | trace_find_procs(gx_device *tdev) | |
90 | { gx_device_procs *tprocs = tdev->procs; | |
91 | register trace_record *tp = trace_list; | |
92 | while ( tp != NULL ) | |
93 | { if ( tp->tprocs == tprocs ) | |
94 | { trace_cache_device = tdev; | |
95 | return (trace_cache_procs = &tp->procs); | |
96 | } | |
97 | tp = tp->next; | |
98 | } | |
99 | lprintf("Traced procedures not found!\n"); | |
100 | gs_exit(1); | |
101 | } | |
102 | ||
103 | /* Trace a device. */ | |
104 | gx_device * | |
105 | gs_trace_device(gx_device *rdev) | |
106 | { trace_record *tp; | |
107 | if ( rdev->procs->open_device == trace_procs.open_device ) | |
108 | return rdev; /* already traced */ | |
109 | tp = (trace_record *)gs_malloc(1, sizeof(trace_record), | |
110 | "gs_trace_device"); | |
111 | if ( tp == 0 ) return 0; | |
112 | tp->next = trace_list; | |
113 | tp->tprocs = rdev->procs; | |
114 | tp->procs = *rdev->procs; | |
115 | tp->index = ++trace_next_index; | |
116 | trace_list = tp; | |
117 | *rdev->procs = trace_procs; | |
118 | return rdev; | |
119 | } | |
120 | ||
121 | /* Utilities */ | |
122 | private int | |
123 | trace_print_code(int result) | |
124 | { if ( result == 0 ) | |
125 | dprintf(";\n"); | |
126 | else | |
127 | dprintf1(";\t/* = %d */\n", result); | |
128 | return result; | |
129 | } | |
130 | private void | |
131 | trace_print_tile(gx_bitmap *tile) | |
132 | { int i; | |
133 | dprintf1("\t{ static byte data = { 0x%x", tile->data[0]); | |
134 | for ( i = 1; i < tile->raster * tile->size.y; i++ ) | |
135 | dprintf1(", 0x%x", tile->data[i]); | |
136 | dprintf4(" };\n\t static gx_bitmap tile = { &data, %d, %d, %d, 0x%lx };\n", | |
137 | tile->raster, tile->size.x, tile->size.y, tile->id); | |
138 | } | |
139 | ||
140 | /* Procedures */ | |
141 | private int | |
142 | trace_open_device(gx_device *dev) | |
143 | { int result = (*rprocs->open_device)(dev); | |
144 | if ( gs_debug['V'] ) | |
145 | dprintf2("[V]\topen_device(0x%lx /*%s*/)", (ulong)dev, dev->dname), | |
146 | trace_print_code(result); | |
147 | return result; | |
148 | } | |
149 | private void | |
150 | trace_get_initial_matrix(gx_device *dev, gs_matrix *pmat) | |
151 | { (*rprocs->get_initial_matrix)(dev, pmat); | |
152 | if ( gs_debug['V'] ) | |
153 | dprintf6("[V]\tget_initial_matrix(dev) = (%6g, %6g, %6g, %6g, %6g, %6g);\n", | |
154 | pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty); | |
155 | } | |
156 | private int | |
157 | trace_sync_output(gx_device *dev) | |
158 | { int result = (*rprocs->sync_output)(dev); | |
159 | if ( gs_debug['V'] ) | |
160 | dprintf("[V]\tsync_output(dev)"), | |
161 | trace_print_code(result); | |
162 | return result; | |
163 | } | |
164 | private int | |
165 | trace_output_page(gx_device *dev, int num_copies, int flush) | |
166 | { int result = (*rprocs->output_page)(dev, num_copies, flush); | |
167 | if ( gs_debug['V'] ) | |
168 | dprintf2("[V]\toutput_page(dev, %d, %d)", num_copies, flush), | |
169 | trace_print_code(result); | |
170 | return result; | |
171 | } | |
172 | private int | |
173 | trace_close_device(gx_device *dev) | |
174 | { int result = (*rprocs->close_device)(dev); | |
175 | if ( gs_debug['V'] ) | |
176 | dprintf2("[V]\tclose_device(0x%lx /*%s*/)", (ulong)dev, dev->dname), | |
177 | trace_print_code(result); | |
178 | return result; | |
179 | } | |
180 | private gx_color_index | |
181 | trace_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g, | |
182 | gx_color_value b) | |
183 | { gx_color_index result = (*rprocs->map_rgb_color)(dev, r, g, b); | |
184 | if ( gs_debug['V'] ) | |
185 | dprintf4("[V]\tmap_rgb_color(dev, %u, %u, %u) /*= %ld */;\n", | |
186 | r, g, b, (long)result); | |
187 | return result; | |
188 | } | |
189 | private int | |
190 | trace_map_color_rgb(gx_device *dev, gx_color_index color, | |
191 | gx_color_value prgb[3]) | |
192 | { int result = (*rprocs->map_color_rgb)(dev, color, prgb); | |
193 | if ( gs_debug['V'] ) | |
194 | dprintf4("[V]\t{ gx_color_value rgb[3]; map_color_rgb(dev, %ld, rgb /* %u, %u, %u */); }", | |
195 | (long)color, prgb[0], prgb[1], prgb[2]), | |
196 | trace_print_code(result); | |
197 | return result; | |
198 | } | |
199 | private int | |
200 | trace_fill_rectangle(gx_device *dev, int x, int y, int w, int h, | |
201 | gx_color_index color) | |
202 | { int result = (*rprocs->fill_rectangle)(dev, x, y, w, h, color); | |
203 | if ( gs_debug['V'] ) | |
204 | dprintf5("[V]\tfill_rectangle(dev, %d, %d, %d, %d, %ld)", | |
205 | x, y, w, h, (long)color), | |
206 | trace_print_code(result); | |
207 | return result; | |
208 | } | |
209 | private int | |
210 | trace_tile_rectangle(gx_device *dev, gx_bitmap *tile, | |
211 | int x, int y, int w, int h, gx_color_index zero, gx_color_index one, | |
212 | int px, int py) | |
213 | { int result = (*rprocs->tile_rectangle)(dev, tile, | |
214 | x, y, w, h, zero, one, px, py); | |
215 | if ( gs_debug['V'] ) | |
216 | { trace_print_tile(tile); | |
217 | dprintf8("[V]\t tile_rectangle(dev, &tile, %d, %d, %d, %d, %ld, %ld, %d, %d);\n\t}", | |
218 | x, y, w, h, (long)zero, (long)one, px, py); | |
219 | trace_print_code(result); | |
220 | } | |
221 | return result; | |
222 | } | |
223 | private int | |
224 | trace_copy_mono(gx_device *dev, byte *data, | |
225 | int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, | |
226 | gx_color_index zero, gx_color_index one) | |
227 | { int result = (*rprocs->copy_mono)(dev, data, | |
228 | dx, raster, id, x, y, w, h, zero, one); | |
229 | if ( gs_debug['V'] ) | |
230 | dprintf9("[V]\tcopy_mono(dev, data, %d, %d, 0x%lx, %d, %d, %d, %d, %ld, %ld)", | |
231 | dx, raster, id, x, y, w, h, (long)zero, (long)one), | |
232 | trace_print_code(result); | |
233 | return result; | |
234 | } | |
235 | private int | |
236 | trace_copy_color(gx_device *dev, byte *data, | |
237 | int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) | |
238 | { int result = (*rprocs->copy_color)(dev, data, | |
239 | dx, raster, id, x, y, w, h); | |
240 | if ( gs_debug['V'] ) | |
241 | dprintf7("[V]\tcopy_color(dev, data, %d, %d, 0x%lx, %d, %d, %d, %d)", | |
242 | dx, raster, id, x, y, w, h), | |
243 | trace_print_code(result); | |
244 | return result; | |
245 | } | |
246 | private int | |
247 | trace_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, | |
248 | gx_color_index color) | |
249 | { int result = (*rprocs->draw_line)(dev, x0, y0, x1, y1, color); | |
250 | if ( gs_debug['V'] ) | |
251 | dprintf5("[V]\tdraw_line(dev, %d, %d, %d, %d, %ld)", | |
252 | x0, y0, x1, y1, (long)color), | |
253 | trace_print_code(result); | |
254 | return result; | |
255 | } | |
256 | private int | |
257 | trace_get_bits(gx_device *dev, int y, byte *data, uint size, int pad) | |
258 | { int result = (*rprocs->get_bits)(dev, y, data, size, pad); | |
259 | if ( gs_debug['V'] ) | |
260 | dprintf3("[V]\tget_bits(dev, %d, data, %d, %d)", | |
261 | y, size, pad), | |
262 | trace_print_code(result); | |
263 | return result; | |
264 | } | |
265 | private int | |
266 | trace_get_props(gx_device *dev, gs_prop_item *plist) | |
267 | { int result = (*rprocs->get_props)(dev, plist); | |
268 | if ( gs_debug['V'] ) | |
269 | dprintf("[V]\tget_props(dev, plist)\n"), | |
270 | trace_print_code(result); | |
271 | return result; | |
272 | } | |
273 | private int | |
274 | trace_put_props(gx_device *dev, gs_prop_item *plist, int count) | |
275 | { int result = (*rprocs->put_props)(dev, plist, count); | |
276 | if ( gs_debug['V'] ) | |
277 | dprintf1("[V]\tput_props(dev, plist, %d)", count), | |
278 | trace_print_code(result); | |
279 | return result; | |
280 | } | |
281 | ||
282 | #endif |