[comp.lang.smalltalk] File in for an object oriented picture editor Part2/2

baumeist@exunido.uucp (Hubert Baumeister) (12/05/89)

Here is the promised object-oriented picture editor, that generates output for
\LaTeX's picture environment. It is written in Smalltalk 80 (ParcPlace Version 2.3).
I post it as an shell-archive in two parts. Thanks for all the responses to my posting.

Have fun,
	Hubert Baumeister
(Hubert Baumeister, baumeist@exunido.uucp)

------------------------------ cut here ---------------------------------
# This is a shell archive.  Unpack with "sh <file".
echo x - picture1.tex
sed -e 's/^X//' > "picture1.tex" << '!Funky!Stuff!'
X\setlength{\unitlength}{1pt}
X\begin{picture}(300.0 ,200.0 ) (0 ,0)
X\put(211.0 ,144.0) { \vector(0 ,-1) {50.0}}
X\put(91.0 ,144.0) { \vector(0 ,-1) {50.0}}
X\put(141.0 ,110.0) {\makebox(23.0 , 18.0 ){p.o.}}
X\put(45.0 ,32.0) {\makebox(217.0 , 18.0 ){This is a pushout in {\bf Sign}}}
X\put(110.0 ,155.0) { \vector(1 ,0) {83.0}}
X\put(169.0 ,148.0) {\makebox(82.0 , 18.0 ){$\Sigma_b$}}
X\put(50.0 ,148.0) {\makebox(80.0 , 18.0 ){$\Sigma_f$}}
X\put(110.0 ,80.0) { \vector(1 ,0) {83.0}}
X\put(49.0 ,73.0) {\makebox(82.0 , 18.0 ){$\Sigma_a$}}
X\put(170.0 ,73.0) {\makebox(80.0 , 18.0 ){$\Sigma_r$}}
X\end{picture}
X
!Funky!Stuff!
echo x - picture2.tex
sed -e 's/^X//' > "picture2.tex" << '!Funky!Stuff!'
X\setlength{\unitlength}{1pt}
X\begin{picture}(400.0 ,280.0 ) (0 ,0)
X\put(55 ,233) { \oval(98.0, 68.0)}
X\put(102.0 ,222.0) { \line(6 ,-1) {48.0}}
X\put(104.0 ,231.0) { \line(3 ,-1) {42.0}}
X\put(195.0 ,212.0) { \line(1 ,0) {197.0}}
X\put(394.0 ,211.0) { \line(0 ,-1) {114.0}}
X\put(204.0 ,147.0) {\makebox(180.0 , 18.0 ){{\huge$E = m\cdot c^2$}}}
X\put(196.0 ,97.0) { \line(1 ,0) {197.0}}
X\put(-13.0 ,228.0) {\makebox(118.0 , 18.0 ){{\large Hi, folks}}}
X\put(157.0 ,204.0) { \line(0 ,-1) {106.0}}
X\put(155.0 ,96.0) { \line(-5 ,-6) {50.0}}
X\put(158.0 ,97.0) { \line(2 ,-3) {38.0}}
X\put(158.0 ,177.0) { \line(-6 ,-1) {63.0}}
X\put(154.0 ,124.0) { \line(-4 ,-5) {8.0}}
X\put(97.0 ,166.0) { \line(4 ,-3) {55.0}}
X\put(216.0 ,248.0) { \line(3 ,-5) {8.0}}
X\put(159.0 ,175.75) { \line(4 ,5) {57.0}}
X\put(156.0 ,225.0) { \circle{40}}
X\put(147.0 ,233.0) { \circle*{6.0}}
X\put(163.0 ,233.0) { \circle*{6.0}}
X\put(156 ,219) { \oval(25.0, 16.0)[b]}
X\put(156.0 ,231.0) { \vector(0 ,-1) {11.0}}
X\put(147.0 ,255.0) { \line(1 ,-3) {4.0}}
X\put(165.0 ,257.0) { \line(-1 ,-4) {3.0}}
X\put(188.0 ,255.0) { \line(-1 ,-1) {16.0}}
X\put(127.0 ,252.0) { \line(5 ,-6) {13.0}}
X\put(194.0 ,211.0) { \line(0 ,-1) {114.0}}
X\end{picture}
!Funky!Stuff!
echo x - picture3.tex
sed -e 's/^X//' > "picture3.tex" << '!Funky!Stuff!'
X\setlength{\unitlength}{1pt}
X\begin{picture}(223.0 ,141.0 ) (0 ,0)
X\put(66, 52){\rule{32pt}{1pt}}
X\put(106, 52){\rule{32pt}{1pt}}
X\put(186, 52){\rule{1pt}{1pt}}
X\put(66, 53){\rule{32pt}{1pt}}
X\put(106, 53){\rule{32pt}{1pt}}
X\put(66, 54){\rule{32pt}{1pt}}
X\put(106, 54){\rule{32pt}{1pt}}
X\put(66, 55){\rule{32pt}{1pt}}
X\put(106, 55){\rule{32pt}{1pt}}
X\put(66, 56){\rule{32pt}{1pt}}
X\put(106, 56){\rule{32pt}{1pt}}
X\put(66, 57){\rule{32pt}{1pt}}
X\put(106, 57){\rule{32pt}{1pt}}
X\put(66, 58){\rule{32pt}{1pt}}
X\put(106, 58){\rule{32pt}{1pt}}
X\put(66, 59){\rule{32pt}{1pt}}
X\put(106, 59){\rule{32pt}{1pt}}
X\put(59, 60){\rule{7pt}{1pt}}
X\put(74, 60){\rule{16pt}{1pt}}
X\put(98, 60){\rule{8pt}{1pt}}
X\put(114, 60){\rule{16pt}{1pt}}
X\put(138, 60){\rule{8pt}{1pt}}
X\put(59, 61){\rule{7pt}{1pt}}
X\put(74, 61){\rule{16pt}{1pt}}
X\put(98, 61){\rule{8pt}{1pt}}
X\put(114, 61){\rule{16pt}{1pt}}
X\put(138, 61){\rule{8pt}{1pt}}
X\put(59, 62){\rule{7pt}{1pt}}
X\put(74, 62){\rule{16pt}{1pt}}
X\put(98, 62){\rule{8pt}{1pt}}
X\put(114, 62){\rule{16pt}{1pt}}
X\put(138, 62){\rule{8pt}{1pt}}
X\put(59, 63){\rule{7pt}{1pt}}
X\put(74, 63){\rule{16pt}{1pt}}
X\put(98, 63){\rule{8pt}{1pt}}
X\put(114, 63){\rule{16pt}{1pt}}
X\put(138, 63){\rule{8pt}{1pt}}
X\put(59, 64){\rule{7pt}{1pt}}
X\put(74, 64){\rule{16pt}{1pt}}
X\put(98, 64){\rule{8pt}{1pt}}
X\put(114, 64){\rule{16pt}{1pt}}
X\put(138, 64){\rule{8pt}{1pt}}
X\put(59, 65){\rule{7pt}{1pt}}
X\put(74, 65){\rule{16pt}{1pt}}
X\put(98, 65){\rule{8pt}{1pt}}
X\put(114, 65){\rule{16pt}{1pt}}
X\put(138, 65){\rule{8pt}{1pt}}
X\put(59, 66){\rule{7pt}{1pt}}
X\put(74, 66){\rule{16pt}{1pt}}
X\put(98, 66){\rule{8pt}{1pt}}
X\put(114, 66){\rule{16pt}{1pt}}
X\put(138, 66){\rule{8pt}{1pt}}
X\put(59, 67){\rule{7pt}{1pt}}
X\put(74, 67){\rule{16pt}{1pt}}
X\put(98, 67){\rule{8pt}{1pt}}
X\put(114, 67){\rule{16pt}{1pt}}
X\put(138, 67){\rule{8pt}{1pt}}
X\put(59, 68){\rule{7pt}{1pt}}
X\put(98, 68){\rule{8pt}{1pt}}
X\put(138, 68){\rule{8pt}{1pt}}
X\put(59, 69){\rule{7pt}{1pt}}
X\put(98, 69){\rule{8pt}{1pt}}
X\put(138, 69){\rule{8pt}{1pt}}
X\put(59, 70){\rule{7pt}{1pt}}
X\put(98, 70){\rule{8pt}{1pt}}
X\put(138, 70){\rule{8pt}{1pt}}
X\put(59, 71){\rule{7pt}{1pt}}
X\put(98, 71){\rule{8pt}{1pt}}
X\put(138, 71){\rule{8pt}{1pt}}
X\put(59, 72){\rule{7pt}{1pt}}
X\put(98, 72){\rule{8pt}{1pt}}
X\put(138, 72){\rule{8pt}{1pt}}
X\put(59, 73){\rule{7pt}{1pt}}
X\put(98, 73){\rule{8pt}{1pt}}
X\put(138, 73){\rule{8pt}{1pt}}
X\put(59, 74){\rule{7pt}{1pt}}
X\put(98, 74){\rule{8pt}{1pt}}
X\put(138, 74){\rule{8pt}{1pt}}
X\put(59, 75){\rule{7pt}{1pt}}
X\put(98, 75){\rule{8pt}{1pt}}
X\put(138, 75){\rule{8pt}{1pt}}
X\put(59, 76){\rule{7pt}{1pt}}
X\put(98, 76){\rule{8pt}{1pt}}
X\put(138, 76){\rule{8pt}{1pt}}
X\put(59, 77){\rule{7pt}{1pt}}
X\put(98, 77){\rule{8pt}{1pt}}
X\put(138, 77){\rule{8pt}{1pt}}
X\put(59, 78){\rule{7pt}{1pt}}
X\put(98, 78){\rule{8pt}{1pt}}
X\put(138, 78){\rule{8pt}{1pt}}
X\put(59, 79){\rule{7pt}{1pt}}
X\put(98, 79){\rule{8pt}{1pt}}
X\put(138, 79){\rule{8pt}{1pt}}
X\put(59, 80){\rule{7pt}{1pt}}
X\put(98, 80){\rule{8pt}{1pt}}
X\put(138, 80){\rule{8pt}{1pt}}
X\put(59, 81){\rule{7pt}{1pt}}
X\put(98, 81){\rule{8pt}{1pt}}
X\put(138, 81){\rule{8pt}{1pt}}
X\put(59, 82){\rule{7pt}{1pt}}
X\put(98, 82){\rule{8pt}{1pt}}
X\put(138, 82){\rule{8pt}{1pt}}
X\put(59, 83){\rule{7pt}{1pt}}
X\put(98, 83){\rule{8pt}{1pt}}
X\put(138, 83){\rule{8pt}{1pt}}
X\put(59, 84){\rule{39pt}{1pt}}
X\put(106, 84){\rule{40pt}{1pt}}
X\put(59, 85){\rule{39pt}{1pt}}
X\put(106, 85){\rule{40pt}{1pt}}
X\put(59, 86){\rule{39pt}{1pt}}
X\put(106, 86){\rule{40pt}{1pt}}
X\put(59, 87){\rule{39pt}{1pt}}
X\put(106, 87){\rule{40pt}{1pt}}
X\put(59, 88){\rule{39pt}{1pt}}
X\put(106, 88){\rule{40pt}{1pt}}
X\put(59, 89){\rule{39pt}{1pt}}
X\put(106, 89){\rule{40pt}{1pt}}
X\put(59, 90){\rule{39pt}{1pt}}
X\put(106, 90){\rule{40pt}{1pt}}
X\put(59, 91){\rule{39pt}{1pt}}
X\put(106, 91){\rule{40pt}{1pt}}
X\put(66, 92){\rule{8pt}{1pt}}
X\put(138, 92){\rule{8pt}{1pt}}
X\put(66, 93){\rule{8pt}{1pt}}
X\put(138, 93){\rule{8pt}{1pt}}
X\put(66, 94){\rule{8pt}{1pt}}
X\put(138, 94){\rule{8pt}{1pt}}
X\put(66, 95){\rule{8pt}{1pt}}
X\put(138, 95){\rule{8pt}{1pt}}
X\put(66, 96){\rule{8pt}{1pt}}
X\put(138, 96){\rule{8pt}{1pt}}
X\put(66, 97){\rule{8pt}{1pt}}
X\put(138, 97){\rule{8pt}{1pt}}
X\put(66, 98){\rule{8pt}{1pt}}
X\put(138, 98){\rule{8pt}{1pt}}
X\put(66, 99){\rule{8pt}{1pt}}
X\put(138, 99){\rule{8pt}{1pt}}
X\put(74, 100){\rule{8pt}{1pt}}
X\put(146, 100){\rule{8pt}{1pt}}
X\put(74, 101){\rule{8pt}{1pt}}
X\put(146, 101){\rule{8pt}{1pt}}
X\put(74, 102){\rule{8pt}{1pt}}
X\put(146, 102){\rule{8pt}{1pt}}
X\put(74, 103){\rule{8pt}{1pt}}
X\put(146, 103){\rule{8pt}{1pt}}
X\put(74, 104){\rule{8pt}{1pt}}
X\put(146, 104){\rule{8pt}{1pt}}
X\put(74, 105){\rule{8pt}{1pt}}
X\put(146, 105){\rule{8pt}{1pt}}
X\put(74, 106){\rule{8pt}{1pt}}
X\put(146, 106){\rule{8pt}{1pt}}
X\put(74, 107){\rule{8pt}{1pt}}
X\put(146, 107){\rule{8pt}{1pt}}
X\put(82, 108){\rule{8pt}{1pt}}
X\put(106, 108){\rule{8pt}{1pt}}
X\put(154, 108){\rule{8pt}{1pt}}
X\put(178, 108){\rule{8pt}{1pt}}
X\put(82, 109){\rule{8pt}{1pt}}
X\put(106, 109){\rule{8pt}{1pt}}
X\put(154, 109){\rule{8pt}{1pt}}
X\put(178, 109){\rule{8pt}{1pt}}
X\put(82, 110){\rule{8pt}{1pt}}
X\put(106, 110){\rule{8pt}{1pt}}
X\put(154, 110){\rule{8pt}{1pt}}
X\put(178, 110){\rule{8pt}{1pt}}
X\put(82, 111){\rule{8pt}{1pt}}
X\put(106, 111){\rule{8pt}{1pt}}
X\put(154, 111){\rule{8pt}{1pt}}
X\put(178, 111){\rule{8pt}{1pt}}
X\put(82, 112){\rule{8pt}{1pt}}
X\put(106, 112){\rule{8pt}{1pt}}
X\put(154, 112){\rule{8pt}{1pt}}
X\put(178, 112){\rule{8pt}{1pt}}
X\put(82, 113){\rule{8pt}{1pt}}
X\put(106, 113){\rule{8pt}{1pt}}
X\put(154, 113){\rule{8pt}{1pt}}
X\put(178, 113){\rule{8pt}{1pt}}
X\put(82, 114){\rule{8pt}{1pt}}
X\put(106, 114){\rule{8pt}{1pt}}
X\put(154, 114){\rule{8pt}{1pt}}
X\put(178, 114){\rule{8pt}{1pt}}
X\put(82, 115){\rule{8pt}{1pt}}
X\put(106, 115){\rule{8pt}{1pt}}
X\put(154, 115){\rule{8pt}{1pt}}
X\put(178, 115){\rule{8pt}{1pt}}
X\put(82, 116){\rule{8pt}{1pt}}
X\put(106, 116){\rule{8pt}{1pt}}
X\put(154, 116){\rule{8pt}{1pt}}
X\put(178, 116){\rule{8pt}{1pt}}
X\put(82, 117){\rule{8pt}{1pt}}
X\put(106, 117){\rule{8pt}{1pt}}
X\put(154, 117){\rule{8pt}{1pt}}
X\put(178, 117){\rule{8pt}{1pt}}
X\put(82, 118){\rule{8pt}{1pt}}
X\put(106, 118){\rule{8pt}{1pt}}
X\put(154, 118){\rule{8pt}{1pt}}
X\put(178, 118){\rule{8pt}{1pt}}
X\put(82, 119){\rule{8pt}{1pt}}
X\put(106, 119){\rule{8pt}{1pt}}
X\put(154, 119){\rule{8pt}{1pt}}
X\put(178, 119){\rule{8pt}{1pt}}
X\put(82, 120){\rule{8pt}{1pt}}
X\put(106, 120){\rule{8pt}{1pt}}
X\put(154, 120){\rule{8pt}{1pt}}
X\put(178, 120){\rule{8pt}{1pt}}
X\put(82, 121){\rule{8pt}{1pt}}
X\put(106, 121){\rule{8pt}{1pt}}
X\put(154, 121){\rule{8pt}{1pt}}
X\put(178, 121){\rule{8pt}{1pt}}
X\put(82, 122){\rule{8pt}{1pt}}
X\put(106, 122){\rule{8pt}{1pt}}
X\put(154, 122){\rule{8pt}{1pt}}
X\put(178, 122){\rule{8pt}{1pt}}
X\put(82, 123){\rule{8pt}{1pt}}
X\put(106, 123){\rule{8pt}{1pt}}
X\put(154, 123){\rule{8pt}{1pt}}
X\put(178, 123){\rule{8pt}{1pt}}
X\put(90, 124){\rule{16pt}{1pt}}
X\put(162, 124){\rule{16pt}{1pt}}
X\put(90, 125){\rule{16pt}{1pt}}
X\put(162, 125){\rule{16pt}{1pt}}
X\put(90, 126){\rule{16pt}{1pt}}
X\put(162, 126){\rule{16pt}{1pt}}
X\put(90, 127){\rule{16pt}{1pt}}
X\put(162, 127){\rule{16pt}{1pt}}
X\put(90, 128){\rule{16pt}{1pt}}
X\put(162, 128){\rule{16pt}{1pt}}
X\put(90, 129){\rule{16pt}{1pt}}
X\put(162, 129){\rule{16pt}{1pt}}
X\put(90, 130){\rule{16pt}{1pt}}
X\put(162, 130){\rule{16pt}{1pt}}
X\put(12.0 ,28.0) {\makebox(179.0 , 18.0 ){{\Huge I'm watching you}}}
X\end{picture}
!Funky!Stuff!
echo x - picture1.xpl
sed -e 's/^X//' > "picture1.xpl" << '!Funky!Stuff!'
X(Picture basicNew instVarAt: 1 put: ((OrderedCollection new) add: (PicElemVector basicNew instVarAt: 1 put: (Point x: 211.0 y: 56.0);
X instVarAt: 2 put: (Point x: 211.0 y: 106.0); instVarAt: 3 put: nil; yourself); add: (PicElemVector basicNew instVarAt: 1 put: (Point x: 91.0 y: 56.0); 
XinstVarAt: 2 put: (Point x: 91.0 y: 106.0); instVarAt: 3 put: nil; yourself);
X add: (PicElemText basicNew instVarAt: 1 put: (Point x: 141.0 y: 72.0);
X instVarAt: 2 put: 'p.o.'; yourself); add: (PicElemText basicNew instVarAt: 1
X put: (Point x: 45.0 y: 150.0); instVarAt: 2 put: 
X'This is a pushout in {\bf Sign}'; yourself); add: (PicElemGroup basicNew
X instVarAt: 1 put: (Point x: 51.0 y: 35.0); instVarAt: 2 put: ((OrderedCollection
X new) add: (PicElemVector basicNew instVarAt: 1 put: (Point x: 59.0 y: 10.0); 
XinstVarAt: 2 put: (Point x: 142.0 y: 10.0); instVarAt: 3 put: nil; yourself); add:
X (PicElemText basicNew instVarAt: 1 put: (Point x: 118.0 y: -1.0); instVarAt: 2 
Xput: '$\Sigma_b$'; yourself); add: (PicElemText basicNew instVarAt: 1 put: 
X(Point x: -1.0 y: -1.0); instVarAt: 2 put: '$\Sigma_f$'; yourself); yourself); 
Xyourself); add: (PicElemGroup basicNew instVarAt: 1 put: (Point x: 50.0 y: 
X110.0); instVarAt: 2 put: ((OrderedCollection new) add: (PicElemVector 
XbasicNew instVarAt: 1 put: (Point x: 60.0 y: 10.0); instVarAt: 2 put: (Point x: 
X143.0 y: 10.0); instVarAt: 3 put: nil; yourself); add: (PicElemText basicNew 
XinstVarAt: 1 put: (Point x: -1.0 y: -1.0); instVarAt: 2 put: '$\Sigma_a$'; 
Xyourself); add: (PicElemText basicNew instVarAt: 1 put: (Point x: 120.0 y: -1.0);
X instVarAt: 2 put: '$\Sigma_r$'; yourself); yourself); yourself); yourself);
X instVarAt: 2 put: 1; instVarAt: 3 put: (Point x: 300 y: 200); instVarAt: 4 put: 
X(Point x: 0 y: 0); instVarAt: 5 put: nil; yourself)
!Funky!Stuff!
echo x - picture2.xpl
sed -e 's/^X//' > "picture2.xpl" << '!Funky!Stuff!'
X(Picture basicNew instVarAt: 1 put: ((OrderedCollection new) add: 
X(PicElemGroup basicNew instVarAt: 1 put: (Point x: 7.0 y: 14.0); instVarAt: 2 
Xput: ((OrderedCollection new) add: (PicElemOval basicNew instVarAt: 1 put: 
X(Rectangle origin: (Point x: -1.0 y: -1.0) corner: (Point x: 97.0 y: 67.0)); 
XinstVarAt: 2 put: nil; instVarAt: 3 put: ((Set new)); yourself); add: (PicElemLine 
XbasicNew instVarAt: 1 put: (Point x: 95.0 y: 44.0); instVarAt: 2 put: (Point x: 
X143.0 y: 52.0); instVarAt: 3 put: nil; yourself); add: (PicElemLine basicNew 
XinstVarAt: 1 put: (Point x: 97.0 y: 35.0); instVarAt: 2 put: (Point x: 139.0 y: 
X49.0); instVarAt: 3 put: nil; yourself); yourself); yourself); add: (PicElemLine 
XbasicNew instVarAt: 1 put: (Point x: 195.0 y: 68.0); instVarAt: 2 put: (Point x:
X 392.0 y: 68.0); instVarAt: 3 put: nil; yourself); add: (PicElemLine basicNew
X instVarAt: 1 put: (Point x: 394.0 y: 69.0); instVarAt: 2 put: (Point x: 394.0 y:
X 183.0); instVarAt: 3 put: nil; yourself); add: (PicElemText basicNew instVarAt: 
X1 put: (Point x: 204.0 y: 115.0); instVarAt: 2 put: '{\huge$E = m\cdot c^2$}'; 
Xyourself); add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 196.0 y: 
X183.0); instVarAt: 2 put: (Point x: 393.0 y: 183.0); instVarAt: 3 put: nil; 
Xyourself); add: (PicElemText basicNew instVarAt: 1 put: (Point x: -13.0 y: 34.0);
X instVarAt: 2 put: '{\large Hi, folks}'; yourself); add: (PicElemGroup basicNew 
XinstVarAt: 1 put: (Point x: 96.0 y: 25.0); instVarAt: 2 put: ((OrderedCollection 
Xnew) add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 61.0 y: 51.0); 
XinstVarAt: 2 put: (Point x: 61.0 y: 157.0); instVarAt: 3 put: nil; yourself); add: 
X(PicElemLine basicNew instVarAt: 1 put: (Point x: 59.0 y: 159.0); instVarAt: 2 
Xput: (Point x: 9.0 y: 219.0); instVarAt: 3 put: nil; yourself); add: (PicElemLine 
XbasicNew instVarAt: 1 put: (Point x: 62.0 y: 158.0); instVarAt: 2 put: (Point x: 
X100.0 y: 215.0); instVarAt: 3 put: nil; yourself); add: (PicElemLine basicNew 
XinstVarAt: 1 put: (Point x: 62.0 y: 78.0); instVarAt: 2 put: (Point x: -1.0 y: 88.5);
X instVarAt: 3 put: nil; yourself); add: (PicElemLine basicNew instVarAt: 1 put: 
X(Point x: 58.0 y: 131.0); instVarAt: 2 put: (Point x: 50.0 y: 141.0); instVarAt: 3 
Xput: nil; yourself); add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 1.0 y: 
X89.0); instVarAt: 2 put: (Point x: 56.0 y: 130.25); instVarAt: 3 put: nil; yourself);
X add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 120.0 y: 7.0); instVarAt: 
X2 put: (Point x: 128.0 y: 20.3333); instVarAt: 3 put: nil; yourself); add: 
X(PicElemLine basicNew instVarAt: 1 put: (Point x: 63.0 y: 79.25); instVarAt: 2 
Xput: (Point x: 120.0 y: 8.0); instVarAt: 3 put: nil; yourself); add: (PicElemGroup 
XbasicNew instVarAt: 1 put: (Point x: 32.0 y: -1.0); instVarAt: 2 put: 
X((OrderedCollection new) add: (PicElemGroup basicNew instVarAt: 1 put: (Point 
Xx: 9.0 y: 12.0); instVarAt: 2 put: ((OrderedCollection new) add: (PicElemCircle 
XbasicNew instVarAt: 1 put: (Point x: 19.0 y: 19.0); instVarAt: 2 put: 20; 
XinstVarAt: 3 put: nil; instVarAt: 4 put: false; yourself); add: (PicElemCircle 
XbasicNew instVarAt: 1 put: (Point x: 10.0 y: 11.0); instVarAt: 2 put: 3.0; 
XinstVarAt: 3 put: nil; instVarAt: 4 put: true; yourself); add: (PicElemCircle 
XbasicNew instVarAt: 1 put: (Point x: 26.0 y: 11.0); instVarAt: 2 put: 3.0; 
XinstVarAt: 3 put: nil; instVarAt: 4 put: true; yourself); add: (PicElemOval 
XbasicNew instVarAt: 1 put: (Rectangle origin: (Point x: 7.0 y: 17.0) corner: 
X(Point x: 32.0 y: 33.0)); instVarAt: 2 put: nil; instVarAt: 3 put: ((Set new) add: 
X#b; yourself); yourself); add: (PicElemVector basicNew instVarAt: 1 put: (Point 
X x: 19.0 y: 13.0); instVarAt: 2 put: (Point x: 19.0 y: 24.0); instVarAt: 3 put: nil; 
Xyourself); yourself); yourself); add: (PicElemLine basicNew instVarAt: 1 put: 
X(Point x: 19.0 y: 1.0); instVarAt: 2 put: (Point x: 23.0 y: 13.0); instVarAt: 3 put: 
Xnil; yourself); add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 37.0 y: 
X-1.0); instVarAt: 2 put: (Point x: 34.0 y: 11.0); instVarAt: 3 put: nil; yourself); 
Xadd: (PicElemLine basicNew instVarAt: 1 put: (Point x: 60.0 y: 1.0); instVarAt: 2 
Xput: (Point x: 44.0 y: 17.0); instVarAt: 3 put: nil; yourself); add: (PicElemLine 
XbasicNew instVarAt: 1 put: (Point x: -1.0 y: 4.0); instVarAt: 2 put: (Point x: 12.0
X y: 19.6); instVarAt: 3 put: nil; yourself); yourself); yourself); yourself); 
Xyourself); add: (PicElemLine basicNew instVarAt: 1 put: (Point x: 194.0 y: 69.0);
X instVarAt: 2 put: (Point x: 194.0 y: 183.0); instVarAt: 3 put: nil; yourself); 
Xyourself); instVarAt: 2 put: 1; instVarAt: 3 put: (Point x: 400 y: 280); 
XinstVarAt: 4 put: (Point x: 0 y: 0); instVarAt: 5 put: nil; yourself)
!Funky!Stuff!
echo x - picture3.xpl
sed -e 's/^X//' > "picture3.xpl" << '!Funky!Stuff!'
X(Picture basicNew instVarAt: 1 put: ((OrderedCollection new) add: 
X(PicElemGroup basicNew instVarAt: 1 put: (Point x: 13.0 y: 11.0); instVarAt: 2 
Xput: ((OrderedCollection new) add: (PicElemForm basicNew instVarAt: 1 put: 
X(Point x: 46.0 y: -1.0); instVarAt: 2 put: (Form
X
X	extent: 128@79
X	fromArray: #( 0 1 65534 0 0 0 511 65024 0 1 65534 0 0 0 511 65024 0 1 
X65534 0 0 0 511 65024 0 1 65534 0 0 0 511 65024 0 1 65534 0 0 0 511 
X65024 0 1 65534 0 0 0 511 65024 0 1 65534 0 0 0 511 65024 0 510 1 
X65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 0 1 
X65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 0 
X510 1 65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 
X0 1 65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 
X0 510 1 65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 
X0 1 65024 510 0 510 1 65024 0 1 65024 510 0 510 1 65024 0 1 65024 510 
X0 510 1 65024 0 1 65024 510 1 65024 0 0 0 510 0 0 1 65024 0 0 0 510 0 0 
X1 65024 0 0 0 510 0 0 1 65024 0 0 0 510 0 0 1 65024 0 0 0 510 0 0 1 65024 
X0 0 0 510 0 0 1 65024 0 0 0 510 0 0 1 65024 0 0 0 510 0 0 510 0 0 0 1 65024 
X0 0 510 0 0 0 1 65024 0 0 510 0 0 0 1 65024 0 0 510 0 0 0 1 65024 0 0 510 
X0 0 0 1 65024 0 0 510 0 0 0 1 65024 0 0 510 0 0 0 1 65024 0 0 510 0 0 0 1 
X65024 0 0 65535 65535 65025 65535 65535 65024 0 0 65535 65535 65025 
X65535 65535 65024 0 0 65535 65535 65025 65535 65535 65024 0 0 65535 
X65535 65025 65535 65535 65024 0 0 65535 65535 65025 65535 65535 65024 
X0 0 65535 65535 65025 65535 65535 65024 0 0 65535 65535 65025 65535 
X65535 65024 0 0 65535 65535 65025 65535 65535 65024 0 0 65024 0 510 0 
X1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 
X510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 
X65024 0 510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 0 1 
X65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 
X0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65024 0 
X510 0 1 65024 0 0 65024 0 510 0 1 65024 0 0 65025 65534 510 511 65025 
X65024 0 0 65025 65534 510 511 65025 65024 0 0 65025 65534 510 511 65025 
X65024 0 0 65025 65534 510 511 65025 65024 0 0 65025 65534 510 511 65025 
X65024 0 0 65025 65534 510 511 65025 65024 0 0 65025 65534 510 511 65025 
X65024 0 0 65025 65534 510 511 65025 65024 0 0 511 65535 65025 65535 
X65534 0 0 0 511 65535 65025 65535 65534 0 0 0 511 65535 65025 65535 
X65534 0 0 0 511 65535 65025 65535 65534 0 0 0 511 65535 65025 65535 65534 
X0 0 0 511 65535 65025 65535 65534 0 0 0 511 65535 65025 65535 65534 0 0 0 
X511 65535 65025 65535 65534 0 0 1)
X	offset: 0@0); yourself); add: (PicElemText basicNew instVarAt: 1 put: 
X(Point x: -1.0 y: 84.0); instVarAt: 2 put: '{\Huge I''m watching you}'; yourself); 
Xyourself); yourself); yourself); instVarAt: 2 put: 1; instVarAt: 3 put: (Point x: 
X223 y: 141); instVarAt: 4 put: (Point x: 0 y: 0); instVarAt: 5 put: nil; yourself)
X
!Funky!Stuff!
echo x - picinter.st
sed -e 's/^X//' > "picinter.st" << '!Funky!Stuff!'
XView subclass: #PictureView
X	instanceVariableNames: 'selection '
X	classVariableNames: 'CopyBuffer '
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PictureView methodsFor: 'updating'!
X
Xupdate: aspect with: picElem 
X	| sv box |
X	(#(addFirst addLast ) includes: aspect)
X		ifTrue: 
X			[sv _ picElem defaultViewClass new.
X			sv model: picElem.
X			sv window: (picElem boundingBox expandBy: 2 @ 2).
X			"Unitlength: model unitlength"
X			aspect = #addFirst
X				ifTrue: [subViews addFirst: sv]
X				ifFalse: [subViews addLast: sv].
X			sv superView: self.
X			sv draw].
X	(#(remove removeFirst removeLast ) includes: aspect)
X		ifTrue: 
X			[sv _ subViews detect: [:pelem | pelem model == picElem]
X						ifNone: [].
X			sv notNil
X				ifTrue: 
X					[sv erase.
X					self removeSubView: sv.
X					sv release]].
X	aspect = #extent
X		ifTrue: 
X			[self window: (model boundingBox expandBy: 2@2). 
X			"viewport: (self superView window)"
X			self flushCache.
X			self superView display]! !
X
X!PictureView methodsFor: 'subView creation'!
X
XcreateSubViews
X	| t1 t2 t3 |
X	self releaseSubViews.
X	model do: 
X		[:t3 | 
X		t1 _ t3 defaultViewClass new.
X		t1 model: t3.
X		t2 _ t3 boundingBox.
X		t1 window: (t3 boundingBox expandBy: 2@2).
X		subViews addLast: t1.
X		t1 superView: self]! !
X
X!PictureView methodsFor: 'selection'!
X
Xselect: t1 
X	t1 == selection ifTrue: [^self].
X	selection _ t1.
X	"self display"!
X
Xselection
X	^selection! !
X
X!PictureView methodsFor: 'displaying'!
X
XrestoreOn: aRegion for: aModel
X	| reg subVws regions indx view hisRegion bits cache |  
X	
X	reg _ aRegion intersect: (self insetDisplayBox).
X	"get the controllers that have views that intersect the view being erased"
X	subVws _ OrderedCollection new: subViews size.
X	regions _ OrderedCollection new: subViews size.
X	indx _ 1.
X	[indx <= subViews size]
X		whileTrue: 
X			[view _ subViews at: indx.
X			((view model ~= aModel)
X				and: [(hisRegion _ view displayWindow) intersects: reg])
X				ifTrue: 
X					[subVws add: view.
X					regions add: hisRegion].
X			indx _ indx + 1].
X
X	"put the cached bits from intersecting views on the display with double buffering"
X	(reg origin < reg corner) ifFalse: [^self].
X	bits _  Form extent: reg extent.
X	(subVws size to: 1 by: -1)
X		do: 
X			[:i | 
X			view _ subVws at: i.
X			(cache _ view viewForm) == nil
X				ifFalse: [cache displayOn: bits at: view displayWindow origin - reg origin rule: Form under]].
X	"bits displayOn: Display at: reg origin"
X	bits displayOn: Display at: reg origin clippingBox: aRegion rule: Form over mask: nil! !
X
X!PictureView methodsFor: 'accessing'!
X
XcopyBuffer
X	^CopyBuffer!
X
XcopyBuffer: item
X	CopyBuffer _ item copy.
X	CopyBuffer breakDependents.!
X
XflushCache
X	subViews do: [:sv| sv flushCache]!
X
XpictureView
X	^self!
X
XtoBottom: t1 
X	| t2 t3 |
X	t2 _ subViews detect: [:t3 | t3 model == t1]
X				ifNone: [].
X	t2 notNil
X		ifTrue: 
X			[subViews remove: t2.
X			subViews addFirst: t2]!
X
XtoTop: t1 
X	| t2 t3 |
X	t2 _ subViews detect: [:t3 | t3 model == t1]
X				ifNone: [].
X	t2 notNil
X		ifTrue: 
X			[subViews remove: t2.
X			subViews add: t2]! !
X
X!PictureView methodsFor: 'controller access'!
X
XdefaultControllerClass
X	^PictureController! !
X
X!PictureView methodsFor: 'lock-access'!
X
Xunlock
X	| scale |
X	super unlock.
X	self isUnlocked
X		ifTrue: 
X			[self superView notNil
X				ifTrue: 
X					[displayTransformation _ WindowingTransformation scale: 1 @ 1 translation: self displayBox origin.
X					insetDisplayBox _ nil].
X			self flushCache]! !
X"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
X
XPictureView class
X	instanceVariableNames: ''!
X
X
X!PictureView class methodsFor: 'instance creation'!
X
XopenOn: picture 
X	"self openOn: Picture new"
X	| tv pv box |
X	tv _ StandardSystemView new.
X	tv label: 'Picture'.
X	tv borderWidth: 1.
X	tv model: picture.
X	pv _ self new.
X	pv borderWidth: 0.
X	pv model: picture.
X	"box _ picture origin * picture unitlength negated extent: picture extent * picture unitlength."
X	box _ picture origin * -1 extent: picture extent.
X	pv window: box.
X	pv createSubViews.
X	pv insideColor: Form white.
X	"tv minimumSize: box extent."
X	tv addSubView: pv.
X	tv insideColor: Form lightGray.
X	tv controller open! !
X
XMouseMenuController subclass: #PictureElementController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PictureElementController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\to bottom' withCRs)
X		yellowButtonMessages: #(cut copy toBottom )! !
X
X!PictureElementController methodsFor: 'testing'!
X
XisSelected
X	^self view isSelected! !
X
X!PictureElementController methodsFor: 'menu messages'!
X
Xcopy
X	self view pictureView copyBuffer: model.!
X
Xcut
X	self view pictureView copyBuffer: model.
X	self view superView model remove: model!
X
Xmove: point 
X	| p box offset grid |
X	self view erase.
X	offset _ (self view displayWindow origin) - point.
X	grid _ self view pictureView controller getGrid.
X	(OpaqueForm shape: self view viewForm)
X		follow:  
X			[p _ (sensor cursorPoint + offset) grid: grid]
X		while: [sensor redButtonPressed].
X	self view moveTo: ((self view inverseDisplayTransform: p) + (self model origin - self view window origin)).
X	self view draw!
X
XredButtonActivity
X	| t1 t2 t3 box insetBox |
X	t3 _ sensor cursorPoint.
X	self select.
X	box _ self view insetDisplayBox.
X	insetBox _ box insetBy: 5.
X	(sensor leftShiftDown and: [(box containsPoint: t3)
X			and: [(insetBox containsPoint: t3) not]])
X		ifTrue: [^self reframe: t3].
X	(Delay forMilliseconds: 50) wait.
X	Sensor redButtonPressed ifTrue: [self move: t3]!
X
Xreframe: point 
X	| t2 box t4 symbol grid |
X	self view erase.
X	box _ self view displayWindow copy.
X	symbol _ box nearestPointTo: point.
X	symbol isNil ifTrue: [^self].
X	t4 _ box origin - point.
X	grid _ self view pictureView controller getGrid.
X	Display
X		outline: 
X			[t2 _ sensor cursorPoint grid: grid.
X			box perform: (symbol,':') asSymbol with: t2.
X			"(box moveTo: t2 + t4)
X				intersect: self view superView insetDisplayBox"]
X		while: [sensor redButtonPressed]
X		width: 1
X		halftone: Form gray.
X	self view newBoundingBox: (self view inverseDisplayTransform: box).
X	self view draw!
X
Xselect
X	| t1 |
X	t1 _ self view superView model picElements.
X	t1 remove: self model.
X	t1 addLast: self model.
X	self view superView toTop: self model.
X	self view pictureView subViews do: [:sv| sv deselect].
X	self view select!
X
XtoBottom
X	| t1 |
X	self view superView toBottom: model.
X	t1 _ self view superView model picElements.
X	t1 remove: model.
X	t1 addFirst: model.
X	self view deselect!
X
XyellowButtonActivity
X	self view superView selection = model ifTrue: [super yellowButtonActivity]! !
X
X!PictureElementController methodsFor: 'control defaults'!
X
XisControlActive
X	view isNil ifTrue: [^false].
X	(view containsPoint: sensor cursorPoint)
X		ifFalse: [^false].
X	sensor blueButtonPressed ifTrue: [^false].
X	sensor redButtonPressed ifTrue: [^true].
X	^sensor yellowButtonPressed & self isSelected! !
X
XPictureElementController subclass: #PicElemGroupController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemGroupController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\ungroup\to bottom' withCRs)
X		yellowButtonMessages: #(cut copy ungroup toBottom )! !
X
X!PicElemGroupController methodsFor: 'menu messages'!
X
Xungroup
X	| picture |
X	picture _ self view pictureView model.
X	picture remove: model.
X	model elements do: 
X		[:elem | 
X		elem origin: elem origin + model origin+(1@1).
X		picture add: elem]! !
X
XPictureElementController subclass: #PicElemCircleController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemCircleController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\fill/nofill\to bottom' withCRs)
X		yellowButtonMessages: #(cut copy fill toBottom )! !
X
X!PicElemCircleController methodsFor: 'menu messages'!
X
Xfill
X	model full: model full not!
X
Xreframe: point 
X	| t2 box t4 symbol |
X	box _ self view displayWindow copy.
X	symbol _ box nearestPoint: point to: #(topLeft topRight bottomLeft bottomRight).
X	(symbol isNil or: [#bottomRight ~= symbol])ifTrue: [^self].
X	self view erase.
X	t4 _ box origin - point.
X	Display
X		outline: 
X			[t2 _ sensor cursorPoint.
X			box perform: (symbol,':') asSymbol with: t2.
X			box _ box origin extent: ((box extent x min: box extent y) @ (box extent x min: box extent y))
X			"(box moveTo: t2 + t4)
X				intersect: self view superView insetDisplayBox"]
X		while: [sensor redButtonPressed]
X		width: 1
X		halftone: Form gray.
X	self view newBoundingBox: (self view inverseDisplayTransform: box).
X	self view draw! !
X
XMouseMenuController subclass: #PictureController
X	instanceVariableNames: 'gridPoint '
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PictureController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: ' circle \ line \ vektor \ text \ oval \ form \ grid \ unitlength \ extent \ paste \ group \ collapse Text \ latex \file out \ copyright' withCRs lines: #(6 12 14))
X		yellowButtonMessages: #(createCircle createLine createVector createText createOval createForm grid setUnitlength setExtent paste group collapseText latex fileOut copyright)! !
X
X!PictureController methodsFor: 'menu messages'!
X
XcollapseText
X	PicElemText isCollapsed: PicElemText isCollapsed not.
X	self view subViews do: [:e| e collapsedTextChanged].
X	self view display!
X
Xcopyright
X	| text form p background |
X	text _ ' Press mouse button to continue \' withCRs asText.
X	text
X		emphasizeFrom: 1
X		to: text size
X		with: 3.
X	form _ ('\        Picture editor V1.0\' withCRs asText allBold , '\  This program was written by \' withCRs asText , '       Hubert Baumeister \' withCRs asText allBold , '  (huba@unidoi5.{uucp, bitnet}) \ \' withCRs asText , text) asDisplayText form.
X	form borderWidth: 2.
X	p _ sensor cursorPoint.
X	p _ p - form boundingBox center.
X	background _ form backgroundAt: p.
X	form displayAt: p.
X	sensor waitButton.
X	background display!
X
XcreateCircle
X	model add: (PicElemCircle inRectangle: self getRect)!
X
XcreateForm
X	| form p grid |
X	form _ Form fromUser.
X	grid _ self getGrid.
X	form follow: [p _ sensor cursorPoint grid: grid]
X		while: [sensor noButtonPressed].
X	p _ (self view inverseDisplayTransform: p).
X	model add: ((PicElemForm form: form)
X			origin: p)!
X
XcreateLine
X	| line |
X	line _ self getLine.
X	line isNil ifTrue: [^self].
X	model add: (PicElemLine from: (line at: 1)
X			to: (line at: 2))!
X
XcreateOval
X	model add: (PicElemOval new newBoundingBox: self getRect)!
X
XcreateText
X	| text p grid |
X	text _ FillInTheBlank request: ' text: ' initialAnswer: 'initial text'.
X	text = '' asText ifTrue: [^self].
X	grid _ self getGrid.
X	text asDisplayText follow: [p _ sensor cursorPoint grid: grid]
X		while: [sensor noButtonPressed].
X	p _ self view inverseDisplayTransform: p.
X	model add: ((PicElemText new text: text)
X			origin: p)!
X
XcreateVector
X	| line |
X	line _ self getLine.
X	line isNil ifTrue: [^self].
X	model add: (PicElemVector from: (line at: 1)
X			to: (line at: 2))!
X
XfileOut
X	| filename stream |
X	filename _ FillInTheBlank request: ' file out on: ' initialAnswer: 'picture.st'.
X	filename = '' ifTrue: [^self].
X	stream _ FileStream fileNamed: filename.
X	Cursor write showWhile: [model storeOn: stream].
X	stream close!
X
Xgrid
X	| newGrid |
X	newGrid _ FillInTheBlank request: 'New grid point' initialAnswer: self getGrid printString.
X	newGrid = '' ifTrue: [^self].
X	newGrid _ Point readFromString: newGrid.
X	newGrid isNil ifTrue: [^self].
X	gridPoint _ newGrid!
X
Xgroup
X	self group: self getRect!
X
Xlatex
X	| filename stream |
X	filename _ FillInTheBlank request: ' latex on: ' initialAnswer: 'picture.tex'.
X	filename = '' ifTrue: [^self].
X	stream _ FileStream fileNamed: filename.
X	Cursor write showWhile: [model latexOn: stream].
X	stream close!
X
Xpaste
X	| box copy p grid| 
X	copy _ self view copyBuffer copy.
X	copy isNil ifTrue: [^self].
X	grid _ self getGrid.
X	box _ self view displayTransform: (copy boundingBox).
X	Display
X		outline: 
X			[p _ sensor cursorPoint grid: grid.
X			(box moveTo: p)]
X		while: [sensor anyButtonPressed not]
X		width: 1
X		halftone: Form gray.
X	copy moveTo: (self view inverseDisplayTransform: p).	
X	model add: copy!
X
XredButtonActivity
X	self view subViewWantingControl notNil ifTrue: [^self].
X	self view subViews do: [:sv | sv deselect].
X	(Delay forMilliseconds: 100) wait.
X	Sensor redButtonPressed ifFalse: [^self].
X	self group: self getRect!
X
XsetExtent
X	| point | 
X	point _ FillInTheBlank request: 'New extent in pt' initialAnswer: model extent printString.
X	point = '' ifTrue: [^self].
X	point _ Point readFromString: point.
X	model extent: point!
X
XsetUnitlength
X	| scale | 
X	scale _ FillInTheBlank request: 'New unitlength' initialAnswer: model unitlength printString.
X	scale = '' ifTrue: [^self].
X	scale _ Number readFromString: scale.
X	model unitlength: scale! !
X
X!PictureController methodsFor: 'control defaults'!
X
XcontrolActivity
X	self controlToNextLevel.
X	sensor yellowButtonPressed & self viewHasCursor ifTrue: [^self yellowButtonActivity].
X	sensor redButtonPressed & self viewHasCursor ifTrue: [^self redButtonActivity].
X	sensor blueButtonPressed & self viewHasCursor ifTrue: [^self blueButtonActivity]!
X
XisControlActive
X	(view containsPoint: sensor cursorPoint) ifFalse: [^false].
X	sensor blueButtonPressed ifTrue: [^false].
X	^true! !
X
X!PictureController methodsFor: 'private'!
X
XgetGrid
X	gridPoint isNil ifTrue: [gridPoint _ 1@1].
X	^gridPoint!
X
XgetLine
X	| to from pen line grid |
X	sensor waitNoButton.
X	pen _ Form dotOfSize: 1.
X	sensor waitButton.
X	grid _ self getGrid.
X	from _ sensor cursorPoint grid: grid.
X	to _ from.
X	[sensor redButtonPressed]
X		whileTrue: 
X			[to _ sensor cursorPoint grid: grid.
X			line _ Line
X						from: from
X						to: to
X						withForm: pen.
X			line
X				displayOn: Display
X				at: 0 @ 0
X				clippingBox: Display boundingBox
X				rule: Form reverse
X				mask: Form black.
X			line
X				displayOn: Display
X				at: 0 @ 0
X				clippingBox: Display boundingBox
X				rule: Form reverse
X				mask: Form black].
X	from = to ifTrue: [^nil].
X	^Array with: (self view inverseDisplayTransform: from)
X		with: (self view inverseDisplayTransform: to)!
X
XgetRect
X	| rect |
X	rect _ Rectangle fromUser: self getGrid.
X	rect _ (self view inverseDisplayTransform: rect).
X	^rect!
X
Xgroup: rect 
X	| box group picElemGroup bbox |
X	group _ model picElements
X				select: 
X					[:pe | 
X					bbox _ pe boundingBox.
X					rect origin < bbox origin and: [rect corner > bbox corner]].
X	group isEmpty ifTrue: [^self].
X	box _ group first boundingBox.
X	group do: [:pe | box _ box merge: pe boundingBox].
X	picElemGroup _ PicElemGroup new origin: box origin.
X	group do: 
X		[:pe | 
X		model remove: pe.
X		picElemGroup add: pe].
X	model add: picElemGroup! !
X
XPictureElementController subclass: #PicElemFormController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemFormController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\edit\to bottom' withCRs)
X		yellowButtonMessages: #(cut copy edit toBottom )! !
X
X!PicElemFormController methodsFor: 'menu messages'!
X
Xedit
X	model form edit! !
X
XView subclass: #PictureElementView
X	instanceVariableNames: 'cache '
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PictureElementView methodsFor: 'displaying'!
X
Xdeselect
X	self isSelected ifTrue: [self pictureView restoreOn:  (self displayBox expandBy: 3) for: nil.
X	self pictureView select: nil]!
X
XdisplaySelected
X	Display
X		border: (self displayBox expandBy: 1@1)
X		widthRectangle: (Rectangle
X				left: 1
X				right: 1
X				top: 1
X				bottom: 1)
X		mask: Form black
X		clippingBox: superView insetDisplayBox!
X
XdisplayView
X	| form | 
X	form _ self viewForm.
X	form
X		displayOn: Display
X		at: self insetDisplayBox origin "(self displayTransform: model origin)""self displayWindow origin"
X		clippingBox: self insetDisplayBox
X		rule: Form paint
X		mask: Form black.
X	self isSelected ifTrue: [self displaySelected]!
X
Xdraw
X	self pictureView restoreOn: self displayWindow for: nil.
X	self isSelected ifTrue:[self displaySelected]!
X
Xerase
X	self pictureView restoreOn: (self displayWindow expandBy: 1@1) for: self model!
X
XflushCache
X	cache _ nil!
X
XmoveTo: p 
X	model moveTo: p.
X	self window: ((model boundingBox expandBy: 2@2))!
X
XnewBoundingBox: rect 
X	model newBoundingBox: rect!
X
Xselect
X	self isSelected ifFalse: [self displaySelected.
X		self pictureView select: self model]!
X
Xunitlength
X	^self superView model unitlength!
X
XviewForm
X	cache isNil ifTrue: [cache _ self createViewForm].
X	^cache! !
X
X!PictureElementView methodsFor: 'controller accessing'!
X
XdefaultControllerClass
X	^PictureElementController! !
X
X!PictureElementView methodsFor: 'testing'!
X
XisSelected
X	| pv | 
X	pv _ self pictureView.
X	pv isNil ifTrue: [^false].
X	^pv selection == self model! !
X
X!PictureElementView methodsFor: 'accessing'!
X
XcollapsedTextChanged
X	^self!
X
XcreateViewForm
X	| form bBox trans |
X	bBox _ self displayBox.
X	form _ Form extent: (bBox extent rounded max: 0 @ 0).
X	trans _ WindowingTransformation identity scaleBy: self displayTransformation scale.
X	trans _ trans translateBy: (self displayTransform: model boundingBox origin)
X					- bBox origin.
X	model
X		displayOn: form
X		transformation: trans
X		clippingBox: (0 @ 0 extent: bBox extent)
X		rule: Form under
X		mask: Form black.
X	^form!
X
XpictureView
X	^self superView isNil
X		ifTrue: [^nil]
X		ifFalse: [self superView pictureView]! !
X
X!PictureElementView methodsFor: 'boundingBox'!
X
XdisplayWindow
X	^self displayTransform: self getWindow! !
X
X!PictureElementView methodsFor: 'updating'!
X
Xupdate: anAspect 
X	anAspect = #boundingBox
X		ifTrue: 
X			[self erase.
X			self flushCache.
X			self window: (model boundingBox expandBy: 2@2).
X			self draw]! !
X
XPictureElementView subclass: #PicElemGroupView
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemGroupView methodsFor: 'default controller access'!
X
XcollapsedTextChanged
X	^self flushCache!
X
XdefaultControllerClass
X	^PicElemGroupController! !
X
XPictureElementController subclass: #PicElemOvalController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemOvalController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\full\top\bottom\right\left\topLeft\topRight\bottomLeft\bottomRight\to bottom' withCRs lines: #(2 7 11))
X		yellowButtonMessages: #(cut copy full top bottom right left topLeft topRight bottomLeft bottomRight toBottom )! !
X
X!PicElemOvalController methodsFor: 'menu messages'!
X
Xbottom
X	model flushParts.
X	model addPart: #b.
X	view flushCache.
X	view draw!
X
XbottomLeft
X	model flushParts.
X	model addPart: #l.
X	model addPart: #b.
X	view flushCache.
X	view draw!
X
XbottomRight
X	model flushParts.
X	model addPart: #r.
X	model addPart: #b.
X	view flushCache.
X	view draw!
X
Xfull
X	model flushParts.
X	view flushCache.
X	view draw!
X
Xleft
X	model flushParts.
X	model addPart: #l.
X	view flushCache.
X	view draw!
X
Xright
X	model flushParts.
X	model addPart: #r.
X	view flushCache.
X	view draw!
X
Xtop
X	model flushParts.
X	model addPart: #t.
X	view flushCache.
X	view draw!
X
XtopLeft
X	model flushParts.
X	model addPart: #l.
X	model addPart: #t.
X	view flushCache.
X	view draw!
X
XtopRight
X	model flushParts.
X	model addPart: #r.
X	model addPart: #t.
X	view flushCache.
X	view draw! !
X
XPictureElementView subclass: #PicElemTextView
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemTextView methodsFor: 'controller access'!
X
XcollapsedTextChanged
X	^self flushCache!
X
XdefaultControllerClass
X	^PicElemTextController! !
X
XPictureElementController subclass: #PicElemTextController
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemTextController methodsFor: 'initialize-release'!
X
Xinitialize
X	super initialize.
X	self yellowButtonMenu: (PopUpMenu labels: 'cut\copy\change text\to bottom' withCRs)
X		yellowButtonMessages: #(cut copy changeText toBottom )! !
X
X!PicElemTextController methodsFor: 'menu messages'!
X
XchangeText
X	| text p |
X	text _ FillInTheBlank request: ' text: ' initialAnswer: model text copy.
X	text = '' asText ifTrue: [^self].
X	model changeText: text! !
X
XPictureElementView subclass: #PicElemFormView
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemFormView methodsFor: 'controller access'!
X
XdefaultControllerClass
X	^PicElemFormController! !
X
XPictureElementView subclass: #PicElemOvalView
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemOvalView methodsFor: 'controller access'!
X
XdefaultControllerClass
X	^PicElemOvalController! !
X
X!PicElemOvalView methodsFor: 'private'!
X
XcomputeQuadrantsFrom: parts 
X	parts size = 1
X		ifTrue: 
X			[(parts includes: #t)
X				ifTrue: [^#(2 1 )].
X			(parts includes: #b)
X				ifTrue: [^#(3 4 )].
X			(parts includes: #r)
X				ifTrue: [^#(1 4 )].
X			(parts includes: #l)
X				ifTrue: [^#(3 2 )]].
X	(parts includes: #t)
X		ifTrue: 
X			[(parts includes: #l)
X				ifTrue: [^#(2 )].
X			(parts includes: #r)
X				ifTrue: [^#(1 )]].
X	(parts includes: #b)
X		ifTrue: 
X			[(parts includes: #l)
X				ifTrue: [^#(3 )].
X			(parts includes: #r)
X				ifTrue: [^#(4 )]].
X	^#(1 2 3 4)! !
X
XPictureElementView subclass: #PicElemCircleView
X	instanceVariableNames: ''
X	classVariableNames: ''
X	poolDictionaries: ''
X	category: 'Pictures-Interface'!
X
X
X!PicElemCircleView methodsFor: 'controller access'!
X
XdefaultControllerClass
X	^PicElemCircleController! !
!Funky!Stuff!
echo x - readme.first
sed -e 's/^X//' > "readme.first" << '!Funky!Stuff!'
XWhen putting the archives together I found that the file picmod.st in the first archive has been truncated. Replace the truncated last method in picmod.st by:
X
X!PicElemGroup methodsFor: 'printing'!
X
XlatexOn: stream in: aPicture
X	| oldOrigin |
X	self elements do: 
X		[:elem | 
X		oldOrigin _ elem origin.
X		elem origin: elem origin + self origin.
X		elem
X			latexOn: stream
X			in: aPicture.
X		elem origin: oldOrigin]! !
X
XHope everything else will get throught.
X
XHubert
!Funky!Stuff!