📄 fad.shape.c
字号:
/** * libFAD - Flash Animation Decode library * Copyright (C) 2005-2006 VGSystem Technologies, Inc. * * libFAD is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fad.shape.c,v 1.72 2006/05/08 06:58:18 wrxzzj Exp $ */#include "fad.shape.h"#include "fad.tags.h"#include "fad.bits.h"#define FAD_ERRORtypedef struct { fad_object_t base; rect_t bound; shape_record_t sr;} style_shape_t;static u8_t _style_shape_do_render(fad_object_t* fo, fad_render_t* render, dl_node_t *node);static void _style_shape_do_free(fad_object_t* fo);static void _style_shape_get_rect(fad_object_t* fo, rect_t *rt);static cairo_pattern_t *pat = NULL;static cairo_surface_t *ips = NULL;static void _line_style_do_render(fad_render_t* render, line_style_array_t* lsa, u16_t idx, u8_t srv, dl_node_t *node) { u8_t* ptr = NULL, r, g, b, a; u16_t width; if(lsa && idx < lsa->count) { ptr = lsa->array; if(srv == FAD_SRV_SHAPE3) { ptr += idx*6; r = *(ptr+2); g = *(ptr+3); b = *(ptr+4); a = *(ptr+5); if(node->flag&0x08) { r = COLOR_DO_CXFORM(r, node->cx.base.rm, node->cx.base.ra); g = COLOR_DO_CXFORM(g, node->cx.base.gm, node->cx.base.ga); b = COLOR_DO_CXFORM(b, node->cx.base.bm, node->cx.base.ba); a = COLOR_DO_CXFORM(a, node->cx.am, node->cx.aa); } width = *ptr|*(ptr+1)<<8; if(width < 1) width = 1; cairo_set_line_width(render->cr, (double)width/20); } else { ptr += idx*5; r = *(ptr+2); g = *(ptr+3); b = *(ptr+4); a = 0xff; if(node->flag&0x08) { r = COLOR_DO_CXFORM(r, node->cx.base.rm, node->cx.base.ra); g = COLOR_DO_CXFORM(g, node->cx.base.gm, node->cx.base.ga); b = COLOR_DO_CXFORM(b, node->cx.base.bm, node->cx.base.ba); a = COLOR_DO_CXFORM(a, node->cx.am, node->cx.aa); } width = *ptr|*(ptr+1)<<8; if(width < 2) width = 2; cairo_set_line_width(render->cr, (double)width/20); } FAD_ERROR("style-shape set line color(r = %d, g = %d, b = %d, a = %d), line width = %d.\n", r, g, b, a, width); cairo_set_source_rgba(render->cr, (double)r/0xff, (double)g/0xff, (double)b/0xff, (double)a/0xff); }}static void _fill_style_do_render(fad_render_t* render, fill_style_array_t* fsa, u16_t idx, u8_t srv, dynarray_t* dict, dl_node_t *node) { u8_t* ptr = NULL, type, r, g, b, a; bits_t bits; cairo_matrix_t mx; if(fsa && idx < fsa->count) { FAD_ERROR("fill style do render (%d, fsa = %x)\n", idx, fsa); bits_init(&bits); ptr = fsa->array[idx]; switch(type = *ptr++) { case 0x00: r = *ptr; g = *(ptr+1); b = *(ptr+2); a = 0xff; if(srv == FAD_SRV_SHAPE3) a = *(ptr+3); if(node->flag&0x08) { r = COLOR_DO_CXFORM(r, node->cx.base.rm, node->cx.base.ra); g = COLOR_DO_CXFORM(g, node->cx.base.gm, node->cx.base.ga); b = COLOR_DO_CXFORM(b, node->cx.base.bm, node->cx.base.ba); a = COLOR_DO_CXFORM(a, node->cx.am, node->cx.aa); } FAD_ERROR("style-shape set fill color (%d, %d, %d, %d), fsa->count = %d.\n", r, g, b, a, fsa->count); cairo_set_source_rgba(render->cr, (double)r/0xff, (double)g/0xff, (double)b/0xff, (double)a/0xff); break; case 0x10: case 0x12: { u8_t num; if(pat != NULL) { cairo_pattern_destroy(pat); pat = NULL; } bits_buffer(&bits, ptr); bits_get_matrix(&bits, &mx); if(type == 0x10) { pat = cairo_pattern_create_linear(-16384.00/20.00, 0.00, 16384.00/20.00, 0.00); FAD_ERROR("style-shape set fill linear gradient.\n"); } else { pat = cairo_pattern_create_radial(0.00, 0.00, 0.00, 0.00, 0.00, 16384.00/20.00); FAD_ERROR("style-shape set fill radial gradient.\n"); } FAD_ERROR("gradient pattern matrix = (%f, %f, %f, %f, %f, %f)\n", mx.xx, mx.xy, mx.x0, mx.yy, mx.yx, mx.y0); ptr = bits_tell(&bits); for(num = *ptr++; num > 0; num--) { if(srv == FAD_SRV_SHAPE3) { FAD_ERROR("add color stop RGBA(%x, %x, %x, %x)\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4)); cairo_pattern_add_color_stop_rgba(pat, (double)*ptr/0xff, (double)*(ptr+1)/0xff, (double)*(ptr+2)/0xff, (double)*(ptr+3)/0xff, (double)*(ptr+4)/0xff); ptr += 5; } else { FAD_ERROR("add color stop RGB(%x, %x, %x, 0xff)\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3)); cairo_pattern_add_color_stop_rgb(pat, (double)*ptr/0xff, (double)*(ptr+1)/0xff, (double)*(ptr+2)/0xff, (double)*(ptr+3)/0xff); ptr += 4; } } cairo_matrix_invert(&mx); cairo_pattern_set_matrix(pat, &mx); cairo_set_source(render->cr, pat); } break; case 0x40: case 0x41: case 0x42: case 0x43: { fad_object_t* fo = NULL; bits_buffer(&bits, ptr); fo = dict->get(dict, bits_get_u16(&bits));#if 1 if(fo && fo->get_image) { s32_t w, h; cairo_matrix_t mx; void* image = fo->get_image(fo, &w, &h); //FAD_ERROR("style shape set fill bitmap, fo = %x, image = %x\n", fo, image); if(pat != NULL) cairo_pattern_destroy(pat); if(ips != NULL) cairo_surface_destroy(ips); if(image) { bits_get_matrix(&bits, &mx); mx.xx = mx.xx/20.00; mx.yy = mx.yy/20.00; FAD_ERROR("image pattern matrix = (%f, %f, %f, %f, %f, %f), type = %x\n", mx.xx, mx.xy, mx.x0, mx.yy, mx.yx, mx.y0, type); ips = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_ARGB32, w, h, w<<2); pat = cairo_pattern_create_for_surface(ips); if(type == 0x40 || type == 0x42) cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); else cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE); cairo_matrix_invert(&mx); cairo_pattern_set_matrix(pat, &mx); cairo_set_source(render->cr, pat); } }#endif } break; default: FAD_ERROR("style-shape fill style unknown, type = %x\n", type); break; } bits_finish(&bits); }}static u16_t _line_style_array_decode(line_style_array_t* lsa, bits_t* bits, u8_t srv) { u32_t offset = 0; lsa->count = bits_get_u8(bits); lsa->array = NULL; if(lsa->count == 0xFF) lsa->count = bits_get_u16(bits); lsa->array = (u8_t* )bits_tell(bits); FAD_ERROR("line style array count = %d, array = %x\n", lsa->count, lsa->array); if(lsa->count > 0) { if(srv == FAD_SRV_SHAPE3) offset = 6; else offset = 5; offset = offset * lsa->count; bits_seek_nbytes(bits, offset); } return lsa->count;}static u16_t _fill_style_array_decode(fill_style_array_t* fsa, bits_t* bits, u8_t srv) { u16_t idx = 0, offset = 0; fsa->count = bits_get_u8(bits); fsa->array = NULL; if(fsa->count == 0xFF) fsa->count = bits_get_u16(bits); if(fsa->count > 0) { fsa->array = calloc(fsa->count, sizeof(u8_t* )); FAD_ERROR("fill style array count = %d, array = %x\n", fsa->count, fsa->array); do { fsa->array[idx] = (u8_t* )bits_tell(bits); //FAD_ERROR("fill style array[%d] = %x\n", idx, bits_tell(bits)); switch(bits_get_u8(bits)) { case 0x00: if(srv == FAD_SRV_SHAPE3) offset = 4; else offset = 3; bits_seek_nbytes(bits, offset); break; case 0x10: case 0x12: bits_get_matrix(bits, NULL); if(srv == FAD_SRV_SHAPE3) offset = 5; else offset = 4; offset = offset*bits_get_u8(bits); bits_seek_nbytes(bits, offset); break; case 0x40: case 0x41: case 0x42: case 0x43: bits_seek_nbytes(bits, 2); bits_get_matrix(bits, NULL); break; } } while(++idx < fsa->count); } return fsa->count;}s32_t style_shape_decode(fad_frame_t* frame, fad_stream_t* s) { style_shape_t* ss = NULL; u16_t id; ss = calloc(1, sizeof(style_shape_t)); if(ss == NULL) { s->err = FAD_ERROR_MEM; return -1; } ss->base.do_render = _style_shape_do_render; ss->base.do_free = _style_shape_do_free; ss->base.get_rect= _style_shape_get_rect; ss->base.type = FO_TYPE_STYLESHAPE; id = bits_get_u16(&s->bits); bits_get_rect(&s->bits, &ss->bound); ss->sr.dict = s->dict; if(s->tag_id == TAG_DEFINESHAPE) ss->sr.srv = FAD_SRV_SHAPE1; else if(s->tag_id == TAG_DEFINESHAPE2) ss->sr.srv = FAD_SRV_SHAPE2; else if(s->tag_id == TAG_DEFINESHAPE3) ss->sr.srv = FAD_SRV_SHAPE3; shape_record_parse(&s->bits, &ss->sr); s->dict->put(s->dict, ss, id); FAD_ERROR("append style-shape = %x to dictionary, id = %d, tag_id = %d\n", ss, id, s->tag_id); return 0;}static sr_node_t* sr_node_new(s32_t x0, s32_t y0, s32_t x1, s32_t y1, u8_t type) { sr_node_t *node = NULL; node = calloc(1, sizeof(sr_node_t)); node->type = type; node->x0 = x0; node->y0 = y0; node->x1 = x1; node->y1 = y1; node->next = NULL; return node;}static void sr_node_destroy(sr_node_t* node) { if(node != NULL) free(node);}static sr_node_list_t *sr_node_list_new(sr_node_t *node) { sr_node_list_t *nl = NULL; nl = calloc(1, sizeof(sr_node_list_t)); nl->header = node; nl->tail = node; nl->sta = FAD_NLSTA_INIT; return nl;}static void sr_node_list_destroy(sr_node_list_t *nl) { sr_node_t *ptr = NULL, *tmp = NULL; for(ptr = nl->header; ptr != NULL; ) { tmp = ptr; ptr = ptr->next; sr_node_destroy(tmp); tmp = NULL; }}static void sr_node_list_rebuild(sr_node_list_t *nl) { sr_node_t *ptr1 = NULL, *ptr2; if(nl != NULL) { ptr1 = nl->header; ptr2 = ptr1->next; if(ptr1->type == FAD_SRT_CPT && ptr2->type == FAD_SRT_LPT) { ptr2->x1 = ptr1->x1; ptr2->y1 = ptr1->y1; ptr1->x1 = 0; ptr1->y1 = 0; ptr1->type = FAD_SRT_LPT; ptr2->type = FAD_SRT_CPT; } }}static void sr_node_list_append(sr_node_list_t *nl, sr_node_t *node) { if(nl != NULL) { if(nl->header != NULL) { nl->tail->next = node; nl->tail = node; } else { nl->header = node; nl->tail = node; } }}static void sr_node_list_prepend(sr_node_list_t *nl, sr_node_t *node) { if(nl != NULL) { if(nl->header != NULL) { node->next = nl->header; nl->header = node; } else { nl->header = node; nl->tail = node; } }}static void sr_node_list_merge(sr_edgesrecord_t *er, sr_node_list_t *nl, u16_t idx) { sr_node_list_t *ptr = er->array[idx], *tail = NULL; s8_t match = FAD_FALSE; DEBUG_ENTER; if(nl->sta == FAD_NLSTA_INIT) { if(ptr == NULL) { nl->next = nl->prev = nl; ptr = er->array[idx] = nl; } else { tail = ptr->prev; tail->next = nl; ptr->prev = nl; nl->prev = tail; nl->next = ptr; } nl->sta = FAD_NLSTA_OPEN; } for(ptr=nl->next; ptr!=nl; ptr=ptr->next) { if(ptr->sta == FAD_NLSTA_OPEN) { if(ptr->header->x0==nl->tail->x0 && ptr->header->y0==nl->tail->y0) { nl->tail->next = ptr->header->next; free(ptr->header); nl->tail = ptr->tail; ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; if(ptr == er->array[idx]) { er->array[idx] = ptr->next; } free(ptr); ptr = nl; } else if(ptr->tail->x0==nl->header->x0 && ptr->tail->y0==nl->header->y0) { ptr->tail->next = nl->header->next; free(nl->header); ptr->tail = nl->tail; nl->prev->next = nl->next; nl->next->prev = nl->prev; if(nl == er->array[idx]) { er->array[idx] = nl->next; } free(nl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -