{Begin SubSec Primitive Graphics Concepts} {Title Primitive Graphics Concepts} {Text The Interlisp-D graphics system is based on manipulating bitmaps (rectangular arrays of pixels), positions, regions, and textures. These objects are used by all of the graphics functions. {Begin SubSec Positions} {Title Positions} {Text {Index *PRIMARY* POSITION (Record)} {index *PRIMARY* Positions} A position denotes a point in an X,Y coordinate system. A {lisp POSITION} is an instance of a record with fields {lisp XCOORD} and {lisp YCOORD} and is manipulated with the standard record package facilities. For example, {lisp (create POSITION XCOORD _ 10 YCOORD _ 20)} creates a position representing the point (10,20). {FnDef {Name POSITIONP} {Args X} {Text Returns {arg X} if {arg X} is a position; {lisp NIL} otherwise. }} }{End SubSec Positions} {Begin SubSec Regions} {Title Regions} {Text {Index *PRIMARY* REGION (Record)} {index *PRIMARY* Regions} A Region denotes a rectangular area in a coordinate system. Regions are characterized by the coordinates of their bottom left corner and their width and height. A {lisp REGION} is a record with fields {lisp LEFT}, {lisp BOTTOM}, {lisp WIDTH}, and {lisp HEIGHT}. It can be manipulated with the standard record package facilities. There are access functions for the {lisp REGION} record that return the {lisp TOP} and {lisp RIGHT} of the region. The following functions are provided for manipulating regions: {FnDef {Name CREATEREGION} {Args LEFT BOTTOM WIDTH HEIGHT} {Text Returns an instance of the {lisp REGION} record which has {arg LEFT}, {arg BOTTOM}, {arg WIDTH} and {arg HEIGHT} as respectively its {lisp LEFT}, {lisp BOTTOM}, {lisp WIDTH}, and {lisp HEIGHT} fields. Example: {lisp (CREATEREGION 10 -20 100 200)} will create a region that denotes a rectangle whose width is 100, whose height is 200, and whose lower left corner is at the position (10,-20). }} {FnDef {Name REGIONP} {Args X} {Text Returns {arg X} if {arg X} is a region, {lisp NIL} otherwise. }} {FnDef {Name INTERSECTREGIONS} {Args REGION{sub 1} REGION{sub 2} {ellipsis} REGION{sub n}} {Type nospread} {Text Returns a region which is the intersection of a number of regions. Returns {lisp NIL} if the intersection is empty. }} {FnDef {Name UNIONREGIONS} {Args REGION{sub 1} REGION{sub 2} {ellipsis} REGION{sub n}} {Type nospread} {Text Returns a region which is the union of a number of regions, i.e. the smallest region that contains all of them. Returns {lisp NIL} if there are no regions given. }} {FnDef {Name REGIONSINTERSECTP} {Args REGION1 REGION2} {Text Returns {lisp T} if {arg REGION1} intersects {arg REGION2}. Returns {lisp NIL} if they do not intersect. }} {FnDef {Name SUBREGIONP} {Args LARGEREGION SMALLREGION} {Text Returns {lisp T} if {arg SMALLREGION} is a subregion (is equal to or entirely contained in) {arg LARGEREGION}; otherwise returns {lisp NIL}. }} {FnDef {Name EXTENDREGION} {Args REGION INCLUDEREGION} {Text Changes (destructively modifies) the region {arg REGION} so that it includes the region {arg INCLUDEREGION}. It returns {arg REGION}. }} {FnDef {Name MAKEWITHINREGION} {Args REGION LIMITREGION} {Text Changes (destructively modifies) the left and bottom of the region {arg REGION} so that it is within the region {arg LIMITREGION}, if possible. If the dimension of {arg REGION} are larger than {arg LIMITREGION}, {arg REGION} is moved to the lower left of {arg LIMITREGION}. If {arg LIMITREGION} is {lisp NIL}, the value of the variable {var WHOLEDISPLAY}{index WHOLEDISPLAY Var} (the screen region) is used. {fn MAKEWITHINREGION} returns the modified {arg REGION}. }} {FnDef {Name INSIDEP} {Args REGION POSORX Y} {Text If {arg POSORX} and {arg Y} are numbers, it returns {lisp T} if the point ({arg POSORX},{arg Y}) is inside of {arg REGION}. If {arg POSORX} is a {lisp POSITION}, it returns {lisp T} if {arg POSORX} is inside of {arg REGION}. If {arg REGION} is a {lisp WINDOW}, the window's interior region in window coordinates is used. Otherwise, it returns {lisp NIL}. }} }{End SubSec Regions} {Begin SubSec Bitmaps} {Title Bitmaps} {Text {Index *PRIMARY* Bitmaps} {Index *PRIMARY* Pixels} {Index *PRIMARY* BITMAP (Data Type)} The display primitives manipulate graphical images in the form of bitmaps. A bitmap is a rectangular array of "pixels," each of which is an integer representing the color of one point in the bitmap image. A bitmap is created with a specific number of bits allocated for each pixel. Most bitmaps used for the display screen use one bit per pixel, so that at most two colors can be represented. If a pixel is 0, the corresponding location on the image is white. If a pixel is 1, its location is black. This interpretation can be changed for the display screen with the function {fn VIDEOCOLOR} ({PageRef Fn VIDEOCOLOR}). Bitmaps with more than one bit per pixel are used to represent color or grey scale images. Bitmaps use a positive integer coordinate system with the lower left corner pixel at coordinate (0,0). Bitmaps are represented as instances of the datatype {lisp BITMAP}. Bitmaps can be saved on files with the {filecom VARS} file package command ({PageRef FileCom VARS}).{Index Saving bitmaps on files} {FnDef {Name BITMAPCREATE} {Args WIDTH HEIGHT BITSPERPIXEL} {Text Creates and returns a new bitmap which is {arg WIDTH} pixels wide by {arg HEIGHT} pixels high, with {arg BITSPERPIXEL} bits per pixel. If {arg BITSPERPIXEL} is {lisp NIL}, it defaults to 1. }} {FnDef {Name BITMAPP} {Args X} {Text Returns {arg X} if {arg X} is a bitmap, {lisp NIL} otherwise. }} {FnDef {Name BITMAPWIDTH} {Args BITMAP} {Text Returns the width of {arg BITMAP} in pixels. }} {FnDef {Name BITMAPHEIGHT} {Args BITMAP} {Text Returns the height of {arg BITMAP} in pixels. }} {FnDef {Name BITSPERPIXEL} {Args BITMAP} {Text Returns the number of bits per pixel of {arg BITMAP}. }} {FnDef {Name BITMAPBIT} {Args BITMAP X Y NEWVALUE} {Text If {arg NEWVALUE} is between 0 and the maximum value for a pixel in {arg BITMAP}, the pixel ({arg X,Y}) is changed to {arg NEWVALUE} and the old value is returned. If {arg NEWVALUE} is {lisp NIL}, {arg BITMAP} is not changed but the value of the pixel is returned. If {arg NEWVALUE} is anything else, an error is generated. If ({arg X,Y}) is outside the limits of {arg BITMAP}, 0 is returned and no pixels are changed. {arg BITMAP} can also be a window or display stream. Note: non-window image streams are "write-only"; the {arg NEWVALUE} argument must be non-{lisp NIL}. }} {FnDef {Name BITMAPCOPY} {Args BITMAP} {Text Returns a new bitmap which is a copy of {arg BITMAP} (same dimensions, bits per pixel, and contents). }} {FnDef {Name EXPANDBITMAP} {Args BITMAP WIDTHFACTOR HEIGHTFACTOR} {Text Returns a new bitmap that is {arg WIDTHFACTOR} times as wide as {arg BITMAP} and {arg HEIGHTFACTOR} times as high. Each pixel of {arg BITMAP} is copied into a {arg WIDTHFACTOR} times {arg HEIGHTFACTOR} block of pixels. If {lisp NIL}, {arg WIDTHFACTOR} defaults to 4, {arg HEIGHTFACTOR} to 1. {note WIDTHFACTOR defaults to 4, HEIGHTFACTOR to 1. this is so that this could be used to translate 1 bitperpixel bitmaps to 4 bitperpixel color bitmaps. However, we don't want to do this, because this relies on knowing that bitmaps are stored width-first. For now, perhaps this should be done by allocating a new array, and doing a BITBLT.} {note Q: I assume that the new bitmap returned by EXPANDBITMAP has the same bitsperpixel??} }} {FnDef {Name SHRINKBITMAP} {Args BITMAP WIDTHFACTOR HEIGHTFACTOR DESTINATIONBITMAP} {Text Returns a copy of {arg BITMAP} that has been shrunken by {arg WIDTHFACTOR} and {arg HEIGHTFACTOR} in the width and height, respectively. If {lisp NIL}, {arg WIDTHFACTOR} defaults to 4, {arg HEIGHTFACTOR} to 1. If {arg DESTINATIONBITMAP} is not provided, a bitmap that is 1/{arg WIDTHFACTOR} by 1/{arg HEIGHTFACTOR} the size of {arg BITMAP} is created and returned. {arg WIDTHFACTOR} and {arg HEIGHTFACTOR} must be positive integers. }} {FnDef {Name PRINTBITMAP} {Args BITMAP FILE} {Text Prints the bitmap {arg BITMAP} on the file {arg FILE} in a format that can be read back in by {fn READBITMAP}. {note (If BITMAP is an atom whose value is a bitmap, its value will be used.) -- crock, sez Larry} }} {FnDef {Name READBITMAP} {Args FILE} {Text Creates a bitmap by reading an expression (written by {fn PRINTBITMAP}) from the file {arg FILE}. }} {FnDef {Name EDITBM} {Args BMSPEC} {Text {fn EDITBM} provides an easy-to-use interactive editing facility for various types of bitmaps. If {arg BMSPEC} is a bitmap, it is edited. If {arg BMSPEC} is an atom whose value is a bitmap, its value is edited. If {arg BMSPEC} is {lisp NIL}, {fn EDITBM} asks for dimensions and creates a bitmap. If {arg BMSPEC} is a region, that portion of the screen bitmap is used. If {arg BMSPEC} is a window, it is brought to the top and its contents edited. }} {fn EDITBM} sets up the bitmap being edited in an editing window. The editing window has two major areas: a gridded edit area in the lower part of the window and a display area in the upper left part. In the edit area, the left button will add points, the middle button will erase points. The right button provides access to the normal window commands to reposition and reshape the window. The actual size bitmap is shown in the display area. For example, the following is a picture of the bitmap editing window editing a eight-high by eighteen-wide bitmap: *~RsFuvmmqmmmv[bfwUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTxDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTDxUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTHDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTDUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPªUUUUUPUUUUUUUPUPUPƪUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUUUPUUUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUUUUUUUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPªUUUUUPUPUPUPUPƪ If the bitmap is too large to fit in the edit area, only a portion will be editable. This portion can be changed by scrolling both up and down in the left margin and left and right in the bottom margin. Pressing the middle button while in the display area will bring up a menu that allows global placement of the portion of the bitmap being edited. To allow more of the bitmap to be editing at once, the window can be reshaped to make it larger or the {lisp GridSize_} command described below can be used to reduce the size of a bit in the edit area. The bitmap editing window can be reshaped to provide more or less room for editing. When this happens, the space allocated to the editing area will be changed to fit in the new region. Whenever the left or middle button is down and the cursor is not in the edit area, the section of the display of the bitmap that is currently in the edit area is complemented. Pressing the left button while not in the edit region will put the lower left 16 x 16 section of the bitmap into the cursor for as long as the left button is held down. Pressing the middle button while not in either the edit area or the display area (i.e. while in the grey area in the upper right or in the title) will bring up a command menu. There are commands to stop editing, to restore the bitmap to its initial state and to clear the bitmap. Holding the middle button down over a command will result in an explanatory message being printed in the prompt window. The commands are described below: {Begin Labeledlist EDITBM menu commands} {Name {lisp Paint}} {Item Puts the current bitmap into a window and call the window {lisp PAINT} command on it. The {lisp PAINT} command implements drawing with various brush sizes and shapes but only on an actual sized bitmap. The {lisp PAINT} mode is left by pressing the {lisp RIGHT} button and selecting the {lisp QUIT} command from the menu. At this point, you will be given a choice of whether or not the changes you made while in {lisp PAINT} mode should be made to the current bitmap. } {Name {lisp ShowAsTile}} {Item Tesselates the current bitmap in the upper part of the window. This is useful for determining how a bitmap will look if it were made the display background (using the function {fn CHANGEBACKGROUND}). Note: The tiled display will not automatically change as the bitmap changes; to update it, use the {lisp ShowAsTile} command again. } {Name {lisp Grid,On/Off}} {Item Turns the editing grid display on or off. } {Name {lisp GridSize_}} {Item Allows specification of the size of the editing grid. Another menu will appear giving a choice of several sizes. If one is selected, the editing portion of the bitmap editor will be redrawn using the selected grid size, allowing more or less of the bitmap to be edited without scrolling. The original size is chosen hueristically and is typically about 8. It is particularly useful when editing large bitmaps to set the edit grid size smaller than the original. } {Name {lisp Reset}} {Item Sets all or part of the bitmap to the contents it had when {fn EDITBM} was called. Another menu will appear giving a choice between resetting the entire bitmap or just the portion that is in the edit area. The second menu also acts as a confirmation, since not selecting one of the choices on this menu results in no action being taken. } {Name {lisp Clear}} {Item Sets all or part of the bitmap to 0. As with the {lisp Reset} command, another menu gives a choice between clearing the entire bitmap or just the portion that is in the edit area. } {Name {lisp Cursor_}} {Item Sets the cursor to the lower left part of the bitmap. This prompts the user to specify the cursor "hot spot" (see {PageRef Term HotSpot}) by clicking in the lower left corner of the grid. {note explain this better} } {Name {lisp OK}} {Item Copies the changed image into the original bitmap, stops the bitmap editor and closes the edit windows. The changes the bitmap editor makes during the interaction occur on a copy of the original bitmap. Unless the bitmap editor is exited via {lisp OK}, no changes are made in the original. } {Name {lisp Stop}} {Item Stops the bitmap editor without making any changes to the original bitmap. } {End Labeledlist EDITBM menu commands} }{End SubSec Bitmaps} {Begin SubSec Textures} {Title Textures} {Text {index *PRIMARY* Textures} {Tag Textures} A Texture denotes a pattern of gray which can be used to (conceptually) tessellate the plane to form an infinite sheet of gray. It is currently either a 4 by 4 pattern or a 16 by {arg N} ({arg N} <= 16) pattern. Textures are created from bitmaps using the following function: {FnDef {Name CREATETEXTUREFROMBITMAP} {Args BITMAP} {Text Returns a texture object that will produce the texture of {arg BITMAP}. If {arg BITMAP} is too large, its lower left portion is used. If {arg BITMAP} is too small, it is repeated to fill out the texture. }} {FnDef {Name TEXTUREP} {Args OBJECT} {Text Returns {arg OBJECT} if it is a texture; {lisp NIL} otherwise. }} The functions which accept textures ({fn TEXTUREP}, {fn BITBLT}, {fn DSPTEXTURE}, etc.) also accept bitmaps up to 16 bits wide by 16 bits high as textures. When a region is being filled with a bitmap texture, the texture is treated as if it were 16 bits wide (if less, the rest is filled with white space). The common textures white and black are available as system constants {var WHITESHADE}{index WHITESHADE Var} and {var BLACKSHADE}.{index BLACKSHADE Var} The global variable {var GRAYSHADE}{index GRAYSHADE Var} is used by many system facilities as a background gray shade and can be set by the user. {Begin Note} Textures can be (and TEXTUREP is true of) BITMAPs of 16 bits wide by up to 16 bits high. 4x4 textures can still be represented as integers. {End Note} {FnDef {Name EDITSHADE} {Args SHADE} {Text Opens a window that allows the user to edit textures. Textures can be either small (4 by 4) patterns or large (16 by 16). In the edit area, the left button adds bits to the shade and the middle button erases bits from the shade. The top part of the window is painted with the current texture whenever all mouse keys are released. Thus it is possible to directly compare two textures that differ by more than one pixel by holding a mouse key down until all changes are made. When the "quit" button is selected, the texture being edited is returned. If {arg SHADE} is a texture object, {fn EDITSHADE} starts with it. If {arg SHADE} is {lisp T}, it starts with a large (16 by 16) white texture. Otherwise, it starts with {var WHITESHADE}. }} The following is a picture of the texture editor, editing a large (16 by 16) pattern: ,,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000``0``0``0`>`0`H`0`H`0`H`0`H`0`H`0`H`0``0``0``0``0``0``000000 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00UUUuU]UWUUUuU]UW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW0ꪺꪺ0 TUU@UTUU@W00 TUU@UTUU@W00 TUU@UTUU@W00 TUU@UTUU@W00UUU`WUUU`W00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW0ꪪꪪ0 TUPUTUPW0**0 TUPUTUPW0**0 TUPUTUPW0**0 TUPUTUPW0**0U@5UXWU@5UXW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW0ꪪꪪ0 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00UUUuUXWUUUuUXW0 0 0 0 0 0 0 0 0@ @ 0 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00UUUuUXWUUUuUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW00 UUUUUUPUUUUUUUPW0ꪪꪪ0 TUPUTUPW0**0 TUPUTUPW0**0 TUPUTUPW0**0 TUPUTUPW0**0U@5UPWU@5UXW00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW00 TUUUUPUTUUUUPW0ꪪꪪ0 TUU@UTUU@W00 TUU@UTUU@W00 TUU@UTUU@W00 TUU@UTUU@W00TUU`WTUU`W00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW0ꪺꪺ0 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00 TUUUUUUUTUUUUUUW00UUUuU]UWTUUuU]UW0 0 0 0 0 0 0 0 0@ @ 000000 }{End SubSec Textures} }{End SubSec Primitive Graphics Concepts} ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) %M~ BMOBJ.GETFN2P, BMOBJ.GETFN2Hz