1
/* GIMP - The GNU Image Manipulation Program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* gimpcanvasrectangle.c
5
* Copyright (C) 2010 Michael Natterer <mitch@gimp.org>
7
* This program is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 3 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include "libgimpbase/gimpbase.h"
27
#include "libgimpmath/gimpmath.h"
29
#include "display-types.h"
31
#include "gimpcanvasrectangle.h"
32
#include "gimpdisplayshell.h"
33
#include "gimpdisplayshell-transform.h"
47
typedef struct _GimpCanvasRectanglePrivate GimpCanvasRectanglePrivate;
49
struct _GimpCanvasRectanglePrivate
58
#define GET_PRIVATE(rectangle) \
59
G_TYPE_INSTANCE_GET_PRIVATE (rectangle, \
60
GIMP_TYPE_CANVAS_RECTANGLE, \
61
GimpCanvasRectanglePrivate)
64
/* local function prototypes */
66
static void gimp_canvas_rectangle_set_property (GObject *object,
70
static void gimp_canvas_rectangle_get_property (GObject *object,
74
static void gimp_canvas_rectangle_draw (GimpCanvasItem *item,
75
GimpDisplayShell *shell,
77
static cairo_region_t * gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
78
GimpDisplayShell *shell);
81
G_DEFINE_TYPE (GimpCanvasRectangle, gimp_canvas_rectangle,
82
GIMP_TYPE_CANVAS_ITEM)
84
#define parent_class gimp_canvas_rectangle_parent_class
88
gimp_canvas_rectangle_class_init (GimpCanvasRectangleClass *klass)
90
GObjectClass *object_class = G_OBJECT_CLASS (klass);
91
GimpCanvasItemClass *item_class = GIMP_CANVAS_ITEM_CLASS (klass);
93
object_class->set_property = gimp_canvas_rectangle_set_property;
94
object_class->get_property = gimp_canvas_rectangle_get_property;
96
item_class->draw = gimp_canvas_rectangle_draw;
97
item_class->get_extents = gimp_canvas_rectangle_get_extents;
99
g_object_class_install_property (object_class, PROP_X,
100
g_param_spec_double ("x", NULL, NULL,
101
-GIMP_MAX_IMAGE_SIZE,
102
GIMP_MAX_IMAGE_SIZE, 0,
103
GIMP_PARAM_READWRITE));
105
g_object_class_install_property (object_class, PROP_Y,
106
g_param_spec_double ("y", NULL, NULL,
107
-GIMP_MAX_IMAGE_SIZE,
108
GIMP_MAX_IMAGE_SIZE, 0,
109
GIMP_PARAM_READWRITE));
111
g_object_class_install_property (object_class, PROP_WIDTH,
112
g_param_spec_double ("width", NULL, NULL,
113
-GIMP_MAX_IMAGE_SIZE,
114
GIMP_MAX_IMAGE_SIZE, 0,
115
GIMP_PARAM_READWRITE));
117
g_object_class_install_property (object_class, PROP_HEIGHT,
118
g_param_spec_double ("height", NULL, NULL,
119
-GIMP_MAX_IMAGE_SIZE,
120
GIMP_MAX_IMAGE_SIZE, 0,
121
GIMP_PARAM_READWRITE));
123
g_object_class_install_property (object_class, PROP_FILLED,
124
g_param_spec_boolean ("filled", NULL, NULL,
126
GIMP_PARAM_READWRITE));
128
g_type_class_add_private (klass, sizeof (GimpCanvasRectanglePrivate));
132
gimp_canvas_rectangle_init (GimpCanvasRectangle *rectangle)
137
gimp_canvas_rectangle_set_property (GObject *object,
142
GimpCanvasRectanglePrivate *private = GET_PRIVATE (object);
147
private->x = g_value_get_double (value);
150
private->y = g_value_get_double (value);
153
private->width = g_value_get_double (value);
156
private->height = g_value_get_double (value);
159
private->filled = g_value_get_boolean (value);
163
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
169
gimp_canvas_rectangle_get_property (GObject *object,
174
GimpCanvasRectanglePrivate *private = GET_PRIVATE (object);
179
g_value_set_double (value, private->x);
182
g_value_set_double (value, private->y);
185
g_value_set_double (value, private->width);
188
g_value_set_double (value, private->height);
191
g_value_set_boolean (value, private->filled);
195
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
201
gimp_canvas_rectangle_transform (GimpCanvasItem *item,
202
GimpDisplayShell *shell,
208
GimpCanvasRectanglePrivate *private = GET_PRIVATE (item);
212
gimp_display_shell_transform_xy_f (shell,
214
private->x + private->width),
216
private->y + private->height),
218
gimp_display_shell_transform_xy_f (shell,
220
private->x + private->width),
222
private->y + private->height),
250
gimp_canvas_rectangle_draw (GimpCanvasItem *item,
251
GimpDisplayShell *shell,
254
GimpCanvasRectanglePrivate *private = GET_PRIVATE (item);
258
gimp_canvas_rectangle_transform (item, shell, &x, &y, &w, &h);
260
cairo_rectangle (cr, x, y, w, h);
263
_gimp_canvas_item_fill (item, cr);
265
_gimp_canvas_item_stroke (item, cr);
268
static cairo_region_t *
269
gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
270
GimpDisplayShell *shell)
272
GimpCanvasRectanglePrivate *private = GET_PRIVATE (item);
273
cairo_rectangle_int_t rectangle;
277
gimp_canvas_rectangle_transform (item, shell, &x, &y, &w, &h);
281
rectangle.x = floor (x - 1.0);
282
rectangle.y = floor (y - 1.0);
283
rectangle.width = ceil (w + 2.0);
284
rectangle.height = ceil (h + 2.0);
286
return cairo_region_create_rectangle (&rectangle);
288
else if (w > 64 && h > 64)
290
cairo_region_t *region;
293
rectangle.x = floor (x - 1.5);
294
rectangle.y = floor (y - 1.5);
295
rectangle.width = 3.0;
296
rectangle.height = ceil (h + 3.0);
298
region = cairo_region_create_rectangle (&rectangle);
301
rectangle.x = floor (x + w - 1.5);
303
cairo_region_union_rectangle (region, &rectangle);
306
rectangle.x = floor (x - 1.5);
307
rectangle.y = floor (y - 1.5);
308
rectangle.width = ceil (w + 3.0);
309
rectangle.height = 3.0;
311
cairo_region_union_rectangle (region, &rectangle);
314
rectangle.y = floor (y + h - 1.5);
316
cairo_region_union_rectangle (region, &rectangle);
322
rectangle.x = floor (x - 1.5);
323
rectangle.y = floor (y - 1.5);
324
rectangle.width = ceil (w + 3.0);
325
rectangle.height = ceil (h + 3.0);
327
return cairo_region_create_rectangle (&rectangle);
332
gimp_canvas_rectangle_new (GimpDisplayShell *shell,
339
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
341
return g_object_new (GIMP_TYPE_CANVAS_RECTANGLE,
352
gimp_canvas_rectangle_set (GimpCanvasItem *rectangle,
358
g_return_if_fail (GIMP_IS_CANVAS_RECTANGLE (rectangle));
360
gimp_canvas_item_begin_change (rectangle);
362
g_object_set (rectangle,
369
gimp_canvas_item_end_change (rectangle);