%! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @(#)handy.ps % % Handy Pointer % Copyright (C) 1989. % By Don Hopkins. (don@brillig.umd.edu) % All rights reserved. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This program is provided for UNRESTRICTED use provided that this % copyright message is preserved on all copies and derivative works. % This is provided without any warranty. No author or distributor % accepts any responsibility whatsoever to any person or any entity % with respect to any loss or damage caused or alleged to be caused % directly or indirectly by this program. This includes, but is not % limited to, any interruption of service, loss of business, loss of % information, loss of anticipated profits, core dumps, abuses of the % virtual memory system, or any consequential or incidental damages % resulting from the use of this program. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin systemdict /XNeWS? known not { systemdict /XNeWS? false put } if XNeWS? { /controlpoint { pop lineto } def } if /pointing-hand { 0 0.0674 moveto open-pointing-hand closepath } def /open-pointing-hand { 0 0.528 .5 controlpoint 0.008 0.535 .5 controlpoint 0.0292 0.553 .5 controlpoint 0.096 0.618 .5 controlpoint 0.1553 0.694 .5 controlpoint 0.208 0.753 .5 controlpoint 0.241 0.7773 .5 controlpoint 0.264 0.7883 .5 controlpoint 0.28 0.798 .5 controlpoint 0.3224 0.824 .5 controlpoint 0.368 0.8651 .5 controlpoint 0.3952 0.898 .5 controlpoint 0.424 0.933 .5 controlpoint 0.443 0.975 .5 controlpoint 0.456 1 .5 controlpoint 0.482 0.9862 .5 controlpoint 0.496 0.933 .5 controlpoint 0.499 0.8721 .5 controlpoint 0.488 0.8202 .5 controlpoint 0.475 0.78 .5 controlpoint 0.467 0.753 .5 controlpoint 0.448 0.708 .5 controlpoint 0.408 0.673 .5 controlpoint 0.384 0.663 .5 controlpoint 0.408 0.652 .5 controlpoint 0.4212 0.652 .5 controlpoint 0.448 0.652 .5 controlpoint 0.465 0.652 .5 controlpoint 0.4934 0.652 .5 controlpoint 0.5121 0.652 .5 controlpoint 0.5334 0.652 .5 controlpoint 0.5574 0.652 .5 controlpoint 0.584 0.652 .5 controlpoint 0.6331 0.653 .5 controlpoint 0.679 0.6502 .5 controlpoint 0.744 0.6404 .5 controlpoint 0.8094 0.635 .5 controlpoint 0.888 0.618 .5 controlpoint 0.9064 0.6132 .5 controlpoint 0.929 0.608 .5 controlpoint 0.968 0.596 .5 controlpoint 0.991 0.5731 .5 controlpoint 1 0.551 .5 controlpoint 0.9854 0.5021 .5 controlpoint 0.968 0.4831 .5 controlpoint 0.926 0.481 .5 controlpoint 0.88 0.472 .5 controlpoint 0.853 0.4744 .5 controlpoint 0.8351 0.476 .5 controlpoint 0.8162 0.478 .5 controlpoint 0.76 0.4831 .5 controlpoint 0.741 0.4823 .5 controlpoint 0.718 0.4831 .5 controlpoint 0.696 0.484 .5 controlpoint 0.68 0.4831 .5 controlpoint 0.69 0.481 .5 controlpoint 0.72 0.461 .5 controlpoint 0.742 0.448 .5 controlpoint 0.752 0.427 .5 controlpoint 0.752 0.406 .5 controlpoint 0.752 0.382 .5 controlpoint 0.736 0.3483 .5 controlpoint 0.721 0.334 .5 controlpoint 0.704 0.326 .5 controlpoint 0.688 0.326 .5 controlpoint 0.6964 0.325 .5 controlpoint 0.72 0.2921 .5 controlpoint 0.7164 0.255 .5 controlpoint 0.704 0.2134 .5 controlpoint 0.6654 0.1972 .5 controlpoint 0.632 0.191 .5 controlpoint 0.608 0.191 .5 controlpoint 0.6152 0.166 .5 controlpoint 0.624 0.124 .5 controlpoint 0.6 0.09 .5 controlpoint 0.568 0.0561 .5 controlpoint 0.55 0.059 .5 controlpoint 0.525 0.0582 .5 controlpoint 0.502 0.057 .5 controlpoint 0.488 0.0561 .5 controlpoint 0.4761 0.057 .5 controlpoint 0.4564 0.0512 .5 controlpoint 0.416 0.034 .5 controlpoint 0.349 0.013 .5 controlpoint 0.288 0 .5 controlpoint 0.2224 0.007 .5 controlpoint 0.202 0.008 .5 controlpoint 0.183 0.009 .5 controlpoint 0.16 0.0112 .5 controlpoint 0.1222 0.0291 .5 controlpoint 0.08 0.045 .5 controlpoint 0.041 0.0593 .5 controlpoint 0 0.0674 .5 controlpoint } def /pointing-fingers { 0.408 0.9101 moveto 0.414 0.9104 .5 controlpoint 0.432 0.9213 .5 controlpoint 0.456 0.955 .5 controlpoint 0.464 0.989 .5 controlpoint 0.464 1 .5 controlpoint 0.68 0.4831 moveto 0.657 0.484 .5 controlpoint 0.638 0.4841 .5 controlpoint 0.624 0.4831 .5 controlpoint 0.6054 0.4801 .5 controlpoint 0.5864 0.4764 .5 controlpoint 0.5682 0.4732 .5 controlpoint 0.552 0.472 .5 controlpoint 0.535 0.477 .5 controlpoint 0.5144 0.482 .5 controlpoint 0.4951 0.4844 .5 controlpoint 0.48 0.4831 .5 controlpoint 0.456 0.4382 .5 controlpoint 0.4604 0.409 .5 controlpoint 0.48 0.382 .5 controlpoint 0.51 0.37 .5 controlpoint 0.5281 0.3704 .5 controlpoint 0.544 0.371 .5 controlpoint 0.5734 0.3574 .5 controlpoint 0.6 0.3483 .5 controlpoint 0.6254 0.341 .5 controlpoint 0.648 0.337 .5 controlpoint 0.675 0.3303 .5 controlpoint 0.688 0.326 .5 controlpoint 0.472 0.472 moveto 0.48 0.472 .5 controlpoint 0.4954 0.472 .5 controlpoint 0.52 0.472 .5 controlpoint 0.537 0.453 .5 controlpoint 0.544 0.427 .5 controlpoint 0.512 0.382 .5 controlpoint 0.487 0.388 .5 controlpoint 0.472 0.3932 .5 controlpoint 0.528 0.371 moveto 0.5164 0.3683 .5 controlpoint 0.496 0.36 .5 controlpoint 0.4782 0.358 .5 controlpoint 0.464 0.3483 .5 controlpoint 0.452 0.311 .5 controlpoint 0.464 0.27 .5 controlpoint 0.483 0.25 .5 controlpoint 0.512 0.236 .5 controlpoint 0.5432 0.217 .5 controlpoint 0.576 0.2022 .5 controlpoint 0.596 0.195 .5 controlpoint 0.608 0.191 .5 controlpoint 0.464 0.27 moveto 0.488 0.27 .5 controlpoint 0.505 0.2643 .5 controlpoint 0.52 0.27 .5 controlpoint 0.536 0.2921 .5 controlpoint 0.5294 0.314 .5 controlpoint 0.52 0.337 .5 controlpoint 0.5062 0.349 .5 controlpoint 0.488 0.3483 .5 controlpoint 0.464 0.3483 .5 controlpoint 0.52 0.225 moveto 0.496 0.236 .5 controlpoint 0.47 0.2334 .5 controlpoint 0.448 0.225 .5 controlpoint 0.432 0.191 .5 controlpoint 0.442 0.164 .5 controlpoint 0.464 0.135 .5 controlpoint 0.48 0.124 .5 controlpoint 0.496 0.1123 .5 controlpoint 0.5192 0.1042 .5 controlpoint 0.544 0.09 .5 controlpoint 0.552 0.09 .5 controlpoint 0.472 0.225 moveto 0.488 0.225 .5 controlpoint 0.512 0.2022 .5 controlpoint 0.512 0.169 .5 controlpoint 0.496 0.157 .5 controlpoint 0.472 0.1573 .5 controlpoint 0.45 0.162 .5 controlpoint 0.44 0.169 .5 controlpoint 0.392 0.652 moveto 0.3811 0.6531 .5 controlpoint 0.36 0.6404 .5 controlpoint 0.328 0.5842 .5 controlpoint } def /fingertip-y .551 def % finger tip @ (1, fingertip-y) /pointer-path { % fx fy tx ty size fingers? => - 10 dict begin /fingers? exch def /size exch def /ty exch def /tx exch def /fy exch def /fx exch def /dx tx fx sub def /dy ty fy sub def /ang dy dx 2 copy 0 eq exch 0 eq and { pop pop 0 } { atan } ifelse def /mat matrix currentmatrix def fx fy moveto tx ty translate ang rotate size dup .75 mul scale -1 fingertip-y neg translate % finger tip to 0,0 open-pointing-hand closepath fingers? { pointing-fingers } if mat setmatrix end % localdict } def /get-pointer { % - => FromX FromY ToX ToY fboverlay setcanvas getclick /FromY exch def /FromX exch def FromX FromY { x0 y0 x y 64 false pointer-path stroke } getanimated waitprocess aload pop /ToY exch def /ToX exch def FromX FromY ToX ToY } def /get-pointer-to { % ToX ToY - => ToX ToY Direction Distance fboverlay setcanvas /ToY exch def /ToX exch def ToX ToY { pop pop x y x0 y0 64 false pointer-path stroke } getanimated waitprocess aload pop /FromY exch def /FromX exch def ToX ToY ToY FromY sub ToX FromX sub 2 copy 2 copy 0 eq exch 0 eq and { pop pop 0 } { atan } ifelse 3 1 roll dup mul exch dup mul add sqrt } def %/UseOverlay? systemdict /OverlayWindow known def /UseOverlay? systemdict /fb_enable known def /PointWindow UseOverlay? { OverlayWindow } { DefaultWindow } ifelse dictbegin /Strings [(That)] def /Font /Helvetica-Bold findfont 14 scalefont def /LineHeight 20 def /Margin 8 def /Distance 0 def /Angle 0 def /TipX 0 def /TipY 0 def /EndX 0 def /EndY 0 def /X null def /Y null def /Width null def /Height null def /FrameRadius 6 def /BorderTop 4 def /BorderBottom 4 def /BorderLeft 4 def /BorderRight 4 def /Hand? true def dictend classbegin /HandColors [ /orange /wheat /pink /plum /yellow /brown /firebrick /salmon /khaki /sienna /coral /gold /tan /goldenrod /gray /green /mediumgoldenrod ] def UseOverlay? framebuffer /Color get not or { /HandColor .75 .75 .75 rgbcolor def /BackgroundColor 1 1 1 rgbcolor def /FrameBorderColor 0 0 0 rgbcolor def /TextColor 0 0 0 rgbcolor def } { /HandColor { HandColors dup length random mul floor cvi get ColorDict exch get self /HandColor 2 index put } def /BackgroundColor ColorDict /LightSteelBlue get def /FrameBorderColor ColorDict /DarkSlateBlue get def /TextColor ColorDict /Yellow get def } ifelse UseOverlay? not { /FullColor {} def } { /FullColor { gsave EnableCanvas setcanvas 0 fillcanvas grestore } def /CreateClientCanvas { /CreateClientCanvas super send %ColorCanvas /Retained false put ColorCanvas /Transparent true put framebuffer /Color get { %FrameCanvas /Retained false put % FrameCanvas /Transparent true put } if } def } ifelse /HandHeight 64 def /HandWidth 80 def /setmessage { % str | [str str ...] => - dup type /arraytype ne { [ exch ] } if /Strings exch store } def /minsize { % - => w h gsave framebuffer setcanvas Font setfont 0 Strings { stringwidth pop max } forall Margin dup add add BorderLeft add BorderRight add Strings length LineHeight mul Margin dup add add BorderTop add BorderBottom add grestore } def /reshape { % x y w h => - /FrameHeight exch def /FrameWidth exch def /FrameY exch def /FrameX exch def /EndX FrameX FrameWidth 2 div add def /EndY FrameY FrameHeight 2 div add def FrameX FrameY FrameWidth FrameHeight /reshape super send gsave framebuffer setcanvas FrameCanvas getcanvaslocation /dy exch FrameY sub def /dx exch FrameX sub def %(X % Y % dx % dy %\n) [FrameX FrameY dx dy] dbgprintf grestore } def /slide { /Hand? false def FrameX FrameY FrameWidth FrameHeight reshape /slide super send } def /slideconstrained { /Hand? false def FrameX FrameY FrameWidth FrameHeight reshape /slideconstrained super send } def /FramePath { %FrameRadius 5 1 roll % r x y w h %3 -1 roll 1 index add 3 1 roll neg % r x y+h w -h %rrectpath % X11/NeWS: This makes inside-out corners! Fix! rectpath Hand? { EndX FrameX sub EndY FrameY sub TipX FrameX sub TipY FrameY sub HandHeight false pointer-path closepath } if } def /ClientPath { % - => - ([Re]set client canvas' shape) FrameCanvas setcanvas clippath } def /PaintFrame { % ClientCanvas setcanvas UseOverlay? { EnableCanvas setcanvas 0 fillcanvas OverlayCanvas setcanvas } if Hand? { HandColor fillcanvas newpath EndX FrameX sub EndY FrameY sub TipX FrameX sub TipY FrameY sub HandHeight true pointer-path closepath FrameBorderColor setcolor stroke } if %FrameRadius 0 0 FrameWidth FrameHeight rrectpath 0 0 FrameWidth FrameHeight rectpath FrameRadius BorderLeft BorderBottom FrameWidth BorderLeft sub BorderRight sub FrameHeight BorderBottom sub BorderTop sub rrectpath %FrameBorderColor setcolor eofill HandColor setcolor eofill FrameRadius BorderLeft BorderBottom FrameWidth BorderLeft sub BorderRight sub FrameHeight BorderBottom sub BorderTop sub rrectpath BackgroundColor setcolor fill } def /PaintClient { gsave UseOverlay? { FullOverlay OverlayCanvas setcanvas } if Margin ClientHeight Margin 2 div sub translate TextColor setcolor Font setfont Strings { 0 LineHeight neg translate 0 0 moveto show } forall grestore } def /PaintFocus {} def /point { % tipx tipy angle distance => - /Distance exch def /Angle exch def /TipY exch def /TipX exch def % Back off a couple points so you can see what I'm pointing at, % and so the cursor is still in the same canvas. /dx Angle cos neg def /dy Angle sin neg def /TipX TipX dx dup add sub def /TipY TipY dy dup add sub def minsize % w h /Height exch def /Width exch def % /Distance Height Width max 2 div Distance add def % /EndX TipX Distance Width add dx mul add def % /EndY TipY Distance Height add dy mul add def /EndX TipX Distance dx mul add def /EndY TipY Distance dy mul add def /X EndX Width 2 div sub def /Y EndY Height 2 div sub def X Y Width Height reshape } def /PaintLabel { } def /move { /Hand? true def FrameWidth FrameHeight reshape } def classend def /pointmsg { % tipx tipy ang dist strings => process { 10 dict begin newprocessgroup /win framebuffer /new PointWindow send def /setmessage win send /point win send /map win send end } fork 5 1 roll 5 { pop } repeat } def end % systemdict %get-pointer %FromX FromY (From) popmsg pop %ToX ToY (To) popmsg pop