1 /* Copyright (C) 2001-2006 artofcode LLC.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 /*$Id: gdevtxtw.c 7795 2007-03-23 13:56:11Z tim $ */
14 /* Device for ASCII or Unicode text extraction */
15 /* FIXME: not all .h files are listed as dependencies */
16 #include "memory_.h"
17 #include "gp.h" /* for gp_file_name_sizeof */
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gsparam.h"
21 #include "gsutil.h"
22 #include "gxdevice.h"
23 #include "gsdevice.h" /* requires gsmatrix.h */
24
25 typedef struct gx_device_txtwrite_s {
26 gx_device_common;
27 void *example_data;
28 char fname[gp_file_name_sizeof]; /* OutputFile */
29 FILE *file;
30 } gx_device_txtwrite_t;
31
32 /* GC descriptor */
33 gs_private_st_suffix_add1_final(st_device_txtwrite, gx_device_txtwrite_t,
34 "gx_device_txtwrite", device_txtwrite_enum_ptrs, device_txtwrite_reloc_ptrs,
35 gx_device_finalize, st_device_forward, example_data);
36
37 /* Device procedures */
38 static dev_proc_open_device(txtwrite_open_device);
39 static dev_proc_close_device(txtwrite_close_device);
40 static dev_proc_output_page(txtwrite_output_page);
41 static dev_proc_fill_rectangle(txtwrite_fill_rectangle);
42 static dev_proc_get_params(txtwrite_get_params);
43 static dev_proc_put_params(txtwrite_put_params);
44 static dev_proc_copy_alpha(txtwrite_copy_alpha);
45 static dev_proc_copy_mono(txtwrite_copy_mono);
46 static dev_proc_copy_color(txtwrite_copy_color);
47 static dev_proc_fill_path(txtwrite_fill_path);
48 static dev_proc_stroke_path(txtwrite_stroke_path);
49 static dev_proc_fill_mask(txtwrite_fill_mask);
50 static dev_proc_fill_trapezoid(txtwrite_fill_trapezoid);
51 static dev_proc_fill_parallelogram(txtwrite_fill_parallelogram);
52 static dev_proc_fill_triangle(txtwrite_fill_triangle);
53 static dev_proc_draw_thin_line(txtwrite_draw_thin_line);
54 static dev_proc_strip_tile_rectangle(txtwrite_strip_tile_rectangle);
55 static dev_proc_strip_copy_rop(txtwrite_strip_copy_rop);
56 static dev_proc_begin_typed_image(txtwrite_begin_typed_image);
57 static dev_proc_text_begin(txtwrite_text_begin);
58
59 /* The device prototype */
60 #define X_DPI 720
61 #define Y_DPI 720
62
63 const gx_device_txtwrite_t gs_txtwrite_device =
64 {
65 /* Define the device as 8-bit gray scale to avoid computing halftones. */
66 std_device_dci_body(gx_device_txtwrite_t, 0, "txtwrite",
67 DEFAULT_WIDTH_10THS * X_DPI / 10,
68 DEFAULT_HEIGHT_10THS * Y_DPI / 10,
69 X_DPI, Y_DPI,
70 1, 8, 255, 0, 256, 1),
71 {txtwrite_open_device,
72 gx_upright_get_initial_matrix,
73 gx_default_sync_output,
74 txtwrite_output_page,
75 gx_default_close_device,
76 gx_default_gray_map_rgb_color,
77 gx_default_gray_map_color_rgb,
78 txtwrite_fill_rectangle,
79 gx_default_tile_rectangle,
80 txtwrite_copy_mono,
81 txtwrite_copy_color,
82 gx_default_draw_line,
83 gx_default_get_bits,
84 txtwrite_get_params,
85 txtwrite_put_params,
86 gx_default_map_cmyk_color,
87 gx_default_get_xfont_procs,
88 gx_default_get_xfont_device,
89 gx_default_map_rgb_alpha_color,
90 gx_page_device_get_page_device,
91 NULL, /* get_alpha_bits */
92 txtwrite_copy_alpha,
93 NULL, /* get_band */
94 NULL, /* copy_rop */
95 txtwrite_fill_path,
96 txtwrite_stroke_path,
97 txtwrite_fill_mask,
98 txtwrite_fill_trapezoid,
99 txtwrite_fill_parallelogram,
100 txtwrite_fill_triangle,
101 txtwrite_draw_thin_line,
102 gx_default_begin_image,
103 NULL, /* image_data */
104 NULL, /* end_image */
105 txtwrite_strip_tile_rectangle,
106 txtwrite_strip_copy_rop,
107 NULL, /* get_clipping_box */
108 txtwrite_begin_typed_image,
109 NULL, /* get_bits_rectangle */
110 gx_default_map_color_rgb_alpha,
111 gx_null_create_compositor,
112 NULL, /* get_hardware_params */
113 txtwrite_text_begin,
114 NULL, /* finish_copydevice */
115 NULL, /* begin_transparency_group */
116 NULL, /* end_transparency_group */
117 NULL, /* begin_transparency_mask */
118 NULL, /* end_transparency_mask */
119 NULL, /* discard_transparency_layer */
120 NULL, /* get_color_mapping_procs */
121 NULL, /* get_color_comp_index */
122 NULL, /* encode_color */
123 NULL /* decode_color */
124 },
125 0, /* example_data */
126 { 0 }, /* OutputFile */
127 0 /* FILE *file */
128 };
129
130 /* ---------------- Open/close/page ---------------- */
131
132 static int
txtwrite_open_device(gx_device * dev)133 txtwrite_open_device(gx_device * dev)
134 {
135 int code;
136 gx_device_txtwrite_t *const tdev = (gx_device_txtwrite_t *) dev;
137
138 gx_device_fill_in_procs(dev);
139 if (tdev->fname[0] == 0)
140 return_error(gs_error_undefinedfilename);
141 code = gx_device_open_output_file(dev, tdev->fname,
142 true, false, &tdev->file); /* binary, sequential */
143 if (code < 0)
144 return code;
145 return 0;
146 }
147
148 static int
txtwrite_close_device(gx_device * dev)149 txtwrite_close_device(gx_device * dev)
150 {
151 return 0;
152
153 }
154
155 static int
txtwrite_output_page(gx_device * dev,int num_copies,int flush)156 txtwrite_output_page(gx_device * dev, int num_copies, int flush)
157 {
158 gx_device_txtwrite_t *const tdev = (gx_device_txtwrite_t *) dev;
159
160 fprintf(tdev->file, "Hello world\n");
161 return gx_default_output_page(dev, num_copies, flush);
162 }
163
164 /* ---------------- Low-level drawing ---------------- */
165
166 static int
txtwrite_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)167 txtwrite_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
168 gx_color_index color)
169 {
170 return 0;
171 }
172
173 static int
txtwrite_copy_alpha(gx_device * dev,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index color,int depth)174 txtwrite_copy_alpha(gx_device * dev, const byte * data, int data_x,
175 int raster, gx_bitmap_id id, int x, int y, int w, int h,
176 gx_color_index color, int depth)
177 {
178 return 0;
179 }
180
181 static int
txtwrite_copy_mono(gx_device * dev,const byte * data,int dx,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)182 txtwrite_copy_mono(gx_device * dev, const byte * data, int dx, int raster,
183 gx_bitmap_id id, int x, int y, int w, int h,
184 gx_color_index zero, gx_color_index one)
185 {
186 return 0;
187 }
188 static int
txtwrite_copy_color(gx_device * dev,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int width,int height)189 txtwrite_copy_color(gx_device * dev, const byte * data,
190 int data_x, int raster, gx_bitmap_id id,
191 int x, int y, int width, int height)
192 {
193 return 0;
194 }
195
196 static int
txtwrite_strip_tile_rectangle(gx_device * dev,const gx_strip_bitmap * tiles,int x,int y,int w,int h,gx_color_index color0,gx_color_index color1,int px,int py)197 txtwrite_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
198 int x, int y, int w, int h, gx_color_index color0, gx_color_index color1,
199 int px, int py)
200 {
201 return 0;
202 }
203
204 static int
txtwrite_strip_copy_rop(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int w,int h,int phase_x,int phase_y,gs_logical_operation_t lop)205 txtwrite_strip_copy_rop(gx_device * dev,
206 const byte * sdata, int sourcex, uint sraster,
207 gx_bitmap_id id,
208 const gx_color_index * scolors,
209 const gx_strip_bitmap * textures,
210 const gx_color_index * tcolors,
211 int x, int y, int w, int h,
212 int phase_x, int phase_y, gs_logical_operation_t lop)
213 {
214 return 0;
215 }
216
217 /* ---------------- Parameters ---------------- */
218
219 static int
txtwrite_get_params(gx_device * dev,gs_param_list * plist)220 txtwrite_get_params(gx_device * dev, gs_param_list * plist)
221 {
222 int code;
223 gs_param_string ofns;
224 gx_device_txtwrite_t *const tdev = (gx_device_txtwrite_t *) dev;
225
226 code = gx_default_get_params(dev, plist);
227 if (code < 0)
228 return code;
229
230 ofns.data = (const byte *)tdev->fname,
231 ofns.size = strlen(tdev->fname),
232 ofns.persistent = false;
233 code = param_write_string(plist, "OutputFile", &ofns);
234
235 return code;
236 }
237
238 /* We implement put_params to ensure that we keep the important */
239 /* device parameters up to date, and to prevent an /undefined error */
240 static int
txtwrite_put_params(gx_device * dev,gs_param_list * plist)241 txtwrite_put_params(gx_device * dev, gs_param_list * plist)
242 {
243 gx_device_txtwrite_t *tdev = (gx_device_txtwrite_t *) dev;
244 int ecode = 0;
245 int code;
246 const char *param_name;
247 gs_param_string ofs;
248
249 switch (code = param_read_string(plist, (param_name = "OutputFile"), &ofs)) {
250 case 0:
251 if (dev->LockSafetyParams &&
252 bytes_compare(ofs.data, ofs.size,
253 (const byte *)tdev->fname, strlen(tdev->fname))) {
254 ecode = gs_note_error(gs_error_invalidaccess);
255 goto ofe;
256 }
257 if (ofs.size >= gp_file_name_sizeof)
258 ecode = gs_error_limitcheck;
259 else
260 break;
261 goto ofe;
262 default:
263 ecode = code;
264 ofe:param_signal_error(plist, param_name, ecode);
265 case 1:
266 ofs.data = 0;
267 break;
268 }
269
270 if (ecode < 0)
271 return ecode;
272 code = gx_default_put_params(dev, plist);
273 if (code < 0)
274 return code;
275
276 if (ofs.data != 0) { /* Close the file if it's open. */
277 if (tdev->file != 0) {
278 fclose(tdev->file);
279 tdev->file = 0;
280 }
281 memcpy(tdev->fname, ofs.data, ofs.size);
282 tdev->fname[ofs.size] = 0;
283 tdev->file = fopen(tdev->fname, "wb");
284 if (tdev->file == 0)
285 return_error(gs_error_ioerror);
286 }
287 return 0;
288 }
289
290 /* ---------------- Polygon drawing ---------------- */
291
292 static int
txtwrite_fill_trapezoid(gx_device * dev,const gs_fixed_edge * left,const gs_fixed_edge * right,fixed ybot,fixed ytop,bool swap_axes,const gx_device_color * pdevc,gs_logical_operation_t lop)293 txtwrite_fill_trapezoid(gx_device * dev,
294 const gs_fixed_edge * left, const gs_fixed_edge * right,
295 fixed ybot, fixed ytop, bool swap_axes,
296 const gx_device_color * pdevc, gs_logical_operation_t lop)
297 {
298 return 0;
299 }
300
301 static int
txtwrite_fill_parallelogram(gx_device * dev,fixed px,fixed py,fixed ax,fixed ay,fixed bx,fixed by,const gx_device_color * pdevc,gs_logical_operation_t lop)302 txtwrite_fill_parallelogram(gx_device * dev,
303 fixed px, fixed py, fixed ax, fixed ay,
304 fixed bx, fixed by, const gx_device_color * pdevc,
305 gs_logical_operation_t lop)
306 {
307 return 0;
308 }
309
310 static int
txtwrite_fill_triangle(gx_device * dev,fixed px,fixed py,fixed ax,fixed ay,fixed bx,fixed by,const gx_device_color * pdevc,gs_logical_operation_t lop)311 txtwrite_fill_triangle(gx_device * dev,
312 fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by,
313 const gx_device_color * pdevc, gs_logical_operation_t lop)
314 {
315 return 0;
316 }
317
318 static int
txtwrite_draw_thin_line(gx_device * dev,fixed fx0,fixed fy0,fixed fx1,fixed fy1,const gx_device_color * pdevc,gs_logical_operation_t lop,fixed adjustx,fixed adjusty)319 txtwrite_draw_thin_line(gx_device * dev,
320 fixed fx0, fixed fy0, fixed fx1, fixed fy1,
321 const gx_device_color * pdevc, gs_logical_operation_t lop,
322 fixed adjustx, fixed adjusty)
323 {
324 return 0;
325 }
326
327 /* ---------------- High-level drawing ---------------- */
328
329 static int
txtwrite_fill_path(gx_device * dev,const gs_imager_state * pis,gx_path * ppath,const gx_fill_params * params,const gx_device_color * pdevc,const gx_clip_path * pcpath)330 txtwrite_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
331 const gx_fill_params * params, const gx_device_color * pdevc,
332 const gx_clip_path * pcpath)
333 {
334 return 0;
335 }
336
337 static int
txtwrite_stroke_path(gx_device * dev,const gs_imager_state * pis,gx_path * ppath,const gx_stroke_params * params,const gx_drawing_color * pdevc,const gx_clip_path * pcpath)338 txtwrite_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
339 const gx_stroke_params * params,
340 const gx_drawing_color * pdevc, const gx_clip_path * pcpath)
341 {
342 return 0;
343 }
344
345 static int
txtwrite_fill_mask(gx_device * dev,const byte * data,int dx,int raster,gx_bitmap_id id,int x,int y,int w,int h,const gx_drawing_color * pdcolor,int depth,gs_logical_operation_t lop,const gx_clip_path * pcpath)346 txtwrite_fill_mask(gx_device * dev,
347 const byte * data, int dx, int raster, gx_bitmap_id id,
348 int x, int y, int w, int h,
349 const gx_drawing_color * pdcolor, int depth,
350 gs_logical_operation_t lop, const gx_clip_path * pcpath)
351 {
352 return 0;
353 }
354
355 static int
txtwrite_begin_typed_image(gx_device * dev,const gs_imager_state * pis,const gs_matrix * pmat,const gs_image_common_t * pic,const gs_int_rect * prect,const gx_drawing_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * memory,gx_image_enum_common_t ** pinfo)356 txtwrite_begin_typed_image(gx_device * dev,
357 const gs_imager_state * pis, const gs_matrix * pmat,
358 const gs_image_common_t * pic, const gs_int_rect * prect,
359 const gx_drawing_color * pdcolor,
360 const gx_clip_path * pcpath,
361 gs_memory_t * memory, gx_image_enum_common_t ** pinfo)
362 {
363 return 0;
364 }
365
366 /* ------ Text imaging ------ */
367
368 static int
txtwrite_text_begin(gx_device * dev,gs_imager_state * pis,const gs_text_params_t * text,gs_font * font,gx_path * path,const gx_device_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * memory,gs_text_enum_t ** ppenum)369 txtwrite_text_begin(gx_device * dev, gs_imager_state * pis,
370 const gs_text_params_t * text, gs_font * font,
371 gx_path * path, const gx_device_color * pdcolor,
372 const gx_clip_path * pcpath,
373 gs_memory_t * memory, gs_text_enum_t ** ppenum)
374 {
375 int code = gx_default_text_begin(dev, pis, text, font, path, pdcolor,
376 pcpath, memory, ppenum);
377
378 return code;
379 }
380
381