(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Tue Jun 16 13:08:18 PDT 1992 by muller *) (* modified on Tue Dec 17 10:47:50 PST 1991 by mhb *) MODULE ShadowPaint; IMPORT Axis, Interval, PaintOp, Pixmap, Point, Rect, Region, Shadow, Trapezoid, VBT, VBTClass; PROCEDURE Bar ( v : VBT.T; READONLY clip : Region.T; shadow: Shadow.T; style : Shadow.Style; axis : Axis.T; READONLY target: Rect.T ) = VAR topOp, bottomOp: PaintOp.T; topR, bottomR: Rect.T; mid: INTEGER; BEGIN CASE style OF | Shadow.Style.Flat => VBT.PaintTexture(v, Rect.Meet(target, clip.r), shadow.bg, Pixmap.Solid, Point.Origin); ELSE GetOps(shadow, style, topOp, bottomOp); IF axis = Axis.T.Hor THEN mid := Interval.Middle(Interval.T{target.west, target.east}) ELSE mid := Interval.Middle(Interval.T{target.north, target.south}) END; Rect.Chop(axis, clip.r, mid, topR, bottomR); VBT.PaintTexture(v, topR, topOp, Pixmap.Solid, Point.Origin); VBT.PaintTexture(v, bottomR, bottomOp, Pixmap.Solid, Point.Origin); END; END Bar; PROCEDURE Diamond ( v : VBT.T; READONLY clip : Region.T; shadow : Shadow.T; style : Shadow.Style; READONLY in, out : Rect.T; insideOp : PaintOp.T; insidePixmap: Pixmap.T ) = PROCEDURE FillTriangle ( op : PaintOp.T; READONLY a, b, c: Point.T; pm : Pixmap.T ) = VAR t: Trapezoid.T; BEGIN t := Trapezoid.FromTriangle(a, b, c); IF (t.vlo >= t.vhi) OR (t.m1.n = 0) OR (t.m2.n = 0) THEN RETURN END; VBT.PaintTrapezoid(v, clip.r, t, op, pm, Point.Origin); END FillTriangle; VAR top, bottom: PaintOp.T; ptW, ptE, ptN, ptS: Point.T; BEGIN CASE style OF | Shadow.Style.Flat => VBT.PaintTexture( v, Rect.Meet(out, clip.r), shadow.bg, Pixmap.Solid, Point.Origin); ELSE GetOps(shadow, style, top, bottom); Midpoints(out, ptW, ptE, ptN, ptS); FillTriangle(shadow.bg, ptN, ptW, Rect.NorthWest(out), Pixmap.Solid); FillTriangle(shadow.bg, ptN, ptE, Rect.NorthEast(out), Pixmap.Solid); FillTriangle(shadow.bg, ptS, ptW, Rect.SouthWest(out), Pixmap.Solid); FillTriangle(shadow.bg, ptS, ptE, Rect.SouthEast(out), Pixmap.Solid); FillTriangle(top, ptW, ptE, ptN, Pixmap.Solid); FillTriangle(bottom, ptW, ptE, ptS, Pixmap.Solid); Midpoints(in, ptW, ptE, ptN, ptS); FillTriangle(insideOp, ptW, ptE, ptN, insidePixmap); FillTriangle(insideOp, ptW, ptE, ptS, insidePixmap); END; END Diamond; PROCEDURE Border ( v : VBT.T; READONLY clip : Region.T; shadow : Shadow.T; style : Shadow.Style; READONLY in, out: Rect.T ) = VAR top, bottom: PaintOp.T; mid: Rect.T; BEGIN GetOps(shadow, style, top, bottom); CASE style OF | Shadow.Style.Flat => MonoColoredBorder(v, clip, in, out, shadow.bg); | Shadow.Style.Raised, Shadow.Style.Lowered => BiColoredBorder(v, clip, in, out, top, bottom); | Shadow.Style.Chiseled, Shadow.Style.Ridged => mid := Midline(in, out); BiColoredBorder(v, clip, mid, out, top, bottom); BiColoredBorder(v, clip, in, mid, bottom, top); END; END Border; PROCEDURE MonoColoredBorder ( v : VBT.T; READONLY clip : Region.T; READONLY in, out: Rect.T; op : PaintOp.T ) = VAR a: Rect.Partition; BEGIN Rect.Factor(Rect.Meet(out, clip.r), in, a, 0, 0); VBT.PaintTexture(v, a[0], op, Pixmap.Solid, Point.Origin); VBT.PaintTexture(v, a[1], op, Pixmap.Solid, Point.Origin); VBT.PaintTexture(v, a[3], op, Pixmap.Solid, Point.Origin); VBT.PaintTexture(v, a[4], op, Pixmap.Solid, Point.Origin); END MonoColoredBorder; PROCEDURE BiColoredBorder ( v : VBT.T; READONLY clip : Region.T; READONLY in, out : Rect.T; top, bottom: PaintOp.T ) = PROCEDURE FillRect (op: PaintOp.T; READONLY r: Rect.T) = BEGIN IF (Rect.HorSize(r) = 0) OR (Rect.VerSize(r) = 0) THEN RETURN END; VBT.PaintTexture( v, Rect.Meet(r, clip.r), op, Pixmap.Solid, Point.Origin); END FillRect; PROCEDURE FillTrapezoid (op: PaintOp.T; READONLY t: Trapezoid.T) = BEGIN IF (t.vlo >= t.vhi) OR (t.m1.n = 0) OR (t.m2.n = 0) THEN RETURN END; VBT.PaintTrapezoid(v, clip.r, t, op, Pixmap.Solid, Point.Origin); END FillTrapezoid; BEGIN FillRect( bottom, Rect.FromEdges(in.east, out.east, out.north, out.south)); FillRect(top, Rect.FromEdges(out.west, in.west, out.north, out.south)); FillTrapezoid( top, Trapezoid.FromEdges( out.north, out.west, out.east, in.north, out.west, in.east)); FillTrapezoid(bottom, Trapezoid.FromEdges(in.south, in.west, out.east, out.south, out.west, out.east)); END BiColoredBorder; PROCEDURE GetOps ( shadow : Shadow.T; style : Shadow.Style; VAR top, bottom: PaintOp.T ) = BEGIN CASE style OF | Shadow.Style.Raised, Shadow.Style.Ridged => top := shadow.light; bottom := shadow.dark; | Shadow.Style.Lowered, Shadow.Style.Chiseled => top := shadow.dark; bottom := shadow.light; | Shadow.Style.Flat => top := shadow.bg; bottom := shadow.bg; END; END GetOps; PROCEDURE Midline (READONLY in, out: Rect.T): Rect.T RAISES {} = VAR de := (in.east - out.east) DIV 2; dw := (in.west - out.west) DIV 2; ds := (in.south - out.south) DIV 2; dn := (in.north - out.north) DIV 2; BEGIN RETURN Rect.Change(out, dw, de, dn, ds); END Midline; PROCEDURE Midpoints (READONLY r: Rect.T; VAR midW, midE, midN, midS: Point.T) = VAR midH := (r.west + r.east) DIV 2; midV := (r.north + r.south) DIV 2; BEGIN midN := Point.FromCoords(midH, r.north); midS := Point.FromCoords(midH, r.south); midW := Point.FromCoords(r.west, midV); midE := Point.FromCoords(r.east, midV); END Midpoints; BEGIN END ShadowPaint.