~ubuntu-branches/ubuntu/breezy/libgnomecanvas/breezy

« back to all changes in this revision

Viewing changes to libgnomecanvas/gnome-canvas-util.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2004-09-13 22:40:39 UTC
  • Revision ID: james.westby@ubuntu.com-20040913224039-giftt9jhvyoorcuv
Tags: upstream-2.8.0
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
 
3
 * All rights reserved.
 
4
 *
 
5
 * This file is part of the Gnome Library.
 
6
 *
 
7
 * The Gnome Library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Library General Public License as
 
9
 * published by the Free Software Foundation; either version 2 of the
 
10
 * License, or (at your option) any later version.
 
11
 *
 
12
 * The Gnome Library 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 GNU
 
15
 * Library General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Library General Public
 
18
 * License along with the Gnome Library; see the file COPYING.LIB.  If not,
 
19
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
20
 * Boston, MA 02111-1307, USA.
 
21
 */
 
22
/*
 
23
  @NOTATION@
 
24
 */
 
25
/* Miscellaneous utility functions for the GnomeCanvas widget
 
26
 *
 
27
 * GnomeCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
 
28
 * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
 
29
 *
 
30
 *
 
31
 * Author: Federico Mena <federico@nuclecu.unam.mx>
 
32
 */
 
33
 
 
34
#include <config.h>
 
35
 
 
36
/* needed for M_PI_2 under 'gcc -ansi -predantic' on GNU/Linux */
 
37
#ifndef _BSD_SOURCE
 
38
#  define _BSD_SOURCE 1
 
39
#endif
 
40
#include <sys/types.h>
 
41
 
 
42
#include <glib.h>
 
43
#include <math.h>
 
44
#include "gnome-canvas.h"
 
45
#include "gnome-canvas-util.h"
 
46
#include <libart_lgpl/art_uta.h>
 
47
#include <libart_lgpl/art_svp.h>
 
48
#include <libart_lgpl/art_svp_ops.h>
 
49
#include <libart_lgpl/art_rgb.h>
 
50
#include <libart_lgpl/art_rgb_svp.h>
 
51
#include <libart_lgpl/art_uta_svp.h>
 
52
#include <libart_lgpl/art_rect_svp.h>
 
53
 
 
54
/**
 
55
 * gnome_canvas_points_new:
 
56
 * @num_points: The number of points to allocate space for in the array.
 
57
 * 
 
58
 * Creates a structure that should be used to pass an array of points to
 
59
 * items.
 
60
 * 
 
61
 * Return value: A newly-created array of points.  It should be filled in
 
62
 * by the user.
 
63
 **/
 
64
GnomeCanvasPoints *
 
65
gnome_canvas_points_new (int num_points)
 
66
{
 
67
        GnomeCanvasPoints *points;
 
68
 
 
69
        g_return_val_if_fail (num_points > 1, NULL);
 
70
 
 
71
        points = g_new (GnomeCanvasPoints, 1);
 
72
        points->num_points = num_points;
 
73
        points->coords = g_new (double, 2 * num_points);
 
74
        points->ref_count = 1;
 
75
 
 
76
        return points;
 
77
}
 
78
 
 
79
/**
 
80
 * gnome_canvas_points_ref:
 
81
 * @points: A canvas points structure.
 
82
 * 
 
83
 * Increases the reference count of the specified points structure.
 
84
 * 
 
85
 * Return value: The canvas points structure itself.
 
86
 **/
 
87
GnomeCanvasPoints *
 
88
gnome_canvas_points_ref (GnomeCanvasPoints *points)
 
89
{
 
90
        g_return_val_if_fail (points != NULL, NULL);
 
91
 
 
92
        points->ref_count += 1;
 
93
        return points;
 
94
}
 
95
 
 
96
/**
 
97
 * gnome_canvas_points_free:
 
98
 * @points: A canvas points structure.
 
99
 * 
 
100
 * Decreases the reference count of the specified points structure.  If it
 
101
 * reaches zero, then the structure is freed.
 
102
 **/
 
103
void
 
104
gnome_canvas_points_free (GnomeCanvasPoints *points)
 
105
{
 
106
        g_return_if_fail (points != NULL);
 
107
 
 
108
        points->ref_count -= 1;
 
109
        if (points->ref_count == 0) {
 
110
                g_free (points->coords);
 
111
                g_free (points);
 
112
        }
 
113
}
 
114
 
 
115
/**
 
116
 * gnome_canvas_get_miter_points:
 
117
 * @x1: X coordinate of the first point
 
118
 * @y1: Y coordinate of the first point
 
119
 * @x2: X coordinate of the second (angle) point
 
120
 * @y2: Y coordinate of the second (angle) point
 
121
 * @x3: X coordinate of the third point
 
122
 * @y3: Y coordinate of the third point
 
123
 * @width: Width of the line
 
124
 * @mx1: The X coordinate of the first miter point is returned here.
 
125
 * @my1: The Y coordinate of the first miter point is returned here.
 
126
 * @mx2: The X coordinate of the second miter point is returned here.
 
127
 * @my2: The Y coordinate of the second miter point is returned here.
 
128
 * 
 
129
 * Given three points forming an angle, computes the coordinates of the inside
 
130
 * and outside points of the mitered corner formed by a line of a given width at
 
131
 * that angle.
 
132
 * 
 
133
 * Return value: FALSE if the angle is less than 11 degrees (this is the same
 
134
 * threshold as X uses.  If this occurs, the return points are not modified.
 
135
 * Otherwise, returns TRUE.
 
136
 **/
 
137
int
 
138
gnome_canvas_get_miter_points (double x1, double y1, double x2, double y2, double x3, double y3,
 
139
                               double width,
 
140
                               double *mx1, double *my1, double *mx2, double *my2)
 
141
{
 
142
        double theta1;          /* angle of segment p2-p1 */
 
143
        double theta2;          /* angle of segment p2-p3 */
 
144
        double theta;           /* angle between line segments */
 
145
        double theta3;          /* angle that bisects theta1 and theta2 and points to p1 */
 
146
        double dist;            /* distance of miter points from p2 */
 
147
        double dx, dy;          /* x and y offsets corresponding to dist */
 
148
 
 
149
#define ELEVEN_DEGREES (11.0 * G_PI / 180.0)
 
150
 
 
151
        if (y2 == y1)
 
152
                theta1 = (x2 < x1) ? 0.0 : G_PI;
 
153
        else if (x2 == x1)
 
154
                theta1 = (y2 < y1) ? G_PI_2 : -G_PI_2;
 
155
        else
 
156
                theta1 = atan2 (y1 - y2, x1 - x2);
 
157
 
 
158
        if (y3 == y2)
 
159
                theta2 = (x3 > x2) ? 0 : G_PI;
 
160
        else if (x3 == x2)
 
161
                theta2 = (y3 > y2) ? G_PI_2 : -G_PI_2;
 
162
        else
 
163
                theta2 = atan2 (y3 - y2, x3 - x2);
 
164
 
 
165
        theta = theta1 - theta2;
 
166
 
 
167
        if (theta > G_PI)
 
168
                theta -= 2.0 * G_PI;
 
169
        else if (theta < -G_PI)
 
170
                theta += 2.0 * G_PI;
 
171
 
 
172
        if ((theta < ELEVEN_DEGREES) && (theta > -ELEVEN_DEGREES))
 
173
                return FALSE;
 
174
 
 
175
        dist = 0.5 * width / sin (0.5 * theta);
 
176
        if (dist < 0.0)
 
177
                dist = -dist;
 
178
 
 
179
        theta3 = (theta1 + theta2) / 2.0;
 
180
        if (sin (theta3 - (theta1 + G_PI)) < 0.0)
 
181
                theta3 += G_PI;
 
182
 
 
183
        dx = dist * cos (theta3);
 
184
        dy = dist * sin (theta3);
 
185
 
 
186
        *mx1 = x2 + dx;
 
187
        *mx2 = x2 - dx;
 
188
        *my1 = y2 + dy;
 
189
        *my2 = y2 - dy;
 
190
 
 
191
        return TRUE;
 
192
}
 
193
 
 
194
/**
 
195
 * gnome_canvas_get_butt_points:
 
196
 * @x1: X coordinate of first point in the line
 
197
 * @y1: Y cooordinate of first point in the line
 
198
 * @x2: X coordinate of second point (endpoint) of the line
 
199
 * @y2: Y coordinate of second point (endpoint) of the line
 
200
 * @width: Width of the line
 
201
 * @project: Whether the butt points should project out by width/2 distance
 
202
 * @bx1: X coordinate of first butt point is returned here
 
203
 * @by1: Y coordinate of first butt point is returned here
 
204
 * @bx2: X coordinate of second butt point is returned here
 
205
 * @by2: Y coordinate of second butt point is returned here
 
206
 * 
 
207
 * Computes the butt points of a line segment.
 
208
 **/
 
209
void
 
210
gnome_canvas_get_butt_points (double x1, double y1, double x2, double y2,
 
211
                              double width, int project,
 
212
                              double *bx1, double *by1, double *bx2, double *by2)
 
213
{
 
214
        double length;
 
215
        double dx, dy;
 
216
 
 
217
        width *= 0.5;
 
218
        dx = x2 - x1;
 
219
        dy = y2 - y1;
 
220
        length = sqrt (dx * dx + dy * dy);
 
221
 
 
222
        if (length < GNOME_CANVAS_EPSILON) {
 
223
                *bx1 = *bx2 = x2;
 
224
                *by1 = *by2 = y2;
 
225
        } else {
 
226
                dx = -width * (y2 - y1) / length;
 
227
                dy = width * (x2 - x1) / length;
 
228
 
 
229
                *bx1 = x2 + dx;
 
230
                *bx2 = x2 - dx;
 
231
                *by1 = y2 + dy;
 
232
                *by2 = y2 - dy;
 
233
 
 
234
                if (project) {
 
235
                        *bx1 += dy;
 
236
                        *bx2 += dy;
 
237
                        *by1 -= dx;
 
238
                        *by2 -= dx;
 
239
                }
 
240
        }
 
241
}
 
242
 
 
243
/**
 
244
 * gnome_canvas_polygon_to_point:
 
245
 * @poly: Vertices of the polygon.  X coordinates are in the even indices, and Y
 
246
 * coordinates are in the odd indices
 
247
 * @num_points: Number of points in the polygon
 
248
 * @x: X coordinate of the point
 
249
 * @y: Y coordinate of the point
 
250
 * 
 
251
 * Computes the distance between a point and a polygon.
 
252
 * 
 
253
 * Return value: The distance from the point to the polygon, or zero if the
 
254
 * point is inside the polygon.
 
255
 **/
 
256
double
 
257
gnome_canvas_polygon_to_point (double *poly, int num_points, double x, double y)
 
258
{
 
259
        double best;
 
260
        int intersections;
 
261
        int i;
 
262
        double *p;
 
263
        double dx, dy;
 
264
 
 
265
        /* Iterate through all the edges in the polygon, updating best and intersections.
 
266
         *
 
267
         * When computing intersections, include left X coordinate of line within its range, but not
 
268
         * Y coordinate.  Otherwise if the point lies exactly below a vertex we'll count it as two
 
269
         * intersections.
 
270
         */
 
271
 
 
272
        best = 1.0e36;
 
273
        intersections = 0;
 
274
 
 
275
        for (i = num_points, p = poly; i > 1; i--, p += 2) {
 
276
                double px, py, dist;
 
277
 
 
278
                /* Compute the point on the current edge closest to the point and update the
 
279
                 * intersection count.  This must be done separately for vertical edges, horizontal
 
280
                 * edges, and others.
 
281
                 */
 
282
 
 
283
                if (p[2] == p[0]) {
 
284
                        /* Vertical edge */
 
285
 
 
286
                        px = p[0];
 
287
 
 
288
                        if (p[1] >= p[3]) {
 
289
                                py = MIN (p[1], y);
 
290
                                py = MAX (py, p[3]);
 
291
                        } else {
 
292
                                py = MIN (p[3], y);
 
293
                                py = MAX (py, p[1]);
 
294
                        }
 
295
                } else if (p[3] == p[1]) {
 
296
                        /* Horizontal edge */
 
297
 
 
298
                        py = p[1];
 
299
 
 
300
                        if (p[0] >= p[2]) {
 
301
                                px = MIN (p[0], x);
 
302
                                px = MAX (px, p[2]);
 
303
 
 
304
                                if ((y < py) && (x < p[0]) && (x >= p[2]))
 
305
                                        intersections++;
 
306
                        } else {
 
307
                                px = MIN (p[2], x);
 
308
                                px = MAX (px, p[0]);
 
309
 
 
310
                                if ((y < py) && (x < p[2]) && (x >= p[0]))
 
311
                                        intersections++;
 
312
                        }
 
313
                } else {
 
314
                        double m1, b1, m2, b2;
 
315
                        int lower;
 
316
 
 
317
                        /* Diagonal edge.  Convert the edge to a line equation (y = m1*x + b1), then
 
318
                         * compute a line perpendicular to this edge but passing through the point,
 
319
                         * (y = m2*x + b2).
 
320
                         */
 
321
 
 
322
                        m1 = (p[3] - p[1]) / (p[2] - p[0]);
 
323
                        b1 = p[1] - m1 * p[0];
 
324
 
 
325
                        m2 = -1.0 / m1;
 
326
                        b2 = y - m2 * x;
 
327
 
 
328
                        px = (b2 - b1) / (m1 - m2);
 
329
                        py = m1 * px + b1;
 
330
 
 
331
                        if (p[0] > p[2]) {
 
332
                                if (px > p[0]) {
 
333
                                        px = p[0];
 
334
                                        py = p[1];
 
335
                                } else if (px < p[2]) {
 
336
                                        px = p[2];
 
337
                                        py = p[3];
 
338
                                }
 
339
                        } else {
 
340
                                if (px > p[2]) {
 
341
                                        px = p[2];
 
342
                                        py = p[3];
 
343
                                } else if (px < p[0]) {
 
344
                                        px = p[0];
 
345
                                        py = p[1];
 
346
                                }
 
347
                        }
 
348
 
 
349
                        lower = (m1 * x + b1) > y;
 
350
 
 
351
                        if (lower && (x >= MIN (p[0], p[2])) && (x < MAX (p[0], p[2])))
 
352
                                intersections++;
 
353
                }
 
354
 
 
355
                /* Compute the distance to the closest point, and see if that is the best so far */
 
356
 
 
357
                dx = x - px;
 
358
                dy = y - py;
 
359
                dist = sqrt (dx * dx + dy * dy);
 
360
                if (dist < best)
 
361
                        best = dist;
 
362
        }
 
363
 
 
364
        /* We've processed all the points.  If the number of intersections is odd, the point is
 
365
         * inside the polygon.
 
366
         */
 
367
 
 
368
        if (intersections & 0x1)
 
369
                return 0.0;
 
370
        else
 
371
                return best;
 
372
}
 
373
 
 
374
/* Here are some helper functions for aa rendering: */
 
375
 
 
376
/**
 
377
 * gnome_canvas_render_svp:
 
378
 * @buf: the canvas buffer to render over
 
379
 * @svp: the vector path to render
 
380
 * @rgba: the rgba color to render
 
381
 *
 
382
 * Render the svp over the buf.
 
383
 **/
 
384
void
 
385
gnome_canvas_render_svp (GnomeCanvasBuf *buf, ArtSVP *svp, guint32 rgba)
 
386
{
 
387
        guint32 fg_color, bg_color;
 
388
        int alpha;
 
389
 
 
390
        if (buf->is_bg) {
 
391
                bg_color = buf->bg_color;
 
392
                alpha = rgba & 0xff;
 
393
                if (alpha == 0xff)
 
394
                        fg_color = rgba >> 8;
 
395
                else {
 
396
                        /* composite over background color */
 
397
                        int bg_r, bg_g, bg_b;
 
398
                        int fg_r, fg_g, fg_b;
 
399
                        int tmp;
 
400
 
 
401
                        bg_r = (bg_color >> 16) & 0xff;
 
402
                        fg_r = (rgba >> 24) & 0xff;
 
403
                        tmp = (fg_r - bg_r) * alpha;
 
404
                        fg_r = bg_r + ((tmp + (tmp >> 8) + 0x80) >> 8);
 
405
 
 
406
                        bg_g = (bg_color >> 8) & 0xff;
 
407
                        fg_g = (rgba >> 16) & 0xff;
 
408
                        tmp = (fg_g - bg_g) * alpha;
 
409
                        fg_g = bg_g + ((tmp + (tmp >> 8) + 0x80) >> 8);
 
410
 
 
411
                        bg_b = bg_color & 0xff;
 
412
                        fg_b = (rgba >> 8) & 0xff;
 
413
                        tmp = (fg_b - bg_b) * alpha;
 
414
                        fg_b = bg_b + ((tmp + (tmp >> 8) + 0x80) >> 8);
 
415
 
 
416
                        fg_color = (fg_r << 16) | (fg_g << 8) | fg_b;
 
417
                }
 
418
                art_rgb_svp_aa (svp,
 
419
                                buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1,
 
420
                                fg_color, bg_color,
 
421
                                buf->buf, buf->buf_rowstride,
 
422
                                NULL);
 
423
                buf->is_bg = 0;
 
424
                buf->is_buf = 1;
 
425
        } else {
 
426
                art_rgb_svp_alpha (svp,
 
427
                                   buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1,
 
428
                                   rgba,
 
429
                                   buf->buf, buf->buf_rowstride,
 
430
                                   NULL);
 
431
        }
 
432
}
 
433
 
 
434
/**
 
435
 * gnome_canvas_update_svp:
 
436
 * @canvas: the canvas containing the svp that needs updating.
 
437
 * @p_svp: a pointer to the existing svp
 
438
 * @new_svp: the new svp
 
439
 *
 
440
 * Sets the svp to the new value, requesting repaint on what's changed. This
 
441
 * function takes responsibility for freeing new_svp.
 
442
 **/
 
443
void
 
444
gnome_canvas_update_svp (GnomeCanvas *canvas, ArtSVP **p_svp, ArtSVP *new_svp)
 
445
{
 
446
        ArtSVP *old_svp;
 
447
        ArtSVP *diff G_GNUC_UNUSED;
 
448
        ArtUta *repaint_uta;
 
449
 
 
450
        old_svp = *p_svp;
 
451
 
 
452
        if (old_svp != NULL) {
 
453
                ArtDRect bb;
 
454
                art_drect_svp (&bb, old_svp);
 
455
                if ((bb.x1 - bb.x0) * (bb.y1 - bb.y0) > (64 * 64)) {
 
456
                        repaint_uta = art_uta_from_svp (old_svp);
 
457
                        gnome_canvas_request_redraw_uta (canvas, repaint_uta);
 
458
                } else {
 
459
                        ArtIRect ib;
 
460
                        art_drect_to_irect (&ib, &bb);
 
461
                        gnome_canvas_request_redraw (canvas, ib.x0, ib.y0, ib.x1, ib.y1);
 
462
                }
 
463
                art_svp_free (old_svp);
 
464
        }
 
465
 
 
466
        if (new_svp != NULL) {
 
467
                ArtDRect bb;
 
468
                art_drect_svp (&bb, new_svp);
 
469
                if ((bb.x1 - bb.x0) * (bb.y1 - bb.y0) > (64 * 64)) {
 
470
                        repaint_uta = art_uta_from_svp (new_svp);
 
471
                        gnome_canvas_request_redraw_uta (canvas, repaint_uta);
 
472
                } else {
 
473
                        ArtIRect ib;
 
474
                        art_drect_to_irect (&ib, &bb);
 
475
                        gnome_canvas_request_redraw (canvas, ib.x0, ib.y0, ib.x1, ib.y1);
 
476
                }
 
477
        }
 
478
 
 
479
        *p_svp = new_svp;
 
480
}
 
481
 
 
482
/**
 
483
 * gnome_canvas_update_svp_clip:
 
484
 * @canvas: the canvas containing the svp that needs updating.
 
485
 * @p_svp: a pointer to the existing svp
 
486
 * @new_svp: the new svp
 
487
 * @clip_svp: a clip path, if non-null
 
488
 *
 
489
 * Sets the svp to the new value, clipping if necessary, and requesting repaint
 
490
 * on what's changed. This function takes responsibility for freeing new_svp.
 
491
 **/
 
492
void
 
493
gnome_canvas_update_svp_clip (GnomeCanvas *canvas, ArtSVP **p_svp, ArtSVP *new_svp, ArtSVP *clip_svp)
 
494
{
 
495
        ArtSVP *clipped_svp;
 
496
 
 
497
        if (clip_svp != NULL) {
 
498
                clipped_svp = art_svp_intersect (new_svp, clip_svp);
 
499
                art_svp_free (new_svp);
 
500
        } else {
 
501
                clipped_svp = new_svp;
 
502
        }
 
503
        gnome_canvas_update_svp (canvas, p_svp, clipped_svp);
 
504
}
 
505
 
 
506
/**
 
507
 * gnome_canvas_item_reset_bounds:
 
508
 * @item: A canvas item
 
509
 * 
 
510
 * Resets the bounding box of a canvas item to an empty rectangle.
 
511
 **/
 
512
void
 
513
gnome_canvas_item_reset_bounds (GnomeCanvasItem *item)
 
514
{
 
515
        item->x1 = 0.0;
 
516
        item->y1 = 0.0;
 
517
        item->x2 = 0.0;
 
518
        item->y2 = 0.0;
 
519
}
 
520
 
 
521
/**
 
522
 * gnome_canvas_item_update_svp:
 
523
 * @item: the canvas item containing the svp that needs updating.
 
524
 * @p_svp: a pointer to the existing svp
 
525
 * @new_svp: the new svp
 
526
 *
 
527
 * Sets the svp to the new value, requesting repaint on what's changed. This
 
528
 * function takes responsibility for freeing new_svp. This routine also adds the
 
529
 * svp's bbox to the item's.
 
530
 **/
 
531
void
 
532
gnome_canvas_item_update_svp (GnomeCanvasItem *item, ArtSVP **p_svp, ArtSVP *new_svp)
 
533
{
 
534
        ArtDRect bbox;
 
535
 
 
536
        gnome_canvas_update_svp (item->canvas, p_svp, new_svp);
 
537
        if (new_svp) {
 
538
                bbox.x0 = item->x1;
 
539
                bbox.y0 = item->y1;
 
540
                bbox.x1 = item->x2;
 
541
                bbox.y1 = item->y2;
 
542
                art_drect_svp_union (&bbox, new_svp);
 
543
                item->x1 = bbox.x0;
 
544
                item->y1 = bbox.y0;
 
545
                item->x2 = bbox.x1;
 
546
                item->y2 = bbox.y1;
 
547
        }
 
548
}
 
549
 
 
550
/**
 
551
 * gnome_canvas_item_update_svp_clip:
 
552
 * @item: the canvas item containing the svp that needs updating.
 
553
 * @p_svp: a pointer to the existing svp
 
554
 * @new_svp: the new svp
 
555
 * @clip_svp: a clip path, if non-null
 
556
 *
 
557
 * Sets the svp to the new value, clipping if necessary, and requesting repaint
 
558
 * on what's changed. This function takes responsibility for freeing new_svp.
 
559
 **/
 
560
void
 
561
gnome_canvas_item_update_svp_clip (GnomeCanvasItem *item, ArtSVP **p_svp, ArtSVP *new_svp,
 
562
                                   ArtSVP *clip_svp)
 
563
{
 
564
        ArtSVP *clipped_svp;
 
565
 
 
566
        if (clip_svp != NULL) {
 
567
                clipped_svp = art_svp_intersect (new_svp, clip_svp);
 
568
                art_svp_free (new_svp);
 
569
        } else {
 
570
                clipped_svp = new_svp;
 
571
        }
 
572
 
 
573
        gnome_canvas_item_update_svp (item, p_svp, clipped_svp);
 
574
}
 
575
 
 
576
/**
 
577
 * gnome_canvas_item_request_redraw_svp
 
578
 * @item: the item containing the svp
 
579
 * @svp: the svp that needs to be redrawn
 
580
 *
 
581
 * Request redraw of the svp if in aa mode, or the entire item in in xlib mode.
 
582
 **/ 
 
583
void
 
584
gnome_canvas_item_request_redraw_svp (GnomeCanvasItem *item, const ArtSVP *svp)
 
585
{
 
586
        GnomeCanvas *canvas;
 
587
        ArtUta *uta;
 
588
 
 
589
        canvas = item->canvas;
 
590
        if (canvas->aa) {
 
591
                if (svp != NULL) {
 
592
                        uta = art_uta_from_svp (svp);
 
593
                        gnome_canvas_request_redraw_uta (canvas, uta);
 
594
                }
 
595
        } else {
 
596
                gnome_canvas_request_redraw (canvas, item->x1, item->y1, item->x2, item->y2);           
 
597
        }
 
598
}
 
599
 
 
600
/**
 
601
 * gnome_canvas_update_bbox:
 
602
 * @item: the canvas item needing update
 
603
 * @x1: Left coordinate of the new bounding box
 
604
 * @y1: Top coordinate of the new bounding box
 
605
 * @x2: Right coordinate of the new bounding box
 
606
 * @y2: Bottom coordinate of the new bounding box
 
607
 *
 
608
 * Sets the bbox to the new value, requesting full repaint.
 
609
 **/
 
610
void
 
611
gnome_canvas_update_bbox (GnomeCanvasItem *item, int x1, int y1, int x2, int y2)
 
612
{
 
613
        gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 
614
        item->x1 = x1;
 
615
        item->y1 = y1;
 
616
        item->x2 = x2;
 
617
        item->y2 = y2;
 
618
        gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 
619
}
 
620
 
 
621
/**
 
622
 * gnome_canvas_buf_ensure_buf:
 
623
 * @buf: the buf that needs to be represened in RGB format
 
624
 *
 
625
 * Ensure that the buffer is in RGB format, suitable for compositing.
 
626
 **/
 
627
void
 
628
gnome_canvas_buf_ensure_buf (GnomeCanvasBuf *buf)
 
629
{
 
630
        guchar *bufptr;
 
631
        int y;
 
632
 
 
633
        if (!buf->is_buf) {
 
634
                bufptr = buf->buf;
 
635
                for (y = buf->rect.y0; y < buf->rect.y1; y++) {
 
636
                        art_rgb_fill_run (bufptr,
 
637
                                          buf->bg_color >> 16,
 
638
                                          (buf->bg_color >> 8) & 0xff,
 
639
                                          buf->bg_color & 0xff,
 
640
                                          buf->rect.x1 - buf->rect.x0);
 
641
                        bufptr += buf->buf_rowstride;
 
642
                }
 
643
                buf->is_buf = 1;
 
644
        }
 
645
}
 
646
 
 
647
/**
 
648
 * gnome_canvas_join_gdk_to_art
 
649
 * @gdk_join: a join type, represented in GDK format
 
650
 *
 
651
 * Convert from GDK line join specifier to libart.
 
652
 *
 
653
 * Return value: The line join specifier in libart format.
 
654
 **/
 
655
ArtPathStrokeJoinType
 
656
gnome_canvas_join_gdk_to_art (GdkJoinStyle gdk_join)
 
657
{
 
658
        switch (gdk_join) {
 
659
        case GDK_JOIN_MITER:
 
660
                return ART_PATH_STROKE_JOIN_MITER;
 
661
 
 
662
        case GDK_JOIN_ROUND:
 
663
                return ART_PATH_STROKE_JOIN_ROUND;
 
664
 
 
665
        case GDK_JOIN_BEVEL:
 
666
                return ART_PATH_STROKE_JOIN_BEVEL;
 
667
 
 
668
        default:
 
669
                g_assert_not_reached ();
 
670
                return ART_PATH_STROKE_JOIN_MITER; /* shut up the compiler */
 
671
        }
 
672
}
 
673
 
 
674
/**
 
675
 * gnome_canvas_cap_gdk_to_art
 
676
 * @gdk_cap: a cap type, represented in GDK format
 
677
 *
 
678
 * Convert from GDK line cap specifier to libart.
 
679
 *
 
680
 * Return value: The line cap specifier in libart format.
 
681
 **/
 
682
ArtPathStrokeCapType
 
683
gnome_canvas_cap_gdk_to_art (GdkCapStyle gdk_cap)
 
684
{
 
685
        switch (gdk_cap) {
 
686
        case GDK_CAP_BUTT:
 
687
        case GDK_CAP_NOT_LAST:
 
688
                return ART_PATH_STROKE_CAP_BUTT;
 
689
 
 
690
        case GDK_CAP_ROUND:
 
691
                return ART_PATH_STROKE_CAP_ROUND;
 
692
 
 
693
        case GDK_CAP_PROJECTING:
 
694
                return ART_PATH_STROKE_CAP_SQUARE;
 
695
 
 
696
        default:
 
697
                g_assert_not_reached ();
 
698
                return ART_PATH_STROKE_CAP_BUTT; /* shut up the compiler */
 
699
        }
 
700
}