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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to doc/canvas.n.

   979    979   coordinate space.
   980    980   \fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
   981    981   operation and \fIangle\fR identifies the amount to rotate the coordinates
   982    982   anticlockwise, in degrees. (Negative values rotate clockwise.)
   983    983   This command returns an empty string.
   984    984   .RS
   985    985   .PP
   986         -Implementation note: not all item types work well with rotations. In
   987         -particular, the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types are very
   988         -unlikely to work as you expect. Several other item types only have a single
   989         -coordinate; this command can move that anchor point, but will not rotate the
   990         -item about that anchor point.
          986  +Implementation note: not all item types work the same with rotations. In
          987  +particular,\fB bitmap\fR,\fB image\fR,\fB text\fR and\fB window\fR items only
          988  +rotate their anchor points and do not rotate the items themselves about those
          989  +points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a
          990  +computed center point instead of moving the bounding box coordinates directly.
          991  +.PP
          992  +Some items (currently \fBarc\R and\fB text\fR) have angles in their options;
          993  +this command \fIdoes not\fR affect those options.
   991    994   .RE
   992    995   .VE "8.7, TIP164"
   993    996   .TP
   994    997   \fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
   995    998   .
   996    999   Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
   997   1000   coordinate space.

Changes to generic/tkCanvArc.c.

  1516   1516       Tk_Canvas canvas,
  1517   1517       Tk_Item *itemPtr,
  1518   1518       double originX,
  1519   1519       double originY,
  1520   1520       double angleRad)
  1521   1521   {
  1522   1522       ArcItem *arcPtr = (ArcItem *) itemPtr;
  1523         -    double s = sin(angleRad), c = cos(angleRad);
  1524         -    double coords[4];
  1525         -
  1526         -    memcpy(coords, arcPtr->bbox, sizeof(coords));
  1527         -    TkRotatePoint(originX, originY, s, c, &coords[0], &coords[1]);
  1528         -    TkRotatePoint(originX, originY, s, c, &coords[2], &coords[3]);
         1523  +    double newX, newY, oldX, oldY;
  1529   1524   
  1530   1525       /*
  1531         -     * Sort the points for the bounding box.
         1526  +     * Compute the centre of the box, then rotate that about the origin.
  1532   1527        */
  1533   1528   
  1534         -    arcPtr->bbox[0] = (coords[0] < coords[2]) ? coords[0] : coords[2];
  1535         -    arcPtr->bbox[1] = (coords[1] < coords[3]) ? coords[1] : coords[3];
  1536         -    arcPtr->bbox[2] = (coords[0] < coords[2]) ? coords[2] : coords[0];
  1537         -    arcPtr->bbox[3] = (coords[1] < coords[3]) ? coords[3] : coords[1];
         1529  +    newX = oldX = (arcPtr->bbox[0] + arcPtr->bbox[2]) / 2.0;
         1530  +    newY = oldY = (arcPtr->bbox[1] + arcPtr->bbox[3]) / 2.0;
         1531  +    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
         1532  +	    &newX, &newY);
         1533  +
         1534  +    /*
         1535  +     * Apply the translation to the box.
         1536  +     */
         1537  +
         1538  +    arcPtr->bbox[0] += newX - oldX;
         1539  +    arcPtr->bbox[1] += newY - oldY;
         1540  +    arcPtr->bbox[2] += newX - oldX;
         1541  +    arcPtr->bbox[3] += newY - oldY;
  1538   1542   
  1539   1543       /*
  1540   1544        * TODO: update the arc endpoints?
  1541   1545        */
  1542   1546   
  1543   1547       ComputeArcBbox(canvas, arcPtr);
  1544   1548   }

Changes to generic/tkRectOval.c.

  1288   1288   
  1289   1289   /*
  1290   1290    *--------------------------------------------------------------
  1291   1291    *
  1292   1292    * RotateRectOval --
  1293   1293    *
  1294   1294    *	This function is invoked to rotate a rectangle or oval item's
  1295         - *	coordinates. It's probably unwise to rotate these by anything other
  1296         - *	than 90-degree increments.
         1295  + *	coordinates. It works by rotating a computed point in the centre of
         1296  + *	the bounding box, NOT by rotating the corners of the bounding box.
  1297   1297    *
  1298   1298    * Results:
  1299   1299    *	None.
  1300   1300    *
  1301   1301    * Side effects:
  1302   1302    *	The position of the rectangle or oval is rotated by angleRad about
  1303   1303    *	(originX, originY), and the bounding box is updated in the generic
................................................................................
  1311   1311       Tk_Canvas canvas,		/* Canvas containing rectangle. */
  1312   1312       Tk_Item *itemPtr,		/* Rectangle to be scaled. */
  1313   1313       double originX, double originY,
  1314   1314   				/* Origin about which to rotate rect. */
  1315   1315       double angleRad)		/* Amount to scale in X direction. */
  1316   1316   {
  1317   1317       RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
  1318         -    double s = sin(angleRad), c = cos(angleRad);
  1319         -    double coords[4];
         1318  +    double newX, newY, oldX, oldY;
  1320   1319   
  1321         -    memcpy(coords, rectOvalPtr->bbox, sizeof(coords));
  1322         -    TkRotatePoint(originX, originY, s, c, &coords[0], &coords[1]);
  1323         -    TkRotatePoint(originX, originY, s, c, &coords[2], &coords[3]);
         1320  +    /*
         1321  +     * Compute the centre of the box, then rotate that about the origin.
         1322  +     */
         1323  +
         1324  +    newX = oldX = (rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2]) / 2.0;
         1325  +    newY = oldY = (rectOvalPtr->bbox[1] + rectOvalPtr->bbox[3]) / 2.0;
         1326  +    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
         1327  +	    &newX, &newY);
  1324   1328   
  1325   1329       /*
  1326         -     * Sort the points for the bounding box.
         1330  +     * Apply the translation to the box.
  1327   1331        */
  1328   1332   
  1329         -    rectOvalPtr->bbox[0] = (coords[0] < coords[2]) ? coords[0] : coords[2];
  1330         -    rectOvalPtr->bbox[1] = (coords[1] < coords[3]) ? coords[1] : coords[3];
  1331         -    rectOvalPtr->bbox[2] = (coords[0] < coords[2]) ? coords[2] : coords[0];
  1332         -    rectOvalPtr->bbox[3] = (coords[1] < coords[3]) ? coords[3] : coords[1];
         1333  +    rectOvalPtr->bbox[0] += newX - oldX;
         1334  +    rectOvalPtr->bbox[1] += newY - oldY;
         1335  +    rectOvalPtr->bbox[2] += newX - oldX;
         1336  +    rectOvalPtr->bbox[3] += newY - oldY;
  1333   1337       ComputeRectOvalBbox(canvas, rectOvalPtr);
  1334   1338   }
  1335   1339   
  1336   1340   /*
  1337   1341    *--------------------------------------------------------------
  1338   1342    *
  1339   1343    * ScaleRectOval --