--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstools/bitmapfonttools/src/FNTREADR.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1013 @@
+/*
+* 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;
+ }