2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This software is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <libgnomecanvas/libgnomecanvas.h>
24 #include <libart_lgpl/art_vpath_dash.h>
25 #include <libart_lgpl/art_svp_point.h>
26 #include <libart_lgpl/art_svp_vpath.h>
29 #include "xo-callbacks.h"
30 #include "xo-interface.h"
31 #include "xo-support.h"
34 #include "xo-selection.h"
36 /************ selection tools ***********/
38 void make_dashed(GnomeCanvasItem *item)
46 dashlen[0] = dashlen[1] = 6.0;
47 gnome_canvas_item_set(item, "dash", &dash, NULL);
51 void start_selectrect(GdkEvent *event)
56 ui.cur_item_type = ITEM_SELECTRECT;
57 ui.selection = g_new(struct Selection, 1);
58 ui.selection->type = ITEM_SELECTRECT;
59 ui.selection->items = NULL;
60 ui.selection->layer = ui.cur_layer;
62 get_pointer_coords(event, pt);
63 ui.selection->bbox.left = ui.selection->bbox.right = pt[0];
64 ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1];
66 ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
67 gnome_canvas_rect_get_type(), "width-pixels", 1,
68 "outline-color-rgba", 0x000000ff,
69 "fill-color-rgba", 0x80808040,
70 "x1", pt[0], "x2", pt[0], "y1", pt[1], "y2", pt[1], NULL);
74 void finalize_selectrect(void)
76 double x1, x2, y1, y2;
80 ui.cur_item_type = ITEM_NONE;
82 if (ui.selection->bbox.left > ui.selection->bbox.right) {
83 x1 = ui.selection->bbox.right; x2 = ui.selection->bbox.left;
84 ui.selection->bbox.left = x1; ui.selection->bbox.right = x2;
86 x1 = ui.selection->bbox.left; x2 = ui.selection->bbox.right;
89 if (ui.selection->bbox.top > ui.selection->bbox.bottom) {
90 y1 = ui.selection->bbox.bottom; y2 = ui.selection->bbox.top;
91 ui.selection->bbox.top = y1; ui.selection->bbox.bottom = y2;
93 y1 = ui.selection->bbox.top; y2 = ui.selection->bbox.bottom;
96 for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
97 item = (struct Item *)itemlist->data;
98 if (item->bbox.left >= x1 && item->bbox.right <= x2 &&
99 item->bbox.top >= y1 && item->bbox.bottom <= y2) {
100 ui.selection->items = g_list_append(ui.selection->items, item);
104 if (ui.selection->items == NULL) {
105 // if we clicked inside a text zone or image?
106 item = click_is_in_text_or_image(ui.selection->layer, x1, y1);
107 if (item!=NULL && item==click_is_in_text_or_image(ui.selection->layer, x2, y2)) {
108 ui.selection->items = g_list_append(ui.selection->items, item);
109 g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
110 gnome_canvas_item_set(ui.selection->canvas_item,
111 "x1", item->bbox.left, "x2", item->bbox.right,
112 "y1", item->bbox.top, "y2", item->bbox.bottom, NULL);
116 if (ui.selection->items == NULL) reset_selection();
117 else make_dashed(ui.selection->canvas_item);
119 update_copy_paste_enabled();
120 update_font_button();
124 void start_selectregion(GdkEvent *event)
129 ui.cur_item_type = ITEM_SELECTREGION;
130 ui.selection = g_new(struct Selection, 1);
131 ui.selection->type = ITEM_SELECTREGION;
132 ui.selection->items = NULL;
133 ui.selection->layer = ui.cur_layer;
135 get_pointer_coords(event, pt);
136 ui.selection->bbox.left = ui.selection->bbox.right = pt[0];
137 ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1];
140 ui.cur_path.num_points = 1;
141 ui.cur_path.coords[0] = ui.cur_path.coords[2] = pt[0];
142 ui.cur_path.coords[1] = ui.cur_path.coords[3] = pt[1];
144 ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
145 gnome_canvas_polygon_get_type(), "width-pixels", 1,
146 "outline-color-rgba", 0x000000ff,
147 "fill-color-rgba", 0x80808040,
149 make_dashed(ui.selection->canvas_item);
153 void continue_selectregion(GdkEvent *event)
157 realloc_cur_path(ui.cur_path.num_points+1);
158 pt = ui.cur_path.coords + 2*ui.cur_path.num_points;
159 get_pointer_coords(event, pt);
160 if (hypot(pt[0]-pt[-2], pt[1]-pt[-1]) < PIXEL_MOTION_THRESHOLD/ui.zoom)
161 return; // not a meaningful motion
162 ui.cur_path.num_points++;
163 if (ui.cur_path.num_points>2)
164 gnome_canvas_item_set(ui.selection->canvas_item,
165 "points", &ui.cur_path, NULL);
168 /* check whether a point, resp. an item, is inside a lasso selection */
170 gboolean hittest_point(ArtSVP *lassosvp, double x, double y)
172 return art_svp_point_wind(lassosvp, x, y)%2;
175 gboolean hittest_item(ArtSVP *lassosvp, struct Item *item)
179 if (item->type == ITEM_STROKE) {
180 for (i=0; i<item->path->num_points; i++)
181 if (!hittest_point(lassosvp, item->path->coords[2*i], item->path->coords[2*i+1]))
186 return (hittest_point(lassosvp, item->bbox.left, item->bbox.top) &&
187 hittest_point(lassosvp, item->bbox.right, item->bbox.top) &&
188 hittest_point(lassosvp, item->bbox.left, item->bbox.bottom) &&
189 hittest_point(lassosvp, item->bbox.right, item->bbox.bottom));
192 void finalize_selectregion(void)
201 ui.cur_item_type = ITEM_NONE;
203 // build SVP for the lasso path
204 n = ui.cur_path.num_points;
205 vpath = g_malloc((n+2)*sizeof(ArtVpath));
206 for (i=0; i<n; i++) {
207 vpath[i].x = ui.cur_path.coords[2*i];
208 vpath[i].y = ui.cur_path.coords[2*i+1];
210 vpath[n].x = vpath[0].x; vpath[n].y = vpath[0].y;
211 vpath[0].code = ART_MOVETO;
212 for (i=1; i<=n; i++) vpath[i].code = ART_LINETO;
213 vpath[n+1].code = ART_END;
214 lassosvp = art_svp_from_vpath(vpath);
217 // see which items we selected
218 for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
219 item = (struct Item *)itemlist->data;
220 if (hittest_item(lassosvp, item)) {
221 // update the selection bbox
222 if (ui.selection->items==NULL || ui.selection->bbox.left>item->bbox.left)
223 ui.selection->bbox.left = item->bbox.left;
224 if (ui.selection->items==NULL || ui.selection->bbox.right<item->bbox.right)
225 ui.selection->bbox.right = item->bbox.right;
226 if (ui.selection->items==NULL || ui.selection->bbox.top>item->bbox.top)
227 ui.selection->bbox.top = item->bbox.top;
228 if (ui.selection->items==NULL || ui.selection->bbox.bottom<item->bbox.bottom)
229 ui.selection->bbox.bottom = item->bbox.bottom;
231 ui.selection->items = g_list_append(ui.selection->items, item);
234 art_svp_free(lassosvp);
236 if (ui.selection->items == NULL) {
237 // if we clicked inside a text zone or image?
238 pt = ui.cur_path.coords;
239 item = click_is_in_text_or_image(ui.selection->layer, pt[0], pt[1]);
241 for (i=0; i<n; i++, pt+=2) {
242 if (pt[0]<item->bbox.left || pt[0]>item->bbox.right || pt[1]<item->bbox.top || pt[1]>item->bbox.bottom)
243 { item = NULL; break; }
247 ui.selection->items = g_list_append(ui.selection->items, item);
248 g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
252 if (ui.selection->items == NULL) reset_selection();
253 else { // make a selection rectangle instead of the lasso shape
254 gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item));
255 ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
256 gnome_canvas_rect_get_type(), "width-pixels", 1,
257 "outline-color-rgba", 0x000000ff,
258 "fill-color-rgba", 0x80808040,
259 "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right,
260 "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
261 make_dashed(ui.selection->canvas_item);
262 ui.selection->type = ITEM_SELECTRECT;
266 update_copy_paste_enabled();
267 update_font_button();
271 /*** moving/resizing the selection ***/
273 gboolean start_movesel(GdkEvent *event)
277 if (ui.selection==NULL) return FALSE;
278 if (ui.cur_layer != ui.selection->layer) return FALSE;
280 get_pointer_coords(event, pt);
281 if (ui.selection->type == ITEM_SELECTRECT || ui.selection->type == ITEM_SELECTREGION) {
282 if (pt[0]<ui.selection->bbox.left || pt[0]>ui.selection->bbox.right ||
283 pt[1]<ui.selection->bbox.top || pt[1]>ui.selection->bbox.bottom)
285 ui.cur_item_type = ITEM_MOVESEL;
286 ui.selection->anchor_x = ui.selection->last_x = pt[0];
287 ui.selection->anchor_y = ui.selection->last_y = pt[1];
288 ui.selection->orig_pageno = ui.pageno;
289 ui.selection->move_pageno = ui.pageno;
290 ui.selection->move_layer = ui.selection->layer;
291 ui.selection->move_pagedelta = 0.;
292 gnome_canvas_item_set(ui.selection->canvas_item, "dash", NULL, NULL);
299 gboolean start_resizesel(GdkEvent *event)
301 double pt[2], resize_margin, hmargin, vmargin;
303 if (ui.selection==NULL) return FALSE;
304 if (ui.cur_layer != ui.selection->layer) return FALSE;
306 get_pointer_coords(event, pt);
308 if (ui.selection->type == ITEM_SELECTRECT || ui.selection->type == ITEM_SELECTREGION) {
309 resize_margin = RESIZE_MARGIN/ui.zoom;
310 hmargin = (ui.selection->bbox.right-ui.selection->bbox.left)*0.3;
311 if (hmargin>resize_margin) hmargin = resize_margin;
312 vmargin = (ui.selection->bbox.bottom-ui.selection->bbox.top)*0.3;
313 if (vmargin>resize_margin) vmargin = resize_margin;
315 // make sure the click is within a box slightly bigger than the selection rectangle
316 if (pt[0]<ui.selection->bbox.left-resize_margin ||
317 pt[0]>ui.selection->bbox.right+resize_margin ||
318 pt[1]<ui.selection->bbox.top-resize_margin ||
319 pt[1]>ui.selection->bbox.bottom+resize_margin)
322 // now, if the click is near the edge, it's a resize operation
323 // keep track of which edges we're close to, since those are the ones which should move
324 ui.selection->resizing_left = (pt[0]<ui.selection->bbox.left+hmargin);
325 ui.selection->resizing_right = (pt[0]>ui.selection->bbox.right-hmargin);
326 ui.selection->resizing_top = (pt[1]<ui.selection->bbox.top+vmargin);
327 ui.selection->resizing_bottom = (pt[1]>ui.selection->bbox.bottom-vmargin);
329 // we're not near any edge, give up
330 if (!(ui.selection->resizing_left || ui.selection->resizing_right ||
331 ui.selection->resizing_top || ui.selection->resizing_bottom))
334 ui.cur_item_type = ITEM_RESIZESEL;
335 ui.selection->new_y1 = ui.selection->bbox.top;
336 ui.selection->new_y2 = ui.selection->bbox.bottom;
337 ui.selection->new_x1 = ui.selection->bbox.left;
338 ui.selection->new_x2 = ui.selection->bbox.right;
339 gnome_canvas_item_set(ui.selection->canvas_item, "dash", NULL, NULL);
340 update_cursor_for_resize(pt);
347 void start_vertspace(GdkEvent *event)
354 ui.cur_item_type = ITEM_MOVESEL_VERT;
355 ui.selection = g_new(struct Selection, 1);
356 ui.selection->type = ITEM_MOVESEL_VERT;
357 ui.selection->items = NULL;
358 ui.selection->layer = ui.cur_layer;
360 get_pointer_coords(event, pt);
361 ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1];
362 for (itemlist = ui.cur_layer->items; itemlist!=NULL; itemlist = itemlist->next) {
363 item = (struct Item *)itemlist->data;
364 if (item->bbox.top >= pt[1]) {
365 ui.selection->items = g_list_append(ui.selection->items, item);
366 if (item->bbox.bottom > ui.selection->bbox.bottom)
367 ui.selection->bbox.bottom = item->bbox.bottom;
371 ui.selection->anchor_x = ui.selection->last_x = 0;
372 ui.selection->anchor_y = ui.selection->last_y = pt[1];
373 ui.selection->orig_pageno = ui.pageno;
374 ui.selection->move_pageno = ui.pageno;
375 ui.selection->move_layer = ui.selection->layer;
376 ui.selection->move_pagedelta = 0.;
377 ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
378 gnome_canvas_rect_get_type(), "width-pixels", 1,
379 "outline-color-rgba", 0x000000ff,
380 "fill-color-rgba", 0x80808040,
381 "x1", -100.0, "x2", ui.cur_page->width+100, "y1", pt[1], "y2", pt[1], NULL);
385 void continue_movesel(GdkEvent *event)
387 double pt[2], dx, dy, upmargin;
391 struct Page *tmppage;
393 get_pointer_coords(event, pt);
394 if (ui.cur_item_type == ITEM_MOVESEL_VERT) pt[0] = 0;
395 pt[1] += ui.selection->move_pagedelta;
397 // check for page jumps
398 if (ui.cur_item_type == ITEM_MOVESEL_VERT)
399 upmargin = ui.selection->bbox.bottom - ui.selection->bbox.top;
400 else upmargin = VIEW_CONTINUOUS_SKIP;
401 tmppageno = ui.selection->move_pageno;
402 tmppage = g_list_nth_data(journal.pages, tmppageno);
403 while (ui.view_continuous && (pt[1] < - upmargin)) {
404 if (tmppageno == 0) break;
406 tmppage = g_list_nth_data(journal.pages, tmppageno);
407 pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
408 ui.selection->move_pagedelta += tmppage->height + VIEW_CONTINUOUS_SKIP;
410 while (ui.view_continuous && (pt[1] > tmppage->height+VIEW_CONTINUOUS_SKIP)) {
411 if (tmppageno == journal.npages-1) break;
412 pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
413 ui.selection->move_pagedelta -= tmppage->height + VIEW_CONTINUOUS_SKIP;
415 tmppage = g_list_nth_data(journal.pages, tmppageno);
418 if (tmppageno != ui.selection->move_pageno) {
419 // move to a new page !
420 ui.selection->move_pageno = tmppageno;
421 if (tmppageno == ui.selection->orig_pageno)
422 ui.selection->move_layer = ui.selection->layer;
424 ui.selection->move_layer = (struct Layer *)(g_list_last(
425 ((struct Page *)g_list_nth_data(journal.pages, tmppageno))->layers)->data);
426 gnome_canvas_item_reparent(ui.selection->canvas_item, ui.selection->move_layer->group);
427 for (list = ui.selection->items; list!=NULL; list = list->next) {
428 item = (struct Item *)list->data;
429 if (item->canvas_item!=NULL)
430 gnome_canvas_item_reparent(item->canvas_item, ui.selection->move_layer->group);
432 // avoid a refresh bug
433 gnome_canvas_item_move(GNOME_CANVAS_ITEM(ui.selection->move_layer->group), 0., 0.);
434 if (ui.cur_item_type == ITEM_MOVESEL_VERT)
435 gnome_canvas_item_set(ui.selection->canvas_item,
436 "x2", tmppage->width+100,
437 "y1", ui.selection->anchor_y+ui.selection->move_pagedelta, NULL);
440 // now, process things normally
442 dx = pt[0] - ui.selection->last_x;
443 dy = pt[1] - ui.selection->last_y;
444 if (hypot(dx,dy) < 1) return; // don't move subpixel
445 ui.selection->last_x = pt[0];
446 ui.selection->last_y = pt[1];
448 // move the canvas items
449 if (ui.cur_item_type == ITEM_MOVESEL_VERT)
450 gnome_canvas_item_set(ui.selection->canvas_item, "y2", pt[1], NULL);
452 gnome_canvas_item_move(ui.selection->canvas_item, dx, dy);
454 for (list = ui.selection->items; list != NULL; list = list->next) {
455 item = (struct Item *)list->data;
456 if (item->canvas_item != NULL)
457 gnome_canvas_item_move(item->canvas_item, dx, dy);
461 void continue_resizesel(GdkEvent *event)
465 get_pointer_coords(event, pt);
467 if (ui.selection->resizing_top) ui.selection->new_y1 = pt[1];
468 if (ui.selection->resizing_bottom) ui.selection->new_y2 = pt[1];
469 if (ui.selection->resizing_left) ui.selection->new_x1 = pt[0];
470 if (ui.selection->resizing_right) ui.selection->new_x2 = pt[0];
472 gnome_canvas_item_set(ui.selection->canvas_item,
473 "x1", ui.selection->new_x1, "x2", ui.selection->new_x2,
474 "y1", ui.selection->new_y1, "y2", ui.selection->new_y2, NULL);
477 void finalize_movesel(void)
481 if (ui.selection->items != NULL) {
483 undo->type = ITEM_MOVESEL;
484 undo->itemlist = g_list_copy(ui.selection->items);
485 undo->val_x = ui.selection->last_x - ui.selection->anchor_x;
486 undo->val_y = ui.selection->last_y - ui.selection->anchor_y;
487 undo->layer = ui.selection->layer;
488 undo->layer2 = ui.selection->move_layer;
489 undo->auxlist = NULL;
490 // build auxlist = pointers to Item's just before ours (for depths)
491 for (list = ui.selection->items; list!=NULL; list = list->next) {
492 link = g_list_find(ui.selection->layer->items, list->data);
493 if (link!=NULL) link = link->prev;
494 undo->auxlist = g_list_append(undo->auxlist, ((link!=NULL) ? link->data : NULL));
496 ui.selection->layer = ui.selection->move_layer;
497 move_journal_items_by(undo->itemlist, undo->val_x, undo->val_y,
498 undo->layer, undo->layer2,
499 (undo->layer == undo->layer2)?undo->auxlist:NULL);
502 if (ui.selection->move_pageno!=ui.selection->orig_pageno)
503 do_switch_page(ui.selection->move_pageno, FALSE, FALSE);
505 if (ui.cur_item_type == ITEM_MOVESEL_VERT)
508 ui.selection->bbox.left += undo->val_x;
509 ui.selection->bbox.right += undo->val_x;
510 ui.selection->bbox.top += undo->val_y;
511 ui.selection->bbox.bottom += undo->val_y;
512 make_dashed(ui.selection->canvas_item);
513 /* update selection box object's offset to be trivial, and its internal
514 coordinates to agree with those of the bbox; need this since resize
515 operations will modify the box by setting its coordinates directly */
516 gnome_canvas_item_affine_absolute(ui.selection->canvas_item, NULL);
517 gnome_canvas_item_set(ui.selection->canvas_item,
518 "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right,
519 "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
521 ui.cur_item_type = ITEM_NONE;
525 #define SCALING_EPSILON 0.001
527 void finalize_resizesel(void)
531 // build the affine transformation
532 double offset_x, offset_y, scaling_x, scaling_y;
533 scaling_x = (ui.selection->new_x2 - ui.selection->new_x1) /
534 (ui.selection->bbox.right - ui.selection->bbox.left);
535 scaling_y = (ui.selection->new_y2 - ui.selection->new_y1) /
536 (ui.selection->bbox.bottom - ui.selection->bbox.top);
537 // couldn't undo a resize-by-zero...
538 if (fabs(scaling_x)<SCALING_EPSILON) scaling_x = SCALING_EPSILON;
539 if (fabs(scaling_y)<SCALING_EPSILON) scaling_y = SCALING_EPSILON;
540 offset_x = ui.selection->new_x1 - ui.selection->bbox.left * scaling_x;
541 offset_y = ui.selection->new_y1 - ui.selection->bbox.top * scaling_y;
543 if (ui.selection->items != NULL) {
544 // create the undo information
546 undo->type = ITEM_RESIZESEL;
547 undo->itemlist = g_list_copy(ui.selection->items);
548 undo->auxlist = NULL;
550 undo->scaling_x = scaling_x;
551 undo->scaling_y = scaling_y;
552 undo->val_x = offset_x;
553 undo->val_y = offset_y;
555 // actually do the resize operation
556 resize_journal_items_by(ui.selection->items, scaling_x, scaling_y, offset_x, offset_y);
560 ui.selection->bbox.left = ui.selection->new_x1;
561 ui.selection->bbox.right = ui.selection->new_x2;
563 ui.selection->bbox.left = ui.selection->new_x2;
564 ui.selection->bbox.right = ui.selection->new_x1;
567 ui.selection->bbox.top = ui.selection->new_y1;
568 ui.selection->bbox.bottom = ui.selection->new_y2;
570 ui.selection->bbox.top = ui.selection->new_y2;
571 ui.selection->bbox.bottom = ui.selection->new_y1;
573 make_dashed(ui.selection->canvas_item);
575 ui.cur_item_type = ITEM_NONE;
579 void selection_delete(void)
581 struct UndoErasureData *erasure;
585 if (ui.selection == NULL) return;
587 undo->type = ITEM_ERASURE;
588 undo->layer = ui.selection->layer;
589 undo->erasurelist = NULL;
590 for (itemlist = ui.selection->items; itemlist!=NULL; itemlist = itemlist->next) {
591 item = (struct Item *)itemlist->data;
592 if (item->canvas_item!=NULL)
593 gtk_object_destroy(GTK_OBJECT(item->canvas_item));
594 erasure = g_new(struct UndoErasureData, 1);
595 erasure->item = item;
596 erasure->npos = g_list_index(ui.selection->layer->items, item);
598 erasure->replacement_items = NULL;
599 ui.selection->layer->items = g_list_remove(ui.selection->layer->items, item);
600 ui.selection->layer->nitems--;
601 undo->erasurelist = g_list_prepend(undo->erasurelist, erasure);
605 /* NOTE: the erasurelist is built backwards; this guarantees that,
606 upon undo, the erasure->npos fields give the correct position
607 where each item should be reinserted as the list is traversed in
608 the forward direction */
611 // modify the color or thickness of pen strokes in a selection
613 void recolor_selection(int color_no, guint color_rgba)
618 GnomeCanvasGroup *group;
620 if (ui.selection == NULL) return;
622 undo->type = ITEM_REPAINTSEL;
623 undo->itemlist = NULL;
624 undo->auxlist = NULL;
625 for (itemlist = ui.selection->items; itemlist!=NULL; itemlist = itemlist->next) {
626 item = (struct Item *)itemlist->data;
627 if (item->type != ITEM_STROKE && item->type != ITEM_TEXT) continue;
628 if (item->type == ITEM_STROKE && item->brush.tool_type!=TOOL_PEN) continue;
629 // store info for undo
630 undo->itemlist = g_list_append(undo->itemlist, item);
631 brush = (struct Brush *)g_malloc(sizeof(struct Brush));
632 g_memmove(brush, &(item->brush), sizeof(struct Brush));
633 undo->auxlist = g_list_append(undo->auxlist, brush);
634 // repaint the stroke
635 item->brush.color_no = color_no;
636 item->brush.color_rgba = color_rgba | 0xff; // no alpha
637 if (item->canvas_item!=NULL) {
638 if (!item->brush.variable_width)
639 gnome_canvas_item_set(item->canvas_item,
640 "fill-color-rgba", item->brush.color_rgba, NULL);
642 group = (GnomeCanvasGroup *) item->canvas_item->parent;
643 gtk_object_destroy(GTK_OBJECT(item->canvas_item));
644 make_canvas_item_one(group, item);
650 void rethicken_selection(int val)
655 GnomeCanvasGroup *group;
657 if (ui.selection == NULL) return;
659 undo->type = ITEM_REPAINTSEL;
660 undo->itemlist = NULL;
661 undo->auxlist = NULL;
662 for (itemlist = ui.selection->items; itemlist!=NULL; itemlist = itemlist->next) {
663 item = (struct Item *)itemlist->data;
664 if (item->type != ITEM_STROKE || item->brush.tool_type!=TOOL_PEN) continue;
665 // store info for undo
666 undo->itemlist = g_list_append(undo->itemlist, item);
667 brush = (struct Brush *)g_malloc(sizeof(struct Brush));
668 g_memmove(brush, &(item->brush), sizeof(struct Brush));
669 undo->auxlist = g_list_append(undo->auxlist, brush);
670 // repaint the stroke
671 item->brush.thickness_no = val;
672 item->brush.thickness = predef_thickness[TOOL_PEN][val];
673 if (item->canvas_item!=NULL) {
674 if (!item->brush.variable_width)
675 gnome_canvas_item_set(item->canvas_item,
676 "width-units", item->brush.thickness, NULL);
678 group = (GnomeCanvasGroup *) item->canvas_item->parent;
679 gtk_object_destroy(GTK_OBJECT(item->canvas_item));
680 item->brush.variable_width = FALSE;
681 make_canvas_item_one(group, item);