44
44
/* local function prototypes */
46
static void gimp_projection_class_init (GimpProjectionClass *klass);
47
static void gimp_projection_init (GimpProjection *proj);
48
static void gimp_projection_pickable_iface_init (GimpPickableInterface *pickable_iface);
46
static void gimp_projection_pickable_iface_init (GimpPickableInterface *iface);
50
48
static void gimp_projection_finalize (GObject *object);
52
50
static gint64 gimp_projection_get_memsize (GimpObject *object,
53
static void gimp_projection_pickable_flush (GimpPickable *pickable);
55
54
static guchar * gimp_projection_get_color_at (GimpPickable *pickable,
57
static gint gimp_projection_get_opacity_at (GimpPickable *pickable,
59
61
static void gimp_projection_alloc_tiles (GimpProjection *proj);
60
62
static void gimp_projection_add_update_area (GimpProjection *proj,
81
83
static void gimp_projection_validate_tile (TileManager *tm,
84
static void gimp_projection_image_update (GimpImage *gimage,
86
static void gimp_projection_image_update (GimpImage *image,
89
91
GimpProjection *proj);
90
static void gimp_projection_image_size_changed (GimpImage *gimage,
91
GimpProjection *proj);
92
static void gimp_projection_image_mode_changed (GimpImage *gimage,
93
GimpProjection *proj);
94
static void gimp_projection_image_flush (GimpImage *gimage,
95
GimpProjection *proj);
92
static void gimp_projection_image_size_changed (GimpImage *image,
93
GimpProjection *proj);
94
static void gimp_projection_image_mode_changed (GimpImage *image,
95
GimpProjection *proj);
96
static void gimp_projection_image_flush (GimpImage *image,
97
GimpProjection *proj);
100
G_DEFINE_TYPE_WITH_CODE (GimpProjection, gimp_projection, GIMP_TYPE_OBJECT,
101
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
102
gimp_projection_pickable_iface_init))
104
#define parent_class gimp_projection_parent_class
98
106
static guint projection_signals[LAST_SIGNAL] = { 0 };
100
static GimpObjectClass *parent_class = NULL;
104
gimp_projection_get_type (void)
106
static GType projection_type = 0;
108
if (! projection_type)
110
static const GTypeInfo projection_info =
112
sizeof (GimpProjectionClass),
113
(GBaseInitFunc) NULL,
114
(GBaseFinalizeFunc) NULL,
115
(GClassInitFunc) gimp_projection_class_init,
116
NULL, /* class_finalize */
117
NULL, /* class_data */
118
sizeof (GimpProjection),
120
(GInstanceInitFunc) gimp_projection_init,
123
static const GInterfaceInfo pickable_iface_info =
125
(GInterfaceInitFunc) gimp_projection_pickable_iface_init,
126
NULL, /* iface_finalize */
127
NULL /* iface_data */
130
projection_type = g_type_register_static (GIMP_TYPE_OBJECT,
132
&projection_info, 0);
134
g_type_add_interface_static (projection_type, GIMP_TYPE_PICKABLE,
135
&pickable_iface_info);
138
return projection_type;
142
110
gimp_projection_class_init (GimpProjectionClass *klass)
144
112
GObjectClass *object_class = G_OBJECT_CLASS (klass);
145
113
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
147
parent_class = g_type_class_peek_parent (klass);
149
115
projection_signals[UPDATE] =
150
116
g_signal_new ("update",
151
G_TYPE_FROM_CLASS (klass),
153
G_STRUCT_OFFSET (GimpProjectionClass, update),
155
gimp_marshal_VOID__BOOLEAN_INT_INT_INT_INT,
117
G_TYPE_FROM_CLASS (klass),
119
G_STRUCT_OFFSET (GimpProjectionClass, update),
121
gimp_marshal_VOID__BOOLEAN_INT_INT_INT_INT,
163
129
object_class->finalize = gimp_projection_finalize;
182
148
proj->construct_flag = FALSE;
151
/* sorry for the evil casts */
186
gimp_projection_pickable_iface_init (GimpPickableInterface *pickable_iface)
154
gimp_projection_pickable_iface_init (GimpPickableInterface *iface)
188
pickable_iface->get_image = gimp_projection_get_image;
189
pickable_iface->get_image_type = gimp_projection_get_image_type;
190
pickable_iface->get_tiles = gimp_projection_get_tiles;
191
pickable_iface->get_color_at = gimp_projection_get_color_at;
156
iface->flush = gimp_projection_pickable_flush;
157
iface->get_image = (GimpImage * (*) (GimpPickable *pickable)) gimp_projection_get_image;
158
iface->get_image_type = (GimpImageType (*) (GimpPickable *pickable)) gimp_projection_get_image_type;
159
iface->get_bytes = (gint (*) (GimpPickable *pickable)) gimp_projection_get_bytes;
160
iface->get_tiles = (TileManager * (*) (GimpPickable *pickable)) gimp_projection_get_tiles;
161
iface->get_color_at = gimp_projection_get_color_at;
162
iface->get_opacity_at = gimp_projection_get_opacity_at;
206
gimp_projection_pickable_flush (GimpPickable *pickable)
208
GimpProjection *proj = GIMP_PROJECTION (pickable);
210
gimp_projection_finish_draw (proj);
211
gimp_projection_flush_now (proj);
235
215
gimp_projection_get_color_at (GimpPickable *pickable,
244
if (x < 0 || y < 0 || x >= proj->gimage->width || y >= proj->gimage->height)
224
if (x < 0 || y < 0 || x >= proj->image->width || y >= proj->image->height)
247
227
dest = g_new (guchar, 5);
248
228
tile = tile_manager_get_tile (gimp_projection_get_tiles (proj),
249
229
x, y, TRUE, FALSE);
250
230
src = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
251
gimp_image_get_color (proj->gimage, gimp_projection_get_image_type (proj),
231
gimp_image_get_color (proj->image, gimp_projection_get_image_type (proj),
241
gimp_projection_get_opacity_at (GimpPickable *pickable,
245
return OPAQUE_OPACITY;
261
gimp_projection_new (GimpImage *gimage)
249
gimp_projection_new (GimpImage *image)
263
251
GimpProjection *proj;
265
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
253
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
267
255
proj = g_object_new (GIMP_TYPE_PROJECTION, NULL);
269
proj->gimage = gimage;
271
g_signal_connect_object (gimage, "update",
259
g_signal_connect_object (image, "update",
272
260
G_CALLBACK (gimp_projection_image_update),
274
g_signal_connect_object (gimage, "size_changed",
262
g_signal_connect_object (image, "size-changed",
275
263
G_CALLBACK (gimp_projection_image_size_changed),
277
g_signal_connect_object (gimage, "mode_changed",
265
g_signal_connect_object (image, "mode-changed",
278
266
G_CALLBACK (gimp_projection_image_mode_changed),
280
g_signal_connect_object (gimage, "flush",
268
g_signal_connect_object (image, "flush",
281
269
G_CALLBACK (gimp_projection_image_flush),
290
278
g_return_val_if_fail (GIMP_IS_PROJECTION (proj), NULL);
292
280
if (proj->tiles == NULL ||
293
tile_manager_width (proj->tiles) != proj->gimage->width ||
294
tile_manager_height (proj->tiles) != proj->gimage->height)
281
tile_manager_width (proj->tiles) != proj->image->width ||
282
tile_manager_height (proj->tiles) != proj->image->height)
296
284
gimp_projection_alloc_tiles (proj);
400
if (proj_type != proj->type ||
401
proj_bytes != proj->bytes ||
402
proj->gimage->width != tile_manager_width (proj->tiles) ||
403
proj->gimage->height != tile_manager_height (proj->tiles))
392
if (proj_type != proj->type ||
393
proj_bytes != proj->bytes ||
394
proj->image->width != tile_manager_width (proj->tiles) ||
395
proj->image->height != tile_manager_height (proj->tiles))
405
397
tile_manager_unref (proj->tiles);
406
398
proj->tiles = NULL;
412
404
proj->type = proj_type;
413
405
proj->bytes = proj_bytes;
415
proj->tiles = tile_manager_new (proj->gimage->width,
416
proj->gimage->height,
407
proj->tiles = tile_manager_new (proj->image->width,
418
410
tile_manager_set_user_data (proj->tiles, proj);
419
411
tile_manager_set_validate_proc (proj->tiles,
433
425
g_return_if_fail (GIMP_IS_PROJECTION (proj));
435
area = gimp_area_new (CLAMP (x, 0, proj->gimage->width),
436
CLAMP (y, 0, proj->gimage->height),
437
CLAMP (x + w, 0, proj->gimage->width),
438
CLAMP (y + h, 0, proj->gimage->height));
427
area = gimp_area_new (CLAMP (x, 0, proj->image->width),
428
CLAMP (y, 0, proj->image->height),
429
CLAMP (x + w, 0, proj->image->width),
430
CLAMP (y + h, 0, proj->image->height));
440
432
proj->update_areas = gimp_area_list_process (proj->update_areas, area);
624
616
gint x1, y1, x2, y2;
626
618
/* Bounds check */
627
x1 = CLAMP (x, 0, proj->gimage->width);
628
y1 = CLAMP (y, 0, proj->gimage->height);
629
x2 = CLAMP (x + w, 0, proj->gimage->width);
630
y2 = CLAMP (y + h, 0, proj->gimage->height);
619
x1 = CLAMP (x, 0, proj->image->width);
620
y1 = CLAMP (y, 0, proj->image->height);
621
x2 = CLAMP (x + w, 0, proj->image->width);
622
y2 = CLAMP (y + h, 0, proj->image->height);
655
647
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
656
648
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
658
tile = tile_manager_get_tile (tm, j, i, FALSE, FALSE);
650
tile = tile_manager_get_tile (tm, j, i, FALSE, FALSE);
660
652
tile_invalidate_tile (&tile, tm, j, i);
695
gimp_projection_image_size_changed (GimpImage *gimage,
696
GimpProjection *proj)
698
gimp_projection_alloc_tiles (proj);
699
gimp_projection_add_update_area (proj, 0, 0, gimage->width, gimage->height);
703
gimp_projection_image_mode_changed (GimpImage *gimage,
704
GimpProjection *proj)
706
gimp_projection_alloc_tiles (proj);
707
gimp_projection_add_update_area (proj, 0, 0, gimage->width, gimage->height);
711
gimp_projection_image_flush (GimpImage *gimage,
687
gimp_projection_image_size_changed (GimpImage *image,
688
GimpProjection *proj)
690
gimp_projection_alloc_tiles (proj);
691
gimp_projection_add_update_area (proj, 0, 0, image->width, image->height);
695
gimp_projection_image_mode_changed (GimpImage *image,
696
GimpProjection *proj)
698
gimp_projection_alloc_tiles (proj);
699
gimp_projection_add_update_area (proj, 0, 0, image->width, image->height);
703
gimp_projection_image_flush (GimpImage *image,
712
704
GimpProjection *proj)
714
706
gimp_projection_flush (proj);