Objective Views : Chapter 8 Components : Image Components
Image Components
The CODImageComponent class encapsulates drawing of a bitmap image. It contains an SECDib object that can be loaded from a disk file, from an application resource, or from memory. The images are stored in a cache in order to prevent multiple copies of the same image from consuming memory. The file name or resource ID is used to identify images in the cache.
Image components cannot be assigned line or fill properties; however, they can be made transparent by assigning a transparent color. The CODSprite class is used to provide transparency for DIBs contained by CODImageComponent objects.
The hierarchy for image classes is shown in Figure 69.
Figure 69 – Image class hierarchy
CODDib
The DIB class handles the loading of and storage of images as device independent bitmaps. It also implements the code to make one color in a bitmap transparent when it is drawn.
CODImageCache
The image cache stores bitmaps for the image components. Suppose you had one thousand symbols in your model that incorporated an image of a stingray. Obviously, it would require a large space in memory to store one thousand stingray bitmaps. Fortunately, you can use the image cache to store one copy of a bitmap and let multiple components reference it.
Use of the image cache is not restricted to image components. You can store images from any source in the cache.
CODImageComponent
The image component contains a bitmap. The points stored in the component define the edges of the bitmap. This component cannot be assigned a line or fill property; however, you can assign it a color so that the bitmap is transparent when the user draws it.
CODImageEntry
An image entry is the data stored in the image cache. Each image entry holds a device independent bitmap that is ready for use. Image entries are reference counted, so if a program ceases to use an image, it is freed from memory.
CODMetafileComponent
The metafile component encapsulates a Windows Enhanced Metafile. The metafile can be loaded from a file, as an application resource, or be copied from a handle. The Windows Enhanced Metafile Format (EMF) is a vector graphics format that stores a list of GDI drawing commands. Each record in the file represents a GDI drawing function and its parameters. When the metafile is played onto a device context, the records in the metafile are executed. The metafile component draws itself by playing the metafile into the bounding rectangle of the component.
CODSprite
The sprite class wraps a DIB class and implements the transparency feature. It sets up the DIB so that a certain color does not get drawn when the rest of the bitmap does.
Using Metafile Components
The CODMetafileComponent class encapsulates a Windows enhanced metafile as an Objective Views component. The Windows metafile format is a vector graphics format that consists of a list of GDI commands. A metafile is rendered by playing the list of GDI commands onto a device context. For simple to moderately complex graphics, metafiles are more efficient in terms of space and performance. Unlike bitmaps, metafiles do not distort when scaled. Unless your graphics are complex in nature, it is recommended that you use metafiles instead of bitmaps.
Metafile components can be loaded from a file, an application resource, or from an existing metafile handle. The metafile component is derived from CODPointComponent and always contains four points that define a bounding rectangle in local coordinates. The local points can be set with the function CODMetafileComponent::SetLocalBounds(). The component’s transformations are applied to the local points to yield the world points, which determine the bounding rectangle in which the metafile is played. The logical bounding rectangle in which the metafile is drawn can be acquired by calling the GetBounds() function. Example 6 demonstrates loading a metafile from a disk file, setting the local bounds, and moving it.
Example 6 – Working with metafile components
void CMyController::OnFoobar()
{
CODMetafileComponent* pMetafile = new CODMetafileComponent();
pMetafile->LoadFromFile(“foobar.emf”);
pMetafile->SetLocalBounds(CRect(0,0,100,100));
pMetafile->Translate(50,25);
ExecuteInsertCommand(pMetafile);
}
In order to draw a metafile component at the original size of the metafile, you need to explicitly call SetLocalBounds() or SizeToFrame(). The metafile contains a header that indicates the original frame size of the graphic in MM_HIMETRIC units. This size must be converted into logical units for your canvas. To get the original frame size in logical units for your canvas, call CODMetafileComponent::GetLogFrame() passing it a pointer to the IODRuler interface for your viewport. Then call SetLocalBounds(), passing it the resulting rectangle. Alternatively, you can call SizeToFrame() and have it scale the metafile component to the original frame size. Example 7 demonstrates loading a metafile from an application resource and setting its size to the original metafile size.
Example 7 – Setting the size of a metafile
void CMyController::OnFoobar()
{
CODMetafileComponent* pMetafile = new CODMetafileComponent();
pMetafile->LoadFromFile(IDR_FOOBAR);
CRect rcFrame;
pMetafile->GetLogFrame(GetCanvasVp()->GetRuler(), rcFrame);
pMetafile->SetLocalBounds(rcFrame);
ExecuteInsertCommand(pMetafile);
}