summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2019-12-24 13:17:52 (GMT)
committerfvogel <fvogelnew1@free.fr>2019-12-24 13:17:52 (GMT)
commit6be2c46561365097393960144e8ba97683718a74 (patch)
tree1d6460e793fbf4955acc84d393efa527f139af80 /generic
parent46ffc538b8aa3e274e4c8b567de60ee2db34a16f (diff)
downloadtk-6be2c46561365097393960144e8ba97683718a74.zip
tk-6be2c46561365097393960144e8ba97683718a74.tar.gz
tk-6be2c46561365097393960144e8ba97683718a74.tar.bz2
A second (and better) implementation fixing [587937fff]: Don't shuffle tag list sequence upon deletion. This implementation is more efficient (it's O(n)).
Diffstat (limited to 'generic')
-rw-r--r--generic/tkCanvas.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index b2007ea..2c1038a 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -1436,7 +1436,7 @@ CanvasWidgetCmd(
}
case CANV_DTAG: {
Tk_Uid tag;
- int i, j;
+ int i;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagToDelete?");
@@ -1451,12 +1451,28 @@ CanvasWidgetCmd(
FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
for (i = 0; i < itemPtr->numTags; i++) {
if (itemPtr->tagPtr[i] == tag) {
- for (j = i; j < itemPtr->numTags - 1; j++) {
- itemPtr->tagPtr[j] = itemPtr->tagPtr[j+1];
- }
+
+ /*
+ * Don't shuffle the tags sequence: memmove the tags.
+ */
+
+ memmove((void *)(itemPtr->tagPtr + i),
+ (void *)(itemPtr->tagPtr + i + 1),
+ sizeof(Tk_Uid *) * (itemPtr->numTags - (i+1)));
itemPtr->numTags--;
- i--; /* deal with the case of successive identical tag to remove */
- /* No break here: all tags with the same name must be deleted */
+
+ /*
+ * Look at the same place again to deal with the case of
+ * successive identical tags matching the tag to delete.
+ */
+
+ i--;
+
+ /*
+ * There must be no break here: all tags with the same name must
+ * be deleted.
+ */
+
}
}
}