# The Interface Kit: BBitmap

Derived from: public BArchivable

Declared in: be/interface/Bitmap.hz

Library: libbe.so

## Overview

A BBitmap object is a container for data that describes an image pixel by pixel. The class provides a way of specifying a bitmap from raw data, and also a way of creating the data using the Interface Kit graphics mechanism.

The BBitmap class doesn't provide a way to actually display the bitmap data. Displaying a bitmap is the task of BView functions such as `DrawBitmap()`.

### Bitmap Data

An image bitmap records the color values of pixels within a rectangular area. The pixels in the rectangle, as on the screen, are arranged in rows and columns. The data is specified in rows, beginning with the top row of pixels in the image and working downward to the bottom row. Each row of data is aligned on a long word boundary and is read from left to right.

New BBitmap objects are constructed with two pieces of information that prepare them to store bitmap data--a bounds rectangle and a color space. For example, this code

       BRect rect(0.0, 0.0, 79.0, 39.0);
       BBitmap *image = new BBitmap(rect, B_CMAP8);

constructs a bitmap of 40 rows and 80 pixels per row. Each pixel is specified by an 8-bit color value.

#### The Bounds Rectangle

A BBitmap's bounds rectangle serves two purposes:

- It sets the size of the image. A bitmap covers as many pixels as its bounds rectangle encloses--under the assumption that one coordinate unit equals one pixel, as it does when the display device is the screen.

  Since a bitmap can't contain a fraction of a pixel, the bounds rectangle shouldn't contain any fractional coordinates. Without fractional coordinates, each side of the bounds rectangle will be aligned with a column or a row of pixels. The pixels around the edge of the rectangle are included in the image, so the bitmap will contain one more column of pixels than the width of the rectangle and one more row than the rectangle's height. (See the BRect class for an illustration.)

- It establishes a coordinate system that can be used later by drawing functions, such as `DrawBitmap()` and `DragMessage()`, to designate particular points or portions of the image.

If a BBitmap object enlists BViews to create the bitmap data, it must have a bounds rectangle with (0.0, 0.0) at the left top corner.

#### The Color Space

The color space of a bitmap determines its depth (how many bits of information are stored for each pixel) and its interpretation (what the data values mean). Bitmap data may be stored in any of the following color spaces:

`B_GRAY1` |
`B_CMAP8` |
`B_RGB15` | `B_RGB15_BIG`
`B_RGBA15` | `B_RGBA15_BIG`
`B_RGB16` | `B_RGB16_BIG`
`R_RGB32` | `R_RGB32_BIG`

A complete description of the color spaces, including the ordering and assignment of pixel color data, can be found under "Colors" in the "Drawing" section of this chapter.

### Specifying the Image

BBitmap objects begin life empty. When constructed, they allocate sufficient memory to store an image of the size and color space specified. However, the memory isn't initialized. The actual image must be set after construction. This can be done by explicitly assigning pixel values with the `SetBits()` function:

       image->SetBits(rawData, numBytes, 0, B_CMAP8);

You can also get the `Bits()` pointer to the memory buffer and copy image data directly to it:

       uchar *bits (uchar *)image->Bits();
       memcpy(bits, sourceData, numBytes);

In this case, you must make sure the data is written in the internal format of the BBitmap object.

In addition to these functions, BView objects can be enlisted to produce the bitmap. Views are assigned to a BBitmap object just as they are to a BWindow (by calling the `AddChild()` function). In reality, the BBitmap sets up a private, off-screen window for the views. When the views draw, the window renders their output into the bitmap buffer. The rendered image has the same format as the data captured by the `SetBits()` function. `SetBits()` and BViews can be used in combination to create a bitmap.

The BViews that construct a bitmap behave a bit differently than the BViews that draw in regular windows:

- In contrast to BViews attached to an ordinary window, the BViews assigned to a BBitmap can create an image off-screen. When an ordinary window is hidden, it doesn't render images; its BViews may draw, but they don't produce image data. However, the BViews assigned to a BBitmap produce an off-screen bitmap.

- Because they never appear on-screen, the BViews that produce a bitmap image never handle events and never get update messages telling them to draw. You must call their drawing functions directly in your own code.

- Because there are no update messages, the output buffer to the Application Server isn't automatically flushed. You must flush it explicitly in application code. This is best done by calling `Sync()`, rather than `Flush()`, so that you can be sure the entire image has been rendered before the bitmap is used.

- A BBitmap has no background color against which images are drawn. Your code must color every pixel within the bounds rectangle.

- Views that are attached to a BWindow normally draw in the window's thread. However, views attached to a BBitmap don't draw in a separate thread; the BBitmap doesn't set up an independent thread for its private window.

If BViews are used to produce a static image, one that will not change, you need to have them draw just once. After creating the image, they can be discarded; they'll never be called upon to update the image. However, if the bitmap will change--perhaps to reflect decisions the user makes as the program runs--the BViews can be retained to make the changes. The BBitmap will serve as an offscreen buffer for a dynamic display.

So that you can manage the BViews that are assigned to a BBitmap, the BBitmap class duplicates a number of BWindow functions--such as `AddChild()`, `FindView()`, and `ChildAt()`.

A BBitmap that enlists views to produce the bitmap consumes more system resources than one that relies solely on `SetBits()`. Therefore, by default, BBitmaps refuse to accept BViews. If BViews will be used to create bitmap data, the BBitmap constructor must be informed so that it can set up the off-screen window and prepare the rendering mechanism.

### Transparency

Color bitmaps can have transparent pixels. When the bitmap is imaged in a drawing mode other than `B_OP_COPY`, its transparent pixels won't be transferred to the destination view. The destination image will show through wherever the bitmap is transparent.

To introduce transparency into a `B_CMAP8` bitmap, a pixel can be assigned a value of `B_TRANSPARENT_8_BIT`. In a `B_RGB32` bitmap, a pixel can be assigned the special value of `B_TRANSPARENT_32_BIT`. (Or `B_TRANSPARENT_32_BIT` can be made the high or low color of the BView drawing the bitmap.)

Transparency is covered in more detail under Drawing Modes .

See also: `system_colors()`

## Constructor and Destructor

### BBitmap()

          BBitmap(BRect bounds, color_space space,
             bool acceptsViews = false,
             bool needsContiguousMemory = false)
          BBitmap(BMessage *archive)

Initializes the BBitmap to the size and internal coordinate system implied by the bounds rectangle and to the depth and color interpretation specified by the space color space.

This function allocates enough memory to store data for an image the size of bounds at the depth required by space, but does not initialize any of it. All pixel data should be explicitly set using the `SetBits()` function, by copying it to the address returned by `Bits()`, or by enlisting BViews to produce the bitmap. If BViews are to be used, the constructor must be informed by setting the acceptsViews flag to `true`. This permits it to set up the mechanisms for rendering the image, including an off-screen window to contain the views.

If the needsContiguousMemory flag is `true`, the BBitmap will make sure that the memory it allocates is one contiguous chunk. This should matter only to drivers doing direct DMA into physical memory. If the flag is `false`, as it is by default, allocated memory may or may not be contiguous.

The possible color spaces are enumerated in the section above titled The Color Space.

If the BBitmap accepts BViews, the left and top sides of its bounds rectangle must be located at 0.0.

### ~BBitmap()

          virtual ~BBitmap()

Frees all memory allocated to hold image data, deletes any BViews used to create the image, gets rid of the off-screen window that held the views, and severs the BBitmap's connection to the Application Server.

## Member Functions

### AddChild()

          virtual void AddChild(BView *aView)

Adds aView to the hierarchy of views associated with the BBitmap, attaching it to an off-screen window (one created by the BBitmap for just this purpose) by making it a child of the window's top view. If aView already has a parent, it's removed from that view hierarchy and adopted into this one. A view can serve only one window at a time.

Like `AddChild()` in the BWindow class, this function calls the BView's `AttachedToWindow()` function to inform it that it now belongs to a view hierarchy. Every view that descends from aView also becomes attached to the BBitmap's off-screen window and receives its own `AttachedToWindow()` notification.

`AddChild()` fails if the BBitmap was not constructed to accept views.

See also: `BWindow::AddChild()`, `BView::AttachedToWindow()`, `RemoveChild()`, the BBitmap constructor

### Bits()

          void *Bits(void) const

Returns a pointer to the bitmap data. The data lies in memory shared by the application and the Application Server. The length of the data can be obtained by calling `BitsLength()`--or it can be calculated from the height of the bitmap (the number of rows) and the number of bytes per row.

A `B_RGB32` bitmap holds the data in an internal format that's most natural for screen display devices. In this format, the color components are ordered BGRA (blue, green, red, alpha).

See also: `Bounds()`, `BytesPerRow()`, `BitsLength()`

### BitsLength()

          int32 BitsLength(void) const

Returns the number of bytes that were allocated to store the bitmap data.

See also: `Bits()`, `BytesPerRow()`

### Bounds()

          BRect Bounds(void) const

Returns the bounds rectangle that defines the size and coordinate system of the bitmap. This should be identical to the rectangle used in constructing the object.

### BytesPerRow()

          int32 BytesPerRow(void) const

Returns how many bytes of data are required to specify a row of pixels. For example, a monochrome bitmap (one bit per pixel) 80 pixels wide would require twelve bytes per row (96 bits). The extra sixteen bits at the end of the twelve bytes are ignored. Every row of bitmap data is aligned on a long word boundary.

### ChildAt(), CountChildren()

          BView *ChildAt(int32 index) const

          int32 CountChildren(void) const

`ChildAt()` returns the child BView at index, or `NULL` if there's no child at index. Indices begin at 0 and count only BViews that were added to the BBitmap (added as children of the top view of the BBitmap's off-screen window) and not subsequently removed.

`CountChildren()` returns the number of BViews the BBitmap currently has. (It counts only BViews that were added directly to the BBitmap, not BViews farther down the view hierarchy.)

These functions fail if the BBitmap wasn't constructed to accept views.

### ColorSpace()

          color_space ColorSpace(void) const

Returns the color space of the data being stored (not necessarily the color space of the data passed to the `SetBits()` function). Once set by the BBitmap constructor, the color space doesn't change.

### CountChildren() see ChildAt()

### FindView()

          BView *FindView(BPoint point) const
          BView *FindView(const char *name) const

Returns the BView located at point within the bitmap or the BView tagged with name. The point must be somewhere within the BBitmap's bounds rectangle, which must have the coordinate origin, (0.0, 0.0), at its left top corner.

If the BBitmap doesn't accept views, this function fails. If no view draws at the point given, or no view associated with the BBitmap has the name given, it returns `NULL`.

### IsValid()

          bool IsValid(void) const

Returns `true` if there's memory for the bitmap (if the address returned by `Bits()` is valid), and `false` if not.

### Lock(), Unlock()

          bool Lock(void)

          void Unlock(void)

These functions lock and unlock the off-screen window where BViews associated with the BBitmap draw. Locking works for this window and its views just as it does for ordinary on-screen windows.

`Lock()` returns `false` if the BBitmap doesn't accept views or if its off-screen window is unlockable (and therefore unusable) for some reason. Otherwise, it doesn't return until it has the window locked and can return `true`.

### RemoveChild()

          virtual bool RemoveChild(BView *aView)

Removes aView from the hierarchy of views associated with the BBitmap, but only if aView was added to the hierarchy by calling BBitmap's version of the `AddChild()` function.

If aView is successfully removed, `RemoveChild()` returns `true`. If not, it returns `false`.

### SetBits()

          void SetBits(const void *data, int32 length, int32 offset, color_space mode)

Assigns length bytes of data to the BBitmap object. The new data is copied into the bitmap beginning offset bytes (not pixels) from the start of allocated memory. To set data beginning with the first (left top) pixel in the image, the offset should be 0; to set data beginning with, for example, the sixth pixel in the first row of a `B_RGB32` image, the offset should be 20. The offset counts any padding required to align rows of data.

The source data is specified in the mode color space, which may or may not be the same as the color space that the BBitmap uses to store the data. If not, the following conversions are automatically made:

- `B_GRAY1` and `B_RGB32` to `B_CMAP8`.
- `B_CMAP8` and `B_GRAY1` to `B_RGB32`.

Colors may be dithered in a conversion to `B_CMAP8` so that the resulting image will match the original as closely as possible, despite the lost information.

If the color space mode is `B_RGB32`, the data should be triplets of three 8-bit components--red, green, and blue, in that order--without an alpha component. Although stored as 32-bit quantities with the components in BGRA order, the input data is only 24 bits in RGB order. Rows of source data do not need to be aligned.

However, if the source data is in any mode other than `B_RGB32`, padding must be added so that each row is aligned on a `int32` word boundary.

This function works for all BBitmaps, whether or not BViews are also enlisted to produce the image.

## Archived Fields

The `Archive()` function adds the following fields to its BMessage argument:

Field | Type code | Meaning
"_frame" | `B_RECT_TYPE` | The BBitmap's bounds rectangle.
"_cspace" | `B_INT32_TYPE` | The color_space of the data.
"_view_ok" | `B_BOOL_TYPE` | Always `true`, indicating the BBitmap accepts views (only present in deep copy archives of BBitmaps accepting views).
"_data" | `B_RAW_TYPE` | The bitmap data (present only if "_view_ok" not present).
"_continguous" | `B_BOOL_TYPE` | Whether the BBitmap requires memory in one contiguous chunk.

If the "_view_ok" field is present, the child views of the BBitmap are additionally archived in the "_views" array of BMessages. See the description of the BView Archived Fields for more information on those fields.

The Be Book, in lovely HTML, for BeOS Release 3.

Copyright © 1998 Be, Inc. All rights reserved.

Last modified March 26, 1998.