git.asbjorn.biz
/
swftools.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fixed build
[swftools.git]
/
lib
/
devices
/
record.c
diff --git
a/lib/devices/record.c
b/lib/devices/record.c
index
796e086
..
90fbfbf
100644
(file)
--- a/
lib/devices/record.c
+++ b/
lib/devices/record.c
@@
-34,6
+34,7
@@
#include <assert.h>
#include "../gfxdevice.h"
#include "../gfxtools.h"
#include <assert.h>
#include "../gfxdevice.h"
#include "../gfxtools.h"
+#include "../gfxfont.h"
#include "../types.h"
#include "../bitio.h"
#include "../log.h"
#include "../types.h"
#include "../bitio.h"
#include "../log.h"
@@
-45,7
+46,7
@@
#include "record.h"
//#define STATS
#include "record.h"
//#define STATS
-#define COMPRESS_IMAGES
+//#define COMPRESS_IMAGES
//#define FILTER_IMAGES
typedef struct _state {
//#define FILTER_IMAGES
typedef struct _state {
@@
-97,6
+98,7
@@
typedef struct _internal_result {
#define OP_FINISH 0x0d
#define FLAG_SAME_AS_LAST 0x10
#define OP_FINISH 0x0d
#define FLAG_SAME_AS_LAST 0x10
+#define FLAG_ZERO_FONT 0x20
#define LINE_MOVETO 0x0e
#define LINE_LINETO 0x0f
#define LINE_MOVETO 0x0e
#define LINE_LINETO 0x0f
@@
-185,6
+187,7
@@
static void dumpImage(writer_t*w, state_t*state, gfximage_t*img)
//48.0% images (3488650 bytes) (without filter, Z_BEST_SPEED)
//55.3% images (4665889 bytes) (without filter, fastlz level 2)
//55.6% images (4726334 bytes) (without filter, fastlz level 1)
//48.0% images (3488650 bytes) (without filter, Z_BEST_SPEED)
//55.3% images (4665889 bytes) (without filter, fastlz level 2)
//55.6% images (4726334 bytes) (without filter, fastlz level 1)
+ //83.0% images (18091804 bytes) (no compression)
gfxcolor_t*image;
#ifdef FILTER_IMAGES
gfxcolor_t*image;
#ifdef FILTER_IMAGES
@@
-206,7
+209,7
@@
static void dumpImage(writer_t*w, state_t*state, gfximage_t*img)
#ifdef HAVE_FASTLZ
compressdata_size = fastlz_compress_level(2, (void*)image, size*sizeof(gfxcolor_t), compressdata);
#else
#ifdef HAVE_FASTLZ
compressdata_size = fastlz_compress_level(2, (void*)image, size*sizeof(gfxcolor_t), compressdata);
#else
- compress2(compressdata, &compressdata_size, (void*)image, sizeof(gfxcolor_t)*size, 6);
+ compress2(compressdata, &compressdata_size, (void*)image, sizeof(gfxcolor_t)*size, Z_BEST_SPEED);
#endif
writer_writeU32(w, compressdata_size);
#endif
writer_writeU32(w, compressdata_size);
@@
-450,6
+453,17
@@
static gfxfont_t*readFont(reader_t*r, state_t*state)
/* ----------------- reading/writing of primitives with caching -------------- */
/* ----------------- reading/writing of primitives with caching -------------- */
+void state_clear(state_t*state)
+{
+ int t;
+ for(t=0;t<sizeof(state->last_string)/sizeof(state->last_string[0]);t++) {
+ if(state->last_string[t]) {
+ free(state->last_string[t]);
+ state->last_string[t] = 0;
+ }
+ }
+}
+
static char* read_string(reader_t*r, state_t*state, U8 id, U8 flags)
{
assert(id>=0 && id<16);
static char* read_string(reader_t*r, state_t*state, U8 id, U8 flags)
{
assert(id>=0 && id<16);
@@
-458,6
+472,9
@@
static char* read_string(reader_t*r, state_t*state, U8 id, U8 flags)
return strdup(state->last_string[id]);
}
char*s = reader_readString(r);
return strdup(state->last_string[id]);
}
char*s = reader_readString(r);
+ if(state->last_string[id]) {
+ free(state->last_string[id]);
+ }
state->last_string[id] = strdup(s);
return s;
}
state->last_string[id] = strdup(s);
return s;
}
@@
-578,16
+595,22
@@
static void record_drawchar(struct _gfxdevice*dev, gfxfont_t*font, int glyphnr,
}
msg("<trace> record: %08x DRAWCHAR %d\n", glyphnr, dev);
}
msg("<trace> record: %08x DRAWCHAR %d\n", glyphnr, dev);
- const char*font_id = font->id?font->id:"*NULL*";
+ const char*font_id = (font&&font->id)?font->id:"*NULL*";
gfxmatrix_t*l = &i->state.last_matrix[OP_DRAWCHAR];
gfxmatrix_t*l = &i->state.last_matrix[OP_DRAWCHAR];
+ U8 flags = 0;
+ if(!font)
+ flags |= FLAG_ZERO_FONT;
+
char same_font = i->state.last_string[OP_DRAWCHAR] && !strcmp(i->state.last_string[OP_DRAWCHAR], font_id);
char same_matrix = (l->m00 == matrix->m00) && (l->m01 == matrix->m01) && (l->m10 == matrix->m10) && (l->m11 == matrix->m11);
char same_color = !memcmp(color, &i->state.last_color[OP_DRAWCHAR], sizeof(gfxcolor_t));
char same_font = i->state.last_string[OP_DRAWCHAR] && !strcmp(i->state.last_string[OP_DRAWCHAR], font_id);
char same_matrix = (l->m00 == matrix->m00) && (l->m01 == matrix->m01) && (l->m10 == matrix->m10) && (l->m11 == matrix->m11);
char same_color = !memcmp(color, &i->state.last_color[OP_DRAWCHAR], sizeof(gfxcolor_t));
- U8 flags = 0;
+
+ /* FIXME
if(same_font && same_matrix && same_color)
flags |= FLAG_SAME_AS_LAST;
if(same_font && same_matrix && same_color)
flags |= FLAG_SAME_AS_LAST;
+ */
writer_writeU8(&i->w, OP_DRAWCHAR|flags);
writer_writeU32(&i->w, glyphnr);
writer_writeU8(&i->w, OP_DRAWCHAR|flags);
writer_writeU32(&i->w, glyphnr);
@@
-596,10
+619,15
@@
static void record_drawchar(struct _gfxdevice*dev, gfxfont_t*font, int glyphnr,
#endif
if(!(flags&FLAG_SAME_AS_LAST)) {
#endif
if(!(flags&FLAG_SAME_AS_LAST)) {
- writer_writeString(&i->w, font_id);
+ if(!(flags&FLAG_ZERO_FONT))
+ writer_writeString(&i->w, font_id);
dumpColor(&i->w, &i->state, color);
dumpMatrix(&i->w, &i->state, matrix);
dumpColor(&i->w, &i->state, color);
dumpMatrix(&i->w, &i->state, matrix);
+
+ if(i->state.last_string[OP_DRAWCHAR])
+ free(i->state.last_string[OP_DRAWCHAR]);
i->state.last_string[OP_DRAWCHAR] = strdup(font_id);
i->state.last_string[OP_DRAWCHAR] = strdup(font_id);
+
i->state.last_color[OP_DRAWCHAR] = *color;
i->state.last_matrix[OP_DRAWCHAR] = *matrix;
} else {
i->state.last_color[OP_DRAWCHAR] = *color;
i->state.last_matrix[OP_DRAWCHAR] = *matrix;
} else {
@@
-634,18
+662,20
@@
static void record_drawlink(struct _gfxdevice*dev, gfxline_t*line, const char*ac
/* ------------------------------- replaying --------------------------------- */
/* ------------------------------- replaying --------------------------------- */
-static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
+static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r, gfxfontlist_t**fontlist)
{
internal_t*i = 0;
if(dev) {
i = (internal_t*)dev->internal;
}
{
internal_t*i = 0;
if(dev) {
i = (internal_t*)dev->internal;
}
+ gfxfontlist_t*_fontlist=0;
+ if(!fontlist) {
+ fontlist = &_fontlist;
+ }
state_t state;
memset(&state, 0, sizeof(state));
state_t state;
memset(&state, 0, sizeof(state));
- gfxfontlist_t* fontlist = gfxfontlist_create();
-
while(1) {
unsigned char op;
if(r->read(r, &op, 1)!=1)
while(1) {
unsigned char op;
if(r->read(r, &op, 1)!=1)
@@
-768,37
+798,42
@@
static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
case OP_ADDFONT: {
msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name);
gfxfont_t*font = readFont(r, &state);
case OP_ADDFONT: {
msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name);
gfxfont_t*font = readFont(r, &state);
- fontlist = gfxfontlist_addfont(fontlist, font);
- out->addfont(out, font);
+ if(!gfxfontlist_hasfont(*fontlist, font)) {
+ *fontlist = gfxfontlist_addfont(*fontlist, font);
+ out->addfont(out, font);
+ } else {
+ gfxfont_free(font);
+ }
break;
}
case OP_DRAWCHAR: {
U32 glyph = reader_readU32(r);
gfxmatrix_t m = {1,0,0, 0,1,0};
break;
}
case OP_DRAWCHAR: {
U32 glyph = reader_readU32(r);
gfxmatrix_t m = {1,0,0, 0,1,0};
- char* id = read_string(r, &state, op, flags);
+ char* id = 0;
+ if(!(flags&FLAG_ZERO_FONT))
+ id = read_string(r, &state, op, flags);
gfxcolor_t color = read_color(r, &state, op, flags);
gfxmatrix_t matrix = read_matrix(r, &state, op, flags);
gfxcolor_t color = read_color(r, &state, op, flags);
gfxmatrix_t matrix = read_matrix(r, &state, op, flags);
- gfxfont_t*font = id?gfxfontlist_findfont(fontlist, id):0;
+ gfxfont_t*font = id?gfxfontlist_findfont(*fontlist, id):0;
if(i && !font) {
font = gfxfontlist_findfont(i->fontlist, id);
}
msg("<trace> replay: DRAWCHAR font=%s glyph=%d", id, glyph);
out->drawchar(out, font, glyph, &color, &matrix);
if(i && !font) {
font = gfxfontlist_findfont(i->fontlist, id);
}
msg("<trace> replay: DRAWCHAR font=%s glyph=%d", id, glyph);
out->drawchar(out, font, glyph, &color, &matrix);
- free(id);
+ if(id)
+ free(id);
break;
}
}
}
finish:
break;
}
}
}
finish:
+ state_clear(&state);
r->dealloc(r);
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);
+ if(_fontlist)
+ gfxfontlist_free(_fontlist, 0);
}
}
-void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device)
+void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device, gfxfontlist_t**fontlist)
{
internal_result_t*i = (internal_result_t*)result->internal;
{
internal_result_t*i = (internal_result_t*)result->internal;
@@
-809,7
+844,7
@@
void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device)
reader_init_memreader(&r, i->data, i->length);
}
reader_init_memreader(&r, i->data, i->length);
}
- replay(0, device, &r);
+ replay(0, device, &r, fontlist);
}
static void record_result_write(gfxresult_t*r, int filedesc)
}
static void record_result_write(gfxresult_t*r, int filedesc)
@@
-884,7
+919,7
@@
static void hexdumpMem(unsigned char*data, int len)
}
}
}
}
-void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out)
+void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out, gfxfontlist_t**fontlist)
{
internal_t*i = (internal_t*)dev->internal;
if(out) {
{
internal_t*i = (internal_t*)dev->internal;
if(out) {
@@
-893,7
+928,7
@@
void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out)
void*data = writer_growmemwrite_memptr(&i->w, &len);
reader_t r;
reader_init_memreader(&r, data, len);
void*data = writer_growmemwrite_memptr(&i->w, &len);
reader_t r;
reader_init_memreader(&r, data, len);
- replay(dev, out, &r);
+ replay(dev, out, &r, fontlist);
writer_growmemwrite_reset(&i->w);
} else {
msg("<fatal> Flushing not supported for file based record device");
writer_growmemwrite_reset(&i->w);
} else {
msg("<fatal> Flushing not supported for file based record device");
@@
-911,6
+946,8
@@
static gfxresult_t* record_finish(struct _gfxdevice*dev)
msg("<error> Warning: unclosed cliplevels");
}
msg("<error> Warning: unclosed cliplevels");
}
+ state_clear(&i->state);
+
#ifdef STATS
int total = i->w.pos;
if(total && i->use_tempfile) {
#ifdef STATS
int total = i->w.pos;
if(total && i->use_tempfile) {