From: Matthias Kramm Date: Sat, 28 Nov 2009 03:35:34 +0000 (-0800) Subject: generate align zones during postprocessing X-Git-Tag: version-0-9-1~232 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=5c25a1fc058ae69818976cbb0e6c6b2f6a1aada5 generate align zones during postprocessing --- diff --git a/lib/devices/swf.c b/lib/devices/swf.c index 8d557da..1db6b38 100644 --- a/lib/devices/swf.c +++ b/lib/devices/swf.c @@ -739,12 +739,6 @@ static void chararray_writetotag(chararray_t*_chardata, TAG*tag) lastx = chr->x; lasty = chr->y; lastsize = chr->size; - } else { - assert(lastchar>=0); - if(pass==1 && lastchar!=chr->charid) { - swf_FontUsePair(chr->font, lastchar, chr->charid); - swf_FontUsePair(chr->font, chr->charid, lastchar); - } } if(islast) @@ -1477,6 +1471,7 @@ void swfoutput_finalize(gfxdevice_t*dev) endpage(dev); fontlist_t *iterator = i->fontlist; char use_font3 = i->config_flashversion>=8 && !NO_FONT3; + while(iterator) { TAG*mtag = i->swf->firstTag; if(iterator->swffont) { @@ -1496,19 +1491,19 @@ void swfoutput_finalize(gfxdevice_t*dev) } else { mtag = swf_InsertTag(mtag, ST_DEFINEFONT3); swf_FontSetDefine2(mtag, iterator->swffont); - if(iterator->swffont->alignzones) { - mtag = swf_InsertTag(mtag, ST_DEFINEFONTALIGNZONES); - swf_FontSetAlignZones(mtag, iterator->swffont); - } } } } iterator = iterator->next; } - + i->tag = swf_InsertTag(i->tag,ST_END); TAG* tag = i->tag->prev; + + if(i->config_storeallcharacters) { + swf_FontPostprocess(i->swf); // generate alignment information + } /* remove the removeobject2 tags between the last ST_SHOWFRAME and the ST_END- they confuse the flash player */ diff --git a/lib/modules/swfalignzones.c b/lib/modules/swfalignzones.c index 21780d3..027585f 100644 --- a/lib/modules/swfalignzones.c +++ b/lib/modules/swfalignzones.c @@ -235,15 +235,15 @@ void swf_FontCreateAlignZones(SWFFONT * f) memset(column, 0, sizeof(float)*(height+1)); int s; int drawn = 0; - printf("[font %d] pairing %c with ", f->id, f->glyph2ascii[t]); for(s=0;suse->num_neighbors;s++) { - if(f->use->neighbors[s].char2 == t) { - printf("%c (%d) ", f->glyph2ascii[f->use->neighbors[s].char1], f->use->neighbors[s].num); - draw_char(f, f->use->neighbors[s].char1, row, column, bounds); + int char1 = f->use->neighbors[s].char1; + int char2 = f->use->neighbors[s].char2; + if(char1 == t || char2 == t) { + int other = t==char1?char2:char1; + draw_char(f, other, row, column, bounds); drawn++; } } - printf("\n"); for(s=0;s<=height;s++) { column[t] /= drawn*2; @@ -262,6 +262,26 @@ void swf_FontCreateAlignZones(SWFFONT * f) } } +void swf_FontPostprocess(SWF*swf) +{ + TAG*tag = swf->firstTag; + while(tag) { + TAG*next = tag->next; + if(tag->id == ST_DEFINEFONT3) { + U16 id = swf_GetDefineID(tag); + SWFFONT*font = 0; + swf_FontExtract(swf, id, &font); + if(!font->alignzones) { + swf_FontCreateAlignZones(font); + tag = swf_InsertTag(tag, ST_DEFINEFONTALIGNZONES); + swf_FontSetAlignZones(tag, font); + } + swf_FontFree(font); + } + tag = next; + } +} + void swf_FontSetAlignZones(TAG*t, SWFFONT *f) { swf_SetU16(t, f->id); @@ -288,4 +308,3 @@ void swf_FontSetAlignZones(TAG*t, SWFFONT *f) } } - diff --git a/lib/modules/swffont.c b/lib/modules/swffont.c index cd553b8..aee2fae 100644 --- a/lib/modules/swffont.c +++ b/lib/modules/swffont.c @@ -347,12 +347,16 @@ SWFFONT* swf_LoadTrueTypeFont(const char*filename) //font->layout->descent = abs(face->descender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMax; //font->layout->leading = font->layout->ascent + font->layout->descent; - font->layout->ascent = -fontbbox.ymin; - if(font->layout->ascent < 0) + if(-fontbbox.ymin < 0) font->layout->ascent = 0; - font->layout->descent = fontbbox.ymax; - if(font->layout->descent < 0) + else + font->layout->ascent = -fontbbox.ymin; + + if(-fontbbox.ymax < 0) font->layout->descent = 0; + else + font->layout->descent = -fontbbox.ymax; + font->layout->leading = fontbbox.ymax - fontbbox.ymin; /* notice: if skip_unused is true, font->glyph2ascii, font->glyphnames and font->layout->bounds will diff --git a/lib/modules/swfobject.c b/lib/modules/swfobject.c index 36b66d4..349824d 100644 --- a/lib/modules/swfobject.c +++ b/lib/modules/swfobject.c @@ -57,7 +57,7 @@ int isUnitCXForm(CXFORM* cx) return 0; } -static int objectplace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name, U16 clipaction, U8 blendmode, FILTERLIST*filters) +static int objectplace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char * name, U16 clipaction, U8 blendmode, FILTERLIST*filters) { U8 flags,flags2; if (!t) return -1; @@ -87,15 +87,15 @@ static int objectplace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 swf_SetU8(t,blendmode); return 0; } -int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name) +int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char * name) { return objectplace(t,id,depth,m,cx,name,0,0,0); } -int swf_ObjectPlaceClip(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name, U16 clipaction) +int swf_ObjectPlaceClip(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char * name, U16 clipaction) { return objectplace(t,id,depth,m,cx,name,clipaction,0,0); } -int swf_ObjectPlaceBlend(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name, U8 blend) +int swf_ObjectPlaceBlend(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char * name, U8 blend) { if(t->id != ST_PLACEOBJECT3) fprintf(stderr, "wrong tag- ignoring blend mode\n"); @@ -198,7 +198,7 @@ void swf_GetPlaceObject(TAG * tag,SWFPLACEOBJECT* obj) l = strlen((const char *)&tag->data[tag->pos]); t = 0; data = (U8*)rfx_alloc(l+1); - obj->name = data; + obj->name = (char*)data; while((data[t++] = swf_GetU8(tag))); } if(flags2&PF2_BLENDMODE) { diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index afa069c..bc972d4 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -616,6 +616,35 @@ static int parseFillStyleArray(TAG*tag, SHAPE2*shape) return 1; } +char swf_ShapeIsEmpty(SHAPE*s) +{ + if(!s || !s->data) return 1; + TAG _tag; + TAG* tag = &_tag; + memset(tag, 0, sizeof(TAG)); + tag->data = s->data; + tag->len = tag->memsize = (s->bitlen+7)/8; + tag->pos = 0; + + while(1) { + if(!swf_GetBits(tag, 1)) { + U16 flags = swf_GetBits(tag, 5); + if(!flags) break; + if(flags&1) { //move + int n = swf_GetBits(tag, 5); + swf_GetSBits(tag, n); //x + swf_GetSBits(tag, n); //y + } + if(flags&2) swf_GetBits(tag, s->bits.fill); + if(flags&4) swf_GetBits(tag, s->bits.fill); + if(flags&8) swf_GetBits(tag, s->bits.line); + if(flags&16) {return 0;} + } else { + return 0; + } + } + return 1; +} /* todo: merge this with swf_GetSimpleShape */ static SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebits, int version, SHAPE2*shape2) diff --git a/lib/modules/swftext.c b/lib/modules/swftext.c index c473211..888f74a 100644 --- a/lib/modules/swftext.c +++ b/lib/modules/swftext.c @@ -255,7 +255,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) U32 *offset; U8 flags1, langcode, namelen; swf_SetTagPos(tag, 0); - font->version = 2; + font->version = tag->id==ST_DEFINEFONT3?3:2; fid = swf_GetU16(tag); if (id && id != fid) return id; @@ -278,7 +278,6 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag) 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; @@ -516,7 +515,7 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs, } int swf_ParseDefineText(TAG * tag, - void (*callback) (void *self, int *chars, int *ypos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self) + void (*callback) (void *self, int *chars, int *xpos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self) { return swf_FontExtract_DefineTextCallback(-1, 0, tag, FEDTJ_CALLBACK, callback, self); } @@ -526,6 +525,52 @@ int swf_FontExtract_DefineText(int id, SWFFONT * f, TAG * t, int jobs) return swf_FontExtract_DefineTextCallback(id, f, t, jobs, 0, 0); } +typedef struct _usagetmp { + SWFFONT*font; + int lastx,lasty; + int last; +} usagetmp_t; +static void updateusage(void *self, int *chars, int *xpos, int nr, + int fontid, int fontsize, int xstart, int ystart, RGBA * color) +{ + usagetmp_t*u = (usagetmp_t*)self; + if(!u->font->use) { + swf_FontInitUsage(u->font); + } + if(fontid!=u->font->id) + return; + + int t; + for(t=0;tu->font->numchars) + continue; + swf_FontUseGlyph(u->font, c, fontsize); + if(u->lasty == y && x>=u->lastx-200 && abs(u->lastx-x)<200 && + u->last!=c && !swf_ShapeIsEmpty(u->font->glyph[u->last].shape) && + !swf_ShapeIsEmpty(u->font->glyph[c].shape)) + { + swf_FontUsePair(u->font, u->last, c); + } + u->lasty = y; + /* FIXME: do we still need to divide advance by 20 for definefont3? */ + u->lastx = x + (u->font->glyph[c].advance*fontsize/20480); + u->last = c; + } +} + +void swf_FontUpdateUsage(SWFFONT*f, TAG* tag) +{ + usagetmp_t u; + u.font = f; + u.lastx = -0x80000000; + u.lasty = -0x80000000; + u.last = 0; + swf_ParseDefineText(tag, updateusage, &u); +} + int swf_FontExtract(SWF * swf, int id, SWFFONT * *font) { TAG *t; @@ -561,7 +606,11 @@ int swf_FontExtract(SWF * swf, int id, SWFFONT * *font) case ST_DEFINETEXT: case ST_DEFINETEXT2: - nid = swf_FontExtract_DefineText(id, f, t, f->layout ? 0 : FEDTJ_MODIFY); + if(!f->layout) { + nid = swf_FontExtract_DefineText(id, f, t, FEDTJ_MODIFY); + } + if(f->version>=3 && f->layout) + swf_FontUpdateUsage(f, t); break; case ST_GLYPHNAMES: diff --git a/lib/rfxswf.h b/lib/rfxswf.h index 7f8eb1c..5bfeb5d 100644 --- a/lib/rfxswf.h +++ b/lib/rfxswf.h @@ -449,6 +449,7 @@ typedef struct _SHAPELINE int swf_ShapeNew(SHAPE ** s); void swf_ShapeFree(SHAPE * s); +char swf_ShapeIsEmpty(SHAPE*s); int swf_GetSimpleShape(TAG * t,SHAPE ** s); // without Linestyle/Fillstyle Record int swf_SetSimpleShape(TAG * t,SHAPE * s); // without Linestyle/Fillstyle Record @@ -658,6 +659,7 @@ void swf_FontSetAlignZones(TAG*t, SWFFONT *f); void swf_FontCreateLayout(SWFFONT*f); void swf_FontCreateAlignZones(SWFFONT * f); void swf_FontAddLayout(SWFFONT * f, int ascent, int descent, int leading); +void swf_FontPostprocess(SWF*swf); int swf_ParseDefineText(TAG * t, void(*callback)(void*self, int*chars, int*xpos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA* color), void*self); @@ -935,9 +937,9 @@ void action_fixjump(ActionMarker m1, ActionMarker m2); extern char*blendModeNames[]; -int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name); -int swf_ObjectPlaceClip(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name, U16 clipaction); -int swf_ObjectPlaceBlend(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const U8 * name, U8 blendmode); +int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char* name); +int swf_ObjectPlaceClip(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char* name, U16 clipaction); +int swf_ObjectPlaceBlend(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,const char* name, U8 blendmode); int swf_ObjectMove(TAG * t,U16 depth,MATRIX * m,CXFORM * cx); #define PF_MOVE 0x01 @@ -977,7 +979,7 @@ typedef struct _SWFPLACEOBJECT { MATRIX matrix; CXFORM cxform; U16 ratio; - U8*name; + char*name; U16 clipdepth; ActionTAG* actions; U8 blendmode;