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