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)
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) {
} 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 */
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;s<f->use->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;
}
}
+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);
}
}
-
//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
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;
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");
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) {
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)
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;
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;
}
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);
}
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;t<nr;t++) {
+ int x=xpos[t];
+ int y=ystart;
+ int c = chars[t];
+ if(c<0 || c>u->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;
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:
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
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);
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
MATRIX matrix;
CXFORM cxform;
U16 ratio;
- U8*name;
+ char*name;
U16 clipdepth;
ActionTAG* actions;
U8 blendmode;