COpenFontRasterizerContext
The rasterizer context provides the link between the framework required by the Open Font system, and the rasterizer engine.
As such it should contain a function to return a bitmap for the specified character, and then convert it into Symbian's run-length
encoded format. Information about this format is provided in "How to derive from COpenFont
".
COpenFontRasterizerContext
is a convenience class — use of this class is optional. It contains a number of utility functions to make it easier to write
glyph bitmaps in Symbian's bitmap format.
Use COpenFontRasterizer::StartGlyph()
to initialise the buffer for writing the bitmap. Use COpenFontRasterizer::WriteGlyphBit()
to write the individual bits to the buffer. When all the bits have been added to the buffer, call COpenFontRasterizer::EndGlyph()
to write the glyph bitmap to aGlyphData->iBitmapBuffer
The following code fragment shows a partial implementation of CFreeTypeContext::RasterizeL()
. This function creates the glyph bitmap used to represent a specified character, based on the specification in the font file.
This fragment has been provided because it shows how the glyph information is obtained from the font file, and how to implement
the algorithm to write a glyph in Symbian run-length encoded format. Note the use of StartGlyph()
, WriteGlyphBit()
and EndGlyph()
.
//code before here writes the character metrics to aGlyphData
// Try to use the built in raster map; if it's not big enough use a temporary bigger one.
TBool use_temp_raster_map = width > KRasterWidth || height > KRasterHeight;
CRasterMap* cur_raster_map = iRasterMap;
if (use_temp_raster_map)
{
cur_raster_map = CRasterMap::NewL(width,height);
CleanupStack::PushL(cur_raster_map);
}
cur_raster_map->Clear();
TT_Raster_Map& tt_raster_map = cur_raster_map->RasterMap();
error = TT_Get_Glyph_Bitmap(aGlyph, &tt_raster_map,-tt_metrics.bearingX,(tt_raster_map.rows - ascent) << 6);
if (error)
User::Leave(KErrGeneral);
StartGlyph(aGlyphData);
const TUint8* p = (const TUint8*)tt_raster_map.bitmap;
int row = 0;
while (row < height)
{
// Find the number of repeating or non-repeating rows (up to 15)
int count = 1;
TBool repeating = EFalse;
const TUint8* cur = p;
while (count < 15 && row + count < height)
{
const TUint8* prev = cur;
cur += tt_raster_map.cols;
TBool same = Mem::Compare(prev,width_bytes,cur,width_bytes) == 0;
if (count == 1)
repeating = same;
else if (repeating != same)
break;
count++;
}
// Write a 0 for repeating or a 1 for non-repeating.
WriteGlyphBit(repeating ? 0 : 1);
// Write the count.
WriteGlyphBit(count & 1 ? 1 : 0);
WriteGlyphBit(count & 2 ? 1 : 0);
WriteGlyphBit(count & 4 ? 1 : 0);
WriteGlyphBit(count & 8 ? 1 : 0);
// Write a single repeating row or all the non-repeating rows.
int rows_written = repeating ? 1 : count;
cur = p;
for (int row_written = 0; row_written < rows_written; row_written++, cur += tt_raster_map.cols)
{
int col = 0;
for (int byte = 0; byte < width_bytes; byte++)
{
unsigned char x = cur[byte];
for (int bit = 0; bit < 8 && col < width; bit++, col++, x <<= 1)
WriteGlyphBit(x & 128 ? 1 : 0);
}
}
row += count;
p += tt_raster_map.cols * count;
}
EndGlyph();
if (use_temp_raster_map)
CleanupStack::PopAndDestroy(); // cur_raster_map
}