Add MMP files to build libOpenVG_sw.lib which uses LINKAS to redirect to libOpenVG.dll (and
the same for libEGL_sw.lib and libOpenVGU_sw.lib).
Only the libEGL_sw.lib redirection isn't activated - this can't happen until there is a merged
libEGL.dll which supports the OpenWF synchronisation and also implements the graphical support functions.
The overall aim is to eliminate the *_sw.dll implementations, at least as a compile-time way of choosing
a software-only implementation.The correct way to choose is to put the right set of libraries into a ROM
with suitable renaming, and in the emulator to use the "switching DLL" technique to pick the right set.
As the Symbian Foundation doesn't have any alternative implementations, we don't need the switching DLLs
and we can build directly to the correct name.
/*
* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
* Header FNTREADR.CPP
*
*/
#include "FNTREADR.H"
const int KMarkFirstCharacterInTypeface = -1;
const int KBytesAddedForMetricIndex = 2;
const int KBytesForIndexForFillCharacters = 2;
const int KReportRateFrequencyInPercent = 10;
// class CroppedValues
class CroppedValues
{
public:
CroppedValues();
public:
int iTopCrop;
int iBottomCrop;
int iLeftCrop;
int iRightCrop;
};
CroppedValues::CroppedValues()
: iTopCrop(0), iBottomCrop(0), iLeftCrop(0), iRightCrop(0)
{}
// class FontReader
FontReader::FontReader()
: Reader(),
iFontStore(),
iFontStoreFile(NULL),
iCharacterMetrics(NULL),
iCodeSection(NULL),
iFontBitmap(NULL),
iTypeface(NULL),
iReadFileFormat(ESymbianGDFFormat),
iBitmapWidth(0),
iBitmapHeight(0),
iDefaultXMoveInPixels(KUndefinedInteger),
iDefaultYMoveInPixels(KUndefinedInteger)
{
}
boolean FontReader::Read(const String& aFilename)
{
iFileName = aFilename;
boolean state = Open(iFileName.Text());
while (!_EOF() && state)
{
if (IdentComp(IdentBDFFileHeader) || IdentComp(IdentBDFComment))
{
state = ReadBDFFontBitmap();
iReadFileFormat = EBDFFormat;
}
else if (IdentComp(IdentTypeface))
state = ReadTypeface();
else if (IdentComp(IdentFontStoreFile))
state = ReadFontStoreFile();
else
{
Error("Resource identifier expected");
state = efalse;
}
if (state)
state = NewLine();
}
return state;
}
boolean FontReader::ReadMetricFromBDFCharacter(CharacterMetrics* aCharacterMetrics, CroppedValues* aCropped= NULL)
{
int xMoveInPixels = 0;
int yMoveInPixels = 0;
int bitmapXOffset = 0;
int bitmapYOffset = 0;
boolean state = true;
if (iDefaultXMoveInPixels != KUndefinedInteger)
xMoveInPixels = iDefaultXMoveInPixels;
if (iDefaultYMoveInPixels != KUndefinedInteger)
yMoveInPixels = iDefaultYMoveInPixels;
while (!IdentComp(IdentBDFEndChar) && !_EOF() && state)
{
iLexAnal->ReadNextLine(); // Skip to next line
if (iLex->iType == ELexIdent)
{
if (IdentComp(IdentBDFCursorMove))
{
state = Number(xMoveInPixels);
if (state)
state = Number(yMoveInPixels);
}
else if (IdentComp(IdentBDFBitmapSizeAndDisplacement))
{
state = Number(iBitmapWidth);
if (state)
{
state = Number(iBitmapHeight);
state = Number(bitmapXOffset);
state = Number(bitmapYOffset);
}
}
else if (IdentComp(IdentBDFStartBitmap) && state)
{
int line = 0;
for (line = 0; line < iBitmapHeight; line++)
{
iLexAnal->ReadNextLine(); // Skip to next line
int bits = 0;
int bitOffset = 0;
int byteValue = 0;
for (bits = 0; bits < iBitmapWidth; bits++)
{
if (bitOffset == 0)
{
Lexical lex;
strncpy(lex.iText, &iLexAnal->iLine[bits >> 2], 2);
lex.iText[2] = '\0';
byteValue = lex.CovertStringToHex();
bitOffset = 8;
}
bitOffset--;
int bitValue = (byteValue >> bitOffset) & 1;
iBitArray[bits][line] = bitValue;
}
}
}
}
else
{
Error("Fontbitmap identifier expected");
state = efalse;
}
}
if (state)
state = NewLine();
//
// Make sure that bitmap is fully cropped
//
int leftCrop = 0;
int rightCrop = 0;
int topCrop = 0;
int bottomCrop = 0;
int line = 0;
while (BitmapLineEmpty(line) && line < iBitmapHeight)
{
topCrop++;;
line++;
}
line = iBitmapHeight - 1;
while (BitmapLineEmpty(line) && line > topCrop)
{
bottomCrop++;
line--;
}
int column = iBitmapWidth - 1;
while (BitmapColumnEmpty(column) && column >= 0)
{
rightCrop++;
column--;
}
column = 0;
while (BitmapColumnEmpty(column) && column < iBitmapWidth - 1 - rightCrop)
{
leftCrop++;
column++;
}
int croppedBitmapHeight = iBitmapHeight - topCrop - bottomCrop;
int croppedBitmapWidth = iBitmapWidth - leftCrop - rightCrop;
int croppedLeftAdjust = bitmapXOffset + leftCrop;
int croppedRightAdjust = (xMoveInPixels - croppedLeftAdjust - croppedBitmapWidth);
int croppedAscent = croppedBitmapHeight + bitmapYOffset + bottomCrop;
if(state)
{
aCharacterMetrics->iAscentInPixels = (chardim) croppedAscent;
aCharacterMetrics->iHeightInPixels = (chardim) croppedBitmapHeight;
aCharacterMetrics->iLeftAdjustInPixels = (chardim) croppedLeftAdjust;
aCharacterMetrics->iMoveInPixels = (chardim) xMoveInPixels;
aCharacterMetrics->iRightAdjustInPixels = (chardim) croppedRightAdjust;
if (aCropped)
{
aCropped->iBottomCrop = bottomCrop;
aCropped->iLeftCrop = leftCrop;
aCropped->iRightCrop = rightCrop;
aCropped->iTopCrop = topCrop;
}
}
return state;
}
boolean FontReader::ReadBDFCharacter(int /*aCode*/)
{
boolean state = etrue;
ObjectList<String*> character;
iCharacterMetrics = new CharacterMetrics;
CroppedValues* croppedValues = new CroppedValues;
state = ReadMetricFromBDFCharacter(iCharacterMetrics, croppedValues);
if (state)
{
BitmapOffset* offset = new BitmapOffset((uint16)iCodeSection->iCharactersBitmap.iByteList.Length());
iCodeSection->iCharactersBitmap.iByteList.NewByte();
iCodeSection->iCharacters.iBitmapOffsetList.Add(offset);
int index = iFontBitmap->iCharacterMetrics->Index(*iCharacterMetrics);
if (index == -1)
{
Error("Internal Compiler Error");
state = 0;
}
delete iCharacterMetrics;
if (state)
{
iCodeSection->iCharactersBitmap.AddIndex(index);
int line = croppedValues->iTopCrop;
boolean repeatLines;
int countLines = 0;
const int bottomCrop = croppedValues->iBottomCrop;
while (line < (iBitmapHeight - bottomCrop))
{
if ((line + 1) == (iBitmapHeight - bottomCrop))
{
repeatLines = efalse;
countLines = 1;
}
else if (!CompareBitmapLines(line, line + 1))
{
repeatLines = efalse;
for (countLines = 2; ((line + countLines) < (iBitmapHeight - bottomCrop)) && (countLines < KMaxNumberRepeatedLines); countLines++)
{
if (CompareBitmapLines(line + countLines - 1, line + countLines))
break;
}
}
else
{
repeatLines = etrue;
for (countLines = 2; ((line + countLines) < (iBitmapHeight - bottomCrop)) && (countLines < KMaxNumberRepeatedLines); countLines++)
{
if (!CompareBitmapLines(line, line + countLines))
break;
}
}
char bit;
if (repeatLines)
bit = 0;
else
bit = 1;
iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
for (int digit = 0; digit < 4; digit++)
{
bit = char(countLines >> digit);
iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
}
int lineFromTop;
for (lineFromTop = line; lineFromTop < (line + countLines); lineFromTop++)
{
if ((!repeatLines) || (lineFromTop == line))
{
int column;
for (column = croppedValues->iLeftCrop;
column < iBitmapWidth - croppedValues->iRightCrop; column++)
{
if (iBitArray[column][lineFromTop] == 1)
bit = 1;
else
bit = 0;
iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
}
}
}
line = line+countLines;
}
}
}
delete croppedValues;
return state;
}
boolean FontReader::ReadBDFChars(const int aNumberOfGlyphsInFile, const int aMaxConsecutiveFillChars)
{
boolean state = etrue;
boolean newCodeSection = etrue;
int currentEncodingValue = 0; // each glyph has an unique encoding value
int lastEncodingValue = KMarkFirstCharacterInTypeface;
const int maxCharacterBitmapsize =
((KMaxBitmapWidth * KMaxBitmapHeight) / KNumberOfBitsInByte) + KBytesAddedForMetricIndex + KBytesForIndexForFillCharacters;
iCodeSection = NULL;
for (int numberGlyphsRead = 0; state && numberGlyphsRead < aNumberOfGlyphsInFile && !_EOF(); numberGlyphsRead++)
{
if (state && iCodeSection && iCodeSection->iCharactersBitmap.iByteList.Length() + maxCharacterBitmapsize >= KMaxSizeCodeSectionBitmap)
{
newCodeSection = etrue;
}
state = IdentComp(IdentBDFCharLabel);
if (!state)
ErrorIdentifierExpected(IdentBDFCharLabel);
if (state)
iLexAnal->ReadNextLine(); // Skip to next line
if (IdentComp(IdentBDFChar))
{
state = Number(currentEncodingValue);
}
else
{
state = efalse;
ErrorIdentifierExpected(IdentBDFChar);
}
if (KLowestPermittedCharacterEncoding > currentEncodingValue ||
KHighestPermittedCharacterEncoding < currentEncodingValue)
{
while (!IdentComp(IdentBDFEndChar) && !_EOF() && state)
// Skip fill character.
{
iLexAnal->ReadNextLine(); // Skip to next line
}
iLexAnal->ReadNextLine();
continue;
}
if (!iCodeSection || state && (currentEncodingValue > (lastEncodingValue + 1 + aMaxConsecutiveFillChars)))
{
// First character skip to new code section
newCodeSection = etrue;
}
else if (state && !newCodeSection && (currentEncodingValue > lastEncodingValue + 1))
{
WriteFillCharacters(currentEncodingValue - (lastEncodingValue + 1));
}
else if (state && currentEncodingValue <= lastEncodingValue)
{
Error("CodeSection out of sequence");
state = efalse;
}
if (state && newCodeSection)
{
if (iCodeSection)
{
iCodeSection->iEnd = (uint16) lastEncodingValue;
iFontBitmap->iCodeSectionList.Add(iCodeSection);
PrintoutCodeSection(iCodeSection);
}
iCodeSection = new BitmapCodeSection;
iCodeSection->iStart = (uint16) currentEncodingValue;
}
if (state)
state = ReadBDFCharacter(currentEncodingValue);
newCodeSection = efalse;
lastEncodingValue = currentEncodingValue;
}
if (state)
{
iCodeSection->iEnd = (uint16) lastEncodingValue;
iFontBitmap->iCodeSectionList.Add(iCodeSection);
PrintoutCodeSection(iCodeSection);
}
return state;
}
void FontReader::PrintoutCodeSection(const BitmapCodeSection* aCodeSection) const
{
cout << hex << "Codesection 0x" << aCodeSection->iStart << ": 0x" << aCodeSection->iEnd << " read" << endl;
cout.flush();
}
boolean FontReader::ReadBDFFontBitmap()
{
boolean state = etrue;
String label;
iFontBitmap = new FontBitmap;
int pointSize;
int xresolution; // in dots per inch
int yresolution; // in dots per inch
int widthBoundingBox = 0; // In pixels
int heightBoundingBox = 0; // in pixels
int boundingBoxXOffset = 0; // From origin (cursor position at baseline)
int boundingBoxYOffset = 0; // From origin (cursor position at baseline)
int numberChars = 0;
String fontLabel;
int maxNormalCharWidth = KUndefinedInteger;
uid fontUid = KNullUid;
int posture = PostureUpright;
int strokeWeight = StrokeWeightNormal;
int defaultXMoveInPixels = KUndefinedInteger;
int defaultYMoveInPixels = KUndefinedInteger;
int writingDirection = 0;
int maxConsecutiveFillChars = 0; // Max permitted "fill" characters with zero size to prevent
// break between code sections.
int fontAscent = 0;
int fontDescent = 0;
while (!IdentComp(IdentBDFNumChars) && !_EOF() && state)
{
iLexAnal->ReadNextLine(); // Skip to next line
if (iLex->iType == ELexIdent)
{
if (IdentComp(IdentBDFFontBitmap))
{
state = IdentCopy(fontLabel);
}
if (IdentComp(IdentBDFPointSize))
{
state = Number(pointSize);
if (state)
state = Number(xresolution);
if (state)
state = Number(yresolution);
}
else if (IdentComp(IdentBDFFontDesignBox))
{
state = Number(widthBoundingBox);
if (state)
state = Number(heightBoundingBox);
if (state)
state = Number(boundingBoxXOffset);
if (state)
state = Number(boundingBoxYOffset);
}
else if (IdentComp(IdentBDFWritingDirection))
{
Number(writingDirection);
if (writingDirection != 0)
cout << "Warning: Only left to right writing direction supported by EPOC32";
}
else if (IdentComp(IdentBDFCursorMove))
{
state = Number(defaultXMoveInPixels);
if (state)
state = Number(defaultYMoveInPixels);
}
else if (IdentComp(IdentBDFStartProperties)) // Adding additional properties
{
int numberOfProperties;
state = Number(numberOfProperties);
if (state)
state = NewLine();
{for (int properties = 0; properties < numberOfProperties && !_EOF() && state; properties++)
{
if (IdentComp(IdentBDFPropertyUid) || IdentComp(IdentUid))
state = Number(fontUid);
else if (IdentComp(IdentBDFPropertyBold) || IdentComp(IdentBold))
state = Number(strokeWeight);
else if (IdentComp(IdentBDFPropertyItalic) || IdentComp(IdentItalic))
state = Number(posture);
else if (IdentComp(IdentBDFPropertyFontAscent))
state = Number(fontAscent);
else if (IdentComp(IdentBDFPropertyFontDescent))
state = Number(fontDescent);
else if (IdentComp(IdentBDFPropertyMaxNormalCharWidth) || IdentComp(IdentMaxNormalCharWidth))
state = Number(maxNormalCharWidth);
else if (IdentComp(IdentBDFPropertyMaxConsecutiveFillChars) || IdentComp(IdentMaxConsecutiveFillChars))
state = Number(maxConsecutiveFillChars);
iLexAnal->ReadNextLine(); // Skip to next line
}
}
if (state)
{
state = IdentComp(IdentBDFEndProperties);
if (!state)
ErrorIdentifierExpected(IdentBDFEndProperties);
}
}
}
else
{
Error("Identifier expected");
state = efalse;
}
}
//
// Check that maximum size of bitmap glyph not exceeded.
//
if (widthBoundingBox>KMaxBitmapWidth || widthBoundingBox>KMaxBitmapWidth)
{
state = efalse;
cout << "Error: A font bounding box dimension exceeds maximum permitted in EPOC32";
}
// Check that have everthing that we need and set some bitmap properties.
iFontBitmap->iMaxCharWidthInPixels = (chardim) widthBoundingBox;
if (fontAscent + fontDescent)
{
iFontBitmap->iCellHeightInPixels =( chardim) (fontAscent+fontDescent);
iFontBitmap->iAscentInPixels = (chardim) (fontAscent);
}
else
{ // Old file so use the old calculation
iFontBitmap->iCellHeightInPixels =( chardim) heightBoundingBox;
iFontBitmap->iAscentInPixels = (chardim) (heightBoundingBox + boundingBoxYOffset);
}
iFontBitmap->iPosture = (boolean) posture;
iFontBitmap->iStrokeWeight =( boolean) strokeWeight;
iFontBitmap->iLabel = fontLabel;
iDefaultXMoveInPixels = defaultXMoveInPixels;
iDefaultYMoveInPixels = defaultYMoveInPixels;
if (fontUid != KNullUid)
iFontBitmap->iUid = fontUid;
else
{
cerr << "Warning: No font bitmap UID specified in properties\n";
iFontBitmap->iUid = rand();
}
if (maxNormalCharWidth != KUndefinedInteger)
iFontBitmap->iMaxNormalCharWidthInPixels = (chardim) maxNormalCharWidth;
else
{
cerr << "Warning: No Maximum Normal Character Width specified in properties\n";
iFontBitmap->iMaxNormalCharWidthInPixels = iFontBitmap->iMaxCharWidthInPixels;
}
if (state)
state = Number(numberChars);
if (state)
state = NewLine();
else
return state;
// store position of Lex here and then set it back for the reading of the BDF chars!
int saveLineNo = iLexAnal->iLineNo;
ParseMetricsFromBDF(numberChars, maxConsecutiveFillChars);
// now reset the lexical
state = Open(iFileName.Text());
do
{
iLexAnal->Read();
}
while(saveLineNo > iLexAnal->iLineNo);
ReadBDFChars(numberChars, maxConsecutiveFillChars);
if (state)
{
state = IdentComp(IdentBDFEndFontBitmap);
if (!state)
Error("ENDFONT identifier expected");
}
int globalMove = KUndefinedInteger;
int monospaced= etrue;
if (state)
{
for (int i = 0; i <iFontBitmap->iCodeSectionList.Size(); i++)
{
const int end = iFontBitmap->iCharacterMetrics->iCharacterMetricsList.Size();
for (int j = 0; j< end; j++)
{
int move = iFontBitmap->iCharacterMetrics->iCharacterMetricsList[j]->Metric()->iMoveInPixels;
if (globalMove == KUndefinedInteger)
globalMove = move;
if (move > iFontBitmap->iMaxCharWidthInPixels)
iFontBitmap->iMaxCharWidthInPixels = (chardim) move;
if (globalMove!= move)
monospaced = efalse;
}
}
}
if (monospaced)
iFontBitmap->iIsProportional = efalse;
else
iFontBitmap->iIsProportional = etrue;
if (state)
{
iFontStore.AddFontBitmap(iFontBitmap);
cout << "FONT read\n";
}
else
delete iFontBitmap;
return state;
}
boolean FontReader::ReadTypeface()
{
boolean state = etrue;
iTypeface = new FntTypeface;
String label;
int num;
state = IdentCopy(iTypeface->iLabel);
if (state)
state = NewLine();
while (!IdentComp(IdentEndTypeface) && !_EOF() && state)
{
if (IdentComp(IdentName))
{
state = StringCopy(iTypeface->iName);
while ((iLex->iType != ELexNL) && !_EOF() && state)
{
if (IdentComp(IdentTypefaceProportional))
iTypeface->iFlags = (boolean) (iTypeface->iFlags | Proportional);
else if (IdentComp(IdentSerif))
iTypeface->iFlags = (boolean) (iTypeface->iFlags | Serif);
else if (IdentComp(IdentSymbol))
iTypeface->iFlags = (boolean) (iTypeface->iFlags | Symbol);
else
{
Error("Typeface identifier or newline expected");
state = efalse;
}
}
}
else if (IdentComp(IdentFontBitmaps))
{
state = NewLine();
while (!IdentComp(IdentEndFontBitmaps) && !_EOF() && state)
{
TypefaceFontBitmap* typefacefontbitmap = NULL;
if (iLex->iType == ELexIdent)
{
state = IdentCopy(label);
FontBitmap* fontbitmap = (FontBitmap*) iFontStore.FindFontBitmap(label);
if (fontbitmap)
{
typefacefontbitmap = new TypefaceFontBitmap(fontbitmap);
state = etrue;
}
else
{
Error("Fontbitmap not found");
state = efalse;
}
}
else
{
uid fontbitmapuid;
state = Number(fontbitmapuid);
if (state)
typefacefontbitmap = new TypefaceFontBitmap(fontbitmapuid);
}
if (state)
{
while ((iLex->iType != ELexNL) && !_EOF() && state)
{
if (IdentComp(IdentWidthFactor))
{
state = Number(num);
typefacefontbitmap->iWidthFactor = (char) num;
}
else if (IdentComp(IdentHeightFactor))
{
state = Number(num);
typefacefontbitmap->iHeightFactor =( char) num;
}
else
{
Error("Typefacefontbitmap identifier or newline expected");
state = efalse;
}
}
if (state)
iTypeface->iTypefaceFontBitmapList.Add(typefacefontbitmap);
else
delete typefacefontbitmap;
}
if (state)
state = NewLine();
}
}
else
{
Error("Typeface identifier expected");
state = efalse;
}
if (state)
state = NewLine();
}
if (state)
{
iFontStore.AddTypeface(iTypeface);
cout << "Typeface read\n";
}
else
delete iTypeface;
return state;
}
boolean FontReader::ReadFontStoreFile()
{
boolean state = etrue;
int num;
if (iFontStoreFile)
{
state = efalse;
Error("Fontstorefile already read");
}
else
{
iFontStoreFile = new FontStoreFile;
String label;
Record* typeface;
state = NewLine();
while (!IdentComp(IdentEndFontStoreFile) && !_EOF() && state)
{
if (IdentComp(IdentCollectionUid))
{
state = Number(iFontStoreFile->iCollectionUid);
}
else if (IdentComp(IdentKPixelAspectRatio))
{
state = Number(num);
if (state)
iFontStoreFile->iKPixelAspectRatio = num;
}
else if (IdentComp(IdentCopyrightInfo))
{
state = NewLine();
while (!IdentComp(IdentEndCopyrightInfo) && !_EOF() && state)
{
String* string = new String;
state = StringCopy(*string);
if (state)
iFontStoreFile->iCopyrightInfo.Add(string);
else
delete string;
state = NewLine();
}
}
else if (IdentComp(IdentTypefaces))
{
state = NewLine();
while (!IdentComp(IdentEndTypefaces) && !_EOF() && state)
{
state =IdentCopy(label);
if (state)
{
typeface = iFontStore.FindTypeface(label);
if (typeface)
{
iFontStoreFile->AddTypeface((FntTypeface*) typeface);
}
else
{
Error("Typeface not found");
state = efalse;
}
}
if (state)
state = NewLine();
}
}
else if (IdentComp(IdentExtraFontBitmaps))
{
state = NewLine();
while (!IdentComp(IdentEndExtraFontBitmaps) && !_EOF() && state)
{
state = IdentCopy(label);
FontBitmap* fontbitmap = (FontBitmap*) iFontStore.FindFontBitmap(label);
if (fontbitmap)
{
iFontStoreFile->AddFontBitmap((FontBitmap*) fontbitmap);
}
else
{
Error("Fontbitmap not found");
state = efalse;
}
if (state)
state = NewLine();
}
}
else
{
Error("Fontstorefile identifier expected");
state = efalse;
}
if (state)
state = NewLine();
}
if (state)
{
iFontStore.AddFontStoreFile(iFontStoreFile);
cout << "Fontstorefile read\n";
}
else
delete iFontStoreFile;
}
return state;
}
int FontReader::Store(const String& aFilename)
{
boolean state = etrue;
if (!iFontStoreFile)
{
state = efalse;
Error("No fontstore file record");
}
else
state = iFontStore.Store(aFilename);
return state;
}
boolean FontReader::CharLine(String& aCharLine)
{
boolean state = etrue;
while (state && (iLex->iType != ELexNL))
{
char ch;
state = Operator(ch);
if (state)
{
if ((ch == '.') || (ch == '*'))
aCharLine += ch;
else
{
state = efalse;
Error("Operator '.' or '*' expected");
}
}
}
return state;
}
void FontReader::ErrorIdentifierExpected(const String& aIdentifier)
{
cerr << "Error: Identifier Expected " << aIdentifier;
iLexAnal->Report();
while ((iLex->iType != ELexNL) && (iLex->iType != ELexEOF))
iLexAnal->Read();
}
boolean FontReader::CompareBitmapLines(int aLine1, int aLine2)
{
int column = 0;
boolean identical = etrue;
for (column=0; column < iBitmapWidth; column++)
{
if (iBitArray[column][aLine1] != iBitArray[column][aLine2])
{
identical = efalse;
break;
}
}
return identical;
}
boolean FontReader::BitmapLineEmpty(int aLine)
{
int column = 0;
boolean empty = etrue;
for (column = 0; column < iBitmapWidth; column++)
{
if (iBitArray[column][aLine] != 0)
{
empty = efalse;
break;
}
}
return empty;
}
boolean FontReader::BitmapColumnEmpty(int aColumn)
{
int line = 0;
boolean empty = etrue;
for (line = 0; line < iBitmapHeight; line++)
{
if (iBitArray[aColumn][line] != 0)
{
empty = efalse;
break;
}
}
return empty;
}
void FontReader::WriteFillCharacters(int aNumberConsecutive)
{
for (int counter = 0; counter < aNumberConsecutive; counter++)
{
BitmapOffset* offset = new BitmapOffset(KFillCharacterOffset);
iCodeSection->iCharacters.iBitmapOffsetList.Add(offset);
}
}
boolean FontReader::ParseMetricsFromBDF(int aNumberCharsInFile, int aMaxConsecutiveFillChars)
{
boolean state = etrue;
int character = 0;
int numberCharactersRead;
int lastCharacter = KMarkFirstCharacterInTypeface;
int reportRate = ((aNumberCharsInFile - 1) / KReportRateFrequencyInPercent) + 1;
CharacterMetrics* metric = 0;
cout << "Analysing character metrics...\n";
cout.flush();
for (numberCharactersRead = 0; numberCharactersRead < aNumberCharsInFile && !_EOF() && state; numberCharactersRead++)
{
state = IdentComp(IdentBDFCharLabel);
if (!state)
ErrorIdentifierExpected(IdentBDFCharLabel);
if (state)
iLexAnal->ReadNextLine(); // Skip to next line
if (IdentComp(IdentBDFChar))
{
state = Number(character);
}
else
{
state = efalse;
ErrorIdentifierExpected(IdentBDFChar);
}
if (character < KLowestPermittedCharacterEncoding || character > KHighestPermittedCharacterEncoding)
{
while (!IdentComp(IdentBDFEndChar) && !_EOF() && state)
// Skip fill character.
{
iLexAnal->ReadNextLine(); // Skip to next line
}
iLexAnal->ReadNextLine();
continue;
}
if (character<lastCharacter)
{
Error("CodeSection out of sequence");
state = efalse;
}
if ((character > lastCharacter + 1)
&& (character <= lastCharacter + 1 + aMaxConsecutiveFillChars) && state)
{
// Would result in fill characters being used if not at end of code section!
metric = new CharacterMetrics;
metric->iLeftAdjustInPixels = (chardim)0;
metric->iMoveInPixels = (chardim)0;
metric->iRightAdjustInPixels = (chardim)0;
metric->iAscentInPixels = (chardim)0;
metric->iHeightInPixels = (chardim)0;
iFontBitmap->iCharacterMetrics->AddOrIncrementMetric(*metric);
delete metric;
metric = 0;
}
if (state)
{
metric = new CharacterMetrics;
state = ReadMetricFromBDFCharacter(metric);
iFontBitmap->iCharacterMetrics->AddOrIncrementMetric(*metric);
delete metric;
metric = 0;
}
lastCharacter = character;
if(numberCharactersRead == ((numberCharactersRead / reportRate) * reportRate))
{
cout << "Done " << (numberCharactersRead * 100 / aNumberCharsInFile) << "% \n";
cout.flush();
}
}
if (state)
{
iFontBitmap->iCharacterMetrics->SortMetricsByFrequency();
}
return state;
}