summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authortreectrl <treectrl>2005-07-07 02:57:19 (GMT)
committertreectrl <treectrl>2005-07-07 02:57:19 (GMT)
commit711538e316a5a69e274eb6c5ce90b594589698a4 (patch)
tree05c7d6945581c929ec12b7eb094f68680ff350ab /generic
parentad0683fec0c8d24da416a398916857ab8cb0ee72 (diff)
downloadtktreectrl-711538e316a5a69e274eb6c5ce90b594589698a4.zip
tktreectrl-711538e316a5a69e274eb6c5ce90b594589698a4.tar.gz
tktreectrl-711538e316a5a69e274eb6c5ce90b594589698a4.tar.bz2
Bitmap, image and text elements are drawn clipped if given less space than they need.
TextUpdateLayout: fiddled with debug messages. Fixed line wrapping of text elements. It did not work for single lines of text at all.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkTreeElem.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/generic/tkTreeElem.c b/generic/tkTreeElem.c
index 7915aba..73f8480 100644
--- a/generic/tkTreeElem.c
+++ b/generic/tkTreeElem.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2005 Tim Baker
*
- * RCS: @(#) $Id: tkTreeElem.c,v 1.32 2005/07/05 02:14:40 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeElem.c,v 1.33 2005/07/07 02:57:19 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -289,10 +289,10 @@ static void AdjustForSticky(int sticky, int cavityWidth, int cavityHeight,
sticky &= ~(STICKY_N | STICKY_S);
}
if (!(sticky & STICKY_W)) {
- *xPtr += (sticky & STICKY_E) ? dx : dx / 2;
+ *xPtr += (sticky & STICKY_E) ? dx : dx / 2;
}
if (!(sticky & STICKY_N)) {
- *yPtr += (sticky & STICKY_S) ? dy : dy / 2;
+ *yPtr += (sticky & STICKY_S) ? dy : dy / 2;
}
}
@@ -504,6 +504,10 @@ static void DisplayProcBitmap(ElementArgs *args)
args->display.width, args->display.height,
FALSE, FALSE,
&x, &y, &width, &height);
+ if (imgW > args->display.width)
+ imgW = args->display.width;
+ if (imgH > args->display.height)
+ imgH = args->display.height;
Tree_DrawBitmap(tree, bitmap, args->display.drawable, fg, bg,
0, 0, (unsigned int) imgW, (unsigned int) imgH,
x, y);
@@ -1510,6 +1514,10 @@ static void DisplayProcImage(ElementArgs *args)
args->display.width, args->display.height,
FALSE, FALSE,
&x, &y, &width, &height);
+ if (imgW > args->display.width)
+ 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);
}
@@ -2442,7 +2450,7 @@ static void TextUpdateStringRep(ElementArgs *args)
}
}
-static void TextUpdateLayout(ElementArgs *args, int fixedWidth, int maxWidth)
+static void TextUpdateLayout(char *func, ElementArgs *args, int fixedWidth, int maxWidth)
{
TreeCtrl *tree = args->tree;
Element *elem = args->elem;
@@ -2461,9 +2469,13 @@ static void TextUpdateLayout(ElementArgs *args, int fixedWidth, int maxWidth)
int i, multiLine = FALSE;
int textWidth;
+ if (tree->debug.enable && tree->debug.textLayout)
+ dbwin("TextUpdateLayout: %s %p (%s) %s\n",
+ Tk_PathName(tree->tkwin), elemX, masterX ? "instance" : "master", func);
+
if (elemX->layout != NULL) {
if (tree->debug.enable && tree->debug.textLayout)
- dbwin("TextUpdateLayout %s: free %p (%s)\n", Tk_PathName(tree->tkwin), elemX, masterX ? "instance" : "master");
+ dbwin(" FREE\n");
TextLayout_Free(elemX->layout);
elemX->layout = NULL;
}
@@ -2508,12 +2520,13 @@ static void TextUpdateLayout(ElementArgs *args, int fixedWidth, int maxWidth)
}
}
if (tree->debug.enable && tree->debug.textLayout)
- dbwin("TextUpdateLayout: lines %d multiLine %d width %d\n",
+ dbwin(" lines %d multiLine %d width %d\n",
lines, multiLine, width);
if (!multiLine) {
if (width == 0)
return;
textWidth = Tk_TextWidth(tkfont, text, textLen);
+if (tree->debug.enable && tree->debug.textLayout) dbwin(" textWidth %d\n", textWidth);
if (width >= textWidth)
return;
}
@@ -2535,7 +2548,7 @@ static void TextUpdateLayout(ElementArgs *args, int fixedWidth, int maxWidth)
Tcl_NumUtfChars(text, textLen), width, justify, lines, flags);
if (tree->debug.enable && tree->debug.textLayout)
- dbwin("TextUpdateLayout %s: alloc %p (%s)\n", Tk_PathName(tree->tkwin), elemX, masterX ? "instance" : "master");
+ dbwin(" ALLOC\n");
}
#ifdef TEXTVAR
@@ -2759,18 +2772,20 @@ static int CreateProcText(ElementArgs *args)
return TCL_OK;
}
-static void TextRedoLayoutIfNeeded(ElementArgs *args, int fixedWidth)
+static void TextRedoLayoutIfNeeded(char *func, ElementArgs *args, int fixedWidth)
{
ElementText *elemX = (ElementText *) args->elem;
int doLayout = 0;
- /* See comment in NeededProc about totalWidth */
- if (fixedWidth >= elemX->neededWidth)
- fixedWidth = elemX->totalWidth;
+ if (elemX->layout != NULL) {
+ /* See comment in NeededProc about totalWidth */
+ if ((elemX->neededWidth != -1) && fixedWidth >= elemX->neededWidth)
+ fixedWidth = elemX->totalWidth;
- /* Already layed out at this width */
- if (fixedWidth == elemX->layoutWidth)
- return;
+ /* Already layed out at this width */
+ if (fixedWidth == elemX->layoutWidth)
+ return;
+ }
/* May switch from layout -> no layout or vice versa */
if (elemX->layout == NULL)
@@ -2789,7 +2804,7 @@ static void TextRedoLayoutIfNeeded(ElementArgs *args, int fixedWidth)
doLayout = 1;
}
if (doLayout)
- TextUpdateLayout(args, fixedWidth, -1);
+ TextUpdateLayout(func, args, fixedWidth, -1);
elemX->layoutInvalid = FALSE;
if (elemX->layout != NULL)
elemX->layoutWidth = fixedWidth;
@@ -2817,6 +2832,7 @@ static void DisplayProcText(ElementArgs *args)
GC gc;
int bytesThatFit, pixelsForText;
char *ellipsis = "...";
+ TkRegion clipRgn = NULL;
BOOLEAN_FOR_STATE(draw, draw, state)
if (!draw)
@@ -2855,7 +2871,7 @@ static void DisplayProcText(ElementArgs *args)
gc = tree->textGC;
}
- TextRedoLayoutIfNeeded(args, args->display.width);
+ TextRedoLayoutIfNeeded("DisplayProcText", args, args->display.width);
if (elemX->layout != NULL)
layout = elemX->layout;
@@ -2865,14 +2881,29 @@ static void DisplayProcText(ElementArgs *args)
/* Hack -- The actual size of the text may be slightly smaller than
* the available space when squeezed. If so we don't want to center
* the text horizontally */
- if (elemX->neededWidth > width)
+ if ((elemX->neededWidth == -1) || (elemX->neededWidth > width))
width = args->display.width;
AdjustForSticky(args->display.sticky,
args->display.width, args->display.height,
FALSE, FALSE,
&x, &y, &width, &height);
+ /* Use clipping if text is taller than display height */
+ if (height > args->display.height) {
+ XRectangle rect;
+ clipRgn = TkCreateRegion();
+ rect.x = x;
+ rect.y = y;
+ rect.width = args->display.width;
+ rect.height = args->display.height;
+ TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
+ TkSetRegion(tree->display, gc, clipRgn);
+ }
TextLayout_Draw(tree->display, args->display.drawable, gc,
layout, x, y, 0, -1);
+ if (clipRgn != NULL) {
+ UnsetClipMask(tree, args->display.drawable, gc);
+ TkDestroyRegion(clipRgn);
+ }
return;
}
@@ -2890,6 +2921,17 @@ static void DisplayProcText(ElementArgs *args)
args->display.width, args->display.height,
FALSE, FALSE,
&x, &y, &width, &height);
+ /* Use clipping if text is taller than display height */
+ if (height > args->display.height) {
+ XRectangle rect;
+ clipRgn = TkCreateRegion();
+ rect.x = x;
+ rect.y = y;
+ rect.width = args->display.width;
+ rect.height = args->display.height;
+ TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
+ TkSetRegion(tree->display, gc, clipRgn);
+ }
if (bytesThatFit != textLen) {
char staticStr[256], *buf = staticStr;
int bufLen = abs(bytesThatFit);
@@ -2910,6 +2952,10 @@ static void DisplayProcText(ElementArgs *args)
Tk_DrawChars(tree->display, args->display.drawable, gc,
tkfont, text, textLen, x, y + fm.ascent);
}
+ if (clipRgn != NULL) {
+ UnsetClipMask(tree, args->display.drawable, gc);
+ TkDestroyRegion(clipRgn);
+ }
}
static void NeededProcText(ElementArgs *args)
@@ -2937,7 +2983,7 @@ static void NeededProcText(ElementArgs *args)
elemX->stringRepInvalid = FALSE;
}
- TextUpdateLayout(args, args->needed.fixedWidth, args->needed.maxWidth);
+ TextUpdateLayout("NeededProcText", args, args->needed.fixedWidth, args->needed.maxWidth);
elemX->layoutInvalid = FALSE;
elemX->layoutWidth = -1;
elemX->neededWidth = -1;
@@ -3003,7 +3049,7 @@ static void HeightProcText(ElementArgs *args)
Tk_Font tkfont;
Tk_FontMetrics fm;
- TextRedoLayoutIfNeeded(args, args->height.fixedWidth);
+ TextRedoLayoutIfNeeded("HeightProcText", args, args->height.fixedWidth);
if (elemX->layout != NULL) {
TextLayout_Size(elemX->layout, NULL, &height);