1 /* Copyright (C) 2000-2012 by George Williams */
2 /* 2013mar3, bug-fixes plus type-formatting, 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 
WriteBase(FILE * file,struct _GImage * base,char * stem,int instance)33 static void WriteBase(FILE *file, struct _GImage *base, char *stem, int instance) {
34 /* Write one image in C code which can be compiled into FontForge. */
35 /* This routine is called and used by GImageWriteGImage() */
36     int i,j,k;
37     uint32 *ipt;
38     uint8 *pt;
39     long val;
40 
41     if ( base->image_type==it_true ) {
42 	fprintf(file,"static uint32 %s%d_data[] = {\n",stem,instance);
43 	for ( i=0; i<base->height; ++i ) {
44 	    ipt = (uint32 *) (base->data+i*base->bytes_per_line);
45 	    for ( j=0; j<base->width; ) {
46 		fprintf(file,j==0?"    ":"\t");
47 		for ( k=0; k<8 && j<base->width; ++k, ++j, ++ipt ) {
48 		    val=*ipt&0xffffffff;
49 		    fprintf(file,"0x%.8x%s",(unsigned int) val,j==base->width-1 && i==base->height-1?"":", ");
50 		}
51 		fprintf(file,"\n");
52 	    }
53 	}
54     } else {
55 	fprintf(file,"static uint8 %s%d_data[] = {\n",stem,instance);
56 	for ( i=0; i<base->height; ++i ) {
57 	    pt = (uint8 *) (base->data+i*base->bytes_per_line);
58 	    for ( j=0; j<base->bytes_per_line; ) {
59 		fprintf(file,j==0?"    ":"\t");
60 		for ( k=0; k<8 && j<base->bytes_per_line; ++k, ++j, ++pt )
61 		    fprintf(file,"0x%.2x%s",*pt,j==base->width-1 && i==base->height-1?"":", ");
62 		fprintf(file,"\n");
63 	    }
64 	}
65     }
66     fprintf(file,"};\n");
67 
68     if ( base->clut!=NULL ) {
69 	fprintf(file,"\nstatic GClut %s%d_clut = { %d, %d, %ld,\n",
70 		stem,instance,
71 		base->clut->clut_len, base->clut->is_grey,(unsigned long) base->clut->trans_index&0xfffffff );
72 	for ( i=0; i<base->clut->clut_len; ) {
73 	    fprintf(file,"    ");
74 	    for ( k=0; k<8 && i<base->clut->clut_len; ++k, ++i ) {
75 		val=base->clut->clut[i]&0xffffffff;
76 		fprintf(file,"0x%.8x%s",(unsigned int) val,i==base->clut->clut_len-1?" };":", ");
77 	    }
78 	    fprintf(file,"\n");
79 	}
80     }
81     fprintf(file,"\nstatic struct _GImage %s%d_base = {\n",stem,instance);
82     fprintf(file,base->image_type==it_true?"    it_true,\n":
83 		 base->image_type==it_index?"    it_index,\n":
84 		 "    it_mono,\n" );
85     fprintf(file,"    %d,%ld,%ld,%ld,\n",(int) base->delay,(long) base->width,(long) base->height,(long) base->bytes_per_line);
86     fprintf(file,"    (uint8 *) %s%d_data,\n",stem,instance);
87     if (base->clut==NULL)
88         fprintf(file,"    NULL,\n" );
89     else
90         fprintf(file,"    &%s%d_clut,\n",stem,instance);
91     fprintf(file,"    0x%.8x\n};\n\n",(unsigned int) base->trans&0xffffffff);
92 }
93 
GImageWriteGImage(GImage * gi,char * filename)94 int GImageWriteGImage(GImage *gi, char *filename) {
95 /* Export a GImage that can be used by FontForge. Return 0 if all done okay */
96     FILE *file;
97     int i;
98     char stem[256];
99     char *pt;
100 
101     if ( gi==NULL )
102 	return( -1 );
103 
104     /* get filename stem (255chars max) */
105     if ( (pt=strrchr(filename,'/'))!=NULL )
106 	++pt;
107     else
108 	pt=filename;
109     strncpy(stem,pt,sizeof(stem)); stem[255]='\0';
110     if ( (pt=strrchr(stem,'.'))!=NULL && pt!=stem )
111 	*pt = '\0';
112 
113     /* Begin writing C code to the file */
114     if ( (file=fopen(filename,"w"))==NULL ) {
115 	fprintf(stderr,"Can't open \"%s\"\n", filename);
116 	return( -1 );
117     }
118     fprintf(file,"/* This file was generated using GImageWriteGImage(gi,\"%s\") */\n",filename);
119     fprintf(file,"#include \"gimage.h\"\n\n" );
120     if ( gi->list_len==0 ) {
121 	/* Construct a single image */
122 	WriteBase(file,gi->u.image,stem,0);
123 	fprintf(file,"GImage %s = { 0, &%s0_base };\n",stem,stem);
124     } else {
125 	/* Construct an array of images */
126 	for ( i=0; i<gi->list_len; ++i )
127 	    WriteBase(file,gi->u.images[i],stem,i);
128 	fprintf(file,"static struct _GImage *%s_bases = {\n",stem);
129 	for ( i=0; i<gi->list_len; ++i )
130 	    fprintf(file,"    &%s%d_base%s\n", stem, i, i==gi->list_len-1?"":"," );
131 	fprintf(file,"};\n\n" );
132 
133 	fprintf(file,"GImage %s = { %d, (struct _GImage *) %s_bases };\n",stem,gi->list_len,stem);
134     }
135     fflush(file);
136     i=ferror(file);
137     fclose(file);
138     return( i );
139 }
140