5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
10 This file is distributed under the GPL, see file COPYING for details
14 #define TF_TEXTCONTROL 0x80
15 #define TF_HASFONT 0x08
16 #define TF_HASCOLOR 0x04
17 #define TF_HASYOFFSET 0x02
18 #define TF_HASXOFFSET 0x01
20 #define FF_WIDECODES 0x01
22 #define FF_ITALIC 0x04
24 #define FF_SHIFTJIS 0x10
25 #define FF_UNICODE 0x20
27 int FontEnumerate(SWF * swf,void (*FontCallback) (U16,U8*))
35 { if (GetTagID(t)==ST_DEFINEFONTINFO)
59 int FontExtract_DefineFont(int id,SWFFONT * f,TAG * t,SHAPE * * shapes)
66 { U16 ofs[MAX_CHAR_PER_FONT];
75 for (i=1;i<n;i++) if (i<MAX_CHAR_PER_FONT) ofs[i] = GetU16(t); else GetU16(t);
76 for (i=0;i<n;i++) if (i<MAX_CHAR_PER_FONT) GetSimpleShape(t,&shapes[i]);
84 int FontExtract_DefineFontInfo(int id,SWFFONT * f,TAG * t,SHAPE * * shapes)
95 { if (f->name) free(f->name);
96 f->name = (U8*)malloc(l+1);
98 { GetBlock(t,f->name,l);
110 { U16 code = ((f->flags&FF_WIDECODES)?GetU16(t):GetU8(t))%MAX_CHAR_PER_FONT;
112 f->glyph[code].shape = shapes[i];
113 f->glyph[code].gid = i;
114 if (i<MAX_CHAR_PER_FONT) f->codes[i] = code;
124 #define FEDTJ_PRINT 0x01
125 #define FEDTJ_MODIFY 0x02
127 int FontExtract_DefineText(int id,SWFFONT * f,TAG * t,int jobs)
131 U8 gbits, abits, flags;
148 { if (flags&TF_TEXTCONTROL)
149 { if (flags&TF_HASFONT) fid = GetU16(t);
150 if (flags&TF_HASCOLOR)
154 if (GetTagID(t)==ST_DEFINETEXT2) GetU8(t);
156 if (flags&TF_HASXOFFSET) GetS16(t);
157 if (flags&TF_HASYOFFSET) GetS16(t);
158 if (flags&TF_HASFONT) GetU16(t);
162 for (i=0;i<flags;i++)
165 glyph = GetBits(t,gbits);
166 adv = GetBits(t,abits);
167 if (id==fid) // mitlesen ?
168 { int code = f->codes[glyph];
169 if (jobs&FEDTJ_PRINT) printf("%c",code);
170 if (jobs&FEDTJ_MODIFY)
171 /*if (f->glyph[code].advance)*/ f->glyph[code].advance = adv;
174 if ((id==fid)&&(jobs&FEDTJ_PRINT)) printf("\n");
183 int FontExtract(SWF * swf,int id,SWFFONT * * font)
186 SHAPE * shapes[MAX_CHAR_PER_FONT];
188 if ((!swf)||(!font)) return -1;
190 f = (SWFFONT *)malloc(sizeof(SWFFONT)); font[0] = f;
193 memset(shapes,0x00,sizeof(shapes));
194 memset(f,0x00,sizeof(SWFFONT));
201 { case ST_DEFINEFONT:
202 nid = FontExtract_DefineFont(id,f,t,shapes);
205 case ST_DEFINEFONTINFO:
206 nid = FontExtract_DefineFontInfo(id,f,t,shapes);
211 nid = FontExtract_DefineText(id,f,t,FEDTJ_MODIFY);
220 int FontIsItalic(SWFFONT * f) { return f->flags&FF_ITALIC; }
221 int FontIsBold(SWFFONT * f) { return f->flags&FF_BOLD; }
223 int FontSetID(SWFFONT * f,U16 id) { if (!f) return -1; f->id = id; return 0; }
225 int FontReduce(SWFFONT * f,FONTUSAGE * use)
227 if ((!f)||(!use)) return -1;
229 memset(&f->codes,0x00,sizeof(f->codes));
232 for (i=0;i<MAX_CHAR_PER_FONT;i++)
233 if (f->glyph[i].shape)
235 { f->glyph[i].gid = j;
240 { ShapeFree(f->glyph[i].shape);
241 f->glyph[i].shape = 0;
243 f->glyph[i].advance = 0;
245 } else f->glyph[i].gid = 0;
250 int FontInitUsage(FONTUSAGE * use)
251 { if (!use) return -1;
252 memset(&use->code,0x00,sizeof(use->code));
256 int FontUse(FONTUSAGE * use,U8 * s)
257 { if ((!use)||(!s)) return -1;
259 { use->code[s[0]] = 1;
265 int FontSetDefine(TAG * t,SWFFONT * f)
266 { U16 ofs[MAX_CHAR_PER_FONT];
269 if ((!t)||(!f)) return -1;
274 for (i=0;i<MAX_CHAR_PER_FONT;i++)
275 if (f->glyph[i].shape)
277 p+=SetSimpleShape(NULL,f->glyph[i].shape);
280 for (i=0;i<j;i++) SetU16(t,ofs[i]+j*2);
282 for (i=0;i<MAX_CHAR_PER_FONT;i++)
283 if (f->glyph[i].shape)
284 SetSimpleShape(t,f->glyph[i].shape);
290 int FontSetInfo(TAG * t,SWFFONT * f)
292 if ((!t)||(!f)) return -1;
295 l = strlen(f->name); if (l>255) l = 255;
297 SetBlock(t,f->name,l);
298 SetU8(t,f->flags&0xfe); // no Wide-Codes
300 for (i=0;i<MAX_CHAR_PER_FONT;i++)
301 if (f->glyph[i].shape)
307 int FontExport(int handle,SWFFONT * f)
314 if (write(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) return -1;
317 { U16 ln = strlen(f->name);
320 { if (write(handle,&ln,2)!=2) return -1;
321 if (write(handle,f->name,ln)!=ln) return -1;
326 { l+=sizeof(SWFLAYOUT);
328 if (write(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) return -1;
329 if (f->layout->kerning.data)
330 { l+=f->layout->kerning.count*4;
332 if (write(handle,f->layout->kerning.data,f->layout->kerning.count*4)!=f->layout->kerning.count*4) return -1;
336 for (i=0;i<MAX_CHAR_PER_FONT;i++)
337 { if (f->glyph[i].shape)
338 { int ll = ShapeExport(handle,f->glyph[i].shape);
347 int FontImport(int handle,SWFFONT * * font)
352 if ((!font)||(handle<0)) return -1;
354 f = (SWFFONT *)malloc(sizeof(SWFFONT)); font[0] = f;
357 memset(f,0x00,sizeof(SWFFONT));
359 if (read(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) goto fehler;
361 layout = (f->layout)?1:0; // avoid illegal free()
367 if (read(handle,&ln,2)!=2) goto fehler;
368 f->name = (U8*)malloc(ln+1);
369 if (!f->name) goto fehler;
370 if (read(handle,f->name,ln)!=ln) goto fehler;
375 { f->layout = (SWFLAYOUT *)malloc(sizeof(SWFLAYOUT));
376 if (!f->layout) goto fehler;
377 if (read(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) goto fehler;
378 if (f->layout->kerning.data)
379 { int l = f->layout->kerning.count*4;
380 f->layout->kerning.data = (U8*)malloc(l);
381 if (!f->layout->kerning.data) goto fehler;
382 if (read(handle,f->layout->kerning.data,l)!=l) goto fehler;
386 for (i=0;i<MAX_CHAR_PER_FONT;i++)
387 { if (f->glyph[i].shape)
388 { if (ShapeImport(handle,&f->glyph[i].shape)<0) goto fehler;
397 if (f) for (;i<MAX_CHAR_PER_FONT;i++) f->glyph[i].shape = NULL;
403 int TextPrintDefineText(TAG * t,SWFFONT * f)
404 { int id = GetTagID(t);
405 if ((id==ST_DEFINETEXT)||(id==ST_DEFINETEXT2)) FontExtract_DefineText(f->id,f,t,FEDTJ_PRINT);
410 void LayoutFree(SWFLAYOUT * l)
412 { if (l->kerning.data) free(l->kerning.data);
413 l->kerning.data = NULL;
418 void FontFree(SWFFONT * f)
422 if (f->name) free(f->name);
423 if (f->layout) LayoutFree(f->layout);
428 for (i=0;i<MAX_CHAR_PER_FONT;i++)
429 if (f->glyph[i].shape)
430 { ShapeFree(f->glyph[i].shape);
431 f->glyph[i].shape = NULL;
437 int TextSetInfoRecord(TAG * t,SWFFONT * font,U16 size,RGBA * color,S16 dx,S16 dy)
441 flags = TF_TEXTCONTROL|(font?TF_HASFONT:0)|(color?TF_HASCOLOR:0)|(dx?TF_HASXOFFSET:0)|(dy?TF_HASYOFFSET:0);
444 if (font) SetU16(t,font->id);
446 { if (GetTagID(t)==ST_DEFINETEXT2) SetRGBA(t,color);
447 else SetRGB(t,color);
449 if (dx) SetS16(t,dx);
450 if (dy) SetS16(t,dy);
451 if (font) SetU16(t,size);
456 int TextCountBits(SWFFONT * font,U8 * s,int scale,U8 * gbits,U8 * abits)
458 if ((!s)||(!font)||((!gbits)&&(!abits))) return -1;
462 { g = CountBits(font->glyph[s[0]].gid,g);
463 a = CountBits((((U32)font->glyph[s[0]].advance)*scale)/100,a);
467 if (gbits) gbits[0] = (U8)g;
468 if (abits) abits[0] = (U8)a;
473 int TextSetCharRecord(TAG * t,SWFFONT * font,U8 * s,int scale,U8 gbits,U8 abits)
476 if ((!t)||(!font)||(!s)) return -1;
479 if (l>0x7f) l = 0x7f;
483 { SetBits(t,font->glyph[s[i]].gid,gbits);
484 SetBits(t,(((U32)font->glyph[s[i]].advance)*scale)/100,abits);
491 U32 TextGetWidth(SWFFONT * font,U8 * s,int scale)
496 { res += font->glyph[s[0]].advance;
499 if (scale) res = (res*scale)/100;