📄 shape.c
字号:
} shapevec = g_ptr_array_index(shape->fills, shape->fills_offset + fill0style-1); g_array_append_val(shapevec->path,pt); } if(fill1style){ SWF_DEBUG(0," using shapevec %d\n",shape->fills_offset); if(shape->fills_offset + fill1style - 1 >= shape->fills2->len){ SWF_DEBUG(4,"fill0style too large (%d >= %d)\n", shape->fills_offset + fill1style - 1, shape->fills2->len); } shapevec = g_ptr_array_index(shape->fills2, shape->fills_offset + fill1style-1); g_array_append_val(shapevec->path,pt); } if(linestyle){ shapevec = g_ptr_array_index(shape->lines, shape->lines_offset + linestyle-1); g_array_append_val(shapevec->path,pt); } } getbits(bits,6); syncbits(bits); pt.code = ART_END; for(i=0;i<shape->fills->len;i++){ shapevec = g_ptr_array_index(shape->fills,i); g_array_append_val(shapevec->path,pt); shapevec = g_ptr_array_index(shape->fills2,i); g_array_append_val(shapevec->path,pt); } for(i=0;i<shape->lines->len;i++){ shapevec = g_ptr_array_index(shape->lines,i); g_array_append_val(shapevec->path,pt); }}int art_define_shape_2(SwfdecDecoder *s){ return art_define_shape(s);}ArtSVP *art_svp_translate(ArtSVP *svp, double x, double y){ ArtSVP *newsvp; int i, j; newsvp = g_malloc(sizeof(ArtSVP) + sizeof(ArtSVPSeg)*svp->n_segs); newsvp->n_segs = svp->n_segs; for(i=0;i<svp->n_segs;i++){ newsvp->segs[i].n_points = svp->segs[i].n_points; newsvp->segs[i].dir = svp->segs[i].dir; newsvp->segs[i].bbox.x0 = svp->segs[i].bbox.x0 + x; newsvp->segs[i].bbox.x1 = svp->segs[i].bbox.x1 + x; newsvp->segs[i].bbox.y0 = svp->segs[i].bbox.y0 + y; newsvp->segs[i].bbox.y1 = svp->segs[i].bbox.y1 + y; newsvp->segs[i].points = g_new(ArtPoint, svp->segs[i].n_points); for(j=0;j<svp->segs[i].n_points;j++){ newsvp->segs[i].points[j].x = svp->segs[i].points[j].x + x; newsvp->segs[i].points[j].y = svp->segs[i].points[j].y + y; } } return newsvp;}void art_svp_bbox(ArtSVP *svp, ArtIRect *box){ ArtDRect dbox; art_drect_svp(&dbox, svp); box->x0 = floor(dbox.x0); box->x1 = ceil(dbox.x1); box->y0 = floor(dbox.y0); box->y1 = ceil(dbox.y1);}SwfdecLayer *swfdec_shape_prerender(SwfdecDecoder *s,SwfdecSpriteSeg *seg, SwfdecObject *obj, SwfdecLayer *oldlayer){ SwfdecLayer *layer; SwfdecShape *shape = obj->priv; int i; SwfdecLayerVec *layervec; SwfdecShapeVec *shapevec; SwfdecShapeVec *shapevec2; if(oldlayer && oldlayer->seg == seg)return oldlayer; layer = swfdec_layer_new(); layer->seg = seg; art_affine_multiply(layer->transform,seg->transform,s->transform);#if 1 if(oldlayer && oldlayer->seg->id == seg->id && layer->transform[0] == oldlayer->transform[0] && layer->transform[1] == oldlayer->transform[1] && layer->transform[2] == oldlayer->transform[2] && layer->transform[3] == oldlayer->transform[3]){ double x,y; SwfdecLayerVec *oldlayervec; x = layer->transform[4] - oldlayer->transform[4]; y = layer->transform[5] - oldlayer->transform[5]; SWF_DEBUG(0,"translation\n"); g_array_set_size(layer->fills, shape->fills->len); for(i=0;i<shape->fills->len;i++){ oldlayervec = &g_array_index(oldlayer->fills,SwfdecLayerVec,i); layervec = &g_array_index(layer->fills,SwfdecLayerVec,i); shapevec = g_ptr_array_index(shape->fills,i); layervec->svp = art_svp_translate (oldlayervec->svp, x, y); layervec->color = transform_color(shapevec->color, seg->color_mult, seg->color_add); art_svp_bbox(layervec->svp, &layervec->rect); art_irect_union_to_masked(&layer->rect, &layervec->rect, &s->irect); layervec->compose = NULL; if(shapevec->fill_id){ swfdec_shape_compose(s, layervec, shapevec, layer->transform); } if(shapevec->grad){ swfdec_shape_compose_gradient(s, layervec, shapevec, layer->transform, seg); } } g_array_set_size(layer->lines, shape->lines->len); for(i=0;i<shape->lines->len;i++){ oldlayervec = &g_array_index(oldlayer->lines,SwfdecLayerVec,i); layervec = &g_array_index(layer->lines,SwfdecLayerVec,i); shapevec = g_ptr_array_index(shape->lines,i); layervec->svp = art_svp_translate (oldlayervec->svp, x, y); layervec->color = transform_color(shapevec->color, seg->color_mult, seg->color_add); art_svp_bbox(layervec->svp, &layervec->rect); art_irect_union_to_masked(&layer->rect, &layervec->rect, &s->irect); layervec->compose = NULL;#if 0 if(shapevec->fill_id){ swfdec_shape_compose(s, layervec, shapevec, layer->transform); }#endif } return layer; }#endif layer->rect.x0 = 0; layer->rect.x1 = 0; layer->rect.y0 = 0; layer->rect.y1 = 0; g_array_set_size(layer->fills, shape->fills->len); for(i=0;i<shape->fills->len;i++){ ArtVpath *vpath,*vpath0,*vpath1; ArtBpath *bpath0,*bpath1; double trans[6]; layervec = &g_array_index(layer->fills,SwfdecLayerVec,i); shapevec = g_ptr_array_index(shape->fills,i); shapevec2 = g_ptr_array_index(shape->fills2,i); art_affine_copy(trans,layer->transform); if(s->subpixel) art_affine_subpixel(trans); bpath0 = art_bpath_affine_transform( &g_array_index(shapevec->path,ArtBpath,0), trans); bpath1 = art_bpath_affine_transform( &g_array_index(shapevec2->path,ArtBpath,0), trans); vpath0 = art_bez_path_to_vec(bpath0,s->flatness); vpath1 = art_bez_path_to_vec(bpath1,s->flatness); vpath1 = art_vpath_reverse_free(vpath1); vpath = art_vpath_cat(vpath0,vpath1); art_vpath_bbox_irect(vpath, &layervec->rect); layervec->svp = art_svp_from_vpath (vpath); art_svp_make_convex(layervec->svp); art_irect_union_to_masked(&layer->rect, &layervec->rect, &s->irect); art_free(bpath0); art_free(bpath1); art_free(vpath0); art_free(vpath1); art_free(vpath); layervec->color = transform_color(shapevec->color, seg->color_mult, seg->color_add); layervec->compose = NULL; if(shapevec->fill_id){ swfdec_shape_compose(s, layervec, shapevec, layer->transform); } if(shapevec->grad){ swfdec_shape_compose_gradient(s, layervec, shapevec, layer->transform, seg); } } g_array_set_size(layer->lines, shape->lines->len); for(i=0;i<shape->lines->len;i++){ ArtVpath *vpath; ArtBpath *bpath; double width; int half_width; double trans[6]; layervec = &g_array_index(layer->lines,SwfdecLayerVec,i); shapevec = g_ptr_array_index(shape->lines,i); art_affine_copy(trans,layer->transform); if(s->subpixel) art_affine_subpixel(trans); bpath = art_bpath_affine_transform( &g_array_index(shapevec->path,ArtBpath,0), trans); vpath = art_bez_path_to_vec(bpath,s->flatness); art_vpath_bbox_irect(vpath, &layervec->rect); /* FIXME for subpixel */ width = shapevec->width*art_affine_expansion(trans); if(width<1)width=1; half_width = floor(width*0.5) + 1; layervec->rect.x0 -= half_width; layervec->rect.y0 -= half_width; layervec->rect.x1 += half_width; layervec->rect.y1 += half_width; art_irect_union_to_masked(&layer->rect, &layervec->rect, &s->irect); layervec->svp = art_svp_vpath_stroke (vpath, ART_PATH_STROKE_JOIN_ROUND, ART_PATH_STROKE_CAP_ROUND, width, 1.0, s->flatness); art_free(vpath); art_free(bpath); layervec->color = transform_color(shapevec->color, seg->color_mult, seg->color_add); } return layer;}void swfdec_shape_render(SwfdecDecoder *s,SwfdecLayer *layer, SwfdecObject *object){ int i; SwfdecLayerVec *layervec; for(i=0;i<layer->fills->len;i++){ layervec = &g_array_index(layer->fills, SwfdecLayerVec, i); swfdec_layervec_render(s, layervec); } for(i=0;i<layer->lines->len;i++){ layervec = &g_array_index(layer->lines, SwfdecLayerVec, i); swfdec_layervec_render(s, layervec); }}static void swfdec_shape_compose(SwfdecDecoder *s, SwfdecLayerVec *layervec, SwfdecShapeVec *shapevec, double trans[6]){ SwfdecObject *image_object; SwfdecImage *image; double mat[6]; double mat0[6]; int i, j; unsigned char *dest; unsigned char *src; double inv_width, inv_height; int width, height; image_object = swfdec_object_get(s, shapevec->fill_id); if(!image_object)return; SWF_DEBUG(0,"swfdec_shape_compose: %d\n", shapevec->fill_id); layervec->color = SWF_COLOR_COMBINE(255,0,0,255); image = image_object->priv; SWF_DEBUG(0,"image %p\n", image->image_data); SWF_DEBUG(0,"%g %g %g %g %g %g\n", shapevec->fill_matrix[0], shapevec->fill_matrix[1], shapevec->fill_matrix[2], shapevec->fill_matrix[3], shapevec->fill_matrix[4], shapevec->fill_matrix[5]); width = layervec->rect.x1 - layervec->rect.x0; height = layervec->rect.y1 - layervec->rect.y0; layervec->compose = g_malloc(width * height * 4); layervec->compose_rowstride = width * 4; layervec->compose_height = height; layervec->compose_width = width; art_affine_multiply(mat0, shapevec->fill_matrix, trans); /* Need an offset in the compose information */ mat0[4] -= layervec->rect.x0; mat0[5] -= layervec->rect.y0; art_affine_invert(mat, mat0); dest = layervec->compose; src = image->image_data; inv_width = 1.0/image->width; inv_height = 1.0/image->height; for(j=0;j<height;j++){ double x,y; x = mat[2]*j + mat[4]; y = mat[3]*j + mat[5]; for(i=0;i<width;i++){ int ix,iy; ix = x - floor(x*inv_width)*image->width; iy = y - floor(y*inv_height)*image->height;#if 0 if(x<0)x=0; if(x>image->width-1)x=image->width-1; if(y<0)y=0; if(y>image->height-1)y=image->height-1; ix = x; iy = y;#endif#define RGBA8888_COPY(a,b) (*(guint32 *)(a) = *(guint32 *)(b)) RGBA8888_COPY(dest,src+ix*4 + iy*image->rowstride); dest+=4; x += mat[0]; y += mat[1]; } }}static void swfdec_shape_compose_gradient(SwfdecDecoder *s, SwfdecLayerVec *layervec, SwfdecShapeVec *shapevec, double trans[6], SwfdecSpriteSeg *seg){ SwfdecGradient *grad; double mat[6]; double mat0[6]; int i, j; unsigned char *dest; unsigned char *palette; int width, height; SWF_DEBUG(0,"swfdec_shape_compose: %d\n", shapevec->fill_id); grad = shapevec->grad; SWF_DEBUG(0,"%g %g %g %g %g %g\n", shapevec->fill_matrix[0], shapevec->fill_matrix[1], shapevec->fill_matrix[2], shapevec->fill_matrix[3], shapevec->fill_matrix[4], shapevec->fill_matrix[5]); width = layervec->rect.x1 - layervec->rect.x0; height = layervec->rect.y1 - layervec->rect.y0; layervec->compose = g_malloc(width * height * 4); layervec->compose_rowstride = width * 4; layervec->compose_height = height; layervec->compose_width = width; art_affine_multiply(mat0, shapevec->fill_matrix, trans); palette = swfdec_gradient_to_palette(grad, seg->color_mult, seg->color_add); mat0[4] -= layervec->rect.x0; mat0[5] -= layervec->rect.y0; art_affine_invert(mat, mat0); dest = layervec->compose; if(shapevec->fill_type==0x10){ for(j=0;j<height;j++){ double x,y; x = mat[2]*j + mat[4]; y = mat[3]*j + mat[5]; for(i=0;i<width;i++){ double z; int index; z = ((x+16384.0)/32768.0) * 256; if(z<0)z=0; if(z>255.0)z=255; index = z; //index &= 0xff; dest[0] = palette[index*4 + 0]; dest[1] = palette[index*4 + 1]; dest[2] = palette[index*4 + 2]; dest[3] = palette[index*4 + 3]; dest+=4; x += mat[0]; y += mat[1]; } } }else{ for(j=0;j<height;j++){ double x,y; x = mat[2]*j + mat[4]; y = mat[3]*j + mat[5]; for(i=0;i<width;i++){ double z; int index; z = sqrt(x*x+y*y)/16384.0 * 256; if(z<0)z=0; if(z>255.0)z=255; index = z; //index &= 0xff; dest[0] = palette[index*4 + 0]; dest[1] = palette[index*4 + 1]; dest[2] = palette[index*4 + 2]; dest[3] = palette[index*4 + 3]; dest+=4; x += mat[0]; y += mat[1]; } } } g_free(palette);}static unsigned char *swfdec_gradient_to_palette(SwfdecGradient *grad, double *color_mult, double *color_add){ swf_color color; unsigned char *p; int i, j; p = malloc(256*4); color = transform_color(grad->array[0].color, color_mult, color_add); for(i=0;i<grad->array[0].ratio;i++){ p[i*4 + 0] = SWF_COLOR_R(color); p[i*4 + 1] = SWF_COLOR_G(color); p[i*4 + 2] = SWF_COLOR_B(color); p[i*4 + 3] = SWF_COLOR_A(color); } for(j=0;j<grad->n_gradients-1;j++){ double len = grad->array[j+1].ratio - grad->array[j].ratio; double x; swf_color color0 = transform_color(grad->array[j].color, color_mult, color_add); swf_color color1 = transform_color(grad->array[j+1].color, color_mult, color_add); for(i=grad->array[j].ratio;i<grad->array[j+1].ratio;i++){ x = (i-grad->array[j].ratio)/len; p[i*4 + 0] = SWF_COLOR_R(color0) * (1-x) + SWF_COLOR_R(color1) * x; p[i*4 + 1] = SWF_COLOR_G(color0) * (1-x) + SWF_COLOR_G(color1) * x; p[i*4 + 2] = SWF_COLOR_B(color0) * (1-x) + SWF_COLOR_B(color1) * x; p[i*4 + 3] = SWF_COLOR_A(color0) * (1-x) + SWF_COLOR_A(color1) * x; } } color = transform_color(grad->array[j].color, color_mult, color_add); for(i=grad->array[j].ratio;i<256;i++){ p[i*4 + 0] = SWF_COLOR_R(color); p[i*4 + 1] = SWF_COLOR_G(color); p[i*4 + 2] = SWF_COLOR_B(color); p[i*4 + 3] = SWF_COLOR_A(color); } return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -