X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftext.c;h=53abace552d2fae4a2782cab54028a3ba539c855;hb=0784a8a882e7b98299fb6a90f0f9a7ebb322562b;hp=a01e10b737448876545f7c2fc10a3b57c9d8e067;hpb=e29b8eb23fc41253809ea4bc090007f80ef3f708;p=swftools.git diff --git a/lib/modules/swftext.c b/lib/modules/swftext.c index a01e10b..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)) @@ -101,7 +101,7 @@ int swf_FontIsBold(SWFFONT * f) static const int WRITEFONTID = 0x4e46; // font id for WriteFont and ReadFont -int swf_FontEnumerate(SWF * swf, void (*FontCallback) (U16, U8 *)) +int swf_FontEnumerate(SWF * swf, void (*FontCallback) (void*, U16, U8 *), void*self) { int n; TAG *t; @@ -129,7 +129,7 @@ int swf_FontEnumerate(SWF * swf, void (*FontCallback) (U16, U8 *)) s[l] = 0; } - (FontCallback) (id, s); + (FontCallback) (self, id, s); swf_RestoreTagPos(t); } @@ -157,8 +157,7 @@ int swf_FontExtract_DefineFont(int id, SWFFONT * f, TAG * t) of = swf_GetU16(t); n = of / 2; f->numchars = n; - f->glyph = malloc(sizeof(SWFGLYPH) * n); - memset(f->glyph, 0, sizeof(SWFGLYPH) * n); + f->glyph = (SWFGLYPH*)rfx_calloc(sizeof(SWFGLYPH) * n); for (i = 1; i < n; i++) swf_GetU16(t); @@ -191,9 +190,9 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t) } if (f->name) - free(f->name); + rfx_free(f->name); - f->name = (U8 *) malloc(l + 1); + f->name = (U8 *) rfx_alloc(l + 1); swf_GetBlock(t, f->name, l); f->name[l] = 0; @@ -213,7 +212,7 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t) f->language = swf_GetU8(t); } - f->glyph2ascii = (U16 *) malloc(sizeof(U16) * f->numchars); + f->glyph2ascii = (U16 *) rfx_alloc(sizeof(U16) * f->numchars); maxcode = 0; for (i = 0; i < f->numchars; i++) { f->glyph2ascii[i] = ((flags & FF_WIDECODES) ? swf_GetU16(t) : swf_GetU8(t)); @@ -224,7 +223,7 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t) if (maxcode < 256) maxcode = 256; f->maxascii = maxcode; - f->ascii2glyph = (int *) malloc(sizeof(int) * maxcode); + f->ascii2glyph = (int *) rfx_alloc(sizeof(int) * maxcode); memset(f->ascii2glyph, -1, sizeof(int) * maxcode); for (i = 0; i < f->numchars; i++) @@ -238,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); @@ -248,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 = malloc(sizeof(char *) * num); + f->glyphnames = (char**)rfx_alloc(sizeof(char *) * num); for (t = 0; t < num; t++) { f->glyphnames[t] = strdup(swf_GetString(tag)); } @@ -264,6 +261,8 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) int t, glyphcount; int maxcode; int fid; + U32 offset_start; + U32 *offset; U8 flags1, flags2, namelen; swf_SaveTagPos(tag); swf_SetTagPos(tag, 0); @@ -287,35 +286,44 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) font->encoding |= FONT_ENCODING_SHIFTJIS; namelen = swf_GetU8(tag); - font->name = (U8 *) malloc(namelen + 1); + font->name = (U8 *) rfx_alloc(namelen + 1); font->name[namelen] = 0; swf_GetBlock(tag, font->name, namelen); font->version = 2; glyphcount = swf_GetU16(tag); font->numchars = glyphcount; - font->glyph = (SWFGLYPH *) malloc(sizeof(SWFGLYPH) * glyphcount); - memset(font->glyph, 0, sizeof(SWFGLYPH) * glyphcount); - font->glyph2ascii = (U16 *) malloc(sizeof(U16) * glyphcount); - memset(font->glyph2ascii, 0, sizeof(U16) * glyphcount); + font->glyph = (SWFGLYPH *) rfx_calloc(sizeof(SWFGLYPH) * glyphcount); + font->glyph2ascii = (U16 *) rfx_calloc(sizeof(U16) * glyphcount); + + offset = (U32*)rfx_calloc(sizeof(U32)*(glyphcount+1)); + offset_start = tag->pos; if (flags1 & 8) { // wide offsets for (t = 0; t < glyphcount; t++) - swf_GetU32(tag); //offset[t] + offset[t] = swf_GetU32(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ - swf_GetU32(tag); // fontcodeoffset + offset[glyphcount] = swf_GetU32(tag); // fontcodeoffset + else + offset[glyphcount] = tag->pos; } else { for (t = 0; t < glyphcount; t++) - swf_GetU16(tag); //offset[t] + offset[t] = swf_GetU16(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ - swf_GetU16(tag); // fontcodeoffset + offset[glyphcount] = swf_GetU16(tag); // fontcodeoffset + else + offset[glyphcount] = tag->pos; } - /* TODO: we should use the offset positions, not just - blindly read in shapes */ - for (t = 0; t < glyphcount; t++) + for (t = 0; t < glyphcount; t++) { + swf_SetTagPos(tag, offset[t]+offset_start); swf_GetSimpleShape(tag, &(font->glyph[t].shape)); + } + + swf_SetTagPos(tag, offset[glyphcount]+offset_start); + + free(offset); maxcode = 0; for (t = 0; t < glyphcount; t++) { @@ -332,7 +340,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) if (maxcode < 256) maxcode = 256; font->maxascii = maxcode; - font->ascii2glyph = (int *) malloc(sizeof(int) * maxcode); + font->ascii2glyph = (int *) rfx_alloc(sizeof(int) * maxcode); memset(font->ascii2glyph, -1, sizeof(int) * maxcode); for (t = 0; t < glyphcount; t++) { font->ascii2glyph[font->glyph2ascii[t]] = t; @@ -340,7 +348,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) if (flags1 & 128) { // has layout U16 kerningcount; - font->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT)); + font->layout = (SWFLAYOUT *) rfx_alloc(sizeof(SWFLAYOUT)); font->layout->ascent = swf_GetU16(tag); font->layout->descent = swf_GetU16(tag); font->layout->leading = swf_GetU16(tag); @@ -348,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 = malloc(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]); @@ -357,9 +365,9 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) kerningcount = swf_GetU16(tag); font->layout->kerningcount = kerningcount; - font->layout->kerning = (SWFKERNING *) malloc(sizeof(SWFKERNING) * kerningcount); + font->layout->kerning = (SWFKERNING *) rfx_alloc(sizeof(SWFKERNING) * kerningcount); if (kerningcount) { - font->layout->kerning = malloc(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); @@ -384,13 +392,13 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) static int swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs, void (*callback) (void *self, - int *chars, int *ypos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self) + int *chars, int *xpos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self) { U16 cid; SRECT r; MATRIX m; U8 gbits, abits; - int fid = 0; + int fid = -1; RGBA color; int x = 0, y = 0; int fontsize = 0; @@ -421,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); @@ -447,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; } @@ -495,8 +499,7 @@ int swf_FontExtract(SWF * swf, int id, SWFFONT * *font) if ((!swf) || (!font)) return -1; - f = (SWFFONT *) malloc(sizeof(SWFFONT)); - memset(f, 0x00, sizeof(SWFFONT)); + f = (SWFFONT *) rfx_calloc(sizeof(SWFFONT)); t = swf->firstTag; @@ -530,7 +533,7 @@ int swf_FontExtract(SWF * swf, int id, SWFFONT * *font) t = swf_NextTag(t); } if (f->id != id) { - free(f); + rfx_free(f); f = 0; } font[0] = f; @@ -549,36 +552,40 @@ void swf_LayoutFree(SWFLAYOUT * l) { if (l) { if (l->kerning) - free(l->kerning); + rfx_free(l->kerning); l->kerning = NULL; if (l->bounds) - free(l->bounds); + rfx_free(l->bounds); l->bounds = NULL; } - free(l); + rfx_free(l); } static void font_freeglyphnames(SWFFONT*f) { - if (f->glyphnames) { - int t; - for (t = 0; t < f->numchars; t++) { - if (f->glyphnames[t]) - 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; } - free(f->glyphnames); - f->glyphnames = 0; - } - } static void font_freeusage(SWFFONT*f) { if (f->use) { if(f->use->chars) { - free(f->use->chars);f->use->chars = 0; + rfx_free(f->use->chars);f->use->chars = 0; } - free(f->use); f->use = 0; + rfx_free(f->use); f->use = 0; } } static void font_freelayout(SWFFONT*f) @@ -591,12 +598,12 @@ static void font_freelayout(SWFFONT*f) static void font_freename(SWFFONT*f) { if (f->name) { - free(f->name); + rfx_free(f->name); f->name = 0; } } -int swf_FontReduce(SWFFONT * f) +int swf_FontReduce_old(SWFFONT * f) { int i, j; int max_unicode = 0; @@ -639,15 +646,106 @@ int swf_FontReduce(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; + int max_unicode = 0; + int max_glyph = 0; + 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]) { + 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->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_freename(f); + return 0; +} + void swf_FontSort(SWFFONT * font) { - int i, j, k; + int i, j; int *newplace; int *newpos; if (!font) return; - - newplace = malloc(sizeof(int) * font->numchars); + + newplace = (int*)rfx_alloc(sizeof(int) * font->numchars); for (i = 0; i < font->numchars; i++) { newplace[i] = i; @@ -685,7 +783,7 @@ void swf_FontSort(SWFFONT * font) } } } - newpos = malloc(sizeof(int) * font->numchars); + newpos = (int*)rfx_alloc(sizeof(int) * font->numchars); for (i = 0; i < font->numchars; i++) { newpos[newplace[i]] = i; } @@ -694,8 +792,8 @@ void swf_FontSort(SWFFONT * font) font->ascii2glyph[i] = newpos[font->ascii2glyph[i]]; } - free(newpos); - free(newplace); + rfx_free(newpos); + rfx_free(newplace); } void swf_FontPrepareForEditText(SWFFONT * font) @@ -713,10 +811,10 @@ int swf_FontInitUsage(SWFFONT * f) fprintf(stderr, "Usage initialized twice"); return -1; } - f->use = malloc(sizeof(FONTUSAGE)); + f->use = (FONTUSAGE*)rfx_alloc(sizeof(FONTUSAGE)); f->use->is_reduced = 0; - f->use->chars = malloc(sizeof(f->use->chars[0]) * f->numchars); - memset(f->use->chars, 0, 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; } @@ -724,37 +822,63 @@ void swf_FontClearUsage(SWFFONT * f) { if (!f || !f->use) return; - free(f->use->chars); f->use->chars = 0; - free(f->use); f->use = 0; + rfx_free(f->use->chars); f->use->chars = 0; + rfx_free(f->use); f->use = 0; } 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) + if(glyph < 0 || glyph >= f->numchars) return -1; + if(!f->use->chars[glyph]) + f->use->used_glyphs++; f->use->chars[glyph] = 1; return 0; } int swf_FontSetDefine(TAG * t, SWFFONT * f) { - U16 *ofs = (U16 *) malloc(f->numchars * 2); + U16 *ofs = (U16 *) rfx_alloc(f->numchars * 2); int p, i, j; if ((!t) || (!f)) @@ -782,7 +906,7 @@ int swf_FontSetDefine(TAG * t, SWFFONT * f) swf_SetSimpleShape(t, f->glyph[i].shape); swf_ResetWriteBits(t); - free(ofs); + rfx_free(ofs); return 0; } @@ -792,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; @@ -806,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 @@ -833,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); @@ -875,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); @@ -910,14 +1041,13 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f) void swf_FontAddLayout(SWFFONT * f, int ascent, int descent, int leading) { - f->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT)); + f->layout = (SWFLAYOUT *) rfx_alloc(sizeof(SWFLAYOUT)); f->layout->ascent = ascent; f->layout->descent = descent; f->layout->leading = leading; f->layout->kerningcount = 0; f->layout->kerning = 0; - f->layout->bounds = (SRECT *) malloc(sizeof(SRECT) * f->numchars); - memset(f->layout->bounds, 0, sizeof(SRECT) * f->numchars); + f->layout->bounds = (SRECT *) rfx_calloc(sizeof(SRECT) * f->numchars); } int swf_FontSetInfo(TAG * t, SWFFONT * f) @@ -929,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); @@ -953,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); } } @@ -975,31 +1105,35 @@ 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; - } - 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) { - free(f->ascii2glyph); - f->ascii2glyph = NULL; + if (f->ascii2glyph) + { + rfx_free(f->ascii2glyph); + f->ascii2glyph = NULL; } - if (f->glyph2ascii) { - free(f->glyph2ascii); - f->glyph2ascii = NULL; + if (f->glyph2ascii) + { + rfx_free(f->glyph2ascii); + f->glyph2ascii = NULL; } font_freename(f); font_freelayout(f); font_freeglyphnames(f); font_freeusage(f); - free(f); + rfx_free(f); } int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int dx, int dy) @@ -1021,14 +1155,22 @@ int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int d swf_SetRGB(t, color); } if (dx) { - if(dx>32767 || dx<-32768) - fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", dx); - swf_SetS16(t, dx); + if(dx != SET_TO_ZERO) { + if(dx>32767 || dx<-32768) + fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", dx); + swf_SetS16(t, dx); + } else { + swf_SetS16(t, 0); + } } if (dy) { - if(dy>32767 || dy<-32768) - fprintf(stderr, "Warning: Vertical char position overflow: %d\n", dy); - swf_SetS16(t, dy); + if(dy != SET_TO_ZERO) { + if(dy>32767 || dy<-32768) + fprintf(stderr, "Warning: Vertical char position overflow: %d\n", dy); + swf_SetS16(t, dy); + } else { + swf_SetS16(t, 0); + } } if (font) swf_SetU16(t, size); @@ -1106,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; } @@ -1158,24 +1305,32 @@ U32 swf_TextGetWidth(SWFFONT * font, U8 * s, int scale) SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale) { - int pos = 0; + int xpos = 0; + int ypos = 0; SRECT r; 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) { SRECT rn = font->layout->bounds[g]; - rn.xmin = (rn.xmin * scale) / 20 / 100 + pos; - rn.xmax = (rn.xmax * scale) / 20 / 100 + pos; - rn.ymin = (rn.ymin * scale) / 20 / 100; - rn.ymax = (rn.ymax * scale) / 20 / 100; + rn.xmin = (rn.xmin * scale) / 20 / 100 + xpos; + rn.xmax = (rn.xmax * scale) / 20 / 100 + xpos; + rn.ymin = (rn.ymin * scale) / 20 / 100 + ypos; + rn.ymax = (rn.ymax * scale) / 20 / 100 + ypos; swf_ExpandRect2(&r, &rn); - pos += (font->glyph[g].advance * scale) / 20 / 100; + xpos += (font->glyph[g].advance * scale) / 20 / 100; } } - c++; } return r; } @@ -1187,7 +1342,7 @@ SWFFONT *swf_ReadFont(char *filename) SWF swf; if (!filename) return 0; - f = open(filename, O_RDONLY); + f = open(filename, O_RDONLY|O_BINARY); if (f < 0 || swf_ReadSWF(f, &swf) < 0) { fprintf(stderr, "%s is not a valid SWF font file or contains errors.\n", filename); @@ -1214,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" @@ -1254,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*)""); } } @@ -1360,7 +1515,7 @@ void swf_WriteFont(SWFFONT * font, char *filename) t = swf_InsertTag(t, ST_END); - f = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); + f = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0644); if FAILED (swf_WriteSWF(f, &swf)) fprintf(stderr, "WriteSWF() failed in writeFont().\n"); close(f); @@ -1405,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 @@ -1427,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); @@ -1439,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; - /* 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); + 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; + } + + 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; @@ -1468,9 +1654,8 @@ void swf_FontCreateLayout(SWFFONT * f) if (!f->numchars) return; - f->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT)); - memset(f->layout, 0, sizeof(SWFLAYOUT)); - f->layout->bounds = (SRECT *) malloc(f->numchars * sizeof(SRECT)); + f->layout = (SWFLAYOUT *) rfx_calloc(sizeof(SWFLAYOUT)); + f->layout->bounds = (SRECT *) rfx_alloc(f->numchars * sizeof(SRECT)); f->layout->ascent = -32767; f->layout->descent = -32767;