void fa_clear(struct fa_t *a) { size_t i; for (i = 0; i < a->num_states; i++) { state_clear(&a->states[i]); } free(a->states); a->states = NULL; }
static gfxresult_t* record_finish(struct _gfxdevice*dev) { internal_t*i = (internal_t*)dev->internal; msg("<trace> record: %08x END", dev); if(i->cliplevel) { msg("<error> Warning: unclosed cliplevels"); } state_clear(&i->state); #ifdef STATS int total = i->w.pos; if(total && i->use_tempfile) { state_t*s = &i->state; msg("<notice> record device finished. stats:"); msg("<notice> %4.1f%% matrices (%d bytes)", s->size_matrices*100.0/total, s->size_matrices); msg("<notice> %4.1f%% positions (%d bytes)", s->size_positions*100.0/total, s->size_positions); msg("<notice> %4.1f%% colors (%d bytes)", s->size_colors*100.0/total, s->size_colors); msg("<notice> %4.1f%% lines (%d bytes)", s->size_lines*100.0/total, s->size_lines); msg("<notice> %4.1f%% fonts (%d bytes)", s->size_fonts*100.0/total, s->size_fonts); msg("<notice> %4.1f%% images (%d bytes)", s->size_images*100.0/total, s->size_images); msg("<notice> %4.1f%% characters (%d bytes)", s->size_chars*100.0/total, s->size_chars); msg("<notice> total: %d bytes", total); } #endif writer_writeU8(&i->w, OP_END); gfxfontlist_free(i->fontlist, 0); internal_result_t*ir = (internal_result_t*)rfx_calloc(sizeof(gfxresult_t)); ir->use_tempfile = i->use_tempfile; if(i->use_tempfile) { ir->filename = i->filename; } else { 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; result->get = record_result_get; result->destroy = record_result_destroy; result->internal = ir; free(dev->internal);memset(dev, 0, sizeof(gfxdevice_t)); return result; }
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; } gfxfontlist_t*_fontlist=0; if(!fontlist) { fontlist = &_fontlist; } state_t state; memset(&state, 0, sizeof(state)); while(1) { unsigned char op; if(r->read(r, &op, 1)!=1) break; unsigned char flags = op&0xf0; op&=0x0f; switch(op) { case OP_END: goto finish; case OP_SETPARAM: { msg("<trace> replay: SETPARAM"); char*key; char*value; key = reader_readString(r); value = reader_readString(r); out->setparameter(out, key, value); free(key); free(value); break; } case OP_STARTPAGE: { msg("<trace> replay: STARTPAGE"); U16 width = reader_readU16(r); U16 height = reader_readU16(r); out->startpage(out, width, height); break; } case OP_ENDPAGE: { msg("<trace> replay: ENDPAGE"); out->endpage(out); break; } case OP_FINISH: { msg("<trace> replay: FINISH"); break; } case OP_STROKE: { msg("<trace> replay: STROKE"); double width = reader_readDouble(r); double miterlimit = reader_readDouble(r); gfxcolor_t color = readColor(r, &state); 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, &state); out->stroke(out, line, width, &color, captype, jointtype,miterlimit); gfxline_free(line); break; } case OP_STARTCLIP: { msg("<trace> replay: STARTCLIP"); gfxline_t* line = readLine(r, &state); out->startclip(out, line); gfxline_free(line); break; } case OP_ENDCLIP: { msg("<trace> replay: ENDCLIP"); out->endclip(out); break; } case OP_FILL: { msg("<trace> replay: FILL"); gfxcolor_t color = readColor(r, &state); gfxline_t* line = readLine(r, &state); out->fill(out, line, &color); gfxline_free(line); break; } case OP_FILLBITMAP: { msg("<trace> replay: FILLBITMAP"); gfximage_t img = readImage(r, &state); gfxmatrix_t matrix = readMatrix(r, &state); gfxline_t* line = readLine(r, &state); gfxcxform_t* cxform = readCXForm(r, &state); out->fillbitmap(out, line, &img, &matrix, cxform); gfxline_free(line); if(cxform) free(cxform); free(img.data);img.data=0; break; } case OP_FILLGRADIENT: { msg("<trace> 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, &state); gfxmatrix_t matrix = readMatrix(r, &state); gfxline_t* line = readLine(r, &state); out->fillgradient(out, line, gradient, type, &matrix); break; } case OP_DRAWLINK: { msg("<trace> replay: DRAWLINK"); gfxline_t* line = readLine(r, &state); char* s = reader_readString(r); out->drawlink(out,line,s); gfxline_free(line); free(s); break; } case OP_ADDFONT: { msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name); gfxfont_t*font = readFont(r, &state); 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}; 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); 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(id) free(id); break; } } } finish: state_clear(&state); r->dealloc(r); if(_fontlist) gfxfontlist_free(_fontlist, 0); }