1 /* Copyright (C) 2000-2012 by George Williams */
2 /* 2013apr13, added mono + grey Jose Da Silva */
3 /*
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13
14 * The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <fontforge-config.h>
30
31 #include "gimage.h"
32
pixname(int i,int ncol)33 static char *pixname(int i, int ncol) {
34 static char one[2], two[3];
35 char *usable = "!#$%&'()*+,-./0123456789;:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ ";
36 static int len=0;
37
38 if ( len==0 ) len = strlen(usable);
39 if ( ncol<len ) {
40 one[0]=usable[i];
41 return( one );
42 } else {
43 two[0] = usable[i/len];
44 two[1] = usable[i%len];
45 return( two );
46 }
47 }
48
GImageWriteXpm(GImage * gi,char * filename)49 int GImageWriteXpm(GImage *gi, char *filename) {
50 /* Export an *.xpm image. Return 0 if all done okay */
51 struct _GImage *base = gi->list_len==0?gi->u.image:gi->u.images[0];
52 FILE *file;
53 char stem[256];
54 char *pt,*color_type; uint8 *scanline;
55 int i,j;
56
57 /* This routine only exports mono or color-indexed type images */
58 if ( base->image_type==it_mono )
59 color_type = "m";
60 else if ( base->image_type==it_index ) {
61 color_type = "c";
62 if ( base->clut->is_grey ) {
63 color_type = "g";
64 if ( base->clut->clut_len<=4 )
65 color_type = "g4";
66 }
67 } else {
68 fprintf(stderr,"Image must be mono or color-indexed.\n");
69 return( -1 );
70 }
71
72 /* get filename stem (255chars max) */
73 if ( (pt=strrchr(filename,'/'))!=NULL )
74 ++pt;
75 else
76 pt=filename;
77 strncpy(stem,pt,sizeof(stem)); stem[255]='\0';
78 if ( (pt=strrchr(stem,'.'))!=NULL && pt!=stem )
79 *pt = '\0';
80
81 if ( (file=fopen(filename,"w"))==NULL ) {
82 fprintf(stderr,"Can't open \"%s\"\n", filename);
83 return( -1 );
84 }
85
86 fprintf(file,"/* XPM */\n" );
87 fprintf(file,"static char *%s[] = {\n",stem);
88 fprintf(file,"/* width height ncolors chars_per_pixel */\n");
89 if ( base->image_type==it_mono )
90 fprintf(file,"\"%d %d 2 1\"\n", (int) base->width, (int) base->height );
91 else
92 fprintf(file,"\"%d %d %d %d\"\n", (int) base->width, (int) base->height, base->clut->clut_len,
93 base->clut->clut_len>95?2:1 );
94 fprintf(file,"/* colors */\n");
95 if ( base->image_type==it_mono ) {
96 fprintf(file,"\"%s m #%06x\"\n", pixname(0,2),0);
97 fprintf(file,"\"%s m #%06x\"\n", pixname(1,2),0xffffff);
98 } else {
99 for ( i=0; i<base->clut->clut_len; ++i )
100 fprintf(file,"\"%s %s #%06x\"\n", pixname(i,base->clut->clut_len),color_type,
101 (int) base->clut->clut[i]);
102 }
103 fprintf(file,"/* image */\n");
104 for ( i=0; i<base->height; ++i ) {
105 fprintf(file,"\"" );
106 scanline = base->data + i*base->bytes_per_line;
107 if ( base->image_type==it_mono )
108 for ( j=0; j<base->width; ++j )
109 fprintf(file,"%s", pixname((scanline[j>>3]>>(7-(j&7)))&1,2));
110 else
111 for ( j=0; j<base->width; ++j )
112 fprintf(file,"%s", pixname(*scanline++,base->clut->clut_len));
113 fprintf(file,"\"%s\n", i==base->height-1?"":"," );
114 }
115 fprintf(file,"};\n" );
116 fflush(file);
117
118 i=ferror(file);
119 fclose(file);
120 return( i );
121 }
122