home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1997-04-23 | 16.6 KB | 558 lines | [TEXT/3PRM] |
- implementation module Picture;
-
- //
- // Drawing functions and other operations on Pictures.
- //
-
- import StdClass,StdBool, StdInt, StdReal;
- import quickdraw, fonts, pointer;
- import font, commonDef;
-
-
- :: *Picture :== * Int;
- :: DrawFunction :== Picture -> Picture;
-
- // The predefined figures that can be drawn:
-
- :: Point :== (!Int, !Int);
- :: Line :== (!Point, !Point);
- :: Curve :== (!Oval, !Int, !Int);
- :: Rectangle :== (!Point, !Point);
- :: RoundRectangle :== (!Rectangle, !Int, !Int);
- :: Oval :== Rectangle;
- :: Circle :== (!Point, !Int);
- :: Wedge :== (!Oval, !Int, !Int);
- :: Polygon :== (!Point, !PolygonShape);
-
- :: PolygonShape :== [Vector];
- :: Vector :== (!Int, !Int);
-
-
- // The pen attributes which influence the way figures are drawn:
-
- :: PenSize :== (!Int, !Int);
- :: PenMode = CopyMode | OrMode | XorMode | ClearMode | HiliteMode
- | NotCopyMode | NotOrMode | NotXorMode | NotClearMode;
- :: PenPattern = BlackPattern
- | DkGreyPattern
- | GreyPattern
- | LtGreyPattern
- | WhitePattern;
-
-
- // The colours:
-
- :: Colour = RGB Real Real Real
- | BlackColour | RedColour
- | WhiteColour | GreenColour
- | BlueColour | YellowColour
- | CyanColour | MagentaColour;
-
-
- PI :== 3.1415926535898;
- MinRGB :== 0.0;
- MaxRGB :== 1.0;
-
-
- // Conversion of Toolbox to Picture and vise versa.
-
- NewPicture :: Picture;
- NewPicture = 0;
-
- MakePicture :: !Toolbox -> Picture;
- MakePicture picture = picture;
-
- MakeMacPicture :: !Picture -> Toolbox;
- MakeMacPicture picture = picture;
-
-
- // Calculations with rects and regions.
-
- Rect_in_region :: !Rectangle !RgnHandle !Toolbox -> (!Bool, !Toolbox);
- Rect_in_region ((l,t),(r,b)) updRgn tb
- = (not empty, tb7);
- where {
- (newRgn, tb1) = QNewRgn tb;
- tb2 = QRectRgn newRgn (l,t,r,b) tb1;
- (resRgn, tb3) = QNewRgn tb2;
- (sectRgn,tb4) = QSectRgn newRgn updRgn resRgn tb3;
- (empty, tb5) = QEmptyRgn sectRgn tb4;
- tb6 = QDisposeRgn newRgn tb5;
- tb7 = QDisposeRgn sectRgn tb6;
- };
-
-
- // Rules setting the attributes of a Picture:
-
- SetPenSize :: !PenSize !Picture -> Picture;
- SetPenSize (w,h) p = QPenSize w h p;
-
- SetPenMode :: !PenMode !Picture -> Picture;
- SetPenMode CopyMode p = QPenMode PatCopy (QTextMode SrcCopy p);
- SetPenMode OrMode p = QPenMode PatOr (QTextMode SrcOr p);
- SetPenMode XorMode p = QPenMode PatXor (QTextMode SrcXor p);
- SetPenMode ClearMode p = QPenMode PatBic (QTextMode SrcBic p);
- SetPenMode NotCopyMode p = QPenMode NotPatCopy (QTextMode SrcOr p);
- SetPenMode NotOrMode p = QPenMode NotPatOr (QTextMode SrcOr p);
- SetPenMode NotXorMode p = QPenMode NotPatXor (QTextMode SrcOr p);
- SetPenMode NotClearMode p = QPenMode NotPatBic (QTextMode SrcOr p);
- SetPenMode HiliteMode p
- | hasColorQD = QPenMode PatHilite (QTextMode PatHilite p1);
- = QPenMode PatXor (QTextMode SrcOr p1);
- where {
- (hasColorQD, p1) = HasColorQD p;
- };
-
- SetPenPattern :: !PenPattern !Picture -> Picture;
- SetPenPattern BlackPattern p = QPenPat Black p;
- SetPenPattern DkGreyPattern p = QPenPat DkGray p;
- SetPenPattern GreyPattern p = QPenPat Gray p;
- SetPenPattern LtGreyPattern p = QPenPat LtGray p;
- SetPenPattern WhitePattern p = QPenPat White p;
-
- SetPenNormal :: !Picture -> Picture;
- SetPenNormal p = QPenNormal (QTextMode SrcOr p);
-
-
- // Using colours:
-
- SetPenColour :: !Colour !Picture -> Picture;
- SetPenColour colour=:(RGB rd gr bl) p
- | hasColorQD = QRGBForeColor (RealToRGB rd, RealToRGB gr, RealToRGB bl) p1;
- = QForeColor (ColourToNormalColor colour) p1;
- where {
- (hasColorQD, p1) = HasColorQD p;
- };
- SetPenColour colour p = QForeColor (ColourToNormalColor colour) p;
-
- SetBackColour :: !Colour !Picture -> Picture;
- SetBackColour colour=:(RGB rd gr bl) p
- | hasColorQD = QRGBBackColor (RealToRGB rd, RealToRGB gr, RealToRGB bl) p1;
- = QBackColor (ColourToNormalColor colour) p1;
- where {
- (hasColorQD, p1) = HasColorQD p;
- };
- SetBackColour colour p = QBackColor (ColourToNormalColor colour) p;
-
- RealToRGB :: !Real -> Int;
- RealToRGB real | real >= MaxRGB = 65535;
- | real <= MinRGB = 0;
- = toInt (real * 65535.0);
-
- ColourToNormalColor :: !Colour -> Int;
- ColourToNormalColor BlackColour = BlackColor;
- ColourToNormalColor RedColour = RedColor;
- ColourToNormalColor WhiteColour = WhiteColor;
- ColourToNormalColor GreenColour = GreenColor;
- ColourToNormalColor BlueColour = BlueColor;
- ColourToNormalColor YellowColour = YellowColor;
- ColourToNormalColor CyanColour = CyanColor;
- ColourToNormalColor MagentaColour = MagentaColor;
- ColourToNormalColor (RGB MaxRGB MaxRGB MaxRGB) = WhiteColor;
- ColourToNormalColor _ = BlackColor;
-
-
- // Using fonts:
-
- SetFont :: !Font !Picture -> Picture;
- SetFont font p
- = QTextFace (StyleToStyleID style) (QTextSize size (QTextFont nr p));
- where {
- (nr, name, style, size) = FontAtts font;
- };
-
- SetFontName :: !FontName !Picture -> Picture;
- SetFontName name p = QTextFont fontNum p1;
- where {
- (fontNum, p1) = GetFNum name p;
- };
-
- SetFontStyle :: ![FontStyle] !Picture -> Picture;
- SetFontStyle style p = QTextFace (StyleToStyleID style) p;
-
- SetFontSize :: !FontSize !Picture -> Picture;
- SetFontSize size p = QTextSize (SetBetween size MinFontSize MaxFontSize) p;
-
- PictureCharWidth :: !Char !Picture -> (!Int, !Picture);
- PictureCharWidth char p = QCharWidth char p;
-
- PictureStringWidth :: !{#Char} !Picture -> (!Int, !Picture);
- PictureStringWidth string p = QStringWidth string p;
-
- PictureFontMetrics :: !Picture -> (!FontInfo, !Picture);
- PictureFontMetrics p = ((ascent,descent,maxWidth,leading),p1);
- where {
- (ascent,descent,maxWidth,leading,p1) = QGetFontInfo p;
- };
-
-
- // Rules changing the position of the pen:
-
- // Absolute and relative pen move operations (without drawing).
-
- MovePenTo :: !Point !Picture -> Picture;
- MovePenTo (x, y) p = QMoveTo x y p;
-
- MovePen :: !Vector !Picture -> Picture;
- MovePen (vx, vy) p = QMove vx vy p;
-
-
- // Absolute and relative pen move operations (with drawing).
-
- LinePenTo :: !Point !Picture -> Picture;
- LinePenTo (x, y) p = QLineTo x y p;
-
- LinePen :: !Vector !Picture -> Picture;
- LinePen (vx, vy) p = QLine vx vy p;
-
-
- // Drawing text:
-
- DrawChar :: !Char !Picture -> Picture;
- DrawChar c p = QDrawChar c p;
-
- DrawString :: !{#Char} !Picture -> Picture;
- DrawString s p = QDrawString s p;
-
-
- // Rules not changing the position of the pen after drawing:
-
- // Non plane figures:
-
- DrawPoint :: !Point !Picture -> Picture;
- DrawPoint point p = DrawPoint` point (penX,penY) p1;
- where {
- (penX,penY,p1) = QGetPen p;
- };
-
- DrawPoint` :: !Point !Point !Picture -> Picture;
- DrawPoint` (x, y) (cx, cy) p = QMoveTo cx cy (QLine 0 0 (QMoveTo x y p));
-
- DrawLine :: !Line !Picture -> Picture;
- DrawLine line p = DrawLine` line (penX,penY) p1;
- where {
- (penX,penY,p1) = QGetPen p;
- };
-
- DrawLine` :: !Line !Point !Picture -> Picture;
- DrawLine` ((px,py),(qx,qy)) (cx, cy) p = QMoveTo cx cy (QLineTo qx qy (QMoveTo px py p));
-
- DrawCurve :: !Curve !Picture -> Picture;
- DrawCurve (r, s, t) p = QFrameArc (RectangleToRect r) (90 - s) (s - t) p;
-
- DrawCPoint :: !Point !Colour !Picture -> Picture;
- DrawCPoint point=:(h,v) colour=:(RGB rd gr bl) p
- | hasColorQD = QSetCPixel h v (RealToRGB rd, RealToRGB gr, RealToRGB bl) p1;
- = DrawPoint` point (x,y) (QForeColor (ColourToNormalColor colour) p2);
- where {
- (hasColorQD,p1) = HasColorQD p;
- (x,y,p2) = QGetPen p1;
- };
- DrawCPoint point colour p
- = DrawPoint` point (x,y) (QForeColor (ColourToNormalColor colour) p1);
- where {
- (x,y,p1) = QGetPen p;
- };
-
- DrawCLine :: !Line !Colour !Picture -> Picture;
- DrawCLine line colour p = DrawLine` line (x,y) (SetPenColour colour p1);
- where {
- (x,y,p1) = QGetPen p;
- };
-
- DrawCCurve :: !Curve !Colour !Picture -> Picture;
- DrawCCurve curve colour p = DrawCurve curve (SetPenColour colour p);
-
-
- // Rectangles:
-
- DrawRectangle :: !Rectangle !Picture -> Picture;
- DrawRectangle r p = QFrameRect (RectangleToRect r) p;
-
- FillRectangle :: !Rectangle !Picture -> Picture;
- FillRectangle r p = QPaintRect (RectangleToRect r) p;
-
- EraseRectangle :: !Rectangle !Picture -> Picture;
- EraseRectangle r p = QEraseRect (RectangleToRect r) p;
-
- InvertRectangle :: !Rectangle !Picture -> Picture;
- InvertRectangle r p = QInvertRect (RectangleToRect r) p;
-
-
- MoveRectangleTo :: !Rectangle !Point !Picture -> Picture;
- MoveRectangleTo r (x, y) pict
- | IsEmptyRect clip_rect
- = pict2;
- = MoveRectangle` grafPtr clip_rect (x-left,y-top) pict2;
- where {
- (grafPtr, pict1)= QGetPort pict;
- (clipRect,pict2)= GrafPtrClipRect grafPtr pict1;
- clip_rect = ClipRect rect clipRect;
- (left,top, _,_) = rect;
- rect = RectangleToRect r;
- };
-
- MoveRectangle :: !Rectangle !Vector !Picture -> Picture;
- MoveRectangle r vector pict
- | IsEmptyRect clip_rect
- = pict2;
- = MoveRectangle` grafPtr clip_rect vector pict2;
- where {
- (grafPtr, pict1) = QGetPort pict;
- (clipRect,pict2) = GrafPtrClipRect grafPtr pict1;
- clip_rect = ClipRect (RectangleToRect r) clipRect;
- };
-
- MoveRectangle` :: !GrafPtr !Rect !Vector !Picture -> Picture;
- MoveRectangle` grafPtr rect=:(left,top, right,bottom) (dh,dv) pict
- | dh_eq_0 && dv_eq_0 = pict;
- | ABS dh >= w
- || ABS dv >= h = QEraseRect rect copy;
- | dv_eq_0 && dh_gr_0 = QEraseRect (left,top, x, bottom) copy;
- | dv_eq_0 && dh_sm_0 = QEraseRect (x`, top, right,bottom) copy;
- | dh_eq_0 && dv_gr_0 = QEraseRect (left,top, right,y ) copy;
- | dh_eq_0 && dv_sm_0 = QEraseRect (left,y`, right,bottom) copy;
- | dh_gr_0 = QEraseRect (left,top, x,bottom`) (QEraseRect (left,bottom`, x,bottom) copy);
- | dv_gr_0 = QEraseRect (left,top, right,y) (QEraseRect (x,y, right,bottom) copy);
- = QEraseRect (left,y`, x`,bottom) (QEraseRect (x`,top, right,bottom) copy);
- where {
- copy = CopyRectangle` grafPtr rect rect` pict;
- x = left + dh; x` = right + dh; w = right - left;
- y = top + dv; y` = bottom + dv; h = bottom - top;
- rect` = (x,y, x`,y`);
- bottom` = Min y` bottom;
- dv_sm_0 = dv < 0;
- dv_gr_0 = dv > 0;
- dh_sm_0 = dh < 0;
- dh_gr_0 = dh > 0;
- dh_eq_0 = dh == 0;
- dv_eq_0 = dv == 0;
- };
-
- ClipRect :: !Rect !Rect -> Rect;
- ClipRect rect clipRect
- | left >= rightC
- || top >= bottomC
- || right <= leftC
- || bottom <= topC = (0,0,0,0);
- = ( SetBetween left leftC rightC,
- SetBetween top topC bottomC,
- SetBetween right leftC rightC,
- SetBetween bottom topC bottomC );
- where {
- (left, top, right, bottom ) = rect;
- (leftC,topC, rightC,bottomC) = clipRect;
- };
-
-
- CopyRectangleTo :: !Rectangle !Point !Picture -> Picture;
- CopyRectangleTo r (x,y) pict
- | IsEmptyRect clip_rect
- = pict2;
- = CopyRectangle` grafPtr clip_rect (leftC+dh,topC+dv, rightC+dh,bottomC+dv) pict2;
- where {
- (grafPtr, pict1) = QGetPort pict;
- dh = x - left;
- dv = y - top;
- (clipRect,pict2) = GrafPtrClipRect grafPtr pict1;
- clip_rect = ClipRect rect clipRect;
- (leftC,topC, rightC,bottomC)= clip_rect;
- (left, top, right, bottom) = rect;
- rect = RectangleToRect r;
- };
-
- CopyRectangle :: !Rectangle !Vector !Picture -> Picture;
- CopyRectangle r (dh,dv) pict
- | IsEmptyRect clip_rect
- = pict2;
- = CopyRectangle` grafPtr clip_rect (leftC+dh,topC+dv, rightC+dh,bottomC+dv) pict2;
- where {
- (grafPtr, pict1) = QGetPort pict;
- (clipRect, pict2) = GrafPtrClipRect grafPtr pict1;
- clip_rect = ClipRect (RectangleToRect r) clipRect;
- (leftC,topC, rightC,bottomC) = clip_rect;
- };
-
- CopyRectangle` :: !GrafPtr !Rect !Rect !Picture -> Picture;
- CopyRectangle` grafPtr source dest pict
- = CopyBits baseAddr rowBytes bounds baseAddr rowBytes bounds source dest SrcCopy 0 pict6;
- where {
- bitMap = grafPtr+GrafPtrportBits;
- (baseAddr, pict1) = LoadLong bitMap pict;
- (rowBytes, pict2) = LoadWord (bitMap+4) pict1;
- (top, pict3) = LoadWord (bitMap+6) pict2;
- (left, pict4) = LoadWord (bitMap+8) pict3;
- (bottom, pict5) = LoadWord (bitMap+10) pict4;
- (right, pict6) = LoadWord (bitMap+12) pict5;
- bounds = (left,top, right,bottom);
- };
-
- GrafPtrClipRect :: !GrafPtr !Picture -> (!Rect, !Picture);
- GrafPtrClipRect grafPtr pict
- = ((left,top, right,bottom), pict6);
- where {
- (clip_rgnhandle,pict1) = LoadLong (grafPtr+GrafPtrclipRgn) pict;
- (clip_rgn, pict2) = LoadLong clip_rgnhandle pict1;
- rect = 2+clip_rgn;
- (top, pict3) = LoadWord rect pict2;
- (left, pict4) = LoadWord (rect+2) pict3;
- (bottom, pict5) = LoadWord (rect+4) pict4;
- (right, pict6) = LoadWord (rect+6) pict5;
- };
-
-
- GrafPtrportBits :== 2;
- GrafPtrclipRgn :== 28;
-
-
- // Rounded corner rectangles:
-
- DrawRoundRectangle :: !RoundRectangle !Picture -> Picture;
- DrawRoundRectangle (r, w, h) p = QFrameRoundRect (RectangleToRect r) w h p;
-
- FillRoundRectangle :: !RoundRectangle !Picture -> Picture;
- FillRoundRectangle (r, w, h) p = QPaintRoundRect (RectangleToRect r) w h p;
-
- EraseRoundRectangle :: !RoundRectangle !Picture -> Picture;
- EraseRoundRectangle (r, w, h) p = QEraseRoundRect (RectangleToRect r) w h p;
-
- InvertRoundRectangle :: !RoundRectangle !Picture -> Picture;
- InvertRoundRectangle (r, w, h) p = QInvertRoundRect (RectangleToRect r) w h p;
-
-
- // Ovals:
-
- DrawOval :: !Oval !Picture -> Picture;
- DrawOval r p = QFrameOval (RectangleToRect r) p;
-
- FillOval :: !Oval !Picture -> Picture;
- FillOval r p = QPaintOval (RectangleToRect r) p;
-
- EraseOval :: !Oval !Picture -> Picture;
- EraseOval r p = QEraseOval (RectangleToRect r) p;
-
- InvertOval :: !Oval !Picture -> Picture;
- InvertOval r p = QInvertOval (RectangleToRect r) p;
-
-
- // Circles:
-
- DrawCircle :: !Circle !Picture -> Picture;
- DrawCircle ((cx, cy), r) p = QFrameOval (RectangleToRect ((cx-r, cy-r), (cx+r, cy+r))) p;
-
- FillCircle :: !Circle !Picture -> Picture;
- FillCircle ((cx, cy), r) p = QPaintOval (RectangleToRect ((cx-r, cy-r), (cx+r, cy+r))) p;
-
- EraseCircle :: !Circle !Picture -> Picture;
- EraseCircle ((cx, cy), r) p = QEraseOval (RectangleToRect ((cx-r, cy-r), (cx+r, cy+r))) p;
-
- InvertCircle :: !Circle !Picture -> Picture;
- InvertCircle ((cx, cy), r) p = QInvertOval (RectangleToRect ((cx-r, cy-r), (cx+r, cy+r))) p;
-
-
- // Wedges:
-
- DrawWedge :: !Wedge !Picture -> Picture;
- DrawWedge w p = DrawWedge` w (x,y) p1;
- where {
- (x,y,p1) = QGetPen p;
- };
-
- DrawWedge` :: !Wedge !Point !Picture -> Picture;
- DrawWedge` (r, s, t) (cx, cy) p
- = QMoveTo cx cy (
- QLineTo st`_x st`_y (
- QLineTo (px + toInt rx) (py + toInt ry) (
- QMoveTo sr`_x sr`_y (
- QFrameArc rect s` t` p))));
- where {
- s` = 90 - s; sr` = toReal s / 180.0;
- t` = s - t; st` = toReal t / 180.0;
- cos_sr` = cos rads; sin_sr` = sin rads;
- cos_st` = cos radt; sin_st` = sin radt;
- sr`_x = px` + toInt (cos_sr` * rx);
- sr`_y = py` - toInt (sin_sr` * ry);
- st`_x = px` + toInt (cos_st` * rx);
- st`_y = py` - toInt (sin_st` * ry);
- rx = toReal (qx - px) / 2.0;
- ry = toReal (qy - py) / 2.0;
- px` = px + toInt rx;
- py` = py + toInt ry;
- (px,py, qx,qy) = rect;
- rect = RectangleToRect r;
- rads = sr` * PI;
- radt = st` * PI;
- };
-
- FillWedge :: !Wedge !Picture -> Picture;
- FillWedge (r, s, t) p = QPaintArc (RectangleToRect r) (90 - s) (s - t) p;
-
- EraseWedge :: !Wedge !Picture -> Picture;
- EraseWedge (r, s, t) p = QEraseArc (RectangleToRect r) (90 - s) (s - t) p;
-
- InvertWedge :: !Wedge !Picture -> Picture;
- InvertWedge (r, s, t) p = QInvertArc (RectangleToRect r) (90 - s) (s - t) p;
-
-
- // Polygons:
-
- DrawPolygon :: !Polygon !Picture -> Picture;
- DrawPolygon (base=:(x,y), shape) p
- = p1;
- where {
- (poly_h,p1) = Draw_polygon base base shape 0 (QMoveTo x y p);
- };
-
- Draw_polygon :: !Point !Point !PolygonShape !PolyHandle !Picture -> (!PolyHandle, !Picture);
- Draw_polygon base position [v=:(dh, dv) : vs] polygon mp
- = Draw_polygon base (TranslatePoint position v) vs polygon (QLine dh dv mp);
- Draw_polygon (x,y) position [] polygon mp = (polygon, QLineTo x y mp);
-
- FillPolygon :: !Polygon !Picture -> Picture;
- FillPolygon (pos, shape) p
- = QKillPoly poly_h (QPaintPoly poly_h p1);
- where {
- (poly_h, p1) = New_poly pos shape p;
- };
-
- ErasePolygon :: !Polygon !Picture -> Picture;
- ErasePolygon (pos, shape) p
- = QKillPoly poly_h (QErasePoly poly_h p1);
- where {
- (poly_h, p1) = New_poly pos shape p;
- };
-
- InvertPolygon :: !Polygon !Picture -> Picture;
- InvertPolygon (pos, shape) p
- = QKillPoly poly_h (QInvertPoly poly_h p1);
- where {
- (poly_h, p1) = New_poly pos shape p;
- };
-
- New_poly :: !Point !PolygonShape !Picture -> (!PolyHandle, !Picture);
- New_poly base=:(x,y) shape p
- = (polygon, QClosePoly polygon p2);
- where {
- (polygon,p2) = Draw_polygon base base shape poly (QMoveTo x y p1);
- (poly, p1) = QOpenPoly p;
- };
-
- ScalePolygon :: !Int !Polygon -> Polygon;
- ScalePolygon k (position, shape) = (position, ScaleShape shape k);
-
- ScaleShape :: !PolygonShape !Int -> PolygonShape;
- ScaleShape [v : vs] k = [ScaleVector k v : ScaleShape vs k];
- ScaleShape vs k = vs;
-
- MovePolygonTo :: !Point !Polygon -> Polygon;
- MovePolygonTo p` (p, shape) = (p`, shape);
-
- MovePolygon :: !Vector !Polygon -> Polygon;
- MovePolygon v (position, shape) = (TranslatePoint position v, shape);
-
- TranslatePoint :: !Point !Vector -> Point;
- TranslatePoint (x,y) (v,w) = (x + v, y + w);
-
- ScaleVector :: !Int !Vector -> Vector;
- ScaleVector k (v,w) = (k*v,k*w);
-