Tk Source Code

Check-in [16470270]
Login

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

Overview
Comment:Document. Factor out basic rotation function.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | tip-164
Files: files | file ages | folders
SHA3-256: 16470270cf67df6c606a546cc15d4c2a11dc641d918bce9748e195f3a8c14016
User & Date: dkf 2019-03-13 19:16:12.402
Context
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
2019-03-11
21:30
All standard item types now have rotation proc callbacks. check-in: 45c999c3 user: dkf tags: tip-164
Changes
Unified Diff Ignore Whitespace Patch
Changes to doc/CrtItemType.3.
79
80
81
82
83
84
85



86
87
88
89
90
91
92
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;



} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized







>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;
.VS "8.7, TIP164"
    Tk_ItemRotateProc *\fIrotateProc\fR;
.VE "8.7, TIP164"
} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized
545
546
547
548
549
550
551








































552
553
554
555
556
557
558
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.








































.SS INDEXPROC
.PP
\fItypePtr\->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text or coordinates;
\fItypePtr\->indexProc\fR may be specified as NULL for non-textual







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.
.SS ROTATEPROC
.VS "8.7, TIP164"
.PP
\fItypePtr\->rotateProc\fR is invoked by Tk to rotate a canvas item
during the \fBrotate\fR widget command.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemRotateProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double \fIoriginX\fR,
        double \fIoriginY\fR,
        double \fIangleRad\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIoriginX\fR and \fIoriginY\fR specify an origin relative to which
the item is to be rotated, and \fIangleRad\fR gives the anticlockwise
rotation to be applied in radians.
The item should adjust the coordinates of its control points so that where
they used to have coordinates \fIx\fR and \fIy\fR, they will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIrelX\fR = \fIx\fR - \fIoriginX\fR
\fIrelY\fR = \fIy\fR - \fIoriginY\fR
\fIx\(fm\fR = \fIoriginX\fR + \fIrelX\fR \(mu cos(\fIangleRad\fR) + \fIrelY\fR \(mu sin(\fIangleRad\fR)
\fIy\(fm\fR = \fIoriginY\fR \(mi \fIrelX\fR \(mu sin(\fIangleRad\fR) + \fIrelY\fR \(mu cos(\fIangleRad\fR)
.CE
.PP
The control points for an item are not necessarily the coordinates provided to
the item when it is created (or via the \fItypePtr\->coordProc\fR), but could
instead be derived from them.
\fIrotateProc\fR must also update the bounding box in the item's header.
.PP
Item types do not need to provide a \fItypePtr\->rotateProc\fR. If the
\fItypePtr\->rotateProc\fR is NULL, the \fItypePtr\->coordProc\fR will be
used instead to retrieve and update the list of coordinates.
.VE "8.7, TIP164"
.SS INDEXPROC
.PP
\fItypePtr\->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text or coordinates;
\fItypePtr\->indexProc\fR may be specified as NULL for non-textual
Changes to doc/canvas.n.
216
217
218
219
220
221
222
223




224
225
226
227
228
229
230
231
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands; this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved or scaled using widget commands




described below, but they may not be rotated.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area. However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and







|
>
>
>
>
|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands; this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved, scaled
.VS "8.7, TIP164"
or rotated
.VE "8.7, TIP164"
using widget commands
described below.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area. However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and
670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
686
687
688
689
690
factor can also be given and the photo image will be enlarged. The image background
will be filled with the canvas background colour. The canvas widget does not need to
be mapped for this widget command to work, but at least one of it's ancestors must be
mapped.
This command returns an empty string.
.TP
\fIpathName \fBimove \fItagOrId index x y\fR
.VS 8.6

This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.
.VE 8.6
.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.







<
>





<







674
675
676
677
678
679
680

681
682
683
684
685
686

687
688
689
690
691
692
693
factor can also be given and the photo image will be enlarged. The image background
will be filled with the canvas background colour. The canvas widget does not need to
be mapped for this widget command to work, but at least one of it's ancestors must be
mapped.
This command returns an empty string.
.TP
\fIpathName \fBimove \fItagOrId index x y\fR

.
This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.

.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR
.VS 8.6

Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair of the bottommost item with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.
.VE 8.6
.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.







<
>








<







765
766
767
768
769
770
771

772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR

.
Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair of the bottommost item with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.

.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.
957
958
959
960
961
962
963
964

965
966
967
968
969
970
971
972

















973
974
975
976
977
978
979
980
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.VS 8.6

This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.

















.VE 8.6
.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.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale







<
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







959
960
961
962
963
964
965

966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR

.
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.
.TP
\fIpathName \fBrotate \fItagOrId xOrigin yOrigin angle\fR
.VS "8.7, TIP164"
Rotate the coordinates of all of the items given by \fItagOrId\fR in canvas
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.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale
1830
1831
1832
1833
1834
1835
1836
1837

1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for text items:
.TP
\fB\-angle \fIrotationDegrees\fR
.VS 8.6

\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the
text will be drawn vertically from bottom to top.
This option defaults to \fB0.0\fR.
.VE 8.6
.TP
\fB\-font \fIfontName\fR
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.TP







<
>





<







1849
1850
1851
1852
1853
1854
1855

1856
1857
1858
1859
1860
1861

1862
1863
1864
1865
1866
1867
1868
\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for text items:
.TP
\fB\-angle \fIrotationDegrees\fR

.
\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the
text will be drawn vertically from bottom to top.
This option defaults to \fB0.0\fR.

.TP
\fB\-font \fIfontName\fR
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.TP
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
1545
1546
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double x, y, nx, ny;
    double s = sin(angleRad);
    double c = cos(angleRad);

    x = arcPtr->bbox[0] - originX;
    y = arcPtr->bbox[1] - originY;
    nx = x * c - y * s;
    ny = x * s + y * c;
    arcPtr->bbox[0] = nx + originX;
    arcPtr->bbox[1] = ny + originY;




    x = arcPtr->bbox[2] - originX;
    y = arcPtr->bbox[3] - originY;
    nx = x * c - y * s;
    ny = x * s + y * c;
    arcPtr->bbox[2] = nx + originX;
    arcPtr->bbox[3] = ny + originY;

    /*
     * 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
    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);
}
Changes to generic/tkCanvBmap.c.
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x, y, nx, ny;
    double s = sin(angleRad);
    double c = cos(angleRad);

    x = bmapPtr->x - originX;
    y = bmapPtr->y - originY;
    nx = x * c - y * s;
    ny = x * s + y * c;
    bmapPtr->x = nx + originX;
    bmapPtr->y = ny + originY;
    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --







<
<
<

<
|
<
<
|
<







813
814
815
816
817
818
819



820

821


822

823
824
825
826
827
828
829
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;





    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),


	    &bmapPtr->x, &bmapPtr->y);

    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --
Changes to generic/tkCanvImg.c.
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    double x, y, nx, ny;
    double s = sin(angleRad);
    double c = cos(angleRad);

    x = imgPtr->x - originX;
    y = imgPtr->y - originY;
    nx = x * c - y * s;
    ny = x * s + y * c;
    imgPtr->x = nx + originX;
    imgPtr->y = ny + originY;
    ComputeImageBbox(canvas, imgPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleImage --







<
<
<

<
|
<
<
|
<







785
786
787
788
789
790
791



792

793


794

795
796
797
798
799
800
801
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;





    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),


	    &imgPtr->x, &imgPtr->y);

    ComputeImageBbox(canvas, imgPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleImage --
Changes to generic/tkCanvLine.c.
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
 *	The position of the line is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static inline void
DoRotate(
    double originX, double originY,
    double sine, double cosine,
    double *xPtr, double *yPtr)
{
    double x = *xPtr - originX;
    double y = *yPtr - originY;

    *xPtr = originX + x * cosine - y * sine;
    *yPtr = originY + x * sine + y * cosine;
}

static void
RotateLine(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	DoRotate(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    DoRotate(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    DoRotate(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------







<
<
<
<
<
<
<
<
<
<
<
<
<














|




|





|







1871
1872
1873
1874
1875
1876
1877













1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
 *	The position of the line is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */














static void
RotateLine(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
Changes to generic/tkCanvPoly.c.
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {
	double x = coordPtr[0] - originX;
	double y = coordPtr[1] - originY;

	coordPtr[0] = originX + x * c - y * s;
	coordPtr[1] = originY + x * s + y * c;
    }
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *







<
<
|
<
<







1767
1768
1769
1770
1771
1772
1773


1774


1775
1776
1777
1778
1779
1780
1781
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {


	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);


    }
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
Changes to generic/tkCanvText.c.
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
RotateText(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    double s = sin(angleRad), c = cos(angleRad);
    double x = textPtr->x - originX;
    double y = textPtr->y - originY;

    textPtr->x = originX + x * c - y * s;
    textPtr->y = originY + x * s + y * c;
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleText --







<
<
<

|
|







1273
1274
1275
1276
1277
1278
1279



1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
RotateText(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    TextItem *textPtr = (TextItem *) itemPtr;




    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &textPtr->x, &textPtr->y);
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleText --
Changes to generic/tkCanvUtil.c.
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * Tk_ResetOutlineGC
 *
 *	Restores the GC to the situation before Tk_ChangeOutlineGC() was







<







1261
1262
1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * Tk_ResetOutlineGC
 *
 *	Restores the GC to the situation before Tk_ChangeOutlineGC() was
1859
1860
1861
1862
1863
1864
1865





































1866
1867
1868
1869
1870
1871
1872
1873
	TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
    }
    if (tempArr != staticSpace) {
	ckfree(tempArr);
    }
    return numOutput;
}






































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
	TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
    }
    if (tempArr != staticSpace) {
	ckfree(tempArr);
    }
    return numOutput;
}

/*
 *--------------------------------------------------------------
 *
 * TkRotatePoint --
 *
 *	Rotate a point about another point. The angle should be converted into
 *	its sine and cosine before calling this function.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The point in (*xPtr,*yPtr) is updated to be rotated about
 *	(originX,originY) by the amount given by the sine and cosine of the
 *	angle to rotate.
 *
 *--------------------------------------------------------------
 */

void
TkRotatePoint(
    double originX, double originY,	/* The point about which to rotate. */
    double sine, double cosine,		/* How much to rotate? */
    double *xPtr, double *yPtr)		/* The point to be rotated. (INOUT) */
{
    double x = *xPtr - originX;
    double y = *yPtr - originY;

    /*
     * Beware! The canvas coordinate space is flipped vertically, so rotations
     * go the "wrong" way with respect to mathematics.
     */

    *xPtr = originX + x * cosine + y * sine;
    *yPtr = originY - x * sine + y * cosine;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCanvWind.c.
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
RotateWinItem(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double s = sin(angleRad), c = cos(angleRad);
    double x = winItemPtr->x - originX;
    double y = winItemPtr->y - originY;

    winItemPtr->x = originX + x * c - y * s;
    winItemPtr->y = originY + x * s + y * c;
    ComputeWindowBbox(canvas, winItemPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWinItem --







<
<
<

|
|







939
940
941
942
943
944
945



946
947
948
949
950
951
952
953
954
955
RotateWinItem(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;




    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &winItemPtr->x, &winItemPtr->y);
    ComputeWindowBbox(canvas, winItemPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWinItem --
Changes to generic/tkInt.h.
1255
1256
1257
1258
1259
1260
1261



1262
1263
1264
1265
1266
1267
1268
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpCancelWarp(TkDisplay *dispPtr);
MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);




#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);







>
>
>







1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpCancelWarp(TkDisplay *dispPtr);
MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);
MODULE_SCOPE void	TkRotatePoint(double originX, double originY,
			    double sine, double cosine, double *xPtr,
			    double *yPtr);

#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);
Changes to generic/tkRectOval.c.
1302
1303
1304
1305
1306
1307
1308
1309
1310
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
 *	The position of the rectangle or oval is rotated by angleRad about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static inline void
DoRotate(
    double originX, double originY,
    double sine, double cosine,
    double *xPtr, double *yPtr)
{
    double x = *xPtr - originX;
    double y = *yPtr - originY;

    *xPtr = originX + x * cosine - y * sine;
    *yPtr = originY + x * sine + y * cosine;
}

static void
RotateRectOval(
    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 = rectOvalPtr->bbox;


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









    ComputeRectOvalBbox(canvas, rectOvalPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleRectOval --







<
<
<
<
<
<
<
<
<
<
<
<
<










|

>
|
|
>
>
>
>
>
>
>
>
>







1302
1303
1304
1305
1306
1307
1308













1309
1310
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
 *	The position of the rectangle or oval is rotated by angleRad about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */














static void
RotateRectOval(
    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 --