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

📄 swfdec_movie.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 2 页
字号:
voidswfdec_movie_get_mouse (SwfdecMovie *movie, double *x, double *y){  SwfdecPlayer *player;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  g_return_if_fail (x != NULL);  g_return_if_fail (y != NULL);  player = SWFDEC_ROOT_MOVIE (movie->root)->player;  *x = player->mouse_x;  *y = player->mouse_y;  swfdec_movie_global_to_local (movie, x, y);}voidswfdec_movie_send_mouse_change (SwfdecMovie *movie, gboolean release){  double x, y;  gboolean mouse_in;  int button;  SwfdecMovieClass *klass;  swfdec_movie_get_mouse (movie, &x, &y);  if (release) {    mouse_in = FALSE;    button = 0;  } else {    mouse_in = swfdec_movie_mouse_in (movie, x, y);    button = SWFDEC_ROOT_MOVIE (movie->root)->player->mouse_button;  }  klass = SWFDEC_MOVIE_GET_CLASS (movie);  g_assert (klass->mouse_change != NULL);  klass->mouse_change (movie, x, y, mouse_in, button);}SwfdecMovie *swfdec_movie_get_movie_at (SwfdecMovie *movie, double x, double y){  GList *walk, *clip_walk;  int clip_depth = 0;  SwfdecMovie *ret;  SwfdecMovieClass *klass;  SWFDEC_LOG ("%s %p getting mouse at: %g %g", G_OBJECT_TYPE_NAME (movie), movie, x, y);  if (!swfdec_rect_contains (&movie->extents, x, y)) {    return NULL;  }  cairo_matrix_transform_point (&movie->inverse_matrix, &x, &y);  /* first check if the movie can handle mouse events, and if it can,   * ignore its children.   * Dunno if that's correct */  klass = SWFDEC_MOVIE_GET_CLASS (movie);  if (klass->mouse_change) {    if (swfdec_movie_mouse_in (movie, x, y))      return movie;    else      return NULL;  }  for (walk = clip_walk = g_list_last (movie->list); walk; walk = walk->prev) {    SwfdecMovie *child = walk->data;    if (walk == clip_walk) {      clip_depth = 0;      for (clip_walk = clip_walk->prev; clip_walk; clip_walk = clip_walk->prev) {	SwfdecMovie *clip = walk->data;	if (clip->content->clip_depth) {	  double tmpx = x, tmpy = y;	  cairo_matrix_transform_point (&clip->inverse_matrix, &tmpx, &tmpy);	  if (!swfdec_movie_mouse_in (clip, tmpx, tmpy)) {	    SWFDEC_LOG ("skipping depth %d to %d due to clipping", clip->content->depth, clip->content->clip_depth);	    clip_depth = child->content->clip_depth;	  }	  break;	}      }    }    if (child->content->clip_depth) {      SWFDEC_LOG ("resetting clip depth");      clip_depth = 0;      continue;    }    if (child->depth <= clip_depth && clip_depth) {      SWFDEC_DEBUG ("ignoring depth=%d, it's clipped (clip_depth %d)", child->depth, clip_depth);      continue;    }    if (!child->visible) {      SWFDEC_LOG ("child %s %s (depth %d) is invisible, ignoring", G_OBJECT_TYPE_NAME (movie), movie->name, movie->depth);      continue;    }    ret = swfdec_movie_get_movie_at (child, x, y);    if (ret)      return ret;  }  return NULL;}voidswfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,    const SwfdecColorTransform *color_transform, const SwfdecRect *inval, gboolean fill){  SwfdecMovieClass *klass;  GList *g;  int clip_depth = 0;  SwfdecColorTransform trans;  SwfdecRect rect;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  g_return_if_fail (cr != NULL);  if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {    g_warning ("%s", cairo_status_to_string (cairo_status (cr)));  }  g_return_if_fail (color_transform != NULL);  g_return_if_fail (inval != NULL);    if (!swfdec_rect_intersect (NULL, &movie->extents, inval)) {    SWFDEC_LOG ("not rendering %s %s, extents %g %g  %g %g are not in invalid area %g %g  %g %g",	G_OBJECT_TYPE_NAME (movie), movie->name, 	movie->extents.x0, movie->extents.y0, movie->extents.x1, movie->extents.y1,	inval->x0, inval->y0, inval->x1, inval->y1);    return;  }  if (!movie->visible) {    SWFDEC_LOG ("not rendering %s %p, movie is invisible",	G_OBJECT_TYPE_NAME (movie), movie->name);    return;  }  cairo_save (cr);  SWFDEC_LOG ("transforming movie, transform: %g %g  %g %g   %g %g",      movie->matrix.xx, movie->matrix.yy,      movie->matrix.xy, movie->matrix.yx,      movie->matrix.x0, movie->matrix.y0);  cairo_transform (cr, &movie->matrix);  swfdec_rect_transform (&rect, inval, &movie->inverse_matrix);  SWFDEC_LOG ("%sinvalid area is now: %g %g  %g %g",  movie->parent ? "  " : "",      rect.x0, rect.y0, rect.x1, rect.y1);  swfdec_color_transform_chain (&trans, &movie->content->color_transform, color_transform);  swfdec_color_transform_chain (&trans, &movie->color_transform, &trans);  for (g = movie->list; g; g = g_list_next (g)) {    SwfdecMovie *child = g->data;    if (child->content->clip_depth) {      if (clip_depth) {	/* FIXME: is clipping additive? */	SWFDEC_INFO ("unsetting clip depth %d for new clip depth", clip_depth);	cairo_restore (cr);	clip_depth = 0;      }      if (fill == FALSE) {	SWFDEC_WARNING ("clipping inside clipping not implemented");      } else {	/* FIXME FIXME FIXME: overlapping objects in the clip movie cause problems	 * due to them being accumulated with CAIRO_FILL_RULE_EVEN_ODD	 */	SWFDEC_INFO ("clipping up to depth %d by using %p with depth %d", child->content->clip_depth,	    child, child->depth);	clip_depth = child->content->clip_depth;	cairo_save (cr);	swfdec_movie_render (child, cr, &trans, &rect, FALSE);	cairo_clip (cr);	continue;      }    }    if (clip_depth && child->depth > clip_depth) {      SWFDEC_INFO ("unsetting clip depth %d for depth %d", clip_depth, child->depth);      clip_depth = 0;      cairo_restore (cr);    }    SWFDEC_LOG ("rendering %p with depth %d", child, child->depth);    swfdec_movie_render (child, cr, &trans, &rect, fill);  }  if (clip_depth) {    SWFDEC_INFO ("unsetting clip depth %d after rendering", clip_depth);    clip_depth = 0;    cairo_restore (cr);  }  klass = SWFDEC_MOVIE_GET_CLASS (movie);  if (klass->render)    klass->render (movie, cr, &trans, &rect, fill);#if 0  /* code to draw a red rectangle around the area occupied by this movie clip */  {    double x = 1.0, y = 0.0;    cairo_transform (cr, &movie->inverse_transform);    cairo_user_to_device_distance (cr, &x, &y);    cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);    cairo_set_line_width (cr, 1 / sqrt (x * x + y * y));    cairo_rectangle (cr, object->extents.x0 + 10, object->extents.y0 + 10,	object->extents.x1 - object->extents.x0 - 20,	object->extents.y1 - object->extents.y0 - 20);    cairo_stroke (cr);  }#endif  if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {    g_warning ("error rendering with cairo: %s", cairo_status_to_string (cairo_status (cr)));  }  cairo_restore (cr);}static voidswfdec_movie_dispose (GObject *object){  SwfdecMovie * movie = SWFDEC_MOVIE (object);  g_assert (movie->list == NULL);  g_assert (movie->content == &default_content);  SWFDEC_LOG ("disposing movie %s", movie->name);  g_free (movie->name);  if (movie->parent)    g_object_unref (movie->parent);  G_OBJECT_CLASS (swfdec_movie_parent_class)->dispose (G_OBJECT (movie));}static gbooleanswfdec_movie_iterate_end (SwfdecMovie *movie){  return movie->parent == NULL || 	 g_list_find (movie->parent->list, movie) != NULL;}static JSObject *swfdec_movie_create_js_object (SwfdecScriptable *script){  /* we create the objects manually and ensure persistence */  g_assert_not_reached ();}extern const JSClass movieclip_class;static voidswfdec_movie_class_init (SwfdecMovieClass * movie_class){  GObjectClass *object_class = G_OBJECT_CLASS (movie_class);  SwfdecScriptableClass *script_class = SWFDEC_SCRIPTABLE_CLASS (movie_class);  object_class->dispose = swfdec_movie_dispose;  script_class->jsclass = &movieclip_class;  script_class->create_js_object = swfdec_movie_create_js_object;  movie_class->iterate_end = swfdec_movie_iterate_end;}static voidswfdec_movie_set_name (SwfdecMovie *movie){  /* FIXME: implement this function in a smarter way, not if (IS_FOO_MOVIE (x)) */  g_assert (movie->name == NULL);  if (movie->content->name) {    movie->name = g_strdup (movie->content->name);    movie->has_name = TRUE;  } else if (SWFDEC_IS_SPRITE_MOVIE (movie)) {    /* FIXME: figure out if it's relative to root or player or something else     * entirely      */    SwfdecRootMovie *root = SWFDEC_ROOT_MOVIE (movie->root);    movie->name = g_strdup_printf ("instance%u", ++root->unnamed_count);    movie->has_name = FALSE;  } else {    movie->name = g_strdup (G_OBJECT_TYPE_NAME (movie));    movie->has_name = FALSE;  }  SWFDEC_LOG ("created movie %s", movie->name);}static voidswfdec_movie_set_parent (SwfdecMovie *movie){  SwfdecMovie *parent = movie->parent;  SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (movie->root)->player;  SwfdecMovieClass *klass;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  if (parent) {    parent->list = g_list_insert_sorted (parent->list, movie, swfdec_movie_compare_depths);    SWFDEC_DEBUG ("inserting %s %p (depth %d) into %s %p", G_OBJECT_TYPE_NAME (movie), movie,	movie->depth,  G_OBJECT_TYPE_NAME (parent), parent);  } else {    player->roots = g_list_insert_sorted (player->roots, movie, swfdec_movie_compare_depths);  }  swfdec_movie_set_name (movie);  klass = SWFDEC_MOVIE_GET_CLASS (movie);  /* 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);  /* we have to create the JSObject here to get actions queued before init_movie executes */  swfdec_js_movie_create_jsobject (movie);  /* queue init and construct events for non-root movies */  if (movie != movie->root) {    g_queue_push_tail (player->init_queue, movie);    g_queue_push_tail (player->construct_queue, movie);  }  if (SWFDEC_IS_DEBUGGER (player))    g_signal_emit_by_name (player, "movie-added", movie);  swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);  if (klass->init_movie)    klass->init_movie (movie);}static voidswfdec_movie_initialize (SwfdecMovie *movie, const SwfdecContent *content){  const SwfdecContent *old;  old = movie->content;  movie->content = content;  movie->depth = content->depth;  swfdec_movie_set_parent (movie);  movie->content = old;  swfdec_movie_set_content (movie, content);}/** * swfdec_movie_new: * @parent: the parent movie that will contain this movie * @content: the content to display * * Creates a new #SwfdecMovie as a child of @parent with the given content. * @parent must not contain a movie clip at the depth specified by @content. * * Returns: a new #SwfdecMovie **/SwfdecMovie *swfdec_movie_new (SwfdecMovie *parent, const SwfdecContent *content){  SwfdecGraphicClass *klass;  SwfdecMovie *ret;  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);  klass = SWFDEC_GRAPHIC_GET_CLASS (content->graphic);  g_return_val_if_fail (klass->create_movie != NULL, NULL);  ret = klass->create_movie (content->graphic);  ret->parent = parent;  SWFDEC_SCRIPTABLE (ret)->jscx = SWFDEC_SCRIPTABLE (parent)->jscx;  g_object_ref (parent);  ret->root = parent->root;  swfdec_movie_initialize (ret, content);  return ret;}SwfdecMovie *swfdec_movie_new_for_player (SwfdecPlayer *player, guint depth){  SwfdecMovie *ret;  SwfdecContent *content;  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);  content = swfdec_content_new ((int) depth - 16384);  content->name = g_strdup_printf ("_level%u", depth);  ret = g_object_new (SWFDEC_TYPE_ROOT_MOVIE, NULL);  g_object_weak_ref (G_OBJECT (ret), (GWeakNotify) swfdec_content_free, content);  SWFDEC_ROOT_MOVIE (ret)->player = player;  SWFDEC_SCRIPTABLE (ret)->jscx = player->jscx;  ret->root = ret;  swfdec_movie_initialize (ret, content);  ret->has_name = FALSE;  return ret;}voidswfdec_movie_goto (SwfdecMovie *movie, guint frame){  SwfdecMovieClass *klass;  g_return_if_fail (SWFDEC_IS_MOVIE (movie));  g_return_if_fail (frame < movie->n_frames);  klass = SWFDEC_MOVIE_GET_CLASS (movie);  if (klass->goto_frame)    klass->goto_frame (movie, frame);}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 + -