############################################################################
#
#	File:     xformimg.icn
#
#	Subject:  Procedures to transform image
#
#	Author:   Ralph E. Griswold
#
#	Date:     February 4, 1995
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#  These procedures perform reflections, rotations, and concatenations
#  of images.
#
#  Warning:  Some of these operations are slow.
#
############################################################################
#
#  Requires:  Version 9 graphics
#
############################################################################
#
#  Links:  numbers, wattrib, wopen
#
############################################################################

link numbers
link wattrib
link wopen

procedure wreflect(win1, dir)
   local win2, x1, x2, y1, y2, width, height

   /dir := "v"				# vertical reflection is the default

   height := Height(win1)
   width := Width(win1)

   win2 := WOpen("canvas=hidden", "width=" || width, "height=" || height) |
      stop("*** cannot window for reflection")

   case dir of {
      "h":  {
         x2 := 0
         y2 := height - 1
         every Fg(win2, Pixel(win1)) do {
            DrawPoint(win2, x2, y2)
            if x2 = width - 1 then {
               x2 := 0
               y2 -:= 1
               }
            else x2 +:= 1
            }
         }
      "v":  {
         x2 := width - 1
         y2 := 0
         every Fg(win2, Pixel(win1)) do {
            DrawPoint(win2, x2, y2)
            if x2 = 0 then {
               x2 := width - 1
               y2 +:= 1
               }
            else x2 -:= 1
            }
         }
      default:  stop("*** invalid specification for reflect()")
      }

   return win2

end

procedure wrotate(win1, dir)
   local win2, x1, x2, y1, y2, width, height

   /dir := "90"				# 90-degree rotation is the default

   height := Height(win1)
   width := Width(win1)


   case integer(dir) of {
      90:  {
         x2 := height - 1
         y2 := 0
         win2 := WOpen("canvas=hidden", "width=" || height,
            "height=" || width) | stop("*** cannot open target window")
         every Fg(win2, Pixel(win1)) do {
            DrawPoint(win2, x2, y2)
            if y2 = width - 1 then {
               y2 := 0
               x2 -:= 1
               }
            else y2 +:= 1
            }
         }
      -90:  {
         win2 := WOpen("canvas=hidden", "width=" || height,
            "height=" || width) | stop("*** cannot open target window")
         x2 := 0
         y2 := width - 1
         every Fg(win2, Pixel(win1)) do {
            DrawPoint(win2, x2, y2)
            if y2 = 0 then {
               y2 := width - 1
               x2 +:= 1
               }
            else y2 -:= 1
            }
         }
      180:  {
         win2 := WOpen("canvas=hidden", "width=" || width,
            "height=" || height) | stop("*** cannot open target window")
         x2 := width - 1
         y2 := height - 1
         every Fg(win2, Pixel(win1)) do {
            DrawPoint(win2, x2, y2)
            if x2 = 0 then {
               x2 := width - 1
               y2 -:= 1
               }
            else x2 -:= 1
            }
         }
      default:  stop("*** invalid specification for rotate()")
      } | stop("*** invalid specification for rotate()")

   return win2

end

procedure wcatenate(win1, win2, dir)
   local width1, width2, height1, height2, win3

   /dir := "h"			# horizontal concatenation is the default

   width1 := Width(win1)
   width2 := Width(win2)
   height1 := Height(win1)
   height2 := Height(win2)

   case dir of {
      "h":  {
         win3 := WOpen("canvas=hidden", "width=" || (width1 + width2),
            "height=" || max(height1, height2)) |
               stop("*** cannot open window for concatenation")
         CopyArea(win1, win3)
         CopyArea(win2, win3, 0, 0, width2, height2, width1, 0)
         }
      "v":  {
         win3 := WOpen("canvas=hidden", "width=" || max(width1, width2),
            "height=" || (height1 + height2)) |
               stop("*** cannot open window for concatenation")
         CopyArea(win1, win3)
         CopyArea(win2, win3, 0, 0, width2, height2, 0, height1)
         }
      default:  stop("*** invalid specification for catenate()")
      }

   return win3

end
