diff -r 000000000000 -r 5d03bc08d59c graphicstools/bitmapfonttools/src/FNTREADR.CPP --- /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 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 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 + 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; + }