Description: |
% info patchlevel
8.5.11
% canvas .c
.c
% set x 573.8
573.8
% .c canvasx $x
574.0
% set x [expr $x+0.0]
573.8
% .c canvasx $x
573.0
Note how the first result 574 differs from the second 573.
this is due to the code in tkObj.c which converts numbers to pixels
and does a rounding in one case and none in the other:
tk/generic/tkObj.c, static int GetPixelsFromObjEx(...),
#206ff
if (objPtr->typePtr != &pixelObjType) {
ThreadSpecificData *tsdPtr = GetTypeCache();
if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
(void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
if (dblPtr != NULL) {
*dblPtr = d;
}
*intPtr = (int) d;
return TCL_OK;
Note this simply casts the double to int, no rounding.
However, in the same routine, if the obj is not double or int:
if (objPtr->typePtr != &pixelObjType) {
result = SetPixelFromAny(interp, objPtr);
...
if ((pixelPtr->tkwin != tkwin)||dblPtr) {
d = pixelPtr->value;
--<snip-snip>--
if (d < 0) {
pixelPtr->returnValue = (int) (d - 0.5);
} else {
pixelPtr->returnValue = (int) (d + 0.5);
}
--<snip-snip>--
}
*intPtr = pixelPtr->returnValue;
Note the rounding in this case.
Proposed patch:
This seems to be related to
2011-11-01 Donal K. Fellows <[email protected]>
* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3431491]: Use a bit of
type hackery to allow numbers to be interpreted as coordinates (most
notably on a canvas) without reinterpreting via a string.
Proposed patch:
--- tk/generic/tkObj.c2011/11/08 14:59:181.1
+++ tk/generic/tkObj.c2012/03/06 18:15:36
@@ -211,7 +211,11 @@
if (dblPtr != NULL) {
*dblPtr = d;
}
- *intPtr = (int) d;
+ if (d < 0) {
+*intPtr = (int) (d - 0.5);
+ } else {
+*intPtr = (int) (d + 0.5);
+ }
return TCL_OK;
} else if (objPtr->typePtr == tsdPtr->intTypePtr) {
(void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
|