1
#define __INKSCAPE_CTRLRECT_C__
4
* Simple non-transformed rectangle, usable for rubberband
7
* Lauris Kaplinski <lauris@ximian.com>
8
* bulia byak <buliabyak@users.sf.net>
9
* Carl Hetherington <inkscape@carlh.net>
11
* Copyright (C) 1999-2001 Lauris Kaplinski
12
* Copyright (C) 2000-2001 Ximian, Inc.
14
* Released under GNU GPL
18
#include "display-forward.h"
19
#include "sp-canvas-util.h"
20
#include "sodipodi-ctrlrect.h"
23
* Currently we do not have point method, as it should always be painted
24
* during some transformation, which takes care of events...
26
* Corner coords can be in any order - i.e. x1 < x0 is allowed
29
static void sp_ctrlrect_class_init(SPCtrlRectClass *c);
30
static void sp_ctrlrect_init(CtrlRect *ctrlrect);
31
static void sp_ctrlrect_destroy(GtkObject *object);
33
static void sp_ctrlrect_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);
34
static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf);
36
static SPCanvasItemClass *parent_class;
38
static const guint DASH_LENGTH = 4;
40
GtkType sp_ctrlrect_get_type()
42
static GtkType ctrlrect_type = 0;
45
GtkTypeInfo ctrlrect_info = {
48
sizeof(SPCtrlRectClass),
49
(GtkClassInitFunc) sp_ctrlrect_class_init,
50
(GtkObjectInitFunc) sp_ctrlrect_init,
53
ctrlrect_type = gtk_type_unique(SP_TYPE_CANVAS_ITEM, &ctrlrect_info);
58
static void sp_ctrlrect_class_init(SPCtrlRectClass *c)
60
GtkObjectClass *object_class = (GtkObjectClass *) c;
61
SPCanvasItemClass *item_class = (SPCanvasItemClass *) c;
63
parent_class = (SPCanvasItemClass*) gtk_type_class(sp_canvas_item_get_type());
65
object_class->destroy = sp_ctrlrect_destroy;
67
item_class->update = sp_ctrlrect_update;
68
item_class->render = sp_ctrlrect_render;
71
static void sp_ctrlrect_init(CtrlRect *cr)
76
static void sp_ctrlrect_destroy(GtkObject *object)
78
if (GTK_OBJECT_CLASS(parent_class)->destroy) {
79
(* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
83
/* FIXME: use definitions from somewhere else */
84
#define RGBA_R(v) ((v) >> 24)
85
#define RGBA_G(v) (((v) >> 16) & 0xff)
86
#define RGBA_B(v) (((v) >> 8) & 0xff)
87
#define RGBA_A(v) ((v) & 0xff)
88
#define COMPOSE(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) / 0xff )
90
static void sp_ctrlrect_hline(SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba, guint dashed)
92
if (y >= buf->rect.y0 && y < buf->rect.y1) {
93
guint const r = RGBA_R(rgba);
94
guint const g = RGBA_G(rgba);
95
guint const b = RGBA_B(rgba);
96
guint const a = RGBA_A(rgba);
97
gint const x0 = MAX(buf->rect.x0, xs);
98
gint const x1 = MIN(buf->rect.x1, xe + 1);
99
guchar *p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3;
100
for (gint x = x0; x < x1; x++) {
101
if (!dashed || ((x / DASH_LENGTH) % 2)) {
102
p[0] = COMPOSE(p[0], r, a);
103
p[1] = COMPOSE(p[1], g, a);
104
p[2] = COMPOSE(p[2], b, a);
111
static void sp_ctrlrect_vline(SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba, guint dashed)
113
if (x >= buf->rect.x0 && x < buf->rect.x1) {
114
guint const r = RGBA_R(rgba);
115
guint const g = RGBA_G(rgba);
116
guint const b = RGBA_B(rgba);
117
guint const a = RGBA_A(rgba);
118
gint const y0 = MAX(buf->rect.y0, ys);
119
gint const y1 = MIN(buf->rect.y1, ye + 1);
120
guchar *p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
121
for (gint y = y0; y < y1; y++) {
122
if (!dashed || ((y / DASH_LENGTH) % 2)) {
123
p[0] = COMPOSE(p[0], r, a);
124
p[1] = COMPOSE(p[1], g, a);
125
p[2] = COMPOSE(p[2], b, a);
127
p += buf->buf_rowstride;
132
/** Fills the pixels in [xs, xe)*[ys,ye) clipped to the tile with rgb * a. */
133
static void sp_ctrlrect_area(SPCanvasBuf *buf, gint xs, gint ys, gint xe, gint ye, guint32 rgba)
135
guint const r = RGBA_R(rgba);
136
guint const g = RGBA_G(rgba);
137
guint const b = RGBA_B(rgba);
138
guint const a = RGBA_A(rgba);
139
gint const x0 = MAX(buf->rect.x0, xs);
140
gint const x1 = MIN(buf->rect.x1, xe + 1);
141
gint const y0 = MAX(buf->rect.y0, ys);
142
gint const y1 = MIN(buf->rect.y1, ye + 1);
143
for (gint y = y0; y < y1; y++) {
144
guchar *p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3;
145
for (gint x = x0; x < x1; x++) {
146
p[0] = COMPOSE(p[0], r, a);
147
p[1] = COMPOSE(p[1], g, a);
148
p[2] = COMPOSE(p[2], b, a);
154
static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf)
156
SP_CTRLRECT(item)->render(buf);
160
static void sp_ctrlrect_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)
162
SP_CTRLRECT(item)->update(affine, flags);
167
void CtrlRect::init()
173
_area.x0 = _area.y0 = 0;
174
_area.x1 = _area.y1 = -1;
178
_border_color = 0x000000ff;
179
_fill_color = 0xffffffff;
180
_shadow_color = 0x000000ff;
184
void CtrlRect::render(SPCanvasBuf *buf)
186
if ((_area.x0 < buf->rect.x1) &&
187
(_area.y0 < buf->rect.y1) &&
188
((_area.x1 + _shadow_size) >= buf->rect.x0) &&
189
((_area.y1 + _shadow_size) >= buf->rect.y0)) {
190
sp_canvas_prepare_buffer(buf);
193
sp_ctrlrect_hline(buf, _area.y0, _area.x0, _area.x1, _border_color, _dashed);
195
sp_ctrlrect_hline(buf, _area.y1, _area.x0, _area.x1, _border_color, _dashed);
197
sp_ctrlrect_vline(buf, _area.x0, _area.y0 + 1, _area.y1 - 1, _border_color, _dashed);
199
sp_ctrlrect_vline(buf, _area.x1, _area.y0 + 1, _area.y1 - 1, _border_color, _dashed);
200
if (_shadow_size > 0) {
202
sp_ctrlrect_area(buf, _area.x1 + 1, _area.y0 + _shadow_size,
203
_area.x1 + _shadow_size, _area.y1 + _shadow_size, _shadow_color);
205
sp_ctrlrect_area(buf, _area.x0 + _shadow_size, _area.y1 + 1,
206
_area.x1, _area.y1 + _shadow_size, _shadow_color);
210
sp_ctrlrect_area(buf, _area.x0 + 1, _area.y0 + 1,
211
_area.x1 - 1, _area.y1 - 1, _fill_color);
217
void CtrlRect::update(NR::Matrix const &affine, unsigned int flags)
219
if (((SPCanvasItemClass *) parent_class)->update) {
220
((SPCanvasItemClass *) parent_class)->update(this, affine, flags);
223
sp_canvas_item_reset_bounds(this);
225
/* Request redraw old */
228
sp_canvas_request_redraw(canvas,
229
_area.x0 - 1, _area.y0 - 1,
230
_area.x1 + 1, _area.y0 + 1);
232
sp_canvas_request_redraw(canvas,
233
_area.x0 - 1, _area.y0 - 1,
234
_area.x0 + 1, _area.y1 + 1);
236
sp_canvas_request_redraw(canvas,
237
_area.x1 - 1, _area.y0 - 1,
238
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
240
sp_canvas_request_redraw(canvas,
241
_area.x0 - 1, _area.y1 - 1,
242
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
244
sp_canvas_request_redraw(canvas,
245
_area.x0 - 1, _area.y0 - 1,
246
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
249
NR::Rect bbox(_rect.min() * affine, _rect.max() * affine);
251
_area.x0 = (int) floor(bbox.min()[NR::X] + 0.5);
252
_area.y0 = (int) floor(bbox.min()[NR::Y] + 0.5);
253
_area.x1 = (int) floor(bbox.max()[NR::X] + 0.5);
254
_area.y1 = (int) floor(bbox.max()[NR::Y] + 0.5);
256
_shadow_size = _shadow;
258
/* Request redraw new */
261
sp_canvas_request_redraw(canvas,
262
_area.x0 - 1, _area.y0 - 1,
263
_area.x1 + 1, _area.y0 + 1);
265
sp_canvas_request_redraw(canvas,
266
_area.x0 - 1, _area.y0 - 1,
267
_area.x0 + 1, _area.y1 + 1);
269
sp_canvas_request_redraw(canvas,
270
_area.x1 - 1, _area.y0 - 1,
271
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
273
sp_canvas_request_redraw(canvas,
274
_area.x0 - 1, _area.y1 - 1,
275
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
277
sp_canvas_request_redraw(canvas,
278
_area.x0 - 1, _area.y0 - 1,
279
_area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1);
284
x2 = _area.x1 + _shadow_size + 1;
285
y2 = _area.y1 + _shadow_size + 1;
289
void CtrlRect::setColor(guint32 b, bool h, guint f)
297
void CtrlRect::setShadow(int s, guint c)
304
void CtrlRect::setRectangle(NR::Rect const &r)
310
void CtrlRect::setDashed(bool d)
316
void CtrlRect::_requestUpdate()
318
sp_canvas_item_request_update(SP_CANVAS_ITEM(this));
324
c-file-style:"stroustrup"
325
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
330
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :