WMRectangles.Mod 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. MODULE WMRectangles; (** AUTHOR "TF"; PURPOSE "Basic rectangles that are used by the WM and visual components"; *)
  2. TYPE
  3. Rectangle* = RECORD l*, t*, r*, b*: LONGINT END;
  4. (* It is important to understand and respect that the point (r,b) is not included in the rectangle !
  5. This is to ensure consistency between the continuous and discrete case
  6. *)
  7. PROCEDURE Min(a, b:LONGINT):LONGINT;
  8. BEGIN
  9. IF a<b THEN RETURN a ELSE RETURN b END;
  10. END Min;
  11. PROCEDURE Max(a, b:LONGINT):LONGINT;
  12. BEGIN
  13. IF a>b THEN RETURN a ELSE RETURN b END;
  14. END Max;
  15. (** move the rectangle by deltaX, deltaY *)
  16. PROCEDURE MoveRel*(VAR x:Rectangle; deltaX, deltaY:LONGINT);
  17. BEGIN
  18. x.l:=x.l+deltaX; x.t:=x.t+deltaY; x.r:=x.r+deltaX; x.b:=x.b+deltaY
  19. END MoveRel;
  20. PROCEDURE Bound(VAR x:LONGINT; min, max:LONGINT);
  21. BEGIN
  22. IF x<min THEN x:=min ELSE IF x>max THEN x:=max END END
  23. END Bound;
  24. (** Clip rectangle rect at the boundary bounds *)
  25. PROCEDURE ClipRect*(VAR rect, bounds : Rectangle);
  26. BEGIN
  27. Bound(rect.l, bounds.l, bounds.r);Bound(rect.r, bounds.l, bounds.r);
  28. Bound(rect.t, bounds.t, bounds.b);Bound(rect.b, bounds.t, bounds.b)
  29. END ClipRect;
  30. (** return true if rectangle x is empty *)
  31. PROCEDURE RectEmpty*(x : Rectangle) : BOOLEAN;
  32. BEGIN
  33. RETURN (x.t >= x.b) OR (x.l >= x.r)
  34. END RectEmpty;
  35. (** return true if x and y are inside rect *)
  36. PROCEDURE PointInRect*(x, y : LONGINT; rect : Rectangle) : BOOLEAN;
  37. BEGIN
  38. RETURN (x >= rect.l) & (x < rect.r) & (y >= rect.t) & (y < rect.b)
  39. END PointInRect;
  40. (** return true if the inner rectangle is completely inside the outer *)
  41. PROCEDURE IsContained*(VAR outer, inner : Rectangle) : BOOLEAN;
  42. BEGIN
  43. RETURN (outer.l <= inner.l) & (outer.r >= inner.r) &
  44. (outer.t <= inner.t) & (outer.b >= inner.b)
  45. END IsContained;
  46. PROCEDURE IsEqual*(CONST a, b : Rectangle) : BOOLEAN;
  47. BEGIN
  48. RETURN (a.l = b.l) & (a.r = b.r) & (a.t = b.t) & (a.b = b.b)
  49. END IsEqual;
  50. (** return whether a and be intersect and not only touche *)
  51. PROCEDURE Intersect*(VAR a, b : Rectangle) : BOOLEAN;
  52. BEGIN
  53. RETURN (a.l < b.r) & (a.r > b.l) & (a.t < b.b) & (a.b > b.t)
  54. END Intersect;
  55. (** Set rect to (l, t, r, b) *)
  56. PROCEDURE SetRect*(VAR rect : Rectangle; l, t, r, b : LONGINT);
  57. BEGIN
  58. rect.l := l; rect.t := t; rect.r := r; rect.b := b
  59. END SetRect;
  60. (** return the area of r. Overflow if r w * h > MAX(LONGINT) *)
  61. PROCEDURE Area*(VAR r : Rectangle) : LONGINT;
  62. BEGIN
  63. RETURN (r.r - r.l) * (r.b - r.t)
  64. END Area;
  65. (** Extend old to contain addition *)
  66. PROCEDURE ExtendRect*(VAR old, addition : Rectangle);
  67. BEGIN
  68. old.l := Min(old.l, addition.l); old.r := Max(old.r,addition.r);
  69. old.t := Min(old.t, addition.t); old.b := Max(old.b, addition.b)
  70. END ExtendRect;
  71. (** return the Rectangle (l, t, r, b) *)
  72. PROCEDURE MakeRect*(l, t, r, b: LONGINT) : Rectangle;
  73. VAR result : Rectangle;
  74. BEGIN
  75. result.l := l; result.t := t; result.r := r; result.b := b; RETURN result
  76. END MakeRect;
  77. (** extend the rectangle by units in each direction *)
  78. PROCEDURE ResizeRect*(x : Rectangle; units : LONGINT) : Rectangle;
  79. VAR t : Rectangle;
  80. BEGIN
  81. t.l := x.l - units; t.t := x.t - units; t.r := x.r + units; t.b := x.b + units;
  82. RETURN t
  83. END ResizeRect;
  84. PROCEDURE Normalize*(VAR rect: Rectangle);
  85. VAR
  86. temp: LONGINT;
  87. BEGIN
  88. IF rect.l > rect.r THEN
  89. temp := rect.l;
  90. rect.l := rect.r;
  91. rect.r := temp;
  92. END;
  93. IF rect.t > rect.b THEN
  94. temp := rect.t;
  95. rect.t := rect.b;
  96. rect.b := temp;
  97. END;
  98. END Normalize;
  99. END WMRectangles.