aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Icon.c229
1 files changed, 130 insertions, 99 deletions
diff --git a/generic/Icon.c b/generic/Icon.c
index d92c0b1..9bcdbc9 100644
--- a/generic/Icon.c
+++ b/generic/Icon.c
@@ -120,7 +120,7 @@ IconImageChange(ClientData client_data,
{
IconItem icon = (IconItem) client_data;
- InvalidateImage(icon->image);
+ InvalidateImage(icon->image_name);
ITEM.Invalidate((Item) icon, ZN_COORDS_FLAG);
}
@@ -201,16 +201,16 @@ Destroy(Item item)
WidgetInfo *wi = item->wi;
IconItem icon = (IconItem) item;
- if (strlen(icon->image_name) != 0) {
- ZnFree(icon->image_name);
- }
if (icon->image != ZnUnspecifiedImage) {
Tk_FreeImage(icon->image);
icon->image = ZnUnspecifiedImage;
}
+ if (strlen(icon->image_name) != 0) {
+ ZnFree(icon->image_name);
+ }
if (icon->mask != ZnUnspecifiedPattern) {
Tk_FreeBitmap(wi->dpy, icon->mask);
- icon->mask = ZnUnspecifiedPattern;
+ icon->mask = ZnUnspecifiedPattern;
}
ZnFreeColor(icon->color);
}
@@ -357,10 +357,10 @@ ComputeCoordinates(Item item,
AddPointToBBox(&item->item_bounding_box, icon->pos_dev.x, icon->pos_dev.y);
AddPointToBBox(&item->item_bounding_box, icon->pos_dev.x+width,
icon->pos_dev.y+height);
- item->item_bounding_box.orig.x -= 1;
- item->item_bounding_box.orig.y -= 1;
- item->item_bounding_box.corner.x += 1;
- item->item_bounding_box.corner.y += 1;
+ item->item_bounding_box.orig.x -= 1.0;
+ item->item_bounding_box.orig.y -= 1.0;
+ item->item_bounding_box.corner.x += 1.0;
+ item->item_bounding_box.corner.y += 1.0;
/*
* Update connected items.
@@ -385,9 +385,21 @@ ToArea(Item item,
int enclosed,
ZnBool report)
{
- /* IconItem icon = (IconItem) item;*/
-
- return BBoxInBBox(&item->item_bounding_box, area);
+ IconItem icon = (IconItem) item;
+ ZnBBox box;
+ int w, h;
+
+ box.orig = icon->pos_dev;
+ if (icon->image != ZnUnspecifiedImage) {
+ Tk_SizeOfImage(icon->image, &w, &h);
+ }
+ else if (icon->mask != ZnUnspecifiedPattern) {
+ Tk_SizeOfBitmap(item->wi->dpy, icon->mask, &w, &h);
+ }
+ box.corner.x = box.orig.x + w;
+ box.corner.y = box.orig.y + h;
+
+ return BBoxInBBox(&box, area);
}
@@ -407,89 +419,96 @@ Draw(Item item)
int gc_mask = 0;
ImageBits *im_bits;
Pixmap pmap, mask_pmap;
+ int w, h;
+ ZnBBox box, inter;
if (icon->image != ZnUnspecifiedImage) {
- if (wi->current_clip) {
- if (wi->current_clip->simple) {
- Tk_RedrawImage(icon->image,
- item->item_bounding_box.orig.x-icon->pos_dev.x,
- item->item_bounding_box.orig.y-icon->pos_dev.y,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
- wi->draw_buffer,
- item->item_bounding_box.orig.x,
- item->item_bounding_box.orig.y);
+ /*
+ * Added the case of a rectangular aligned clipping and the
+ * simple case of the damaged area clip. These are done here
+ * to avoid the use of Tk_RedrawImage which use a different
+ * GC and lead to wrong clip behaviour.
+ *
+ * Non rectangular clipping. Two cases here: if the image
+ * has no contour mask, simply use the clipping set in the
+ * current gc, if not, we have to generate a bitmap mask
+ * using the image mask and the current clip and use this
+ * bitmap as the current clip.
+ */
+ Tk_SizeOfImage(icon->image, &w, &h);
+ box.orig = icon->pos_dev;
+ box.corner.x = icon->pos_dev.x + w;
+ box.corner.y = icon->pos_dev.y + h;
+ IntersectBBox(&box, &wi->damaged_area, &inter);
+ box = inter;
+ im_bits = GetImageBits(wi->win, icon->image_name, icon->image);
+ pmap = GetImagePixmap(wi->win, icon->image_name, icon->image, &mask_pmap);
+ if ((im_bits->mask == ZnUnspecifiedPattern) ||
+ !wi->current_clip || (wi->current_clip->simple)) {
+ if (im_bits->mask != ZnUnspecifiedPattern) {
+ XSetClipMask(wi->dpy, wi->gc, mask_pmap);
+ values.clip_x_origin = (int) icon->pos_dev.x;
+ values.clip_y_origin = (int) icon->pos_dev.y;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ }
+ XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
+ box.orig.x-icon->pos_dev.x, box.orig.y-icon->pos_dev.y,
+ box.corner.x-box.orig.x, box.corner.y-box.orig.y,
+ box.orig.x, box.orig.y);
+ values.clip_x_origin = values.clip_y_origin = 0;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ if (wi->current_clip) {
+ XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
}
else {
- /*
- * Non rectangular clipping. Two cases here: if the image
- * has no contour mask, simply use the clipping set in the
- * current gc, if not, we have to generate a bitmap mask
- * using the image mask and the current clip and use this
- * bitmap as the current clip.
- */
- im_bits = GetImageBits(wi->win, icon->image);
- pmap = GetImagePixmap(wi->win, icon->image);
- if (im_bits->mask == ZnUnspecifiedPattern) {
- XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
- item->item_bounding_box.orig.x-icon->pos_dev.x,
- item->item_bounding_box.orig.y-icon->pos_dev.y,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
- item->item_bounding_box.orig.x,
- item->item_bounding_box.orig.y);
- }
- else {
- GC gc;
- /*
- * Build of the mask
- */
- mask_pmap = XCreatePixmap(wi->dpy, ZnWindowId(wi->win),
- im_bits->width, im_bits->height, 1);
- gc = XCreateGC(wi->dpy, mask_pmap, 0, NULL);
- XFillRectangle(wi->dpy, mask_pmap, gc, 0, 0, im_bits->width, im_bits->height);
- XSetRegion(wi->dpy, gc, wi->current_clip->region);
- values.foreground = 1;
- values.background = 0;
- values.clip_x_origin = (int) -icon->pos_dev.x;
- values.clip_y_origin = (int) -icon->pos_dev.y;
- XChangeGC(wi->dpy, gc,
- GCForeground|GCBackground|GCClipXOrigin|GCClipYOrigin, &values);
- XPutImage(wi->dpy, mask_pmap, gc, im_bits->mask, 0, 0, 0, 0,
- im_bits->width, im_bits->height);
- XFreeGC(wi->dpy, gc);
- /*
- * Drawing of the icon using the mask.
- */
- XSetClipMask(wi->dpy, wi->gc, mask_pmap);
- values.clip_x_origin = (int) icon->pos_dev.x;
- values.clip_y_origin = (int) icon->pos_dev.y;
- XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
- XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
- item->item_bounding_box.orig.x-icon->pos_dev.x,
- item->item_bounding_box.orig.y-icon->pos_dev.y,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
- item->item_bounding_box.orig.x,
- item->item_bounding_box.orig.y);
- XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
- values.clip_x_origin = 0;
- values.clip_y_origin = 0;
- XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
- XFreePixmap(wi->dpy, mask_pmap);
- }
+ XSetRegion(wi->dpy, wi->gc, wi->damaged_region);
}
}
- else { /* !current_clip */
- Tk_RedrawImage(icon->image, 0, 0,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
- wi->draw_buffer,
- item->item_bounding_box.orig.x,
- item->item_bounding_box.orig.y);
+ else {
+ GC gc;
+ /*
+ * Build of the mask
+ */
+ mask_pmap = XCreatePixmap(wi->dpy, ZnWindowId(wi->win),
+ im_bits->width, im_bits->height, 1);
+ gc = XCreateGC(wi->dpy, mask_pmap, 0, NULL);
+ XFillRectangle(wi->dpy, mask_pmap, gc, 0, 0, im_bits->width, im_bits->height);
+ XSetRegion(wi->dpy, gc, wi->current_clip->region);
+ values.foreground = 1;
+ values.background = 0;
+ values.clip_x_origin = (int) -icon->pos_dev.x;
+ values.clip_y_origin = (int) -icon->pos_dev.y;
+ XChangeGC(wi->dpy, gc,
+ GCForeground|GCBackground|GCClipXOrigin|GCClipYOrigin, &values);
+ XPutImage(wi->dpy, mask_pmap, gc, im_bits->mask, 0, 0, 0, 0,
+ im_bits->width, im_bits->height);
+ XFreeGC(wi->dpy, gc);
+ /*
+ * Drawing of the icon using the mask.
+ */
+ XSetClipMask(wi->dpy, wi->gc, mask_pmap);
+ values.clip_x_origin = (int) icon->pos_dev.x;
+ values.clip_y_origin = (int) icon->pos_dev.y;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
+ box.orig.x-icon->pos_dev.x, box.orig.y-icon->pos_dev.y,
+ box.corner.x-box.orig.x, box.corner.y-box.orig.y,
+ box.orig.x, box.orig.y);
+ values.clip_x_origin = values.clip_y_origin = 0;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
+ XFreePixmap(wi->dpy, mask_pmap);
}
}
else if (icon->mask != ZnUnspecifiedPattern) {
+ Tk_SizeOfBitmap(wi->dpy, icon->mask, &w,&h);
+ box.orig = icon->pos_dev;
+ box.corner.x = icon->pos_dev.x + w;
+ box.corner.y = icon->pos_dev.y + h;
+ if (wi->current_clip && (wi->current_clip->simple)) {
+ IntersectBBox(&box, &wi->current_clip->clip_box, &inter);
+ box = inter;
+ }
values.fill_style = FillStippled;
values.stipple = icon->mask;
values.ts_x_origin = icon->pos_dev.x;
@@ -498,10 +517,8 @@ Draw(Item item)
gc_mask |= GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCForeground;
XChangeGC(wi->dpy, wi->gc, gc_mask, &values);
XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc,
- item->item_bounding_box.orig.x,
- item->item_bounding_box.orig.y,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y);
+ box.orig.x, box.orig.y,
+ box.corner.x-box.orig.x, box.corner.y-box.orig.y);
}
}
@@ -560,15 +577,15 @@ Pick(Item item,
ZnPoint dp;
dist = 0.0;
- dp.x = p->x - item->item_bounding_box.orig.x;
- dp.y = p->y - item->item_bounding_box.orig.y;
+ dp.x = p->x - icon->pos_dev.x;
+ dp.y = p->y - icon->pos_dev.y;
if (icon->image != ZnUnspecifiedImage) {
Tk_SizeOfImage(icon->image, &width, &height);
if (dp.x >= width || dp.y >= height) {
dist = off_dist;
goto out_pick;
}
- im_bits = GetImageBits(wi->win, icon->image);
+ im_bits = GetImageBits(wi->win, icon->image_name, icon->image);
bitmap = im_bits->mask;
}
else if (icon->mask != ZnUnspecifiedPattern) {
@@ -624,13 +641,17 @@ GetAnchor(Item item,
ZnPoint *p)
{
IconItem icon = (IconItem) item;
+ int w=0, h=0;
if ((icon->image != ZnUnspecifiedImage) ||
(icon->mask != ZnUnspecifiedPattern)) {
- Origin2Anchor(&icon->pos_dev,
- item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
- item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
- anchor, p);
+ if (icon->image != ZnUnspecifiedImage) {
+ Tk_SizeOfImage(icon->image, &w, &h);
+ }
+ else {
+ Tk_SizeOfBitmap(item->wi->dpy, icon->mask, &w, &h);
+ }
+ Origin2Anchor(&icon->pos_dev, w, h, anchor, p);
}
else {
p->x = p->y = 0.0;
@@ -651,11 +672,21 @@ GetClipVertices(Item item,
ZnPoint **points,
int *num_points)
{
+ IconItem icon = (IconItem) item;
+ int w=0, h=0;
+
ZnListAssertSize(item->wi->work_pts, 2);
*points = (ZnPoint *) ZnListArray(item->wi->work_pts);
*num_points = 2;
- (*points)[0] = item->item_bounding_box.orig;
- (*points)[1] = item->item_bounding_box.corner;
+ if (icon->image != ZnUnspecifiedImage) {
+ Tk_SizeOfImage(icon->image, &w, &h);
+ }
+ else {
+ Tk_SizeOfBitmap(item->wi->dpy, icon->mask, &w, &h);
+ }
+ (*points)[0] = icon->pos_dev;
+ (*points)[1].x = icon->pos_dev.x + w;
+ (*points)[1].y = icon->pos_dev.y + h;
return True;
}