X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftext.c;h=4b57c83689bbd9c6164c446c4df6574144d7fd2a;hb=f87cabd9d7dc5e891104f98b8b60f65b8bc86559;hp=69edf6cd5ef89c5c76625d87539a8cf41889eb0e;hpb=210530b62a1389c48a289cdcd607f9207d80f76e;p=swftools.git diff --git a/lib/modules/swftext.c b/lib/modules/swftext.c index 69edf6c..4b57c83 100644 --- a/lib/modules/swftext.c +++ b/lib/modules/swftext.c @@ -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); } @@ -263,6 +263,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); @@ -296,23 +298,34 @@ 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_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++) { @@ -381,7 +394,7 @@ 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; @@ -418,6 +431,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); @@ -560,8 +575,10 @@ static void font_freeglyphnames(SWFFONT*f) if (f->glyphnames) { int t; for (t = 0; t < f->numchars; t++) { - if (f->glyphnames[t]) + if (f->glyphnames[t]) { rfx_free(f->glyphnames[t]); + f->glyphnames[t] = 0; + } } rfx_free(f->glyphnames); f->glyphnames = 0; @@ -592,7 +609,7 @@ static void font_freename(SWFFONT*f) } } -int swf_FontReduce(SWFFONT * f) +int swf_FontReduce_old(SWFFONT * f) { int i, j; int max_unicode = 0; @@ -635,6 +652,42 @@ int swf_FontReduce(SWFFONT * 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); + + for (i = 0; i < f->numchars; i++) { + if(!f->use->chars[i]) { + 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; + } + } else { + max_glyph = i+1; + } + } + for (i = 0; i < f->maxascii; i++) { + if(!f->use->chars[f->ascii2glyph[i]]) { + 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; @@ -741,7 +794,7 @@ int swf_FontUseGlyph(SWFFONT * f, int glyph) { if (!f->use) swf_FontInitUsage(f); - if(glyph < 0 || glyph > f->numchars) + if(glyph < 0 || glyph >= f->numchars) return -1; f->use->chars[glyph] = 1; return 0; @@ -1015,14 +1068,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); @@ -1100,6 +1161,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,6 +1224,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) { @@ -1170,7 +1244,6 @@ SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale) xpos += (font->glyph[g].advance * scale) / 20 / 100; } } - c++; } return r; } @@ -1409,10 +1482,14 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s { 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); + 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 @@ -1422,6 +1499,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); @@ -1438,17 +1516,45 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s 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; + } + + if(next[0] == 13 && next[1] == 10) + next++; + + if(next[0] == 13 || next[0] == 10) { + *next = 0; + next++; + } - /* 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); + /* 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; + + printf("%s\n", upos); + } + free(utext); swf_SetU8(tag, 0); return r;