Graphics Environment: 7 Working With Bitmaps

Up: GEOS SDK TechDocs| Up | Prev: 6 Graphics State | Next: 8 Graphics Strings
GrCreateBitmap(), GrDestroyBitmap(), GrEditBitmap() GrGetPoint(), GrSetBitmapMode(), GrGetBitmapMode(), GrSetBitmapRes(), GrGetBitmapRes(), GrClearBitmap(), GrGetBitmapSize(), GrCompactBitmap(), GrUncompactBitmap()

Bitmaps are useful for describing complicated pictures that don't have to be smooth at all resolutions. For example, coming up with all the lines and shapes necessary to describe a complicated photograph would be time-consuming and a waste of memory. It's much easier to set up a rectangular array of cells and to set a color value for each cell. Bitmaps are often used for defining program icons. GEOS includes a great deal of bitmap support. It has kernel routines to create, modify, and draw bitmaps.

There are three main ways to create a bitmap for an application to use. One often used is to embed the data of a desired bitmap directly into a graphics string. This is the way normally used for defining system icons. The other common way is to call the kernel graphics routine GrCreateBitmap() . Another way to create a bitmap, not used so often, is to manipulate memory directly: The formats used for describing bitmaps are public, and though it would be easier in most cases to work through GrCreateBitmap() , those with specialized needs might want to create their bitmap data structures from scratch.

The GrCreateBitmap() routine creates an offscreen bitmap and returns a Graphics State which can be drawn to; changes to this Graphics State become changes to the offscreen bitmap. For example, calling GrDrawLine() and passing the Graphics State provided with such a bitmap would result in a bitmap depicting a line. To display this bitmap, call the GrFillBitmap(), GrDrawHugeBitmap(), GrDrawImage(), or GrDrawHugeImage() commands in another graphics space (see the Drawing Shapes chapter).

When creating a bitmap, you must make choices about what sort of bitmap you want. Depending on your choices, GEOS will be able to use a variety of optimizations. For instance, it takes much less room to store a monochrome bitmap than a color bitmap the same size.

Whenever creating a bitmap, you must specify its dimensions and what sort of coloring it will use (monochrome, four bit, eight bit, or 24 bit).

You may store a mask with your bitmap. This mask works something like the mask used when drawing a view's mouse pointer. When the bitmap is drawn, blank areas of the bitmap will be drawn as black for those pixels where the mask is turned on. For pixels where the mask is turned off, whatever was underneath the bitmap will be allowed to show through.

By asking for a Complex bitmap, you can specify even more information. Complex bitmaps may include their own palette and may specify their own horizontal and vertical resolution. They are very useful for working with bitmaps that may have been captured on other systems or for working with display devices.

The GrDestroyBitmap() routine destroys some or all of the information associated with a bitmap. You may use this function to free all memory taken up by the bitmap. You may also use this function to free only the GState associated with a bitmap by GrCreateBitmap() , but leave the bitmap's data alone; the BMDestroy argument will determine exactly what is destroyed. This usage comes in handy for those times when a bitmap will not be changing, but will be drawn. Large bitmaps are stored in HugeArrays so they won't take up inordinate amounts of RAM; of course it's always wise to free the memory associated with a bitmap when that bitmap is no longer needed.

If you have freed the GState associated with a huge bitmap using GrDestroyBitmap() but want to make changes to the bitmap, all is not lost. Call GrEditBitmap() to associate a new GState with the bitmap. Be careful, however; the bitmap will not recall anything about the old GState, so you must set up colors, patterns, and other such information again. To update the VM file used to store a bitmap (if any), call GrSetVMFile() .

GrClearBitmap() clears the data from a bitmap.

GrGetPoint() can retrieve information from a bitmap, returning its color value for some location. It works with all sorts of display areas, not just bitmaps. It is mentioned here because of its usefulness for those who wish to be able to exercise effects on their bitmaps.

GrSetBitmapMode() gives you control over how drawing commands will affect the bitmap. If your bitmap has a mask, use this routine to switch between editing the mask and the bitmap itself; the BitmapMode argument will specify what is to be edited.

This routine also gives you control over how monochrome bitmaps should handle color. When you draw something in color to a monochrome bitmap, the system tries to approximate the color using dithering. It turns some pixels on and some pixels off in an attempt to simulate the color's brightness. A crimson area would appear with most pixels black, and thus rather dark. A pink area on the other hand would have mostly white pixels, and thus appear light. GrSetBitmapMode() can change which strategy GEOS will use when deciding which pixels to turn on. If you wish to use "dispersed" dithering, the pixels turned on will be spread out evenly, resulting in a smooth gray. However, some output devices (notably certain printers) have trouble drawing small, widely spaced dots accurately. Using "clustered" dithering causes the system to keep the pixels turned on close together, resulting in pictures reminiscent of newspaper photographs. Thus, devices that prefer a few big dots to lots of little dots will have an easier time with bitmaps so edited.

The bitmap mode information may also include a color transfer table. These tables are normally only used by printer drivers, but your geode is welcome to use them, if you can find a reason. Some models of printer have problems when mixing colors. Several printers have problems trying to mix dark colors, tending to end up with black. The table contains a byte value for each possible value of each color component. When mixing the colors, the graphics system will find the real color value to use in the table. Thus, if the reds in RGB bitmaps are looking somewhat washed out, you might set up a table so that reds would be boosted. RGBT_red[1] might be 16, RGBT_red[2] 23, so that the device would use more than the standard amount of the red component.

GrGetBitmapMode() returns the current bitmap editing mode.

GrSetBitmapRes() works with complex bitmaps, changing their resolution. Because simple bitmaps are assumed to be 72 dpi, their resolution cannot be changed unless they are turned into complex bitmaps. GrGetBitmapRes() returns the resolution associated with a complex bitmap.

GrGetBitmapSize() returns a bitmap's size in points. This function might be useful for quickly determining how much space to set aside when displaying the bitmap. GrGetHugeBitmapSize() retrieves the size of a bitmap stored in a HugeArray .

Use GrCompactBitmap() and GrUncompactBitmap() to compact and uncompact bitmaps. Compacted bitmaps take up less memory; uncompacted bitmaps draw more quickly. Note that the bitmap drawing routines can handle compacted and uncompacted bitmaps. These functions are here to aid programmers who wish more immediate control over their memory usage.


Up: GEOS SDK TechDocs| Up | Prev: 6 Graphics State | Next: 8 Graphics Strings