summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2017-11-11 12:50:12 (GMT)
committerfvogel <fvogelnew1@free.fr>2017-11-11 12:50:12 (GMT)
commit7b92051ed76e0b8b51e76515c7676639f3498fe6 (patch)
treed468de4db661b199e9c793a600b17fb56786b79a /generic
parent419b1d82d5ba52eb7015ee71f338205aaf428c28 (diff)
parent9d866ca9c9caef7746f53cc6daaf6381769ba12a (diff)
downloadtk-7b92051ed76e0b8b51e76515c7676639f3498fe6.zip
tk-7b92051ed76e0b8b51e76515c7676639f3498fe6.tar.gz
tk-7b92051ed76e0b8b51e76515c7676639f3498fe6.tar.bz2
merge core-8-6-branch
Diffstat (limited to 'generic')
-rw-r--r--generic/tkFont.c14
-rw-r--r--generic/tkImgPhoto.c34
-rw-r--r--generic/tkRectOval.c102
-rw-r--r--generic/tkScale.c25
-rw-r--r--generic/tkTextDisp.c49
5 files changed, 182 insertions, 42 deletions
diff --git a/generic/tkFont.c b/generic/tkFont.c
index 4183686..86fdd87 100644
--- a/generic/tkFont.c
+++ b/generic/tkFont.c
@@ -3151,14 +3151,13 @@ TkIntersectAngledTextLayout(
cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent;
cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth;
cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent;
- if ( !PointInQuadrilateral(cx, cy, rx[0], ry[0]) ||
- !PointInQuadrilateral(cx, cy, rx[1], ry[1]) ||
- !PointInQuadrilateral(cx, cy, rx[2], ry[2]) ||
- !PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
- goto notReverseInside;
- }
+ if ( PointInQuadrilateral(cx, cy, rx[0], ry[0]) &&
+ PointInQuadrilateral(cx, cy, rx[1], ry[1]) &&
+ PointInQuadrilateral(cx, cy, rx[2], ry[2]) &&
+ PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
+ return 0;
+ }
}
- return 0;
/*
* If we're overlapping now, we must be partially in and out of at least
@@ -3166,7 +3165,6 @@ TkIntersectAngledTextLayout(
* rectangle that is touching or crossing a line segment of a chunk.
*/
- notReverseInside:
chunkPtr = layoutPtr->chunks;
for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 1fec208..0389c79 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -625,7 +625,24 @@ ImgPhotoCmd(
}
/*
+ * Copy the image data over using Tk_PhotoPutZoomedBlock.
+ */
+
+ block.pixelPtr += options.fromX * block.pixelSize
+ + options.fromY * block.pitch;
+ block.width = options.fromX2 - options.fromX;
+ block.height = options.fromY2 - options.fromY;
+ result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
+ &block, options.toX, options.toY, options.toX2 - options.toX,
+ options.toY2 - options.toY, options.zoomX, options.zoomY,
+ options.subsampleX, options.subsampleY,
+ options.compositingRule);
+
+ /*
* Set the destination image size if the -shrink option was specified.
+ * This has to be done _after_ copying the data. Otherwise, if source
+ * and destination are the same image, block.pixelPtr would point to
+ * an invalid memory block (bug [5239fd749b]).
*/
if (options.options & OPT_SHRINK) {
@@ -637,20 +654,9 @@ ImgPhotoCmd(
return TCL_ERROR;
}
}
-
- /*
- * Copy the image data over using Tk_PhotoPutZoomedBlock.
- */
-
- block.pixelPtr += options.fromX * block.pixelSize
- + options.fromY * block.pitch;
- block.width = options.fromX2 - options.fromX;
- block.height = options.fromY2 - options.fromY;
- return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
- &block, options.toX, options.toY, options.toX2 - options.toX,
- options.toY2 - options.toY, options.zoomX, options.zoomY,
- options.subsampleX, options.subsampleY,
- options.compositingRule);
+ Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
+ masterPtr->width, masterPtr->height);
+ return result;
case PHOTO_DATA: {
char *data;
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index 50b5f1a..4d48fe7 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -759,11 +759,103 @@ DisplayRectOval(
&x1, &y1);
Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3],
&x2, &y2);
- if (x2 <= x1) {
- x2 = x1+1;
- }
- if (y2 <= y1) {
- y2 = y1+1;
+ if (x2 == x1) {
+
+ /*
+ * The width of the bounding box corresponds to less than one pixel
+ * on screen. Adjustment is needed to avoid drawing attempts with zero
+ * width items (which would draw nothing). The bounding box spans
+ * either 1 or 2 pixels. Select which pixel will be drawn.
+ */
+
+ short ix1 = (short) (rectOvalPtr->bbox[0]);
+ short ix2 = (short) (rectOvalPtr->bbox[2]);
+
+ if (ix1 == ix2) {
+
+ /*
+ * x1 and x2 are "within the same pixel". Use this pixel.
+ * Note: the degenerated case (bbox[0]==bbox[2]) of a completely
+ * flat box results in arbitrary selection of the pixel at the
+ * right (with positive coordinate) or left (with negative
+ * coordinate) of the box. There is no "best choice" here.
+ */
+
+ if (ix1 > 0) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ } else {
+
+ /*
+ * (x1,x2) span two pixels. Select the one with the larger
+ * covered "area".
+ */
+
+ if (ix1 > 0) {
+ if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ } else {
+ if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ }
+ }
+ }
+ if (y2 == y1) {
+
+ /*
+ * The height of the bounding box corresponds to less than one pixel
+ * on screen. Adjustment is needed to avoid drawing attempts with zero
+ * height items (which would draw nothing). The bounding box spans
+ * either 1 or 2 pixels. Select which pixel will be drawn.
+ */
+
+ short iy1 = (short) (rectOvalPtr->bbox[1]);
+ short iy2 = (short) (rectOvalPtr->bbox[3]);
+
+ if (iy1 == iy2) {
+
+ /*
+ * y1 and y2 are "within the same pixel". Use this pixel.
+ * Note: the degenerated case (bbox[1]==bbox[3]) of a completely
+ * flat box results in arbitrary selection of the pixel below
+ * (with positive coordinate) or above (with negative coordinate)
+ * the box. There is no "best choice" here.
+ */
+
+ if (iy1 > 0) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ } else {
+
+ /*
+ * (y1,y2) span two pixels. Select the one with the larger
+ * covered "area".
+ */
+
+ if (iy1 > 0) {
+ if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ } else {
+ if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ }
+ }
}
/*
diff --git a/generic/tkScale.c b/generic/tkScale.c
index cbc5202..ef67630 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -21,6 +21,10 @@
#include "tkInt.h"
#include "tkScale.h"
+#if defined(_WIN32)
+#define snprintf _snprintf
+#endif
+
/*
* The following table defines the legal values for the -orient option. It is
* used together with the "enum orient" declaration in tkScale.h.
@@ -677,9 +681,9 @@ ConfigureScale(
} else {
char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];
- sprintf(varString, scalePtr->format, varValue);
- sprintf(scaleString, scalePtr->format, scalePtr->value);
- if (strcmp(varString, scaleString)) {
+ Tcl_PrintDouble(NULL, varValue, varString);
+ Tcl_PrintDouble(NULL, scalePtr->value, scaleString);
+ if (strcmp(varString, scaleString)) {
ScaleSetVariable(scalePtr);
}
}
@@ -936,10 +940,16 @@ ComputeScaleGeometry(
* whichever length is longer.
*/
- sprintf(valueString, scalePtr->format, scalePtr->fromValue);
+ if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->fromValue) < 0) {
+ valueString[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
- sprintf(valueString, scalePtr->format, scalePtr->toValue);
+ if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->toValue) < 0) {
+ valueString[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
if (valuePixels < tmp) {
valuePixels = tmp;
@@ -1314,7 +1324,10 @@ ScaleSetVariable(
if (scalePtr->varNamePtr != NULL) {
char string[TCL_DOUBLE_SPACE];
- sprintf(string, scalePtr->format, scalePtr->value);
+ if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->value) < 0) {
+ string[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
scalePtr->flags |= SETTING_VAR;
Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 9c2f536..238ae1a 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -4120,8 +4120,8 @@ DisplayText(
MacDrawable *macWin = winPtr->privatePtr;
if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
dInfoPtr->flags &= ~REDRAW_PENDING;
- return;
- }
+ return;
+ }
#endif
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
@@ -4274,7 +4274,6 @@ DisplayText(
}
dlPtr = dlPtr->nextPtr;
}
-
/*
* Scan through the lines following the copied ones to see if we are
* going to overwrite them with the copy operation. If so, mark them
@@ -4298,9 +4297,7 @@ DisplayText(
if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
damageRgn)) {
-#ifndef MAC_OSX_TK
TextInvalidateRegion(textPtr, damageRgn);
-#endif
}
numCopies++;
TkDestroyRegion(damageRgn);
@@ -4442,11 +4439,38 @@ DisplayText(
}
dlPtr->oldY = dlPtr->y;
dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID);
+#ifdef MAC_OSX_TK
+ } else if (dlPtr->chunkPtr != NULL) {
+ /*
+ * On macOS we need to redisplay all embedded windows which
+ * were moved by the call to TkScrollWindows above. This is
+ * not necessary on Unix or Windows because XScrollWindow will
+ * have included the bounding rectangles of all of these
+ * windows in the damage region. The macosx implementation of
+ * TkScrollWindow does not do this. It simply generates a
+ * damage region which is the scroll source rectangle minus
+ * the scroll destination rectangle. This is because there is
+ * no efficient process available for iterating through the
+ * subwindows which meet the scrolled area. (On Unix this is
+ * handled by GraphicsExpose events generated by XCopyArea and
+ * on Windows by ScrollWindowEx. On macOS the low level
+ * scrolling is accomplished by calling [view scrollRect:by:].
+ * This method does not provide any damage information and, in
+ * any case, could not be aware of Tk windows which were not
+ * based on NSView objects.
+ *
+ * On the other hand, this loop is already iterating through
+ * all embedded windows which could possibly have been moved
+ * by the scrolling. So it is as efficient to redisplay them
+ * here as it would have been if they had been redisplayed by
+ * the call to TextInvalidateRegion above.
+ */
+#else
} else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0)
|| (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) {
- register TkTextDispChunk *chunkPtr;
-
- /*
+ /*
+ * On platforms other than the Mac:
+ *
* It's the first or last DLine which are also overlapping the
* top or bottom of the window, but we decided above it wasn't
* necessary to display them (we were able to update them by
@@ -4460,6 +4484,8 @@ DisplayText(
* So, we loop through all the chunks, calling the display
* proc of embedded windows only.
*/
+#endif
+ register TkTextDispChunk *chunkPtr;
for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
chunkPtr = chunkPtr->nextPtr) {
@@ -4482,13 +4508,18 @@ DisplayText(
x = -chunkPtr->width;
}
+ if (tkTextDebug) {
+ char string[TK_POS_CHARS];
+
+ TkTextPrintIndex(textPtr, &dlPtr->index, string);
+ LOG("tk_textEmbWinDisplay", string);
+ }
TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
dlPtr->spaceAbove,
dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, NULL,
(Drawable) None, dlPtr->y + dlPtr->spaceAbove);
}
-
}
}
#ifndef TK_NO_DOUBLE_BUFFERING