xref: /plan9/sys/src/cmd/gs/src/gdevcif.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1993 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gdevcif.c,v 1.6 2004/08/10 13:02:36 stefan Exp $*/
18 /*
19   CIF output driver
20 
21    The `Fake bitmapped device to estimate rendering time'
22    slightly modified to produce CIF files from PostScript.
23    So anyone can put a nice logo free on its chip!
24    Frederic Petrot, petrot@masi.ibp.fr */
25 
26 #include "gdevprn.h"
27 
28 /* Define the device parameters. */
29 #ifndef X_DPI
30 #  define X_DPI 72
31 #endif
32 #ifndef Y_DPI
33 #  define Y_DPI 72
34 #endif
35 
36 /* The device descriptor */
37 private dev_proc_print_page(cif_print_page);
38 const gx_device_printer far_data gs_cif_device =
39   prn_device(prn_std_procs, "cif",
40 	DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
41 	X_DPI, Y_DPI,
42 	0,0,0,0,
43 	1, cif_print_page);
44 
45 /* Send the page to the output. */
46 private int
cif_print_page(gx_device_printer * pdev,FILE * prn_stream)47 cif_print_page(gx_device_printer *pdev, FILE *prn_stream)
48 {	int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
49 	int lnum;
50 	byte *in = (byte *)gs_malloc(pdev->memory, line_size, 1, "cif_print_page(in)");
51 	char *s;
52 	int scanline, scanbyte;
53 	int length, start; /* length is the number of successive 1 bits, */
54 			   /* start is the set of 1 bit start position */
55 
56 	if (in == 0)
57 		return_error(gs_error_VMerror);
58 
59 	if ((s = strchr(pdev->fname, '.')) == NULL)
60 		length = strlen(pdev->fname) + 1;
61 	else
62 		length = s - pdev->fname;
63 	s = (char *)gs_malloc(pdev->memory, length, sizeof(char), "cif_print_page(s)");
64 
65 	strncpy(s, pdev->fname, length);
66 	*(s + length) = '\0';
67 	fprintf(prn_stream, "DS1 25 1;\n9 %s;\nLCP;\n", s);
68 	gs_free(pdev->memory, s, length, 1, "cif_print_page(s)");
69 
70    for (lnum = 0; lnum < pdev->height; lnum++) {
71       gdev_prn_copy_scan_lines(pdev, lnum, in, line_size);
72       length = 0;
73       for (scanline = 0; scanline < line_size; scanline++)
74 #ifdef TILE			/* original, simple, inefficient algorithm */
75          for (scanbyte = 0; scanbyte < 8; scanbyte++)
76             if (((in[scanline] >> scanbyte) & 1) != 0)
77                fprintf(prn_stream, "B4 4 %d %d;\n",
78                   (scanline * 8 + (7 - scanbyte)) * 4,
79                   (pdev->height - lnum) * 4);
80 #else				/* better algorithm */
81          for (scanbyte = 7; scanbyte >= 0; scanbyte--)
82             /* cheap linear reduction of rectangles in lines */
83             if (((in[scanline] >> scanbyte) & 1) != 0) {
84                if (length == 0)
85                   start = (scanline * 8 + (7 - scanbyte));
86                length++;
87             } else {
88                if (length != 0)
89                   fprintf(prn_stream, "B%d 4 %d %d;\n", length * 4,
90                            start * 4 + length * 2,
91                            (pdev->height - lnum) * 4);
92                length = 0;
93             }
94 #endif
95    }
96 	fprintf(prn_stream, "DF;\nC1;\nE\n");
97 	gs_free(pdev->memory, in, line_size, 1, "cif_print_page(in)");
98 	return 0;
99 }
100