static gfxcolor_t readColor(reader_t*r, state_t*state) { gfxcolor_t col; col.r = reader_readU8(r); col.g = reader_readU8(r); col.b = reader_readU8(r); col.a = reader_readU8(r); return col; }
static gfxline_t* readLine(reader_t*r, state_t*s) { gfxline_t*start = 0, *pos = 0; while(1) { unsigned char op = reader_readU8(r); if(op == OP_END) break; gfxline_t*line = (gfxline_t*)rfx_calloc(sizeof(gfxline_t)); if(!start) { start = pos = line; } else { pos->next = line; pos = line; } if(op == LINE_MOVETO) { line->type = gfx_moveTo; line->x = reader_readDouble(r); line->y = reader_readDouble(r); } else if(op == LINE_LINETO) { line->type = gfx_lineTo; line->x = reader_readDouble(r); line->y = reader_readDouble(r); } else if(op == LINE_SPLINETO) { line->type = gfx_splineTo; line->x = reader_readDouble(r); line->y = reader_readDouble(r); line->sx = reader_readDouble(r); line->sy = reader_readDouble(r); } } return start; }
unsigned int read_compressed_uint(reader_t*r) { unsigned int u = 0; unsigned int b; do { b = reader_readU8(r); u = u<<7|b&0x7f; } while(b&0x80); return u; }
uint32_t read_compressed_uint(reader_t*r) { uint32_t u = 0; uint32_t b; do { b = reader_readU8(r); u = u<<7|b&0x7f; } while(b&0x80); return u; }
static gfxcxform_t* readCXForm(reader_t*r, state_t*state) { U8 type = reader_readU8(r); if(!type) return 0; 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); c->ar = reader_readFloat(r); c->ag = reader_readFloat(r); c->ab = reader_readFloat(r); c->aa = reader_readFloat(r); return c; }
char*reader_readString(reader_t*r) { writer_t g; writer_init_growingmemwriter(&g, 16); while(1) { U8 b = reader_readU8(r); writer_writeU8(&g, b); if(!b) break; } char*string = (char*)writer_growmemwrite_getmem(&g); g.finish(&g); return string; }
static gfxgradient_t* readGradient(reader_t*r, state_t*state) { gfxgradient_t*start = 0, *pos = 0; while(1) { U8 op = reader_readU8(r); if(!op) break; gfxgradient_t*g = (gfxgradient_t*)rfx_calloc(sizeof(gfxgradient_t)); if(!start) { start = pos = g; } else { pos->next = g; pos = g; } g->color = readColor(r, state); g->pos = reader_readFloat(r); } return start; }
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); }