diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Icon.c | 229 |
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; } |