[14481] | 1 | /* GTK - The GIMP Toolkit |
---|
| 2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
---|
| 3 | * |
---|
| 4 | * This library is free software; you can redistribute it and/or |
---|
| 5 | * modify it under the terms of the GNU Library General Public |
---|
| 6 | * License as published by the Free Software Foundation; either |
---|
| 7 | * version 2 of the License, or (at your option) any later version. |
---|
| 8 | * |
---|
| 9 | * This library is distributed in the hope that it will be useful, |
---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 12 | * Library General Public License for more details. |
---|
| 13 | * |
---|
| 14 | * You should have received a copy of the GNU Library General Public |
---|
| 15 | * License along with this library; if not, write to the |
---|
| 16 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
| 17 | * Boston, MA 02111-1307, USA. |
---|
| 18 | */ |
---|
| 19 | |
---|
| 20 | /* |
---|
| 21 | * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS |
---|
| 22 | * file for a list of people on the GTK+ Team. See the ChangeLog |
---|
| 23 | * files for a list of changes. These files are distributed with |
---|
| 24 | * GTK+ at ftp://ftp.gtk.org/pub/gtk/. |
---|
| 25 | */ |
---|
| 26 | |
---|
| 27 | |
---|
| 28 | #include <math.h> |
---|
| 29 | #include <string.h> |
---|
| 30 | #include <sys/types.h> |
---|
| 31 | #include <sys/param.h> |
---|
| 32 | #include "gdk/gdkx.h" |
---|
| 33 | #include "gdk/gdkrgb.h" |
---|
| 34 | #include "gtkpreview.h" |
---|
| 35 | #include "gtksignal.h" |
---|
| 36 | |
---|
| 37 | |
---|
| 38 | #define PREVIEW_CLASS(w) GTK_PREVIEW_CLASS (GTK_OBJECT (w)->klass) |
---|
| 39 | |
---|
| 40 | enum { |
---|
| 41 | ARG_0, |
---|
| 42 | ARG_EXPAND |
---|
| 43 | }; |
---|
| 44 | |
---|
| 45 | |
---|
| 46 | static void gtk_preview_class_init (GtkPreviewClass *klass); |
---|
| 47 | static void gtk_preview_init (GtkPreview *preview); |
---|
| 48 | static void gtk_preview_set_arg (GtkObject *object, |
---|
| 49 | GtkArg *arg, |
---|
| 50 | guint arg_id); |
---|
| 51 | static void gtk_preview_get_arg (GtkObject *object, |
---|
| 52 | GtkArg *arg, |
---|
| 53 | guint arg_id); |
---|
| 54 | static void gtk_preview_finalize (GtkObject *object); |
---|
| 55 | static void gtk_preview_realize (GtkWidget *widget); |
---|
| 56 | static void gtk_preview_size_allocate (GtkWidget *widget, |
---|
| 57 | GtkAllocation *allocation); |
---|
| 58 | static gint gtk_preview_expose (GtkWidget *widget, |
---|
| 59 | GdkEventExpose *event); |
---|
| 60 | static void gtk_preview_make_buffer (GtkPreview *preview); |
---|
| 61 | static void gtk_fill_lookup_array (guchar *array); |
---|
| 62 | |
---|
| 63 | static GtkWidgetClass *parent_class = NULL; |
---|
| 64 | static GtkPreviewClass *preview_class = NULL; |
---|
| 65 | static gint install_cmap = FALSE; |
---|
| 66 | |
---|
| 67 | |
---|
| 68 | GtkType |
---|
| 69 | gtk_preview_get_type (void) |
---|
| 70 | { |
---|
| 71 | static GtkType preview_type = 0; |
---|
| 72 | |
---|
| 73 | if (!preview_type) |
---|
| 74 | { |
---|
| 75 | static const GtkTypeInfo preview_info = |
---|
| 76 | { |
---|
| 77 | "GtkPreview", |
---|
| 78 | sizeof (GtkPreview), |
---|
| 79 | sizeof (GtkPreviewClass), |
---|
| 80 | (GtkClassInitFunc) gtk_preview_class_init, |
---|
| 81 | (GtkObjectInitFunc) gtk_preview_init, |
---|
| 82 | /* reserved_1 */ NULL, |
---|
| 83 | /* reserved_2 */ NULL, |
---|
| 84 | (GtkClassInitFunc) NULL, |
---|
| 85 | }; |
---|
| 86 | |
---|
| 87 | preview_type = gtk_type_unique (GTK_TYPE_WIDGET, &preview_info); |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | return preview_type; |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | static void |
---|
| 94 | gtk_preview_class_init (GtkPreviewClass *klass) |
---|
| 95 | { |
---|
| 96 | GtkObjectClass *object_class; |
---|
| 97 | GtkWidgetClass *widget_class; |
---|
| 98 | |
---|
| 99 | object_class = (GtkObjectClass*) klass; |
---|
| 100 | widget_class = (GtkWidgetClass*) klass; |
---|
| 101 | |
---|
| 102 | parent_class = gtk_type_class (GTK_TYPE_WIDGET); |
---|
| 103 | preview_class = klass; |
---|
| 104 | |
---|
| 105 | object_class->set_arg = gtk_preview_set_arg; |
---|
| 106 | object_class->get_arg = gtk_preview_get_arg; |
---|
| 107 | object_class->finalize = gtk_preview_finalize; |
---|
| 108 | |
---|
| 109 | widget_class->realize = gtk_preview_realize; |
---|
| 110 | widget_class->size_allocate = gtk_preview_size_allocate; |
---|
| 111 | widget_class->expose_event = gtk_preview_expose; |
---|
| 112 | |
---|
| 113 | klass->info.visual = NULL; |
---|
| 114 | klass->info.cmap = NULL; |
---|
| 115 | |
---|
| 116 | klass->info.lookup = NULL; |
---|
| 117 | |
---|
| 118 | klass->info.gamma = 1.0; |
---|
| 119 | |
---|
| 120 | gdk_rgb_init (); |
---|
| 121 | klass->info.cmap = gdk_rgb_get_cmap (); |
---|
| 122 | klass->info.visual = gdk_rgb_get_visual (); |
---|
| 123 | |
---|
| 124 | gtk_object_add_arg_type ("GtkPreview::expand", |
---|
| 125 | GTK_TYPE_BOOL, |
---|
| 126 | GTK_ARG_READWRITE, |
---|
| 127 | ARG_EXPAND); |
---|
| 128 | } |
---|
| 129 | |
---|
| 130 | static void |
---|
| 131 | gtk_preview_set_arg (GtkObject *object, |
---|
| 132 | GtkArg *arg, |
---|
| 133 | guint arg_id) |
---|
| 134 | { |
---|
| 135 | GtkPreview *preview = GTK_PREVIEW (object); |
---|
| 136 | |
---|
| 137 | switch (arg_id) |
---|
| 138 | { |
---|
| 139 | case ARG_EXPAND: |
---|
| 140 | gtk_preview_set_expand (preview, GTK_VALUE_BOOL (*arg)); |
---|
| 141 | break; |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | |
---|
| 145 | static void |
---|
| 146 | gtk_preview_get_arg (GtkObject *object, |
---|
| 147 | GtkArg *arg, |
---|
| 148 | guint arg_id) |
---|
| 149 | { |
---|
| 150 | GtkPreview *preview; |
---|
| 151 | |
---|
| 152 | preview = GTK_PREVIEW (object); |
---|
| 153 | |
---|
| 154 | switch (arg_id) |
---|
| 155 | { |
---|
| 156 | case ARG_EXPAND: |
---|
| 157 | GTK_VALUE_BOOL (*arg) = preview->expand; |
---|
| 158 | break; |
---|
| 159 | default: |
---|
| 160 | arg->type = GTK_TYPE_INVALID; |
---|
| 161 | break; |
---|
| 162 | } |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | void |
---|
| 166 | gtk_preview_reset (void) |
---|
| 167 | { |
---|
| 168 | /* unimplemented */ |
---|
| 169 | } |
---|
| 170 | |
---|
| 171 | static void |
---|
| 172 | gtk_preview_init (GtkPreview *preview) |
---|
| 173 | { |
---|
| 174 | preview->buffer = NULL; |
---|
| 175 | preview->buffer_width = 0; |
---|
| 176 | preview->buffer_height = 0; |
---|
| 177 | preview->expand = FALSE; |
---|
| 178 | } |
---|
| 179 | |
---|
| 180 | void |
---|
| 181 | gtk_preview_uninit (void) |
---|
| 182 | { |
---|
| 183 | |
---|
| 184 | /* unimplemented */ |
---|
| 185 | } |
---|
| 186 | |
---|
| 187 | GtkWidget* |
---|
| 188 | gtk_preview_new (GtkPreviewType type) |
---|
| 189 | { |
---|
| 190 | GtkPreview *preview; |
---|
| 191 | |
---|
| 192 | preview = gtk_type_new (gtk_preview_get_type ()); |
---|
| 193 | preview->type = type; |
---|
| 194 | |
---|
| 195 | if (type == GTK_PREVIEW_COLOR) |
---|
| 196 | preview->bpp = 3; |
---|
| 197 | else |
---|
| 198 | preview->bpp = 1; |
---|
| 199 | |
---|
| 200 | preview->dither = GDK_RGB_DITHER_NORMAL; |
---|
| 201 | |
---|
| 202 | return GTK_WIDGET (preview); |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | void |
---|
| 206 | gtk_preview_size (GtkPreview *preview, |
---|
| 207 | gint width, |
---|
| 208 | gint height) |
---|
| 209 | { |
---|
| 210 | g_return_if_fail (preview != NULL); |
---|
| 211 | g_return_if_fail (GTK_IS_PREVIEW (preview)); |
---|
| 212 | |
---|
| 213 | if ((width != GTK_WIDGET (preview)->requisition.width) || |
---|
| 214 | (height != GTK_WIDGET (preview)->requisition.height)) |
---|
| 215 | { |
---|
| 216 | GTK_WIDGET (preview)->requisition.width = width; |
---|
| 217 | GTK_WIDGET (preview)->requisition.height = height; |
---|
| 218 | |
---|
| 219 | if (preview->buffer) |
---|
| 220 | g_free (preview->buffer); |
---|
| 221 | preview->buffer = NULL; |
---|
| 222 | } |
---|
| 223 | } |
---|
| 224 | |
---|
| 225 | void |
---|
| 226 | gtk_preview_put (GtkPreview *preview, |
---|
| 227 | GdkWindow *window, |
---|
| 228 | GdkGC *gc, |
---|
| 229 | gint srcx, |
---|
| 230 | gint srcy, |
---|
| 231 | gint destx, |
---|
| 232 | gint desty, |
---|
| 233 | gint width, |
---|
| 234 | gint height) |
---|
| 235 | { |
---|
| 236 | GtkWidget *widget; |
---|
| 237 | GdkRectangle r1, r2, r3; |
---|
| 238 | guchar *src; |
---|
| 239 | guint bpp; |
---|
| 240 | guint rowstride; |
---|
| 241 | |
---|
| 242 | g_return_if_fail (preview != NULL); |
---|
| 243 | g_return_if_fail (GTK_IS_PREVIEW (preview)); |
---|
| 244 | g_return_if_fail (window != NULL); |
---|
| 245 | |
---|
| 246 | if (!preview->buffer) |
---|
| 247 | return; |
---|
| 248 | |
---|
| 249 | widget = GTK_WIDGET (preview); |
---|
| 250 | |
---|
| 251 | r1.x = 0; |
---|
| 252 | r1.y = 0; |
---|
| 253 | r1.width = preview->buffer_width; |
---|
| 254 | r1.height = preview->buffer_height; |
---|
| 255 | |
---|
| 256 | r2.x = srcx; |
---|
| 257 | r2.y = srcy; |
---|
| 258 | r2.width = width; |
---|
| 259 | r2.height = height; |
---|
| 260 | |
---|
| 261 | if (!gdk_rectangle_intersect (&r1, &r2, &r3)) |
---|
| 262 | return; |
---|
| 263 | |
---|
| 264 | bpp = preview->bpp; |
---|
| 265 | rowstride = preview->rowstride; |
---|
| 266 | |
---|
| 267 | src = preview->buffer + r3.y * rowstride + r3.x * bpp; |
---|
| 268 | |
---|
| 269 | if (preview->type == GTK_PREVIEW_COLOR) |
---|
| 270 | gdk_draw_rgb_image (window, |
---|
| 271 | gc, |
---|
| 272 | destx + (r3.x - srcx), |
---|
| 273 | desty + (r3.y - srcy), |
---|
| 274 | r3.width, |
---|
| 275 | r3.height, |
---|
| 276 | preview->dither, |
---|
| 277 | src, |
---|
| 278 | rowstride); |
---|
| 279 | else |
---|
| 280 | gdk_draw_gray_image (window, |
---|
| 281 | gc, |
---|
| 282 | destx + (r3.x - srcx), |
---|
| 283 | desty + (r3.y - srcy), |
---|
| 284 | r3.width, |
---|
| 285 | r3.height, |
---|
| 286 | preview->dither, |
---|
| 287 | src, |
---|
| 288 | rowstride); |
---|
| 289 | |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | void |
---|
| 293 | gtk_preview_draw_row (GtkPreview *preview, |
---|
| 294 | guchar *data, |
---|
| 295 | gint x, |
---|
| 296 | gint y, |
---|
| 297 | gint w) |
---|
| 298 | { |
---|
| 299 | guint bpp; |
---|
| 300 | guint rowstride; |
---|
| 301 | |
---|
| 302 | g_return_if_fail (preview != NULL); |
---|
| 303 | g_return_if_fail (GTK_IS_PREVIEW (preview)); |
---|
| 304 | g_return_if_fail (data != NULL); |
---|
| 305 | g_return_if_fail (preview_class->info.visual != NULL); |
---|
| 306 | |
---|
| 307 | bpp = (preview->type == GTK_PREVIEW_COLOR ? 3 : 1); |
---|
| 308 | rowstride = (preview->buffer_width * bpp + 3) & -4; |
---|
| 309 | |
---|
| 310 | if ((w <= 0) || (y < 0)) |
---|
| 311 | return; |
---|
| 312 | |
---|
| 313 | g_return_if_fail (data != NULL); |
---|
| 314 | |
---|
| 315 | gtk_preview_make_buffer (preview); |
---|
| 316 | |
---|
| 317 | if (x + w > preview->buffer_width) |
---|
| 318 | return; |
---|
| 319 | |
---|
| 320 | if (y + 1 > preview->buffer_height) |
---|
| 321 | return; |
---|
| 322 | |
---|
| 323 | if (preview_class->info.gamma == 1.0) |
---|
| 324 | memcpy (preview->buffer + y * rowstride + x * bpp, data, w * bpp); |
---|
| 325 | else |
---|
| 326 | { |
---|
| 327 | guint i, size; |
---|
| 328 | guchar *src, *dst; |
---|
| 329 | guchar *lookup; |
---|
| 330 | |
---|
| 331 | if (preview_class->info.lookup != NULL) |
---|
| 332 | lookup = preview_class->info.lookup; |
---|
| 333 | else |
---|
| 334 | { |
---|
| 335 | preview_class->info.lookup = g_new (guchar, 256); |
---|
| 336 | gtk_fill_lookup_array (preview_class->info.lookup); |
---|
| 337 | lookup = preview_class->info.lookup; |
---|
| 338 | } |
---|
| 339 | size = w * bpp; |
---|
| 340 | src = data; |
---|
| 341 | dst = preview->buffer + y * rowstride + x * bpp; |
---|
| 342 | for (i = 0; i < size; i++) |
---|
| 343 | *dst++ = lookup[*src++]; |
---|
| 344 | } |
---|
| 345 | } |
---|
| 346 | |
---|
| 347 | void |
---|
| 348 | gtk_preview_set_expand (GtkPreview *preview, |
---|
| 349 | gboolean expand) |
---|
| 350 | { |
---|
| 351 | g_return_if_fail (preview != NULL); |
---|
| 352 | g_return_if_fail (GTK_IS_PREVIEW (preview)); |
---|
| 353 | |
---|
| 354 | expand = expand != FALSE; |
---|
| 355 | |
---|
| 356 | if (preview->expand != expand) |
---|
| 357 | { |
---|
| 358 | preview->expand = expand; |
---|
| 359 | gtk_widget_queue_resize (GTK_WIDGET (preview)); |
---|
| 360 | } |
---|
| 361 | } |
---|
| 362 | |
---|
| 363 | void |
---|
| 364 | gtk_preview_set_gamma (double _gamma) |
---|
| 365 | { |
---|
| 366 | if (!preview_class) |
---|
| 367 | preview_class = gtk_type_class (gtk_preview_get_type ()); |
---|
| 368 | |
---|
| 369 | if (preview_class->info.gamma != _gamma) |
---|
| 370 | { |
---|
| 371 | preview_class->info.gamma = _gamma; |
---|
| 372 | if (preview_class->info.lookup != NULL) |
---|
| 373 | { |
---|
| 374 | g_free (preview_class->info.lookup); |
---|
| 375 | preview_class->info.lookup = NULL; |
---|
| 376 | } |
---|
| 377 | } |
---|
| 378 | } |
---|
| 379 | |
---|
| 380 | void |
---|
| 381 | gtk_preview_set_color_cube (guint nred_shades, |
---|
| 382 | guint ngreen_shades, |
---|
| 383 | guint nblue_shades, |
---|
| 384 | guint ngray_shades) |
---|
| 385 | { |
---|
| 386 | /* unimplemented */ |
---|
| 387 | } |
---|
| 388 | |
---|
| 389 | void |
---|
| 390 | gtk_preview_set_install_cmap (gint _install_cmap) |
---|
| 391 | { |
---|
| 392 | /* effectively unimplemented */ |
---|
| 393 | install_cmap = _install_cmap; |
---|
| 394 | } |
---|
| 395 | |
---|
| 396 | void |
---|
| 397 | gtk_preview_set_reserved (gint nreserved) |
---|
| 398 | { |
---|
| 399 | |
---|
| 400 | /* unimplemented */ |
---|
| 401 | } |
---|
| 402 | |
---|
| 403 | void |
---|
| 404 | gtk_preview_set_dither (GtkPreview *preview, |
---|
| 405 | GdkRgbDither dither) |
---|
| 406 | { |
---|
| 407 | preview->dither = dither; |
---|
| 408 | } |
---|
| 409 | |
---|
| 410 | GdkVisual* |
---|
| 411 | gtk_preview_get_visual (void) |
---|
| 412 | { |
---|
| 413 | if (!preview_class) |
---|
| 414 | preview_class = gtk_type_class (gtk_preview_get_type ()); |
---|
| 415 | |
---|
| 416 | return preview_class->info.visual; |
---|
| 417 | } |
---|
| 418 | |
---|
| 419 | GdkColormap* |
---|
| 420 | gtk_preview_get_cmap (void) |
---|
| 421 | { |
---|
| 422 | if (!preview_class) |
---|
| 423 | preview_class = gtk_type_class (gtk_preview_get_type ()); |
---|
| 424 | |
---|
| 425 | return preview_class->info.cmap; |
---|
| 426 | } |
---|
| 427 | |
---|
| 428 | GtkPreviewInfo* |
---|
| 429 | gtk_preview_get_info (void) |
---|
| 430 | { |
---|
| 431 | if (!preview_class) |
---|
| 432 | preview_class = gtk_type_class (gtk_preview_get_type ()); |
---|
| 433 | |
---|
| 434 | return &preview_class->info; |
---|
| 435 | } |
---|
| 436 | |
---|
| 437 | |
---|
| 438 | static void |
---|
| 439 | gtk_preview_finalize (GtkObject *object) |
---|
| 440 | { |
---|
| 441 | GtkPreview *preview; |
---|
| 442 | |
---|
| 443 | g_return_if_fail (object != NULL); |
---|
| 444 | g_return_if_fail (GTK_IS_PREVIEW (object)); |
---|
| 445 | |
---|
| 446 | preview = GTK_PREVIEW (object); |
---|
| 447 | if (preview->buffer) |
---|
| 448 | g_free (preview->buffer); |
---|
| 449 | preview->type = (GtkPreviewType) -1; |
---|
| 450 | |
---|
| 451 | (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); |
---|
| 452 | } |
---|
| 453 | |
---|
| 454 | static void |
---|
| 455 | gtk_preview_realize (GtkWidget *widget) |
---|
| 456 | { |
---|
| 457 | GtkPreview *preview; |
---|
| 458 | GdkWindowAttr attributes; |
---|
| 459 | gint attributes_mask; |
---|
| 460 | |
---|
| 461 | g_return_if_fail (widget != NULL); |
---|
| 462 | g_return_if_fail (GTK_IS_PREVIEW (widget)); |
---|
| 463 | |
---|
| 464 | GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); |
---|
| 465 | preview = GTK_PREVIEW (widget); |
---|
| 466 | |
---|
| 467 | attributes.window_type = GDK_WINDOW_CHILD; |
---|
| 468 | |
---|
| 469 | if (preview->expand) |
---|
| 470 | { |
---|
| 471 | attributes.width = widget->allocation.width; |
---|
| 472 | attributes.height = widget->allocation.height; |
---|
| 473 | } |
---|
| 474 | else |
---|
| 475 | { |
---|
| 476 | attributes.width = MIN (widget->requisition.width, widget->allocation.width); |
---|
| 477 | attributes.height = MIN (widget->requisition.height, widget->allocation.height); |
---|
| 478 | } |
---|
| 479 | |
---|
| 480 | attributes.x = widget->allocation.x + (widget->allocation.width - attributes.width) / 2; |
---|
| 481 | attributes.y = widget->allocation.y + (widget->allocation.height - attributes.height) / 2;; |
---|
| 482 | |
---|
| 483 | attributes.wclass = GDK_INPUT_OUTPUT; |
---|
| 484 | attributes.visual = preview_class->info.visual; |
---|
| 485 | attributes.colormap = preview_class->info.cmap; |
---|
| 486 | attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; |
---|
| 487 | attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; |
---|
| 488 | |
---|
| 489 | widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); |
---|
| 490 | gdk_window_set_user_data (widget->window, widget); |
---|
| 491 | |
---|
| 492 | widget->style = gtk_style_attach (widget->style, widget->window); |
---|
| 493 | gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); |
---|
| 494 | } |
---|
| 495 | |
---|
| 496 | static void |
---|
| 497 | gtk_preview_size_allocate (GtkWidget *widget, |
---|
| 498 | GtkAllocation *allocation) |
---|
| 499 | { |
---|
| 500 | GtkPreview *preview; |
---|
| 501 | gint width, height; |
---|
| 502 | |
---|
| 503 | g_return_if_fail (widget != NULL); |
---|
| 504 | g_return_if_fail (GTK_IS_PREVIEW (widget)); |
---|
| 505 | |
---|
| 506 | preview = GTK_PREVIEW (widget); |
---|
| 507 | widget->allocation = *allocation; |
---|
| 508 | |
---|
| 509 | if (GTK_WIDGET_REALIZED (widget)) |
---|
| 510 | { |
---|
| 511 | if (preview->expand) |
---|
| 512 | { |
---|
| 513 | width = widget->allocation.width; |
---|
| 514 | height = widget->allocation.height; |
---|
| 515 | } |
---|
| 516 | else |
---|
| 517 | { |
---|
| 518 | width = MIN (widget->allocation.width, widget->requisition.width); |
---|
| 519 | height = MIN (widget->allocation.height, widget->requisition.height); |
---|
| 520 | } |
---|
| 521 | |
---|
| 522 | gdk_window_move_resize (widget->window, |
---|
| 523 | widget->allocation.x + (widget->allocation.width - width) / 2, |
---|
| 524 | widget->allocation.y + (widget->allocation.height - height) / 2, |
---|
| 525 | width, height); |
---|
| 526 | } |
---|
| 527 | } |
---|
| 528 | |
---|
| 529 | static gint |
---|
| 530 | gtk_preview_expose (GtkWidget *widget, |
---|
| 531 | GdkEventExpose *event) |
---|
| 532 | { |
---|
| 533 | GtkPreview *preview; |
---|
| 534 | gint width, height; |
---|
| 535 | |
---|
| 536 | g_return_val_if_fail (widget != NULL, FALSE); |
---|
| 537 | g_return_val_if_fail (GTK_IS_PREVIEW (widget), FALSE); |
---|
| 538 | g_return_val_if_fail (event != NULL, FALSE); |
---|
| 539 | |
---|
| 540 | if (GTK_WIDGET_DRAWABLE (widget)) |
---|
| 541 | { |
---|
| 542 | preview = GTK_PREVIEW (widget); |
---|
| 543 | |
---|
| 544 | gdk_window_get_size (widget->window, &width, &height); |
---|
| 545 | |
---|
| 546 | gtk_preview_put (GTK_PREVIEW (widget), |
---|
| 547 | widget->window, widget->style->black_gc, |
---|
| 548 | event->area.x - (width - preview->buffer_width)/2, |
---|
| 549 | event->area.y - (height - preview->buffer_height)/2, |
---|
| 550 | event->area.x, event->area.y, |
---|
| 551 | event->area.width, event->area.height); |
---|
| 552 | } |
---|
| 553 | |
---|
| 554 | return FALSE; |
---|
| 555 | } |
---|
| 556 | |
---|
| 557 | static void |
---|
| 558 | gtk_preview_make_buffer (GtkPreview *preview) |
---|
| 559 | { |
---|
| 560 | GtkWidget *widget; |
---|
| 561 | gint width; |
---|
| 562 | gint height; |
---|
| 563 | |
---|
| 564 | g_return_if_fail (preview != NULL); |
---|
| 565 | g_return_if_fail (GTK_IS_PREVIEW (preview)); |
---|
| 566 | |
---|
| 567 | widget = GTK_WIDGET (preview); |
---|
| 568 | |
---|
| 569 | if (preview->expand && |
---|
| 570 | (widget->allocation.width != 0) && |
---|
| 571 | (widget->allocation.height != 0)) |
---|
| 572 | { |
---|
| 573 | width = widget->allocation.width; |
---|
| 574 | height = widget->allocation.height; |
---|
| 575 | } |
---|
| 576 | else |
---|
| 577 | { |
---|
| 578 | width = widget->requisition.width; |
---|
| 579 | height = widget->requisition.height; |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | if (!preview->buffer || |
---|
| 583 | (preview->buffer_width != width) || |
---|
| 584 | (preview->buffer_height != height)) |
---|
| 585 | { |
---|
| 586 | if (preview->buffer) |
---|
| 587 | g_free (preview->buffer); |
---|
| 588 | |
---|
| 589 | preview->buffer_width = width; |
---|
| 590 | preview->buffer_height = height; |
---|
| 591 | |
---|
| 592 | preview->rowstride = (preview->buffer_width * preview->bpp + 3) & -4; |
---|
| 593 | preview->buffer = g_new0 (guchar, |
---|
| 594 | preview->buffer_height * |
---|
| 595 | preview->rowstride); |
---|
| 596 | } |
---|
| 597 | } |
---|
| 598 | |
---|
| 599 | /* This is used for implementing gamma. */ |
---|
| 600 | static void |
---|
| 601 | gtk_fill_lookup_array (guchar *array) |
---|
| 602 | { |
---|
| 603 | double one_over_gamma; |
---|
| 604 | double ind; |
---|
| 605 | int val; |
---|
| 606 | int i; |
---|
| 607 | |
---|
| 608 | one_over_gamma = 1.0 / preview_class->info.gamma; |
---|
| 609 | |
---|
| 610 | for (i = 0; i < 256; i++) |
---|
| 611 | { |
---|
| 612 | ind = (double) i / 255.0; |
---|
| 613 | val = (int) (255 * pow (ind, one_over_gamma)); |
---|
| 614 | array[i] = val; |
---|
| 615 | } |
---|
| 616 | } |
---|