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

📄 swfdec_shape.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 3 页
字号:
    else      swfdec_path_line_to (&path->path, *x, *y);  } else {    SWFDEC_ERROR ("no path to line in");  }}static SubPath *swfdec_shape_parse_change (SwfdecSwfDecoder *s, SwfdecShape *shape, GArray *path_array, SubPath *path,    int *x, int *y, SwfdecPatternFunc parse_fill, SwfdecStrokeFunc parse_stroke){  int state_new_styles, state_line_styles, state_fill_styles1, state_fill_styles0, state_moveto;  SwfdecBits *bits = &s->b;  if (swfdec_bits_getbit (bits) != 0) {    g_assert_not_reached ();  }  state_new_styles = swfdec_bits_getbit (bits);  state_line_styles = swfdec_bits_getbit (bits);  state_fill_styles1 = swfdec_bits_getbit (bits);  state_fill_styles0 = swfdec_bits_getbit (bits);  state_moveto = swfdec_bits_getbit (bits);  if (path) {    path->x_end = *x;    path->y_end = *y;  }  g_array_set_size (path_array, path_array->len + 1);  path = &g_array_index (path_array, SubPath, path_array->len - 1);  if (path_array->len > 1)    *path = g_array_index (path_array, SubPath, path_array->len - 2);  swfdec_path_init (&path->path);  if (state_moveto) {    int n_bits = swfdec_bits_getbits (bits, 5);    *x = swfdec_bits_getsbits (bits, n_bits);    *y = swfdec_bits_getsbits (bits, n_bits);    SWFDEC_LOG ("   moveto %d,%d", *x, *y);  }  path->x_start = *x;  path->y_start = *y;  if (state_fill_styles0) {    path->fill0style = swfdec_bits_getbits (bits, shape->n_fill_bits);    if (path->fill0style)      path->fill0style += shape->fills_offset;    SWFDEC_LOG ("   * fill0style = %d", path->fill0style);  } else {    SWFDEC_LOG ("   * not changing fill0style");  }  if (state_fill_styles1) {    path->fill1style = swfdec_bits_getbits (bits, shape->n_fill_bits);    if (path->fill1style)      path->fill1style += shape->fills_offset;    SWFDEC_LOG ("   * fill1style = %d", path->fill1style);  } else {    SWFDEC_LOG ("   * not changing fill1style");  }  if (state_line_styles) {    path->linestyle = swfdec_bits_getbits (bits, shape->n_line_bits);    if (path->linestyle)      path->linestyle += shape->lines_offset;    SWFDEC_LOG ("   * linestyle = %d", path->linestyle);  } else {    SWFDEC_LOG ("   * not changing linestyle");  }  if (state_new_styles) {    guint old_fills_offset = shape->fills_offset;    guint old_lines_offset = shape->lines_offset;    SWFDEC_LOG ("   * new styles");    swfdec_shape_add_styles (s, shape, parse_fill, parse_stroke);    if (path->fill0style)      path->fill0style += shape->fills_offset - old_fills_offset;    if (path->fill1style)      path->fill1style += shape->fills_offset - old_fills_offset;    if (path->linestyle)      path->linestyle += shape->lines_offset - old_lines_offset;  }  return path;}static voidswfdec_shape_initialize_from_sub_paths (SwfdecShape *shape, GArray *path_array){  guint i;#if 0  g_print ("\n\n");  for (i = 0; i < path_array->len; i++) {    SubPath *path = &g_array_index (path_array, SubPath, i);    g_print ("%d %d => %d %d  -  %u %u %u\n", path->x_start, path->y_start, path->x_end, path->y_end,	path->fill0style, path->fill1style, path->linestyle);  }#endif  swfdec_shape_accumulate_fills (shape, (SubPath *) path_array->data, path_array->len);  swfdec_shape_accumulate_lines (shape, (SubPath *) path_array->data, path_array->len);  for (i = 0; i < path_array->len; i++) {    swfdec_path_reset (&g_array_index (path_array, SubPath, i).path);  }  g_array_free (path_array, TRUE);  g_array_sort (shape->vecs, swfdec_shape_vec_compare);  for (i = 0; i < shape->vecs->len; i++) {    SwfdecShapeVec *vec = &g_array_index (shape->vecs, SwfdecShapeVec, i);    swfdec_pattern_get_path_extents (vec->pattern, &vec->path, &vec->extents);    swfdec_rect_union (&SWFDEC_GRAPHIC (shape)->extents, &SWFDEC_GRAPHIC (shape)->extents, &vec->extents);  }}voidswfdec_shape_get_recs (SwfdecSwfDecoder * s, SwfdecShape * shape,    SwfdecPatternFunc pattern_func, SwfdecStrokeFunc stroke_func){  int x = 0, y = 0;  SubPath *path = NULL;  GArray *path_array;  SwfdecShapeType type;  SwfdecBits *bits = &s->b;  /* First, accumulate all sub-paths into an array */  path_array = g_array_new (FALSE, TRUE, sizeof (SubPath));  while ((type = swfdec_shape_peek_type (bits))) {    switch (type) {      case SWFDEC_SHAPE_TYPE_CHANGE:	path = swfdec_shape_parse_change (s, shape, path_array, path, &x, &y, pattern_func, stroke_func);	break;      case SWFDEC_SHAPE_TYPE_LINE:	swfdec_shape_parse_line (bits, path, &x, &y, FALSE);	break;      case SWFDEC_SHAPE_TYPE_CURVE:	swfdec_shape_parse_curve (bits, path, &x, &y);	break;      case SWFDEC_SHAPE_TYPE_END:      default:	g_assert_not_reached ();	break;    }  }  if (path) {    path->x_end = x;    path->y_end = y;  }  swfdec_bits_getbits (bits, 6);  swfdec_bits_syncbits (bits);  swfdec_shape_initialize_from_sub_paths (shape, path_array);}/*** MORPH SHAPE ***/#include "swfdec_morphshape.h"static SubPath *swfdec_morph_shape_do_change (SwfdecBits *end_bits, SubPath *other, SwfdecMorphShape *morph,     GArray *path_array, SubPath *path, int *x, int *y){  if (path) {    path->x_end = *x;    path->y_end = *y;  }  g_array_set_size (path_array, path_array->len + 1);  path = &g_array_index (path_array, SubPath, path_array->len - 1);  *path = *other;  swfdec_path_init (&path->path);  if (swfdec_shape_peek_type (end_bits) == SWFDEC_SHAPE_TYPE_CHANGE) {    int state_line_styles, state_fill_styles1, state_fill_styles0, state_moveto;    if (swfdec_bits_getbit (end_bits) != 0) {      g_assert_not_reached ();    }    if (swfdec_bits_getbit (end_bits)) {      SWFDEC_ERROR ("new styles aren't allowed in end edges, ignoring");    }    state_line_styles = swfdec_bits_getbit (end_bits);    state_fill_styles1 = swfdec_bits_getbit (end_bits);    state_fill_styles0 = swfdec_bits_getbit (end_bits);    state_moveto = swfdec_bits_getbit (end_bits);    if (state_moveto) {      int n_bits = swfdec_bits_getbits (end_bits, 5);      *x = swfdec_bits_getsbits (end_bits, n_bits);      *y = swfdec_bits_getsbits (end_bits, n_bits);      SWFDEC_LOG ("   moveto %d,%d", *x, *y);    }    if (state_fill_styles0) {      guint check = swfdec_bits_getbits (end_bits, morph->n_fill_bits) + 	SWFDEC_SHAPE (morph)->fills_offset;      if (check != path->fill0style)	SWFDEC_ERROR ("end fill0style %u differs from start fill0style %u", check, path->fill0style);    }    if (state_fill_styles1) {      guint check = swfdec_bits_getbits (end_bits, morph->n_fill_bits) + 	SWFDEC_SHAPE (morph)->fills_offset;      if (check != path->fill1style)	SWFDEC_ERROR ("end fill1style %u differs from start fill1style %u", check, path->fill1style);    }    if (state_line_styles) {      guint check = swfdec_bits_getbits (end_bits, morph->n_line_bits) + 	SWFDEC_SHAPE (morph)->lines_offset;      if (check != path->linestyle)	SWFDEC_ERROR ("end linestyle %u differs from start linestyle %u", check, path->linestyle);    }  }  path->x_start = *x;  path->y_start = *y;  return path;}static voidswfdec_morph_shape_get_recs (SwfdecSwfDecoder * s, SwfdecMorphShape *morph, SwfdecBits *end_bits){  int start_x = 0, start_y = 0, end_x = 0, end_y = 0;  SubPath *start_path = NULL, *end_path = NULL;  GArray *start_path_array, *end_path_array, *tmp;  SwfdecShapeType start_type, end_type;  SwfdecBits *start_bits = &s->b;  SwfdecShape *shape = SWFDEC_SHAPE (morph);  /* First, accumulate all sub-paths into an array */  start_path_array = g_array_new (FALSE, TRUE, sizeof (SubPath));  end_path_array = g_array_new (FALSE, TRUE, sizeof (SubPath));  while ((start_type = swfdec_shape_peek_type (start_bits))) {    end_type = swfdec_shape_peek_type (end_bits);    if (end_type == SWFDEC_SHAPE_TYPE_CHANGE && start_type != SWFDEC_SHAPE_TYPE_CHANGE) {      SubPath *path;      if (start_path) {	start_path->x_end = start_x;	start_path->y_end = start_y;      }      g_array_set_size (start_path_array, start_path_array->len + 1);      path = &g_array_index (start_path_array, SubPath, start_path_array->len - 1);      if (start_path)	*path = *start_path;      start_path = path;      swfdec_path_init (&start_path->path);      start_path->x_start = start_x;      start_path->y_start = start_y;      end_path = swfdec_morph_shape_do_change (end_bits, start_path, morph, end_path_array, end_path, &end_x, &end_y);      continue;    }    switch (start_type) {      case SWFDEC_SHAPE_TYPE_CHANGE:	start_path = swfdec_shape_parse_change (s, shape, start_path_array, start_path, &start_x, &start_y, 	    swfdec_pattern_parse_morph, swfdec_stroke_parse_morph);	end_path = swfdec_morph_shape_do_change (end_bits, start_path, morph, end_path_array, end_path, &end_x, &end_y);	break;      case SWFDEC_SHAPE_TYPE_LINE:	if (end_type == SWFDEC_SHAPE_TYPE_LINE) {	  swfdec_shape_parse_line (start_bits, start_path, &start_x, &start_y, FALSE);	  swfdec_shape_parse_line (end_bits, end_path, &end_x, &end_y, FALSE);	} else if (end_type == SWFDEC_SHAPE_TYPE_CURVE) {	  swfdec_shape_parse_line (start_bits, start_path, &start_x, &start_y, TRUE);	  swfdec_shape_parse_curve (end_bits, end_path, &end_x, &end_y);	} else {	  SWFDEC_ERROR ("edge type didn't match, wanted line or curve, but got %s",	      end_type ? "change" : "end");	  goto error;	}	break;      case SWFDEC_SHAPE_TYPE_CURVE:	swfdec_shape_parse_curve (start_bits, start_path, &start_x, &start_y);	if (end_type == SWFDEC_SHAPE_TYPE_LINE) {	  swfdec_shape_parse_line (end_bits, end_path, &end_x, &end_y, TRUE);	} else if (end_type == SWFDEC_SHAPE_TYPE_CURVE) {	  swfdec_shape_parse_curve (end_bits, end_path, &end_x, &end_y);	} else {	  SWFDEC_ERROR ("edge type didn't match, wanted line or curve, but got %s",	      end_type ? "change" : "end");	  goto error;	}	break;      case SWFDEC_SHAPE_TYPE_END:      default:	g_assert_not_reached ();	break;    }  }  if (start_path) {    start_path->x_end = start_x;    start_path->y_end = start_y;  }  if (end_path) {    end_path->x_end = end_x;    end_path->y_end = end_y;  }  swfdec_bits_getbits (start_bits, 6);  swfdec_bits_syncbits (start_bits);  if (swfdec_bits_getbits (end_bits, 6) != 0) {    SWFDEC_ERROR ("end shapes are not finished when start shapes are");  }  swfdec_bits_syncbits (end_bits);error:  /* FIXME: there's probably a problem if start and end paths get accumulated in    * different ways, this could lead to the morphs not looking like they should.    * Need a good testcase for this first though.   * FIXME: Also, due to error handling, there needs to be syncing of code paths   */  tmp = shape->vecs;  shape->vecs = morph->end_vecs;  swfdec_shape_initialize_from_sub_paths (shape, end_path_array);  morph->end_vecs = shape->vecs;  shape->vecs = tmp;  swfdec_shape_initialize_from_sub_paths (shape, start_path_array);  g_assert (morph->end_vecs->len == shape->vecs->len);}inttag_define_morph_shape (SwfdecSwfDecoder * s, guint tag){  SwfdecBits end_bits;  SwfdecBits *bits = &s->b;  SwfdecMorphShape *morph;  guint offset;  int id;  id = swfdec_bits_get_u16 (bits);  morph = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_MORPH_SHAPE);  if (!morph)    return SWFDEC_STATUS_OK;  SWFDEC_INFO ("id=%d", id);  swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (morph)->extents);  swfdec_bits_get_rect (bits, &morph->end_extents);  offset = swfdec_bits_get_u32 (bits);  end_bits = *bits;  if (swfdec_bits_skip_bytes (&end_bits, offset) != offset) {    SWFDEC_ERROR ("wrong offset in DefineMorphShape");    return SWFDEC_STATUS_OK;  }  bits->end = end_bits.ptr;  swfdec_shape_add_styles (s, SWFDEC_SHAPE (morph),      swfdec_pattern_parse_morph, swfdec_stroke_parse_morph);  morph->n_fill_bits = swfdec_bits_getbits (&end_bits, 4);  morph->n_line_bits = swfdec_bits_getbits (&end_bits, 4);  SWFDEC_LOG ("%u fill bits, %u line bits in end shape", morph->n_fill_bits, morph->n_line_bits);  swfdec_morph_shape_get_recs (s, morph, &end_bits);  if (swfdec_bits_left (&s->b)) {    SWFDEC_WARNING ("early finish when parsing start shapes: %u bytes",        swfdec_bits_left (&s->b));  }  s->b = end_bits;  return SWFDEC_STATUS_OK;}

⌨️ 快捷键说明

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