AGfxBuffer.Mod 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. (* ETH Oberon, Copyright 2001 ETH Zuerich Institut fuer Computersysteme, ETH Zentrum, CH-8092 Zuerich.
  2. Refer to the "General ETH Oberon System Source License" contract available at: http://www.oberon.ethz.ch/ *)
  3. MODULE GfxBuffer; (** portable *) (* eos *)
  4. (** AUTHOR "eos"; PURPOSE "Raster contexts rendering into background buffers"; *)
  5. (*
  6. 10.12.98 - first version; derived from GfxDev
  7. 25.8.99 - replaced GfxMaps with Images/GfxImages
  8. 10.8.99 - scratched SetPoint, added Close method
  9. 13.02.2000 - new get/set clip methods
  10. 10.05.2000 - Rect now ignores empty rectangles
  11. *)
  12. IMPORT
  13. Images := Raster, GfxMatrix, GfxImages, GfxRegions, Gfx, GfxRaster;
  14. TYPE
  15. Context* = OBJECT (GfxRaster.Context)
  16. VAR
  17. orgX*, orgY*: REAL; (** origin of default coordinate system **)
  18. scale*: REAL; (** default scale factor **)
  19. bgCol*: Gfx.Color; (** background color for erasing **)
  20. img*: Images.Image; (** target buffer **)
  21. pix: Images.Pixel;
  22. compOp:SHORTINT; (* composition operation for raster device *)
  23. (** initialize buffered context **)
  24. PROCEDURE InitBuffer* (img: Images.Image);
  25. BEGIN
  26. SELF.InitRaster();
  27. SELF.compOp := 1; (* Copy Op is default *)
  28. SELF.img := img;
  29. SELF.SetCoordinates(0, 0, 1);
  30. SELF.SetBGColor(Gfx.White);
  31. SELF.Reset();
  32. END InitBuffer;
  33. PROCEDURE{FINAL} SetColPat* (col: Gfx.Color; pat: Gfx.Pattern);
  34. BEGIN
  35. SetColPat^(col, pat);
  36. Images.SetRGBA(SELF.pix, col.r, col.g, col.b, col.a)
  37. END SetColPat;
  38. (** set default coordinate origin and scale factor **)
  39. PROCEDURE{FINAL} SetCoordinates* (x, y, scale: REAL);
  40. BEGIN
  41. SELF.orgX := x; SELF.orgY := y; SELF.scale := scale
  42. END SetCoordinates;
  43. (** set background color **)
  44. PROCEDURE{FINAL} SetBGColor* (col: Gfx.Color);
  45. BEGIN
  46. SELF.bgCol := col
  47. END SetBGColor;
  48. (** set composition operation as defined in Raster **)
  49. PROCEDURE{FINAL} SetCompOp* (op:SHORTINT);
  50. BEGIN
  51. SELF.compOp := op
  52. END SetCompOp;
  53. (**--- Coordinate System ---**)
  54. (** current transformation matrix **)
  55. PROCEDURE{FINAL} ResetCTM* ();
  56. BEGIN
  57. GfxMatrix.Translate(GfxMatrix.Identity, SELF.orgX, SELF.orgY, SELF.ctm);
  58. GfxMatrix.Scale(SELF.ctm, SELF.scale, SELF.scale, SELF.ctm)
  59. END ResetCTM;
  60. (**--- Clipping ---**)
  61. PROCEDURE{FINAL} ResetClip* ();
  62. BEGIN
  63. SELF.ResetClip^();
  64. SELF.clipReg.SetToRect(0, 0, SHORT(SELF.img.width), SHORT(SELF.img.height))
  65. END ResetClip;
  66. (**--- Raster ---**)
  67. PROCEDURE{FINAL} DrawImage* (x, y: REAL; img: Images.Image; VAR filter: GfxImages.Filter);
  68. VAR m: GfxMatrix.Matrix; dx, dy, llx, lly, urx, ury: INTEGER; col: Images.Pixel;
  69. BEGIN
  70. GfxMatrix.Translate(SELF.ctm, x, y, m);
  71. dx := SHORT(ENTIER(m[2, 0] + 0.5));
  72. dy := SHORT(ENTIER(m[2, 1] + 0.5));
  73. col := filter.col;
  74. Images.SetModeColor(filter, SELF.fillCol.r, SELF.fillCol.g, SELF.fillCol.b);
  75. IF (filter.hshift # GfxImages.hshift) & (dx + 0.1 < m[2, 0]) & (m[2, 0] < dx + 0.9) OR
  76. (filter.vshift # GfxImages.vshift) & (dy + 0.1 < m[2, 1]) & (m[2, 1] < dy + 0.9) OR
  77. GfxMatrix.Scaled(m) OR
  78. GfxMatrix.Rotated(m)
  79. THEN
  80. GfxImages.Transform(img, SELF.img, m, filter)
  81. ELSE
  82. llx := 0; lly := 0; urx := SHORT(img.width); ury := SHORT(img.height);
  83. GfxRegions.ClipRect(llx, lly, urx, ury, SELF.clipReg.llx - dx, SELF.clipReg.lly - dy, SELF.clipReg.urx - dx, SELF.clipReg.ury - dy);
  84. IF SELF.clipReg.llx > dx THEN dx := SELF.clipReg.llx END;
  85. IF SELF.clipReg.lly > dy THEN dy := SELF.clipReg.lly END;
  86. IF dx + urx > SELF.img.width THEN urx := SHORT(SELF.img.width - dx) END;
  87. IF dy + ury > SELF.img.height THEN ury := SHORT(SELF.img.height - dy) END;
  88. IF dx < 0 THEN llx := -dx; dx := 0 END;
  89. IF dy < 0 THEN lly := -dy; dy := 0 END;
  90. IF (llx < urx) & (lly < ury) THEN
  91. IF ~GfxRegions.RectEmpty(llx, lly, urx, ury) THEN
  92. Images.Copy(img, SELF.img, llx, lly, urx, ury, dx, dy, filter)
  93. END
  94. END
  95. END;
  96. Images.SetModeColor(filter, ORD(col[Images.r]), ORD(col[Images.g]), ORD(col[Images.b]))
  97. END DrawImage;
  98. PROCEDURE{FINAL} dot*(x, y: LONGINT); (** current dot procedure **)
  99. VAR px, py: LONGINT; mode: Images.Mode;
  100. BEGIN
  101. IF (SELF.clipState = GfxRaster.In) OR
  102. (SELF.clipState = GfxRaster.InOut) & SELF.clipReg.RectInside(SHORT(x), SHORT(y), SHORT(x+1), SHORT(y+1))
  103. THEN
  104. IF SELF.pat = NIL THEN
  105. Images.InitMode(mode, SELF.compOp);
  106. Images.Put(SELF.img, SHORT(x), SHORT(y), SELF.pix, mode)
  107. ELSE
  108. px := (x - ENTIER(SELF.orgX + SELF.pat.px + 0.5)) MOD SELF.pat.img.width;
  109. py := (y - ENTIER(SELF.orgY + SELF.pat.py + 0.5)) MOD SELF.pat.img.height;
  110. Images.InitModeColor(mode, Images.srcOverDst, SELF.col.r, SELF.col.g, SELF.col.b);
  111. Images.Copy(SELF.pat.img, SELF.img, px, py, px+1, py+1, SHORT(x), SHORT(y), mode)
  112. END
  113. END
  114. END dot;
  115. PROCEDURE{FINAL} rect* (llx, lly, urx, ury: LONGINT); (** current rect procedure **)
  116. VAR data: RegData; mode: Images.Mode;
  117. BEGIN
  118. IF (SELF.clipState # GfxRaster.Out) & (llx < urx) & (lly < ury) THEN
  119. IF SELF.pat = NIL THEN
  120. IF SELF.clipState = GfxRaster.In THEN
  121. Images.InitMode(mode, SELF.compOp);
  122. Images.Fill(SELF.img, SHORT(llx), SHORT(lly), SHORT(urx), SHORT(ury), SELF.pix, mode)
  123. ELSE
  124. data.bc := SELF;
  125. SELF.clipReg.Enumerate(SHORT(llx), SHORT(lly), SHORT(urx), SHORT(ury), Color, data)
  126. END
  127. ELSE
  128. data.bc := SELF;
  129. data.dx := SHORT(ENTIER(SELF.orgX + SELF.pat.px + 0.5));
  130. data.dy := SHORT(ENTIER(SELF.orgY + SELF.pat.py + 0.5));
  131. Images.InitModeColor(data.mode, Images.srcOverDst, SELF.col.r, SELF.col.g, SELF.col.b);
  132. SELF.clipReg.Enumerate(SHORT(llx), SHORT(lly), SHORT(urx), SHORT(ury), Tile, data)
  133. END
  134. END
  135. END rect;
  136. END Context;
  137. RegData = RECORD (GfxRegions.EnumData)
  138. dx, dy: INTEGER;
  139. bc: Context;
  140. mode: Images.Mode;
  141. END;
  142. (*--- Rendering ---*)
  143. PROCEDURE Color (llx, lly, urx, ury: INTEGER; VAR data: GfxRegions.EnumData);
  144. VAR bc: Context; mode: Images.Mode;
  145. BEGIN
  146. bc := data(RegData).bc;
  147. Images.InitMode(mode, bc.compOp);
  148. Images.Fill(bc.img, llx, lly, urx, ury, bc.pix, mode)
  149. END Color;
  150. PROCEDURE Tile (llx, lly, urx, ury: INTEGER; VAR data: GfxRegions.EnumData);
  151. VAR bc: Context;
  152. BEGIN
  153. WITH data: RegData DO
  154. bc := data.bc;
  155. Images.FillPattern(bc.pat.img, bc.img, llx, lly, urx, ury, data.dx, data.dy, data.mode)
  156. END
  157. END Tile;
  158. (** set default coordinate origin and scale factor **)
  159. PROCEDURE SetCoordinates* (bc: Context; x, y, scale: REAL);
  160. BEGIN
  161. bc.SetCoordinates(x, y, scale);
  162. END SetCoordinates;
  163. (** set background color **)
  164. PROCEDURE SetBGColor* (bc: Context; col: Gfx.Color);
  165. BEGIN
  166. bc.SetBGColor(col);
  167. END SetBGColor;
  168. (** set composition operation as defined in Raster **)
  169. PROCEDURE SetCompOp* (bc: Context; op:SHORTINT);
  170. BEGIN
  171. bc.SetCompOp(op);
  172. END SetCompOp;
  173. (** initialize buffered context **)
  174. PROCEDURE Init* (bc: Context; img: Images.Image);
  175. BEGIN
  176. bc.InitBuffer( img );
  177. END Init;
  178. END GfxBuffer.