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

📄 fad.morph.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.morph.c,v 1.32 2006/03/07 10:17:57 wrxzzj Exp $ */#include "fad.morph.h"#include "fad.bits.h"typedef fill_style_array_t morph_fill_style_array_t;typedef line_style_array_t morph_line_style_array_t;typedef struct {  u16_t fs_num, ls_num;  dynarray_t* dict;  morph_sr_node_list_t **array;} morph_shape_record_t;typedef struct {  fad_object_t base;  rect_t start_bound, end_bound;  morph_fill_style_array_t mfsa;  morph_line_style_array_t mlsa;  morph_shape_record_t msr;} morph_shape_t;static cairo_pattern_t *pat = NULL;static cairo_surface_t *ips = NULL;static void _morph_line_style_do_render(fad_render_t* render, line_style_array_t* mlsa, u16_t idx, u16_t ratio) {  u8_t *ptr = NULL;  u16_t sw, ew;  bits_t bits;  u8_t r, g, b, a;  if(mlsa && idx <= mlsa->count && idx) {    ptr = mlsa->array + (idx-1)*12;    bits_init(&bits);    bits_buffer(&bits, ptr);    sw = bits_get_u16(&bits);    ew = bits_get_u16(&bits);    sw = sw+(((ew-sw)*ratio+0x8000)>>16);    if(sw < 2) sw = 2;    cairo_set_line_width(render->cr, (double)sw/20);     r = *(ptr+4); g = *(ptr+5); b = *(ptr+6); a = *(ptr+7);    r +=  ((*(ptr+8)-r)*ratio+0x8000)>>16;    g +=  ((*(ptr+9)-g)*ratio+0x8000)>>16;    b +=  ((*(ptr+10)-b)*ratio+0x8000)>>16;    a +=  ((*(ptr+11)-a)*ratio+0x8000)>>16;    FAD_DEBUG("set morph line style, r = %d, g = %d, b = %d, a = %d\n", r, g, b, a);    cairo_set_source_rgba(render->cr, (double)r/0xff, (double)g/0xff, (double)b/0xff, (double)a/0xff);  }}static void _calc_matrix_by_ratio(bits_t* bits, cairo_matrix_t* mx, u16_t ratio) {  cairo_matrix_t emx, smx;  double rate = (double)ratio/0xffff;  bits_get_matrix(bits, &smx);  bits_get_matrix(bits, &emx);  mx->xx = smx.xx + (emx.xx-smx.xx)*rate;  mx->yy = smx.yy + (emx.yy-smx.yy)*rate;  mx->yx = smx.yx + (emx.yx-smx.yx)*rate;  mx->xy = smx.xy + (emx.xy-smx.xy)*rate;  mx->x0 = smx.x0 + (emx.x0-smx.x0)*rate;  mx->y0 = smx.y0 + (emx.y0-smx.y0)*rate;}static void _morph_fill_style_do_render(fad_render_t* render, fill_style_array_t* mfsa, u16_t idx, dynarray_t* dict, u16_t ratio) {  u8_t* ptr = NULL;  u8_t r, g, b, a, type;  bits_t bits;  cairo_matrix_t mx;  if(mfsa && idx <= mfsa->count && idx) {    bits_init(&bits);    ptr = mfsa->array[idx-1];    switch(type = *ptr++) {      case 0x00:        r = *ptr; g = *(ptr+1); b = *(ptr+2); a = *(ptr+3);        r += ((*(ptr+4)-r)*ratio+0x8000)>>16;        g += ((*(ptr+5)-g)*ratio+0x8000)>>16;        b += ((*(ptr+6)-b)*ratio+0x8000)>>16;        a += ((*(ptr+7)-a)*ratio+0x8000)>>16;        FAD_DEBUG("set morph fill color style, r = %d, g = %d, b = %d, a = %d\n", r, g, b, a);        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 = 0, sr, er, r, g, b, a;          u32_t sc, ec;          if(pat != NULL)            cairo_pattern_destroy(pat);          bits_buffer(&bits, ptr);          _calc_matrix_by_ratio(&bits, &mx, ratio);          if(type == 0x10)            pat = cairo_pattern_create_linear(-16384.00/20.00, 0.00, 16384.00/20.00, 0.00);          else            pat = cairo_pattern_create_radial(0.00, 0.00, 0.00, 0.00, 0.00, 16384.00/20.00);          for(num = bits_get_u8(&bits); num > 0; num--) {            sr = bits_get_u8(&bits); sc = bits_get_u32(&bits);            er = bits_get_u8(&bits); ec = bits_get_u32(&bits);            sr += ((er-sr)*ratio>>16);            sc += ((ec-sc)*ratio>>16);            r = sc>>24; g = (sc&0xff0000)>>16; b = (sc&0xff00)>>8; a = sc&0xff;            cairo_pattern_add_color_stop_rgba(pat, (double)sr/0xff,                 (double)r/0xff, (double)g/0xff, (double)b/0xff, (double)a/0xff);          }          cairo_matrix_invert(&mx);          cairo_pattern_set_matrix(pat, &mx);          cairo_set_source(render->cr, pat);          bits_finish(&bits);        }        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(fo && fo->get_image) {            s32_t w, h;            void* image = fo->get_image(fo, &w, &h);            if(pat != NULL)              cairo_pattern_destroy(pat);            if(ips != NULL)              cairo_surface_destroy(ips);            if(image) {              _calc_matrix_by_ratio(&bits, &mx, ratio);              mx.xx = mx.xx/20.00;              mx.yy = mx.yy/20.00;              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);            }          }        }        break;      default:        FAD_ERROR("morph.shape fill style error\n");        break;    }    bits_finish(&bits);  }}static void _morph_line_style_array_decode(line_style_array_t* mlsa, bits_t* bits) {  mlsa->count = bits_get_u8(bits);  if(mlsa->count == 0xFF)    mlsa->count = bits_get_u16(bits);  mlsa->array = (u8_t* )bits_tell(bits);  if(mlsa->count > 0)    bits_seek_nbytes(bits, mlsa->count*12);}static void _morph_fill_style_array_decode(fill_style_array_t* mfsa, bits_t* bits) {  u16_t idx = 0;  u8_t style_flag;  mfsa->count = bits_get_u8(bits);  if(mfsa->count == 0xFF)    mfsa->count = bits_get_u16(bits);  if(mfsa->count > 0) {    mfsa->array = calloc(mfsa->count, sizeof(u8_t* ));    do {      mfsa->array[idx] = (u8_t* )bits_tell(bits);      switch(style_flag = bits_get_u8(bits)) {        case 0x00:          bits_seek_nbytes(bits, 8);          break;        case 0x10:        case 0x12:          bits_get_matrix(bits, NULL);          bits_get_matrix(bits, NULL);          bits_seek_nbytes(bits, 10*bits_get_u8(bits));          break;        case 0x40:        case 0x41:        case 0x42:        case 0x43:          bits_seek_nbytes(bits, 2);          bits_get_matrix(bits, NULL);          bits_get_matrix(bits, NULL);          break;      }    } while(++idx < mfsa->count);  }}static void _morph_shape_record_render_node_list(morph_sr_node_list_t *mnl, fad_render_t *render, u16_t ratio) {  morph_sr_node_t *hdr = NULL;  s32_t x, y;#define RATIO(val) (((val*ratio)+0x8000)>>16)  hdr = mnl->header;  if(hdr == NULL)    return;  x = hdr->sx0+RATIO(hdr->ox0); y = hdr->sy0+RATIO(hdr->oy0);#ifdef LIBFAD_DO_RENDER  cairo_move_to(render->cr, x/20.00, y/20.00);  FAD_ERROR("move to(%f, %f)\n", x/20.00, y/20.00);#endif  hdr = hdr->next;  while(hdr != NULL) {    if(hdr->type == FAD_SRT_LPT) {      x = hdr->sx0+RATIO(hdr->ox0); y = hdr->sy0+RATIO(hdr->oy0);#ifdef LIBFAD_DO_RENDER      cairo_line_to(render->cr, x/20.00, y/20.00);      FAD_ERROR("line to(%f, %f)\n", x/20.00, y/20.00);#endif    } else {      s32_t x0, y0, x1, y1;#ifdef LIBFAD_DO_RENDER      x0 = hdr->sx1+RATIO(hdr->ox1); y0 = hdr->sy1+RATIO(hdr->oy1);      x1 = hdr->sx0+RATIO(hdr->ox0); y1 = hdr->sy0+RATIO(hdr->oy0);      cairo_curve_to(render->cr, (x+((x0-x)<<1)/3)/20.00, (y+((y0-y)<<1)/3)/20.00,          (x0+(x1-x0)/3)/20.00, (y0+(y1-y0)/3)/20.00, x1/20.00, y1/20.00);      x = x1; y = y1;#endif    }    hdr = hdr->next;  }}static void _morph_shape_core_do_render(fad_render_t* render, morph_shape_t *ms, dl_node_t *node) {  u16_t idx, total = ms->msr.fs_num + ms->msr.ls_num+2;  for(idx=1; idx<total; idx++) {    morph_sr_node_list_t *mnlptr = ms->msr.array[idx];    if(mnlptr == NULL) continue;    do {      FAD_ERROR("render node list = %x, idx = %d\n", mnlptr, idx);      _morph_shape_record_render_node_list(mnlptr, render, node->ratio);      mnlptr = mnlptr->next;    } while(mnlptr != ms->msr.array[idx]);    if(node->flag&0x40)      break;#ifdef LIBFAD_DO_RENDER    if (idx <= ms->msr.fs_num) {      _morph_fill_style_do_render(render, &ms->mfsa, idx, ms->msr.dict, node->ratio);      cairo_fill(render->cr);    } else {      _morph_line_style_do_render(render, &ms->mlsa, idx-ms->mfsa.count, node->ratio);      cairo_stroke(render->cr);    }#endif  }}static u8_t _morph_shape_do_render(fad_object_t* fo, fad_render_t* render, dl_node_t *node) {  morph_shape_t* ms = (morph_shape_t* )fo;  _morph_shape_core_do_render(render, ms, node);  return FAD_TRUE;}static void _morph_shape_record_free(morph_shape_record_t *msr) {}static void morph_sr_node_list_destroy(morph_sr_node_list_t *nl) {  morph_sr_node_t *ptr = NULL, *tmp = NULL;  for(ptr = nl->header; ptr != NULL; ) {    tmp = ptr;    ptr = ptr->next;    free(tmp);    tmp = NULL;  }}static void _morph_shape_do_free(fad_object_t* fo) {  morph_shape_t* ms = (morph_shape_t* )fo;  u16_t idx, total = 0;    if(ms != NULL) {    if(ms->mfsa.count > 0)      free(ms->mfsa.array);    total = ms->msr.fs_num + 1 + ms->msr.ls_num + 1;    for(idx=0; idx<total; idx++) {      if(ms->msr.array[idx]) {        morph_sr_node_list_destroy(ms->msr.array[idx]);        free(ms->msr.array[idx]);        ms->msr.array[idx] = NULL;      }    }  }}static s32_t _morph_shape_record_init(morph_shape_record_t *msr, u16_t fs_num, u16_t ls_num) {  msr->fs_num = fs_num;  msr->ls_num = ls_num;  msr->array  = (morph_sr_node_list_t **)calloc(fs_num+1+ls_num+1, sizeof(morph_sr_node_list_t*));  if(msr->array) {    u16_t idx = 0;    for(; idx<fs_num+1+ls_num+1; idx++) {      msr->array[idx] = NULL;    }    return 0;  }  return -1;}morph_sr_node_t* morph_sr_node_copy(morph_sr_node_t *msn) {  morph_sr_node_t *new = NULL;  new = calloc(1, sizeof(morph_sr_node_t));  new->type = msn->type;  new->sx0 = msn->sx0; new->sx1 = msn->sx1;  new->sy0 = msn->sy0; new->sy1 = msn->sy1;  new->ox0 = msn->ox0; new->ox1 = msn->ox1;  new->oy0 = msn->oy0; new->oy1 = msn->oy1;  return new;}morph_sr_node_t* morph_sr_node_lpt_new(s32_t sx, s32_t sy, s32_t ex, s32_t ey) {  morph_sr_node_t *msn = NULL;  msn = calloc(1, sizeof(morph_sr_node_t));  msn->sx0 = sx; msn->sy0 = sy;  msn->ox0 = ex-sx; msn->oy0 = ey-sy;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -