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