bfca4faeb9e8d58f4a03584d099844023021341e
[swftools.git] / src / swfstrings.c
1 /* swfstrings.c
2    Scans a swf file for strings
3
4    Part of the swftools package.
5    
6    Copyright (c) 2000,2001 Rainer Böhme <rfxswf@reflex-studio.de>
7  
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include "../lib/rfxswf.h"
25 #include "../lib/args.h"
26 #include "../lib/utf8.h"
27
28 static char * filename = 0;
29 static char showfonts = 0;
30 static int x=0,y=0,w=0,h=0;
31
32 static struct options_t options[] = {
33 {"f", "fonts"},
34 {"x", "xpos"},
35 {"y", "ypos"},
36 {"W", "width"},
37 {"H", "height"},
38 {"V", "version"},
39 {0,0}
40 };
41
42 int args_callback_option(char*name,char*val)
43 {
44     if(!strcmp(name, "V")) {
45         printf("swfstrings - part of %s %s\n", PACKAGE, VERSION);
46         exit(0);
47     } else if(!strcmp(name, "x")) {
48         x = atoi(val);
49         return 1;
50     } else if(!strcmp(name, "y")) {
51         y = atoi(val);
52         return 1;
53     } else if(!strcmp(name, "W")) {
54         w = atoi(val);
55         return 1;
56     } else if(!strcmp(name, "H")) {
57         h = atoi(val);
58         return 1;
59     } else if(!strcmp(name, "f")) {
60         showfonts = 1;
61         return 0;
62     } else if(!strcmp(name, "V")) {
63         printf("swfstrings - part of %s %s\n", PACKAGE, VERSION);
64         exit(0);
65     } else {
66         fprintf(stderr, "Unknown option: -%s\n", name);
67         exit(1);
68     }
69     return 0;
70 }
71 int args_callback_longoption(char*name,char*val)
72 {
73     return args_long2shortoption(options, name, val);
74 }
75 void args_callback_usage(char *name)
76 {
77     printf("\n");
78     printf("Usage: %s [options] file.swf\n", name);
79     printf("\n");
80     printf("-f , --fonts                   Print out font information for each text block\n");
81     printf("-x , --xpos <x>                Set bounding box x coordinate\n");
82     printf("-y , --ypos <y>                Set bounding box y coordinate\n");
83     printf("-W , --width <width>           Set bounding box width\n");
84     printf("-H , --height <height>         Set bounding box height\n");
85     printf("-V , --version                 Print version information and exit\n");
86     printf("\n");
87 }
88 int args_callback_command(char*name,char*val)
89 {
90     if(filename) {
91         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
92                  filename, name);
93     }
94     filename = name;
95     return 0;
96 }
97
98 static SWF swf;
99 static int fontnum = 0;
100 static SWFFONT**fonts = 0;
101
102 void fontcallback1(void*self, U16 id,U8 * name)
103 { fontnum++;
104 }
105
106 void fontcallback2(void*self, U16 id,U8 * name)
107
108   swf_FontExtract(&swf,id,&fonts[fontnum]);
109   fontnum++;
110 }
111
112
113 void textcallback(void*self, int*glyphs, int*advance, int nr, int fontid, int fontsize, int startx, int starty, RGBA*color) 
114 {
115     SWFFONT*font = 0;
116     int t;
117     for(t=0;t<fontnum;t++)
118     {
119         if(fonts[t]->id == fontid) {
120             font = fonts[t];
121             break;
122         }
123     }
124
125     if(showfonts) {
126         if(font)
127             printf("#<font %d \"%s\"%s%s>\n", fontid, font->name, swf_FontIsBold(font)?" bold":"",swf_FontIsItalic(font)?" italic":"");
128         printf("#<color #%02x%02x%02x%02x>\n", color->r, color->g, color->b, color->a);
129         printf("#<size %d>\n", fontsize);
130     }
131
132     for(t=0;t<nr;t++)
133     {
134         int xx = startx + advance[t]/20;
135         if(x|y|w|h) {
136             /* TODO: this does not do any matrix handling yet */
137
138             if(xx < x || starty < y || xx > x+w || starty > y+h) {
139                 /* outside of bounding box */
140                 continue;
141             }
142         }
143
144         unsigned char a; 
145         int advance = 0;
146         if(font>=0) {
147             if(glyphs[t]<0 || glyphs[t] >= font->numchars  /*glyph is not in range*/
148                     || !font->glyph2ascii /* font has ascii<->glyph mapping */
149               ) a = glyphs[t];
150             else {
151                 if(font->glyph2ascii[glyphs[t]])
152                     a = font->glyph2ascii[glyphs[t]];
153                 else
154                     a = glyphs[t];
155             }
156         } else {
157             a = glyphs[t];
158         }
159
160         if(a>=32) {
161             char* utf8 = getUTF8(a);
162             printf("%s", utf8);
163         } else {
164             printf("\\x%x", (int)a);
165         }
166     }
167     printf("\n");
168 }
169
170 void fontcallback(void*self,U16 id,U8 * name)
171 { SWFFONT* font;
172   TAG* t;
173   
174   swf_FontExtract(&swf,id,&font);
175
176   t = swf.firstTag;
177
178   swf_FontFree(font);
179 }
180
181
182 int main (int argc,char ** argv)
183
184     int f;
185     processargs(argc, argv);
186     if(!filename)
187         exit(0);
188
189     f = open(filename,O_RDONLY|O_BINARY);
190     if (f<0 || swf_ReadSWF(f,&swf)<0) {
191         fprintf(stderr,"%s is not a valid SWF file or contains errors.\n",filename);
192         if(f>=0) close(f);
193         exit(-1);
194     }
195     close(f);
196     
197     if(x|y|w|h) {
198         if(!w) w = (swf.movieSize.xmax - swf.movieSize.xmin) / 20;
199         if(!h) h = (swf.movieSize.ymax - swf.movieSize.ymin) / 20;
200     }
201
202     fontnum = 0;
203     swf_FontEnumerate(&swf,&fontcallback1, 0);
204     fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*));
205     fontnum = 0;
206     swf_FontEnumerate(&swf,&fontcallback2, 0);
207  
208     TAG*tag = swf.firstTag;
209     while (tag)
210     { 
211         if(swf_isTextTag(tag)) {
212             swf_ParseDefineText(tag, textcallback, 0);
213         }
214         tag = tag->next;
215     }
216   
217     swf_FreeTags(&swf);
218     return 0;
219 }
220