diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | changes | 4 | ||||
-rw-r--r-- | generic/tkObj.c | 85 |
3 files changed, 93 insertions, 18 deletions
@@ -1,7 +1,27 @@ -2011-10-26 Don Porter <dgp@users.sourceforge.net> +2011-11-04 Don Porter <dgp@users.sourceforge.net> *** 8.5.11 TAGGED FOR RELEASE *** + * generic/tk.h: Bump to 8.5.11 for release. + * library/tk.tcl: + * unix/configure.in: + * unix/tk.spec: + * win/configure.in: + * README: + + * unix/configure: autoconf-2.59 + * win/configure: + + * changes: Updated for 8.5.11 release. + +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. 2011-10-01 Kevin B. Kenny <kennykb@acm.org> @@ -6792,4 +6792,6 @@ and -to (porter) 2011-10-25 (bug fix)[3410609] AltGr keysyms on Swiss keyboard (tasser,kenny) ---- Released 8.5.11, November 1, 2011 --- See ChangeLog for details --- +2011-11-02 (performance)[3431491] improved "pixels" shimmer logic (fellows) + +--- Released 8.5.11, November 4, 2011 --- See ChangeLog for details --- diff --git a/generic/tkObj.c b/generic/tkObj.c index d973bd4..4c8516e 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 { + const Tcl_ObjType *doubleTypePtr; + const Tcl_ObjType *intTypePtr; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * The following structure is the internal representation for mm objects. @@ -74,6 +87,7 @@ static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj *copyPtr); static void FreeMMInternalRep(Tcl_Obj *objPtr); static void FreePixelInternalRep(Tcl_Obj *objPtr); static void FreeWindowInternalRep(Tcl_Obj *objPtr); +static ThreadSpecificData *GetTypeCache(void); static void UpdateStringOfMM(Tcl_Obj *objPtr); static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); @@ -123,6 +137,31 @@ static Tcl_ObjType windowObjType = { /* *---------------------------------------------------------------------- * + * GetTypeCache -- + * + * Get (and build if necessary) the cache of useful Tcl object types for + * comparisons in the conversion functions. This allows optimized checks + * for standard cases. + * + *---------------------------------------------------------------------- + */ + +static ThreadSpecificData * +GetTypeCache() +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tsdPtr->doubleTypePtr == NULL) { + tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); + tsdPtr->intTypePtr = Tcl_GetObjType("int"); + } + return tsdPtr; +} + +/* + *---------------------------------------------------------------------- + * * GetPixelsFromObjEx -- * * Attempt to return a pixel value from the Tcl object "objPtr". If the @@ -157,6 +196,32 @@ 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 = GetTypeCache(); + + 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 +336,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) { @@ -642,29 +707,17 @@ SetMMFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr) /* The object to convert. */ { + ThreadSpecificData *tsdPtr = GetTypeCache(); const Tcl_ObjType *typePtr; char *string, *rest; double d; int units; MMRep *mmPtr; - static const Tcl_ObjType *tclDoubleObjType = NULL; - static const Tcl_ObjType *tclIntObjType = NULL; - - if (tclDoubleObjType == NULL) { - /* - * Cache the object types for comaprison below. This allows optimized - * checks for standard cases. - */ - - tclDoubleObjType = Tcl_GetObjType("double"); - tclIntObjType = Tcl_GetObjType("int"); - } - - if (objPtr->typePtr == tclDoubleObjType) { + if (objPtr->typePtr == tsdPtr->doubleTypePtr) { Tcl_GetDoubleFromObj(interp, objPtr, &d); units = -1; - } else if (objPtr->typePtr == tclIntObjType) { + } else if (objPtr->typePtr == tsdPtr->intTypePtr) { Tcl_GetIntFromObj(interp, objPtr, &units); d = (double) units; units = -1; |