Bitmap Animation Overview

Purpose

This document shows you how to create an animation using the Bitmap Animation framework.

Architectural relationships

The Bitmap Animation framework (bmpanim.dll) uses the font and bitmap server (fbscli.dll) to provide the bitmap images (CFbsBitmap s).

An animation DLL (bmpansrv.dll), loaded by the Window Server, is used to perform the animation.

The animation DLL uses the bitgdi component (bitgdi.dll) to draw the bitmaps.

Description

To use a bitmap animation in your application you need to:

  • define one or more animation frames, each of which owns a bitmap,

  • assign the frames to an animation container,

  • create an animation player object and pass the animation container to it. This communicates with the window server to start and stop playing the animation inside a window.

Collectively, these steps make up the Bitmap Animation framework. The key client side classes that are involved in these steps are:

The rest of this document describes each of these steps, starting with the animation frame.

Defining an animation frame

The CBitmapFrameData class represents a single frame in an animation. The following properties of a frame can be set:

  • the bitmap image,

  • the mask, which is used for making parts of the image transparent,

  • the time the frame is displayed, in milliseconds,

  • the position in the window where the frame is displayed.

These properties can either be set in CBitmapFrameData::NewL() or by calling various setter functions, described below.

Setting the image and mask bitmaps

The following code loads the bitmap and mask from a multi bitmap file, and constructs the frame, setting its bitmap and mask, which it takes ownership of:

CFbsBitmap* bitmap=new (ELeave) CFbsBitmap; // load the image bitmap from an mbm file 
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Load(KMBMFileName, EMbmAnimFrame1));
CFbsBitmap* mask=new (ELeave) CFbsBitmap; // load the mask from the same mbm file
CleanupStack::PushL(mask);
User::LeaveIfError(mask->Load(KMBMFileName, EMbmAnimFrameMask1));
CBitmapFrameData* frame1 = CBitmapFrameData::NewL(bitmap, mask);
CleanupStack::Pop(2); // bitmap, mask

CBitmapFrameData::SetBitmap() and CBitmapFrameData::SetMask() could alternatively be used.

An animation can have multiple frames, each of which has an image and mask bitmap. Each frame stores a flag to indicate whether or not it owns the bitmaps. If the frame owns the bitmaps, they are deleted in the frame’s destructor. This flag can be set or unset by calling CBitmapFrameData::SetBitmapsOwnedExternally(). By default, bitmaps are owned by the frame.

The mask is used in the standard way for a bitmap mask, so pixels in the bitmap image that map to black pixels in the mask are drawn, while pixels that map to white pixels in the mask are not, so appear transparent.

Setting the time interval

The time period for the frame to be displayed on the screen is set in milliseconds:

frame1->SetInterval(125);

Note that a default time interval can be set in the frame container (described in the next section) by calling CBitmapAnimClientData::SetFrameInterval(). Any value set in the container will apply to frames that have not set an interval themselves.

Setting the frame’s position

The position of the frame relative to the animation window is set using CBitmapFrameData::SetPosition():

TPoint framePos(3,6);
frame1->SetPosition(framePos);

Note that the position can also be specified in RBitmapAnim; if so, this value applies to all frames.

When you have finished defining the animation frame(s), use the frame container class, CBitmapAnimClientData, to create the animation.

Defining an animation

Frames are grouped into an animation frame container (CBitmapAnimClientData), which allows the following behaviour to be set:

  • append frames to the container,

  • set a default display interval for all frames, (note that the time interval set by an individual frame takes precedence, for that frame, over the default interval),

  • set one of the following play modes for the animation: play once, loop or bounce (plays forwards and backwards),

  • set the animation to flash,

  • provide an additional bitmap frame to use for the background to the animation (explained below).

Appending frames

First, create the frame container, and append the frame(s) to it in the correct sequence:

CBitmapAnimClientData* animFrames=CBitmapAnimClientData::NewL();
CleanupStack::PushL(animFrames);
animFrames->AppendFrameL(*frame1);
animFrames->AppendFrameL(*frame2); // etc.

Setting the default display interval

A default display interval can be set for the animation:

animFrames->SetFrameInterval(100);

This applies only to frames which have not specified their own interval (using CBitmapFrameData::SetInterval()). In this example, the default interval for frames without their own interval is 100 milliseconds (0.1 second). It can be used to ensure that all frames are displayed for the same length of time.

Setting the play mode

There are three play modes: play once, play repeatedly in the same direction ('loop') and play forwards and backwards repeatedly ('bounce'). This code sets the animation to play once:

animFrames->SetPlayMode(CBitmapAnimClientData::EPlay);

Other properties

CBitmapAnimClientData::SetFlash() and CBitmapAnimClientData::SetBackgroundFrame() are used to set/unset the flash flag and the background frame, respectively. The flash flag determines whether the animation should flash or not.

The background frame, which is optional, is used to clear the current frame before drawing the next one. If no background frame is provided by the client, the window server creates its own background frame using the original screen contents, and updates it when the animation window is redrawn.

If the client-provided background frame contains an image bitmap and a mask, the background image used is a combination of the screen contents and the supplied background bitmap. If the client-provided background frame has a bitmap but no mask, the bitmap is used as the background.

Playing the animation

When the animation is ready to play, it must be packaged and sent to the window server’s animation DLL. This is done through an animation player (RBitmapAnim) object.

RBitmapAnim allows you to do the following:

  • specify the window in which the animation is displayed,

  • associate the animation with an RAnimDll object, which provides a connection to the window server,

  • pass the animation object to the window server’s animation DLL,

  • specify the number of times the animation should play,

  • start and stop playing the animation. Optionally the animation can start playing from a particular frame.

Note that after the animation object has been set up and passed to the window server, the general attributes of the animation, namely the flash property, the default display time for each frame and the play mode can still be changed, using the following RBitmapAnim functions:

  • SetFlashL(),

  • SetFrameIntervalL(),

  • SetPlayModeL().

Any changes to these properties made using RBitmapAnim will override the values previously set in CBitmapAnimClientData.

Constructing the animation player

RAnimDll is a handle to the server-side animation DLL. It is used to load the window server animation DLL, bmpansrv.dll, which provides the functions that perform the frames animation. The RAnimDll instance is passed to the RBitmapAnim constructor.

RAnimDll animDLL(iEikonEnv->WsSession()); // session is used to interact with the window server
_LIT(KDllName, "BMPANSRV.DLL"); 
User::LeaveIfError(animDll.Load(KDllName)); 
RBitmapAnim animPlayer(animDLL);
animPlayer.ConstructL(Window());

Passing the animation object to the window server

The animation frame container (CBitmapAnimClientData) should be passed via the RBitmapAnim object to the window server. This is done using the function SetBitmapAnimDataL(). Note that calling this function does not cause the animation to start playing:

animPlayer.SetBitmapAnimDataL(*animFrames);

Setting the number of cycles

If the animation should play more than once, the number of cycles should be set:

animPlayer.SetNumberOfCyclesL(10);

Note that if the animation's play mode is 'bounce', the number of cycles must be set to at least two to ensure a complete animation routine.

Setting the position

To set the animation’s position, use SetPositionL(). This value is an offset from the origin of the animation window.

TPoint animPos(20,40);
animPlayer.SetPositionL(animPos);

Starting/stopping the animation

The RBitmapAnim::StartL() and RBitmapAnim::StopL() functions send commands to the animation DLL to start/stop the animation routine.

Calling RBitmapAnim::DisplayFrameL() before the animation has started sets the frame from which the animation should start playing.

Freeing resources

After they have been finished with, Close() should be called on the RAnimDll and RBitmapAnim objects.

animPlayer.Close();
animDLL.Close();