X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftext.c;h=53abace552d2fae4a2782cab54028a3ba539c855;hb=0784a8a882e7b98299fb6a90f0f9a7ebb322562b;hp=54e49bfe57750d8b91e49a1f1e8cb7d0e6d528b0;hpb=749f477480059aab697459927857d648f0145b8b;p=swftools.git diff --git a/lib/modules/swftext.c b/lib/modules/swftext.c index 54e49bf..53abace 100644 --- a/lib/modules/swftext.c +++ b/lib/modules/swftext.c @@ -1,13 +1,13 @@ /* swftext.c Text and font routines - + Extension module for the rfxswf library. Part of the swftools package. Copyright (c) 2001 Rainer Böhme Copyright (c) 2003,2004 Matthias Kramm - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,7 +22,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -static U32 readUTF8char(U8 ** text) +U32 readUTF8char(U8 ** text) { U32 c = 0; if (!(*(*text) & 0x80)) @@ -157,7 +157,7 @@ int swf_FontExtract_DefineFont(int id, SWFFONT * f, TAG * t) of = swf_GetU16(t); n = of / 2; f->numchars = n; - f->glyph = rfx_calloc(sizeof(SWFGLYPH) * n); + f->glyph = (SWFGLYPH*)rfx_calloc(sizeof(SWFGLYPH) * n); for (i = 1; i < n; i++) swf_GetU16(t); @@ -237,8 +237,6 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t) int swf_FontExtract_GlyphNames(int id, SWFFONT * f, TAG * tag) { U16 fid; - U16 maxcode; - U8 flags; swf_SaveTagPos(tag); swf_SetTagPos(tag, 0); @@ -247,7 +245,7 @@ int swf_FontExtract_GlyphNames(int id, SWFFONT * f, TAG * tag) if (fid == id) { int num = swf_GetU16(tag); int t; - f->glyphnames = rfx_alloc(sizeof(char *) * num); + f->glyphnames = (char**)rfx_alloc(sizeof(char *) * num); for (t = 0; t < num; t++) { f->glyphnames[t] = strdup(swf_GetString(tag)); } @@ -298,7 +296,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) font->glyph = (SWFGLYPH *) rfx_calloc(sizeof(SWFGLYPH) * glyphcount); font->glyph2ascii = (U16 *) rfx_calloc(sizeof(U16) * glyphcount); - offset = rfx_calloc(sizeof(U32)*(glyphcount+1)); + offset = (U32*)rfx_calloc(sizeof(U32)*(glyphcount+1)); offset_start = tag->pos; if (flags1 & 8) { // wide offsets @@ -358,7 +356,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) S16 advance = swf_GetS16(tag); font->glyph[t].advance = advance; } - font->layout->bounds = rfx_alloc(glyphcount * sizeof(SRECT)); + font->layout->bounds = (SRECT*)rfx_alloc(glyphcount * sizeof(SRECT)); for (t = 0; t < glyphcount; t++) { swf_ResetReadBits(tag); swf_GetRect(tag, &font->layout->bounds[t]); @@ -369,7 +367,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) font->layout->kerning = (SWFKERNING *) rfx_alloc(sizeof(SWFKERNING) * kerningcount); if (kerningcount) { - font->layout->kerning = rfx_alloc(sizeof(*font->layout->kerning) * kerningcount); + font->layout->kerning = (SWFKERNING*)rfx_alloc(sizeof(*font->layout->kerning) * kerningcount); for (t = 0; t < kerningcount; t++) { if (flags1 & 4) { // wide codes font->layout->kerning[t].char1 = swf_GetU16(tag); @@ -400,7 +398,7 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs, SRECT r; MATRIX m; U8 gbits, abits; - int fid = 0; + int fid = -1; RGBA color; int x = 0, y = 0; int fontsize = 0; @@ -431,6 +429,8 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs, color.b = swf_GetU8(t); if (swf_GetTagID(t) == ST_DEFINETEXT2) color.a = swf_GetU8(t); + else + color.a = 255; } if (flags & TF_HASXOFFSET) x = swf_GetS16(t); @@ -457,20 +457,14 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs, adv = swf_GetBits(t, abits); xpos += adv; - // if (id == fid) { if (jobs & FEDTJ_PRINT) { int code = f->glyph2ascii[glyph]; - printf("%c", code); + printf("%lc", code); } if (jobs & FEDTJ_MODIFY) f->glyph[glyph].advance = adv * 20; //? - } else { - if (jobs & FEDTJ_PRINT) { - printf("?"); - } } - // buf[i] = glyph; } @@ -570,16 +564,20 @@ void swf_LayoutFree(SWFLAYOUT * l) static void font_freeglyphnames(SWFFONT*f) { - if (f->glyphnames) { - int t; - for (t = 0; t < f->numchars; t++) { - if (f->glyphnames[t]) - rfx_free(f->glyphnames[t]); + if (f->glyphnames) + { + int t; + for (t = 0; t < f->numchars; t++) + { + if (f->glyphnames[t]) + { + rfx_free(f->glyphnames[t]); + f->glyphnames[t] = 0; + } + } + rfx_free(f->glyphnames); + f->glyphnames = 0; } - rfx_free(f->glyphnames); - f->glyphnames = 0; - } - } static void font_freeusage(SWFFONT*f) { @@ -648,6 +646,54 @@ int swf_FontReduce_old(SWFFONT * f) return j; } +int swf_FontReduce_swfc(SWFFONT * f) +{ + int i, j; + int max_unicode = 0; + if ((!f) || (!f->use) || f->use->is_reduced) + return -1; + + font_freeglyphnames(f); + + j = 0; + for (i = 0; i < f->numchars; i++) { + if (f->glyph[i].shape && f->use->chars[i]) { + f->glyph2ascii[j] = f->glyph2ascii[i]; + if (f->layout) + f->layout->bounds[j] = f->layout->bounds[i]; + f->glyph[j] = f->glyph[i]; + f->use->chars[i] = j; + j++; + } else { + f->glyph2ascii[i] = 0; + if(f->glyph[i].shape) { + swf_ShapeFree(f->glyph[i].shape); + f->glyph[i].shape = 0; + f->glyph[i].advance = 0; + } + f->use->chars[i] = -1; + } + } + f->use->used_glyphs = j; + for (i = 0; i < f->maxascii; i++) { + if(f->ascii2glyph[i] > -1) { + if (f->use->chars[f->ascii2glyph[i]]<0) { + f->use->chars[f->ascii2glyph[i]] = 0; + f->ascii2glyph[i] = -1; + } else { + f->ascii2glyph[i] = f->use->chars[f->ascii2glyph[i]]; + f->use->chars[f->ascii2glyph[i]] = 1; + max_unicode = i + 1; + } + } + } + f->maxascii = max_unicode; + f->use->is_reduced = 1; + f->numchars = j; + font_freename(f); + return j; +} + int swf_FontReduce(SWFFONT * f) { int i; @@ -656,42 +702,50 @@ int swf_FontReduce(SWFFONT * f) if ((!f) || (!f->use) || f->use->is_reduced) return -1; + font_freelayout(f); + font_freeglyphnames(f); + + f->use->used_glyphs= 0; for (i = 0; i < f->numchars; i++) { if(!f->use->chars[i]) { - f->glyph2ascii[i] = 0; + if(f->glyph2ascii) { + f->glyph2ascii[i] = 0; + } if(f->glyph[i].shape) { swf_ShapeFree(f->glyph[i].shape); f->glyph[i].shape = 0; f->glyph[i].advance = 0; } +// f->use->used_glyphs++; } else { + f->use->used_glyphs++; max_glyph = i+1; } } for (i = 0; i < f->maxascii; i++) { - if(!f->use->chars[f->ascii2glyph[i]]) { - f->ascii2glyph[i] = -1; + if(f->ascii2glyph[i] > -1 && !f->use->chars[f->ascii2glyph[i]]) { + if(f->ascii2glyph) { + f->ascii2glyph[i] = -1; + } } else { max_unicode = i+1; } } f->maxascii = max_unicode; f->numchars = max_glyph; - font_freelayout(f); - font_freeglyphnames(f); font_freename(f); return 0; } void swf_FontSort(SWFFONT * font) { - int i, j, k; + int i, j; int *newplace; int *newpos; if (!font) return; - - newplace = rfx_alloc(sizeof(int) * font->numchars); + + newplace = (int*)rfx_alloc(sizeof(int) * font->numchars); for (i = 0; i < font->numchars; i++) { newplace[i] = i; @@ -729,7 +783,7 @@ void swf_FontSort(SWFFONT * font) } } } - newpos = rfx_alloc(sizeof(int) * font->numchars); + newpos = (int*)rfx_alloc(sizeof(int) * font->numchars); for (i = 0; i < font->numchars; i++) { newpos[newplace[i]] = i; } @@ -757,9 +811,10 @@ int swf_FontInitUsage(SWFFONT * f) fprintf(stderr, "Usage initialized twice"); return -1; } - f->use = rfx_alloc(sizeof(FONTUSAGE)); + f->use = (FONTUSAGE*)rfx_alloc(sizeof(FONTUSAGE)); f->use->is_reduced = 0; - f->use->chars = rfx_calloc(sizeof(f->use->chars[0]) * f->numchars); + f->use->used_glyphs = 0; + f->use->chars = (int*)rfx_calloc(sizeof(f->use->chars[0]) * f->numchars); return 0; } @@ -773,24 +828,50 @@ void swf_FontClearUsage(SWFFONT * f) int swf_FontUse(SWFFONT * f, U8 * s) { - if (!f->use) - swf_FontInitUsage(f); if( (!s)) return -1; while (*s) { if(*s < f->maxascii && f->ascii2glyph[*s]>=0) - f->use->chars[f->ascii2glyph[*s]] = 1; + swf_FontUseGlyph(f, f->ascii2glyph[*s]); s++; } return 0; } +int swf_FontUseUTF8(SWFFONT * f, U8 * s) +{ + if( (!s)) + return -1; + int ascii; + while (*s) + { + ascii = readUTF8char(&s); + if(ascii < f->maxascii && f->ascii2glyph[ascii]>=0) + swf_FontUseGlyph(f, f->ascii2glyph[ascii]); + } + return 0; +} + +int swf_FontUseAll(SWFFONT* f) +{ + int i; + + if (!f->use) + swf_FontInitUsage(f); + for (i = 0; i < f->numchars; i++) + f->use->chars[i] = 1; + f->use->used_glyphs = f->numchars; + return 0; +} + int swf_FontUseGlyph(SWFFONT * f, int glyph) { - if (!f->use) + if (!f->use) swf_FontInitUsage(f); if(glyph < 0 || glyph >= f->numchars) return -1; + if(!f->use->chars[glyph]) + f->use->used_glyphs++; f->use->chars[glyph] = 1; return 0; } @@ -835,7 +916,7 @@ static inline int fontSize(SWFFONT * font) int size = 0; for (t = 0; t < font->numchars; t++) { int l = 0; - if(font->glyph[t].shape) + if(font->glyph[t].shape) l = (font->glyph[t].shape->bitlen + 7) / 8; else l = 8; @@ -849,7 +930,6 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f) U8 flags = 0; int t; int pos; - int pos2; swf_SetU16(tag, f->id); if (f->layout) flags |= 128; // haslayout @@ -876,8 +956,8 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f) swf_SetU8(tag, 0); //reserved flags if (f->name) { /* font name */ - swf_SetU8(tag, strlen(f->name)); - swf_SetBlock(tag, f->name, strlen(f->name)); + swf_SetU8(tag, strlen((const char*)f->name)); + swf_SetBlock(tag, f->name, strlen((const char*)f->name)); } else { /* font name (="") */ swf_SetU8(tag, 0); @@ -918,14 +998,22 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f) /* font code table */ - if (flags & 4) { /* wide codes */ - for (t = 0; t < f->numchars; t++) { - swf_SetU16(tag, f->glyph2ascii[t]); + for (t = 0; t < f->numchars; t++) { + if (flags & 4) { /* wide codes */ + if(f->glyph2ascii[t]) { + swf_SetU16(tag, f->glyph2ascii[t]); + } else { + swf_SetU16(tag, 0); + } + } else { + if(f->glyph2ascii[t]) { + swf_SetU8(tag, f->glyph2ascii[t]); + } else { + swf_SetU8(tag, 0); + } } - } else { - for (t = 0; t < f->numchars; t++) - swf_SetU8(tag, f->glyph2ascii[t]); } + if (f->layout) { swf_SetU16(tag, f->layout->ascent); swf_SetU16(tag, f->layout->descent); @@ -971,7 +1059,7 @@ int swf_FontSetInfo(TAG * t, SWFFONT * f) return -1; swf_ResetWriteBits(t); swf_SetU16(t, f->id); - l = f->name ? strlen(f->name) : 0; + l = f->name ? strlen((const char *)f->name) : 0; if (l > 255) l = 255; swf_SetU8(t, l); @@ -995,7 +1083,7 @@ int swf_FontSetInfo(TAG * t, SWFFONT * f) for (i = 0; i < f->numchars; i++) { if (f->glyph[i].shape) { - int g2a = f->glyph2ascii[i]; + int g2a = f->glyph2ascii?f->glyph2ascii[i]:0; wide ? swf_SetU16(t, g2a) : swf_SetU8(t, g2a); } } @@ -1017,24 +1105,28 @@ void swf_FontFree(SWFFONT * f) { int i; if (!f) - return; + return; - if (f->glyph) { - for (i = 0; i < f->numchars; i++) - if (f->glyph[i].shape) { - swf_ShapeFree(f->glyph[i].shape); - f->glyph[i].shape = NULL; - } - rfx_free(f->glyph); - f->glyph = NULL; + if (f->glyph) + { + for (i = 0; i < f->numchars; i++) + if (f->glyph[i].shape) + { + swf_ShapeFree(f->glyph[i].shape); + f->glyph[i].shape = NULL; + } + rfx_free(f->glyph); + f->glyph = NULL; } - if (f->ascii2glyph) { - rfx_free(f->ascii2glyph); - f->ascii2glyph = NULL; + if (f->ascii2glyph) + { + rfx_free(f->ascii2glyph); + f->ascii2glyph = NULL; } - if (f->glyph2ascii) { - rfx_free(f->glyph2ascii); - f->glyph2ascii = NULL; + if (f->glyph2ascii) + { + rfx_free(f->glyph2ascii); + f->glyph2ascii = NULL; } font_freename(f); font_freelayout(f); @@ -1156,6 +1248,11 @@ static int swf_TextSetCharRecord2(TAG * t, SWFFONT * font, U8 * s, int scale, U8 swf_SetBits(t, g, gbits); swf_SetBits(t, ((((U32) font->glyph[g].advance) * scale) / 20) / 100, abits); l++; + /* We split into 127 characters per text field. + We could do 255, by the (formerly wrong) flash specification, + but some SWF parsing code out there still assumes that char blocks + are at max 127 characters, and it would save only a few bits. + */ if (l == 0x7f) break; } @@ -1214,6 +1311,14 @@ SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale) swf_GetRect(0, &r); while (*s) { int c = readUTF8char(&s); + if(c==13 || c==10) { + if(s[0] == 10) { + s++; + } + xpos=0; + ypos+=font->layout->leading; + continue; + } if (c < font->maxascii) { int g = font->ascii2glyph[c]; if (g >= 0) { @@ -1226,7 +1331,6 @@ SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale) xpos += (font->glyph[g].advance * scale) / 20 / 100; } } - c++; } return r; } @@ -1265,7 +1369,7 @@ void swf_WriteFont(SWFFONT * font, char *filename) int storeGlyphNames = 1; if (font->layout) - useDefineFont2 = 1; /* the only thing new in definefont2 + useDefineFont2 = 1; /* the only thing new in definefont2 is layout information. */ font->id = WRITEFONTID; //"FN" @@ -1305,9 +1409,9 @@ void swf_WriteFont(SWFFONT * font, char *filename) swf_SetU16(t, font->numchars); for (c = 0; c < font->numchars; c++) { if (font->glyphnames[c]) - swf_SetString(t, font->glyphnames[c]); + swf_SetString(t, (U8*)font->glyphnames[c]); else - swf_SetString(t, ""); + swf_SetString(t, (U8*)""); } } @@ -1456,19 +1560,23 @@ void swf_SetEditText(TAG * tag, U16 flags, SRECT r, char *text, RGBA * color, in swf_SetU16(tag, layout->indent); //indent swf_SetU16(tag, layout->leading); //leading } - swf_SetString(tag, variable); + swf_SetString(tag, (U8*)variable); if (flags & ET_HASTEXT) - swf_SetString(tag, text); + swf_SetString(tag, (U8*)text); } SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int scale) { SRECT r; U8 gbits, abits; - U8 *c = (U8 *) text; + U8 *utext = (U8 *) strdup(text); + U8 *upos = utext; + int x = 0, y = 0; int pos = 0; + int ystep = 0; if (font->layout) { - r = swf_TextCalculateBBoxUTF8(font, text, scale * 20); + r = swf_TextCalculateBBoxUTF8(font, (U8*)text, scale * 20); + ystep = font->layout->leading; } else { fprintf(stderr, "No layout information- can't compute text bbox accurately"); /* Hm, without layout information, we can't compute a bounding @@ -1478,6 +1586,7 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s */ r.xmin = r.ymin = 0; r.xmax = r.ymax = 1024 * 20; + ystep = 100; } swf_SetRect(tag, &r); @@ -1490,21 +1599,47 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s */ swf_SetMatrix(tag, 0); - swf_TextCountBitsUTF8(font, text, scale * 20, &gbits, &abits); + swf_TextCountBitsUTF8(font, (U8*)text, scale * 20, &gbits, &abits); swf_SetU8(tag, gbits); swf_SetU8(tag, abits); - /* now set the text params- notice that a font size of - 1024 means that the glyphs will be displayed exactly - as they would be in/with a defineshape. (Try to find - *that* in the flash specs) - */ - swf_TextSetInfoRecord(tag, font, (scale * 1024) / 100, rgb, 0, 0); //scale + while(*upos) { + U8*next = upos; + int count = 0; + + swf_TextSetInfoRecord(tag, font, (scale * 1024) / 100, rgb, x, y); //scale + x = 0; + + while(*next && *next!=13 && *next!=10 && count<127) { + readUTF8char(&next); + count++; + } + if(next[0] == 13 || next[0] == 10) { + x = SET_TO_ZERO; + y += ystep; + } - /* set the actual text- notice that we just pass our scale - parameter over, as TextSetCharRecord calculates with - percent, too */ - swf_TextSetCharRecordUTF8(tag, font, text, scale * 20, gbits, abits); + if(next[0] == 13 && next[1] == 10) + next++; + + if(next[0] == 13 || next[0] == 10) { + *next = 0; + next++; + } + + /* now set the text params- notice that a font size of + 1024 means that the glyphs will be displayed exactly + as they would be in/with a defineshape. (Try to find + *that* in the flash specs) + */ + /* set the actual text- notice that we just pass our scale + parameter over, as TextSetCharRecord calculates with + percent, too */ + swf_TextSetCharRecordUTF8(tag, font, upos, scale * 20, gbits, abits); + + upos= next; + } + free(utext); swf_SetU8(tag, 0); return r;