⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fad.shape.c

📁 嵌入式linux环境下的一个FLASH播放器(支持FLASH7.0以下版本)
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * 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 + -