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

📄 swfdec_movie.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* FIXME: This function can definitely be implemented easier */static SwfdecMovie *swfdec_movie_get_by_name (SwfdecPlayer *player, const char *name){  GList *walk;  int i = SWFDEC_AS_CONTEXT (player)->version;  gulong l;  char *end;  if ((i >= 7 && !g_str_has_prefix (name, "_level")) ||      strncasecmp (name, "_level", 6) != 0)    return NULL;  errno = 0;  l = strtoul (name + 6, &end, 10);  if (errno != 0 || *end != 0 || l > G_MAXINT)    return NULL;  i = l - 16384;  for (walk = player->roots; walk; walk = walk->next) {    SwfdecMovie *cur = walk->data;    if (cur->depth < i)      continue;    if (cur->depth == i)      return cur;    break;  }  return NULL;}static gbooleanswfdec_movie_get_variable (SwfdecAsObject *object, SwfdecAsObject *orig,    const char *variable, SwfdecAsValue *val, guint *flags){  SwfdecMovie *movie = SWFDEC_MOVIE (object);  if (movie->state == SWFDEC_MOVIE_STATE_DESTROYED)    return FALSE;  if (SWFDEC_AS_OBJECT_CLASS (swfdec_movie_parent_class)->get (object, orig, variable, val, flags))    return TRUE;  if (swfdec_movie_get_asprop (movie, variable, val)) {    *flags = 0;    return TRUE;  }  /* FIXME: check that this is correct */  if (object->context->version > 5 && variable == SWFDEC_AS_STR__global) {    SWFDEC_AS_VALUE_SET_OBJECT (val, object->context->global);    *flags = 0;    return TRUE;  }    movie = swfdec_movie_get_by_name (SWFDEC_PLAYER (object->context), variable);  if (movie) {    SWFDEC_AS_VALUE_SET_OBJECT (val, SWFDEC_AS_OBJECT (movie));    *flags = 0;    return TRUE;  }  return FALSE;}static voidswfdec_movie_set_variable (SwfdecAsObject *object, const char *variable,     const SwfdecAsValue *val, guint flags){  SwfdecMovie *movie = SWFDEC_MOVIE (object);  if (movie->state == SWFDEC_MOVIE_STATE_DESTROYED)    return;  if (swfdec_movie_set_asprop (movie, variable, val))    return;  SWFDEC_AS_OBJECT_CLASS (swfdec_movie_parent_class)->set (object, variable, val, flags);}static char *swfdec_movie_get_debug (SwfdecAsObject *object){  SwfdecMovie *movie = SWFDEC_MOVIE (object);  return swfdec_movie_get_path (movie);}static gbooleanswfdec_movie_iterate_end (SwfdecMovie *movie){  return movie->parent == NULL || 	 movie->state < SWFDEC_MOVIE_STATE_REMOVED;}static voidswfdec_movie_class_init (SwfdecMovieClass * movie_class){  GObjectClass *object_class = G_OBJECT_CLASS (movie_class);  SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (movie_class);  object_class->dispose = swfdec_movie_dispose;  object_class->get_property = swfdec_movie_get_property;  object_class->set_property = swfdec_movie_set_property;  asobject_class->mark = swfdec_movie_mark;  asobject_class->get = swfdec_movie_get_variable;  asobject_class->set = swfdec_movie_set_variable;  asobject_class->debug = swfdec_movie_get_debug;  g_object_class_install_property (object_class, PROP_DEPTH,      g_param_spec_int ("depth", "depth", "z order inside the parent",	  G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));  movie_class->iterate_end = swfdec_movie_iterate_end;}voidswfdec_movie_initialize (SwfdecMovie *movie){  SwfdecMovieClass *klass;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  klass = SWFDEC_MOVIE_GET_CLASS (movie);  if (klass->init_movie)    klass->init_movie (movie);}voidswfdec_movie_set_depth (SwfdecMovie *movie, int depth){  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  if (movie->depth == depth)    return;  swfdec_movie_invalidate (movie);  movie->depth = depth;  if (movie->parent) {    movie->parent->list = g_list_sort (movie->parent->list, swfdec_movie_compare_depths);  } else {    SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);    player->roots = g_list_sort (player->roots, swfdec_movie_compare_depths);  }  g_object_notify (G_OBJECT (movie), "depth");}/** * swfdec_movie_new: * @player: a #SwfdecPlayer * @depth: depth of movie * @parent: the parent movie or %NULL to make this a root movie * @graphic: the graphic that is displayed by this movie or %NULL to create an  *           empty movieclip * @name: a garbage-collected string to be used as the name for this movie or  *        %NULL for a default one. * * Creates a new movie #SwfdecMovie for the given properties. No movie may exist * at the given @depth. The actual type of * this movie depends on the @graphic parameter. The movie will be initialized  * with default properties. No script execution will be scheduled. After all  * properties are set, the new-movie signal will be emitted if @player is a  * debugger. * * Returns: a new #SwfdecMovie **/SwfdecMovie *swfdec_movie_new (SwfdecPlayer *player, int depth, SwfdecMovie *parent, SwfdecGraphic *graphic, const char *name){  SwfdecMovie *movie;  gsize size;  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);  g_return_val_if_fail (parent == NULL || SWFDEC_IS_MOVIE (parent), NULL);  g_return_val_if_fail (graphic == NULL || SWFDEC_IS_GRAPHIC (graphic), NULL);  /* create the right movie */  if (graphic == NULL) {    movie = g_object_new (SWFDEC_TYPE_SPRITE_MOVIE, "depth", depth, NULL);    size = sizeof (SwfdecSpriteMovie);  } else {    SwfdecGraphicClass *klass = SWFDEC_GRAPHIC_GET_CLASS (graphic);    g_return_val_if_fail (klass->create_movie != NULL, NULL);    movie = klass->create_movie (graphic, &size);    movie->graphic = g_object_ref (graphic);    movie->depth = depth;  }  /* register it to the VM */  /* FIXME: It'd be nice if we'd not overuse memory here when calling this function from a script */  if (!swfdec_as_context_use_mem (SWFDEC_AS_CONTEXT (player), size)) {    size = 0;  }  g_object_ref (movie);  /* set essential properties */  movie->parent = parent;  if (parent) {    movie->swf = g_object_ref (parent->swf);    parent->list = g_list_insert_sorted (parent->list, movie, swfdec_movie_compare_depths);    SWFDEC_DEBUG ("inserting %s %s (depth %d) into %s %p", G_OBJECT_TYPE_NAME (movie), movie->name,	movie->depth,  G_OBJECT_TYPE_NAME (parent), parent);  } else {    player->roots = g_list_insert_sorted (player->roots, movie, swfdec_movie_compare_depths);  }  /* set its name */  if (name) {    movie->original_name = name;    movie->name = name;  } else {    movie->original_name = SWFDEC_AS_STR_EMPTY;    if (SWFDEC_IS_SPRITE_MOVIE (movie) || SWFDEC_IS_BUTTON_MOVIE (movie)) {      movie->name = swfdec_as_context_give_string (SWFDEC_AS_CONTEXT (player), 	  g_strdup_printf ("instance%u", ++player->unnamed_count));    } else {      movie->name = SWFDEC_AS_STR_EMPTY;    }  }  /* add the movie to the global movies list */  /* NB: adding to the movies list happens before setting the parent.   * Setting the parent does a gotoAndPlay(0) for Sprites which can cause   * new movies to be created (and added to this list)   */  player->movies = g_list_prepend (player->movies, movie);  /* only add the movie here, because it needs to be setup for the debugger */  swfdec_as_object_add (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_CONTEXT (player), size);  return movie;}/* FIXME: since this is only used in PlaceObject, wouldn't it be easier to just have * swfdec_movie_update_static_properties (movie); that's notified when any of these change * and let PlaceObject modify the movie directly? */voidswfdec_movie_set_static_properties (SwfdecMovie *movie, const cairo_matrix_t *transform,    const SwfdecColorTransform *ctrans, int ratio, int clip_depth, SwfdecEventList *events){  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  g_return_if_fail (clip_depth >= -16384 || clip_depth <= 0);  g_return_if_fail (ratio >= -1);  if (movie->modified) {    SWFDEC_LOG ("%s has already been modified by scripts, ignoring updates", movie->name);    return;  }  if (transform) {    movie->original_transform = *transform;    movie->matrix.x0 = movie->original_transform.x0;    movie->matrix.y0 = movie->original_transform.y0;    movie->xscale = swfdec_matrix_get_xscale (&movie->original_transform);    movie->yscale = swfdec_matrix_get_yscale (&movie->original_transform);    movie->rotation = swfdec_matrix_get_rotation (&movie->original_transform);    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);  }  if (ctrans) {    movie->original_ctrans = *ctrans;    swfdec_movie_invalidate (movie);  }  if (ratio >= 0 && (guint) ratio != movie->original_ratio) {    movie->original_ratio = ratio;    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_EXTENTS);  }  if (clip_depth && clip_depth != movie->clip_depth) {    movie->clip_depth = clip_depth;    /* FIXME: is this correct? */    swfdec_movie_invalidate (movie->parent ? movie->parent : movie);  }  if (events) {    if (movie->events)      swfdec_event_list_free (movie->events);    movie->events = swfdec_event_list_copy (events);  }}/** * swfdec_movie_duplicate: * @movie: #SwfdecMovie to copy * @name: garbage-collected name for the new copy * @depth: depth to put this movie in * * Creates a duplicate of @movie. The duplicate will not be initialized or * queued up for any events. You have to do this manually. In particular calling * swfdec_movie_initialize() on the returned movie must be done. * * Returns: a newly created movie or %NULL on error **/SwfdecMovie *swfdec_movie_duplicate (SwfdecMovie *movie, const char *name, int depth){  SwfdecMovie *parent, *copy;  g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), NULL);  g_return_val_if_fail (name != NULL, NULL);  parent = movie->parent;  if (movie->parent == NULL) {    SWFDEC_FIXME ("don't know how to duplicate root movies");    return NULL;  }  copy = swfdec_movie_find (movie->parent, depth);  if (copy) {    SWFDEC_LOG ("depth %d already occupied while duplicating, removing old movie", depth);    swfdec_movie_remove (copy);  }  copy = swfdec_movie_new (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), depth,       parent, movie->graphic, name);  if (copy == NULL)    return NULL;  swfdec_movie_set_static_properties (copy, &movie->original_transform,      &movie->original_ctrans, movie->original_ratio, movie->clip_depth, movie->events);  return copy;}SwfdecMovie *swfdec_movie_new_for_content (SwfdecMovie *parent, const SwfdecContent *content){  SwfdecPlayer *player;  SwfdecMovie *movie;  g_return_val_if_fail (SWFDEC_IS_MOVIE (parent), NULL);  g_return_val_if_fail (SWFDEC_IS_GRAPHIC (content->graphic), NULL);  g_return_val_if_fail (swfdec_movie_find (parent, content->depth) == NULL, NULL);  SWFDEC_DEBUG ("new movie for parent %p", parent);  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (parent)->context);  movie = swfdec_movie_new (player, content->depth, parent, content->graphic,       content->name ? swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (player), content->name) : NULL);  swfdec_movie_set_static_properties (movie, content->has_transform ? &content->transform : NULL,      content->has_color_transform ? &content->color_transform : NULL,       content->ratio, content->clip_depth, content->events);  if (SWFDEC_IS_SPRITE_MOVIE (movie)) {    g_queue_push_tail (player->init_queue, movie);    g_queue_push_tail (player->construct_queue, movie);    swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);  }  swfdec_movie_initialize (movie);  return movie;}voidswfdec_movie_load (SwfdecMovie *movie, const char *url, const char *target,    SwfdecLoaderRequest request, const char *data, gsize data_len){  SwfdecPlayer *player;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  g_return_if_fail (url != NULL);  g_return_if_fail (target != NULL);  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);  /* yay for the multiple uses of GetURL - one of the crappier Flash things */  if (g_str_has_prefix (target, "_level")) {    const char *nr = target + strlen ("_level");    char *end;    guint depth;    errno = 0;    depth = strtoul (nr, &end, 10);    if (errno == 0 && *end == '\0') {      if (url[0] == '\0') {	swfdec_player_remove_level (player, depth);      } else {	SwfdecLoader *loader = swfdec_loader_load (movie->swf->loader, url,	    request, data, data_len);	g_assert (loader);	swfdec_player_add_level_from_loader (player, depth, loader, NULL);      }    } else {      SWFDEC_ERROR ("%s does not specify a valid level", target);    }    /* FIXME: what do we do here? Is returning correct?*/    return;  }  swfdec_player_launch (player, url, target);}char *swfdec_movie_get_path (SwfdecMovie *movie){  GString *s;  g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), NULL);    s = g_string_new ("");  do {    if (movie->parent) {      g_string_prepend (s, movie->name);      g_string_prepend_c (s, '.');    } else {      char *ret = g_strdup_printf ("_level%u%s",	movie->depth + 16384, s->str);      g_string_free (s, TRUE);      return ret;    }    movie = movie->parent;  } while (TRUE);  g_assert_not_reached ();  return NULL;}intswfdec_movie_compare_depths (gconstpointer a, gconstpointer b){  if (SWFDEC_MOVIE (a)->depth < SWFDEC_MOVIE (b)->depth)    return -1;  if (SWFDEC_MOVIE (a)->depth > SWFDEC_MOVIE (b)->depth)    return 1;  return 0;}/** * swfdec_depth_classify: * @depth: the depth to classify * * Classifies a depth. This classification is mostly used when deciding if * certain operations are valid in ActionScript. * * Returns: the classification of the depth. **/SwfdecDepthClassswfdec_depth_classify (int depth){  if (depth < -16384)    return SWFDEC_DEPTH_CLASS_EMPTY;  if (depth < 0)    return SWFDEC_DEPTH_CLASS_TIMELINE;  if (depth < 1048576)    return SWFDEC_DEPTH_CLASS_DYNAMIC;  if (depth < 2130690046)    return SWFDEC_DEPTH_CLASS_RESERVED;  return SWFDEC_DEPTH_CLASS_EMPTY;}

⌨️ 快捷键说明

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