Tk Source Code

Check-in [96c17d59]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Make some items have a virtual centre point to move. Much saner behaviour.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-164
Files: files | file ages | folders
SHA3-256: 96c17d59a0a684ee4a190d0f852ee24cd485235fa193dcc84a8946cc7c0b3029
User & Date: dkf 2019-03-15 18:41:23
Context
2019-03-16
14:54
Tests of rotation Closed-Leaf check-in: 320b73bd user: dkf tags: tip-164
2019-03-15
18:41
Make some items have a virtual centre point to move. Much saner behaviour. check-in: 96c17d59 user: dkf tags: tip-164
2019-03-13
19:16
Document. Factor out basic rotation function. check-in: 16470270 user: dkf tags: tip-164
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/canvas.n.

979
980
981
982
983
984
985
986


987
988
989
990



991
992
993
994
995
996
997
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates
anticlockwise, in degrees. (Negative values rotate clockwise.)
This command returns an empty string.
.RS
.PP
Implementation note: not all item types work well with rotations. In


particular, the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types are very
unlikely to work as you expect. Several other item types only have a single
coordinate; this command can move that anchor point, but will not rotate the
item about that anchor point.



.RE
.VE "8.7, TIP164"
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.






|
>
>
|
<
<
|
>
>
>







979
980
981
982
983
984
985
986
987
988
989


990
991
992
993
994
995
996
997
998
999
1000
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates
anticlockwise, in degrees. (Negative values rotate clockwise.)
This command returns an empty string.
.RS
.PP
Implementation note: not all item types work the same with rotations. In
particular,\fB bitmap\fR,\fB image\fR,\fB text\fR and\fB window\fR items only
rotate their anchor points and do not rotate the items themselves about those
points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a


computed center point instead of moving the bounding box coordinates directly.
.PP
Some items (currently \fBarc\R and\fB text\fR) have angles in their options;
this command \fIdoes not\fR affect those options.
.RE
.VE "8.7, TIP164"
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.

Changes to generic/tkCanvArc.c.

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525

1526




1527
1528

1529
1530
1531

1532
1533
1534
1535
1536
1537




1538
1539
1540
1541
1542
1543
1544
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double s = sin(angleRad), c = cos(angleRad);
    double coords[4];


    memcpy(coords, arcPtr->bbox, sizeof(coords));




    TkRotatePoint(originX, originY, s, c, &coords[0], &coords[1]);
    TkRotatePoint(originX, originY, s, c, &coords[2], &coords[3]);


    /*
     * Sort the points for the bounding box.

     */

    arcPtr->bbox[0] = (coords[0] < coords[2]) ? coords[0] : coords[2];
    arcPtr->bbox[1] = (coords[1] < coords[3]) ? coords[1] : coords[3];
    arcPtr->bbox[2] = (coords[0] < coords[2]) ? coords[2] : coords[0];
    arcPtr->bbox[3] = (coords[1] < coords[3]) ? coords[3] : coords[1];





    /*
     * TODO: update the arc endpoints?
     */

    ComputeArcBbox(canvas, arcPtr);
}






|
<

>
|
>
>
>
>
|
<
>


<
>


<
<
<
<
>
>
>
>







1516
1517
1518
1519
1520
1521
1522
1523

1524
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534

1535
1536
1537




1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double newX, newY, oldX, oldY;


    /*
     * Compute the centre of the box, then rotate that about the origin.
     */

    newX = oldX = (arcPtr->bbox[0] + arcPtr->bbox[2]) / 2.0;
    newY = oldY = (arcPtr->bbox[1] + arcPtr->bbox[3]) / 2.0;
    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),

	    &newX, &newY);

    /*

     * Apply the translation to the box.
     */





    arcPtr->bbox[0] += newX - oldX;
    arcPtr->bbox[1] += newY - oldY;
    arcPtr->bbox[2] += newX - oldX;
    arcPtr->bbox[3] += newY - oldY;

    /*
     * TODO: update the arc endpoints?
     */

    ComputeArcBbox(canvas, arcPtr);
}

Changes to generic/tkRectOval.c.

1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
....
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320

1321




1322
1323

1324
1325
1326

1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
 
/*
 *--------------------------------------------------------------
 *
 * RotateRectOval --
 *
 *	This function is invoked to rotate a rectangle or oval item's
 *	coordinates. It's probably unwise to rotate these by anything other
 *	than 90-degree increments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the rectangle or oval is rotated by angleRad about
 *	(originX, originY), and the bounding box is updated in the generic
................................................................................
    Tk_Canvas canvas,		/* Canvas containing rectangle. */
    Tk_Item *itemPtr,		/* Rectangle to be scaled. */
    double originX, double originY,
				/* Origin about which to rotate rect. */
    double angleRad)		/* Amount to scale in X direction. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double s = sin(angleRad), c = cos(angleRad);
    double coords[4];


    memcpy(coords, rectOvalPtr->bbox, sizeof(coords));




    TkRotatePoint(originX, originY, s, c, &coords[0], &coords[1]);
    TkRotatePoint(originX, originY, s, c, &coords[2], &coords[3]);


    /*
     * Sort the points for the bounding box.

     */

    rectOvalPtr->bbox[0] = (coords[0] < coords[2]) ? coords[0] : coords[2];
    rectOvalPtr->bbox[1] = (coords[1] < coords[3]) ? coords[1] : coords[3];
    rectOvalPtr->bbox[2] = (coords[0] < coords[2]) ? coords[2] : coords[0];
    rectOvalPtr->bbox[3] = (coords[1] < coords[3]) ? coords[3] : coords[1];
    ComputeRectOvalBbox(canvas, rectOvalPtr);
}
 
/*
 *--------------------------------------------------------------
 *
 * ScaleRectOval --






|
|







 







|
<

>
|
>
>
>
>
|
<
>


<
>


|
|
|
|







1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
....
1311
1312
1313
1314
1315
1316
1317
1318

1319
1320
1321
1322
1323
1324
1325
1326

1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
 
/*
 *--------------------------------------------------------------
 *
 * RotateRectOval --
 *
 *	This function is invoked to rotate a rectangle or oval item's
 *	coordinates. It works by rotating a computed point in the centre of
 *	the bounding box, NOT by rotating the corners of the bounding box.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the rectangle or oval is rotated by angleRad about
 *	(originX, originY), and the bounding box is updated in the generic
................................................................................
    Tk_Canvas canvas,		/* Canvas containing rectangle. */
    Tk_Item *itemPtr,		/* Rectangle to be scaled. */
    double originX, double originY,
				/* Origin about which to rotate rect. */
    double angleRad)		/* Amount to scale in X direction. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double newX, newY, oldX, oldY;


    /*
     * Compute the centre of the box, then rotate that about the origin.
     */

    newX = oldX = (rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2]) / 2.0;
    newY = oldY = (rectOvalPtr->bbox[1] + rectOvalPtr->bbox[3]) / 2.0;
    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),

	    &newX, &newY);

    /*

     * Apply the translation to the box.
     */

    rectOvalPtr->bbox[0] += newX - oldX;
    rectOvalPtr->bbox[1] += newY - oldY;
    rectOvalPtr->bbox[2] += newX - oldX;
    rectOvalPtr->bbox[3] += newY - oldY;
    ComputeRectOvalBbox(canvas, rectOvalPtr);
}
 
/*
 *--------------------------------------------------------------
 *
 * ScaleRectOval --