english
version "1.0"
identify "xyz"

#: Copyright (c) 1994, 1995, 1997, 2000, 2003 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 cell

#: This module implements one cell of a printed circuit board.

define cell				#: Printed circuit board cell
    record
	artwork_thick unsigned		#: Artwork layer thick line segments
	artwork_thin unsigned		#: Artwork layer thin line segments
	back_thick unsigned		#: Back layer thick line segments
	back_thin unsigned		#: Back layer thin line segments
	bartwork_thick unsigned		#: Back artwork layer thick line segs
	bartwork_thin unsigned		#: Back artwork layer thin line segs
	board_data board_data		#: {board_data} object cell is part of
	cache_artwork_thick_edge unsigned #: Tempoary artwork thick edge segs.
	cache_artwork_thin_edge unsigned #: Temporary artwork thin edge segs.
	cache_back_thick_edge unsigned	#: Temporary back thick edge segments
	cache_back_thin_edge unsigned	#: Temporary back thin edge segments
	cache_back_via_edge unsigned	#: Temporary back via edge segments
	cache_bartwork_thick_edge unsigned #: Temp back artwork thick edge segs
	cache_bartwork_thin_edge unsigned #: Temp. back artwork thin edge segs.
	cache_front_thick_edge unsigned	#: Temporary front thick edge segments
	cache_front_thin_edge unsigned	#: Temporary front thin edge segments
	cache_front_via_edge unsigned	#: Temporary front via edge segments
	cache_over_bar unsigned		#: Temporary overbar indicator
	changed logical			#: {true} if cell contents have changed
	character_artwork character	#: Character for artwork layer
	character_back character	#: Character for back layer
	character_bartwork character	#: Character for back artwork layer
	character_front character	#: Character for front layer
	chunk_layers vector[chunk_layer] #: Additional chunks rendered
	cursor_layer layer		#: Layer to display cursor on (or none)
	cursor_thickness line_thickness	#: Cursor thickness
	front_thick unsigned		#: Front layer thick line segments
	front_thin unsigned		#: Front layer thin line segments
	hole_number unsigned		#: {hole_number} of drill rack
	name string			#: Part name
	via logical			#: {true}=>there is a via at cell
	x unsigned			#: X index for cell
	y unsigned			#: Y index for cell
    generate allocate, erase

define cell_row				#: Row of autosizing cells
    record
	board_data board_data		#: Containing board data object
	row vector[cell]		#: One row of cells in board.
	index unsigned			#: Index of row
    generate allocate, erase, print

define cells				#: Matrix of autosizing cells
    record
	board_data board_data		#: Containing board data object
	rows vector[cell_row]		#: One row of cells in board.
    generate allocate, erase, print

define chunk_layer			#: A {chunk}/{layer} pair.
    record
	chunk chunk			#: {chunk} to render
	layer layer			#: {layer} to render it upon
    generate allocate, erase, hash, identical, print

define direction			#: Line directions
    enumeration
	north
	north_east
	east
	south_east
	south
	south_west
	west
	north_west
    generate equal, print, unsigned_convert

define line_operation			#: Line operation
    enumeration
	set				#: Draw
	clear				#: Erase
	invert				#: Complement
    generate print

define line_thickness			#: Line thickness
    enumeration
	thin				#: Thin line
	thick				#: Thick line
    generate equal, print, unsigned_convert

define layer				#: PCB layer
    enumeration
	artwork				#: Artwork layer
	bartwork			#: Back Artwork layer
	back				#: Back PCB layer
	front				#: Front PCB layer
	none				#: No layer (cursor only)
    generate equal, hash, print



procedure print@cell
    takes
	cell cell
	out_stream out_stream
    returns_nothing

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


#: {cell} routines:

procedure changed@cell
    takes
	cell cell
    returns_nothing

    #: This routine will mark {cell} as changed.


procedure contents_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear the contents of {cell}.


procedure mask@cell
    takes
	cell cell
	direction1 direction
	direction2 direction
	direction3 direction
    returns_nothing

    #: This procedure will mask {cell} so that it contains no line
    #, segments in {direction1}, {direction2}, or {direction3}.


procedure east_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear the contents of {cell}.


procedure north_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear the contents of {cell}.


procedure south_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear the contents of {cell}.


procedure west_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear the contents of {cell}.


procedure contents_copy@cell
    takes
	to cell
	from cell
    returns_nothing

    #: This procedure will copy the contents of {from} to {to}.


procedure contents_merge@cell
    takes
	to cell
	from cell
    returns_nothing

    #: This procedure will merge the contents of {from} into {to}.


procedure create@cell
    takes
	board_data board_data
	x unsigned
	y unsigned
    returns cell

    #: This procedure will create and return an empty {cell} object
    #, for {board_data} at position ({x}, {y}).


procedure edge_cache@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will look around {cell} to see if any of the features
    #, in adjacent cells will be rendered in {cell} and store the results
    #, of that computation in the {cache_}* fields of {cell}.


procedure over_bar_cache@cell
    takes
	cell cell
	layer layer
    returns_nothing

    #: This procedure will figure out whether or not an overbar needs
    #, to be drawn in {layer} of {cell}.


procedure equal@cell
    takes
	cell1 cell
	cell2 cell
    returns logical

    #: This procedure will return {true} if the rendering of {cell1} is
    #, equal to the rendering of {cell2}.  The values of the {cache_}*
    #, fields must be prefilled via a call to {cache@cell}().


procedure fetch1@cell
    takes
	cell cell
	layer layer
    returns character

    #: This procedure will fetch the character at {layer} in {cell}.


procedure fetch2@cell
    takes
	cell cell
	layer layer
	line_thickness line_thickness
    returns unsigned

    #: This procedure will fetch the segments of {line_thickness} in {layer}
    #, of {cell}.


procedure hash@cell
    takes
	cell cell
    returns unsigned

    #: This procedure will return a hash value associated with the rendering
    #, of {cell}.  The values of the {cache_}* fields must be prefilled
    #, via a call to {cache@cell}().


procedure is_empty@cell
    takes
	cell cell
    returns logical

    #: This procedure will return {true} if {cell} is empty and {false}
    #, otherwise.


procedure line_edge_cache@cell
    takes
	cell cell
	direction direction
    returns_nothing

    #: This procedure will determine which (if any) line segments edges
    #, that are {direction} from {cell} will need to be rendered and
    #, cache the result in {cell}'s {cache_}* fields.


procedure line_segment@cell
    takes
	cell cell
	direction direction
	layer layer
	thickness line_thickness
	operation line_operation
    returns_nothing

    #: This procedure will add/delete/compliment a line segment of thickness
    #, {thickness} on {layer} in {cell} depending upon {operation}.


procedure line_direction_write@cell
    takes
	cell cell
	layer layer
	line_thickness line_thickness
	direction direction
	out_stream out_stream
    returns_nothing

    #: This procedure will output the lines starting at {cell} in
    #, {layer} of thickness {line_thickness} to {out_stream}.
    #, Only the shortest straight line segments eminating up and
    #, to the right are output.

    #, segments without having to actually erase the board contents
    #, as we go.  The trick is to only output the line segment if it
    #, "starts" within the cell.  Basically, a line segment "starts"
    #, in a cell if it is anything but a straight segment in {direction}.
    #, Vias and connections terminate line segments as well.


procedure end_point@cell
    takes
	cell cell
	layer layer
	line_thickness line_thickness
	direction direction
    returns logical

    #: This procedure will return {true}@{logical} if {cell} is the
    #, end point for a line in {layer} of thickness {line_thinckness}
    #, going in {direction}.


procedure line_write@cell
    takes
	cell cell
	layer layer
	line_thickness line_thickness
	out_stream out_stream
    returns_nothing

    #: This procedure will output the lines starting at {cell} in
    #, {layer} of thickness {line_thickness} to {out_stream}.


procedure render@cell1[render_area]
    takes
	cell cell
	render_area render_area
    returns_nothing
    needs
	procedure render@render_area
	    takes render_area, chunk, layer
	    returns_nothing

    #: This procedure will call
    #, {render_area@(render_area, pcb_character_type, layer)} successive
    #, times to render {cell} into {render_area}.

    #: Render the line segments first:

procedure store1@cell
    takes
	cell cell
	layer layer
	character character
    returns_nothing

    #: This procedure will store {character} into {layer} in {cell}.


procedure store2@cell
    takes
	cell cell
	layer layer
	line_thickness line_thickness
	segments unsigned
    returns_nothing

    #: This procedure will store {segments} into {line_thickness} in {layer}
    #, of {cell}.


procedure string_write@cell
    takes
	cell cell
	layer layer
	out_stream out_stream
    returns_nothing

    #: This procedure will output the string associated at ({x}, {y}) in
    #, {layer} of {cell} if it is the first character of the string.


procedure via_clear@cell
    takes
	cell cell
    returns_nothing

    #: This procedure will clear any via in {cell}.


procedure via_edge_cache@cell
    takes
	cell cell
	direction direction
    returns_nothing

    #: This procedure will figure out whether there is a via in {direction}
    #, from {cell} that has an edge that needs to be rendered into {cell}.
    #, The resultant edge information is added to {cell}.{via_edge}.


procedure write@cell
    takes
	cell cell
	board_data board_data
	out_stream out_stream
    returns_nothing

    #: This procedure will write {cell} to {out_stream}.


#: {chunk_layer} routines:

procedure compare@chunk_layer
    takes
	chunk_layer1 chunk_layer
	chunk_layer2 chunk_layer
    returns integer

    #: This procedeure will return -1, 0, or 1 depending upon whether
    #, {chunk_layer1} is less than, equal to, or greater than
    #, {chunk_layer2}.


procedure copy@chunk_layer
    takes
	chunk_layer chunk_layer
    returns chunk_layer

    #: This procedure will return a copy of {chunk_layer}.


procedure equal@chunk_layer
    takes
	chunk_layer1 chunk_layer
	chunk_layer2 chunk_layer
    returns logical

    #: This procedure will return {true} if {chunk_layer1} is equal
    #, to {chunk_layer2} and {false} otherwise.


procedure less_than@chunk_layer
    takes
	chunk_layer1 chunk_layer
	chunk_layer2 chunk_layer
    returns logical

    #: This procedure will return {true} if {chunk_layer1} is less
    #, than {chunk_layer2} and {false} otherwise.


procedure read@chunk_layer
    takes
	in_stream in_stream
	glyph_table glyph_table
    returns chunk_layer

    #: This procedure will read in and return a {chunk_layer} from {in_stream}.


procedure write@chunk_layer
    takes
	chunk_layer chunk_layer
	out_stream out_stream
    returns_nothing

    #: This procedure will write {chunk_layer} to {out_stream}.


#: {direction} routines:

procedure mask_create@direction
    takes
	direction1 direction
	direction2 direction
	direction3 direction
    returns unsigned

    #: This procedure will create and return a mask created from {direction1}
    #, {direction2}, and {direction3}.  This routine is used by the edge
    #, clearing routines.


procedure mask_get@direction
    takes
	direction direction
    returns unsigned

    #: This procedure will return the mask associated with {direction}.


procedure opposite_get@direction
    takes
	direction direction
    returns direction

    #: This procedure will return the opposite direction of {direction}.


#: Some {layer} routines:

procedure compare@layer
    takes
	layer1 layer
	layer2 layer
    returns integer

    #: This procedeure will return -1, 0, or 1 depending upon whether
    #, {layer1} is less than, equal to, or greater than
    #, {layer2}.


procedure copy@layer
    takes
	layer layer
    returns layer

    #: This procedure will return a copy of {layer}.


procedure format@layer
    takes
	layer layer
	out_stream out_stream
	format string
	offset unsigned
    returns_nothing

    #: This procedure will output {layer} to {out_stream} using the characters
    #, in {format} starting at {offset} to control formatting.


procedure read@layer
    takes
	in_stream in_stream
    returns layer

    #: This procedure will read a {layer} in from {in_stream}.


procedure unsigned_convert@layer
    takes
	layer layer
    returns unsigned

    #: This procedure will convert {layer} into a number.


procedure layer_convert@unsigned
    takes
	number unsigned
    returns layer

    #: this procedure will convert {number} to a {layer} and return it.


procedure write@layer
    takes
	layer layer
	out_stream out_stream
    returns_nothing

    #: This procedure will write {layer} to {out_stream}.


# {cell_row} routines:

procedure create@cell_row
    takes
	board_data board_data
	index unsigned
    returns cell_row

    #: This procedure will create and return a new {cell_row} object
    #, with a row index of {index}.


procedure fetch1@cell_row
    takes
	cell_row cell_row
	index unsigned
    returns cell


procedure size@cell_row
    takes
	cell_row cell_row
    returns unsigned


procedure write@cell_row
    takes
	cell_row cell_row
	board_data board_data
	out_stream out_stream
    returns_nothing

    #: This procedure will write the contents of {cell_row} to {out_stream}.


# {cells} routines:

procedure clear@cells
    takes
	cells cells
    returns_nothing

    #: This procedure will clear out {cells}.


procedure columns_size_get@cells
    takes
	cells cells
    returns unsigned

    #: This procedure returns the high-water mark for columns in {cells}.


procedure create@cells
    takes
	board_data board_data
    returns cells

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


procedure fetch1@cells
    takes
	cells cells
	index unsigned
    returns cell_row

    #: This procedure will return the {index}'th cell from {cells}.


procedure fetch2@cells
    takes
	cells cells
	column_index unsigned
	row_index unsigned
    returns cell

    #: This procedure will return the ({column_index}, {row_index})
    #, cell from {cells}.


procedure rows_size_get@cells
    takes
	cells cells
    returns unsigned

    #: This procedure returns the high-water mark for rows in {cells}.


procedure size@cells
    takes
	cells cells
    returns unsigned


procedure write@cells
    takes
	cells cells
	board_data board_data
	out_stream out_stream
    returns_nothing

    #: This procedure will write the contents of {cells} to {out_stream}.


procedure opposite_get@line_thickness
    takes
	line_thickness line_thickness
    returns line_thickness

    #: This procedure will return the opposite line thickness for
    #, {line_thickness}.


procedure pass_through@unsigned
    takes
	segments unsigned
    returns logical

    #: This procedure will return {true}@{logical} if all of the line
    #, segments in {segments} pass through one another.