コード例 #1
0
void swf_FontSetAlignZones(TAG*t, SWFFONT *f)
{
    swf_SetU16(t, f->id);
    swf_SetU8(t, f->alignzone_flags);
    int i;
    for(i=0;i<f->numchars;i++) {
	ALIGNZONE*a = &f->alignzones[i];
	U8 flags = 0;
	if((a->x & a->dx)!=0xffff)
	    flags |= 1;
	if((a->y & a->dy)!=0xffff)
	    flags |= 2;
	int num = 1;
	if(a->dx != 0xffff || a->dy != 0xffff)
	    num++;
	swf_SetU8(t, num);
	if(flags&1) swf_SetU16(t, a->x); else swf_SetU16(t, 0);
	if(flags&2) swf_SetU16(t, a->y); else swf_SetU16(t, 0);
	if(num==2) {
	    if((flags&1) && a->dx!=0xffff) swf_SetU16(t, a->dx); else swf_SetU16(t, 0);
	    if((flags&2) && a->dy!=0xffff) swf_SetU16(t, a->dy); else swf_SetU16(t, 0);
	}
	swf_SetU8(t, flags);
    }
}
コード例 #2
0
ファイル: swfcombine.c プロジェクト: MaChao5/pdfviewer-win32
TAG* write_sprite(TAG*tag, SWF*sprite, int spriteid, int replaceddefine)
{
    TAG* definespritetag;
    TAG* rtag;
    int tmp;

    definespritetag = tag = swf_InsertTag(tag, ST_DEFINESPRITE);
    swf_SetU16(tag, spriteid);
    swf_SetU16(tag, sprite->frameCount);
    msg ("<notice> sprite id is %d", spriteid);

    tmp = sprite->frameCount;
    msg("<debug> %d frames to go",tmp);

    if(config.clip) {
	tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
	swf_SetU8(tag, 2+64); //flags: character+clipdepth
	swf_SetU16(tag, 0); //depth
	swf_SetU16(tag, replaceddefine); //id
	swf_SetU16(tag, 65535); //clipdepth
    }

    if(config.overlay && !config.isframe) {
	tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
	swf_SetU8(tag, 2); //flags: character
	swf_SetU16(tag, 1); //depth
	swf_SetU16(tag, replaceddefine); //id
    }

    rtag = sprite->firstTag;
    while(rtag && rtag->id!=ST_END)
    {
	if (swf_isAllowedSpriteTag(rtag)) {

	    msg("<debug> [sprite main] write tag %02x (%d bytes in body)", 
		    rtag->id, rtag->len);
	    tag = swf_InsertTag(tag, rtag->id);
	    write_changepos(tag, rtag, config.movex, config.movey, config.scalex, config.scaley, 0);

	    if(config.clip || (config.overlay && !config.isframe))
		changedepth(tag, +2);

	    if(tag->id == ST_SHOWFRAME)
	    {
		tmp--;
		msg("<debug> %d frames to go",tmp);
	    }
	}
	rtag = rtag->next;
    }
    tag = swf_InsertTag(tag, ST_END);
    return tag;
}
コード例 #3
0
ファイル: swfdraw.c プロジェクト: Beloded/swfparselib
static void swf_ShapeDrawerInit(drawer_t*draw, TAG*tag, int fillstylebits, int linestylebits)
{
    SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)rfx_calloc(sizeof(SWFSHAPEDRAWER));
    draw->internal = sdraw;

    draw->setLineStyle = swf_ShapeDrawerSetLineStyle;
    draw->setFillStyle = swf_ShapeDrawerSetFillStyle;
    draw->moveTo = swf_ShapeDrawerMoveTo;
    draw->lineTo = swf_ShapeDrawerLineTo;
    draw->splineTo = swf_ShapeDrawerSplineTo;
    draw->finish = swf_ShapeDrawerFinish;
    draw->dealloc = swf_ShapeDrawerClear;
    
    sdraw->tagfree = 0;
    if(tag == 0) {
	tag = swf_InsertTag(0, ST_DEFINESHAPE);
	sdraw->tagfree = 1;
    }
    sdraw->tag = tag;
    swf_ShapeNew(&sdraw->shape);
    draw->pos.x = 0;
    draw->pos.y = 0;

    swf_SetU8(sdraw->tag,0);
    sdraw->shape->bits.fill = fillstylebits;
    sdraw->shape->bits.line = linestylebits;
    
    sdraw->bbox.xmin = sdraw->bbox.ymin = SCOORD_MAX;
    sdraw->bbox.xmax = sdraw->bbox.ymax = SCOORD_MIN;

    sdraw->isfinished = 0;

    swf_ShapeSetStyle(sdraw->tag,sdraw->shape,linestylebits?1:0,fillstylebits?1:0,0/*?*/);
}
コード例 #4
0
ファイル: swfcombine.c プロジェクト: MaChao5/pdfviewer-win32
void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, float scaley, int scalepos)
{
    if(movex || movey || scalex != 1.0 || scaley != 1.0)
    {
	switch(tag->id)
	{
	    case ST_PLACEOBJECT2: {
		MATRIX m;
		U8 flags;
		swf_GetMatrix(0, &m);
		tag->pos = 0;
		tag->readBit = 0;

		flags = swf_GetU8(tag);
		swf_SetU8(output, flags|4);
		swf_SetU16(output, swf_GetU16(tag)); //depth
		//flags&1: move
		if(flags&2) {
		    swf_SetU16(output, swf_GetU16(tag)); //id
		}
		// flags & 4
		if(flags&4) {
		    swf_GetMatrix(tag, &m);
		} else {
		    swf_GetMatrix(0, &m);
		}
		matrix_adjust(&m, movex, movey, scalex, scaley, scalepos);
		swf_SetMatrix(output, &m);

		if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);

		swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos);
		break;
	    }
	    case ST_PLACEOBJECT: {
		MATRIX m;
		swf_SetU16(output, swf_GetU16(tag)); //id
		swf_SetU16(output, swf_GetU16(tag)); //depth
		
		swf_GetMatrix(tag, &m);
		matrix_adjust(&m, movex, movey, scalex, scaley, scalepos);
		swf_SetMatrix(output, &m);
		
		if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);

		swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos);
		break;
	    }
	    default:
	    swf_SetBlock(output, tag->data, tag->len);
	}
    } 
    else 
    {
	    swf_SetBlock(output, tag->data, tag->len);
    }
}
コード例 #5
0
ファイル: swffilter.c プロジェクト: DJwa163/swftools
void swf_SetFilter(TAG*tag, FILTER*filter)
{
    swf_SetU8(tag, filter->type);
    if(filter->type == FILTERTYPE_BLUR) {
	FILTER_BLUR*f = (FILTER_BLUR*)filter;
	swf_SetFixed(tag, f->blurx);
	swf_SetFixed(tag, f->blury);
	U8 flags = f->passes << 3;
	swf_SetU8(tag, flags);
    } else if(filter->type == FILTERTYPE_GLOW) {
	FILTER_GLOW*f = (FILTER_GLOW*)filter;
    } else if(filter->type == FILTERTYPE_DROPSHADOW) {
	FILTER_DROPSHADOW*f = (FILTER_DROPSHADOW*)filter;
	swf_SetRGBA(tag, &f->color);
	swf_SetFixed(tag, f->blurx);
	swf_SetFixed(tag, f->blury);
	swf_SetFixed(tag, f->angle);
	swf_SetFixed(tag, f->distance);
	swf_SetFixed8(tag, f->strength);
	U8 flags = f->innershadow<<7|f->knockout<<6|f->composite<<5|f->passes;
	swf_SetU8(tag, flags);
    } else if(filter->type == FILTERTYPE_GRADIENTGLOW) {
	FILTER_GRADIENTGLOW*f = (FILTER_GRADIENTGLOW*)filter;
	swf_SetU8(tag, f->gradient->num);
	int s;
	for(s=0;s<f->gradient->num;s++)
	    swf_SetRGBA(tag, &f->gradient->rgba[s]);
	for(s=0;s<f->gradient->num;s++)
	    swf_SetU8(tag, f->gradient->ratios[s]);

	swf_SetFixed(tag, f->blurx);
	swf_SetFixed(tag, f->blury);
	swf_SetFixed(tag, f->angle);
	swf_SetFixed(tag, f->distance);
	swf_SetFixed8(tag, f->strength);
	U8 flags = f->passes|f->innershadow<<7|f->knockout<<6|f->composite<<5|f->ontop<<4;
	swf_SetU8(tag, flags);
    } else if(filter->type == FILTERTYPE_BEVEL) {
	FILTER_BEVEL*f = (FILTER_BEVEL*)filter;
	swf_SetRGBA(tag, &f->shadow);
	swf_SetRGBA(tag, &f->highlight);
	swf_SetFixed(tag, f->blurx);
	swf_SetFixed(tag, f->blury);
	swf_SetFixed(tag, f->angle);
	swf_SetFixed(tag, f->distance);
	swf_SetFixed8(tag, f->strength);
	U8 flags = f->passes|f->innershadow<<7|f->knockout<<6|f->composite<<5|f->ontop<<4;
	swf_SetU8(tag, flags);
    } else {
	fprintf(stderr, "Writing of filter type %02x not supported yet\n", filter->type);
    }
}
コード例 #6
0
ファイル: swfaction.c プロジェクト: Beloded/swfparselib
void swf_ActionSet(TAG*tag, ActionTAG*action)
{
    if(!action) {
	return;
    }
    action=action->parent;
    while(action)
    {
	swf_SetU8(tag, action->op);
	if(action->op & 128)
	  swf_SetU16(tag, action->len);

	swf_SetBlock(tag, action->data, action->len);

	action = action->next;
    }
}
コード例 #7
0
ファイル: swfaction.c プロジェクト: Beloded/swfparselib
ActionTAG* swf_ActionCompile(const char* source, int version)
{
    TAG* tag;
    ActionTAG* a = 0;
    void*buffer = 0;
    int len = 0;
    int ret;
    
    tag = swf_InsertTag(NULL, ST_DOACTION);
    ret = compileSWFActionCode(source, version, &buffer, &len);
    if(!ret || buffer==0 || len == 0)
	return 0;

    swf_SetBlock(tag, (U8*)buffer, len);
    swf_SetU8(tag, 0);

    rfx_free(buffer);

    a = swf_ActionGet(tag);
    swf_DeleteTag(0, tag);
    return a;
}
コード例 #8
0
ファイル: code.c プロジェクト: GaetanBeurrier/Refresh
static int opcode_write(TAG*tag, code_t*c, pool_t*pool, abc_file_t*file, int length)
{
    opcode_t*op = opcode_get(c->opcode);
    char*p = op->params;
    int pos = 0;
    int len = 0;

    if(tag)
        swf_SetU8(tag, c->opcode);
    len++;

    if(op->flags & OP_INTERNAL) {
        if(c->opcode == OPCODE___BREAK__ ||
           c->opcode == OPCODE___CONTINUE__) {
            fprintf(stderr, "Unresolved %s\n", op->name);
        } else {
            fprintf(stderr, "Error: writing undefined internal opcode %s\n", op->name);
        }
    }

    while(*p) {
        void*data = c->data[pos++];
        assert(pos<=2);
        switch(*p) {
            case 'n': { // number
                len += swf_SetU30(tag, (ptroff_t)data);
                break;
            }
            case '2': { //multiname
                multiname_t*m = (multiname_t*)data;
                len += swf_SetU30(tag, pool_register_multiname(pool, m));
                break;
            }
            case 'N': { //namespace
                namespace_t*ns = (namespace_t*)data;
                len += swf_SetU30(tag, pool_register_namespace(pool, ns));
                break;
            }
            case 'm': { //method
                abc_method_t*m = (abc_method_t*)data;
                len += swf_SetU30(tag, m->index);
                break;
            }
            case 'c': { //classinfo 
                abc_class_t*cls = (abc_class_t*)data;
                len += swf_SetU30(tag, cls->index);
                break;
            }
            case 'i': { //methodbody
                abc_method_body_t*m = (abc_method_body_t*)data;
                len += swf_SetU30(tag, m->index);
                break;
            }
            case 'I': { // int
                len += swf_SetU30(tag, pool_register_int(pool, (ptroff_t)data));
                break;
            }
            case 'U': { // uint
                len += swf_SetU30(tag, pool_register_uint(pool, (ptroff_t)data));
                break;
            }
            case 'f': { //  float
                len += swf_SetU30(tag, pool_register_float(pool, *(double*)data));
                break;
            }
            case 'u': { // integer
                len += swf_SetU30(tag, (ptroff_t)data);
                break;
            }
            case 'r': { // integer
                len += swf_SetU30(tag, (ptroff_t)data);
                break;
            }
            case 'b': { // byte
                if(tag)
                    swf_SetU8(tag, (ptroff_t)data);
                len++;
                break;
            }
            case 'j': { // jump
                int skip = length-c->pos-4;
                if(c->branch) 
                    skip = (c->branch->pos) - c->pos - 4;
                len += swf_SetS24(tag, skip);
                break;
            }
            case 's': { // string
                int index = pool_register_string2(pool, (string_t*)data);
                len += swf_SetU30(tag, index);
                break;
            }
            case 'D': { // debug statement
                if(tag)
                    swf_SetU8(tag, 1);
                len++;
                len+=swf_SetU30(tag, pool_register_string(pool,c->data[0]));
                if(tag)
                    swf_SetU8(tag, (ptroff_t)c->data[1]);
                len++;
                len+=swf_SetU30(tag, 0);
                break;
            }
            case 'S': { // switch statement
                lookupswitch_t*l = (lookupswitch_t*)data;
                int offset = 0;
                len+=swf_SetS24(tag, l->def->pos-c->pos+offset); //default
                code_list_t*t = l->targets;
                if(list_length(t)) {
                    len+=swf_SetU30(tag, list_length(t)-1); //nr-1
                    code_list_t*t = l->targets;
                    while(t) {
                        len+=swf_SetS24(tag, t->code->pos - c->pos+offset);
                        t = t->next;
                    }
                } else {
                    len+=swf_SetU30(tag, 0); //nr-1
                    len+=swf_SetS24(tag, l->def->pos-c->pos+offset);
                }
                break;
            }
            default:
                printf("Can't parse opcode param type \"%c\"\n", *p);
        }
        p++;
    }
    return len;
}
コード例 #9
0
ファイル: swfcombine.c プロジェクト: MaChao5/pdfviewer-win32
TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefine, int flags)
{
    int outputslave = 0;
    int frame = 1;
    int sframe = 0;
    int slavewritten = 0;
    int deletedepth = -1;

    TAG* rtag = master->firstTag;
    TAG* stag = slave->firstTag;

    while(rtag && rtag->id!=ST_END)
    {
	if(rtag->id == ST_SHOWFRAME && outputslave)
	{
	    while(stag && stag->id!=ST_END) {
		if(stag->id == ST_SHOWFRAME) {
		    stag = stag->next;
		    sframe++;
		    break;
		}
		if(tag_ok_for_slave(stag->id)) {
		    tag = swf_InsertTag(tag, stag->id);
		    write_changepos(tag, stag, config.movex, config.movey, config.scalex, config.scaley, 0);
		}
		stag = stag->next;
	    }
	}
	if(rtag->id == ST_SHOWFRAME)
	{
	    frame ++;
	    tag = swf_InsertTag(tag, ST_SHOWFRAME);
            if(deletedepth>=0) {
                tag = swf_InsertTag(tag, ST_REMOVEOBJECT2);
                swf_SetU16(tag, deletedepth);
                deletedepth=-1;
            }
	    rtag = rtag->next;
            continue;
	}

	if(swf_isDefiningTag(rtag) && (flags&FLAGS_WRITEDEFINES))
	{
	    msg("<debug> [master] write tag %02x (%d bytes in body)", 
		    rtag->id, rtag->len);
	    if(swf_GetDefineID(rtag) == spriteid && !config.isframe)
	    {
		if(config.overlay)
		{
		    tag = swf_InsertTag(tag, rtag->id);
		    swf_SetBlock(tag, rtag->data, rtag->len);
		    swf_SetDefineID(tag, replaceddefine);
		} else {
		    /* don't write this tag */
		    msg("<verbose> replacing tag %d ID %d with sprite", rtag->id ,spriteid);
		}

		if(flags&FLAGS_WRITESPRITE)
		{
		    msg("<debug> writing sprite defines");
		    tag = write_sprite_defines(tag, slave);
		    msg("<debug> writing sprite");
		    tag = write_sprite(tag, slave, spriteid, replaceddefine);
		}
		if(flags&FLAGS_WRITESLAVE)
		{
		    msg("<debug> writing slave");
		    outputslave = 1;
		}
	    } else { 
		tag = swf_InsertTag(tag, rtag->id);
		swf_SetBlock(tag, rtag->data, rtag->len);
	    }
	}
	if(frame == slaveframe) /* only happens with config.isframe: put slave at specific frame */
	{
	    if(flags&FLAGS_WRITESLAVE) {
		outputslave = 1;
		slavewritten = 1;
	    }
	    if((flags&FLAGS_WRITESPRITE) && !slavewritten)
	    {
		int id = get_free_id(masterbitmap);
		int depth = 65535;
		deletedepth = 65535;
		if(config.clip) {
		    msg("<fatal> Can't combine --clip and --frame");
		}
		
		tag = write_sprite_defines(tag, slave);
		tag = write_sprite(tag, slave, id, -1);

		tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
		    swf_SetU8(tag, 2); //flags: id
		    swf_SetU16(tag, depth);
		    swf_SetU16(tag, id);

		slavewritten = 1;
	    }
	}
	if(!swf_isDefiningTag(rtag) && (flags&FLAGS_WRITENONDEFINES))
	{
	    int dontwrite = 0;
	    switch(rtag->id) {
		case ST_PLACEOBJECT:
		case ST_PLACEOBJECT2:
		    if(frame == slaveframe && !config.overlay)
			dontwrite = 1;
		case ST_REMOVEOBJECT:
		    /* place/removetags for the object we replaced
		       should be discarded, too, as the object to insert 
		       isn't a sprite 
		     */
		    if(spriteid>=0 && swf_GetPlaceID(rtag) == spriteid && 
			    !config.isframe && config.merge)
			dontwrite = 1;
		break;
		case ST_REMOVEOBJECT2:
		break;
	    }
	    if(!dontwrite) {
		msg("<debug> [master] write tag %02x (%d bytes in body)", 
			rtag->id, rtag->len);
		tag = swf_InsertTag(tag, rtag->id);
		write_changepos(tag, rtag, config.mastermovex, config.mastermovey, config.masterscalex, config.masterscaley, 1);
		
	    }
	}
	rtag = rtag->next;
    }
   
    if(outputslave) 
    while(stag && stag->id!=ST_END)
    {
	    if(tag_ok_for_slave(stag->id)) {
		msg("<debug> [slave] write tag %02x (%d bytes in body), %.2f %.2f", rtag->id, rtag->len, config.movex /20.0, config.movey /20.0);
		tag = swf_InsertTag(tag, stag->id);
		write_changepos(tag, stag, config.movex, config.movey, config.scalex, config.scaley, 0);
	    }
	    stag = stag->next;
    }
    if(!slavewritten && config.isframe && (flags&(FLAGS_WRITESLAVE|FLAGS_WRITESPRITE)))
    {
	if(slaveframe>=0)
	    msg("<warning> Frame %d doesn't exist in file. No substitution will occur",
		    slaveframe);
	else
	    msg("<warning> Frame \"%s\" doesn't exist in file. No substitution will occur",
		    slavename);
    }
    tag = swf_InsertTag(tag, ST_END);
    return tag;
}
コード例 #10
0
ファイル: alignzones.c プロジェクト: DJwa163/swftools
static void write_font(SWFFONT * font, char *filename)
{
    SWF swf;
    TAG *t;
    SRECT r;
    RGBA rgb;
    int f;
    int useDefineFont2 = 1;
    int storeGlyphNames = 1;
   
#define WRITEFONTID 8888
    font->id = WRITEFONTID;

    memset(&swf, 0x00, sizeof(SWF));

    swf.fileVersion = 9;
    swf.frameRate = 0x4000;

    t = swf_InsertTag(NULL, ST_SETBACKGROUNDCOLOR);
    swf.firstTag = t;
    rgb.r = 0xef;
    rgb.g = 0xef;
    rgb.b = 0xff;
    swf_SetRGB(t, &rgb);
    
    t = swf_InsertTag(t, ST_DEFINEFONT3);
    swf_FontSetDefine2(t, font);

    t = swf_InsertTag(t, ST_DEFINEFONTALIGNZONES);
    swf_SetU16(t, font->id);
    swf_SetU8(t, 0); //thin
    int i;
    for(i=0;i<256;i++) {
	swf_SetU8(t, 2);
	swf_SetF16(t, 82.0 / 1024.0);
	swf_SetF16(t, 82.0 / 1024.0);
	swf_SetF16(t, ((i%16/2)*82.0) / 1024.0);
	swf_SetF16(t, ((i/16/2)*82.0) / 1024.0);
	/*
	if(i<128 && (i&15)<8) {
	    swf_SetF16(t, 0.0);
	    swf_SetF16(t, 0.0);
	    swf_SetF16(t, 640.0 / 1024.0);
	    swf_SetF16(t, 640.0 / 1024.0);
	} else if(i<128 && (i&15)>=8) {
	    swf_SetF16(t, 0.0 / 1024.0);
	    swf_SetF16(t, 0.0   / 1024.0);
	    swf_SetF16(t, 330.0 / 1024.0);
	    swf_SetF16(t, 640.0 / 1024.0);
	} else if(i>=128 && (i&15)<8) {
	    swf_SetF16(t, 0.0   / 1024.0);
	    swf_SetF16(t, 0.0 / 1024.0);
	    swf_SetF16(t, 640.0 / 1024.0);
	    swf_SetF16(t, 330.0 / 1024.0);
	} else {
	    swf_SetF16(t, 0.0 / 1024.0);
	    swf_SetF16(t, 0.0 / 1024.0);
	    swf_SetF16(t, 330.0 / 1024.0);
	    swf_SetF16(t, 330.0 / 1024.0);
	}*/
	swf_SetU8(t, 3); // x and y
    }

    int s;
    int xmax = 0;
    int ymax = 0;
    int ypos = 1;
    U8 gbits, abits;
    int x, y, c;
    int range = font->maxascii;

    c = 0;
    range = 256;

    xmax = 1280;
    ymax = 1280*20;

    swf.movieSize.xmax = xmax * 20;
    swf.movieSize.ymax = ymax;

    t = swf_InsertTag(t, ST_DEFINETEXT);
    swf_SetU16(t, font->id + 1);	// ID
    r.xmin = 0;
    r.ymin = 0;
    r.xmax = swf.movieSize.xmax;
    r.ymax = swf.movieSize.ymax;
    swf_SetRect(t, &r);
    swf_SetMatrix(t, NULL);
    abits = swf_CountBits(xmax * 16, 0);
    gbits = 8;
    swf_SetU8(t, gbits);
    swf_SetU8(t, abits);

    rgb.r = 0x00;
    rgb.g = 0x00;
    rgb.b = 0x00;
    ypos = 2;
    
    int textscale = 1024;
    for (y = 0; y < ((range + 15) / 16); y++) {
	for (x = 0; x < 16; x++) {
	    //swf_TextSetInfoRecord(t, font, textscale, &rgb, x*64*20+64*20+10+(x+y)*20, y*64*20+128*20+10+(x^y)*20);
	    swf_TextSetInfoRecord(t, font, textscale, &rgb, x*64*20+64*20+10, y*64*20+128*20+10);
	    int g = y * 16 + x;
	    swf_SetU8(t, 1);
	    swf_SetBits(t, g, gbits);
	    swf_SetBits(t, 0, abits);
	    swf_ResetWriteBits(t);
	}
    }
    swf_SetU8(t, 0);
		 
    t = swf_InsertTag(t, ST_CSMTEXTSETTINGS);
    swf_SetU16(t, font->id + 1);
    swf_SetU8(t, (1<<3)//grid
	         |0x40//flashtype
		 );
    swf_SetU32(t, 0x20000);//thickness
    swf_SetU32(t, 0x800000);//sharpness
    swf_SetU8(t, 0);//reserved

    t = swf_InsertTag(t, ST_PLACEOBJECT2);
    swf_ObjectPlace(t, font->id + 1, 1, NULL, NULL, NULL);

    t = swf_InsertTag(t, ST_SHOWFRAME);
    t = swf_InsertTag(t, ST_END);

    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);

    swf_FreeTags(&swf);
}