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