diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2011-11-01 22:46:40 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2011-11-01 22:46:40 (GMT) |
commit | 001ae23c00c84af98a880e6f37b976d94aa7b6fe (patch) | |
tree | c0f7aa3d90f6406a2d3698d15f89dd8e0737d304 | |
parent | 6e979156d6fa9009b6b5cd3bce6904fcdbaf4fa2 (diff) | |
download | tk-001ae23c00c84af98a880e6f37b976d94aa7b6fe.zip tk-001ae23c00c84af98a880e6f37b976d94aa7b6fe.tar.gz tk-001ae23c00c84af98a880e6f37b976d94aa7b6fe.tar.bz2 |
* 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.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tkObj.c | 47 |
2 files changed, 52 insertions, 1 deletions
@@ -1,3 +1,9 @@ +2011-11-01 Donal K. Fellows <dkf@users.sf.net> + + * 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. + 2011-10-26 Don Porter <dgp@users.sourceforge.net> * changes: Updates for 8.5.11. diff --git a/generic/tkObj.c b/generic/tkObj.c index d973bd4..cb222cb 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -39,6 +39,19 @@ typedef struct PixelRep { #define GET_COMPLEXPIXEL(objPtr) \ ((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2) +/* + * One of these structures is created per thread to store thread-specific + * data. In this case, it is used to contain references to selected + * Tcl_ObjTypes that we can use as screen distances without conversion. The + * "dataKey" below is used to locate the ThreadSpecificData for the current + * thread. + */ + +typedef struct ThreadSpecificData { + Tcl_ObjType *doubleTypePtr; + Tcl_ObjType *intTypePtr; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * The following structure is the internal representation for mm objects. @@ -157,6 +170,38 @@ GetPixelsFromObjEx( 1.0, 10.0, 25.4, 0.35278 /*25.4 / 72.0*/ }; + /* + * Special hacks where the type of the object is known to be something + * that is just numeric and cannot require distance conversion. This pokes + * holes in Tcl's abstractions, but they are just for optimization, not + * semantics. + */ + + if (objPtr->typePtr != &pixelObjType) { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tsdPtr->doubleTypePtr == NULL) { + tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); + tsdPtr->intTypePtr = Tcl_GetObjType("int"); + } + + if (objPtr->typePtr == tsdPtr->doubleTypePtr) { + (void) Tcl_GetDoubleFromObj(interp, objPtr, &d); + if (dblPtr != NULL) { + *dblPtr = d; + } + *intPtr = (int) d; + return TCL_OK; + } else if (objPtr->typePtr == tsdPtr->intTypePtr) { + (void) Tcl_GetIntFromObj(interp, objPtr, intPtr); + if (dblPtr) { + *dblPtr = (double) (*intPtr); + } + return TCL_OK; + } + } + retry: if (objPtr->typePtr != &pixelObjType) { result = SetPixelFromAny(interp, objPtr); @@ -271,7 +316,7 @@ Tk_GetDoublePixelsFromObj( if (result != TCL_OK) { return result; } - if (!SIMPLE_PIXELREP(objPtr)) { + if (objPtr->typePtr == &pixelObjType && !SIMPLE_PIXELREP(objPtr)) { PixelRep *pixelPtr; pixelPtr = GET_COMPLEXPIXEL(objPtr); if (pixelPtr->units >= 0) { |