int drawonlyshapes=0;
int jpegquality=85;
int storeallcharacters=0;
+int enablezlib=0;
+int insertstoptag=0;
+int flashversion=4;
static int flag_protected = 0;
typedef unsigned char u8;
int CHARMIDX = 0;
int CHARMIDY = 0;
-void startshape(struct swfoutput* obj);
-void starttext(struct swfoutput* obj);
-void endshape();
-void endtext();
+char fillstylechanged = 0;
+
+static void startshape(struct swfoutput* obj);
+static void starttext(struct swfoutput* obj);
+static void endshape();
+static void endtext();
// matrix multiplication. changes p0
-void transform (plotxy*p0,struct swfmatrix*m)
+static void transform (plotxy*p0,struct swfmatrix*m)
{
double x,y;
x = m->m11*p0->x+m->m12*p0->y;
}
// write a move-to command into the swf
-void moveto(TAG*tag, plotxy p0)
+static int moveto(TAG*tag, plotxy p0)
{
int rx = (int)(p0.x*20);
int ry = (int)(p0.y*20);
- if(rx!=swflastx || ry!=swflasty) {
+ if(rx!=swflastx || ry!=swflasty || fillstylechanged) {
swf_ShapeSetMove (tag, shape, rx,ry);
+ fillstylechanged = 0;
+ swflastx=rx;
+ swflasty=ry;
+ return 1;
}
- swflastx=rx;
- swflasty=ry;
+ return 0;
}
// write a line-to command into the swf
-void lineto(TAG*tag, plotxy p0)
+static void lineto(TAG*tag, plotxy p0)
{
int rx = ((int)(p0.x*20)-swflastx);
int ry = ((int)(p0.y*20)-swflasty);
}
// write a spline-to command into the swf
-void splineto(TAG*tag, plotxy control,plotxy end)
+static void splineto(TAG*tag, plotxy control,plotxy end)
{
int cx = ((int)(control.x*20)-swflastx);
int cy = ((int)(control.y*20)-swflasty);
int ey = ((int)(end.y*20)-swflasty);
swflastx += ex;
swflasty += ey;
- swf_ShapeSetCurve(tag, shape, cx,cy,ex,ey);
+ if(cx || cy || ex || ey)
+ swf_ShapeSetCurve(tag, shape, cx,cy,ex,ey);
}
/* write a line, given two points and the transformation
matrix. */
-void line(TAG*tag, plotxy p0, plotxy p1, struct swfmatrix*m)
+static void line(TAG*tag, plotxy p0, plotxy p1, struct swfmatrix*m)
{
transform(&p0,m);
transform(&p1,m);
/* write a cubic (!) spline. This involves calling the approximate()
function out of spline.cc to convert it to a quadratic spline. */
-void spline(TAG*tag,plotxy p0,plotxy p1,plotxy p2,plotxy p3,struct swfmatrix*m)
+static void spline(TAG*tag,plotxy p0,plotxy p1,plotxy p2,plotxy p3,struct swfmatrix*m)
{
double d;
- struct qspline q[16];
+ struct qspline q[128];
int num;
int t;
transform(&p0,m);
transform(&p1,m);
transform(&p2,m);
transform(&p3,m);
-
- num = approximate(p0,p1,p2,p3,q);
+ cspline c;
+ c.start = p3;
+ c.control1 = p2;
+ c.control2 = p1;
+ c.end = p0;
+
+ if(storefont) {
+ /* fonts use a different approximation than shapes */
+ num = cspline_approximate(&c, q, 10.0, APPROXIMATE_RECURSIVE_BINARY);
+ //num = cspline_approximate(&c, q, 10.0, APPROXIMATE_INFLECTION);
+ } else {
+ num = cspline_approximate(&c, q, 1.0, APPROXIMATE_RECURSIVE_BINARY);
+ }
for(t=0;t<num;t++) {
- moveto(tag,q[t].start);
+ if(!t)
+ moveto(tag,q[t].start);
splineto(tag,q[t].control, q[t].end);
}
}
}
}
-int colorcompare(RGBA*a,RGBA*b)
+static inline int colorcompare(RGBA*a,RGBA*b)
{
if(a->r!=b->r ||
} chardata[CHARDATAMAX];
int chardatapos = 0;
-void putcharacters(TAG*tag)
+static void putcharacters(TAG*tag)
{
int t;
SWFFONT font;
chardatapos = 0;
}
-void putcharacter(struct swfoutput*obj, int fontid, int charid,
+static void putcharacter(struct swfoutput*obj, int fontid, int charid,
int x,int y, int size)
{
if(chardatapos == CHARDATAMAX)
/* process a character. */
-void drawchar(struct swfoutput*obj, SWFFont*font, char*character, int charnr, swfmatrix*m)
+static void drawchar(struct swfoutput*obj, SWFFont*font, char*character, int charnr, swfmatrix*m)
{
int usefonts=1;
if(m->m12!=0 || m->m21!=0)
}
else
{
- T1_OUTLINE*outline = font->getOutline(character);
+ T1_OUTLINE*outline = font->getOutline(character, charnr);
char* charname = character;
if(!outline) {
logf("<warning> Didn't find %s in current charset (%s)",
- character,font->getName());
+ FIXNULL(character),FIXNULL(font->getName()));
return;
}
if(shapeid<0)
startshape(obj);
- if(!lastwasfill)
+ if(!lastwasfill) {
swf_ShapeSetStyle(tag,shape,0x8000,fillstyleid,0);
+ fillstylechanged = 1;
+ }
lastwasfill = 1;
int lf = fill;
{
if(textid>=0)
endtext();
+
+ /* Multiple polygons in one shape don't overlap correctly,
+ so we better start a new shape here if the polygon is filled
+ */
+ if(shapeid>=0 && fill && !ignoredraworder) {
+ endshape();
+ }
+
if(shapeid<0)
startshape(output);
if(lastwasfill && !fill)
{
swf_ShapeSetStyle(tag,shape,linestyleid,0x8000,0);
+ fillstylechanged = 1;
lastwasfill = 0;
}
if(!lastwasfill && fill)
{
swf_ShapeSetStyle(tag,shape,0x8000,fillstyleid,0);
+ fillstylechanged = 1;
lastwasfill = 1;
}
if(!charnum)
return;
- logf("<verbose> Font %s(%d): Storing %d outlines.\n", name, id, charnum);
+ logf("<verbose> Font %s(%d): Storing %d outlines.\n", FIXNULL(name), id, charnum);
this->standardtablesize = 256;
if(this->charnum < this->standardtablesize)
if(usednum && !drawonlyshapes)
{
- logf("<verbose> Font %s has %d used characters",fontid, usednum);
+ logf("<verbose> Font %s has %d used characters",FIXNULL(fontid), usednum);
TAG*ftag = swf_InsertTag(swf.firstTag,ST_DEFINEFONT);
swf_SetU16(ftag, this->swfid);
int initpos = swf_GetTagLen(ftag);
}
for(t=0;t<swfcharpos;t++)
{
- *(U16*)&ftag->data[ptr[t]] = swf_GetTagLen(ftag)-initpos;
+ *(U16*)&ftag->data[ptr[t]] =
+ SWAP16(swf_GetTagLen(ftag)-initpos);
+
swflastx=0;
swflasty=0;
- swf_SetU8(ftag,0x10); //0 fill bits, 0 linestyle bits
+ swf_SetU8(ftag,0x10); //1 fill bits, 0 linestyle bits
SHAPE s;
s.bits.fill = 1;
s.bits.line = 0;
swf_ShapeSetStyle(ftag,&s,0,1,0);
+ fillstylechanged = 1;
int lastfill = fill;
fill = 1;
storefont = 1;
free(char2swfcharid);
}
-T1_OUTLINE*SWFFont::getOutline(char*name)
+T1_OUTLINE*SWFFont::getOutline(char*name, int charnr)
{
int t;
for(t=0;t<this->charnum;t++) {
if(!strcmp(this->charname[t],name)) {
- if(!used[t])
- {
- swfcharid2char[swfcharpos] = t;
- char2swfcharid[t] = swfcharpos;
- swfcharpos++;
- used[t] = 1;
- }
return outline[t];
}
}
+
+ /* if we didn't find the character, maybe
+ we can find the capitalized version */
+ for(t=0;t<this->charnum;t++) {
+ if(!strcasecmp(this->charname[t],name))
+ return outline[t];
+ }
+
+ /* if we didn't find it by name, use the names of the first 256 characters
+ of the font to try a new name based on charnr */
+ if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) {
+ return getOutline(this->standardtable[charnr], -1);
+ }
+
+ logf("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
return 0;
}
-int SWFFont::getWidth(char*name)
+int SWFFont::getSWFCharID(char*name, int charnr)
{
int t;
for(t=0;t<this->charnum;t++) {
if(!strcmp(this->charname[t],name)) {
- return this->width[t];
+ if(!used[t])
+ {
+ swfcharid2char[swfcharpos] = t;
+ char2swfcharid[t] = swfcharpos++;
+ used[t] = 1;
+ }
+ return char2swfcharid[t];
}
}
- return 0;
-}
-int SWFFont::getSWFCharID(char*name, int charnr)
-{
- int t;
+ /* if we didn't find the character, maybe
+ we can find the capitalized version */
for(t=0;t<this->charnum;t++) {
- if(!strcmp(this->charname[t],name)) {
+ if(!strcasecmp(this->charname[t],name)) {
if(!used[t])
{
swfcharid2char[swfcharpos] = t;
return char2swfcharid[t];
}
}
+
+ /* if we didn't find it by name, use the names of the first 256 (or so) characters
+ of the font to try a new name based on charnr */
if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) {
return getSWFCharID(this->standardtable[charnr], -1);
}
- logf("<warning> Didn't find character '%s' in font '%s'", name, this->name);
+ logf("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
+ return 0;
+}
+
+int SWFFont::getWidth(char*name)
+{
+ int t;
+ for(t=0;t<this->charnum;t++) {
+ if(!strcmp(this->charname[t],name)) {
+ return this->width[t];
+ }
+ }
return 0;
}
}
if(t1id<0) {
- logf("<error> internal error: t1id:%d, fontid:%s\n", t1id,fontid);
+ logf("<error> internal error: t1id:%d, fontid:%s\n", t1id,FIXNULL(fontid));
}
SWFFont*font = new SWFFont(fontid, t1id, filename);
memset(&swf,0x00,sizeof(SWF));
- swf.fileVersion = 4;
+ swf.fileVersion = flashversion;
swf.frameRate = 0x0040; // 1 frame per 4 seconds
swf.movieSize.xmax = 20*sizex;
swf.movieSize.ymax = 20*sizey;
flag_protected = 1;
}
-void startshape(struct swfoutput*obj)
+static void startshape(struct swfoutput*obj)
{
RGBA rgb;
SRECT r;
lastwasfill = 0;
}
-void starttext(struct swfoutput*obj)
+static void starttext(struct swfoutput*obj)
{
SRECT r;
MATRIX m;
swflastx=swflasty=0;
}
-void endshape()
+static void endshape()
{
if(shapeid<0)
return;
shapeid = -1;
}
-void endtext()
+static void endtext()
{
if(textid<0)
return;
textid = -1;
}
-void endpage(struct swfoutput*obj)
+static void endpage(struct swfoutput*obj)
{
if(shapeid>=0)
endshape();
endtext();
while(clippos)
swfoutput_endclip(obj);
+
+ if(insertstoptag) {
+ ActionTAG*atag=0;
+ atag = action_Stop(atag);
+ atag = action_End(atag);
+ tag = swf_InsertTag(tag,ST_DOACTION);
+ swf_ActionSet(tag,atag);
+ }
tag = swf_InsertTag(tag,ST_SHOWFRAME);
}
if(!filename)
return;
if(filename)
- fi = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0777);
+ fi = open(filename, O_BINARY|O_CREAT|O_TRUNC|O_WRONLY, 0777);
else
fi = 1; // stdout
if(fi<=0) {
- logf("<fatal> Could not create \"%s\". ", filename);
+ logf("<fatal> Could not create \"%s\". ", FIXNULL(filename));
exit(1);
}
tag = swf_InsertTag(tag,ST_END);
- if FAILED(swf_WriteSWF(fi,&swf))
- logf("<error> WriteSWF() failed.\n");
+ if(enablezlib) {
+ if FAILED(swf_WriteSWC(fi,&swf))
+ logf("<error> WriteSWC() failed.\n");
+ } else {
+ if FAILED(swf_WriteSWF(fi,&swf))
+ logf("<error> WriteSWF() failed.\n");
+ }
+
if(filename)
close(fi);
logf("<notice> SWF written\n");
obj->fillrgb.g == g &&
obj->fillrgb.b == b &&
obj->fillrgb.a == a) return;
-
if(shapeid>=0)
endshape();
+
obj->fillrgb.r = r;
obj->fillrgb.g = g;
obj->fillrgb.b = b;
swf_ObjectPlaceClip(cliptags[clippos],clipshapes[clippos],clipdepths[clippos],NULL,NULL,NULL,depth++);
}
-void drawlink(struct swfoutput*obj, ActionTAG*, swfcoord*points);
+static void drawlink(struct swfoutput*obj, ActionTAG*,ActionTAG*, swfcoord*points, char mouseover);
void swfoutput_linktourl(struct swfoutput*obj, char*url, swfcoord*points)
{
ActionTAG* actions;
+ if(!strncmp("http://pdf2swf:", url, 15)) {
+ char*tmp = strdup(url);
+ int l = strlen(tmp);
+ if(tmp[l-1] == '/')
+ tmp[l-1] = 0;
+ swfoutput_namedlink(obj, tmp+15, points);
+ free(tmp);
+ return;
+ }
if(shapeid>=0)
endshape();
if(textid>=0)
endtext();
- actions = swf_ActionStart();
if(opennewwindow)
- action_GetUrl(url, "_parent");
+ actions = action_GetUrl(0, url, "_parent");
else
- action_GetUrl(url, "_this");
- action_End();
- swf_ActionEnd();
+ actions = action_GetUrl(0, url, "_this");
+ actions = action_End(actions);
- drawlink(obj, actions, points);
+ drawlink(obj, actions, 0, points,0);
}
void swfoutput_linktopage(struct swfoutput*obj, int page, swfcoord*points)
{
if(textid>=0)
endtext();
- actions = swf_ActionStart();
- action_GotoFrame(page);
- action_End();
- swf_ActionEnd();
+ actions = action_GotoFrame(0, page);
+ actions = action_End(actions);
- drawlink(obj, actions, points);
+ drawlink(obj, actions, 0, points,0);
}
-void drawlink(struct swfoutput*obj, ActionTAG*actions, swfcoord*points)
+/* Named Links (a.k.a. Acrobatmenu) are used to implement various gadgets
+ of the viewer objects, like subtitles, index elements etc.
+*/
+void swfoutput_namedlink(struct swfoutput*obj, char*name, swfcoord*points)
+{
+ ActionTAG *actions1,*actions2;
+ char*tmp = strdup(name);
+ char mouseover = 1;
+
+ if(shapeid>=0)
+ endshape();
+ if(textid>=0)
+ endtext();
+
+ if(!strncmp(tmp, "call:", 5))
+ {
+ char*x = strchr(&tmp[5], ':');
+ if(!x) {
+ actions1 = action_PushInt(0, 0); //number of parameters (0)
+ actions1 = action_PushString(actions1, &tmp[5]); //function name
+ actions1 = action_CallFunction(actions1);
+ } else {
+ *x = 0;
+ actions1 = action_PushString(0, x+1); //parameter
+ actions1 = action_PushInt(actions1, 1); //number of parameters (1)
+ actions1 = action_PushString(actions1, &tmp[5]); //function name
+ actions1 = action_CallFunction(actions1);
+ }
+ actions2 = action_End(0);
+ mouseover = 0;
+ }
+ else
+ {
+ actions1 = action_PushString(0, "/:subtitle");
+ actions1 = action_PushString(actions1, name);
+ actions1 = action_SetVariable(actions1);
+ actions1 = action_End(actions1);
+
+ actions2 = action_PushString(0, "/:subtitle");
+ actions2 = action_PushString(actions2, "");
+ actions2 = action_SetVariable(actions2);
+ actions2 = action_End(actions2);
+ }
+
+ drawlink(obj, actions1, actions2, points,mouseover);
+
+ swf_ActionFree(actions1);
+ swf_ActionFree(actions2);
+ free(tmp);
+}
+
+static void drawlink(struct swfoutput*obj, ActionTAG*actions1, ActionTAG*actions2, swfcoord*points, char mouseover)
{
RGBA rgb;
SRECT r;
int myshapeid2;
double xmin,ymin;
double xmax=xmin=points[0].x,ymax=ymin=points[0].y;
+ double posx = 0;
+ double posy = 0;
int t;
int buttonid = ++currentswfid;
for(t=1;t<4;t++)
if(points[t].x<xmin) xmin=points[t].x;
if(points[t].y<ymin) ymin=points[t].y;
}
+
p1.x=points[0].x; p1.y=points[0].y; p2.x=points[1].x; p2.y=points[1].y;
p3.x=points[2].x; p3.y=points[2].y; p4.x=points[3].x; p4.y=points[3].y;
+
+ /* the following code subtracts the upper left edge from all coordinates,
+ and set's posx,posy so that ST_PLACEOBJECT is used with a matrix.
+ Necessary for preprocessing with swfcombine. */
+ posx = xmin; posy = ymin;
+ p1.x-=posx;p2.x-=posx;p3.x-=posx;p4.x-=posx;
+ p1.y-=posy;p2.y-=posy;p3.y-=posy;p4.y-=posy;
+ xmin -= posx; ymin -= posy;
+ xmax -= posx; ymax -= posy;
/* shape */
myshapeid = ++currentswfid;
lineto(tag, p1);
swf_ShapeSetEnd(tag);
- tag = swf_InsertTag(tag,ST_DEFINEBUTTON);
- swf_SetU16(tag,buttonid); //id
- swf_ButtonSetFlags(tag, 0); //menu=no
- swf_ButtonSetRecord(tag,0x01,myshapeid,depth,0,0);
- swf_ButtonSetRecord(tag,0x02,myshapeid2,depth,0,0);
- swf_ButtonSetRecord(tag,0x04,myshapeid2,depth,0,0);
- swf_ButtonSetRecord(tag,0x08,myshapeid,depth,0,0);
- swf_SetU8(tag,0);
- swf_ActionSet(tag,actions);
- swf_SetU8(tag,0);
+ if(!mouseover)
+ {
+ tag = swf_InsertTag(tag,ST_DEFINEBUTTON);
+ swf_SetU16(tag,buttonid); //id
+ swf_ButtonSetFlags(tag, 0); //menu=no
+ swf_ButtonSetRecord(tag,0x01,myshapeid,depth,0,0);
+ swf_ButtonSetRecord(tag,0x02,myshapeid2,depth,0,0);
+ swf_ButtonSetRecord(tag,0x04,myshapeid2,depth,0,0);
+ swf_ButtonSetRecord(tag,0x08,myshapeid,depth,0,0);
+ swf_SetU8(tag,0);
+ swf_ActionSet(tag,actions1);
+ swf_SetU8(tag,0);
+ }
+ else
+ {
+ tag = swf_InsertTag(tag,ST_DEFINEBUTTON2);
+ swf_SetU16(tag,buttonid); //id
+ swf_ButtonSetFlags(tag, 0); //menu=no
+ swf_ButtonSetRecord(tag,0x01,myshapeid,depth,0,0);
+ swf_ButtonSetRecord(tag,0x02,myshapeid2,depth,0,0);
+ swf_ButtonSetRecord(tag,0x04,myshapeid2,depth,0,0);
+ swf_ButtonSetRecord(tag,0x08,myshapeid,depth,0,0);
+ swf_SetU8(tag,0); // end of button records
+ swf_ButtonSetCondition(tag, BC_IDLE_OVERUP);
+ swf_ActionSet(tag,actions1);
+ if(actions2) {
+ swf_ButtonSetCondition(tag, BC_OVERUP_IDLE);
+ swf_ActionSet(tag,actions2);
+ swf_SetU8(tag,0);
+ swf_ButtonPostProcess(tag, 2);
+ } else {
+ swf_SetU8(tag,0);
+ swf_ButtonPostProcess(tag, 1);
+ }
+ }
tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
- swf_ObjectPlace(tag, buttonid, depth++,0,0,0);
+
+ if(posx!=0 || posy!=0) {
+ MATRIX m;
+ swf_GetMatrix(0,&m);
+ m.tx = (int)(posx*20);
+ m.ty = (int)(posy*20);
+ swf_ObjectPlace(tag, buttonid, depth++,&m,0,0);
+ }
+ else {
+ swf_ObjectPlace(tag, buttonid, depth++,0,0,0);
+ }
}
-void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey,
+static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey,
double x1,double y1,
double x2,double y2,
double x3,double y3,
if(y4>ymax) ymax=y4;
if(x4<xmin) xmin=x4;
if(y4<ymin) ymin=y4;
- p1.x=x1;
- p1.y=y1;
- p2.x=x2;
- p2.y=y2;
- p3.x=x3;
- p3.y=y3;
- p4.x=x4;
- p4.y=y4;
+ p1.x=x1; p1.y=y1;
+ p2.x=x2; p2.y=y2;
+ p3.x=x3; p3.y=y3;
+ p4.x=x4; p4.y=y4;
+
+ {p1.x = (int)(p1.x*20)/20.0;
+ p1.y = (int)(p1.y*20)/20.0;
+ p2.x = (int)(p2.x*20)/20.0;
+ p2.y = (int)(p2.y*20)/20.0;
+ p3.x = (int)(p3.x*20)/20.0;
+ p3.y = (int)(p3.y*20)/20.0;
+ p4.x = (int)(p4.x*20)/20.0;
+ p4.y = (int)(p4.y*20)/20.0;}
MATRIX m;
- m.sx = (int)(65536*20*(x4-x1))/sizex;
- m.r1 = -(int)(65536*20*(y4-y1))/sizex;
- m.r0 = (int)(65536*20*(x1-x2))/sizey;
- m.sy = -(int)(65536*20*(y1-y2))/sizey;
+ m.sx = (int)(65536*20*(p4.x-p1.x)/sizex);
+ m.r1 = -(int)(65536*20*(p4.y-p1.y)/sizex);
+ m.r0 = (int)(65536*20*(p1.x-p2.x)/sizey);
+ m.sy = -(int)(65536*20*(p1.y-p2.y)/sizey);
- m.tx = (int)(x1*20);
- m.ty = (int)(y1*20);
+ m.tx = (int)(p1.x*20);
+ m.ty = (int)(p1.y*20);
/* shape */
myshapeid = ++currentswfid;
swf_ShapeNew(&shape);
//lsid = ShapeAddLineStyle(shape,obj->linewidth,&obj->strokergb);
//fsid = ShapeAddSolidFillStyle(shape,&obj->fillrgb);
- fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,0);
+ fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,1);
swf_SetU16(tag, myshapeid);
r.xmin = (int)(xmin*20);
r.ymin = (int)(ymin*20);
swf_ObjectPlace(tag,myshapeid,/*depth*/depth++,NULL,NULL,NULL);
}
-int swfoutput_drawimagejpeg(struct swfoutput*obj, char*filename, int sizex,int sizey,
+int swfoutput_drawimagejpeg_old(struct swfoutput*obj, char*filename, int sizex,int sizey,
double x1,double y1,
double x2,double y2,
double x3,double y3,
return bitid;
}
+int swfoutput_drawimagejpeg(struct swfoutput*obj, RGBA*mem, int sizex,int sizey,
+ double x1,double y1,
+ double x2,double y2,
+ double x3,double y3,
+ double x4,double y4)
+{
+ TAG*oldtag;
+ JPEGBITS*jpeg;
+
+ if(shapeid>=0)
+ endshape();
+ if(textid>=0)
+ endtext();
+
+ int bitid = ++currentswfid;
+ oldtag = tag;
+ tag = swf_InsertTag(tag,ST_DEFINEBITSJPEG2);
+ swf_SetU16(tag, bitid);
+ swf_SetJPEGBits2(tag,sizex,sizey,mem,jpegquality);
+ drawimage(obj, bitid, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
+ return bitid;
+}
+
int swfoutput_drawimagelossless(struct swfoutput*obj, RGBA*mem, int sizex,int sizey,
double x1,double y1,
double x2,double y2,
return bitid;
}
-int swfoutput_drawimagelossless256(struct swfoutput*obj, U8*mem, RGBA*pal, int sizex,int sizey,
+int swfoutput_drawimagelosslessN(struct swfoutput*obj, U8*mem, RGBA*pal, int sizex,int sizey,
double x1,double y1,
double x2,double y2,
double x3,double y3,
- double x4,double y4)
+ double x4,double y4, int n)
{
TAG*oldtag;
+ U8*mem2 = 0;
if(shapeid>=0)
endshape();
if(textid>=0)
endtext();
+ if(sizex&3)
+ {
+ /* SWF expects scanlines to be 4 byte aligned */
+ int x,y;
+ U8*ptr;
+ mem2 = (U8*)malloc(BYTES_PER_SCANLINE(sizex)*sizey);
+ ptr = mem2;
+ for(y=0;y<sizey;y++)
+ {
+ for(x=0;x<sizex;x++)
+ *ptr++ = mem[y*sizex+x];
+ ptr+= BYTES_PER_SCANLINE(sizex)-sizex;
+ }
+ mem = mem2;
+ }
+
int bitid = ++currentswfid;
oldtag = tag;
tag = swf_InsertTag(tag,ST_DEFINEBITSLOSSLESS2);
swf_SetU16(tag, bitid);
- if(swf_SetLosslessBitsIndexed(tag,sizex,sizey,mem, pal, 256)<0) {
+ if(swf_SetLosslessBitsIndexed(tag,sizex,sizey,mem, pal, n)<0) {
swf_DeleteTag(tag);
tag = oldtag;
return -1;
}
+ if(mem2)
+ free(mem2);
drawimage(obj, bitid, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
return bitid;