1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  GThumb
5  *
6  *  Copyright (C) 2010 Free Software Foundation, Inc.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef CAIRO_UTILS_H
23 #define CAIRO_UTILS_H
24 
25 #include <glib.h>
26 #include <gdk/gdk.h>
27 #include <gdk-pixbuf/gdk-pixbuf.h>
28 #include <cairo.h>
29 #include "typedefs.h"
30 
31 
32 #define CAIRO_MAX_IMAGE_SIZE    32767
33 #define CLAMP_TEMP(x, min, max) (temp = (x), CLAMP (temp, min, max))
34 #define CLAMP_PIXEL(x)          CLAMP_TEMP (x, 0, 255)
35 
36 #if G_BYTE_ORDER == G_LITTLE_ENDIAN /* BGRA */
37 
38 #define CAIRO_RED   2
39 #define CAIRO_GREEN 1
40 #define CAIRO_BLUE  0
41 #define CAIRO_ALPHA 3
42 
43 #elif G_BYTE_ORDER == G_BIG_ENDIAN /* ARGB */
44 
45 #define CAIRO_RED   1
46 #define CAIRO_GREEN 2
47 #define CAIRO_BLUE  3
48 #define CAIRO_ALPHA 0
49 
50 #else /* PDP endianness: RABG */
51 
52 #define CAIRO_RED   0
53 #define CAIRO_GREEN 3
54 #define CAIRO_BLUE  2
55 #define CAIRO_ALPHA 1
56 
57 #endif
58 
59 #define CAIRO_SET_RGB(pixel, red, green, blue)					\
60 	G_STMT_START {								\
61 		pixel[CAIRO_RED] = (red);					\
62 		pixel[CAIRO_GREEN] = (green);					\
63 		pixel[CAIRO_BLUE] = (blue);					\
64 		pixel[CAIRO_ALPHA] = 0xff;					\
65 	} G_STMT_END
66 
67 #define CAIRO_SET_RGBA(pixel, red, green, blue, alpha)				\
68 	G_STMT_START {								\
69 		pixel[CAIRO_ALPHA] = (alpha);					\
70 		if (pixel[CAIRO_ALPHA] == 0xff) {				\
71 			pixel[CAIRO_RED] = (red);				\
72 			pixel[CAIRO_GREEN] = (green);				\
73 			pixel[CAIRO_BLUE] = (blue);				\
74 		}								\
75 		else {								\
76 			double factor = (double) pixel[CAIRO_ALPHA] / 0xff;	\
77 			pixel[CAIRO_RED] = CLAMP_PIXEL (factor * (red));	\
78 			pixel[CAIRO_GREEN] = CLAMP_PIXEL (factor * (green));	\
79 			pixel[CAIRO_BLUE] = CLAMP_PIXEL (factor * (blue));	\
80 		}								\
81 	} G_STMT_END
82 
83 #define CAIRO_GET_RGB(pixel, red, green, blue)					\
84 	G_STMT_START {								\
85 		red = pixel[CAIRO_RED];						\
86 		green = pixel[CAIRO_GREEN];					\
87 		blue = pixel[CAIRO_BLUE];					\
88 	} G_STMT_END
89 
90 #define CAIRO_GET_RGBA(pixel, red, green, blue, alpha)				\
91 	G_STMT_START {								\
92 		alpha = pixel[CAIRO_ALPHA];					\
93 		if (alpha == 0xff) {						\
94 			red = pixel[CAIRO_RED];					\
95 			green = pixel[CAIRO_GREEN];				\
96 			blue = pixel[CAIRO_BLUE];				\
97 		}								\
98 		else {								\
99 			double factor = (double) 0xff / alpha;			\
100 			red = CLAMP_PIXEL (factor * pixel[CAIRO_RED]);		\
101 			green = CLAMP_PIXEL (factor * pixel[CAIRO_GREEN]);	\
102 			blue = CLAMP_PIXEL (factor * pixel[CAIRO_BLUE]);	\
103 		}								\
104 	} G_STMT_END
105 
106 #define CAIRO_COPY_RGBA(pixel, red, green, blue, alpha)	\
107 	G_STMT_START {					\
108 		alpha = pixel[CAIRO_ALPHA];		\
109 		red = pixel[CAIRO_RED];			\
110 		green = pixel[CAIRO_GREEN];		\
111 		blue = pixel[CAIRO_BLUE];		\
112 	} G_STMT_END
113 
114 #define CAIRO_RGBA_TO_UINT32(red, green, blue, alpha) 				\
115 	(((alpha) << 24) | ((red) << 16) | ((green) << 8) | (blue))
116 
117 #define interpolate_value(original, reference, distance) 			\
118 	(((distance) * (reference)) + ((1.0 - (distance)) * (original)))
119 
120 
121 /* types */
122 
123 typedef cairo_surface_t GthCairoSurface;
124 
125 GType gth_cairo_surface_get_type (void);
126 #define GTH_TYPE_CAIRO_SURFACE (gth_cairo_surface_get_type ())
127 
128 typedef struct {
129 	guchar r;
130 	guchar g;
131 	guchar b;
132 	guchar a;
133 } cairo_color_255_t;
134 
135 typedef struct {
136 	int image_width;
137 	int image_height;
138 } thumbnail_metadata_t;
139 
140 typedef enum {
141 	_CAIRO_METADATA_FLAG_NONE = 0,
142 	_CAIRO_METADATA_FLAG_HAS_ALPHA = 1 << 0,
143 	_CAIRO_METADATA_FLAG_ORIGINAL_SIZE = 1 << 1,
144 	_CAIRO_METADATA_FLAG_THUMBNAIL_SIZE = 1 << 2
145 } cairo_metadata_flags_t;
146 
147 typedef struct {
148 	cairo_metadata_flags_t  valid_data;
149 	gboolean		has_alpha;
150 	int			original_width;
151 	int			original_height;
152 	thumbnail_metadata_t	thumbnail;
153 } cairo_surface_metadata_t;
154 
155 extern const unsigned char cairo_channel[4];
156 
157 typedef enum {
158 	ITEM_STYLE_ICON,
159 	ITEM_STYLE_IMAGE,
160 	ITEM_STYLE_VIDEO
161 } ItemStyle;
162 
163 /* math */
164 
165 int                _cairo_multiply_alpha                    (int                    color,
166 							     int                    alpha);
167 gboolean           _cairo_rectangle_contains_point          (cairo_rectangle_int_t *rect,
168 			 	 	 	 	     int                    x,
169 			 	 	 	 	     int                    y);
170 
171 /* colors */
172 
173 void               _gdk_color_to_cairo_color                (GdkColor              *g_color,
174 							     GdkRGBA               *c_color);
175 void               _gdk_color_to_cairo_color_255            (GdkColor              *g_color,
176 			         	 	 	     cairo_color_255_t     *c_color);
177 void               _gdk_rgba_to_cairo_color_255             (GdkRGBA               *g_color,
178 			         	 	 	     cairo_color_255_t     *c_color);
179 
180 /* metadata */
181 
182 void               _cairo_metadata_set_has_alpha            (cairo_surface_metadata_t	*metadata,
183 							     gboolean                    has_alpha);
184 void               _cairo_metadata_set_original_size        (cairo_surface_metadata_t	*metadata,
185 							     int                         width,
186 							     int                         height);
187 void               _cairo_metadata_set_thumbnail_size       (cairo_surface_metadata_t	*metadata,
188 							     int                         width,
189 							     int                         height);
190 
191 /* surface */
192 
193 void               _cairo_clear_surface                     (cairo_surface_t      **surface);
194 unsigned char *    _cairo_image_surface_flush_and_get_data  (cairo_surface_t       *surface);
195 cairo_surface_metadata_t *
196 		   _cairo_image_surface_get_metadata        (cairo_surface_t       *surface);
197 void               _cairo_image_surface_copy_metadata       (cairo_surface_t	   *src,
198 							     cairo_surface_t	   *dest);
199 void               _cairo_image_surface_clear_metadata      (cairo_surface_t	   *surface);
200 gboolean           _cairo_image_surface_get_has_alpha       (cairo_surface_t       *surface);
201 gboolean           _cairo_image_surface_get_original_size   (cairo_surface_t       *surface,
202 							     int                   *original_width,
203 							     int                   *original_height);
204 cairo_surface_t *  _cairo_image_surface_create              (cairo_format_t         format,
205 							     int                    width,
206 							     int                    height);
207 cairo_surface_t *  _cairo_image_surface_copy                (cairo_surface_t       *surface);
208 cairo_surface_t *  _cairo_image_surface_copy_subsurface     (cairo_surface_t       *surface,
209 				      	      	      	     int                    src_x,
210 				      	      	      	     int                    src_y,
211 				      	      	      	     int                    width,
212 				      	      	      	     int                    height);
213 cairo_surface_t *  _cairo_image_surface_create_from_pixbuf  (GdkPixbuf             *pixbuf);
214 cairo_surface_t *  _cairo_image_surface_create_compatible   (cairo_surface_t       *surface);
215 void               _cairo_image_surface_transform_get_steps (cairo_format_t         format,
216 							     int                    width,
217 							     int                    height,
218 							     GthTransform           transform,
219 							     int                   *destination_width_p,
220 							     int                   *destination_height_p,
221 							     int                   *line_start_p,
222 							     int                   *line_step_p,
223 							     int                   *pixel_step_p);
224 cairo_surface_t *  _cairo_image_surface_transform           (cairo_surface_t       *image,
225 							     GthTransform           transform);
226 cairo_surface_t *  _cairo_image_surface_color_shift         (cairo_surface_t       *image,
227 							     int                    shift);
228 void               _cairo_copy_line_as_rgba_big_endian      (guchar                *dest,
229 							     guchar                *src,
230 							     guint                  width,
231 							     guint                  alpha);
232 void               _cairo_copy_line_as_rgba_little_endian   (guchar                *dest,
233 							     guchar                *src,
234 							     guint                  width,
235 							     guint                  alpha);
236 
237 /* paint / draw */
238 
239 void              _cairo_paint_full_gradient                (cairo_surface_t       *surface,
240 							     GdkRGBA               *h_color1,
241 							     GdkRGBA               *h_color2,
242 							     GdkRGBA               *v_color1,
243 							     GdkRGBA               *v_color2);
244 void              _cairo_draw_rounded_box                   (cairo_t               *cr,
245 			 	 	 	 	     double                 x,
246 			 	 	 	 	     double                 y,
247 			 	 	 	 	     double                 w,
248 			 	 	 	 	     double                 h,
249 			 	 	 	 	     double                 r);
250 void              _cairo_draw_drop_shadow                   (cairo_t               *cr,
251  	 	 	 	 	 	 	     double                 x,
252  	 	 	 	 	 	 	     double                 y,
253  	 	 	 	 	 	 	     double                 w,
254  	 	 	 	 	 	 	     double                 h,
255  	 	 	 	 	 	 	     double                 r);
256 void              _cairo_draw_frame                         (cairo_t               *cr,
257  	 	 	 	 	 	 	     double                 x,
258  	 	 	 	 	 	 	     double                 y,
259  	 	 	 	 	 	 	     double                 w,
260  	 	 	 	 	 	 	     double                 h,
261  	 	 	 	 	 	 	     double                 r);
262 void              _cairo_draw_slide                         (cairo_t               *cr,
263 		   	   	   	   	 	     double                 frame_x,
264 		   	   	   	   	 	     double                 frame_y,
265 		   	   	   	   	 	     double                 frame_width,
266 		   	   	   	   	 	     double                 frame_height,
267 		   	   	   	   	 	     double                 image_width,
268 		   	   	   	   	 	     double                 image_height,
269 		   	   	   	   	 	     GdkRGBA               *frame_color,
270 		   	   	   	   	 	     gboolean               draw_inner_border);
271 void              _cairo_paint_grid                         (cairo_t               *cr,
272 							     cairo_rectangle_int_t *rectangle,
273 							     GthGridType            grid_type);
274 cairo_pattern_t * _cairo_create_checked_pattern	            (int		    size);
275 void              _cairo_draw_thumbnail_frame               (cairo_t               *cr,
276 							     int                    x,
277 							     int                    y,
278 							     int                    width,
279 							     int                    height);
280 void              _cairo_draw_film_background               (cairo_t               *cr,
281 							     int                    x,
282 							     int                    y,
283 							     int                    width,
284 							     int                    height);
285 void              _cairo_draw_film_foreground               (cairo_t               *cr,
286 							     int                    x,
287 							     int                    y,
288 							     int                    width,
289 							     int                    height,
290 							     int                    thumbnail_size);
291 cairo_surface_t * _cairo_create_dnd_icon                    (cairo_surface_t       *image,
292 							     int                    icon_size,
293 							     ItemStyle              style,
294 							     gboolean               multi_dnd);
295 
296 #endif /* CAIRO_UTILS_H */
297