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

📄 swfdec_pattern.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Swfdec * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library 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 * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include "swfdec_pattern.h"#include "swfdec_bits.h"#include "swfdec_color.h"#include "swfdec_debug.h"#include "swfdec_decoder.h"#include "swfdec_image.h"#include "swfdec_stroke.h"/*** PATTERN ***/G_DEFINE_ABSTRACT_TYPE (SwfdecPattern, swfdec_pattern, G_TYPE_OBJECT);static voidswfdec_pattern_class_init (SwfdecPatternClass *klass){}static voidswfdec_pattern_init (SwfdecPattern *pattern){  cairo_matrix_init_identity (&pattern->start_transform);  cairo_matrix_init_identity (&pattern->end_transform);}/*** COLOR PATTERN ***/typedef struct _SwfdecColorPattern SwfdecColorPattern;typedef struct _SwfdecColorPatternClass SwfdecColorPatternClass;#define SWFDEC_TYPE_COLOR_PATTERN                    (swfdec_color_pattern_get_type())#define SWFDEC_IS_COLOR_PATTERN(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_COLOR_PATTERN))#define SWFDEC_IS_COLOR_PATTERN_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_COLOR_PATTERN))#define SWFDEC_COLOR_PATTERN(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_COLOR_PATTERN, SwfdecColorPattern))#define SWFDEC_COLOR_PATTERN_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_COLOR_PATTERN, SwfdecColorPatternClass))#define SWFDEC_COLOR_PATTERN_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_COLOR_PATTERN, SwfdecColorPatternClass))struct _SwfdecColorPattern{  SwfdecPattern		pattern;  SwfdecColor		start_color;		/* color to paint with at the beginning */  SwfdecColor		end_color;		/* color to paint with in the end */};struct _SwfdecColorPatternClass{  SwfdecPatternClass	pattern_class;};GType swfdec_color_pattern_get_type (void);G_DEFINE_TYPE (SwfdecColorPattern, swfdec_color_pattern, SWFDEC_TYPE_PATTERN);static cairo_pattern_t *swfdec_color_pattern_get_pattern (SwfdecPattern *pat,     const SwfdecColorTransform *trans, guint ratio){  SwfdecColorPattern *pattern = SWFDEC_COLOR_PATTERN (pat);  SwfdecColor color;  color = swfdec_color_apply_morph (pattern->start_color, pattern->end_color, ratio);  color = swfdec_color_apply_transform (color, trans);  return cairo_pattern_create_rgba (       SWFDEC_COLOR_R (color) / 255.0, SWFDEC_COLOR_G (color) / 255.0,      SWFDEC_COLOR_B (color) / 255.0, SWFDEC_COLOR_A (color) / 255.0);}static voidswfdec_color_pattern_class_init (SwfdecColorPatternClass *klass){  SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_color_pattern_get_pattern;}static voidswfdec_color_pattern_init (SwfdecColorPattern *pattern){}/*** IMAGE PATTERN ***/typedef struct _SwfdecImagePattern SwfdecImagePattern;typedef struct _SwfdecImagePatternClass SwfdecImagePatternClass;#define SWFDEC_TYPE_IMAGE_PATTERN                    (swfdec_image_pattern_get_type())#define SWFDEC_IS_IMAGE_PATTERN(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_IMAGE_PATTERN))#define SWFDEC_IS_IMAGE_PATTERN_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_IMAGE_PATTERN))#define SWFDEC_IMAGE_PATTERN(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_IMAGE_PATTERN, SwfdecImagePattern))#define SWFDEC_IMAGE_PATTERN_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_IMAGE_PATTERN, SwfdecImagePatternClass))#define SWFDEC_IMAGE_PATTERN_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_IMAGE_PATTERN, SwfdecImagePatternClass))struct _SwfdecImagePattern{  SwfdecPattern		pattern;  SwfdecImage *		image;		/* image to paint */  cairo_extend_t	extend;  cairo_filter_t	filter;};struct _SwfdecImagePatternClass{  SwfdecPatternClass	pattern_class;};GType swfdec_image_pattern_get_type (void);G_DEFINE_TYPE (SwfdecImagePattern, swfdec_image_pattern, SWFDEC_TYPE_PATTERN);static cairo_pattern_t *swfdec_image_pattern_get_pattern (SwfdecPattern *pat,     const SwfdecColorTransform *trans, guint ratio){  SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat);  cairo_pattern_t *pattern;  cairo_matrix_t mat;  cairo_surface_t *surface;    surface = swfdec_image_create_surface_transformed (image->image, trans);  if (surface == NULL)    return NULL;  pattern = cairo_pattern_create_for_surface (surface);  cairo_surface_destroy (surface);  swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio);  cairo_pattern_set_matrix (pattern, &mat);  cairo_pattern_set_extend (pattern, image->extend);  cairo_pattern_set_filter (pattern, image->filter);  return pattern;}static voidswfdec_image_pattern_class_init (SwfdecImagePatternClass *klass){  SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_image_pattern_get_pattern;}static voidswfdec_image_pattern_init (SwfdecImagePattern *pattern){}/*** GRADIENT PATTERN ***/typedef struct _SwfdecGradientPattern SwfdecGradientPattern;typedef struct _SwfdecGradientPatternClass SwfdecGradientPatternClass;#define SWFDEC_TYPE_GRADIENT_PATTERN                    (swfdec_gradient_pattern_get_type())#define SWFDEC_IS_GRADIENT_PATTERN(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GRADIENT_PATTERN))#define SWFDEC_IS_GRADIENT_PATTERN_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GRADIENT_PATTERN))#define SWFDEC_GRADIENT_PATTERN(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPattern))#define SWFDEC_GRADIENT_PATTERN_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))#define SWFDEC_GRADIENT_PATTERN_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))struct _SwfdecGradientPattern{  SwfdecPattern		pattern;  SwfdecGradient *	gradient;		/* gradient to paint */  gboolean		radial;			/* TRUE for radial gradient, FALSE for linear gradient */  gboolean		morph;			/* TRUE for morph gradients */  double		focus;			/* focus point */};struct _SwfdecGradientPatternClass{  SwfdecPatternClass	pattern_class;};GType swfdec_gradient_pattern_get_type (void);G_DEFINE_TYPE (SwfdecGradientPattern, swfdec_gradient_pattern, SWFDEC_TYPE_PATTERN);static cairo_pattern_t *swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat,     const SwfdecColorTransform *trans, guint ratio){  guint i;  cairo_pattern_t *pattern;  SwfdecColor color;  double offset;  SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat);#if 0  /* use this when https://bugs.freedesktop.org/show_bug.cgi?id=8341 is fixed */  if (gradient->radial)    pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 16384);  else    pattern = cairo_pattern_create_linear (-16384.0, 0, 16384.0, 0);  cairo_pattern_set_matrix (pattern, &pat->transform);#else  {    cairo_matrix_t mat;    swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio);    if (gradient->radial) {      pattern = cairo_pattern_create_radial ((16384.0 / 256.0) * gradient->focus, 	  0, 0, 0, 0, 16384 / 256.0);    } else {      pattern = cairo_pattern_create_linear (-16384.0 / 256.0, 0, 16384.0 / 256.0, 0);    }    cairo_matrix_scale (&mat, 1 / 256.0, 1 / 256.0);    mat.x0 /= 256.0;    mat.y0 /= 256.0;    cairo_pattern_set_matrix (pattern, &mat);  }#endif  if (gradient->morph) {    for (i = 0; i < gradient->gradient->n_gradients; i += 2){      color = swfdec_color_apply_morph (gradient->gradient->array[i].color,	  gradient->gradient->array[i + 1].color, ratio);      color = swfdec_color_apply_transform (color, trans);      offset = gradient->gradient->array[i].ratio * (65535 - ratio) +	      gradient->gradient->array[i + 1].ratio * ratio;      offset /= 65535 * 255;      cairo_pattern_add_color_stop_rgba (pattern, offset,	  SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,	  SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);    }  } else {    for (i = 0; i < gradient->gradient->n_gradients; i++){      color = swfdec_color_apply_transform (gradient->gradient->array[i].color,	  trans);      offset = gradient->gradient->array[i].ratio / 255.0;      cairo_pattern_add_color_stop_rgba (pattern, offset,	  SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,	  SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);    }  }  return pattern;}static voidswfdec_gradient_pattern_dispose (GObject *object){  SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (object);  g_free (gradient->gradient);  gradient->gradient = NULL;  G_OBJECT_CLASS (swfdec_gradient_pattern_parent_class)->dispose (object);}static voidswfdec_gradient_pattern_class_init (SwfdecGradientPatternClass *klass){  G_OBJECT_CLASS (klass)->dispose = swfdec_gradient_pattern_dispose;  SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_gradient_pattern_get_pattern;}static voidswfdec_gradient_pattern_init (SwfdecGradientPattern *pattern){}/*** EXPORTED API ***/static SwfdecPattern *swfdec_pattern_do_parse (SwfdecSwfDecoder *dec, gboolean rgba){  guint paint_style_type;  SwfdecBits *bits;  SwfdecPattern *pattern;  bits = &dec->b;  paint_style_type = swfdec_bits_get_u8 (bits);  SWFDEC_LOG ("    type 0x%02x", paint_style_type);  if (paint_style_type == 0x00) {    pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL);    if (rgba) {      SWFDEC_COLOR_PATTERN (pattern)->start_color = swfdec_bits_get_rgba (bits);    } else {      SWFDEC_COLOR_PATTERN (pattern)->start_color = swfdec_bits_get_color (bits);    }    SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color;    SWFDEC_LOG ("    color %08x", SWFDEC_COLOR_PATTERN (pattern)->start_color);  } else if (paint_style_type == 0x10 || paint_style_type == 0x12 || paint_style_type == 0x13) {    SwfdecGradientPattern *gradient;    pattern = g_object_new (SWFDEC_TYPE_GRADIENT_PATTERN, NULL);    gradient = SWFDEC_GRADIENT_PATTERN (pattern);    swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);    pattern->end_transform = pattern->start_transform;    if (rgba) {      gradient->gradient = swfdec_bits_get_gradient_rgba (bits);    } else {      gradient->gradient = swfdec_bits_get_gradient (bits);    }    gradient->radial = (paint_style_type != 0x10);    /* FIXME: need a way to ensure 0x13 only happens in Flash 8 */    if (paint_style_type == 0x13) {      gradient->focus = swfdec_bits_get_s16 (bits) / 256.0;    }  } else if (paint_style_type >= 0x40 && paint_style_type <= 0x43) {    guint paint_id = swfdec_bits_get_u16 (bits);    SWFDEC_LOG ("   background paint id = %d (type 0x%02x)",	paint_id, paint_style_type);    if (paint_id == 65535) {      /* FIXME: someone explain this magic paint id here */      pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL);      SWFDEC_COLOR_PATTERN (pattern)->start_color = SWFDEC_COLOR_COMBINE (0, 255, 255, 255);      SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color;      swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);      pattern->end_transform = pattern->start_transform;    } else {      pattern = g_object_new (SWFDEC_TYPE_IMAGE_PATTERN, NULL);      swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);      pattern->end_transform = pattern->start_transform;      SWFDEC_IMAGE_PATTERN (pattern)->image = swfdec_swf_decoder_get_character (dec, paint_id);      if (!SWFDEC_IS_IMAGE (SWFDEC_IMAGE_PATTERN (pattern)->image)) {

⌨️ 快捷键说明

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