			GUI WORK NOTES - November 1993

TODO

    enhance mapping code in Gterm widget (see below)
    ximtool enhancements
	locator, magnifier, control panel, socket support, etc.
    clean up xgterm
			    - beta release -
    obm enhancements
	more gui bindings, new widgets
    imbrowse, movie demos
    obm documentation


1. MAPPINGS

    src rect -> dst rect

    construct pixel level mappings for each axis
	this source pixel maps to these destination pixels
	this destination pixel maps to these source pixels

    in general (zoom/dezoom) the mapping is not one-to-one
    when one source pixel maps to several destination pixels, pixel replication
	is used to draw the destination pixels
    when one destination pixel maps to several source pixels the destination
	pixel value may be computed by any of several different techniques

    major cases

	mapping is one-to-one
	mapping is one-to-many	 zoom mapping (pixel replication)
	mapping is many-to-one	 dezoom mapping (antialias)

    antialiasing techniques

	nearest			nearest neighbor
	bilinear		2x2 distance weighted sum

	area			included area weighted sum
	lowpass			convolve followed by nearest neighbor
	gaussian		gaussian weighted sum over NxN pixels

	All of these involve projecting the center of each destination
	pixel back into the source raster.  The antialiasing technique
	applied to the NxN neighborhood around the source coordinate
	then determines the value of the destination pixel.

	Reasonable choices
	    nearest		fastest, but no antialiasing
	    bilinear		mininum smoothing if mag < 2
	    lowpass		not bad for mag < 3
	    area,gaussian	best for large demagnification ratios

	Nearest and bilinear (NB) are mutually exclusive and may be selected
	independently of area, lowpass, or gaussian (ALG).  If one of ALG is
	selected and one of NB is also selected, the antialias code will use
	one or the other technique depending upon the scaling.  If one of NB
	or ALG is selected but not both, the specified technique will be
	used regardless of the scaling.

    setMapping should compute scaling maps
    copyRaster uses these to compute the destination pixels
    refreshRaster uses these to compute region of source rect

    computing a mapping
	rasterop
	src rect, dst rect
	coordinate types
	flags: enabled, defined, refresh
	scaling type (unitary, zoom, dezoom)
	backprojection array maps dst pixel to src pixel
	    integer mapping (1-1, zoom):	pixel number, integer
	    antialias mapping (dezoom):		pixel center, floating
	extent array gives range of dst pixels affected by a given
	    src pixel - 2 values per source pixel
	xscale, yscale (forward direction)


2. PSEUDOCODE

procedure copyRaster (src, src rect, dst, dst rect)
begin
	create temporary mapping
	refresh entire mapping
end

procedure writePixels (dst, dst rect, pixels)
begin
	modify source raster pixels
	update any mappings that intersect source rect
end

procedure setMapping (mapping, mapping data)
begin
	if (new mapping, mapping not enabled, or refreshNone set)
	    merely store new mapping
	else {
	    # Edit and refresh a mapping.
	    if (scale is unchanged) {
		compare old, new mappings
		refresh only changed regions
		store new mapping
	    } else {
		store new mapping
		refresh entire mapping
	    }
	    refresh any uncovered regions
	}

	if (mapping is one-to-one) {
	    scaling = none
	} else if (mapping is one-to-many) {
	    compute integer dst->src scaling maps
	    scaling = zoom
	} else if (mapping is many-to-one) {
	    compute array of back projected dst->src pixel centers
	    scaling = dezoom
	}
end

procedure refresh_source (mapping, source rect)
begin
	compute destination rect
	refresh_destination (mapping, destination rect)
end

procedure refresh_destination (mapping, destination rect)
begin
	set clip mask in GC to prevent drawing into any mapped regions
	which cover the mapping being refreshed

	# Special case of pixmap to pixmap copy with no scaling.
	if (no scaling and src is pixmap and dst is pixmap) {
	    do direct XCopyArea
	    goto done
	}

	# Get source ximage.
	if (src is pixmap) {
	    xin = ximage returned by XGetImage
	    set del_xin flag
	} else
	    xin = src ximage

	# Special case of ximage to pixmap copy with no scaling.
	if (no scaling and dst is pixmap) {
	    do XPutImage to write xin to dst pixmap
	    goto done
	}

	# Get destination ximage.
	if (dst is pixmap) {
	    xout = create an ximage of the required size
	    set del_xout flag
	} else
	    xout = dst ximage

	# Copy src ximage to dst ximage.
	if (mapping is one to one) {
	    copy region of xin to xout without scaling

	} else if (mapping is one to many - zoom) {
	    for (each line of destination)
		if (mapped src Y same as previous line)
		    copy previous dst line
		else {
		    for (each destination pixel)
			pixel = get pixel from xin using dst->src map
		}

	} else (mapping is many to one - dezoom) {
	    if (function is lowpass) {
		compute lowpass xin
		set function to nearest neighbor
	    }

	    for (each line of destination)
		for (each destination pixel)
		    pixel = antialias_function (src, x, y, nx, ny)
	}

	if (dst is pixmap)
	    do XPutImage to write xout to dst pixmap

	clear clip mask in GC
end
	


