From 583fccf7dacaca22ab10188f000498427a7b0b6b Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 22 Apr 2002 12:45:48 +0000 Subject: Fix for Bug 223739 to get rid of floating point equality test. Sorry for delaying this fix for months; I hadn't noticed that it had been reviewed! --- ChangeLog | 12 ++++++++++++ generic/tkTextDisp.c | 22 +++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 451a49d..8727893 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2002-04-22 Donal K. Fellows + + * generic/tkTextDisp.c (GetXView,GetYView): Comparison with + previous values of scrollbar range are now done in a way that is + sensitive to the bizarreness of floating-point on architectures + where IEEE-FP is not used on the processor. Also increased the + size of the temporary buffer to take account of the fact that + TCL_DOUBLE_SPACE is meant to only imply enough space to take a + printed double and trailing '\0', and no more. [Bug #223739] + (FP_EQUAL_SCALE): New macro to help compare floating-point numbers + for equality in a sane way, used in GetXView and GetYView. + 2002-04-12 Jeff Hobbs * generic/tkWindow.c (TkCloseDisplay): Added to centralize where a diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index e0d1d57..2a3cf44 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -11,7 +11,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.9 2000/01/06 02:18:59 hobbs Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.10 2002/04/22 12:45:49 dkf Exp $ */ #include "tkPort.h" @@ -96,6 +96,16 @@ typedef struct TextStyle { && ((s1)->sValuePtr->bgStipple == (s2)->sValuePtr->bgStipple)) /* + * The following macro is used to compare two floating-point numbers + * to within a certain degree of scale. Direct comparison fails on + * processors where the processor and memory representations of FP + * numbers of a particular precision is different (e.g. Intel) + */ + +#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \ + (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3) + +/* * The following structure describes one line of the display, which may * be either part or all of one line of the text. */ @@ -3865,7 +3875,7 @@ GetXView(interp, textPtr, report) * scrollbar if it has changed. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; - char buffer[TCL_DOUBLE_SPACE * 2]; + char buffer[TCL_DOUBLE_SPACE * 2 + 1]; double first, last; int code; @@ -3886,7 +3896,8 @@ GetXView(interp, textPtr, report) Tcl_SetResult(interp, buffer, TCL_VOLATILE); return; } - if ((first == dInfoPtr->xScrollFirst) && (last == dInfoPtr->xScrollLast)) { + if (FP_EQUAL_SCALE(first, dInfoPtr->xScrollFirst, dInfoPtr->maxLength) && + FP_EQUAL_SCALE(last, dInfoPtr->xScrollLast, dInfoPtr->maxLength)) { return; } dInfoPtr->xScrollFirst = first; @@ -3936,7 +3947,7 @@ GetYView(interp, textPtr, report) * scrollbar if it has changed. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; - char buffer[TCL_DOUBLE_SPACE * 2]; + char buffer[TCL_DOUBLE_SPACE * 2 + 1]; double first, last; DLine *dlPtr; int totalLines, code, count; @@ -3971,7 +3982,8 @@ GetYView(interp, textPtr, report) Tcl_SetResult(interp, buffer, TCL_VOLATILE); return; } - if ((first == dInfoPtr->yScrollFirst) && (last == dInfoPtr->yScrollLast)) { + if (FP_EQUAL_SCALE(first, dInfoPtr->yScrollFirst, totalLines) && + FP_EQUAL_SCALE(last, dInfoPtr->yScrollLast, totalLines)) { return; } dInfoPtr->yScrollFirst = first; -- cgit v0.12