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

📄 swfdec_pattern.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 2 页
字号:
#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"/*** MORPHING ***/static voidswfdec_matrix_morph (cairo_matrix_t *dest, const cairo_matrix_t *start,    const cairo_matrix_t *end, unsigned int ratio){  unsigned int inv_ratio = 65535 - ratio;  g_assert (ratio < 65536);  if (ratio == 0) {    *dest = *start;    return;  }  if (ratio == 65535) {    *dest = *end;    return;  }  dest->xx = (start->xx * inv_ratio + end->xx * ratio) / 65535;  dest->xy = (start->xy * inv_ratio + end->xy * ratio) / 65535;  dest->yy = (start->yy * inv_ratio + end->yy * ratio) / 65535;  dest->yx = (start->yx * inv_ratio + end->yx * ratio) / 65535;  dest->x0 = (start->x0 * inv_ratio + end->x0 * ratio) / 65535;  dest->y0 = (start->y0 * inv_ratio + end->y0 * ratio) / 65535;}/*** 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);}/*** STROKE PATTERN ***/#define MAX_ALIGN 10typedef struct _SwfdecStrokePattern SwfdecStrokePattern;typedef struct _SwfdecStrokePatternClass SwfdecStrokePatternClass;#define SWFDEC_TYPE_STROKE_PATTERN                    (swfdec_stroke_pattern_get_type())#define SWFDEC_IS_STROKE_PATTERN(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_STROKE_PATTERN))#define SWFDEC_IS_STROKE_PATTERN_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_STROKE_PATTERN))#define SWFDEC_STROKE_PATTERN(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePattern))#define SWFDEC_STROKE_PATTERN_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePatternClass))#define SWFDEC_STROKE_PATTERN_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePatternClass))struct _SwfdecStrokePattern{  SwfdecPattern		pattern;  guint			start_width;		/* width of line */  SwfdecColor		start_color;		/* color to paint with */  guint			end_width;		/* width of line */  SwfdecColor		end_color;		/* color to paint with */};struct _SwfdecStrokePatternClass{  SwfdecPatternClass	pattern_class;};G_DEFINE_TYPE (SwfdecStrokePattern, swfdec_stroke_pattern, SWFDEC_TYPE_PATTERN);static voidswfdec_pattern_append_path_snapped (cairo_t *cr, const cairo_path_t *path){  cairo_path_data_t *data;  double x, y;  int i;  data = path->data;  for (i = 0; i < path->num_data; i++) {    switch (data[i].header.type) {      case CAIRO_PATH_MOVE_TO:	i++;	x = data[i].point.x;	y = data[i].point.y;	cairo_user_to_device (cr, &x, &y);	x = rint (x - 0.5) + 0.5;	y = rint (y - 0.5) + 0.5;	cairo_device_to_user (cr, &x, &y);	/* FIXME: currently we need to clamp this due to extents */	x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN);	y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN);	cairo_move_to (cr, x, y);	break;      case CAIRO_PATH_LINE_TO:	i++;	x = data[i].point.x;	y = data[i].point.y;	cairo_user_to_device (cr, &x, &y);	x = rint (x - 0.5) + 0.5;	y = rint (y - 0.5) + 0.5;	cairo_device_to_user (cr, &x, &y);	/* FIXME: currently we need to clamp this due to extents */	x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN);	y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN);	cairo_line_to (cr, x, y);	break;      case CAIRO_PATH_CURVE_TO:	x = data[i+3].point.x;	y = data[i+3].point.y;	cairo_user_to_device (cr, &x, &y);	x = rint (x - 0.5) + 0.5;	y = rint (y - 0.5) + 0.5;	cairo_device_to_user (cr, &x, &y);	/* FIXME: currently we need to clamp this due to extents */	x = CLAMP (x, data[i+3].point.x - MAX_ALIGN, data[i+3].point.x + MAX_ALIGN);	y = CLAMP (y, data[i+3].point.y - MAX_ALIGN, data[i+3].point.y + MAX_ALIGN);	cairo_curve_to (cr, data[i+1].point.x, data[i+1].point.y, 	    data[i+2].point.x, data[i+2].point.y, x, y);	i += 3;	break;      case CAIRO_PATH_CLOSE_PATH:	/* doesn't exist in our code */      default:	g_assert_not_reached ();    }  }}static voidswfdec_stroke_pattern_paint (SwfdecPattern *pattern, cairo_t *cr, const cairo_path_t *path,    const SwfdecColorTransform *trans, unsigned int ratio){  SwfdecColor color;  double width;  SwfdecStrokePattern *stroke = SWFDEC_STROKE_PATTERN (pattern);  swfdec_pattern_append_path_snapped (cr, path);  color = swfdec_color_apply_morph (stroke->start_color, stroke->end_color, ratio);  color = swfdec_color_apply_transform (color, trans);  swfdec_color_set_source (cr, color);  if (ratio == 0) {    width = stroke->start_width;  } else if (ratio == 65535) {    width = stroke->end_width;  } else {    width = (stroke->start_width * (65535 - ratio) + stroke->end_width * ratio) / 65535;  }  if (width < SWFDEC_TWIPS_SCALE_FACTOR)    width = SWFDEC_TWIPS_SCALE_FACTOR;  cairo_set_line_width (cr, width);  cairo_stroke (cr);}static voidswfdec_stroke_pattern_class_init (SwfdecStrokePatternClass *klass){  SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_stroke_pattern_paint;}static voidswfdec_stroke_pattern_init (SwfdecStrokePattern *pattern){}/*** 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;};G_DEFINE_TYPE (SwfdecColorPattern, swfdec_color_pattern, SWFDEC_TYPE_PATTERN);static voidswfdec_color_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path,    const SwfdecColorTransform *trans, unsigned int ratio){  SwfdecColorPattern *pattern = SWFDEC_COLOR_PATTERN (pat);  SwfdecColor color;  cairo_append_path (cr, (cairo_path_t *) path);  color = swfdec_color_apply_morph (pattern->start_color, pattern->end_color, ratio);  color = swfdec_color_apply_transform (color, trans);  swfdec_color_set_source (cr, color);  cairo_fill (cr);}static voidswfdec_color_pattern_class_init (SwfdecColorPatternClass *klass){  SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_color_pattern_paint;}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;};G_DEFINE_TYPE (SwfdecImagePattern, swfdec_image_pattern, SWFDEC_TYPE_PATTERN);static voidswfdec_image_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path,    const SwfdecColorTransform *trans, unsigned int 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;  cairo_append_path (cr, (cairo_path_t *) path);  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);  cairo_set_source (cr, pattern);  cairo_pattern_destroy (pattern);  cairo_fill (cr);}static voidswfdec_image_pattern_class_init (SwfdecImagePatternClass *klass){  SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_image_pattern_paint;}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 */};struct _SwfdecGradientPatternClass{  SwfdecPatternClass	pattern_class;};G_DEFINE_TYPE (SwfdecGradientPattern, swfdec_gradient_pattern, SWFDEC_TYPE_PATTERN);static voidswfdec_gradient_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path,    const SwfdecColorTransform *trans, unsigned int ratio){  unsigned int i;  cairo_pattern_t *pattern;  SwfdecColor color;  double offset;  SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat);  cairo_append_path (cr, (cairo_path_t *) path);#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 (0, 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);    }  }  cairo_set_source (cr, pattern);  cairo_pattern_destroy (pattern);  cairo_fill (cr);}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;

⌨️ 快捷键说明

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