From 9b77e9e7deb66533f2b70a21659508cb760338f8 Mon Sep 17 00:00:00 2001 From: treectrl Date: Sat, 21 Apr 2007 21:34:00 +0000 Subject: Fixed partially-exposed transparent photo images not being redrawn when scrolling under X11. This involved creating a wrapper around Tk_RedrawImage to ensure proper clipping of the source image to the bounds of the destination drawable. A new data type TreeDrawable remembers the height and width of a drawable. --- generic/tkTreeColumn.c | 130 +++++++++++++++++++++++------------------------- generic/tkTreeCtrl.h | 21 +++++--- generic/tkTreeDisplay.c | 99 ++++++++++++++++++------------------ generic/tkTreeElem.c | 4 +- generic/tkTreeElem.h | 3 +- generic/tkTreeItem.c | 60 +++++++++++----------- generic/tkTreeStyle.c | 8 +-- generic/tkTreeUtils.c | 60 +++++++++++++++++++++- 8 files changed, 226 insertions(+), 159 deletions(-) diff --git a/generic/tkTreeColumn.c b/generic/tkTreeColumn.c index 88d0796..e683514 100644 --- a/generic/tkTreeColumn.c +++ b/generic/tkTreeColumn.c @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003 ActiveState Corporation * - * RCS: @(#) $Id: tkTreeColumn.c,v 1.77 2007/01/23 22:41:30 treectrl Exp $ + * RCS: @(#) $Id: tkTreeColumn.c,v 1.78 2007/04/21 21:34:00 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -4324,7 +4324,7 @@ errorExit: static void Column_DrawArrow( TreeColumn column, /* Column record. */ - Drawable drawable, /* Where to draw. */ + TreeDrawable td, /* Where to draw. */ int x, int y, /* Top-left corner of the column's header. */ struct Layout layout /* Size/position info. */ ) @@ -4344,8 +4344,8 @@ Column_DrawArrow( image = PerStateImage_ForState(tree, &column->arrowImage, state, NULL); if (image != NULL) { - Tk_RedrawImage(image, 0, 0, layout.arrowWidth, layout.arrowHeight, - drawable, + Tree_RedrawImage(image, 0, 0, layout.arrowWidth, layout.arrowHeight, + td, x + layout.arrowLeft + sunken, y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken); return; @@ -4356,7 +4356,7 @@ Column_DrawArrow( int bx, by; bx = x + layout.arrowLeft + sunken; by = y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken; - Tree_DrawBitmap(tree, bitmap, drawable, NULL, NULL, + Tree_DrawBitmap(tree, bitmap, td.drawable, NULL, NULL, 0, 0, (unsigned int) layout.arrowWidth, (unsigned int) layout.arrowHeight, bx, by); @@ -4364,7 +4364,7 @@ Column_DrawArrow( } if (tree->useTheme) { - if (TreeTheme_DrawHeaderArrow(tree, drawable, + if (TreeTheme_DrawHeaderArrow(tree, td.drawable, column->arrow == ARROW_UP, x + layout.arrowLeft + sunken, y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken, layout.arrowWidth, layout.arrowHeight) == TCL_OK) @@ -4415,14 +4415,13 @@ Column_DrawArrow( points[i].y += sunken; } - border = PerStateBorder_ForState(tree, &column->border, - Column_MakeState(column), NULL); + border = PerStateBorder_ForState(tree, &column->border, state, NULL); if (border == NULL) border = tree->border; - XDrawLines(tree->display, drawable, + XDrawLines(tree->display, td.drawable, Tk_3DBorderGC(tree->tkwin, border, color2), points + 2, 3, CoordModeOrigin); - XDrawLines(tree->display, drawable, + XDrawLines(tree->display, td.drawable, Tk_3DBorderGC(tree->tkwin, border, color1), points, 2, CoordModeOrigin); } @@ -4447,7 +4446,7 @@ Column_DrawArrow( static void Column_Draw( TreeColumn column, /* Column record. */ - Drawable drawable, /* Where to draw. */ + TreeDrawable td, /* Where to draw. */ int x, int y, /* Top-left corner of the column's header. */ int dragImage /* TRUE if we are creating a transparent * drag image for this header. */ @@ -4473,14 +4472,14 @@ Column_Draw( if (dragImage) { GC gc = Tk_GCForColor(tree->columnDrag.color, Tk_WindowId(tree->tkwin)); - XFillRectangle(tree->display, drawable, gc, x, y, width, height); + XFillRectangle(tree->display, td.drawable, gc, x, y, width, height); } else { if (tree->useTheme) { - theme = TreeTheme_DrawHeaderItem(tree, drawable, column->state, + theme = TreeTheme_DrawHeaderItem(tree, td.drawable, column->state, column->arrow, x, y, width, height); } if (theme != TCL_OK) - Tk_Fill3DRectangle(tree->tkwin, drawable, border, + Tk_Fill3DRectangle(tree->tkwin, td.drawable, border, x, y, width, height, 0, TK_RELIEF_FLAT); } @@ -4492,7 +4491,7 @@ Column_Draw( + column->imagePadY[PAD_BOTTOM_RIGHT]; iy = y + (height - h) / 2 + sunken; iy += column->imagePadY[PAD_TOP_LEFT]; - Tk_RedrawImage(column->image, 0, 0, imgW, imgH, drawable, ix, iy); + Tree_RedrawImage(column->image, 0, 0, imgW, imgH, td, ix, iy); } else if (column->bitmap != None) { int imgW, imgH, bx, by, h; @@ -4502,7 +4501,7 @@ Column_Draw( + column->imagePadY[PAD_BOTTOM_RIGHT]; by = y + (height - h) / 2 + sunken; by += column->imagePadY[PAD_TOP_LEFT]; - Tree_DrawBitmapWithGC(tree, column->bitmap, drawable, column->bitmapGC, + Tree_DrawBitmapWithGC(tree, column->bitmap, td.drawable, column->bitmapGC, 0, 0, (unsigned int) imgW, (unsigned int) imgH, bx, by); } @@ -4519,7 +4518,7 @@ Column_Draw( gcValues.graphics_exposures = False; mask = GCFont | GCForeground | GCGraphicsExposures; gc = Tree_GetGC(tree, mask, &gcValues); - TextLayout_Draw(tree->display, drawable, gc, + TextLayout_Draw(tree->display, td.drawable, gc, column->textLayout, x + layout.textLeft + sunken, y + (height - h) / 2 + column->textPadY[PAD_TOP_LEFT] + sunken, @@ -4555,7 +4554,7 @@ Column_Draw( + column->textPadY[PAD_BOTTOM_RIGHT]; ty = y + (height - h) / 2 + layout.fm.ascent + sunken; ty += column->textPadY[PAD_TOP_LEFT]; - Tk_DrawChars(tree->display, drawable, gc, + Tk_DrawChars(tree->display, td.drawable, gc, layout.tkfont, text, textLen, tx, ty); if (text != staticStr) ckfree(text); @@ -4568,10 +4567,10 @@ Column_Draw( /* Under Aqua, we let the Appearance Manager draw the sort arrow */ if (theme != TCL_OK) #endif - Column_DrawArrow(column, drawable, x, y, layout); + Column_DrawArrow(column, td, x, y, layout); if (theme != TCL_OK) - Tk_Draw3DRectangle(tree->tkwin, drawable, border, + Tk_Draw3DRectangle(tree->tkwin, td.drawable, border, x, y, width, height, column->borderWidth, relief); } @@ -4603,7 +4602,7 @@ SetImageForColumn( ) { Tk_PhotoHandle photoH; - Pixmap pixmap; + TreeDrawable td; int width = column->useWidth; /* the entire column, not just what is visible */ int height = tree->headerHeight; XImage *ximage; @@ -4616,22 +4615,24 @@ SetImageForColumn( return NULL; } - pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tree->tkwin), + td.width = width; + td.height = height; + td.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tree->tkwin), width, height, Tk_Depth(tree->tkwin)); - Column_Draw(column, pixmap, 0, 0, TRUE); + Column_Draw(column, td, 0, 0, TRUE); /* Pixmap -> XImage */ - ximage = XGetImage(tree->display, pixmap, 0, 0, + ximage = XGetImage(tree->display, td.drawable, 0, 0, (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); if (ximage == NULL) - panic("ximage is NULL"); + panic("tkTreeColumn.c:SetImageForColumn() ximage is NULL"); /* XImage -> Tk_Image */ Tree_XImage2Photo(tree->interp, photoH, ximage, tree->columnDrag.alpha); XDestroyImage(ximage); - Tk_FreePixmap(tree->display, pixmap); + Tk_FreePixmap(tree->display, td.drawable); return Tk_GetImage(tree->interp, tree->tkwin, "::TreeCtrl::ImageColumn", NULL, (ClientData) NULL); @@ -4686,65 +4687,69 @@ DrawDragIndicator( static void DrawHeaderLeft( TreeCtrl *tree, /* Widget info. */ - Drawable drawable /* Where to draw. */ + TreeDrawable td /* Where to draw. */ ) { TreeColumn column = tree->columnLockLeft; Tk_Window tkwin = tree->tkwin; int x = Tree_HeaderLeft(tree), y = Tree_HeaderTop(tree); - Drawable pixmap; + TreeDrawable td2; - pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin)); + td2.width = Tk_Width(tkwin); + td2.height = Tree_HeaderBottom(tree); + td2.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), + td2.width, td2.height, Tk_Depth(tkwin)); while (column != NULL && column->lock == COLUMN_LOCK_LEFT) { if (column->visible) { - Column_Draw(column, pixmap, x, y, FALSE); + Column_Draw(column, td2, x, y, FALSE); x += column->useWidth; } column = column->next; } - DrawDragIndicator(tree, pixmap, COLUMN_LOCK_LEFT); + DrawDragIndicator(tree, td2.drawable, COLUMN_LOCK_LEFT); - XCopyArea(tree->display, pixmap, drawable, + XCopyArea(tree->display, td2.drawable, td.drawable, tree->copyGC, Tree_HeaderLeft(tree), y, x - Tree_HeaderLeft(tree), tree->headerHeight, Tree_HeaderLeft(tree), y); - Tk_FreePixmap(tree->display, pixmap); + Tk_FreePixmap(tree->display, td2.drawable); } static void DrawHeaderRight( TreeCtrl *tree, /* Widget info. */ - Drawable drawable /* Where to draw. */ + TreeDrawable td /* Where to draw. */ ) { TreeColumn column = tree->columnLockRight; Tk_Window tkwin = tree->tkwin; int x = Tree_ContentRight(tree), y = Tree_HeaderTop(tree); - Drawable pixmap; + TreeDrawable td2; - pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin)); + td2.width = Tk_Width(tkwin); + td2.height = Tree_HeaderBottom(tree); + td2.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), + td2.width, td2.height, Tk_Depth(tkwin)); while (column != NULL && column->lock == COLUMN_LOCK_RIGHT) { if (column->visible) { - Column_Draw(column, pixmap, x, y, FALSE); + Column_Draw(column, td2, x, y, FALSE); x += column->useWidth; } column = column->next; } - DrawDragIndicator(tree, pixmap, COLUMN_LOCK_RIGHT); + DrawDragIndicator(tree, td2.drawable, COLUMN_LOCK_RIGHT); - XCopyArea(tree->display, pixmap, drawable, + XCopyArea(tree->display, td2.drawable, td.drawable, tree->copyGC, Tree_ContentRight(tree), y, x - Tree_ContentRight(tree), tree->headerHeight, Tree_ContentRight(tree), y); - Tk_FreePixmap(tree->display, pixmap); + Tk_FreePixmap(tree->display, td2.drawable); } /* @@ -4766,13 +4771,15 @@ DrawHeaderRight( void Tree_DrawHeader( TreeCtrl *tree, /* Widget info. */ - Drawable drawable, /* Where to draw. */ + TreeDrawable td, /* Where to draw. */ int x, int y /* Top-left corner of the header. */ ) { TreeColumn column = tree->columns; Tk_Window tkwin = tree->tkwin; int minX, maxX, width, height; + Drawable drawable = td.drawable; + TreeDrawable tp; Drawable pixmap; /* Update layout if needed */ @@ -4782,17 +4789,21 @@ Tree_DrawHeader( minX = Tree_ContentLeft(tree); maxX = Tree_ContentRight(tree); - if (tree->doubleBuffer == DOUBLEBUFFER_ITEM) - pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin)); - else - pixmap = drawable; + if (tree->doubleBuffer == DOUBLEBUFFER_ITEM) { + tp.width = Tk_Width(tkwin); + tp.height = Tree_HeaderBottom(tree); + tp.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), + tp.width, tp.height, Tk_Depth(tkwin)); + } else { + tp = td; + } + pixmap = tp.drawable; column = tree->columnLockNone; while (column != NULL && column->lock == COLUMN_LOCK_NONE) { if (column->visible) { if ((x < maxX) && (x + column->useWidth > minX)) - Column_Draw(column, pixmap, x, y, FALSE); + Column_Draw(column, tp, x, y, FALSE); x += column->useWidth; } column = column->next; @@ -4823,9 +4834,9 @@ Tree_DrawHeader( DrawDragIndicator(tree, pixmap, COLUMN_LOCK_NONE); if (Tree_WidthOfLeftColumns(tree) > 0) - DrawHeaderLeft(tree, pixmap); + DrawHeaderLeft(tree, tp); if (Tree_WidthOfRightColumns(tree) > 0) - DrawHeaderRight(tree, pixmap); + DrawHeaderRight(tree, tp); if (tree->columnDrag.column != NULL) { Tk_Image image; @@ -4836,22 +4847,7 @@ Tree_DrawHeader( image = SetImageForColumn(tree, tree->columnDrag.column); x += tree->columnDrag.offset; -#if !defined(WIN32) && !defined(MAC_TCL) && !defined(MAC_OSX_TK) - /* - * Do boundary clipping, so that Tk_RedrawImage is passed - * valid coordinates. [Tk Bug 979239] - */ - if (x < minX) { - ix = minX - x; - iw -= ix; - x = minX; - w -= ix; - } - if (x + w > maxX) { - iw -= (x + w) - maxX; - } -#endif - Tk_RedrawImage(image, ix, iy, iw, ih, pixmap, x, y); + Tree_RedrawImage(image, ix, iy, iw, ih, tp, x, y); Tk_FreeImage(image); } } diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h index 7bd1bef..fc4b7a2 100644 --- a/generic/tkTreeCtrl.h +++ b/generic/tkTreeCtrl.h @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003 ActiveState Corporation * - * RCS: @(#) $Id: tkTreeCtrl.h,v 1.89 2007/01/31 23:21:44 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.h,v 1.90 2007/04/21 21:34:00 treectrl Exp $ */ #include "tkPort.h" @@ -92,6 +92,13 @@ struct PerStateType /*****/ +typedef struct +{ + Drawable drawable; + int width; + int height; +} TreeDrawable; + typedef struct GCCache GCCache; struct GCCache { @@ -537,9 +544,9 @@ extern int TreeItem_TotalHeight(TreeCtrl *tree, TreeItem self); extern void TreeItem_InvalidateHeight(TreeCtrl *tree, TreeItem self); extern void TreeItem_SpansInvalidate(TreeCtrl *tree, TreeItem item_); extern int *TreeItem_GetSpans(TreeCtrl *tree, TreeItem item_); -extern void TreeItem_Draw(TreeCtrl *tree, TreeItem self, int lock, int x, int y, int width, int height, Drawable drawable, int minX, int maxX, int index); -extern void TreeItem_DrawLines(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, Drawable drawable); -extern void TreeItem_DrawButton(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, Drawable drawable); +extern void TreeItem_Draw(TreeCtrl *tree, TreeItem self, int lock, int x, int y, int width, int height, TreeDrawable td, int minX, int maxX, int index); +extern void TreeItem_DrawLines(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, TreeDrawable td); +extern void TreeItem_DrawButton(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, TreeDrawable td); extern int TreeItem_ReallyVisible(TreeCtrl *tree, TreeItem self); extern void TreeItem_FreeResources(TreeCtrl *tree, TreeItem self); extern void TreeItem_Release(TreeCtrl *tree, TreeItem item); @@ -592,7 +599,7 @@ struct StyleDrawArgs int y; int width; int height; - Drawable drawable; + TreeDrawable td; int state; /* STATE_xxx */ Tk_Justify justify; int bounds[4]; @@ -714,7 +721,7 @@ extern int TreeColumn_Visible(TreeColumn column_); extern int TreeColumn_Squeeze(TreeColumn column_); extern int TreeColumn_BackgroundCount(TreeColumn column_); extern GC TreeColumn_BackgroundGC(TreeColumn column_, int which); -extern void Tree_DrawHeader(TreeCtrl *tree, Drawable drawable, int x, int y); +extern void Tree_DrawHeader(TreeCtrl *tree, TreeDrawable td, int x, int y); extern int TreeColumn_WidthOfItems(TreeColumn column_); extern void TreeColumn_InvalidateWidth(TreeColumn column_); extern void TreeColumn_Init(TreeCtrl *tree); @@ -882,6 +889,8 @@ extern void TextLayout_Draw(Display *display, Drawable drawable, GC gc, extern void DrawXORLine(Display *display, Drawable drawable, int x1, int y1, int x2, int y2); #endif +extern void Tree_RedrawImage(Tk_Image image, int imageX, int imageY, + int width, int height, TreeDrawable td, int drawableX, int drawableY); extern void Tree_DrawBitmapWithGC(TreeCtrl *tree, Pixmap bitmap, Drawable drawable, GC gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y); extern void Tree_DrawBitmap(TreeCtrl *tree, Pixmap bitmap, Drawable drawable, diff --git a/generic/tkTreeDisplay.c b/generic/tkTreeDisplay.c index 02af68c..0d4f460 100644 --- a/generic/tkTreeDisplay.c +++ b/generic/tkTreeDisplay.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeDisplay.c,v 1.83 2007/01/31 23:23:49 treectrl Exp $ + * RCS: @(#) $Id: tkTreeDisplay.c,v 1.84 2007/04/21 21:34:00 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -90,13 +90,6 @@ struct TreeColumnDInfo_ int width; /* Last seen column width */ }; -struct DPixmap -{ - Pixmap pixmap; - int width; - int height; -}; - /* Display information for a TreeCtrl. */ struct TreeDInfo_ { @@ -117,8 +110,8 @@ struct TreeDInfo_ int rItemMax; /* size of rItem[] */ int itemHeight; /* Observed max TreeItem height */ int itemWidth; /* Observed max TreeItem width */ - struct DPixmap pixmapW; /* Pixmap as big as the window */ - struct DPixmap pixmapI; /* Pixmap as big as the largest item */ + TreeDrawable pixmapW; /* Pixmap as big as the window */ + TreeDrawable pixmapI; /* Pixmap as big as the largest item */ TkRegion dirtyRgn; /* DOUBLEBUFFER_WINDOW */ int flags; /* DINFO_XXX */ int xScrollIncrement; /* Last seen TreeCtr.xScrollIncrement */ @@ -3846,8 +3839,8 @@ ScrollVerticalComplex( if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { int dirtyMin, dirtyMax; - XCopyArea(tree->display, dInfo->pixmapW.pixmap, - dInfo->pixmapW.pixmap, tree->copyGC, + XCopyArea(tree->display, dInfo->pixmapW.drawable, + dInfo->pixmapW.drawable, tree->copyGC, oldX, oldY, width, height, oldX, oldY + offset); if (offset < 0) { @@ -3964,7 +3957,8 @@ ScrollHorizontalSimple( damageRgn = Tree_GetRegion(tree); if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { - XCopyArea(tree->display, dInfo->pixmapW.pixmap, dInfo->pixmapW.pixmap, + XCopyArea(tree->display, dInfo->pixmapW.drawable, + dInfo->pixmapW.drawable, tree->copyGC, x, minY, width, maxY - minY, x + offset, minY); @@ -4062,8 +4056,8 @@ ScrollVerticalSimple( damageRgn = Tree_GetRegion(tree); if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { - XCopyArea(tree->display, dInfo->pixmapW.pixmap, dInfo->pixmapW.pixmap, - tree->copyGC, + XCopyArea(tree->display, dInfo->pixmapW.drawable, + dInfo->pixmapW.drawable, tree->copyGC, minX, y, maxX - minX, height, minX, y + offset); Tree_InvalidateArea(tree, minX, dirtyMin, maxX, dirtyMax); @@ -4209,8 +4203,8 @@ ScrollHorizontalComplex( if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { int dirtyMin, dirtyMax; - XCopyArea(tree->display, dInfo->pixmapW.pixmap, - dInfo->pixmapW.pixmap, tree->copyGC, + XCopyArea(tree->display, dInfo->pixmapW.drawable, + dInfo->pixmapW.drawable, tree->copyGC, oldX, oldY, width, height, oldX + offset, oldY); if (offset < 0) { @@ -5077,8 +5071,8 @@ DisplayDItem( DItemArea *area, int lock, /* Which set of columns. */ int bounds[4], /* TREE_AREA_xxx bounds of drawing. */ - Drawable pixmap, /* Where to draw. */ - Drawable drawable /* Where to copy to. */ + TreeDrawable pixmap, /* Where to draw. */ + TreeDrawable drawable /* Where to copy to. */ ) { Tk_Window tkwin = tree->tkwin; @@ -5133,7 +5127,7 @@ DisplayDItem( pixmap, 0, right - left, dItem->index); - XCopyArea(tree->display, pixmap, drawable, + XCopyArea(tree->display, pixmap.drawable, drawable.drawable, tree->copyGC, 0, 0, right - left, bottom - top, @@ -5265,27 +5259,27 @@ TreeDisplay_WasThereTrouble( static Pixmap DisplayGetPixmap( TreeCtrl *tree, - struct DPixmap *dPixmap, + TreeDrawable *dPixmap, int width, int height ) { Tk_Window tkwin = tree->tkwin; - if (dPixmap->pixmap == None) { - dPixmap->pixmap = Tk_GetPixmap(tree->display, + if (dPixmap->drawable == None) { + dPixmap->drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin)); dPixmap->width = width; dPixmap->height = height; } else if ((dPixmap->width < width) || (dPixmap->height < height)) { - Tk_FreePixmap(tree->display, dPixmap->pixmap); - dPixmap->pixmap = Tk_GetPixmap(tree->display, + Tk_FreePixmap(tree->display, dPixmap->drawable); + dPixmap->drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin)); dPixmap->width = width; dPixmap->height = height; } - return dPixmap->pixmap; + return dPixmap->drawable; } /* @@ -5315,8 +5309,9 @@ Tree_Display( TreeDInfo dInfo = tree->dInfo; DItem *dItem; Tk_Window tkwin = tree->tkwin; - Drawable drawable = Tk_WindowId(tkwin); - int minX, minY, maxX, maxY, height, width; + Drawable drawable; + TreeDrawable tdrawable; + int minX, minY, maxX, maxY; int count; int numCopy = 0, numDraw = 0; TkRegion wsRgnNew, wsRgnDif; @@ -5595,10 +5590,15 @@ displayRetry: goto displayRetry; } + tdrawable.width = Tk_Width(tkwin); + tdrawable.height = Tk_Height(tkwin); if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { - drawable = DisplayGetPixmap(tree, &dInfo->pixmapW, - Tk_Width(tkwin), Tk_Height(tkwin)); + tdrawable.drawable = DisplayGetPixmap(tree, &dInfo->pixmapW, + tdrawable.width, tdrawable.height); + } else { + tdrawable.drawable = Tk_WindowId(tkwin); } + drawable = tdrawable.drawable; /* XOR off */ TreeColumnProxy_Undisplay(tree); @@ -5613,7 +5613,7 @@ displayRetry: tree->debug.gcDraw, minX, minY, maxX - minX, maxY - minY); DisplayDelay(tree); } - Tree_DrawHeader(tree, drawable, 0 - tree->xOrigin, Tree_HeaderTop(tree)); + Tree_DrawHeader(tree, tdrawable, 0 - tree->xOrigin, Tree_HeaderTop(tree)); if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { DblBufWinDirty(tree, minX, minY, maxX, maxY); } @@ -5761,13 +5761,14 @@ displayRetry: /* Display dirty items */ if (count > 0) { - Drawable pixmap = drawable; + TreeDrawable tpixmap = tdrawable; if (tree->doubleBuffer != DOUBLEBUFFER_NONE) { /* Allocate pixmap for largest item */ - width = MIN(Tk_Width(tkwin), dInfo->itemWidth); - height = MIN(Tk_Height(tkwin), dInfo->itemHeight); - pixmap = DisplayGetPixmap(tree, &dInfo->pixmapI, width, height); + tpixmap.width = MIN(Tk_Width(tkwin), dInfo->itemWidth); + tpixmap.height = MIN(Tk_Height(tkwin), dInfo->itemHeight); + tpixmap.drawable = DisplayGetPixmap(tree, &dInfo->pixmapI, + tpixmap.width, tpixmap.height); } for (dItem = dInfo->dItem; @@ -5787,7 +5788,7 @@ displayRetry: } if (dItem->area.flags & DITEM_DIRTY) { drawn += DisplayDItem(tree, dItem, &dItem->area, - COLUMN_LOCK_NONE, dInfo->bounds, pixmap, drawable); + COLUMN_LOCK_NONE, dInfo->bounds, tpixmap, tdrawable); } } if (!dInfo->emptyL) { @@ -5803,7 +5804,7 @@ displayRetry: } if (dItem->left.flags & DITEM_DIRTY) { drawn += DisplayDItem(tree, dItem, &dItem->left, COLUMN_LOCK_LEFT, - dInfo->boundsL, pixmap, drawable); + dInfo->boundsL, tpixmap, tdrawable); } } if (!dInfo->emptyR) { @@ -5819,7 +5820,7 @@ displayRetry: } if (dItem->right.flags & DITEM_DIRTY) { drawn += DisplayDItem(tree, dItem, &dItem->right, COLUMN_LOCK_RIGHT, - dInfo->boundsR, pixmap, drawable); + dInfo->boundsR, tpixmap, tdrawable); } } numDraw += drawn ? 1 : 0; @@ -5841,7 +5842,7 @@ displayRetry: TkClipBox(dInfo->dirtyRgn, &box); if (box.width > 0 && box.height > 0) { TkSetRegion(tree->display, tree->copyGC, dInfo->dirtyRgn); - XCopyArea(tree->display, dInfo->pixmapW.pixmap, drawable, + XCopyArea(tree->display, dInfo->pixmapW.drawable, drawable, tree->copyGC, box.x, box.y, box.width, box.height, @@ -6518,15 +6519,15 @@ Tree_RelayoutWindow( dInfo->flags |= DINFO_DRAW_WHITESPACE; if (tree->doubleBuffer != DOUBLEBUFFER_WINDOW) { - if (dInfo->pixmapW.pixmap != None) { - Tk_FreePixmap(tree->display, dInfo->pixmapW.pixmap); - dInfo->pixmapW.pixmap = None; + if (dInfo->pixmapW.drawable != None) { + Tk_FreePixmap(tree->display, dInfo->pixmapW.drawable); + dInfo->pixmapW.drawable = None; } } if (tree->doubleBuffer == DOUBLEBUFFER_NONE) { - if (dInfo->pixmapI.pixmap != None) { - Tk_FreePixmap(tree->display, dInfo->pixmapI.pixmap); - dInfo->pixmapI.pixmap = None; + if (dInfo->pixmapI.drawable != None) { + Tk_FreePixmap(tree->display, dInfo->pixmapI.drawable); + dInfo->pixmapI.drawable = None; } } @@ -7361,10 +7362,10 @@ TreeDInfo_Free( Tk_FreeGC(tree->display, dInfo->scrollGC); if (dInfo->flags & DINFO_REDRAW_PENDING) Tcl_CancelIdleCall(Tree_Display, (ClientData) tree); - if (dInfo->pixmapW.pixmap != None) - Tk_FreePixmap(tree->display, dInfo->pixmapW.pixmap); - if (dInfo->pixmapI.pixmap != None) - Tk_FreePixmap(tree->display, dInfo->pixmapI.pixmap); + if (dInfo->pixmapW.drawable != None) + Tk_FreePixmap(tree->display, dInfo->pixmapW.drawable); + if (dInfo->pixmapI.drawable != None) + Tk_FreePixmap(tree->display, dInfo->pixmapI.drawable); if (dInfo->xScrollIncrements != NULL) ckfree((char *) dInfo->xScrollIncrements); if (dInfo->yScrollIncrements != NULL) diff --git a/generic/tkTreeElem.c b/generic/tkTreeElem.c index 8289bfe..1fc39fa 100644 --- a/generic/tkTreeElem.c +++ b/generic/tkTreeElem.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeElem.c,v 1.64 2007/01/31 00:52:01 treectrl Exp $ + * RCS: @(#) $Id: tkTreeElem.c,v 1.65 2007/04/21 21:34:00 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -1743,7 +1743,7 @@ static void DisplayProcImage(TreeElementArgs *args) imgW = args->display.width; if (imgH > args->display.height) imgH = args->display.height; - Tk_RedrawImage(image, 0, 0, imgW, imgH, args->display.drawable, x, y); + Tree_RedrawImage(image, 0, 0, imgW, imgH, args->display.td, x, y); } static void NeededProcImage(TreeElementArgs *args) diff --git a/generic/tkTreeElem.h b/generic/tkTreeElem.h index d17f3f4..e0ab803 100644 --- a/generic/tkTreeElem.h +++ b/generic/tkTreeElem.h @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeElem.h,v 1.26 2007/01/31 00:51:07 treectrl Exp $ + * RCS: @(#) $Id: tkTreeElem.h,v 1.27 2007/04/21 21:34:01 treectrl Exp $ */ typedef struct TreeElementType TreeElementType; @@ -41,6 +41,7 @@ struct TreeElementArgs #define STICKY_E 0x4000 #define STICKY_S 0x8000 int sticky; + TreeDrawable td; Drawable drawable; int bounds[4]; } display; diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c index 7ee38c3..a989e89 100644 --- a/generic/tkTreeItem.c +++ b/generic/tkTreeItem.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeItem.c,v 1.100 2007/01/23 22:41:31 treectrl Exp $ + * RCS: @(#) $Id: tkTreeItem.c,v 1.101 2007/04/21 21:34:01 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -3590,7 +3590,7 @@ ItemDrawBackground( TreeColumn treeColumn, /* Tree-column token. */ TreeItem item, /* Item record. */ Column *column, /* First column. */ - Drawable drawable, /* Where to draw. */ + TreeDrawable drawable, /* Where to draw. */ int x, int y, /* Area of the item to draw. */ int width, int height, /* ^ */ int index /* Used to select a color from the @@ -3606,9 +3606,9 @@ ItemDrawBackground( * FIXME: If the background image is non-transparent, there is no * need to erase first. */ - XFillRectangle(tree->display, drawable, gc, x, y, width, height); + XFillRectangle(tree->display, drawable.drawable, gc, x, y, width, height); if (tree->backgroundImage != NULL) { - Tree_DrawTiledImage(tree, drawable, tree->backgroundImage, x, y, + Tree_DrawTiledImage(tree, drawable.drawable, tree->backgroundImage, x, y, x + width, y + height, tree->drawableXOrigin, tree->drawableYOrigin); } @@ -3949,7 +3949,7 @@ TreeItem_WalkSpans( spanCount = Item_GetSpans(tree, item, treeColumn, spans); drawArgs.tree = tree; - drawArgs.drawable = None; + drawArgs.td.drawable = None; totalWidth = 0; for (spanIndex = 0; spanIndex < spanCount; spanIndex++) { @@ -4023,7 +4023,7 @@ SpanWalkProc_Draw( Column *itemColumn = (Column *) spanPtr->itemColumn; int i, x; struct { - Drawable drawable; + TreeDrawable td; int minX; int maxX; int index; @@ -4034,14 +4034,14 @@ SpanWalkProc_Draw( (drawArgs->x + drawArgs->width <= data->minX)) return 0; - drawArgs->drawable = data->drawable; + drawArgs->td = data->td; /* Draw background colors. */ if (spanPtr->span == 1) { /* Important point: use drawArgs->width since an item's width may * be totally different than tree->columnVis' width. */ ItemDrawBackground(tree, treeColumn, item, itemColumn, - drawArgs->drawable, drawArgs->x, drawArgs->y, + drawArgs->td, drawArgs->x, drawArgs->y, drawArgs->width, drawArgs->height, data->index); } else { x = drawArgs->x; @@ -4050,7 +4050,7 @@ SpanWalkProc_Draw( if ((columnWidth > 0) && (x < data->maxX) && (x + columnWidth > data->minX)) { ItemDrawBackground(tree, treeColumn, item, itemColumn, - drawArgs->drawable, x, drawArgs->y, + drawArgs->td, x, drawArgs->y, columnWidth, drawArgs->height, data->index); } x += columnWidth; @@ -4066,10 +4066,10 @@ SpanWalkProc_Draw( if (spanPtr->treeColumn == tree->columnTree) { if (tree->showLines) TreeItem_DrawLines(tree, item, drawArgs->x, drawArgs->y, - drawArgs->width, drawArgs->height, data->drawable); + drawArgs->width, drawArgs->height, data->td); if (tree->showButtons) TreeItem_DrawButton(tree, item, drawArgs->x, drawArgs->y, - drawArgs->width, drawArgs->height, data->drawable); + drawArgs->width, drawArgs->height, data->td); } /* Stop walking if we went past the right edge of the dirty area. */ @@ -4099,20 +4099,20 @@ TreeItem_Draw( int lock, /* Which columns. */ int x, int y, /* Drawable coordinates of the item. */ int width, int height, /* Total size of the item. */ - Drawable drawable, /* Where to draw. */ + TreeDrawable td, /* Where to draw. */ int minX, int maxX, /* Left/right edge that needs to be drawn. */ int index /* Used to select a color from a * tree-column's -itembackground option. */ ) { struct { - Drawable drawable; + TreeDrawable td; int minX; int maxX; int index; } clientData; - clientData.drawable = drawable; + clientData.td = td; clientData.minX = minX; clientData.maxX = maxX; clientData.index = index; @@ -4145,7 +4145,7 @@ TreeItem_DrawLines( TreeItem item, /* Item token. */ int x, int y, /* Drawable coordinates of columnTree. */ int width, int height, /* Total size of columnTree. */ - Drawable drawable /* Where to draw. */ + TreeDrawable td /* Where to draw. */ ) { TreeItem parent, walk; @@ -4198,12 +4198,12 @@ TreeItem_DrawLines( if (tree->lineStyle == LINE_STYLE_DOT) { for (i = 0; i < tree->lineThickness; i++) - Tree_VDotLine(tree, drawable, tree->lineGC, + Tree_VDotLine(tree, td.drawable, tree->lineGC, lineLeft + i, top, bottom); } else - XFillRectangle(tree->display, drawable, tree->lineGC, + XFillRectangle(tree->display, td.drawable, tree->lineGC, lineLeft, top, tree->lineThickness, @@ -4217,12 +4217,12 @@ TreeItem_DrawLines( if (hasPrev || hasNext) { if (tree->lineStyle == LINE_STYLE_DOT) { for (i = 0; i < tree->lineThickness; i++) - Tree_HDotLine(tree, drawable, tree->lineGC, + Tree_HDotLine(tree, td.drawable, tree->lineGC, lineLeft + vert, lineTop + i, x /* + tree->columnTreeLeft */ + indent); } else - XFillRectangle(tree->display, drawable, tree->lineGC, + XFillRectangle(tree->display, td.drawable, tree->lineGC, lineLeft + vert, lineTop, left + tree->useIndent - (lineLeft + vert), @@ -4247,12 +4247,12 @@ TreeItem_DrawLines( if (item != NULL) { if (tree->lineStyle == LINE_STYLE_DOT) { for (i = 0; i < tree->lineThickness; i++) - Tree_VDotLine(tree, drawable, tree->lineGC, + Tree_VDotLine(tree, td.drawable, tree->lineGC, lineLeft + i, y, y + height); } else - XFillRectangle(tree->display, drawable, tree->lineGC, + XFillRectangle(tree->display, td.drawable, tree->lineGC, lineLeft, y, tree->lineThickness, @@ -4283,7 +4283,7 @@ TreeItem_DrawButton( TreeItem item, /* Item token. */ int x, int y, /* Drawable coordinates of columnTree. */ int width, int height, /* Total size of columnTree. */ - Drawable drawable /* Where to draw. */ + TreeDrawable td /* Where to draw. */ ) { int indent, left, lineLeft, lineTop; @@ -4309,7 +4309,7 @@ TreeItem_DrawButton( if (image != NULL) { int imgW, imgH; Tk_SizeOfImage(image, &imgW, &imgH); - Tk_RedrawImage(image, 0, 0, imgW, imgH, drawable, + Tree_RedrawImage(image, 0, 0, imgW, imgH, td, left + (tree->useIndent - imgW) / 2, y + (height - imgH) / 2); return; @@ -4322,7 +4322,7 @@ TreeItem_DrawButton( Tk_SizeOfBitmap(tree->display, bitmap, &bmpW, &bmpH); bx = left + (tree->useIndent - bmpW) / 2; by = y + (height - bmpH) / 2; - Tree_DrawBitmap(tree, bitmap, drawable, NULL, NULL, + Tree_DrawBitmap(tree, bitmap, td.drawable, NULL, NULL, 0, 0, (unsigned int) bmpW, (unsigned int) bmpH, bx, by); return; @@ -4330,9 +4330,9 @@ TreeItem_DrawButton( if (tree->useTheme) { int bw, bh; - if (TreeTheme_GetButtonSize(tree, drawable, item->state & STATE_OPEN, + if (TreeTheme_GetButtonSize(tree, td.drawable, item->state & STATE_OPEN, &bw, &bh) == TCL_OK) { - if (TreeTheme_DrawButton(tree, drawable, item->state & STATE_OPEN, + if (TreeTheme_DrawButton(tree, td.drawable, item->state & STATE_OPEN, left + (tree->useIndent - bw) / 2, y + (height - bh) / 2, bw, bh) == TCL_OK) { return; @@ -4354,7 +4354,7 @@ TreeItem_DrawButton( buttonTop = y + (height - tree->buttonSize) / 2; /* Erase button background */ - XFillRectangle(tree->display, drawable, + XFillRectangle(tree->display, td.drawable, Tk_3DBorderGC(tree->tkwin, tree->border, TK_3D_FLAT_GC), buttonLeft + tree->buttonThickness, buttonTop + tree->buttonThickness, @@ -4362,14 +4362,14 @@ TreeItem_DrawButton( tree->buttonSize - tree->buttonThickness); /* Draw button outline */ - XDrawRectangle(tree->display, drawable, tree->buttonGC, + XDrawRectangle(tree->display, td.drawable, tree->buttonGC, buttonLeft + w1, buttonTop + w1, tree->buttonSize - tree->buttonThickness + macoffset, tree->buttonSize - tree->buttonThickness + macoffset); /* Horizontal '-' */ - XFillRectangle(tree->display, drawable, tree->buttonGC, + XFillRectangle(tree->display, td.drawable, tree->buttonGC, buttonLeft + tree->buttonThickness * 2, lineTop, tree->buttonSize - tree->buttonThickness * 4, @@ -4377,7 +4377,7 @@ TreeItem_DrawButton( if (!(item->state & STATE_OPEN)) { /* Finish '+' */ - XFillRectangle(tree->display, drawable, tree->buttonGC, + XFillRectangle(tree->display, td.drawable, tree->buttonGC, lineLeft, buttonTop + tree->buttonThickness * 2, tree->buttonThickness, diff --git a/generic/tkTreeStyle.c b/generic/tkTreeStyle.c index 851420f..a983d08 100644 --- a/generic/tkTreeStyle.c +++ b/generic/tkTreeStyle.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeStyle.c,v 1.74 2007/01/31 00:52:17 treectrl Exp $ + * RCS: @(#) $Id: tkTreeStyle.c,v 1.75 2007/04/21 21:34:01 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -2347,7 +2347,8 @@ void TreeStyle_Draw( args.tree = tree; args.state = drawArgs->state; - args.display.drawable = drawArgs->drawable; + args.display.td = drawArgs->td; + args.display.drawable = drawArgs->td.drawable; for (i = 0; i < masterStyle->numElements; i++) { struct Layout *layout = &layouts[i]; @@ -2541,7 +2542,8 @@ TreeStyle_UpdateWindowPositions( args.tree = tree; args.state = drawArgs->state; - args.display.drawable = drawArgs->drawable; + args.display.td = drawArgs->td; + args.display.drawable = drawArgs->td.drawable; for (i = 0; i < numElements; i++) { struct Layout *layout = &layouts[i]; diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c index 403b39d..2827532 100644 --- a/generic/tkTreeUtils.c +++ b/generic/tkTreeUtils.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeUtils.c,v 1.66 2007/03/03 22:16:44 treectrl Exp $ + * RCS: @(#) $Id: tkTreeUtils.c,v 1.67 2007/04/21 21:34:01 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -1146,6 +1146,64 @@ Tree_UnsetClipMask( /* *---------------------------------------------------------------------- * + * Tree_RedrawImage -- + * + * Wrapper around Tk_RedrawImage to clip the drawing to the actual + * area of the drawable. If you try to draw a transparent photo + * image outside the bounds of a drawable, X11 will silently fail + * and nothing will be drawn. See tkImgPhoto.c:ImgPhotoDisplay. + * + * Results: + * None. + * + * Side effects: + * Stuff is drawn. + * + *---------------------------------------------------------------------- + */ +void Tree_RedrawImage( + Tk_Image image, + int imageX, + int imageY, + int width, + int height, + TreeDrawable td, + int drawableX, + int drawableY + ) +{ +#if 0 + int ix = imageX, iy = imageY, iw = width, ih = height; +#endif + if (drawableX < 0) { + imageX = 0 - drawableX; + width -= imageX; + drawableX = 0; + } + if (drawableX + width > td.width) { + width -= (drawableX + width) - td.width; + } + if (drawableY < 0) { + imageY = 0 - drawableY; + height -= imageY; + drawableY = 0; + } + if (drawableY + height > td.height) { + height -= (drawableY + height) - td.height; + } +#if 0 + if (ix != imageX || iy != imageY || iw != width || ih != height) + dbwin("Tree_RedrawImage clipped %d,%d,%d,%d -> %d,%d,%d,%d\n", ix,iy,iw,ih, imageX, imageY, width, height); +#endif + if (width > 0 && height > 0) { + Tk_RedrawImage(image, imageX, imageY, width, height, td.drawable, + drawableX, drawableY); + } +} + +/* + *---------------------------------------------------------------------- + * * Tree_DrawBitmapWithGC -- * * Draw part of a bitmap. -- cgit v0.12