diff options
author | fvogel <fvogelnew1@free.fr> | 2017-11-11 12:50:12 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2017-11-11 12:50:12 (GMT) |
commit | 7b92051ed76e0b8b51e76515c7676639f3498fe6 (patch) | |
tree | d468de4db661b199e9c793a600b17fb56786b79a /generic | |
parent | 419b1d82d5ba52eb7015ee71f338205aaf428c28 (diff) | |
parent | 9d866ca9c9caef7746f53cc6daaf6381769ba12a (diff) | |
download | tk-7b92051ed76e0b8b51e76515c7676639f3498fe6.zip tk-7b92051ed76e0b8b51e76515c7676639f3498fe6.tar.gz tk-7b92051ed76e0b8b51e76515c7676639f3498fe6.tar.bz2 |
merge core-8-6-branch
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkFont.c | 14 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 34 | ||||
-rw-r--r-- | generic/tkRectOval.c | 102 | ||||
-rw-r--r-- | generic/tkScale.c | 25 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 49 |
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 |