summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--changes4
-rw-r--r--generic/tkObj.c85
3 files changed, 93 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 18e335c..4fc0f18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
diff --git a/changes b/changes
index ba6314d..e3a96be 100644
--- a/changes
+++ b/changes
@@ -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;