diff options
Diffstat (limited to 'generic/tkTextDisp.c')
-rw-r--r-- | generic/tkTextDisp.c | 115 |
1 files changed, 64 insertions, 51 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index e47a19d..e1a3fee 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextDisp.c,v 1.28 2003/11/14 17:21:03 dkf Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.29 2003/11/15 02:33:50 vincentdarley Exp $ */ #include "tkPort.h" @@ -232,10 +232,9 @@ typedef struct TextDInfo { * Information used for scrolling: */ - int newXByteOffset; /* Desired x scroll position, measured as the - * number of average-size characters off-screen - * to the left for a line with no left - * margin. */ + int newXPixelOffset; /* Desired x scroll position, measured as the + * number of pixels off-screen to the left + * for a line with no left margin. */ int curXPixelOffset; /* Actual x scroll position, measured as the * number of pixels off-screen to the left. */ int maxLength; /* Length in pixels of longest line that's @@ -255,9 +254,8 @@ typedef struct TextDInfo { * The following information is used to implement scanning: */ - int scanMarkIndex; /* Byte index of character that was at the - * left edge of the window when the scan - * started. */ + int scanMarkXPixel; /* Pixel index of left edge of the window + * when the scan started. */ int scanMarkX; /* X-position of mouse at time scan started. */ int scanTotalYScroll; /* Total scrolling (in screen pixels) that has * occurred since scanMarkY was set. */ @@ -495,14 +493,14 @@ TkTextCreateDInfo(textPtr) dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues); dInfoPtr->topOfEof = 0; - dInfoPtr->newXByteOffset = 0; + dInfoPtr->newXPixelOffset = 0; dInfoPtr->curXPixelOffset = 0; dInfoPtr->maxLength = 0; dInfoPtr->xScrollFirst = -1; dInfoPtr->xScrollLast = -1; dInfoPtr->yScrollFirst = -1; dInfoPtr->yScrollLast = -1; - dInfoPtr->scanMarkIndex = 0; + dInfoPtr->scanMarkXPixel = 0; dInfoPtr->scanMarkX = 0; dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = 0; @@ -1861,15 +1859,29 @@ UpdateDisplayInfo(textPtr) dInfoPtr->maxLength = dlPtr->length; } } - maxOffset = (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) - + textPtr->charWidth - 1)/textPtr->charWidth; - if (dInfoPtr->newXByteOffset > maxOffset) { - dInfoPtr->newXByteOffset = maxOffset; + maxOffset = dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x); + + xPixelOffset = dInfoPtr->newXPixelOffset; + if (xPixelOffset > maxOffset) { + xPixelOffset = maxOffset; + } + if (xPixelOffset < 0) { + xPixelOffset = 0; } - if (dInfoPtr->newXByteOffset < 0) { - dInfoPtr->newXByteOffset = 0; + + /* + * Here's a problem: see the tests textDisp-29.2.1-4 + * + * If the widget is being created, but has not yet been configured + * it will have a maxY of 1 above, and we we won't have examined + * all the lines (just the first line, in fact), and so maxOffset + * will not be a true reflection of the widget's lines. Therefore + * we must not overwrite the original newXPixelOffset in this case. + */ + if (!(((Tk_FakeWin *) (textPtr->tkwin))->flags & TK_NEED_CONFIG_NOTIFY)) { + dInfoPtr->newXPixelOffset = xPixelOffset; } - xPixelOffset = dInfoPtr->newXByteOffset * textPtr->charWidth; + if (xPixelOffset != dInfoPtr->curXPixelOffset) { dInfoPtr->curXPixelOffset = xPixelOffset; for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL; @@ -2689,7 +2701,7 @@ TkTextInvalidateLineMetrics(textPtr, linePtr, lineCount, action) fromLine = TkBTreeLineIndex(linePtr); /* - * Invalid the height calculations of each line in the + * Invalidate the height calculations of each line in the * given range. */ linePtr->pixelCalculationEpoch = 0; @@ -3923,7 +3935,7 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag) lineCount -= TkBTreeLineIndex(startLine); } TkTextInvalidateLineMetrics(textPtr, startLine, lineCount, - TK_TEXT_INVALIDATE_ONLY); + TK_TEXT_INVALIDATE_ONLY); } /* @@ -4124,6 +4136,9 @@ TkTextRelayoutWindow(textPtr, mask) if (dInfoPtr->maxX <= dInfoPtr->x) { dInfoPtr->maxX = dInfoPtr->x + 1; } + /* + * This is the only place where dInfoPtr->maxY is set. + */ dInfoPtr->maxY = Tk_Height(textPtr->tkwin) - textPtr->highlightWidth - textPtr->borderWidth - textPtr->padY; if (dInfoPtr->maxY <= dInfoPtr->y) { @@ -4630,21 +4645,17 @@ TkTextSeeCmd(textPtr, interp, objc, objv) oneThird = lineWidth/3; if (delta < 0) { if (delta < -oneThird) { - dInfoPtr->newXByteOffset = (x - lineWidth/2) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset = (x - lineWidth/2); } else { - dInfoPtr->newXByteOffset -= ((-delta) + textPtr->charWidth - 1) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset -= ((-delta) ); } } else { delta -= (lineWidth - width); if (delta > 0) { if (delta > oneThird) { - dInfoPtr->newXByteOffset = (x - lineWidth/2) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset = (x - lineWidth/2); } else { - dInfoPtr->newXByteOffset += - (delta+textPtr->charWidth-1) / textPtr->charWidth; + dInfoPtr->newXPixelOffset += (delta ); } } else { return TCL_OK; @@ -4699,34 +4710,36 @@ TkTextXviewCmd(textPtr, interp, objc, objv) return TCL_OK; } - newOffset = dInfoPtr->newXByteOffset; - type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); + newOffset = dInfoPtr->newXPixelOffset; + type = TextGetScrollInfoObj(interp, textPtr, objc, objv, + &fraction, &count); switch (type) { - case TK_SCROLL_ERROR: + case TKTEXT_SCROLL_ERROR: return TCL_ERROR; - case TK_SCROLL_MOVETO: + case TKTEXT_SCROLL_MOVETO: if (fraction > 1.0) { fraction = 1.0; } if (fraction < 0) { fraction = 0; } - newOffset = (int) (((fraction * dInfoPtr->maxLength) - / textPtr->charWidth) + 0.5); + newOffset = (int) (fraction * dInfoPtr->maxLength + 0.5); break; - case TK_SCROLL_PAGES: + case TKTEXT_SCROLL_PAGES: charsPerPage = (dInfoPtr->maxX-dInfoPtr->x)/textPtr->charWidth - 2; if (charsPerPage < 1) { charsPerPage = 1; } - newOffset += charsPerPage * count; + newOffset += charsPerPage * count * textPtr->charWidth; + break; + case TKTEXT_SCROLL_UNITS: + newOffset += count * textPtr->charWidth; break; - case TK_SCROLL_UNITS: + case TKTEXT_SCROLL_PIXELS: newOffset += count; break; } - - dInfoPtr->newXByteOffset = newOffset; + dInfoPtr->newXPixelOffset = newOffset; dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; @@ -5106,7 +5119,7 @@ TkTextScanCmd(textPtr, interp, objc, objv) { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; - int c, x, y, totalScroll, newByte, maxByte, gain=10; + int c, x, y, totalScroll, gain=10; size_t length; if ((objc != 5) && (objc != 6)) { @@ -5128,6 +5141,8 @@ TkTextScanCmd(textPtr, interp, objc, objv) c = Tcl_GetString(objv[2])[0]; length = strlen(Tcl_GetString(objv[2])); if (c=='d' && strncmp(Tcl_GetString(objv[2]), "dragto", length)==0) { + int newX, maxX; + /* * Amplify the difference between the current position and the * mark position to compute how much the view should shift, then @@ -5140,20 +5155,18 @@ TkTextScanCmd(textPtr, interp, objc, objv) * moving again). */ - newByte = dInfoPtr->scanMarkIndex + (gain*(dInfoPtr->scanMarkX - x)) - / (textPtr->charWidth); - maxByte = 1 + (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) - + textPtr->charWidth - 1)/textPtr->charWidth; - if (newByte < 0) { - newByte = 0; - dInfoPtr->scanMarkIndex = 0; + newX = dInfoPtr->scanMarkXPixel + gain*(dInfoPtr->scanMarkX - x); + maxX = 1 + dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x); + if (newX < 0) { + newX = 0; + dInfoPtr->scanMarkXPixel = 0; dInfoPtr->scanMarkX = x; - } else if (newByte > maxByte) { - newByte = maxByte; - dInfoPtr->scanMarkIndex = maxByte; + } else if (newX > maxX) { + newX = maxX; + dInfoPtr->scanMarkXPixel = maxX; dInfoPtr->scanMarkX = x; } - dInfoPtr->newXByteOffset = newByte; + dInfoPtr->newXPixelOffset = newX; totalScroll = gain*(dInfoPtr->scanMarkY - y); if (totalScroll != dInfoPtr->scanTotalYScroll) { @@ -5167,7 +5180,7 @@ TkTextScanCmd(textPtr, interp, objc, objv) } } } else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) { - dInfoPtr->scanMarkIndex = dInfoPtr->newXByteOffset; + dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset; dInfoPtr->scanMarkX = x; dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = y; |