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