=====================================================================
Functional PostScript Reference Manual
=====================================================================

      o Global Constants and Variables
          	pi 1/4pi 1/2pi 3/4pi 5/4pi 3/2pi 7/4pi 2pi	
		origin
		identity-matrix 
		afm-directory-path

      o	Point and Matrices
      		pt pt?
                pt:x pt:y pt=
		add-pts scale-pt negate-pt
		matrix? matrix=
		matrix
		matrix* 

      o Path
		path?
		line
		rect	  	
		arc	   
		tangent-arc
		curve
		close-path
		stroke-path   
		bitmap->path 
		the-empty-path

      o Font and Glyph Path Makers
		font 
      		char->glyphpath	
		int->glyphpath
		glyphname->glyphpath
		vector->glyphpath
		simple-string->glyphpath
		string->glyphpath

      o Composite
		compose	  compose-path   compose-pict
		join	  join-path      join-pict
		link

      o Picture
		picture?
		paint-glyphpath
      		stroke
		fill
		clip
		colormap
		bitmap->pict 
      		the-empty-pict

      o Transformation
		translate
		rotate
		scale

      o Style and Attributes
		style?
		attrib?
		vary-default  
		build-style
		with-style
		with-attrib
		:color
		:line-width
		:line-cap     
		:line-join    
		:dash-pattern
		:dash-offset
		:miter-limit

      o Colors
		color?
      		gray		gray:val
		rgb 		rgb:r rgb:g rgb:b
		hsb		hsb:h hsb:s hsb:b
		cmyk 		cmyk:c cmyk:m cmyk:y cmyk:k

      o Character Map and Integer Map
		char-map?
		base-char-map
		lookup-char-map
		function->char-map
		alist->char-map
		mask-char-map
		native-font-char-map

		int-map?
		base-int-map
		lookup-int-map
		function->int-map
		alist->int-map
		mask-int-map
		native-font-char-map

      o Path and Picture Info
		start-pt
		end-pt
		bounding-box

      o Bitmap
		bitmap?
		vector->bitmap
		hex-str->bitmap
		bin-str->bitmap
		bitmap-recolor

      o Output Channels
		show
		show-w/-ps2-text-channel
		ps2-text-channel
		close-channel

      o Options
		:creator       	:duplex
		:creation-date 	:duplex-tumble
		:title         	:num-copies
		:copyright     	:collate
		:for  		:orientation
		:routing  	:page-label   

      o Utilities
		rad->deg
		deg->rad
		inch
		bounding-box->rect

      o	Appendix A: Base Maps

      o Appendix B: The Missing Pieces



=====================================================================
Global Constants and Variables
=====================================================================

1/4pi 1/2pi 3/4pi pi 5/4pi 3/2pi 7/4pi 2pi    	        constant: real
origin							constant: pt
identity-matrix				   		constant: matrix

pi = 3.141593.
origin is (pt 0 0).
identity-matrix is (matrix 1 0 0 1 0 0)

====================

FPS_AFM_PATH						env variable

This env variable lists the directories where FPS should look for
.afm files. The directories are delimited by colon ":".




=====================================================================
Point and Matrix
=====================================================================

(pt x y)     -> pt					procedure
(pt?  obj)   -> boolean					procedure
(pt:x point) -> real					procedure
(pt:x point) -> real					procedure
(pt= p1 p2)  -> boolean					procedure

A point is a Cartesian coordinate reference in space. The origin point
(0,0) is located on the lower-left hand corner of the page; point
(1,0) is 1/72 inch to the right of the origin; point (0,1) is 1/72
inch above the origin, and so forth. 

The pt procedure constructs such a point in space. x and y are the
point's coordinates in real numbers.

pt:x and pt:y return the x and y coordinates of a point. pt?
determines whether a scheme-value is a point, and pt= determines
whether two points have the same x and y values.

====================

(add-pts point1 point2 ...)        -> pt		procedure
(scale-pt x-factor y-factor point) -> pt		procedure
(negate-pt point)                  -> pt		procedure

These are utility procedures for working with points. add-pts creates
a new point whose x and y coordinates are the sums of x and y
coordinates of all given points. scale-pt multiplies the x- and
y-factor with the x and y coordinates of the given point. negate-pt is
the same as (scale-pt -1 -1 point)

====================

(matrix a b c d tx ty)     -> matrix			procedure
(matrix? obj)              -> boolean			procedure
(matrix= matrix1 matrix2) -> boolean			procedure
(matrix* matrix1 matrix2)  -> matrix			procedure

A two-dimensional transformation is described mathematically by a 3x3
matrix:

	| a  b  0 |
	| c  d  0 |
	| tx ty 1 |

In FPS, the matrix is represented as a "matrix" record with six
fields, a b c d tx ty. The third column in the matrix is omitted
because it is constant. This matrix transforms a point (x,y) into
point (x',y') according to the linear equations:

	x' = ax + cy + tx
	y' = bx + dy + ty

matrix= tests if two matrices have the same six values.  matrix?
tests whether a scheme object is a matrix. matrix* multiplies two
matrices together. Remember that matrix multiplications are not
commutative, so the order of multiplication does matter.




=====================================================================
Path Makers

Paths are geometrical constructs on a plane that have a starting point,
an ending point, and a bounding box. They can be created from a 
variety of procedures (line, arc, etc). New paths can be formed by 
transformation and composition. Paths can be turned into pictures by 
the stroke and fill procedures.
=====================================================================

(path? scheme-value) -> boolean				procedure

path? determines whether some scheme value is a path.  A scheme
value is a path only if all of its components are paths.

====================

(line pt1 [pt2 pt3...]) -> path				procedure

line constructs a path made out of straight lines that goes from pt1
to pt2 to pt3 etc. There must be at least one point in a line. For
example,

	(line (pt 0 0) (pt 50 50) (pt 100 0))


====================

(rect pt width height) -> path				procedure

rect creates a closed rectangular path described by a corner on
pt (x,y) and the width and height of the rectangle.  The rectangle has
corners located at coordinates (x,y) (x+width, y) (x+width, y+height)
(x, y+height). Note that width and height can be negative. The
starting point and the ending point of rectangle is the corner
specified by the pt argument. For example,

	(rect (pt 100 100) -50 -50)


====================

(arc center-pt radius start-angle end-angle) -> path	procedure

arc constructs a path of a counterclockwise arc of a
circle. start-angle and end-angle are measured in radians
counterclockwise from the positive x-axis, as shown below.

			     1/2 pi 
				|
				|
		     pi	<---------------> 0 or 2 pi
		     		|
				|
			     3/4 pi	

The arc produced is circular. You can scale it to an ellipse.
Here is an example that makes a path of a 45-degree "pie slice"

	(close-path (link (line (pt 0 0) (pt 50 0))
		          (arc  (pt 0 0) 50  0  1/4pi)))

And here's an O shaped elliptical path:

	(scale 2 1 (arc (pt 0 0) 50 0 2pi)))

====================

(tangent-arc point1 point2 point3 radius) -> path	procedure

tangent-arc constructs a path of an arc as follows:

- point1 and point2 define tangent line 1
- point2 and point3 define tangent line 2
- The arc is defined by the radius and these two tangent lines.
  The center of the arc is located within the inner angle between
  the tangent lines. It is the only point located at distance 
  radius in a direction perpendicular to both lines.
- The arc begins at the first tangent point on the first tangent line,
  passes between this center and point2 and ends at the second
  tangent point on the second tangent line (this point is NOT point3,
  it is where the arc touches the second tangent line).

The above technical definition is probably difficult to understand
without a picture. What is tangent-arc good for anyway?  tangent-arc
is useful when, say, you want to construct a "rounded cornered"
rectangular frame. The crude ASCII art below shows such a frame. The
corners are not connected because we are going to draw them using
tangent-arc. To construct the upper left corner, we would call
tangent-arc with three points: 1) the point where the horizontal line
stops, 2) the point where the real corner of the frame is, and 3) the
point where the vertical line starts. The radius argument determines
how "curved" your corner will be.

			.  ______  .

			|	   |
			|	   |		
			.  ______  .

For an example of tangent-arc, see the square-to-circle example in
fps-example.scm.

====================

(curve start-pt ctrl-pt1 ctrl-pt2 end-pt) -> path	procedure

curve constructs a path of a Bezier curve using a start point, two
Bezier cubic control points, and an end point. The four points define
the shape of the curve.  The curve starts at start-pt and leaves the
point in that direction tangent to the line from start-pt to
ctrl-pt1. The curve approaches the end-pt from the direction tangent
to the line from ctrl-pt2 to end-pt and stops at end-pt. The curve is
always entirely enclosed by the convex quadrilateral defined by the
four points.

For example, (curve (pt 0 50) 
	            (pt 15 100) (pt 60 0)
		    (pt 75 50))
    would give you a tilde ~ shaped curve.

    	     (curve (pt 15 0)
	     	    (pt 125 200) (pt -50 200)
		    (pt 65 0))
    would give you a scripted l shaped curve.

====================

(close-path path) -> path				procedure

close-path constructs a path by appending a straight line from the end
point to the start point of the given path. If the given path is
already closed (for example, any circles, where end point equals to
start point), then close-path has no effect.

	(close-path (arc (pt 100 100) 100 (- 1/2pi) 1/2pi))

        would give you a D shaped curve.

====================

(stroke-outline-path path style) -> path		procedure

stroke-outline-path constructs a new path by outlining the picture
that would result if the given path were stroked with the given
style. For example,

      (stroke-outline-path (arc (pt 100 100) 100 0 2pi)
		           (build-style (vary-default) (:line-width 30)))

returns the outline of a circle of 30 pt thickness.

The path resulting from stroke-outline-path is suitable for filling
and clipping. In general, the path is not suitable for stroking, as it
is usually not a "simple outline" path but a path of many complex
interior segments or disconnected sub-paths.

====================

(bitmap->path bitmap transparent-val) -> path		procedure

bitmap->path creates a path from a bi-level (1-bit gray scale black
and white) bitmap. This path is suitable for filling and clipping.

How is this path created from a bitmap and what does the
transparent-val mean? Consider the following sample 3x3 bi-level
bitmap of a black + sign, where 'X' is black (0)and '-' is white (1).

		  -X-  or in binary  101
		  XXX                000
		  -X-                101

So (fill (bitmap->path plus-sign 0)) gives you a picture of a + sign.

And (fill (bitmap->path plus-sign 1)) gives you a picture of four
squares sitting where the '-' are in the bitmap.

====================

the-empty-path						constant: path

the-empty-path constant is a "null" path. You can combine
the-empty-path with other paths without making any side-effects.



=====================================================================
Font and Glyph Path Makers

Glyph path is a kind of path. It can be transformed and turned into
pictures just like all other paths. Glyph paths are pre-drawn paths
that tell us how characters such as "A", "B", "C" etc in a font should
be drawn.

In FPS, fonts are made up of the following: a collection of glyphs, a
character map, an integer map, and a transformation matrix. Glyphs are
data structures that associate strings (glyphnames) to a path
(glyphpath).  Character and integer maps are data structures that
associate characters and integers (such as #\A and 65) to glyphnames
("A").
=====================================================================

(font font-name size [char map | int map | matrix]) -> font	procedure
(font? scheme-value) -> boolean					procedure

You need to create fonts in order to create glyph paths. FPS uses
PostScript font to create and manipulate glyph paths. To use a
PostScript font, you must have the font's Adobe Font Metrics (AFM)
file the directory listed in the FPS_AFM_PATH env variable. FPS comes
with afm files for some common fonts: Helvetica.afm, Symbol.afm,
Courier.afm, etc.

Argument font-name must be a PostScript filename string (properly
cased like the AFM file filename). For example, if you installed a
font with the AFM file "Dingdong.afm", the font-name would be
"Dingdong". Argument size describes how big your glyphpaths are in
points. Of course, you can always scale your glyphpaths afterwards.

For example, to define a Helvetica 36 pt font:
	(define helv (font "Helvetica" 36))

You can then use it to create glyph paths;
	(string->glyphpath helv "Hola!")

Users can also specify their own char map, int map, and transformation
matrix. The char and int maps associate characters and integers to
glyphnames (refer to character and integer map sections for more
information) And the matrix is a transformation matrix that modify the
path (so you can do slant, rotate, flip, etc). These optional args do
not need to come in any order. By default, a font is created with
the identity matrix (no transformation) and the font's native charmap
and intmap (as described by the font's AFM file).

====================

(char->glyphpath font char [error-tag]) -> path | #f	procedure

char->glyphpath takes a scheme character, looks up the glyphname that
the character maps to in the font's character map, and returns the
corresponding glyphpath associated with the glyphname.
	
	(define helv36 (font "Helvetica" 36))
	(char->glyphpath helv36 #\A)

would give you the path of the letter 'A' in Helvetica 36 point.

error-tag determines what happens if the character does not map to
any glyphname in the font's character map. error-tag can be one of the
following:

'empty    Procedure returns the empty path. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.

====================

(int->glyphpath font int [error-tag]) -> path | #f	procedure

int->glyphpath takes an integer, looks up the glyphname that the
integer maps to in the font's integer map, and returns the
corresponding glyphpath associated with the glyphname. Using integers
to referece glyphs allows us to access fonts of arbitrarily large
collection of glyphs (Chinese font, for example) by associating glyphs
with an integer ID.

	(define helv36 (font "Helvetica" 36))
	(int->glyphpath helv36 64)

would give you the path of the letter 'A' in Helvetica 36 point.

error-tag determines what happens if the integer does not map to any
glyphname in the font's integer map. error-tag can be one of the
following:

'empty    Procedure returns the empty path. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.

====================

(glyphname->glyphpath font glyphname [error-tag]) -> path | #f 	procedure

glyphname->glyphpath takes a glyphname (a string), and returns the
corresponding glyphpath in the given font.

	(define helv36 (font "Helvetica" 36))
	(glyphname->glyphpath helv36 "copyright")

would give you the path of the copyright symbol in Helvetica 36 pt.

error-tag determines what happens if the glyphname is not found in the
given font. error-tag can be one of the following:

'empty    Procedure returns the empty path. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.

====================

(vector->glyphpath font vector [error-tag]) -> path | #f	procedure

vector->glyphpath takes a vector of characters, integers, glyphnames
(i.e. strings) finds the glyphpath that each element maps to, and
joins the paths together horizontally.

	(vector->glyphpath helvetica36 '#(#\A #\B #\C "trademark"))

	would give you a path consists of ABC followed by a trademark 
	symbol in Helvetica 36 pt.

This version of FPS only supports horizontal writing direction, we
would like to add in support for vertical writing in the next version
(for special effects or for Asian fonts). For now, if you want to
compose characters vertically, the glyphpaths of individual characters
have to be composed vertically together by writing a separate user
level procedure.

error-tag determines what happens if a glyphpath cannot be found for
any elements in the vector (invalid mapping, for example). error-tag
can be one of the following:

'empty    Procedure joins the empty path to the rest of the glyphpath.
	  i.e. The illegal element is turned into an empty path and has
          no side effects. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.

====================

(simple-string->glyphpath font string [error-tag]) -> path | #f procedure

simple-string->glyphpath takes a string, looks up the glyphname that
each character in the string maps to in the font's character map,
finds the glyphpath associated with the glyphname, and joins the
glyphpaths together horizontally.

What's a simple string? A simple string is a string with no special
interpretation for special "escape" characters. In an ordinary string
(see string->glyphpath), % begins an escape sequence. In
simple-string, % has no special meaning; it is simply printed as a
percent-sign.

This is useful for operations such as I/O with users, where one would
want to print all the characters in the string as is.

Vertical writing direction is not supported in this version. You must
write a user level procedure achieve the effect.

error-tag determines what happens if a glyphpath cannot be found for
a character in the string. error-tag can be one of the following:

'empty    Procedure joins the empty path to the rest of the glyphpath.
	  i.e. The illegal character is turned into an empty path and has
          no side effects. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.

====================

(string->glyphpath font string [error-tag]) -> path | #f	procedure

string->glyphpath takes a string and returns a glyphpath.  It acts very
much like the simple-string->glyphpath procedure, except that strings
can contain escape sequences.

	(define helv (font "Helvetica" 36))
	(string->glyphpath helv36 "Mushroom")

The string "Mushroom" does not contain any escape sequences, and
string->glyphpath behaves just like simple-string->glyphpath.

Escape sequences allow you to insert glyphnames and constants into the
string. They begin with a percent-sign % and ends with a colon :

%% prints a percent-sign.
%: is an empty escape sequence.

The escape sequences contain elements separated by at least one space
character.  Three kinds of elements may be found in an escape
sequence:

1) Glyphname - 	glyphnames are separated by space.
  
  (string->glyphpath helv36 "%semicolon period copyright:")

2) 8-bit Integers - 8-bit integers in hex are wrapped in a pair of
		parenthesis. FPS uses these integers to look up the 
		appropriate glyphs using the integer map.

  (string->glyphpath helv36 "%(023D437F):")

3) 16-bit Integers - 16-bit integers in hex are wrapped in a pair of
		square brackets. FPS uses these numbers to look up the
		appropriate glyphs using the integer map.

  (string->glyphpath helv36 "%[573A3D57]:")

Different accessing methods can be mixed in a single escape sequence.
For example: (string->glyphpath helv36 "A Test %(02) colon Lslash [234F]:")

Vertical writing direction is not supported in this version. You can 
write your own procedure to achieve the effect or borrow procedure from
the user library.

error-tag determines what happens if a glyphpath cannot be found for a
character in the string or an element in the escape
sequence. error-tag can be one of the following:

'empty    Procedure joins the empty path to the rest of the glyphpath.
	  i.e. The illegal character/element is turned into an empty
          path and has no side effects. This is the default.
'error    Scheme raises an exception.
#f        Procedure returns #f.


=====================================================================
Making Composite Paths and Pictures

You can create more complex paths and pictures by composing simpler
ones together. Three composite operators are presented: compose,
join, and link.
=====================================================================

(compose path1 [path2 ...])       -> path		procedure
(compose picture1 [picture2 ...]) -> picture		procedure

Since the compose procedure can handle paths and pictures, whenever
"path" is mentioned in this section, "or picture" is implied.

compose builds a new path by collecting many paths together.  No
transformation is done on any of the given paths; the first
path/picture is drawn, and the second is drawn right over it, and so
on, resulting in paths/pictures that come later in the composite list
obscuring ones that are earlier the list. Paths and pictures remain
disjoint after they are composed together.

The composite procedure must be called with at least one argument. The
arguments must be all paths or all pictures.

Let's say we want to draw a '%' sign:
	
	(compose (line (pt 0 0) (pt 100 100))	; the slanted line
		 (arc (pt 20 80) 15 0 (* 2 pi)) ; the top left circle
		 (arc (pt 80 20) 15 0 (* 2 pi))); the bottom right circle

====================

(compose-path [path1 path2 ...])       -> path		procedure
(compose-pict [picture1 picture2 ...]) -> picture	procedure

These procedures behave just like compose, except that they can take
zero arguments. When you call compose-path and compose-pict with no
arguments, the-empty-path and the-empty-pict are returned
respectively.

====================

(join path1 [path2 ...])       -> path			procedure
(join picture1 [picture2 ...]) -> picture		procedure

Since the join procedure can handle path and pictures, whenever
"path" is mentioned in this section, "or picture" is implied.

join builds a new path by "joining" given paths together. By 'joining'
we mean the following:

	- path1 is added to the new path. 
	- path2 is translated so that the start point of path2
	  is on the endpoint of path1.
	- path3 is translated so that the start point of path3
          is on the endpoint of path2. 
        - etc etc.

The join procedure must be called with at least one argument. The
arguments must be all paths or all pictures.

Note that when two paths are joined togher, they become a single
path (i.e. the line-join attribute applies to the junction between
paths).

====================

(join-path [path1 path2 ...])       -> path		procedure
(join-pict [picture1 picture2 ...]) -> picture		procedure

These procedures behave just like join, except that they can take zero
arguments. When you call join-path and join-pict with no arguments,
the-empty-path and the-empty-pict are returned respectively.

====================

(link [path1 path2 ...]) -> path				procedure

link builds new path by 'linking' the given paths together. By linking
we mean the following:

	- path1 is added to the new path. 
	- a straight line path that goes from the endpoint of
	  path1 to the start point of path2 is added.
	- path2 is added to the new path. 
	- a straight line path that goes from endpoint of
	  path2 to start point of path3 is added.
	- etc etc.

Note that when two paths are linked togher, they become a single
path (i.e. the line-join attribute applies to the junction between
paths).


=====================================================================
Picture Makers

Pictures can be thought of as "ink on paper". Pictures can be made
from lines (by stroke and fill), from bitmaps (bitmap->pict), or
from other pictures (colormap). Pictures can be transformed and
composed together to make new pictures.
=====================================================================

(paint-glyphpath path [style])      	    -> picture	procedure
(paint-glyphpath path [attrib1 attrib2 ..]) -> picture	procedure

paint-glyphpath paints the glyphpath using the method (stroke or fill)
as defined by the font itself. Most fonts are designed to be filled,
but there are outline fonts which are designed to be stroked. Unless
you specifically want to stroke or fill the glyphpath, use
paint-glyphpath whenever you can for better rendering performance.

You may also include a style or a number of attributes when calling
paint-glyphpath.  If you specify a style, the path is painted in that
style.  If you specify some attributes, the path is painted in the
style created by calling vary-default on those attributes.  If no
style or attributes args are supplied, the path is painted in the
current default style. 

====================

(stroke path [glyphpath-painter] [style])              -> picture   procedure
(stroke path [glyphpath-painter] [attrib1 attrib2 ..]) -> picture   procedure

stroke creates a picture by painting a line along the path using the
default style or the user specified style/attribute. If the path is
the-empty-path, stroke returns the-empty-pict.

You can specify a glyphpath-painter which tells FPS how to paint
the glyphpaths in the path. glyphpath-painter can be one of the following:

'native		This is the default painter. The painting method is
		defined by the font with which the glyphpath was created.
'stroke		Glyphpaths are stroked to produce outlines of the 
		characters.
'fill		Glyphpaths are filled to produce solid characters.

You may also include a style or a number of attributes when calling
stroke.  If you specify a style, the path is stroked in that style.
If you specify some attributes, the path is stroked in the style
created by calling vary-default on those attributes.  If no style or
attributes args are supplied, the path is stroked in the current
default style. For example, here's how to create a picture of an empty
green circle:

    	(define green (rgb 0 1 0))
       	(stroke circle-path (:color green))

====================

(fill path [glyphpath-painter] [style])              -> picture	    procedure
(fill path [glyphpath-painter] [attrib1 attrib2 ..]) -> picture	    procedure

The fill procedure creates a picture by painting the area enclosed by
the path in the color of the default style or the user specified
style/attribute. If the path is the-empty-path, fill returns
the-empty-pict.

You may specify a glyphpath-painter which tells FPS how to paint
the glyphpaths in the path. glyphpath-painter can be one of the following:

'native		This is the default painter. The painting method is
		defined by the font with which the glyphpath was created.
'stroke		Glyphpaths are stroked to produce outlines of the 
		characters.
'fill		Glyphpaths are filled to produce solid characters.

You may also include a style or a number of attributes when calling
fill.  If you specify a style, the path is filled in that style.  If
you specify some attributes, the path is filled in the style created
by calling vary-default on those attributes.  If no style or
attributes args are supplied, the path is filled in the current
default style. For example, here's how to create a picture of an empty
green circle:

	(define green (rgb 0 1 0))
	(fill circle-path (:color green))

====================

(clip path picture) -> picture				procedure

clip creates a new picture by cropping the given picture with the
given path. If the path or the picture is empty, then the-empty-pict
is returned. 

This example is taken from fps-examples.scm. It creates a picture of
'rays' and then clip the picture with a glyphpath.

(define (clip-msg msg)
  (let* ((times  (font "Times-BoldItalic" 84))
	 (m-path (simple-string->glyphpath times msg))
	 (max-pt (bounding-box:max (bounding-box m-path)))
	 (height (pt:y max-pt))
	 (width  (pt:x max-pt))
	 (l-len  (sqrt (+ (* (/ width 2) (/ width 2))
			  (* height height))))
	 (l          (line (pt 0 0) (pt (+ 150 width) 0)))
	 (angle-step .025)
	 (rays (translate (/ width 2) 0
			  (apply compose
				 (let recur ((angle 0))
				   (if (> angle pi) '()
				       (cons (rotate angle l)
					     (recur (+ angle 
						       angle-step)))))))))
    (translate 100 400
	       (clip m-path 
		     (stroke rays (:color (hsb 0.4 0.1 0.4)))))))

====================

(colormap c-func picture) -> picture			procedure

colormap creates a new picture by modifying the colors of the given
picture. The argument c-func is a color transformation function that
takes an FPS color as argument and returns an FPS color.  For example,

;; make some colors
(define red   (rgb 1 0 0))
(define green (rgb 0 1 0))

;; make a picture of green rectangle and a red circle
(define my-shape (compose (fill my-rectangle (:color green))	
			  (fill my-circle    (:color red))))	

;; color function that reduces brightness (darkens) the picture
(define (darken color) (hsb (hsb:h color)
			    (hsb:s color)
			    (- .2 (hsb:b color))))

;; now colormap the picture
(define new-color-shape (colormap darken my-shape))

==================== 

(bitmap->pict bitmap) -> picture			procedure

bitmap->pict creates a picture from a bitmap.  Once a bitmap is turned
into a picture, you can treat it like any other pictures
(i.e. compose, transformation, colormap).

Note that when recoloring a bitmap, you can specify the color
resolution to optimize resources usage. But once a bitmap is turned
into a picture, colormapping assumes that color resolution is
infinite.  Therefore, colormapping a picture created from a bitmap is
usually a very expensive operation. The cheaper way to do color
changes is to use the bitmap-recolor function, where you can specify
the color resolution needed. 

==================== 

the-empty-pict						constant: picture

the-empty-pict is a "null" picture. You can combine the-empty-pict
with other pictures without making any side-effects.



=====================================================================
Transformation

New paths and pictures can be created by translating, rotating,
and scaling existing ones. 
=====================================================================

(translate x y path)    -> path				procedure
(translate x y picture) -> picture			procedure

Since the translate procedure can handle paths and pictures, whenever
"path" is mentioned in this section, "or picture" is implied.

translate builds a new path by adding the x and y numbers to every
point in the path (or picture) and thereby moving the whole picture by
the x and y amount.

For example, 

	(define old-circle (arc (pt 0 0) 1 0 2pi))
	(define new-circle (translate 5 5 circle))

The new circle has center at point 5,5.

====================

(rotate angle path)    -> path				procedure
(rotate angle picture) -> picture			procedure

Since the rotate procedure can handle path and pictures, whenever
"path" is mentioned in this section, "or picture" is implied.

rotate builds a new path by rotating the given path around point
(0,0). The angle must be specified in radians.

For example, let's say that I have a square, called my-square.  The
square has its bottom left corner at point 0,0. Now let's rotate it by
45 degrees (or 1/2 pi in radians):

	(rotate 1/2pi my-square) 

This gives us a diamond whose bottom corner lands on point 0,0.


====================

(scale x-val y-val path)    -> path			procedure
(scale x-val y-val picture) -> picture			procedure

Since the scale procedure can handle path and pictures, whenever
"path" is mentioned in this section, "or picture" is implied.

scale builds a new path by multiplying every point in the old path by
x-val and y-val. If x-val and y-val are positive numbers, the path is
stretched or shrunk. If x-val and y-val are negative numbers, then the
path is not only stretched or shrunk, it is also reflected across the
axis.

For example, let's say that I have a path of a square, called my-sqr,
of width and height 1, and whose bottom left corner sits at point (0
0). Let's look at the following transformation:

(scale 2 3 my-sqr)  ;; stretches my-square into a 2 by 3 rectangle
(scale -1 1 my-sqr) ;; negate all x-coordinates, thereby "flipping"
                       the square across the y-axis. 
(scale 1/2 1/2 my-sqr);; shrunk the square to a quarter size.



=====================================================================
Style and Attributes

Style and attributes determine the outcome of stroking and filling
operations. Attributes are specific pieces of information such as line
width, color, dash, etc. A style is a collection of attributes.
=====================================================================

(style?  scheme-val) -> boolean				procedure
(attrib? scheme-val) -> boolean				procedure

The style? and attrib? predicates determine whether a scheme value is
a style or an attribute.

====================

(vary-default [attrib1 attrib2 ...]) -> style	procedure

vary-default builds a new style by altering the current default style
with the user specified attributes. The procedure takes zero or more
arguments.

The FPS system default style has the following attributes:

	(:color        (rgb 0 0 0)) ;black
	(:line-width   1)
	(:line-cap     'butt)
	(:line-join    'miter)
	(:dash         'none)
	(:dash-pattern '#())        ;solid line
	(:dash-offset  0)
	(:miter-limit 10)

Here's an example of building a style with color red and line width
of 5 points. You can then use this style, say, in a stroke operation.

         (define red-style (vary-default (:color (rgb 1 0 0)) 
                                         (:line-width 5)))
         (stroke my-line red-style)

my-line will be stroked in color red and line-width of 5 points.

====================

(build-style style [attrib1 attrib2 ...]) -> style	procedure

build-style builds a new style by altering the given style with the
user specified attributes. The style arg is mandatory.  There can be
zero or more attribute args.

Here's an example: we can build a generic "thick line" style,
and then alter it to draw in different colors.

	(define thick (vary-default (:line-width 20)))
	(define blue-thick   (build-style thick (:color (rgb 0 0 1))))
	(define yellow-thick (build-style thick (:color (rgb 1 1 0))))
	(join (stroke my-line   blue-thick)
	      (stroke my-circle yellow-thick))

====================

(with-style user-style exp ...) 			syntax
(with-style* style thunk) -> unspecific			procedural eqv

Using the with-style syntax, you can temporarily set the default style
to the specified user-style. i.e. all expressions inside with-style
use user-style as the default-style.

For example, let's say you want the next few paths to be stroked in
different line widths but all in green, you can do the following:

	(with-style (vary-default (:color (rgb 0 1 0)))
            (join (stroke my-line)
	          (stroke my-circle   (vary-default (:line-width 10)))
	          (stroke my-triangle (vary-default (:line-width 20)))))

====================

(with-attrib (attrib ...) exp ...) 			syntax

Using the with-attrib syntax, you can temporarily alter the current
default style with the specified attributes.

For example, you want to stroke a few paths in different line widths
but all in green, and you want the line width to be 5 if you don't
specify it in stroke:

	(with-attrib ((:color (rgb 0 1 0))
		      (:line-width 5))
            (join (stroke my-line)
	          (stroke my-circle   (vary-default (:line-width 10)))	
		  (stroke my-house)
	          (stroke my-triangle (vary-default (:line-width 20)))))

====================

(:color color) -> attrib				procedure

:color builds an instance of the color attribute.  The color attribute
determines the color with which the paths are stroked or filled. The
argument color is any FPS color.

For example.  (:color (rgb 1 0 0)) builds a red color attribute.

The FPS system default style has color attribute = black (gray 0)

====================

(:line-width width) -> attrib				procedure

:line-width builds an instance of the line-width attribute.  The
line-width attribute controls the thickness of the line painted by the
stroke operation. The stroke procedure paints all points whose
perpendicular distance from the current path in user space is less
than or equal to 1/2 the value of argument width.

The FPS system default style has line-width attribute = 1.

====================

(:line-cap cap-shape) -> attrib				procedure      

:line-cap builds an instance of the line-cap attribute.  The line-cap
attribute determines the ending shape of the lines painted by the
stroke operator. The different line cap geometry is specified by the
following cap shapes:

 'butt         Stroke is squared off at the endpoint of the path.
               There is no projection beyond the end of the path.

 'round        A semicircular arc with diameter equal to the line 
               width is drawn around the endpoint and filled in.	

 'project-square  The stroke continues beyond the endpoint of the
               path for a distance equal to half the line width and
               is squared off.

The FPS system default style has line-cap attribute = 'butt

====================

(:line-join join-shape) -> attrib			procedure

:line-join builds an instance of the line-join attribute.  The
line-join attribute determines the cornering shape of the lines
painted by the stroke operator. The different line join geometry is
specified by the following join shapes:

 'miter    The outer edges of the strokes for the two segments are
           extended until they meet at an angle, as in a picture
           frame.

 'round    A circular arc with diameter equal to the line width is
           drawn around the point where the segments meet and is filled
           in, producing a rounded corner.

 'bevel    The meeting path segments are finished with butt-end caps
           (see line-cap attribute); the the resulting notch beyond
           the ends of the segments is filled with a triangle.

Note that the line-join attribute is only relevant for segments of
straight line path created by a single 'line' procedure call.  (for
example, (line (pt 0 0) (pt 50 50) (pt 100 0))). The line-join
attribute does not apply to composite paths created by the compose,
join, or link procedure.

The FPS system default style has line-join attribute = 'miter

====================

(:dash-pattern pattern-vector) -> attrib		procedure

:dash-pattern builds an instance of the dash-pattern attribute.  The
dash-pattern attribute determines the the on-off sequence of the line
painted by the stroke operator. The pattern is specified as a vector
of positive integers, each integer represents the number of points on
(painted) or off (not painted). The vector begins with the 'on'
number, and then alternate between off and on.

For example:

(:dash-pattern '#())       ;solid lines
(:dash-pattern '#(2 1))    ;2 on, 1 off, 2 on 1 off, ...
(:dash-pattern '#(3 1 1 1) ;3 on, 1 off, 1 on, 1 off, 3 on, ..

The FPS system default style has dash-pattern attribute = #()

====================

(:dash-offset offset) -> attrib				procedure

:dash-offset builds an instance of the the dash-offset attribute. The
dash-offset attribute determines how far into the dash pattern does a
line begin.

For example:

(:dash pattern '#(8 4))
(:dash-offset  0)         ;8 on, 4 off, 8 on, 4 off

(:dash pattern '#(8 4))
(:dash-offset 6)          ;2 on, 4 off, 8 on, 4 off

The FPS system default style has dash-offset attribute = 0

====================

(:miter-limit num) -> attrib				procedure	

:miter-limit builds the miter-limit attribute that is used an an
argument to the style-building procedures or the with-attribute
syntax. Miter-limit controls the stroke operator's treatment of
corners when miter joins have been specified (see :line-join). When
path segments connect at a sharp angle, a miter join results in a
spike that extends well beyond the connection point. The purpose of
the miter limit is to cut off such spikes (i.e. convert them into
bevels) when they become objectionably long.

The radio of miter length to line width is directly related to the
angle x between the segments by the formula:

	miter length =     1
        ------------   ---------
         line width     sin (x/2)

For example: 
(:miter-limit 1.415) ;; cuts off miters at angles < 90 degrees.
(:miter-limit 2.0)   ;; cuts off miters at angles < 60 degrees.
(:miter-limit 10.0)  ;; cuts off miters at angles < 11 degrees.
(:miter-limit 1.0)   ;; cuts off miters at all angles (always bevel)

The FPS system default style has miter-limit attribute = 10.




=====================================================================
Colors
=====================================================================

(gray gray-val)  -> color				procedure

(gray:val color) -> real num between 0 and 1		procedure

gray creates a FPS color with the given gray-val. The argument
gray-val is a real number between 0 and 1, where 0 means no light
(black), and 1 means all the light (white), and intermediate values
are various shades of gray. Numbers outside of this range are rounded
to the nearest legal value.

gray:val converts a color to gray scale by desaturation and returns
the gray value.

====================

(rgb red-val green-val blue-val) -> color		procedure

(rgb:r color) -> real num between 0 and 1		procedure
(rgb:g color) -> real num between 0 and 1		procedure
(rgb:b color) -> real num between 0 and 1		procedure

rgb creates a FPS color with the given red, green, and blue values.
Color is formed by adding the specified amount of red, green, and blue
"lights" (i.e. red and green yields yellow, and equal amount of all
three lights yields white) The arguments specify the "intensity" of
the light and must be real numbers between 0 (no light of that color)
and 1 (all light of that color).  Numbers outside of this range are
rounded to the nearest legal value.

	(rgb 1 0  0)  ;; pure red
	(rgb 0 .5 1)  ;; greenish blue
	(rgb 1 1  1)  ;; white
	(rgb 0 0  0)  ;; black

rgb:r, rgb:g, and rgb:b return the red, green, and blue component of a
color.

====================

(hsb hue-val saturation-val brightness-val) -> color	procedure

(hsb:h color) -> real num between 0 and 1		procedure
(hsb:s color) -> real num between 0 and 1		procedure
(hsb:b color) -> real num between 0 and 1		procedure

hsb creates a FPS color with the given hue, saturation, and brightness
values. The arguments must be real numbers between 0 and 1.  Numbers
outside of this range are rounded to the nearest legal value.  In the
HSB model, colors are arranged on a "color wheel", and the arguments
determine where in the color wheel you land.

Hue: corresponds to the common notion of "color" such as purple or sky
blue. It specifies the angular position of a color on this wheel, with
pure red at 0, pure green at 1/3, pure blue and 2/3, and red at 1
again.  Intermediate hue values correspond to mixtures of the adjacent
colors.

Saturation: indicates how much of the hue there is. Saturation of 1
shows that the color has all its hue.  Saturation of 0 indicates that
none of the color's hue is visible, leaving only a shade of gray.  This
is why the technique used to convert color pictures to black-and-white
ones is known as "desaturation" - one simply sets all the saturation of
all the colors to 0.

Brightness: determines how light or how "bright" the color is.
Brightness of 0 is always black.  Brightness of 1 is shining all the
lights on the color.  You can "darken" a color by reducing its
brightness value.

	(hsb 0 1 1)  ;; the purest and brightest red
	(hsb 0 1 .5) ;; a darker red
        (hsb 0 1 0)  ;; black (zero brightness)

hsb:h, hsb, and hsb:b return the hue, saturation, and brightness
components of a color.
 
====================

(cmyk cyan-val magenta-val yellow-val black-val) -> color procedure

(cmyk:c color) -> real num between 0 and 1		procedure
(cmyk:m color) -> real num between 0 and 1		procedure
(cmyk:y color) -> real num between 0 and 1		procedure
(cmyk:k color) -> real num between 0 and 1		procedure

cmyk creates a FPS color from the cyan, magenta, yellow, and black
values.  The color is formed by adding the cyan, magenta, yellow, and
black "ink" together. The arguments specify the amount of ink applied
on a piece of white paper, where 0 means no ink (white) and 1 means
all the ink.  Numbers outside of this range are rounded to the nearest
legal value.

	(cmyk 1 1 0 0) ;; blue
	(cmyk 1 0 1 0) ;; green

cmyk:c, cmyk:m, cmyk:y, and cmyk:k return the cyan, magenta, yellow,
and black component of a color.

====================

(color= color1 color2) -> boolean			procedure

color= compares two FPS colors and determines whether they are the
same colors or not.




=====================================================================
Character and Integer Map

Recall that in FPS, a font is made up of three elements: a character
map, an integer map, an a collection of glyphs. Character and integer
maps are collections of key-value pairs, where the keys are characters
and integers and the values are strings representing glyphnames. 

Every font comes with its own native character and integer map. For
example, in Helvetica, character #\a maps to the glyphname "a" by
default, but in the Symbols font, #\a maps to the name "alpha". You
can change this mapping to access special characters.  For example,
instead of mapping #\! to "exclam", you may wish to map #\! to the
copyright symbol (with the glyphname "copyright"). You can do this by
creating new maps with the procedures described in this section.
=====================================================================

(char-map? scheme-val) -> boolean			procedure
(int-map?  scheme-val) -> boolean			procedure

char-map? and int-map? determine whether a scheme value is a character
map or an integer map.

====================

base-char-map						constant

In this version of FPS for ASCII Scheme, base-char-map contains the
Adobe standard mapping of characters to glyphnames, where the
character #\a maps to the glyphname string "a"; character #\1 maps to
glyphname "one" etc. (Appendix A contains the complete listing.)  This
charmap simply serves as a 'starting point' template character map for
the user. Since this version of FPS is written for ASCII Scheme, the
base-char-map only contains the 128 ASCII characters.  For unicode
Scheme, however, one may expect that the base-char-map contain
mappings for foreign characters to glyphnames.

====================

(function->char-map func) -> char map			procedure

function->char-map creates a new character map from the given
function.  The function must take a character as argument and return a
string which is a glyphname, or #f which indicates that the character
does not map to any glyphnames in this map.  All Scheme characters
will be fed through func, and key-value pairs for the character map
will be created from the characters and the glyphnames returned.

====================

(alist->char-map alist [default]) -> char map		procedure

alist->char-map creates a new character map from an alist. The alist
must be a list of a-pairs of characters and glyphname strings.  The
characters that are not specified in the alist are mapped to the
default value #f, or users can specify their own default value.

For example, we can create a character map that maps characters
a, b, and c to "alpha", "beta", and "gamma". All other characters
are mapped to the glyph "space".

(alist->char-map ((#\a . "alpha")
                  (#\b . "beta" )
		  (#\c . "gamma"))
		  "space")
		 
====================

(mask-char-map alist template-c-map) -> char map	procedure

mask-char-map creates a new char map from an existing char map and an
a-list.  This procedure makes a copy of the template-c-map and then
overwrites entries in the new map with the key-value pairs in the
a-list.

For example, we can create a new char map based on base-char-map where
the dieresis characters (also known as "umlout", as found in the
German alphabet set) are easily accessible from keyboard characters.

(mask-char-map ((#\* "adieresis") ;; "a" with two dots above it
	        (#\( "edieresis") ;; "e" with two dots above it
		(#\) "idieresis") ;; "i" with two dots above it
		(#\- "odieresis") ;; "o" with two dots above it
		(#\- "udieresis"));; "u" with two dots above it
	       base-char-map)

====================

(native-font-char-map font [default-val]) -> char map	procedure

native-font-char-map retrieves a given font's native character map as
defined in the font's AFM (Adobe Font Metrics) file.

The default-val allows you specify a glyphname to which all characters
which do not map to any glyphnames in the native map will be
mapped. If no default-val is specified, the characters that do not map
to glyphnames will be mapped to #f.

====================

(lookup-char-map c-map char) -> glyphname (string) | #f	procedure

You can use this procedure to find out what a character is mapped to
in a given character map. If the character is mapped to a glyphname,
then the glyphname is returned. If the character does not map to any
glyphnames, then #f is returned.

====================

base-int-map						constant

In this version of FPS for ASCII Scheme, base-int-map contains the
Adobe standard mapping of integers to glyphnames, where the integer 65
maps to the glyphname "a" and the integer 49 maps to the glyphname
"one" etc. (Appendix A contains the complete listing.) Since this
version of FPS is written for ASCII Scheme, base-int-map is 256
entries big.


====================

(function->int-map func map-size) -> int map		procedure

function->int-map creates a new integer map from the given function.
The function must takes an integer as an argument and return a string
which is a glyphname, or #f which indicates that the integer does not
map to any glyphnames in this map. Integers from 0 to (map-size - 1)
are fed through func, and key-value pairs for the integer map will be
created from the integers and the glyphnames returned.

====================

(alist->int-map alist map-size [default]) -> int map	procedure

alist->int-map constructs a new integer map from an alist. The alist
must be a list of a-pairs of positive integers and glyphname strings
The map-size arg specifies the range of integers (0 to mapsize-1) in
this integer map. The integers that are not specified in the alist are
mapped to a default value #f, or users can specify their own default
value.

====================

(mask-int-map alist template-i-map) -> int map		procedure

mask-int-map creates a new int map from an existing int map and an
a-list. This procedure makes a copy of the template-i-map and then
overwrites entries in the new map with the key-values pairs in the
a-list.

For example, we can modify the base-char-map so that the dieresis
characters (also known as "umlout", as found in the German alphabet
set) are accessible from easily remembered integers:

(mask-int-map ((1 "adieresis") ;; "a" with two dots above it
	       (2 "edieresis") ;; "e" with two dots above it
	       (3 "idieresis") ;; "i" with two dots above it
	       (4 "odieresis") ;; "o" with two dots above it
	       (5 "udieresis"));; "u" with two dots above it
	      base-int-map)

====================

(native-font-int-map font [default-val]) -> int map  	procedure

native-font-int-map retrieves a given font's native integer map as
defined in the font's AFM (Adobe Font Metrics) file.

The default-val allows you to specify a glyphname to which all
integers which do not map to any glyphnames in the native map will be
mapped. If no default-val is specified, the integers that do not map
to glyphnames will be mapped to #f.

====================

(lookup-int-map int-map int) -> glyphname (string) | #f	procedure

You can use this procedure to find out what an integer is mapped to in
a given integer map. If the integer is mapped to a glyphname, then the
glyphname is returned. If the integer does not map to any glyphnames,
then #f is returned.



=====================================================================
Path and Picture Info
=====================================================================

(start-pt path)    -> pt				procedure
(start-pt picture) -> pt				procedure
(end-pt path)      -> pt				procedure
(end-pt picture)   -> pt				procedure

Returns the starting point and ending point of paths and pictures.
the-empty-path and the-empty-pict have starting point and ending
point at pt (0,0).

====================

(bounding-box path)    -> bbox				procedure
(bounding-box picture) -> bbox				procedure

(bbox:max bbox) -> pt					procedure
(bbox:min bbox) -> pt					procedure

Returns the bounding box of a path or picture in the bbox record
in the fields 'max' and 'min' for the upper-right and the lower-left
corner. the-empty-path and the-empty-pict have bounding box whose
lower-left and upper-right corners land on pt (0,0).



=====================================================================
Bitmap

Bitmaps are matrices of colors. The matrix of colors is enumerated
horizontally from top-left-most sample point to the bottom-right-most
sample point, each sample point being a rectangular space that
contains a color value. Any bitmap can be turned into pictures but
only a bi-level (1-bit gray-scale) bitmap can be turned into path. You
can create new bitmaps by recoloing an existing one.
=====================================================================

(bitmap? scheme-val) -> boolean				procedure

The bitmap? predicate determines whether a scheme value is a bitmap.

====================

(vector->bitmap  row col res colorspace vect)   -> bitmap    procedure 

vector->bitmap creates a bitmap from a vector of integers. Recall that
bitmaps are matrices of colors, and so this procedure converts a
vector of numbers to a matrix of colors. Each element in the vector is
an integer that specifies a color value. How the vector gets turned
into a matrices of color depends on the color resolution and
colorspace.

The row and col specify the geometry and the number of total "sample
points" in the bitmap. The res argument specifies the color resolution
and can be either 1, 2, 4, 8, or 12 bits. So if res = 1 bit, your
vector can only contain 0 or 1. If res = 2 bits, your vector can
contain integers 0, 1, 2, or 3. If res = 8 bits, your vector can
contain integers ranging from 0 to 255.

The colorspace argument can be either the symbol 'gray or 'rgb. In the
gray colorspace, each sample point has a single value which is its
gray-scale value. In the rgb colorspace, each sample point has three
values, which is its red, green, blue values, respectively.  So the
vector length for a gray-scale bitmap would be row*col; but the vector
length for a color bitmap would be 3*row*rol. The bitmap is created
such that the matrix of colors

Let's say you want to create a 1x4 bitmap where each sample point is
either black or white:

	(vector->bitmap 1 4 1 'gray '#(1 0 1 0))

Or you can create a 1x4 bitmap in the rgb color space, and each sample
point only has 1 bit of resolution (8 colors all together):

	(vector->bitmap 1 4 1 'rgb '#(1 0 1   1 1 0   0 1 1   0 1 0))

Note that there are twelve numbers in the vector for the four sample points.
This is because each sample point needs a red, a green, and a blue value.

====================

(hex-str->bitmap row col res colorspace hex-str) -> bitmap    procedure
(bin-str->bitmap row col res colorspace bin-str) -> bitmap    procedure

hex-str->bitmap and bin-str->bitmap create bitmaps from hex strings
and binary strings. Recall that bitmaps are matrices of colors, so
these procedures convert a string of constants into matrices of
colors. The constant strings are converted into string of binary
constants, each digit representing a bit value. The procedure
traverses down the string and depending on the resolution and
colorspace, some number or some groups of number of bits are read off
and converted into colors.

The row and col specify the geometry and the number of total "sample
points" in the bitmap. The res argument specifies the color resolution
and can be either 1, 2, 4, 8, or 12 bits. To construct the bitmap, the
string constants get converted into a stream of binary digits, if res
= 1 bit, every 1 binary digit is interpreted as a sample point color;
if res = 2 bits, every 2 binary digits is interpreted as a sample
point color; and so on.

The colorspace argument can be either the symbol 'gray or 'rgb. In the
gray colorspace, each sample point has a single value which is its
gray-scale value. In the rgb colorspace, each sample point has three
values, which is its red, green, blue values, respectively.

Let's say you want to create a 1x4 bitmap where each sample point is
either black or white:

	(bin-str->bitmap 1 4 1 'gray "1010") or
	(hex-str->bitmap 1 4 1 'gray "A")

Or you can create a 1x4 bitmap in the rgb color space, and each sample
point only has 1 bit of resolution (8 colors all together):

	(bin-str->bitmap 1 4 1 'rgb "101110011010")
	(hex-str->bitmap 1 4 1 'rgb "B9A")

Note that there are twelve binary digits in the string for the four
sample points.  This is because each sample point needs a red, a
green, and a blue value.

====================

(bitmap-recolor bitmap c-func) -> bitmap		procedure

bitmap-recolor creates a new bitmap by modifying the given bitmap's
color with the c-func. The c-func argument is a function that takes
three arguments (red, green, and blue value) and returns three values
(red, green, blue) using the Scheme multiple-return "values"
procedure. For example, the following in a c-func that removes the red
component:

	(lambda (r g b) (values 0 g b))



===================================================================== 
Output Channels             

Channels are mechanisms for rendering pictures on specific targets
such as PostScript printers, screens, etc.
=====================================================================

(show channel picture [options]) -> unspecific		procedure

show renders the picture on some output target.  The channel argument
specify how the rendering is done. For example, a ps2-text-channel
outputs PostScript text to a Scheme output port, but a
Ghostscript-channel could render directly to an X display.

You may specify some FPS options which supply additional information
about how this picture is rendered.

==================== 

(show-w/ps2-text-channel filename-or-port picture [options])
-> unspecific						procedure

show-w/ps2-text-channel shows the picture like show does, but creates
a channel from the given filename-or-port and automatically closes the
channel at the end of the show-picture. The arg filename-or-port can
be a string (filename) or any scheme port.

You may specify some FPS options which supply additional information
about how this picture is rendered.

==================== 

(channel? scheme-val) -> boolean			procedure

The channel? predicate determines whether a scheme value is a channel.

==================== 

(ps2-text-channel filename-or-port [options]) -> channel  procedure

Creates a ps2-text-channel given a filename (a string) or any other
scheme port.

==================== 

(close-channel channel) -> unspecific			procedure

close-channel explicitly closes a channel. For a ps2-text-channel, the
procedure forces all text output to be written to the file (or port)
and closes the file (or port). If you don't use
show-w/ps2-text-channel, you must close the channel to force all
output from the text buffer and into the file (or port).



=====================================================================
Options

Options are extra information and switches supplied by the user about
the picture(s) that are going to be drawn. 
=====================================================================

(:format str)  -> option				procedure

This option specify the format of the output. For ps2-text-channel,
instead of printing out plain PostScript, you can specify (:format
"EPS) to get Encapsulated PostScript file format. Default format 
is normal plain PostScript (non EPS).

====================

(:creator str)       -> option				procedure
(:creation-date str) -> option				procedure
(:title str)         -> option				procedure
(:copyright str)     -> option				procedure
(:for str)           -> option				procedure
(:routing str)       -> option				procedure

These options are for documentation and informational use. For PS2-text
output, these information are printed out at the beginning of the text
output and may be interpreted as useful info by your print manager or
previewer.  These options only take effects when they are called with
channel makers or with show-w/channel.

====================

(:duplex boolean)               -> option		procedure
(:duplex-tumble boolean)        -> option		procedure
(:num-copies int)               -> option		procedure
(:collate boolean)              -> option		procedure
(:orientation orientation)      -> option		procedure

These options specify how the pages are printed on paper. Since they
are interpreted only when they are called with channel makers or with
show-w/channel, these options cannot be changed after a channel is
created. Note that these options are largely device dependent.  For
example, if your printer is not capable of double-sided printing, the
:duplex option will have no effect.

:duplex is set to #f by default. When it is set to true, you get
double-sided printing.

:duplex-tumble is set to #f by default. When it is set to true, you
get double-sided printing, but the picture on the back side of the
page is rotated 180 degree -- the resulting set of pages is suitable
for binding at the top or the bottom.

:num-copies is set to 1 by default. This option specifies how many
copies of the document, that is, all pages output by the channel,  
are printed.

:collate is set to #f by default. This option determines how the
output is organized when multiple copies are requested (by
:num-copies) for a multiple-page document. Output consists of 'sets'
of pages that are delivered together. If :collate is #t, a set
consists of one copy of all pages of the document. If :collate is #f,
a set consists of all copies of one page of the document.

:orientation specifies the orientation of the picture when it is
printed on the page from this channel. The arg orientation can be one
of the following:

	'normal		Normal default orientation.
	'rotate-left	Rotate the image on the page 90 degrees counter-
			clockwise with respect to the default orientation.
	'rotate-right	Rotate the image on the page 90 degrees clockwise
			with respect to the default orientation.
	'upside-down	Rotate the image 180 degrees with respect to the 
			default orientation.

====================

(:page-label label) -> option			procedure

:page-label specifies the label associated with a particular picture.
The option only takes effect when it is called with the show
procedure. The arg label is any scheme-value that can be displayed
(could be a string, a number, a symbol, etc). Page labels to not have
to be the physical page numbers, it could be the title of the page or
anything else that you like. If the page-label option is not
specified, FPS automatically assumes the physical page number of the
picture to be the page label. Page labels are especially useful for
viewing your multi-page picture in postscript previewers such as
ghostview. ghostview uses these numbers to help you navigate through
the PostScript document.

Some examples of page-labels:

(:page-label "Intro")  ;; intro page
(:page-label 1)        ;; first page with Arabic numeral 1
(:page-label 'ii)      ;; first page with Roman numeral 2




=====================================================================
Utilities
=====================================================================

(deg->rad real) -> real					procedure
(rad->deg real) -> real					procedure

These procedures convert angle measurements between degrees and
radians.

====================

(inch real)      -> real				procedure

This procedure converts inch to point by multiplying the arg by
72. For example, 

	(translate 0 (inch 4.5) my-picture)
	(translate 0 (* 72 4.5) my-picture)

The two expressions above are equivelant: they move my-picture up 4.5
inches (or 4.5 * 72 points)

====================

(bounding-box->rect box) -> path			procedure

This procedure builds a rectangle path out of the min/max points of
a bounding box.


=====================================================================
Appendix A: Base Maps
=====================================================================

base-char-map and base-int-map

	Integer 	Character	Glyphname
	-------------------------------------------------------
	0 to 31				notdef (the-empty-path)
	32				space
	33 		 !		exclam 
	34 		 "		quotedbl 
	35 		 #		numbersign 
	36 		 $		dollar 
	37 		 %		percent 
	38 		 &		ampersand 
	39 		 '		quoteright 
	40 		 (		parenleft 
	41 		 )		parenright 
	42 		 *		asterisk 
	43 		 +		plus 
	44 		 ,		comma 
	45 		 -		hyphen 
	46 		 .		period 
	47 		 /		slash 
	48 		 0		zero 
	49 		 1		one 
	50 		 2		two 
	51 		 3		three 
	52 		 4		four 
	53 		 5		five 
	54 		 6		six 
	55 		 7		seven 
	56 		 8		eight 
	57 		 9		nine 
	58 		 :		colon 
	59 		 ;		semicolon 
	60 		 <		less 
	61 		 =		equal 
	62 		 >		greater 
	63 		 ?		question 
	64 		 @		at 
	65 		 A		A 
	66 		 B		B 
	67 		 C		C
	68 		 D		D 
	69 		 E		E 
	70 		 F		F 
	71 		 G		G 
	72 		 H		H 
	73 		 I		I 
	74 		 J		J 
	75 		 K		K 
	76 		 L		L 
	77 		 M		M 
	78 		 N		N 
	79 		 O		O 
	80 		 P		P 
	81 		 Q		Q 
	82 		 R		R 
	83 		 S		S 
	84 		 T		T 	
	85 		 U		U 
	86 		 V		V 
	87 		 W		W 
	88 		 X		X 
	89 		 Y		Y 
	90 		 Z		Z 
	91 		 [		bracketleft 
	92 		 \		backslash 
	93 		 ]		bracketright 
	94 		 ^		asciicircum 
	95 		 _		underscore 
	96 		 `		quoteleft 
	97 		 a		a 
	98 		 b		b 
	99 		 c		c
	100 		 d		d 
	101 		 e		e 
	102 		 f		f 
	103 		 g		g 
	104 		 h		h 
	105 		 i		i 
	106 		 j		j 
	107 		 k		k 
	108 		 l		l 
	109 		 m		m 
	110 		 n		n 
	111 		 o		o 
	112 		 p		p 
	113 		 q		q 
	114 		 r		r 
	115 		 s		s 
	116 		 t		t 
	117 		 u		u 
	118 		 v		v 
	119 		 w		w 
	120 		 x		x 
	121 		 y		y 
	122 		 z		z 
	123 		 {		braceleft 
	124 		 |		bar 
	125 		 }		braceright 
	126 		 ~		asciitilde 
	127 to 160			notdef (the-empty-path)
	161 		 		exclamdown 
	162 		 		cent 
	163 		 		sterling 
	164 		 		fraction 
	165 		 		yen 
	166 		 		florin 
	167 		 		section 
	168 		 		currency 
	169 		 		quotesingle 
	170 		 		quotedblleft 
	171 		 		guillemotleft 
	172 		 		guilsinglleft 
	173 		 		guilsinglright 
	174 		 		fi 
	175 		 		fl 
	177 		 		endash 
	178 		 		dagger 
	179 		 		daggerdbl 
	180 		 		periodcentered 
	182 		 		paragraph 
	183 		 		bullet 
	184 		 		quotesinglbase 
	185 		 		quotedblbase 
	186 		 		quotedblright 
	187 		 		guillemotright 
	188 		 		ellipsis 
	189 		 		perthousand 
	191 		 		questiondown 
	193 		 		grave 
	194 		 		acute 
	195 		 		circumflex 
	196 		 		tilde 
	197 		 		macron 
	198 		 		breve 
	199 		 		dotaccent 
	200 		 		dieresis 
	202 		 		ring 
	203 		 		cedilla 
	205 		 		hungarumlaut 
	206 		 		ogonek 
	207 		 		caron 
	208 		 		emdash 
	225 		 		AE 
	227 		 		ordfeminine 
	232 		 		Lslash 
	233 		 		Oslash 
	234 		 		OE 
	235 		 		ordmasculine 
	241 		 		ae 
	245 		 		dotlessi 
	248 		 		lslash 
	249 		 		oslash 
	250 		 		oe 
	251 		 		germandbls 
	252 to 256			notdef (the-empty-path)

=====================================================================
Appendix B: The Missing Pieces
=====================================================================	

Features that will be included in future version of FPS:

1) Kerning	Spacing adjustment between each pair of glyph
	  	in the glyphpath.

2) Pattern	Filling with any picture by tiling the picture
		across the page.

3) CID Fonts	Access to fonts with big glyph sets such as Chinese, 
		Japanese, Korean fonts.

4) Vertical Writing	Connectng glyphpaths of individual glyphs from 
			top to bottom, achieving the vertical writing
			direction effect.

=====================================================================
Copyright (C) 1996 by Wandy Sae-Tan and Olin Shivers









