home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
gprocs
/
gpxop.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
10KB
|
315 lines
############################################################################
#
# File: gpxop.icn
#
# Subject: Procedures for graphics operations
#
# Author: Gregg M. Townsend
#
# Date: May 26, 1999
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This file contains some graphics procedures.
#
# LeftString(x, y, s) draws a string left-aligned at (x, y).
#
# CenterString(x, y, s) draws a string centered at (x, y).
#
# RightString(x, y, s) draws a string right-aligned at (x, y).
#
# ClearOutline(x, y, w, h) draws a rectangle, erasing its interior.
#
# Translate(dx, dy, w, h) moves the window origin and optionally
# sets the clipping region.
#
# Zoom(x1, y1, w1, h1, x2, y2, w2, h2)
# copies and distorts a rectangle.
#
# Capture(p, x, y, w, h) converts a window area to an image string.
#
# Sweep() lets the user select a rectangular area.
#
############################################################################
#
# LeftString(x, y, s), CenterString(x, y, s), and RightString(x, y, s)
# draw a string centered vertically about y and left-justified,
# centered, or right-justified about x.
#
# ClearOutline(x, y, w, h) draws a rectangle in the foreground color
# and fills it with the background color.
#
# Translate(dx, dy, w, h) adjusts a window's dx and dy attributes by
# the values given. Note that the resulting attribute values are the
# sums of the existing values with the parameters, so that successive
# translations accumulate. If w and h are supplied, the clipping
# region is set to a rectangle of size (w, h) at the new origin.
#
# Zoom(x1, y1, w1, h1, x2, y2, w2, h2) is a distorting variation of
# CopyArea that can be used to shrink or enlarge a rectangular area.
# Zero, one, or two window arguments can be supplied. Rectangle 1 is
# copied to fill rectangle 2 using simple pixel sampling and replication.
# The rectangles can overlap. The usual defaults apply for both rectangles.
#
# Sweep() lets the user select a rectangular area using the mouse.
# Called when a mouse button is pressed, Sweep handles all subsequent
# events until a mouse button is released. As the mouse moves, a
# reverse-mode outline rectangle indicates the selected area. The
# pixels underneath the rectangle outline are considered part of this
# rectangle, implying a minimum width/height of 1, and the rectangle
# is clipped to the window boundary. Sweep returns a list of four
# integers [x,y,w,h] giving the rectangle bounds in canonical form
# (w and h always positive). Note that w and h give the width as
# measured in FillRectangle terms (number of pixels included) rather
# than DrawRectangle terms (coordinate difference).
#
# Capture(palette, x, y, w, h) converts a window region into an
# image string using the specified palette, and returns the string.
#
# These procedures all accept an optional initial window argument.
#
############################################################################
#
# Links: gpxlib
#
############################################################################
#
# Requires: Version 9 graphics
#
############################################################################
link gpxlib
# LeftString(x, y, s) -- draw string left-justified at (x,y).
procedure LeftString(win, x, y, s) #: draw left-justified string
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: x :=: y :=: s
win := &window
}
y +:= (WAttrib(win, "ascent") - WAttrib(win, "descent")) / 2 + 1
return DrawString(win, x, y, s)
end
# CenterString(x, y, s) -- draw string centered about (x,y).
procedure CenterString(win, x, y, s) #: draw centered string
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: x :=: y :=: s
win := &window
}
x -:= TextWidth(win, s) / 2
y +:= (WAttrib(win, "ascent") - WAttrib(win, "descent")) / 2 + 1
return DrawString(win, x, y, s)
end
# RightString(x, y, s) -- draw string right-justified at (x,y).
procedure RightString(win, x, y, s) #: draw right-justified string
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: x :=: y :=: s
win := &window
}
x -:= TextWidth(win, s)
y +:= (WAttrib(win, "ascent") - WAttrib(win, "descent")) / 2 + 1
return DrawString(win, x, y, s)
end
# ClearOutline(x, y, w, h) -- draw rectangle and fill background.
procedure ClearOutline(win, x, y, w, h) #: draw and clear rectangle
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: x :=: y :=: w :=: h
win := &window
}
/x := -WAttrib(win, "dx")
/y := -WAttrib(win, "dy")
/w := WAttrib(win, "width") - (x + WAttrib(win, "dx"))
/h := WAttrib(win, "height") - (y + WAttrib(win, "dy"))
if w < 0 then
x -:= (w := -w)
if h < 0 then
y -:= (h := -h)
DrawRectangle(win, x, y, w, h)
EraseArea(win, x+1, y+1, w-1, h-1)
return win
end
# Translate(dx, dy, w, h) -- add translation and possibly clipping.
procedure Translate(win, dx, dy, w, h) #: add translation
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: dx :=: dy :=: w :=: h
win := &window
}
WAttrib(win, "dx=" || WAttrib(win,"dx")+dx, "dy=" || WAttrib(win,"dy")+dy)
Clip(win, 0, 0, \w, \h)
return win
end
# Sweep() -- sweep out area with mouse, return bounds
procedure Sweep(win) #: sweep area with mouse
local x, y, w, h, wmin, wmax, hmin, hmax
/win := &window
win := Clone(win, "drawop=reverse")
x := &x # set initial rect bounds
y := &y
w := h := 0
wmin := -WAttrib(win, "dx") - x # calc coordinate limits
hmin := -WAttrib(win, "dy") - y
wmax := wmin + WAttrib(win, "width") - 1
hmax := hmin + WAttrib(win, "height") - 1
DrawRectangle(win, x, y, w, h) # draw initial bounding rect
until Event(win) === (&lrelease | &mrelease | &rrelease) do {
DrawRectangle(win, x, y, w, h) # erase old bounds
w := &x - x # calc new width & height
h := &y - y
w <:= wmin # clip to stay on window
w >:= wmax
h <:= hmin
h >:= hmax
DrawRectangle(win, x, y, w, h) # draw new bounds
}
DrawRectangle(win, x, y, w, h) # erase bounding rectangle
if w < 0 then x -:= (w := -w) # ensure nonnegative sizes
if h < 0 then y -:= (h := -h)
Uncouple(win)
return [x, y, w + 1, h + 1] # return FillRectangle bounds
end
# Zoom(win1, win2, x1, y1, w1, h1, x2, y2, w2, h2) -- copy and distort.
procedure Zoom(args[]) #: zoom image
local win1, x1, y1, w1, h1
local win2, x2, y2, w2, h2
local x, y, scr
static type
initial type := proc("type", 0) # protect attractive name
if type(args[1]) == "window" then
win1 := get(args)
else
win1 := \&window | runerr(140, &window)
if type(args[1]) == "window" then
win2 := get(args)
else
win2 := win1
x1 := \get(args) | -WAttrib(win1, "dx")
y1 := \get(args) | -WAttrib(win1, "dy")
w1 := \get(args) | WAttrib(win1, "width") - (x1 + WAttrib(win1, "dx"))
h1 := \get(args) | WAttrib(win1, "height") - (y1 + WAttrib(win1, "dy"))
if w1 < 0 then
x1 -:= (w1 := -w1)
if h1 < 0 then
y1 -:= (h1 := -h1)
x2 := \get(args) | -WAttrib(win2, "dx")
y2 := \get(args) | -WAttrib(win2, "dy")
w2 := \get(args) | WAttrib(win2, "width") - (x2 + WAttrib(win2, "dx"))
h2 := \get(args) | WAttrib(win2, "height") - (y2 + WAttrib(win2, "dy"))
if w2 < 0 then
x2 -:= (w2 := -w2)
if h2 < 0 then
y2 -:= (h2 := -h2)
if w1 = 0 | w2 = 0 | h1 = 0 | h2 = 0 then
return
scr := ScratchCanvas(win2, w2, h1, "__Zoom__") | fail
every x := 0 to w2 - 1 do
CopyArea(win1, scr, x1 + w1 * ((x + 0.5) / w2), y1, 1, h1, x, 0)
every y := 0 to h2 - 1 do
CopyArea(scr, win2, 0, h1 * ((y + 0.5) / h2), w2, 1, x2, y2 + y)
EraseArea(scr) # release colors
return win1
end
# Capture(win, pal, x, y, w, h) -- capture screen region as image string
$define CaptureChunk 100
procedure Capture(win, pal, x, y, w, h) #: capture image as string
local a, c, k, s, t, cmap
static type
initial type := proc("type", 0) # protect attractive name
if type(win) ~== "window" then {
win :=: pal :=: x :=: y :=: w :=: h
win := \&window | runerr(140, &window)
}
/pal := "c1"
/x := -WAttrib(win, "dx")
/y := -WAttrib(win, "dy")
/w := WAttrib(win, "width") - (x + WAttrib(win, "dx"))
/h := WAttrib(win, "height") - (y + WAttrib(win, "dy"))
if w < 0 then
x -:= (w := -w)
if h < 0 then
y -:= (h := -h)
PaletteChars(win, pal) | runerr(205, pal)
cmap := table()
# accumulate the image in chunks and then concatenate
# (much faster than concatenating single chars on a very long string)
s := ""
a := []
every k := Pixel(win, x, y, w, h) do {
c := \cmap[k] | (cmap[k] := PaletteKey(win, pal, k))
if *(s ||:= c) >= CaptureChunk then {
put(a, s)
s := ""
}
}
put(a, s)
s := w || "," || pal || ","
while s ||:= get(a)
return s
end