english
version "1.0"
identify "xyz"

#: Copyright (c) 1994, 1995, 1997, 2000-2006 by Wayne C. Gramlich.
#, All rights reserved.
#,
#, Permission to use, copy, modify, distribute, and sell this software
#, for any purpose is hereby granted without fee provided that the above
#, copyright notice and this permission are retained.  The author makes
#, no representations about the suitability of this software for any purpose.
#, It is provided "as is" without express or implied warranty.

module plot

#: This module implements a Gerber photo plotter output generator.

define aperture_kind
    enumeration
	circle				#: Circle aperture
	rectangle			#: Rectangle aperture
	oval				#: Oval aperture
    generate equal, print, unsigned_convert

define hole_kind
    enumeration
	circle				#: Circle hole
	rectangle			#: Rectangle hole
	none				#: No hole
    generate equal, print, unsigned_convert

define aperture
    record
	height unsigned			#: Height in ".00001
	hole_kind hole_kind		#: Kind of hole
	hole_height unsigned		#: Hole height in ".00001
	hole_width unsigned		#: Hole width in ".00001
	number unsigned			#: Aperture number (between 10 and 99)
	kind aperture_kind		#: Kind of aperture
	text string			#: Usage text
	width unsigned			#: Width in ".00001
    generate address_get, allocate, erase, identical, print

define aperture_format			#: Aperture format
    enumeration
	apt				#: .APT
	apr				#: .APR
    generate equal, print, unsigned_convert

define apertures
    record
	cell_width unsigned		#: Cell width ".05000
	character_aperture aperture	#: Thick line aperture (6 mil circle)
	list vector[aperture]		#: Aperture declaration strings
	thick_aperture aperture		#: Thick line aperture (62 mil circle)
	thick_line_width unsigned	#: Thick line width
	thin_aperture aperture		#: Thin line aperture (12 mil circle)
  	thin_line_width unsigned	#: Thin line width
	separation_width unsigned	#: Minimum distance between features
	shaved_width unsigned 		#: Shaved width of pad
	unshaved_width unsigned 	#: Unshaved width of pad
    generate allocate, erase, print

define drill
    record
	aperture_all_shave aperture	#: Aperture number shaved N, E, W, & S
	aperture_east_west_shave aperture #: Aperture number shaved E & W
	aperture_no_shave aperture	#: Aperture number without shaving
	aperture_north_south_shave aperture #: Aperture number shaved N & S
	count unsigned			#: Holes drilled for each drill
	diameter unsigned		#: Diameter in .00001"
	number unsigned			#: Drill number in drill rack
    generate allocate, erase, print

define drill_rack			#: Drill rack
    record
	drills vector[drill]		#: Drills in drill rack
	total unsigned			#: Total number of wholes drilled
    generate allocate, erase, print

define extra				#: Extra Gerber line
    record
	x1 unsigned			#: First X coordinate
	y1 unsigned			#: First Y coordinate
	x2 unsigned			#: Second X coordinate
	y2 unsigned			#: Second Y coordinate
	layer layer			#: Layer to draw in
	aperture unsigned		#: Aperture to use
    generate allocate, erase, print

define plot				#: The plotter data
    record
	debug_stream out_stream		#: Debugging output stream
	dx unsigned			#: Amount to add to each X in gerber
	dy unsigned			#: Amount to add to each Y in gerber
	extras vector[extra]		#: Extra lines
	error_stream out_stream		#: Error output stream
	geometry geometry		#: {geometry} object
	lines_drawn_count unsigned	#: Number of lines drawn
	lines_total unsigned		#: Total number of lines to be drawn
	plot_lines vector[plot_line]	#: All {plot_line}'s
	plot_nodes plot_nodes		#: All of the {plot_node}'s
	rotate unsigned			#: Current rotation for aggregation
	strings_drawn_count unsigned	#: Number of strings drawn
	strings_total unsigned		#: Total number of strings to be drawn
	vias_drawn_count unsigned	#: Number of vias drawn count
	vias_total unsigned		#: Total number of vias to be drawn
	with_hole_diameters logical	#: Apertures have hole widths.
	x_offset unsigned		#: X offset for reading
	y_offset unsigned		#: Y offset for reading
	package_table table[string, package] #: Package table
	part_table table[string, part_root] #: Part table
	board_part_table table[string, board_part] #: Board part table
	board_table table[string, table[string, board_part]] #: Master table
    generate allocate, erase, print

define plot_line			#: One line of plot
    record
	drawn logical			#: {true} => line drawn
	layer layer			#: Layer line occurs on
	thickness line_thickness	#: Line thickness
	plot_node1 plot_node		#: {plot_node} at one end
	plot_node2 plot_node		#: {plot_node} at one end
	x_offset unsigned		#: X offset
	y_offset unsigned		#: Y offset
    generate allocate, erase, identical, print

define plot_node			#: One node of plotting
    record
	draws_list vector[vector[draw]]	#: Extra artwork or ??
	draws_orientation character	#: Extra artwork orientation
	plot_strings vector[plot_string] #: {plot_strings} to plot
	plot_lines vector[plot_line]	#: The lines attached to this cell
	hole_number unsigned		#: Drill number for hole
	hole_drilled logical		#: {true}=>hole has been drilled
	shave_east logical		#: {true}=>east side of via shaved
	shave_north logical		#: {true}=>north side of via shaved
	shave_south logical		#: {true}=>south side of via shaved
	shave_west logical		#: {true}=>west side of via shaved
	search_flags unsigned		#: Search flags
	symbol string			#: Symbol for node
	via logical			#: {true}=>via present
	via_drawn logical		#: {true}=>via drawn
	x unsigned			#: X coordinate
	x_offset integer		#: X offset of node
	y unsigned			#: Y coordinate
	y_offset integer		#: Y offset of node
    generate address_get, allocate, erase, identical, print

define plot_nodes			#: The plotter nodes
    record
	nodes vector[vector[plot_node]]	#: The {plot_nodes}
	plot plot			#: Parent {plot} object
	x_maximum unsigned		#: Maximum x coordinate
	y_maximum unsigned		#: Maximum y coordinate
    generate allocate, erase, identical, print

define plot_operation			#: Plotter operation
    enumeration
	line_draw			#: Draw a line
	move				#: Move
	move_and_flash			#: Move, then flash
    generate equal, print, unsigned_convert

define plot_search			#: Search state
    record
	distance integer		#: Current distance around perimeter
	flags unsigned			#: Mark flags
	plot plot			#: {plot} object to search
	radius integer			#: Current radius from origin
	radius_maximum integer		#: Maximum radius to search
	x_maximum integer		#: Maximum x cooridiate
	y_maximum integer		#: Maximum y cooridiate
	x_origin integer		#: X origin
	y_origin integer		#: Y origin
    generate allocate, erase, print

define plot_stream			#: Gerber/Excellon output stream
    record
	aperture aperture		#: Current aperture
	apertures apertures		#: All apertures
	block string			#: Block of commands
	block_size_maximum unsigned	#: Maximum characters in block
	command string			#: Command buffer
	debug_stream out_stream		#: Debug stream
	distance_buffer string		#: Distance buffer
	dx unsigned			#: Amount to add to each X in gerber
	dy unsigned			#: Amount to add to each Y in gerber
	font vector[string]		#: Character font
	fraction_digits unsigned	#: Digits after implied decimal point
	incremental logical		#: {true}=>incremental;{false}=>abs.
	out_stream out_stream		#: Output stream
	plot plot			#: Plot object
	whole_digits unsigned		#: Digits before implied decimal point
	x unsigned			#: The last x coordinate
	y unsigned			#: The last y coordinate
	zero_supression zero_supression	#: Zero supression for numbers
    generate allocate, erase, identical, print

define plot_string			#: A string to plot
    record
	characters vector[unsigned]	#: Characters to plot
	drawn logical			#: {true}=>characters plotted
	layer layer			#: Layer to plot on
	transpose logical		#: {true}=>plot transposed string
    generate allocate, erase, identical, print
	
define zero_supression
    enumeration
	leading				#: Leading zero supression
	none				#: No zero supression
	trailing			#: Trailing zero supression
    generate equal, print



#: {aperture} routines:

procedure aperture_write@aperture
    takes
	aperture aperture
	format aperture_format
	out_stream out_stream
    returns_nothing

    #: This procedure will output {aperture} to {out_stream}.


procedure create@aperture
    takes
	kind aperture_kind
	width unsigned
	height unsigned
	hole_kind hole_kind
	hole_width unsigned
	hole_height unsigned
	text string
    returns aperture

    #: This procedure will create and return a new {aperture} object
    #, containing {kind}, {height}, {width}, {hole_kind}, {hole_height},
    #, {hole_width}, and {text}.


procedure comment_write@aperture
    takes
	aperture aperture
	out_stream out_stream
    returns_nothing

    #: Output an aperture comment for {aperture} to {out_stream}.


procedure declaration_write@aperture
    takes
	aperture aperture
	with_hole_diameter logical
	out_stream out_stream
    returns_nothing

    #: This procedure will write the declaration for {aperture} out
    #, to {out_stream}.  If {with_hole_diameter} is {true}@{logical},
    #, the output hole diameter is also output.


#: {apertures} routines:

procedure create@apertures
    takes
	thin_line_width unsigned
    returns apertures

    #: This procedure will create and return a new {apertures} object.


procedure append@apertures
    takes
	apertures apertures
	aperture aperture
    returns unsigned

    #: This procedure will append {aperture} to {apertures}.


procedure declarations_write@apertures
    takes
	apertures apertures
	with_hole_diameter logical
	out_stream out_stream
    returns_nothing

    #: This procedure will write the declarations for {apertures} out
    #, to {out_stream}.  If {with_hole_diameter} is {true}@{logical},
    #, any hole diameter is output as well.


procedure apertures_write@apertures
    takes
	apertures apertures
	file_name string
	format aperture_format
	error_stream out_stream
    returns logical

    #: This procedure will write out an aperture file:


#: {drill} routines:

procedure create@drill
    takes
	diameter unsigned
	outer_diameter unsigned
	apertures apertures
    returns drill

    #: This procedure will create and return a {drill} with a diameter
    #, of {diamenter} measured in ".00001".

    #: We want to make sure that the "via" overlaps the plated
    #, hole material.  So, we subtract .008" from the diameter
    #, make sure that there is .004" of overlap all around the hole.

procedure declaration_write@drill
    takes
	drill drill
	out_stream out_stream
    returns_nothing

    #: This procedure will write out the NC drill file declaration
    #, for {drill}.


#: {drill_rack} routines:

procedure append@drill_rack
    takes
	drill_rack drill_rack
	drill drill
    returns_nothing

    #: This procedure will append {drill} to {drill_rack}.


procedure create@drill_rack
    takes
	rack_file_name string
	apertures apertures
    returns drill_rack

    #: This procedure will return a {drill_rack}.  If {rack_file_name}
    #, is non-empty, it will be opened and read to identify the
    #, drill sizes.  Otherwise, the drill sizes are default to the
    #, ones used by Alberta Printed Circuits.


procedure fetch1@drill_rack
    takes
	drill_rack drill_rack
	index unsigned
    returns drill

    #: This procedure will return the {index}'th drill size from {drill_rack}
    #, tenth mils (.0001").


procedure increment@drill_rack
    takes
	drill_rack drill_rack
	index unsigned
    returns_nothing

    #: This procedure will incremnt the hole count for the {index}'th
    #, drill in {drill_rack}.


procedure size_get@drill_rack
    takes
	drill_rack drill_rack
    returns unsigned

    #: This procedure will return the number of drills in {drill_rack}.


procedure total_holes@drill_rack
    takes
	drill_rack drill_rack
    returns unsigned

    #: This procedure will return the total number of holes
    #, drilled with {drill_rack}.


#: {plot} routines:

procedure characters_insert@plot
    takes
	plot plot
	layer layer
	x unsigned
	y unsigned
	characters_transpose logical
	characters vector[unsigned]
    returns logical

    #: This procedure will insert {characters} into {plot} at ({x}, {y})
    #, on {layer}.  If {characters_transpose} is {true}, the characters
    #, will be transposed.  If any errors occur, {true} is returned
    #, {false} otherwise.


procedure chunk_layer_insert@plot
    takes
	plot plot
	layer layer
	x unsigned
	y unsigned
	name string
    returns logical

    #: This procedure will insert a glyph into the output.  Since
    #, plotting does not support glyphs, this procedure is a no-op.


procedure create@plot
    takes
	error_stream out_stream
	debug_stream out_stream
	geometry geometry
	with_hole_diameters logical
    returns plot

    #: This procedure will create and return a newly allocated {plot}
    #, object and containing {error_stream} and {debug_stream}.


procedure connection_insert@plot
    takes
	plot plot
	x unsigned
	y unsigned
	hole_number unsigned
    returns logical

    #: This procuedure will insert a via at ({x}, {y}) with a 
    #, hole number of {hole_number} in {plot}.  {true} is returned
    #, if there are any errors and {false} otherwise.


procedure generate@plot
    takes
	executable_directory string
	file_names vector[string]
	base_name string
	characters_transpose logical
	inverted_image logical
	geometry geometry
	aggregate logical
	with_hole_diameters logical
	rack_file_name string
	cnc_drll logical
	thin_line_width unsigned
	error_stream out_stream
	debug_stream out_stream
	timer timer
    returns logical

    #: This procedure will read the .pcb file in {file_name} and
    #, output five RS274X files (i.e. "Gerber" format) for the
    #, the top, bottom layer, the top and bottom artwork layer,
    #, and the mask layer in addition to a NC drill file
    #, in "Excellon" format for the drills.  The file name for
    #, the bottom layer is {base_name}.gbl (i.e. Gerber Bottom
    #, Layer), for the top layer is {base_name}.gtl (i.e. Gerber
    #, Top Layer), for the artwork layer {base_name}.gal (i.e.
    #, Gerber Artwork Layer), for the reverse artwork layer
    #, {base_name}.grl for (Gerber Reverse artwork Layer), and
    #, for the mask layer {base_name}.gml (i.e. Gerber Masktom
    #, Layer), for the top layer is {base_name}.gtl (i.e. Gerber
    #, Top Layer), for the artwork layer {base_name}.gal (i.e.
    #, Gerber Artwork Layer), for the reverse artwork layer
    #, {base_name}.grl for (Gerber Reverse artwork Layer), and
    #, for the mask layer {basem _name}.gml (i.e. Gerber Mask Layer.)
    #, The file name for the drill file is {base_name}.drl (i.e.
    #, DRilL) and its corresponding "tool" file is {base_name}.tol
    #, (i.e. TOoL.)  The reasons for using the three character
    #, suffixes is because sometimes these files are viewed on crufty
    #, MS DOS with 8+3 file names.  {characters_transpose} specifies
    #, whether strings are to be transposed and mirroed.
    #, {inverted_image} specifies whether the entire image is
    #, to be mirrored (not implmented yet!)  The remaining options
    #, should be obvious.


procedure drill_generate@plot
    takes
	plot plot
	out_stream out_stream
	drill_rack drill_rack
	error_stream out_stream
	drill_first logical
    returns logical

    #: This procedure will output an Excellon NC Drill file to
    #, {file_name} for {plot}.  {drill_rack} specifies the drill rack.
    #, Any errors are output to {error_stream} and {true} is returned.


procedure layer_plot@plot
    takes
	plot plot
	plot_stream plot_stream
	layer layer
	transpose logical
	drill_rack drill_rack
	apertures apertures
	error_stream out_stream
    returns logical

    #: This procedure will output an RS274X file to "file_name"
    #, that contains the instructions for rendering the {layer}
    #, layer of {plot}.  If {transpose} is {true}, any character
    #, strings are transposed.  Any errors are output to {error_stream}.


procedure layer_via_shave@plot
    takes
	plot plot
	layer layer
    returns_nothing

    #: This procedure will shave the edges off of any vias that
    #, come close to any of the lines in {layer} in {plot}.


procedure line_draw@plot
    takes
	plot plot
	layer layer
	x1 unsigned
	y1 unsigned
	x2 unsigned
	y2 unsigned
	line_thickness line_thickness
    returns logical

    #: This procedure will draw a line of thickness {line_thickness}
    #, from ({x1}, {y1}) to ({x2}, {y2}) on {layer} in {plot}.
    #, If any error occurs, {true} is returned; otherwise {false}
    #, is returned.


procedure mask_write@plot
    takes
	plot plot
	plot_stream plot_stream
	drill_rack drill_rack
	apertures apertures
	error_stream out_stream
    returns logical

    #: This procedure will plot the mask layer for {plot} to {file_name}
    #, useing {drill_rack} and {apertures}.  If any errors occur, {true}
    #, is returned; otherwise, {false} is returned.


procedure schematic_capture_set@plot
    takes
	plot plot
	schematic logical
    returns_nothing

    #: This procedure is used to set whether the to capture whether
    #, the input file is a PCB or a schematic.


procedure tool_generate@plot
    takes
	plot plot
	file_name string
	drill_rack drill_rack
	error_stream out_stream
    returns logical

    #: This procedure will output an Excellon NC Drill file to
    #, {file_name} for {plot}.  {drill_rack} specifies the drill rack.
    #, Any errors are output to {error_stream} and {true} is returned.


procedure via_name_insert@plot
    takes
	plot plot
	x unsigned
	y unsigned
	hole_number unsigned
	name string
    returns logical

    #: This procuedure will insert a via at ({x}, {y}) with a hole
    #, number of {hole_number} into {plot}.  The via name in {name}
    #, is ignored.  {true} is returned if there are any errors and
    #, {false} otherwise.


procedure glyph_file_read@plot
    takes
	plot plot
	characters_mirror logical
    returns logical

    #: This procedure is used to read the `glyph file'.  Since we
    #, don't support glyphs in plotted output, this procedur is a no-op.


#: {plot_line} routines:

procedure create@plot_line
    takes
	layer layer
	thickness line_thickness
	plot_node1 plot_node
	plot_node2 plot_node
    returns plot_line

    #: This procedure will create and return a new {plot_line} object.


#: {plot_node} routines:

procedure create@plot_node
    takes
	x unsigned
	y unsigned
    returns plot_node

    #: This procedure will create and return an empty {plot_node} object.


procedure clear@plot_node
    takes
	plot_node plot_node
    returns_nothing

    #: This procedure will clear out drawing state in {plot_node}:


procedure line_append@plot_node
    takes
	plot_node plot_node
	plot_line plot_line
    returns_nothing

    #: This procedure will append {plot_line} to {plot_node}.


procedure flash@plot_node
    takes
	plot_node plot_node
	drill_rack drill_rack
	plot_stream plot_stream
    returns_nothing

    #: This procedure will cause {plot_node} to be flashed out
    #, appropriate via shaving to {plot_stream}.

    #put@("<=flash@plot_node()\n\", debug_stream)



procedure stroke@plot_line
    takes
	plot_line plot_line
	plot_stream plot_stream
    returns_nothing

    #: This procedure will stroke {plot_line} to {plot_stream}.

    #, line end-points, so we don't overwrite the
    #, hole in the pad.
    

#: {plot_nodes} routines:

procedure clear@plot_nodes
    takes
	plot_nodes plot_nodes
    returns_nothing

    #: This procedure will clear out the drawing state in {plot_nodes}.


procedure create@plot_nodes
    takes
	plot plot
    returns plot_nodes

    #: This procedure will create and return an empty {plot_nodes} object.


procedure has_node@plot_nodes
    takes
	plot_nodes plot_nodes
	x unsigned
	y unsigned
    returns logical

    #: This procedure will return {true} if there is a non-empty
    #, {plot_node} at ({x}, {y}) in {plot_nodes} and {false} otherwise.


procedure fetch2@plot_nodes
    takes
	plot_nodes plot_nodes
	x unsigned
	y unsigned
    returns plot_node

    #: This procedure will return the {plot_node} at ({x}, {y}) in
    #, {plot_nodes}.


#: {plot_operation} routines:

procedure code_convert@plot_operation
    takes
	plot_operation plot_operation
    returns unsigned

    #: This procedure will convert {plot_operation} into a Gerber D code.


#: {plot_search} routines:

procedure create@plot_search
    takes
	plot plot
	flags unsigned
    returns plot_search

    #: This procedure will create and return a {plot_search} object.


procedure origin_set@plot_search
    takes
	plot_search plot_search
	x_origin unsigned
	y_origin unsigned
    returns_nothing

    #: This procedure wil set {plot_search} to start searching at
    #, ({x_origin}, {y_origin}).


procedure mark@plot_search
    takes
	plot_search plot_search
	x unsigned
	y unsigned
    returns_nothing

    #: This procedure will mark the node at ({x},{y}) as visited.


procedure next@plot_search
    takes
	plot_search plot_search
    returns plot_node

    #: This procedure will return the next {plot_node} in {plot_search}'s
    #, search path.  If no more {plot_node}'s are available, ??@{plot_node}
    #, is returned.


procedure x_position_get@plot_node
    takes
	plot_node plot_node
    returns unsigned

    #: This procedure will return the X position of {plot_node} in
    #, units of .00001".


procedure y_position_get@plot_node
    takes
	plot_node plot_node
    returns unsigned

    #: This procedure will return the Y position of {plot_node} in
    #, units of .00001".


#: {plot_stream} routines:
	
procedure absolute_mode@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will output an absolute plot mode command.


procedure block_flush@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will ensure that all internal buffers in
    #, {plot_stream} have been flushed out.


procedure character_put@plot_stream
    takes
	plot_stream plot_stream
	character character
    returns_nothing

    #: This procedure will output {character} to {plot_stream}.


procedure character_plot@plot_stream
    takes
	plot_stream plot_stream
	character unsigned
	x unsigned
	y unsigned
	horizontal_scale unsigned
	vertical_scale unsigned
	transpose logical
    returns_nothing

    #: This procedure will plot each {character} to {plot_stream}
    #, starting at ({x_mils}, {y_mils}) with a scale of {scale_mils}.
    #, If {transpose} is {true}, the character will be plotted
    #, transposed.


procedure characters_plot@plot_stream
    takes
	plot_stream plot_stream
	characters vector[unsigned]
	x_position unsigned
	y_position unsigned
	horizontal_scale unsigned
	vertical_scale unsigned
	transpose logical
    returns_nothing

    #: This procedure will plot each character in {characters}
    #, to {plot_stream} starting at ({x_position}, {y_position}) with
    #, a scale of {scale}.  If {transposed} is {true}, the
    #, character will be plotted transposed.


procedure close@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will close {plot_stream}


procedure command_end@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure marks the end of a command sequence.


procedure command_flush@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will flush the command buffer out to the
    #, internal block buffer.  If the block buffer is too, full
    #, if is flushed out to the output file.


procedure coordinate_put@plot_stream
    takes
	plot_stream plot_stream
	coordinate_character character
	new_coordinate unsigned
	old_coordinate unsigned
    returns_nothing

    #: This procedure will will output output {new_coordinate} to
    #, {plot_stream} using {coordinate_character} to mark the
    #, coordinate.  {old_coordinate} is the previous coordinate
    #, value; it is only used for incrmental mode.


procedure open@plot_stream
    takes
	plot plot
	base_name string
	suffix string
	apertures apertures
	error_stream out_stream
    returns plot_stream

    #: This procedure will open {base_name}{suffix} as an RS274X file.


procedure create@plot_stream
    takes
	plot plot
	file_name string
	whole_digits unsigned
	fraction_digits unsigned
	zero_supression zero_supression
	incremental logical
	block_size_maximum unsigned
	apertures apertures
	error_stream out_stream
    returns plot_stream

    #: This procedure will create and return a {plot_stream} object
    #, that is prepared to produced Gerber/Excellon file output
    #, in {leading_digits},{trailing_digits} format.  {leading_digits}
    #, specifies the number of digits before the implied decimal
    #, point and {trailing_digits} specifies the number of digits
    #, following the implied decimal point.  If {leading_zero_supress}
    #, is {true}, all preceeding zeros are supressed.  If
    #, {trailing_zero_supress} is {true}, all trailing zeros are
    #, supressed.  {block_size_maximum} is the maximum number of
    #, chracters that can go into a block prior to being flushed.
    #, A value of 0, will default to a reasonable value.  {apertures}
    #, is the {apertures} object.  If the file can not be opened,
    #, an error message is output to {error_stream} and
    #, ??@{plot_stream} is returned.


procedure d_code@plot_stream
    takes
	plot_stream plot_stream
	code unsigned
    returns_nothing

    #: This procedure will output a D code for {code} to {plot_stream}.


procedure distance_put@plot_stream
    takes
	plot_stream plot_stream
	distance unsigned
    returns_nothing

    #: This procedure will output {distance} to {plot_stream} using
    #, specified number format.


procedure distance_put_helper@plot_stream
    takes
	distance_buffer string
	distance unsigned
    returns_nothing

    #: This procedure will append {distance} to {distance_buffer} as
    #, a decimal number.


procedure end@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will output an end plot command to {plot_stream}.


procedure flash@plot_stream
    takes
	plot_stream plot_stream
	aperture aperture
	x unsigned
	y unsigned
    returns_nothing

    #: This procedure will flash {aperture} at ({x}, {y}) in {plot_stream}.


procedure flush@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will ensure that all internal buffers in
    #, {plot_stream} have been flushed out.


procedure goto@plot_stream
    takes
	plot_stream plot_stream
	aperture aperture
	x unsigned
	y unsigned
	plot_operation plot_operation
    returns_nothing

    #: This procedure will instruct the photoplotter/NC drill to perform
    #, {plot_operation}, with {aperture} selected, as it goes to
    #, ({x}, {y}), where {x} and {y} are measured in .00001".


procedure g_code@plot_stream
    takes
	plot_stream plot_stream
	code unsigned
    returns_nothing

    #: This procedure will output a G code for {code} to {plot_stream}.


procedure gerber_header@plot_stream
    takes
	plot_stream plot_stream
	negative logical
    returns_nothing

    #: This procedure will output a RS274X header for a gerber file.


procedure incremental_mode@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will output an incremental plot mode command.


procedure lines_mode@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will output a command to flash an aperture.


procedure m_code@plot_stream
    takes
	plot_stream plot_stream
	code unsigned
    returns_nothing

    #: This procedure will output an M code for {code} to {plot_stream}.


procedure new_line_put@plot_stream
    takes
	plot_stream plot_stream
    returns_nothing

    #: This procedure will output a new-line sequece to {plot_stream}.


procedure store1@plot_stream
    takes
	plot_stream plot_stream
	letter string
	value string
    returns_nothing

    #: This procedure stores the plotting commands in {value} for {letter}
    #, in {plot_stream}'s character font.


procedure string_put@plot_stream
    takes
	plot_stream plot_stream
	text string
    returns_nothing

    #: This procedure will output {text} to {plot_stream}.


procedure stroke@plot_stream
    takes
	plot_stream plot_stream
	aperture aperture
	x1 unsigned
	y1 unsigned
	x2 unsigned
	y2 unsigned
    returns_nothing

    #: This procedure will stroke from ({x1}, {y1}) to ({x2}, {y2})
    #, with an aperture of {aperture} to {plot_stream}.


procedure unsigned_put@plot_stream
    takes
	plot_stream plot_stream
	number unsigned
	width unsigned
    returns_nothing

    #: This procedure will output {number} to {plot_stream} ensuring
    #, that at least {width} digits are output.


procedure aggregate_parse
    takes
	full_file_name string
    returns string, unsigned, unsigned, unsigned, unsigned, unsigned

    #: This procedure will parse an aggregate file name of
    #, the form "NAME.pcb@X:Y[<^>]".

    #, Format = "0@1.2:3.4[<^>]":