Tk Source Code

View Ticket
Login
2012-03-07
21:25 Closed ticket [3497848f]: GetPixelsFromObjEx error for doubleObjs plus 8 other changes artifact: 47c35b03 user: dkf
01:47 Ticket [3497848f]: 1 change artifact: 44cd410b user: hobbs
2012-03-06
18:30 New ticket [3497848f]. artifact: e1d408ad user: ralfixx

Ticket UUID: 3497848
Title: GetPixelsFromObjEx error for doubleObjs
Type: Bug Version: obsolete: 8.5.10
Submitter: ralfixx Created on: 2012-03-06 18:30:01
Subsystem: 27. Objects Assigned To: dkf
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2012-03-07 21:25:58
Resolution: Fixed Closed By: dkf
    Closed on: 2012-03-07 14:25:58
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);
User Comments: dkf added on 2012-03-07 21:25:58:

allow_comments - 1