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