X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fdevices%2Frecord.c;h=a8a0088672b5ea848c97cc726d857c3204b00077;hb=bf04757cd94e94c1f67fa3d2a4e3e59fa5bce0c0;hp=ae5bedf84186da34a5d5fb5052a04982f442cebc;hpb=d3fb559b6b8ca9c122b310cae1a3e8b0805f97ad;p=swftools.git diff --git a/lib/devices/record.c b/lib/devices/record.c index ae5bedf..a8a0088 100644 --- a/lib/devices/record.c +++ b/lib/devices/record.c @@ -21,16 +21,26 @@ #include #include #include +#include "../../config.h" +#ifdef HAVE_UNISTD_H #include +#endif #include +#ifdef HAVE_IO_H +#include +#endif +#include #include "../gfxdevice.h" #include "../gfxtools.h" #include "../types.h" #include "../bitio.h" +#include "../log.h" +#include "record.h" typedef struct _internal { gfxfontlist_t* fontlist; writer_t w; + int cliplevel; } internal_t; typedef struct _internal_result { @@ -60,6 +70,7 @@ typedef struct _internal_result { static int record_setparameter(struct _gfxdevice*dev, const char*key, const char*value) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x SETPARAM %s %s\n", dev, key, value); writer_writeU8(&i->w, OP_SETPARAM); writer_writeString(&i->w, key); writer_writeString(&i->w, value); @@ -95,7 +106,7 @@ static gfxline_t* readLine(reader_t*r) unsigned char op = reader_readU8(r); if(op == OP_END) break; - gfxline_t*line = rfx_calloc(sizeof(gfxline_t)); + gfxline_t*line = (gfxline_t*)rfx_calloc(sizeof(gfxline_t)); if(!start) { start = pos = line; } else { @@ -125,7 +136,7 @@ static gfximage_t readImage(reader_t*r) gfximage_t img; img.width = reader_readU16(r); img.height = reader_readU16(r); - img.data = rfx_alloc(img.width*img.height*4); + img.data = (gfxcolor_t*)rfx_alloc(img.width*img.height*4); r->read(r, img.data, img.width*img.height*4); return img; } @@ -156,7 +167,7 @@ static gfxgradient_t* readGradient(reader_t*r) U8 op = reader_readU8(r); if(!op) break; - gfxgradient_t*g = rfx_calloc(sizeof(gfxgradient_t)); + gfxgradient_t*g = (gfxgradient_t*)rfx_calloc(sizeof(gfxgradient_t)); if(!start) { start = pos = g; } else { @@ -173,7 +184,7 @@ static gfxcxform_t* readCXForm(reader_t*r) U8 type = reader_readU8(r); if(!type) return 0; - gfxcxform_t* c = rfx_calloc(sizeof(gfxcxform_t)); + gfxcxform_t* c = (gfxcxform_t*)rfx_calloc(sizeof(gfxcxform_t)); c->rr = reader_readFloat(r); c->rg = reader_readFloat(r); c->rb = reader_readFloat(r); c->ra = reader_readFloat(r); c->gr = reader_readFloat(r); c->gg = reader_readFloat(r); c->gb = reader_readFloat(r); c->ga = reader_readFloat(r); c->br = reader_readFloat(r); c->bg = reader_readFloat(r); c->bb = reader_readFloat(r); c->ba = reader_readFloat(r); @@ -247,12 +258,12 @@ static void dumpFont(writer_t*w, gfxfont_t*font) } static gfxfont_t*readFont(reader_t*r) { - gfxfont_t* font = rfx_calloc(sizeof(gfxfont_t)); + gfxfont_t* font = (gfxfont_t*)rfx_calloc(sizeof(gfxfont_t)); font->id = reader_readString(r); font->num_glyphs = reader_readU32(r); font->max_unicode = reader_readU32(r); - font->glyphs = rfx_calloc(sizeof(gfxglyph_t)*font->num_glyphs); - font->unicode2glyph = rfx_calloc(sizeof(font->unicode2glyph[0])*font->max_unicode); + font->glyphs = (gfxglyph_t*)rfx_calloc(sizeof(gfxglyph_t)*font->num_glyphs); + font->unicode2glyph = (int*)rfx_calloc(sizeof(font->unicode2glyph[0])*font->max_unicode); int t; for(t=0;tnum_glyphs;t++) { font->glyphs[t].line = readLine(r); @@ -260,7 +271,7 @@ static gfxfont_t*readFont(reader_t*r) font->glyphs[t].unicode = reader_readU32(r); font->glyphs[t].name = reader_readString(r); if(!font->glyphs[t].name[0]) { - free(font->glyphs[t].name); + free((void*)(font->glyphs[t].name)); font->glyphs[t].name = 0; } } @@ -273,6 +284,7 @@ static gfxfont_t*readFont(reader_t*r) static void record_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x STROKE\n", dev); writer_writeU8(&i->w, OP_STROKE); writer_writeDouble(&i->w, width); writer_writeDouble(&i->w, miterLimit); @@ -285,19 +297,27 @@ static void record_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t widt static void record_startclip(struct _gfxdevice*dev, gfxline_t*line) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x STARTCLIP\n", dev); writer_writeU8(&i->w, OP_STARTCLIP); dumpLine(&i->w, line); + i->cliplevel++; } static void record_endclip(struct _gfxdevice*dev) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x ENDCLIP\n", dev); writer_writeU8(&i->w, OP_ENDCLIP); + i->cliplevel--; + if(i->cliplevel<0) { + msg(" record: endclip() without startclip()"); + } } static void record_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x FILL\n", dev); writer_writeU8(&i->w, OP_FILL); dumpColor(&i->w, color); dumpLine(&i->w, line); @@ -306,6 +326,7 @@ static void record_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color) static void record_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x FILLBITMAP\n", dev); writer_writeU8(&i->w, OP_FILLBITMAP); dumpImage(&i->w, img); dumpMatrix(&i->w, matrix); @@ -316,6 +337,7 @@ static void record_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t* static void record_fillgradient(struct _gfxdevice*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x FILLGRADIENT %08x\n", dev, gradient); writer_writeU8(&i->w, OP_FILLGRADIENT); writer_writeU8(&i->w, type); dumpGradient(&i->w, gradient); @@ -326,17 +348,22 @@ static void record_fillgradient(struct _gfxdevice*dev, gfxline_t*line, gfxgradie static void record_addfont(struct _gfxdevice*dev, gfxfont_t*font) { internal_t*i = (internal_t*)dev->internal; - writer_writeU8(&i->w, OP_ADDFONT); - dumpFont(&i->w, font); - i->fontlist = gfxfontlist_addfont(i->fontlist, font); + msg(" record: %08x ADDFONT %s\n", dev, font->id); + if(font && !gfxfontlist_hasfont(i->fontlist, font)) { + writer_writeU8(&i->w, OP_ADDFONT); + dumpFont(&i->w, font); + i->fontlist = gfxfontlist_addfont(i->fontlist, font); + } } static void record_drawchar(struct _gfxdevice*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix) { internal_t*i = (internal_t*)dev->internal; - if(font && !gfxfontlist_hasfont(i->fontlist, font)) + if(font && !gfxfontlist_hasfont(i->fontlist, font)) { record_addfont(dev, font); + } + msg(" record: %08x DRAWCHAR %d\n", glyphnr, dev); writer_writeU8(&i->w, OP_DRAWCHAR); if(font) writer_writeString(&i->w, font->id); @@ -350,6 +377,7 @@ static void record_drawchar(struct _gfxdevice*dev, gfxfont_t*font, int glyphnr, static void record_startpage(struct _gfxdevice*dev, int width, int height) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x STARTPAGE\n", dev); writer_writeU8(&i->w, OP_STARTPAGE); writer_writeU16(&i->w, width); writer_writeU16(&i->w, height); @@ -358,124 +386,179 @@ static void record_startpage(struct _gfxdevice*dev, int width, int height) static void record_endpage(struct _gfxdevice*dev) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x ENDPAGE\n", dev); writer_writeU8(&i->w, OP_ENDPAGE); } -static void record_drawlink(struct _gfxdevice*dev, gfxline_t*line, char*action) +static void record_drawlink(struct _gfxdevice*dev, gfxline_t*line, const char*action) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x DRAWLINK\n", dev); writer_writeU8(&i->w, OP_DRAWLINK); dumpLine(&i->w, line); writer_writeString(&i->w, action); } -void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device) +static void replay(struct _gfxdevice*dev, gfxdevice_t*out, void*data, int length) { - internal_result_t*i = (internal_result_t*)result->internal; + internal_t*i = 0; + if(dev) { + i = (internal_t*)dev->internal; + } + reader_t r2; reader_t*r = &r2; - reader_init_memreader(r, i->data, i->length); + reader_init_memreader(r, data, length); gfxfontlist_t* fontlist = gfxfontlist_create(); - while(1) { + while(r->pos < length) { unsigned char op = reader_readU8(r); switch(op) { case OP_END: - return; + goto finish; case OP_SETPARAM: { + msg(" replay: SETPARAM"); char*key; char*value; key = reader_readString(r); value = reader_readString(r); - device->setparameter(device, key, value); + out->setparameter(out, key, value); free(key); free(value); break; } case OP_STARTPAGE: { + msg(" replay: STARTPAGE"); U16 width = reader_readU16(r); U16 height = reader_readU16(r); - device->startpage(device, width, height); + out->startpage(out, width, height); break; } case OP_ENDPAGE: { + msg(" replay: ENDPAGE"); break; } case OP_FINISH: { + msg(" replay: FINISH"); break; } case OP_STROKE: { + msg(" replay: STROKE"); double width = reader_readDouble(r); double miterlimit = reader_readDouble(r); gfxcolor_t color = readColor(r); - gfx_capType captype = reader_readU8(r); - gfx_joinType jointtype = reader_readU8(r); + gfx_capType captype; + int v = reader_readU8(r); + switch (v) { + case 0: captype = gfx_capButt; break; + case 1: captype = gfx_capRound; break; + case 2: captype = gfx_capSquare; break; + } + gfx_joinType jointtype; + v = reader_readU8(r); + switch (v) { + case 0: jointtype = gfx_joinMiter; break; + case 1: jointtype = gfx_joinRound; break; + case 2: jointtype = gfx_joinBevel; break; + } gfxline_t* line = readLine(r); - device->stroke(device, line, width, &color, captype, jointtype,miterlimit); + out->stroke(out, line, width, &color, captype, jointtype,miterlimit); gfxline_free(line); break; } case OP_STARTCLIP: { + msg(" replay: STARTCLIP"); gfxline_t* line = readLine(r); - device->startclip(device, line); + out->startclip(out, line); gfxline_free(line); break; } case OP_ENDCLIP: { - device->endclip(device); + msg(" replay: ENDCLIP"); + out->endclip(out); break; } case OP_FILL: { + msg(" replay: FILL"); gfxcolor_t color = readColor(r); gfxline_t* line = readLine(r); - device->fill(device, line, &color); + out->fill(out, line, &color); gfxline_free(line); break; } case OP_FILLBITMAP: { + msg(" replay: FILLBITMAP"); gfximage_t img = readImage(r); gfxmatrix_t matrix = readMatrix(r); gfxline_t* line = readLine(r); gfxcxform_t* cxform = readCXForm(r); - device->fillbitmap(device, line, &img, &matrix, cxform); + out->fillbitmap(out, line, &img, &matrix, cxform); + gfxline_free(line); if(cxform) free(cxform); + free(img.data);img.data=0; break; } case OP_FILLGRADIENT: { - gfxgradienttype_t type = reader_readU8(r); + msg(" replay: FILLGRADIENT"); + gfxgradienttype_t type; + int v = reader_readU8(r); + switch (v) { + case 0: + type = gfxgradient_radial; break; + case 1: + type = gfxgradient_linear; break; + } gfxgradient_t*gradient = readGradient(r); gfxmatrix_t matrix = readMatrix(r); gfxline_t* line = readLine(r); - device->fillgradient(device, line, gradient, type, &matrix); + out->fillgradient(out, line, gradient, type, &matrix); break; } case OP_DRAWLINK: { + msg(" replay: DRAWLINK"); gfxline_t* line = readLine(r); char* s = reader_readString(r); - device->drawlink(device,line,s); + out->drawlink(out,line,s); gfxline_free(line); free(s); break; } case OP_ADDFONT: { + msg(" replay: ADDFONT out=%08x(%s)", out, out->name); gfxfont_t*font = readFont(r); fontlist = gfxfontlist_addfont(fontlist, font); - device->addfont(device, font); + out->addfont(out, font); break; } case OP_DRAWCHAR: { char* id = reader_readString(r); gfxfont_t*font = id?gfxfontlist_findfont(fontlist, id):0; + if(i && !font) { + font = gfxfontlist_findfont(i->fontlist, id); + } U32 glyph = reader_readU32(r); + msg(" replay: DRAWCHAR font=%s glyph=%d", id, glyph); gfxcolor_t color = readColor(r); gfxmatrix_t matrix = readMatrix(r); - device->drawchar(device, font, glyph, &color, &matrix); + out->drawchar(out, font, glyph, &color, &matrix); free(id); break; } } } +finish: + r->dealloc(r); + /* problem: if we just replayed into a device which stores the + font for later use (the record device itself is a nice example), + then we can't free it yet */ + //gfxfontlist_free(fontlist, 1); + gfxfontlist_free(fontlist, 0); +} +void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device) +{ + internal_result_t*i = (internal_result_t*)result->internal; + replay(0, device, i->data, i->length); } static void record_result_write(gfxresult_t*r, int filedesc) @@ -483,7 +566,7 @@ static void record_result_write(gfxresult_t*r, int filedesc) internal_result_t*i = (internal_result_t*)r->internal; write(filedesc, i->data, i->length); } -static int record_result_save(gfxresult_t*r, char*filename) +static int record_result_save(gfxresult_t*r, const char*filename) { internal_result_t*i = (internal_result_t*)r->internal; FILE*fi = fopen(filename, "wb"); @@ -495,7 +578,7 @@ static int record_result_save(gfxresult_t*r, char*filename) fclose(fi); return 0; } -static void*record_result_get(gfxresult_t*r, char*name) +static void*record_result_get(gfxresult_t*r, const char*name) { internal_result_t*i = (internal_result_t*)r->internal; if(!strcmp(name, "data")) { @@ -508,21 +591,66 @@ static void*record_result_get(gfxresult_t*r, char*name) static void record_result_destroy(gfxresult_t*r) { internal_result_t*i = (internal_result_t*)r->internal; - free(i->data);i->data = 0; + if(i->data) { + free(i->data);i->data = 0; + } free(r->internal);r->internal = 0; free(r); } +static unsigned char printable(unsigned char a) +{ + if(a<32 || a==127) return '.'; + else return a; +} + +static void hexdumpMem(unsigned char*data, int len) +{ + int t; + char ascii[32]; + for(t=0;tinternal; + if(out) { + int len=0; + void*data = writer_growmemwrite_memptr(&i->w, &len); + replay(dev, out, data, len); + } + writer_growmemwrite_reset(&i->w); +} static gfxresult_t* record_finish(struct _gfxdevice*dev) { internal_t*i = (internal_t*)dev->internal; + msg(" record: %08x END", dev); + + if(i->cliplevel) { + msg(" Warning: unclosed cliplevels"); + } writer_writeU8(&i->w, OP_END); + + gfxfontlist_free(i->fontlist, 0); internal_result_t*ir = (internal_result_t*)rfx_calloc(sizeof(gfxresult_t)); ir->data = writer_growmemwrite_getmem(&i->w); ir->length = i->w.pos; + i->w.finish(&i->w); gfxresult_t*result= (gfxresult_t*)rfx_calloc(sizeof(gfxresult_t)); result->save = record_result_save; @@ -545,6 +673,7 @@ void gfxdevice_record_init(gfxdevice_t*dev) writer_init_growingmemwriter(&i->w, 1048576); i->fontlist = gfxfontlist_create(); + i->cliplevel = 0; dev->setparameter = record_setparameter; dev->startpage = record_startpage;