static void draw_char(SWFFONT * f, int nr, float*row, float*column, SRECT b) { SWFGLYPH*g = &f->glyph[nr]; SHAPE2*s = swf_ShapeToShape2(g->shape); SHAPELINE*l = s->lines; int x=0,y=0; while(l) { if(l->type == lineTo) { draw_line_xy(row,column,x,-y,l->x,-l->y,&b); } else if(l->type == splineTo) { double x1=x,x2=l->sx,x3=l->x; double y1=y,y2=l->sy,y3=l->y; double c = fabs(x3-2*x2+x1) + fabs(y3-2*y2+y1); int parts = ((int)(sqrt(c)/6))*2+1; float xx=x1,yy=y1; int t; for(t=1;t<=parts;t++) { float nx = ((t*t*x3 + 2*t*(parts-t)*x2 + (parts-t)*(parts-t)*x1)/(double)(parts*parts)); float ny = ((t*t*y3 + 2*t*(parts-t)*y2 + (parts-t)*(parts-t)*y1)/(double)(parts*parts)); draw_line_xy(row,column,xx,-yy,nx,-ny,&b); xx = nx; yy = ny; } } x = l->x; y = l->y; l = l->next; } swf_Shape2Free(s); free(s); }
void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _depth,U16 _clipdepth) { // renderbuf_internal*i = (renderbuf_internal*)dest->internal; SHAPELINE*line; int x=0,y=0; MATRIX mat = *m; SHAPE2* s2 = 0; SHAPE2* lshape = 0; renderpoint_t p, lp; U32 clipdepth; double widthmultiply = matrixsize(m); memset(&p, 0, sizeof(renderpoint_t)); memset(&lp, 0, sizeof(renderpoint_t)); clipdepth = _clipdepth? _clipdepth << 16 | 0xffff : 0; p.depth = _depth << 16; mat.tx -= dest->posx*20; mat.ty -= dest->posy*20; s2 = swf_Shape2Clone(shape); line = s2->lines; if(shape->numfillstyles) { int t; p.s = s2; /* multiply fillstyles matrices with placement matrix- important for texture and gradient fill */ for(t=0;t<s2->numfillstyles;t++) { MATRIX nm; swf_MatrixJoin(&nm, &mat, &s2->fillstyles[t].m); /*nm.sx *= i->multiply; nm.sy *= i->multiply; nm.r0 *= i->multiply; nm.r1 *= i->multiply; nm.tx *= i->multiply; nm.ty *= i->multiply;*/ s2->fillstyles[t].m = nm; } } if(shape->numlinestyles) { lshape = linestyle2fillstyle(shape); lp.s = lshape; lp.depth = (_depth << 16)+1; } while(line) { int x1,y1,x2,y2,x3,y3; if(line->type == moveTo) { } else if(line->type == lineTo) { transform_point(&mat, x, y, &x1, &y1); transform_point(&mat, line->x, line->y, &x3, &y3); if(line->linestyle && ! clipdepth) { lp.shapeline = &lshape->lines[line->linestyle-1]; add_solidline(dest, x1, y1, x3, y3, shape->linestyles[line->linestyle-1].width * widthmultiply, &lp); lp.depth++; } if(line->fillstyle0 || line->fillstyle1) { assert(shape->numfillstyles); p.shapeline = line; add_line(dest, x1, y1, x3, y3, &p); } } else if(line->type == splineTo) { int c,t,parts;//,qparts; double xx,yy; transform_point(&mat, x, y, &x1, &y1); transform_point(&mat, line->sx, line->sy, &x2, &y2); transform_point(&mat, line->x, line->y, &x3, &y3); c = abs(x3-2*x2+x1) + abs(y3-2*y2+y1); xx=x1; yy=y1; parts = (int)(sqrt((float)c)/3); if(!parts) parts = 1; for(t=1;t<=parts;t++) { double nx = (double)(t*t*x3 + 2*t*(parts-t)*x2 + (parts-t)*(parts-t)*x1)/(double)(parts*parts); double ny = (double)(t*t*y3 + 2*t*(parts-t)*y2 + (parts-t)*(parts-t)*y1)/(double)(parts*parts); if(line->linestyle && ! clipdepth) { lp.shapeline = &lshape->lines[line->linestyle-1]; add_solidline(dest, xx, yy, nx, ny, shape->linestyles[line->linestyle-1].width * widthmultiply, &lp); lp.depth++; } if(line->fillstyle0 || line->fillstyle1) { assert(shape->numfillstyles); p.shapeline = line; add_line(dest, xx, yy, nx, ny, &p); } xx = nx; yy = ny; } } x = line->x; y = line->y; line = line->next; } swf_Process(dest, clipdepth); if(s2) { swf_Shape2Free(s2); rfx_free(s2);s2=0; } if(lshape) { swf_Shape2Free(lshape); rfx_free(lshape);lshape=0; } }
int swf_FontExtract_DefineFont2(int id, SWFFONT *font, TAG *tag) { int t, glyphcount; int maxcode; int fid; uint32_t offset_start; uint32_t *offset; uint8_t flags1, /*langcode, */namelen; swf_SetTagPos(tag, 0); font->version = tag->id == ST_DEFINEFONT3 ? 3 : 2; fid = swf_GetU16(tag); if (id && id != fid) return id; font->id = fid; flags1 = swf_GetU8(tag); /*langcode = */swf_GetU8(tag); //reserved flags if (flags1 & 1) font->style |= FONT_STYLE_BOLD; if (flags1 & 2) font->style |= FONT_STYLE_ITALIC; if (flags1 & 16) font->encoding |= FONT_ENCODING_ANSI; if (flags1 & 32) font->encoding |= FONT_ENCODING_UNICODE; if (flags1 & 64) font->encoding |= FONT_ENCODING_SHIFTJIS; namelen = swf_GetU8(tag); font->name = (uint8_t *) malloc(namelen + 1); font->name[namelen] = 0; swf_GetBlock(tag, font->name, namelen); glyphcount = swf_GetU16(tag); font->numchars = glyphcount; font->glyph = (SWFGLYPH *) calloc(1, sizeof(SWFGLYPH) * glyphcount); font->glyph2ascii = (uint16_t *) calloc(1, sizeof(uint16_t) * glyphcount); offset = (uint32_t*)calloc(1, sizeof(uint32_t)*(glyphcount + 1)); offset_start = tag->pos; if (flags1 & 8) { // wide offsets for (t = 0; t < glyphcount; t++) offset[t] = swf_GetU32(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ offset[glyphcount] = swf_GetU32(tag); // fontcodeoffset else offset[glyphcount] = tag->pos; } else { for (t = 0; t < glyphcount; t++) offset[t] = swf_GetU16(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ offset[glyphcount] = swf_GetU16(tag); // fontcodeoffset else offset[glyphcount] = tag->pos; } for (t = 0; t < glyphcount; t++) { swf_SetTagPos(tag, offset[t] + offset_start); swf_GetSimpleShape(tag, &(font->glyph[t].shape)); } if (glyphcount) swf_SetTagPos(tag, offset[glyphcount] + offset_start); free(offset); maxcode = 0; for (t = 0; t < glyphcount; t++) { int code; if (flags1 & 4) // wide codes (always on for definefont3) code = swf_GetU16(tag); else code = swf_GetU8(tag); font->glyph2ascii[t] = code; if (code > maxcode) maxcode = code; } maxcode++; if (maxcode < 256) maxcode = 256; font->maxascii = maxcode; font->ascii2glyph = (int *) malloc(sizeof(int) * maxcode); memset(font->ascii2glyph, -1, sizeof(int) * maxcode); for (t = 0; t < glyphcount; t++) { font->ascii2glyph[font->glyph2ascii[t]] = t; } if (flags1 & 128) { // has layout uint16_t kerningcount; font->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT)); font->layout->ascent = swf_GetU16(tag); font->layout->descent = swf_GetU16(tag); font->layout->leading = swf_GetU16(tag); for (t = 0; t < glyphcount; t++) { int16_t advance = swf_GetS16(tag); font->glyph[t].advance = advance; } font->layout->bounds = (SRECT*)malloc(glyphcount * sizeof(SRECT)); for (t = 0; t < glyphcount; t++) { swf_ResetReadBits(tag); swf_GetRect(tag, &font->layout->bounds[t]); SRECT b = font->layout->bounds[t]; if ((b.xmin | b.xmax | b.ymin | b.ymax) == 0) { // recalculate bounding box SHAPE2 *shape2 = swf_ShapeToShape2(font->glyph[t].shape); font->layout->bounds[t] = swf_GetShapeBoundingBox(shape2); swf_Shape2Free(shape2); free(shape2); } } kerningcount = swf_GetU16(tag); font->layout->kerningcount = kerningcount; font->layout->kerning = (SWFKERNING *) malloc(sizeof(SWFKERNING) * kerningcount); if (kerningcount) { font->layout->kerning = (SWFKERNING*)malloc(sizeof(*font->layout->kerning) * kerningcount); for (t = 0; t < kerningcount; t++) { if (flags1 & 4) { // wide codes font->layout->kerning[t].char1 = swf_GetU16(tag); font->layout->kerning[t].char2 = swf_GetU16(tag); } else { font->layout->kerning[t].char1 = swf_GetU8(tag); font->layout->kerning[t].char2 = swf_GetU8(tag); } font->layout->kerning[t].adjustment = swf_GetS16(tag); } } } return font->id; }