double config_dumpfonts;
double config_ppmsubpixels;
double config_jpegsubpixels;
+ int config_simpleviewer;
int config_opennewwindow;
int config_ignoredraworder;
int config_drawonlyshapes;
static U16 getNewDepth(gfxdevice_t* dev)
{
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
- if(i->depth == 65535) {
+ if(i->depth == 65520) {
if(!id_error) {
msg("<error> Depth Table overflow");
msg("<error> This file is too complex to render- SWF only supports 65536 shapes at once");
i->pagefinished = 1;
}
+static void addViewer(gfxdevice_t* dev)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+
+ SHAPE*s;
+ RGBA button_colors[3]= {{0xbf,0x00,0x00,0x80},{0xbf,0x20,0x20,0xc0}, {0xbf,0xc0,0xc0,0xff}};
+ int ids[6];
+ int button_sizex = 20;
+ int button_sizey = 20;
+ int t;
+ RGBA black = {255,0,0,0};
+ for(t=0;t<6;t++) {
+ i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE3);
+ swf_ShapeNew(&s);
+ int ls1 = swf_ShapeAddLineStyle(s,40,&black);
+ int fs1 = swf_ShapeAddSolidFillStyle(s,&button_colors[t/2]);
+ int shapeid = ids[t] = getNewID(dev);
+ swf_SetU16(i->tag,shapeid);
+ SRECT r;
+ r.xmin = -20*button_sizex;
+ r.xmax = 20*button_sizex;
+ r.ymin = 0;
+ r.ymax = 40*button_sizey;
+ swf_SetRect(i->tag,&r); // set shape bounds
+ swf_SetShapeHeader(i->tag,s); // write all styles to tag
+ swf_ShapeSetAll(i->tag,s,0*button_sizex,0,ls1,fs1,0);
+ swf_ShapeSetLine(i->tag,s,(1-(t&1)*2)*20*button_sizex,20*button_sizey);
+ swf_ShapeSetLine(i->tag,s,-(1-(t&1)*2)*20*button_sizex,20*button_sizey);
+ swf_ShapeSetLine(i->tag,s,0,-40*button_sizey);
+ swf_ShapeSetEnd(i->tag); // finish drawing
+ swf_ShapeFree(s); // clean shape structure (which isn't needed anymore after writing the tag)
+ }
+ ActionTAG*a1=0,*a2=0,*a3=0;
+ a1 = action_NextFrame(a1);
+ a1 = action_Stop(a1);
+ a1 = action_End(a1);
+
+ a2 = action_PreviousFrame(a2);
+ a2 = action_Stop(a2);
+ a2 = action_End(a2);
+
+ a3 = action_Stop(a3);
+ a3 = action_End(a3);
+
+ i->tag = swf_InsertTag(i->tag, ST_DOACTION);
+ swf_ActionSet(i->tag,a3);
+
+ i->tag = swf_InsertTag(i->tag,ST_DEFINEBUTTON);
+ int buttonid1 = getNewID(dev);
+ swf_SetU16(i->tag, buttonid1);
+ swf_ButtonSetRecord(i->tag,BS_UP|BS_HIT,ids[0],1,NULL,NULL);
+ swf_ButtonSetRecord(i->tag,BS_OVER,ids[2],1,NULL,NULL);
+ swf_ButtonSetRecord(i->tag,BS_DOWN,ids[4],1,NULL,NULL);
+ swf_SetU8(i->tag,0); // end of button records
+ swf_ActionSet(i->tag,a1);
+
+ i->tag = swf_InsertTag(i->tag,ST_DEFINEBUTTON);
+ int buttonid2 = getNewID(dev);
+ swf_SetU16(i->tag, buttonid2);
+ swf_ButtonSetRecord(i->tag,BS_UP|BS_HIT,ids[1],1,NULL,NULL);
+ swf_ButtonSetRecord(i->tag,BS_OVER,ids[3],1,NULL,NULL);
+ swf_ButtonSetRecord(i->tag,BS_DOWN,ids[5],1,NULL,NULL);
+ swf_SetU8(i->tag,0); // end of button records
+ swf_ActionSet(i->tag,a2);
+
+ i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
+ MATRIX m;
+ swf_GetMatrix(0, &m);
+ m.tx = button_sizex*20+200;
+ swf_ObjectPlace(i->tag, buttonid2, 65534,&m,0,0);
+ i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
+ m.tx = button_sizex*20+200+200;
+ swf_ObjectPlace(i->tag, buttonid1, 65535,&m,0,0);
+}
+
+
void swf_startframe(gfxdevice_t*dev, int width, int height)
{
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+ if(i->firstpage) {
+ if(i->config_protect) {
+ i->tag = swf_InsertTag(i->tag, ST_PROTECT);
+ i->config_protect = 0;
+ }
+ if(i->config_simpleviewer) {
+ addViewer(dev);
+ }
+ }
+
if(!i->firstpage && !i->pagefinished)
endpage(dev);
+
msg("<verbose> Starting new SWF page of size %dx%d", width, height);
swf_GetMatrix(0, &i->page_matrix);
dev->name = "swf";
- dev->internal = init_internal_struct();
+ dev->internal = init_internal_struct(); // set config to default values
dev->startpage = swf_startframe;
dev->endpage = swf_endframe;
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
i->dev = dev;
- RGBA rgb;
-
msg("<verbose> initializing swf output\n", i->max_x,i->max_y);
i->swffont = 0;
i->swf = (SWF*)rfx_calloc(sizeof(SWF));
- i->swf->fileVersion = i->config_flashversion;
- i->swf->frameRate = i->config_framerate*0x100;
+ i->swf->fileVersion = 0;
+ i->swf->frameRate = 0x80;
i->swf->movieSize.xmin = 0;
i->swf->movieSize.ymin = 0;
i->swf->movieSize.xmax = 0;
i->swf->firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
i->tag = i->swf->firstTag;
+ RGBA rgb;
rgb.a = rgb.r = rgb.g = rgb.b = 0xff;
rgb.r = 0;
swf_SetRGB(i->tag,&rgb);
i->startdepth = i->depth = 0;
-
- if(i->config_protect)
- i->tag = swf_InsertTag(i->tag, ST_PROTECT);
}
static void startshape(gfxdevice_t*dev)
i->shapeid = -1;
i->bboxrectpos = -1;
-// i->currentswfid--; // this was an *exceptionally* bad idea
+// i->currentswfid--; // doesn't work, for some reason
}
void fixAreas(gfxdevice_t*dev)
if(i->tag && i->tag->id == ST_END)
return; //already done
+ i->swf->fileVersion = i->config_flashversion;
+ i->swf->frameRate = i->config_framerate*0x100;
+
if(i->config_bboxvars) {
TAG* tag = swf_InsertTag(i->swf->firstTag, ST_DOACTION);
ActionTAG*a = 0;
iterator = iterator->next;
}
+
i->tag = swf_InsertTag(i->tag,ST_END);
TAG* tag = i->tag->prev;
actions = action_GetUrl(actions, url, i->config_linktarget);
}
actions = action_End(actions);
-
- drawlink(dev, actions, 0, points,0);
+
+ drawlink(dev, actions, 0, points, 0);
}
void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points)
{
actions = action_End(actions);
}
- drawlink(dev, actions, 0, points,0);
+ drawlink(dev, actions, 0, points, 0);
}
/* Named Links (a.k.a. Acrobatmenu) are used to implement various gadgets
actions2 = action_End(actions2);
}
- drawlink(dev, actions1, actions2, points,mouseover);
+ drawlink(dev, actions1, actions2, points, mouseover);
swf_ActionFree(actions1);
swf_ActionFree(actions2);
swf_ButtonPostProcess(i->tag, 1);
}
}
+ char name[80];
+ sprintf(name, "link%d", buttonid);
msg("<trace> Placing link ID %d", buttonid);
i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
m = i->page_matrix;
m.tx = p.x;
m.ty = p.y;
- swf_ObjectPlace(i->tag, buttonid, getNewDepth(dev),&m,0,0);
+ swf_ObjectPlace(i->tag, buttonid, getNewDepth(dev),&m,0,name);
} else {
- swf_ObjectPlace(i->tag, buttonid, getNewDepth(dev),&i->page_matrix,0,0);
+ swf_ObjectPlace(i->tag, buttonid, getNewDepth(dev),&i->page_matrix,0,name);
}
}
i->config_dumpfonts = atoi(value);
} else if(!strcmp(name, "animate")) {
i->config_animate = atoi(value);
+ } else if(!strcmp(name, "simpleviewer")) {
+ i->config_simpleviewer = atoi(value);
} else if(!strcmp(name, "next_bitmap_is_jpeg")) {
i->jpeg = 1;
} else if(!strcmp(name, "jpegquality")) {
swffont->version = 2;
swffont->name = (U8*)strdup(id);
swffont->layout = (SWFLAYOUT*)rfx_calloc(sizeof(SWFLAYOUT));
- swffont->layout->ascent = 0; /* ? */
+ swffont->layout->ascent = 0;
swffont->layout->descent = 0;
swffont->layout->leading = 0;
swffont->layout->bounds = (SRECT*)rfx_calloc(sizeof(SRECT)*font->num_glyphs);
swf_ExpandRect2(&bounds, &swffont->layout->bounds[t]);
}
- if(bounds.ymin < 0 && bounds.ymax > 0) {
- swffont->layout->ascent = -bounds.ymin;
- swffont->layout->descent = bounds.ymax;
- swffont->layout->leading = bounds.ymax - bounds.ymin;
- } else {
- swffont->layout->ascent = (bounds.ymax - bounds.ymin)/2;
- swffont->layout->descent = (bounds.ymax - bounds.ymin)/2;
- swffont->layout->leading = bounds.ymax - bounds.ymin;
- }
- swffont->layout->descent= (bounds.ymax - bounds.ymin);
- swffont->layout->ascent = 0;
+
+
+ /* Flash player will use the advance value from the char, and the ascent/descent values
+ from the layout for text selection.
+ ascent will extend the char into negative y direction, from the baseline, while descent
+ will extend in positive y direction, also from the baseline.
+ The baseline is defined as the y-position zero
+ */
+
+ swffont->layout->ascent = -bounds.ymin;
+ if(swffont->layout->ascent < 0)
+ swffont->layout->ascent = 0;
+ swffont->layout->descent = bounds.ymax;
+ if(swffont->layout->descent < 0)
+ swffont->layout->descent = 0;
swffont->layout->leading = bounds.ymax - bounds.ymin;
return swffont;