--
--	rastergraphics: raster graphics primitives
--	Copyright (C) 2007  David Wood <dcw@kent.ac.uk>
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	License as published by the Free Software Foundation, either
--	version 2 of the License, or (at your option) any later version.
--
--	This library is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library.  If not, see
--	<http://www.gnu.org/licenses/>.
--

--** @module rastergraphics

--* Copy one raster onto another.
--
--  One corner of [@code src] always maps to [@code (x, y)] of [@code dst].
--
--  Let the least significant three bits of [@code f] be abc:
--
--  [@item] a = 1:  flip about [@text \], then
--  [@item] b = 1:  flip about [@text |]
--  [@item] c = 1:  flip about [@text -]
--
--  Hence
--  [@item] f = 7:  flip about [@text /]
--
--  @param src Source raster
--  @param x, y Top left of target in [@code dst]
--  @param c Transparent colour -- don't copy
--  @param f Orientation
--  @param dst Destination raster

PROC copy.raster (VAL [][]INT src, VAL INT x, y, c, f, [][]INT dst)

  VAL INT w IS SIZE src[0]:		-- width of src
  VAL INT d IS SIZE src:		-- depth of src
  VAL INT W IS SIZE dst[0]:		-- width of dst
  VAL INT D IS SIZE dst:		-- depth of dst
  VAL INT f IS f /\ 7:

  SEQ
    IF
      (f < 4) AND ((x < 0) OR (y < 0) OR ((x + w) > W) OR ((y + d) > D))
        SKIP				-- (partly) outside dst
      (f > 3) AND ((x < 0) OR (y < 0) OR ((x + d) > W) OR ((y + w) > D))
        SKIP
      TRUE
        CASE f
          0
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              []INT d.i IS dst[y + i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    d.i[x + j] := s.i.j
                  TRUE
                    SKIP
          1
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              []INT d.i IS dst[(y + d) - (i + 1)]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    d.i[x + j] := s.i.j
                  TRUE
                    SKIP
          2
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              []INT d.i IS dst[y + i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    d.i[(x + w) - (j + 1)] := s.i.j
                  TRUE
                    SKIP
          3
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              []INT d.i IS dst[(y + d) - (i + 1)]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    d.i[(x + w) - (j + 1)] := s.i.j
                  TRUE
                    SKIP
          4
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    dst[y + j][x + i] := s.i.j
                  TRUE
                    SKIP
          5
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    dst[(y + w) - (j + 1)][x + i] := s.i.j
                  TRUE
                    SKIP
          6
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    dst[y + j][(x + d) - (i + 1)] := s.i.j
                  TRUE
                    SKIP
          7
            SEQ i = 0 FOR d
              VAL []INT s.i IS src[i]:
              SEQ j = 0 FOR w
                VAL INT s.i.j IS s.i[j]:
                IF
                  s.i.j <> c
                    dst[(y + w) - (j + 1)][(x + d) - (i + 1)] := s.i.j
                  TRUE
                    SKIP
:

PROC overwrite.raster (VAL [][]INT src, VAL INT x, y, f, [][]INT dst)

  copy.raster (src, x, y, -1, f, dst)		-- impossible colour
:
