Deriving from COpenFont

Overview

Write a class derived from COpenFont to represent an instance of a typeface at a particular size, provide bitmaps of the glyphs, and determine whether a particular character is defined in the typeface. An object of this type is created by COpenFontFile::GetNearestFontInPixelsL() when it is called by the Font and Bitmap server.

To derive from COpenFont:

  • Write a function to construct the derived object on the shared heap. The base class constructor must be called when creating the derived object.

  • Provide an implementation for COpenFont's pure virtual function RasterizeL().

These are discussed further in the following sections.

Construction using the shared heap

The derived object must be created on a shared heap because it is shared by several processes, e.g. the Font and Bitmap Server and its clients. The following code fragment shows how the FreeType implementation creates the object on the shared heap aHeap:

CFreeTypeFont* CFreeTypeFont::NewL(RHeap* aHeap,
    COpenFontSessionCacheList* aSessionCacheList,
    CFreeTypeFontFile* aFontFile,TInt aSizeInPixels)
    {
    CFreeTypeFont* f =
        (CFreeTypeFont*)aHeap->AllocL(sizeof(CFreeTypeFont));
    new(f) CFreeTypeFont(aHeap,aSessionCacheList,aFontFile);
    CleanupStack::PushL(f);
    f->ConstructL(aSizeInPixels);
    CleanupStack::Pop();
    return f;
    }

Note that we use aHeap->AllocL() to obtain memory, then construct in place using a placement argument to new.

The base class constructor is called when creating the derived object. Pass the arguments aHeap and aSessionCacheList supplied to COpenFontFile::GetNearestFontInPixelsL(), and pass the address of the COpenFontFile object that creates the COpenFont (i.e., 'this') as aFile.

Implementing RasterizeL()

The derived class's RasterizeL() function is called by the Font and Bitmap Server to return the bitmap for a specified Unicode character. The function prototype is given below:

virtual void RasterizeL(TInt aCode,TOpenFontGlyphData* aGlyphData) = 0;

Implementations must create a bitmap, in Symbian's run-length-encoded format, for the Unicode character aCode. The bitmap must be placed in aGlyphData->iBitmapBuffer, and the character metrics must be placed in aGlyphData->iMetricsBuffer. The other parts of aGlyphData should be left alone.

The actual rasterization task should be passed to the rasterization engine. One way of doing this is to call some rasterization member function of the COpenFontFile object, to which a pointer can be obtained by calling COpenFont::File(). The derived COpenFontFile object can then call a rasterizer function via a pointer it owns to the rasterizer context object. Note that if the rasterizer context object is derived from COpenFontRasterizerContext, it will have utility functions for writing bits to the bitmap buffer in Symbian's run-length-encoded format.

The FreeType implementation follows this strategy. CFreeTypeFont::RasterizeL() calls CFreeTypeFontFile::RasterizeL(), which calls CFreeTypeContext::RasterizeL().

The run-length-encoded bitmap format

The run-length-encoded format is a packed binary format starting on a byte boundary and made up of a number of sections.

Each section starts with a five-bit header. If the first bit of the header is 0 the next four bits are a repeat count, starting with the least significant bit, and a single row of bits follows (the number of bits in a row is specified by aGlyphData->iMetricsBuffer.Width()). If the first bit of the header is 1 the next four bits are a count of non-repeating rows, again starting with the least significant bit, and that many rows of bits follow.

See How to derive from COpenFontRasterizerContext for an implementation of this algorithm.