implementation module ospicture
import StdBool, StdFunc, StdInt, StdList, StdReal, StdTuple
import pictCCall_12, osfont, ostypes
from osrgn import :: OSRgnHandle
from ostoolbox import OSNewToolbox
import StdPictureDef
from commondef import class toTuple(..), instance toTuple Point2, instance toTuple Vector2,
class subVector(..), instance subVector OSRect, setBetween
:: Picture
= { pictContext :: !OSPictContext // The context for drawing operations
, pictToolbox :: !.OSToolbox // The continuation value
, pictOrigin :: !Origin // The current origin of the picture
, pictPen :: !.Pen // The current state of the pen
, pictToScreen :: !Bool // Flag: the output goes to screen (True) or printer (False)
}
:: Origin
:== Point2
/* PA: moved to ostypes
:: OSPictContext
:== HDC
*/
:: Pen
= { penSize :: !Int // The width and height of the pen
, penForeColour :: !Colour // The drawing colour of the pen
, penBackColour :: !Colour // The background colour of the pen
, penPos :: !.Point2 // The pen position in local coordinates
, penFont :: !Font // The font information to draw text and characters
}
// Conversion operations to and from Picture
/*
initialisePicture :: !Origin !Pen !OSPictContext !*OSToolbox -> (!OSPictContext,!*OSToolbox)
initialisePicture origin pen=:{penSize,penForeColour,penBackColour,penPos,penFont} hdc tb
# {osfontname,osfontstyles,osfontsize} = osFontgetimp penFont
# (hdc,tb) = winInitPicture
penSize
iModeCopy
initforecolour
initbackcolour
initpen
(osfontname,osfontstyles,osfontsize)
(0,0)
(hdc,tb)
# (_,_,_,_,_,_,(hdc,tb)) = winDonePicture (hdc,tb)
= (hdc,tb)
where
initforecolour = toRGBtriple penForeColour
initbackcolour = toRGBtriple penBackColour
initpen = toTuple (penPos-origin)
*/
packPicture :: !Origin !*Pen !Bool !OSPictContext !*OSToolbox -> *Picture
packPicture origin pen=:{penSize,penForeColour,penBackColour,penPos,penFont} isScreenOutput hdc tb
#! {osfontname,osfontstyles,osfontsize}= osFontgetimp penFont
#! (hdc,tb) = winInitPicture
penSize
iModeCopy
initforecolour
initbackcolour
initpen
(osfontname,osfontstyles,osfontsize)
(0,0)
(hdc,tb)
= { pictContext = hdc
, pictToolbox = tb
, pictOrigin = origin
, pictPen = pen
, pictToScreen= isScreenOutput
}
where
initforecolour = toRGBtriple penForeColour
initbackcolour = toRGBtriple penBackColour
initpen = toTuple (penPos-origin)
unpackPicture :: !*Picture -> (!Origin,!*Pen,!Bool,!OSPictContext,!*OSToolbox)
unpackPicture {pictOrigin,pictPen,pictToScreen,pictContext,pictToolbox}
// PA: intend to use simplified version of winDonePicture; crashes for some reason.
// CS: done (cause of crash still unknown).
// # (_,_,_,_,_,_,(hdc,tb)) = winDonePicture (pictContext,pictToolbox)
# (hdc,tb) = winDonePicture (pictContext,pictToolbox)
= (pictOrigin,pictPen,pictToScreen,hdc,tb)
peekPicture :: !*Picture -> (!Origin,!*Pen,!Bool,!OSPictContext,!*OSToolbox)
peekPicture {pictOrigin,pictPen,pictToScreen,pictContext,pictToolbox}
= (pictOrigin,pictPen,pictToScreen,pictContext,pictToolbox)
unpeekPicture :: !Origin !*Pen !Bool !OSPictContext !*OSToolbox -> *Picture
unpeekPicture origin pen isScreenOutput hdc tb
= {pictOrigin=origin,pictPen=pen,pictToScreen=isScreenOutput,pictContext=hdc,pictToolbox=tb}
peekOSPictContext :: !*Picture -> (!OSPictContext,!*Picture)
peekOSPictContext picture=:{pictContext}
= (pictContext,picture)
sharePicture :: !*Picture -> (!Picture,!*Picture)
sharePicture picture=:{pictOrigin,pictPen,pictToScreen}
# (sPen,uPen) = sharePen pictPen
= ({pictContext=0,pictToolbox=OSNewToolbox,pictOrigin=pictOrigin,pictPen=sPen,pictToScreen=pictToScreen},{picture & pictPen=uPen})
sharePen :: !*Pen -> (!Pen,!*Pen)
sharePen pen=:{penSize,penForeColour,penBackColour,penPos,penFont}
# (sPenPos,uPenPos) = sharePoint penPos
= ({penSize=penSize,penForeColour=penForeColour,penBackColour=penBackColour,penPos=sPenPos,penFont=penFont},{pen & penPos=uPenPos})
where
sharePoint :: !*Point2 -> (!Point2,!*Point2)
sharePoint point=:{x,y} = ({x=x,y=y},point)
copyPen :: !Pen -> *Pen
copyPen {penSize,penForeColour,penBackColour,penPos={x,y},penFont}
= {penSize=penSize,penForeColour=penForeColour,penBackColour=penBackColour,penPos={x=x,y=y},penFont=penFont}
peekScreen :: !.(St *Picture .x) !*OSToolbox -> (!.x,!*OSToolbox)
peekScreen f tb
# (hdc,tb) = winCreateScreenHDC tb
# picture = packPicture zero defaultPen True hdc tb
# (x,picture) = f picture
# (_,_,_,hdc,tb)= unpackPicture picture
# tb = winDestroyScreenHDC (hdc,tb)
= (x,tb)
defaultPen :: *Pen
defaultPen
= { penSize = 1
, penForeColour = Black
, penBackColour = White
, penPos = {x=0,y=0}
, penFont = defaultFont
}
where
(defaultFont,_) = osDefaultfont OSNewToolbox
dialogPen :: *Pen
dialogPen
= { penSize = 1
, penForeColour = Black
, penBackColour = White
, penPos = {x=0,y=0}
, penFont = dialogFont
}
where
(dialogFont,_) = osDialogfont OSNewToolbox
setPenAttribute :: !PenAttribute !u:Pen -> u:Pen
setPenAttribute (PenSize size) pen = {pen & penSize =max 1 size}
setPenAttribute (PenPos {x,y}) pen = {pen & penPos ={x=x,y=y} }
setPenAttribute (PenColour colour) pen = {pen & penForeColour=colour }
setPenAttribute (PenBack colour) pen = {pen & penBackColour=colour }
setPenAttribute (PenFont font) pen = {pen & penFont =font }
/* Picture interface functions.
*/
apppicttoolbox :: !(IdFun *OSToolbox) !*Picture -> *Picture
apppicttoolbox f picture=:{pictToolbox}
= {picture & pictToolbox=f pictToolbox}
accpicttoolbox :: !(St *OSToolbox .x) !*Picture -> (!.x,!*Picture)
accpicttoolbox f picture=:{pictToolbox}
# (x,tb) = f pictToolbox
= (x,{picture & pictToolbox=tb})
/* Attribute functions.
*/
// Access to Origin and Pen:
getpictorigin :: !*Picture -> (!Origin,!*Picture)
getpictorigin picture=:{pictOrigin}
= (pictOrigin,picture)
setpictorigin :: !Origin !*Picture -> *Picture
setpictorigin origin picture
= {picture & pictOrigin=origin}
getpictpen :: !*Picture -> (!Pen,!*Picture)
getpictpen picture=:{pictPen}
# (sPen,uPen) = sharePen pictPen
= (sPen,{picture & pictPen=uPen})
setpictpen :: !Pen !*Picture -> *Picture
setpictpen {penSize,penForeColour,penBackColour,penPos,penFont} picture
# picture = setpictpensize penSize picture
# picture = setpictpencolour penForeColour picture
# picture = setpictbackcolour penBackColour picture
# picture = setpictpenpos penPos picture
# picture = setpictpenfont penFont picture
= picture
// Change the pen position:
setpictpenpos :: !Point2 !*Picture -> *Picture
setpictpenpos newpos=:{x=x`,y=y`} picture=:{pictToolbox,pictOrigin,pictPen=pen=:{penPos={x,y}},pictContext}
| x==x` && y==y`
= picture
| otherwise
# (context,tb) = winMovePenTo (toTuple (newpos-pictOrigin)) (pictContext,pictToolbox)
pen = {pen & penPos={x=x`,y=y`}}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
getpictpenpos :: !*Picture -> (!Point2,!*Picture)
getpictpenpos picture=:{pictPen={penPos={x,y}}}
= ({x=x,y=y},picture)
movepictpenpos :: !Vector2 !*Picture -> *Picture
movepictpenpos v=:{vx,vy} picture=:{pictToolbox,pictPen=pen=:{penPos={x,y}},pictContext}
# (context,tb) = winMovePen (toTuple v) (pictContext,pictToolbox)
pen = {pen & penPos={x=x+vx,y=y+vy}}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
// Change the pen size:
setpictpensize :: !Int !*Picture -> *Picture
setpictpensize w picture=:{pictToolbox,pictContext,pictPen}
| w`==pictPen.penSize
= picture
| otherwise
# (context,tb) = winSetPenSize w` (pictContext,pictToolbox)
pen = {pictPen & penSize=w`}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
where
w` = max 1 w
getpictpensize :: !*Picture -> (!Int,!*Picture)
getpictpensize picture=:{pictPen={penSize}}
= (penSize,picture)
// Change the PenColour:
setpictpencolour :: !Colour !*Picture -> *Picture
setpictpencolour colour picture=:{pictToolbox,pictPen,pictContext}
| reqRGB==curRGB
= picture
| otherwise
# (context,tb) = winSetPenColor reqRGB (pictContext,pictToolbox)
pen = {pictPen & penForeColour=colour}
= {picture & pictPen=pen,pictToolbox=tb,pictContext=context}
where
reqRGB = toRGBtriple colour
curRGB = toRGBtriple pictPen.penForeColour
setpictbackcolour :: !Colour !*Picture -> *Picture
setpictbackcolour colour picture=:{pictToolbox,pictPen,pictContext}
| reqRGB==curRGB
= picture
| otherwise
# (context,tb) = winSetBackColor (toRGBtriple colour) (pictContext,pictToolbox)
pen = {pictPen & penBackColour=colour}
= {picture & pictPen=pen,pictToolbox=tb,pictContext=context}
where
reqRGB = toRGBtriple colour
curRGB = toRGBtriple pictPen.penBackColour
toRGBtriple :: !Colour -> (!Int,!Int,!Int)
toRGBtriple (RGB {r,g,b}) = (setBetween r MinRGB MaxRGB,setBetween g MinRGB MaxRGB,setBetween b MinRGB MaxRGB)
toRGBtriple Black = (MinRGB,MinRGB,MinRGB)
toRGBtriple DarkGrey = ( MaxRGB>>2, MaxRGB>>2, MaxRGB>>2)
toRGBtriple Grey = ( MaxRGB>>1, MaxRGB>>1, MaxRGB>>1)
toRGBtriple LightGrey = ((MaxRGB>>2)*3,(MaxRGB>>2)*3,(MaxRGB>>2)*3)
toRGBtriple White = (MaxRGB,MaxRGB,MaxRGB)
toRGBtriple Red = (MaxRGB,MinRGB,MinRGB)
toRGBtriple Green = (MinRGB,MaxRGB,MinRGB)
toRGBtriple Blue = (MinRGB,MinRGB,MaxRGB)
toRGBtriple Cyan = (MinRGB,MaxRGB,MaxRGB)
toRGBtriple Magenta = (MaxRGB,MinRGB,MaxRGB)
toRGBtriple Yellow = (MaxRGB,MaxRGB,MinRGB)
getpictpencolour :: !*Picture -> (!Colour,!*Picture)
getpictpencolour picture=:{pictPen={penForeColour}}
= (penForeColour,picture)
getpictbackcolour :: !*Picture -> (!Colour,!*Picture)
getpictbackcolour picture=:{pictPen={penBackColour}}
= (penBackColour,picture)
// Change the font attributes:
setpictpenfont :: !Font !*Picture -> *Picture
setpictpenfont font picture=:{pictToolbox,pictContext,pictPen=pen}
| imp==osFontgetimp pen.penFont
= picture
| otherwise
# (context,tb) = winSetFont (osfontname,osfontstyles,osfontsize) (pictContext,pictToolbox)
pen = {pen & penFont=font}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
where
imp = osFontgetimp font
{osfontname,osfontstyles,osfontsize} = imp
getpictpenfont :: !*Picture -> (!Font,!*Picture)
getpictpenfont picture=:{pictPen={penFont}}
= (penFont,picture)
setpictpendefaultfont :: !*Picture -> *Picture
setpictpendefaultfont picture=:{pictToolbox,pictContext,pictPen}
# (font,tb) = osDefaultfont pictToolbox
{osfontname,osfontstyles,osfontsize}
= osFontgetimp font
# (context,tb) = winSetFont (osfontname,osfontstyles,osfontsize) (pictContext,tb)
pen = {pictPen & penFont=font}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
/* Drawing mode setting functions.
*/
setpictxormode :: !*Picture -> *Picture
setpictxormode picture=:{pictToolbox,pictContext}
# (context,tb) = winSetMode iModeXor (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
setpicthilitemode :: !*Picture -> *Picture
setpicthilitemode picture=:{pictToolbox,pictContext}
# (context,tb) = winSetMode iModeXor (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
setpictnormalmode :: !*Picture -> *Picture
setpictnormalmode picture=:{pictToolbox,pictContext}
# (context,tb) = winSetMode iModeCopy (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
/* Point2 drawing operations.
pictdrawpoint
only draws a point at that position. The pen position is not changed.
*/
pictdrawpoint :: !Point2 !*Picture -> *Picture
pictdrawpoint pos=:{x,y} picture=:{pictPen={penSize},pictOrigin={x=ox,y=oy},pictToolbox,pictContext}
| penSize==1
# (context,tb) = winDrawPoint (x`,y`) (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
| otherwise
# (context,tb) = winFillRectangle {rleft=x`,rtop=y`,rright=x`+penSize,rbottom=y`+penSize} (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
where
(x`,y`) = (x-ox,y-oy)
/* Line drawing operations.
pictdrawlineto
draws a line from the current pen position to the given pen position.
The new pen position is the endpoint of the line.
pictdrawline
draws a line from the first point to the second point. The pen position
is not changed.
*/
pictdrawlineto :: !Point2 !*Picture -> *Picture
pictdrawlineto pos=:{x,y} picture=:{pictOrigin,pictToolbox,pictContext,pictPen}
# (context,tb) = winLinePenTo (toTuple (pos-pictOrigin)) (pictContext,pictToolbox)
pen = {pictPen & penPos={x=x,y=y}}
= {picture & pictToolbox=tb,pictContext=context,pictPen=pen}
pictundrawlineto :: !Point2 !*Picture -> *Picture
pictundrawlineto pos=:{x,y} picture=:{pictOrigin,pictToolbox,pictContext,pictPen=pen=:{penForeColour,penBackColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winLinePenTo (toTuple (pos-pictOrigin)) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictToolbox=tb,pictContext=context,pictPen={pen & penPos={x=x,y=y}}}
pictdrawline :: !Point2 !Point2 !*Picture -> *Picture
pictdrawline a b picture=:{pictOrigin,pictToolbox,pictContext}
# (context,tb) = winDrawLine (toTuple (a-pictOrigin)) (toTuple (b-pictOrigin)) (pictContext,pictToolbox)
= {picture & pictToolbox=tb,pictContext=context}
pictundrawline :: !Point2 !Point2 !*Picture -> *Picture
pictundrawline a b picture=:{pictOrigin,pictToolbox,pictContext,pictPen={penForeColour,penBackColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawLine (toTuple (a-pictOrigin)) (toTuple (b-pictOrigin)) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictToolbox=tb,pictContext=context}
/* Text drawing operations.
pictdraw(char/string) draws a char/string at the current pen position. The new
pen position is immediately after the drawn char/string.
*/
pictdrawchar :: !Char !*Picture -> *Picture
pictdrawchar char picture=:{pictContext,pictToolbox,pictPen,pictOrigin}
# (context,tb) = winDrawChar (toInt char) (pictContext,pictToolbox)
# (x`,y`,context,tb)= winGetPenPos (context,tb)
#! {x,y} = pictOrigin
#! pen = {pictPen & penPos={x=x+x`,y=y+y`}}
= {picture & pictContext=context,pictToolbox=tb,pictPen=pen}
pictundrawchar :: !Char !*Picture -> *Picture
pictundrawchar char picture=:{pictContext,pictToolbox,pictPen=pen=:{penForeColour,penBackColour},pictOrigin={x=ox,y=oy}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawChar (toInt char) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
# (x,y,context,tb) = winGetPenPos (context,tb)
= {picture & pictContext=context,pictToolbox=tb,pictPen={pen & penPos={x=x+ox,y=y+oy}}}
pictdrawstring :: !String !*Picture -> *Picture
pictdrawstring string picture=:{pictContext,pictToolbox,pictPen,pictOrigin={x=ox,y=oy}} // PA:
# (context,tb) = winDrawString string (pictContext,pictToolbox)
# (x,y,context,tb) = winGetPenPos (context,tb)
pen = {pictPen & penPos={x=x+ox,y=y+oy}}
= {picture & pictContext=context,pictToolbox=tb,pictPen=pen}
pictundrawstring :: !String !*Picture -> *Picture
pictundrawstring string picture=:{pictContext,pictToolbox,pictPen=pen=:{penForeColour,penBackColour},pictOrigin={x=ox,y=oy}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawString string (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
# (x,y,context,tb) = winGetPenPos (context,tb)
= {picture & pictContext=context,pictToolbox=tb,pictPen={pen & penPos={x=x+ox,y=y+oy}}}
/* Oval drawing operations.
pict(draw/fill)oval center oval
draws/fills an oval at center with horizontal and vertical radius. The new
pen position is not changed.
*/
pictdrawoval :: !Point2 !Oval !*Picture -> *Picture
pictdrawoval center oval picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winDrawOval rect (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
where
rect = ovalToRect (center-pictOrigin) oval
pictundrawoval :: !Point2 !Oval !*Picture -> *Picture
pictundrawoval center oval picture=:{pictContext,pictToolbox,pictOrigin,pictPen={penBackColour,penForeColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawOval rect (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictContext=context,pictToolbox=tb}
where
rect = ovalToRect (center-pictOrigin) oval
pictfilloval :: !Point2 !Oval !*Picture -> *Picture
pictfilloval center oval picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winFillOval rect (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
where
rect = ovalToRect (center-pictOrigin) oval
pictunfilloval :: !Point2 !Oval !*Picture -> *Picture
pictunfilloval center oval picture=:{pictContext,pictToolbox,pictOrigin,pictPen}
# (context,tb) = winEraseOval rect (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
where
rect = ovalToRect (center-pictOrigin) oval
ovalToRect :: !Point2 !Oval -> OSRect
ovalToRect {x,y} {oval_rx,oval_ry}
= {rleft=x-rx,rtop=y-ry,rright=x+rx,rbottom=y+ry}
where
rx = abs oval_rx
ry = abs oval_ry
/* Curve drawing operations.
pict(draw/fill)curve movePen point curve
draws/fills a curve starting at point with a shape defined by curve. If movePen
is True, then the new pen position is at the end of the curve, otherwise it does
not change.
*/
pictdrawcurve :: !Bool !Point2 !Curve !*Picture -> *Picture
pictdrawcurve movePen start=:{x,y} curve picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winDrawCurve wrect (toTuple wstart) (toTuple wend) (pictContext,pictToolbox)
# picture = {picture & pictContext=context,pictToolbox=tb}
| not movePen = picture
| otherwise = setpictpenpos end picture
where
start` = start-pictOrigin
(wrect,wstart,wend) = getcurve_rect_begin_end start` curve
end = wend+pictOrigin
pictundrawcurve :: !Bool !Point2 !Curve !*Picture -> *Picture
pictundrawcurve movePen start=:{x,y} curve picture=:{pictContext,pictToolbox,pictOrigin,pictPen={penForeColour,penBackColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawCurve wrect (toTuple wstart) (toTuple wend) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
# picture = {picture & pictContext=context,pictToolbox=tb}
| not movePen = picture
| otherwise = setpictpenpos end picture
where
start` = start-pictOrigin
(wrect,wstart,wend) = getcurve_rect_begin_end start` curve
end = wend+pictOrigin
pictfillcurve :: !Bool !Point2 !Curve !*Picture -> *Picture
pictfillcurve movePen start curve picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winFillWedge wrect (toTuple wstart) (toTuple wend) (pictContext,pictToolbox)
# picture = {picture & pictContext=context,pictToolbox=tb}
| not movePen = picture
| otherwise = setpictpenpos end picture
where
start` = start-pictOrigin
(wrect,wstart,wend) = getcurve_rect_begin_end start` curve
end = wend+pictOrigin
pictunfillcurve :: !Bool !Point2 !Curve !*Picture -> *Picture
pictunfillcurve movePen start curve picture=:{pictContext,pictToolbox,pictOrigin,pictPen={penForeColour,penBackColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winFillWedge wrect (toTuple wstart) (toTuple wend) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
# picture = {picture & pictContext=context,pictToolbox=tb}
| not movePen = picture
| otherwise = setpictpenpos end picture
where
start` = start-pictOrigin
(wrect,wstart,wend) = getcurve_rect_begin_end start` curve
end = wend+pictOrigin
getcurve_rect_begin_end :: !Point2 !Curve -> (!OSRect,!Point2,!Point2)
getcurve_rect_begin_end start=:{x,y} {curve_oval={oval_rx,oval_ry},curve_from,curve_to,curve_clockwise}
| curve_clockwise = (rect,end,start)
| otherwise = (rect,start,end)
where
rx` = toReal (abs oval_rx)
ry` = toReal (abs oval_ry)
cx = x -(toInt ((cos curve_from)*rx`))
cy = y +(toInt ((sin curve_from)*ry`))
ex = cx+(toInt ((cos curve_to )*rx`))
ey = cy-(toInt ((sin curve_to )*ry`))
end = {x=ex,y=ey}
rect = {rleft=cx-oval_rx,rtop=cy-oval_ry,rright=cx+oval_rx,rbottom=cy+oval_ry}
/* OSRect drawing operations.
pict(draw/fill)rect rect
draws/fills a rect. The pen position is not changed.
*/
pictdrawrect :: !OSRect !*Picture -> *Picture
pictdrawrect r picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winDrawRectangle (subVector (toVector pictOrigin) r) (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
pictundrawrect :: !OSRect !*Picture -> *Picture
pictundrawrect r picture=:{pictContext,pictToolbox,pictOrigin,pictPen={penForeColour,penBackColour}}
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,pictToolbox)
# (context,tb) = winDrawRectangle (subVector (toVector pictOrigin) r) (context,tb)
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictContext=context,pictToolbox=tb}
pictfillrect :: !OSRect !*Picture -> *Picture
pictfillrect r picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winFillRectangle (subVector (toVector pictOrigin) r) (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
pictunfillrect :: !OSRect !*Picture -> *Picture
pictunfillrect r picture=:{pictContext,pictToolbox,pictOrigin}
# (context,tb) = winEraseRectangle (subVector (toVector pictOrigin) r) (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
/* Scrolling operation (handle with care).
*/
pictscroll :: !OSRect !Vector2 !*Picture -> (!OSRect,!*Picture)
pictscroll r v picture=:{pictContext,pictToolbox,pictOrigin}
# (updRect,(context,tb)) = winScrollRectangle (subVector (toVector pictOrigin) r) (toTuple v) (pictContext,pictToolbox)
= (updRect,{picture & pictContext=context,pictToolbox=tb})
pictscroll2 :: !OSRect !Vector2 !*Picture -> (!OSRect,!*Picture)
pictscroll2 r v picture=:{pictContext,pictToolbox,pictOrigin}
# (updRect,(context,tb)) = winScrollRectangle2 (subVector (toVector pictOrigin) r) (toTuple v) (pictContext,pictToolbox)
= (updRect,{picture & pictContext=context,pictToolbox=tb})
/* Polygon drawing operations.
pict(draw/fill)polygon point polygon
draws/fills a polygon starting at point. The pen position is not changed.
*/
pictdrawpolygon :: !Point2 !Polygon !*Picture -> *Picture
pictdrawpolygon start {polygon_shape} picture=:{pictContext,pictToolbox,pictOrigin}
# tb = transferPolygon (start-pictOrigin) polygon_shape pictToolbox
# (context,tb) = winDrawPolygon (pictContext,tb)
# tb = winEndPolygon tb
= {picture & pictContext=context,pictToolbox=tb}
pictundrawpolygon :: !Point2 !Polygon !*Picture -> *Picture
pictundrawpolygon start {polygon_shape} picture=:{pictContext,pictToolbox,pictOrigin,pictPen={penForeColour,penBackColour}}
# tb = transferPolygon (start-pictOrigin) polygon_shape pictToolbox
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,tb)
# (context,tb) = winDrawPolygon (context,tb)
# tb = winEndPolygon tb
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictContext=context,pictToolbox=tb}
pictfillpolygon :: !Point2 !Polygon !*Picture -> *Picture
pictfillpolygon start {polygon_shape} picture=:{pictPen={penSize},pictContext,pictToolbox,pictOrigin}
# tb = transferPolygon (start-pictOrigin) polygon_shape pictToolbox
# (context,tb) = winSetPenSize 1 (pictContext,tb)
# (context,tb) = winFillPolygon (context,tb)
# (context,tb) = winDrawPolygon (context,tb)
# (context,tb) = winSetPenSize penSize (context,tb)
# tb = winEndPolygon tb
= {picture & pictContext=context,pictToolbox=tb}
pictunfillpolygon :: !Point2 !Polygon !*Picture -> *Picture
pictunfillpolygon start {polygon_shape} picture=:{pictPen={penSize,penForeColour,penBackColour},pictContext,pictToolbox,pictOrigin}
# tb = transferPolygon (start-pictOrigin) polygon_shape pictToolbox
# (context,tb) = winSetPenColor (toRGBtriple penBackColour) (pictContext,tb)
# (context,tb) = winSetPenSize 1 (context,tb)
# (context,tb) = winFillPolygon (context,tb)
# (context,tb) = winDrawPolygon (context,tb)
# (context,tb) = winSetPenSize penSize (context,tb)
# tb = winEndPolygon tb
# (context,tb) = winSetPenColor (toRGBtriple penForeColour) (context,tb)
= {picture & pictContext=context,pictToolbox=tb}
transferPolygon :: !Point2 ![Vector2] !*OSToolbox -> *OSToolbox
transferPolygon start vs tb
# tb = winStartPolygon (1 + length vs) tb
# tb = winAddPolygonPoint wstart tb
# tb = transferShape wstart vs tb
= tb
where
wstart = toTuple start
transferShape :: !(!Int,!Int) ![Vector2] !*OSToolbox -> *OSToolbox
transferShape (x,y) [{vx,vy}:vs] tb
= transferShape newpos vs (winAddPolygonPoint newpos tb)
where
newpos = (x+vx,y+vy)
transferShape _ _ tb
= tb
/* Clipping operations.
pictgetcliprgn gets the current clipping region.
pictsetcliprgn sets the given clipping region.
pictandcliprgn takes the intersection of the current clipping region and the argument region.
*/
pictgetcliprgn :: !*Picture -> (!OSRgnHandle,!*Picture)
pictgetcliprgn picture=:{pictContext,pictToolbox}
# (cliprgn,(context,tb)) = winGetClipRgnPicture (pictContext,pictToolbox)
= (cliprgn,{picture & pictContext=context,pictToolbox=tb})
pictsetcliprgn :: !OSRgnHandle !*Picture -> *Picture
pictsetcliprgn cliprgn picture=:{pictContext,pictToolbox}
# (context,tb) = winSetClipRgnPicture cliprgn (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
pictandcliprgn :: !OSRgnHandle !*Picture -> *Picture
pictandcliprgn cliprgn picture=:{pictContext,pictToolbox}
# (context,tb) = winClipRgnPicture cliprgn (pictContext,pictToolbox)
= {picture & pictContext=context,pictToolbox=tb}
/* Resolution access function (added by MW):
*/
getResolutionC :: !OSPictContext !*OSToolbox -> (!(!Int,!Int),!*OSToolbox)
getResolutionC _ _
= code {
ccall getResolutionC "I:VII:I"
}
// MW: scaling of screen coordinates to printer coordinates.
getPictureScalingFactors :: !OSPictContext !*OSToolbox -> (!(!Int,!Int),!(!Int,!Int),!OSPictContext,!*OSToolbox)
getPictureScalingFactors _ _
= code
{
ccall WinGetPictureScaleFactor "II-IIIIII"
}
getpictpenattributes :: !*Picture -> (![PenAttribute],!*Picture)
getpictpenattributes picture
# (pen,picture) = getpictpen picture
= (getpenattribute pen,picture)
where
getpenattribute :: !Pen -> [PenAttribute]
getpenattribute {penSize,penForeColour,penBackColour,penPos,penFont}
= [PenSize penSize,PenPos penPos,PenColour penForeColour,PenBack penBackColour,PenFont penFont]
getPenPenPos :: !*Pen -> (!Point2,!*Pen)
getPenPenPos pen=:{penPos={x,y}} = ({x=x,y=y},pen)