graphicstools/bitmapfonttools/src/FNTREADR.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * Header FNTREADR.CPP
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "FNTREADR.H"
       
    21 
       
    22 const int KMarkFirstCharacterInTypeface = -1;
       
    23 const int KBytesAddedForMetricIndex = 2;
       
    24 const int KBytesForIndexForFillCharacters = 2;
       
    25 const int KReportRateFrequencyInPercent = 10;
       
    26 
       
    27 // class CroppedValues
       
    28 
       
    29 class CroppedValues
       
    30 	{
       
    31 public:
       
    32 	CroppedValues();
       
    33 public:
       
    34 	int iTopCrop;
       
    35 	int iBottomCrop;
       
    36 	int iLeftCrop;
       
    37 	int iRightCrop;
       
    38 	};
       
    39 
       
    40 CroppedValues::CroppedValues()
       
    41  :	iTopCrop(0), iBottomCrop(0), iLeftCrop(0), iRightCrop(0)
       
    42 	{}
       
    43 
       
    44 // class FontReader
       
    45 
       
    46 FontReader::FontReader()
       
    47  :	Reader(),
       
    48 	iFontStore(),
       
    49 	iFontStoreFile(NULL),
       
    50 	iCharacterMetrics(NULL),
       
    51 	iCodeSection(NULL),
       
    52 	iFontBitmap(NULL),
       
    53 	iTypeface(NULL),
       
    54 	iReadFileFormat(ESymbianGDFFormat),
       
    55 	iBitmapWidth(0),
       
    56 	iBitmapHeight(0),
       
    57 	iDefaultXMoveInPixels(KUndefinedInteger),
       
    58 	iDefaultYMoveInPixels(KUndefinedInteger)
       
    59 	{
       
    60 	}
       
    61 
       
    62 boolean FontReader::Read(const String& aFilename)
       
    63 	{
       
    64 	iFileName = aFilename;
       
    65 	boolean state = Open(iFileName.Text());
       
    66 
       
    67 	while (!_EOF() && state)
       
    68 		{
       
    69 		if (IdentComp(IdentBDFFileHeader) || IdentComp(IdentBDFComment))
       
    70 			{
       
    71 			state = ReadBDFFontBitmap();
       
    72 			iReadFileFormat = EBDFFormat;
       
    73 			}
       
    74 		else if (IdentComp(IdentTypeface))
       
    75 			state = ReadTypeface();
       
    76 		else if (IdentComp(IdentFontStoreFile))
       
    77 			state = ReadFontStoreFile();
       
    78 		else
       
    79 			{
       
    80 			Error("Resource identifier expected");
       
    81 			state = efalse;
       
    82 			}
       
    83 		if (state)
       
    84 			state = NewLine();
       
    85 		}
       
    86 	return state;
       
    87 	}
       
    88 
       
    89 boolean FontReader::ReadMetricFromBDFCharacter(CharacterMetrics* aCharacterMetrics, CroppedValues* aCropped=  NULL)
       
    90 	{
       
    91 	int xMoveInPixels = 0;
       
    92 	int yMoveInPixels = 0;
       
    93 	int bitmapXOffset = 0;
       
    94 	int bitmapYOffset = 0;
       
    95 
       
    96 	boolean state = true;
       
    97 
       
    98 	if (iDefaultXMoveInPixels != KUndefinedInteger)
       
    99 		xMoveInPixels = iDefaultXMoveInPixels;
       
   100 	if (iDefaultYMoveInPixels != KUndefinedInteger)
       
   101 		yMoveInPixels = iDefaultYMoveInPixels;
       
   102 	
       
   103 	while (!IdentComp(IdentBDFEndChar) && !_EOF() && state)
       
   104 		{
       
   105 		iLexAnal->ReadNextLine(); // Skip to next line
       
   106 		if (iLex->iType == ELexIdent)
       
   107 			{
       
   108 			if (IdentComp(IdentBDFCursorMove))
       
   109 				{
       
   110 				state = Number(xMoveInPixels);
       
   111 				if (state)
       
   112 					state = Number(yMoveInPixels);
       
   113 				}
       
   114 			else if (IdentComp(IdentBDFBitmapSizeAndDisplacement))
       
   115 				{
       
   116 				state = Number(iBitmapWidth);
       
   117 				if (state)
       
   118 					{
       
   119 					state = Number(iBitmapHeight);
       
   120 					state = Number(bitmapXOffset);
       
   121 					state = Number(bitmapYOffset);
       
   122 					}
       
   123 				}
       
   124 			else if (IdentComp(IdentBDFStartBitmap) && state)
       
   125 				{
       
   126 				int line = 0;
       
   127 				for (line = 0; line < iBitmapHeight; line++)
       
   128 					{
       
   129 					iLexAnal->ReadNextLine();	// Skip to next line
       
   130 					int bits = 0;
       
   131 					int bitOffset = 0;
       
   132 					int byteValue = 0;
       
   133 					for (bits = 0; bits < iBitmapWidth; bits++)
       
   134 						{
       
   135 						if (bitOffset == 0)
       
   136 							{
       
   137 							Lexical lex;
       
   138 							strncpy(lex.iText, &iLexAnal->iLine[bits >> 2], 2);
       
   139 							lex.iText[2] = '\0';
       
   140 							byteValue = lex.CovertStringToHex();
       
   141 							bitOffset = 8;
       
   142 							}
       
   143 
       
   144 						bitOffset--;
       
   145 						int bitValue = (byteValue >> bitOffset) & 1;
       
   146 						iBitArray[bits][line] = bitValue;
       
   147 						}
       
   148 					}
       
   149 				}
       
   150 			}
       
   151 		else
       
   152 			{
       
   153 			Error("Fontbitmap identifier expected");
       
   154 			state = efalse;
       
   155 			}
       
   156 		}
       
   157 
       
   158 	if (state)
       
   159 		state = NewLine();
       
   160 //
       
   161 // Make sure that bitmap is fully cropped
       
   162 //
       
   163 	int leftCrop = 0;
       
   164 	int rightCrop = 0;
       
   165 	int topCrop = 0;
       
   166 	int bottomCrop = 0;
       
   167 	
       
   168 	int line = 0;
       
   169 	while (BitmapLineEmpty(line) && line < iBitmapHeight)
       
   170 		{
       
   171 		topCrop++;;
       
   172 		line++;
       
   173 		}
       
   174 	line = iBitmapHeight - 1;
       
   175 	while (BitmapLineEmpty(line) && line > topCrop)
       
   176 		{
       
   177 		bottomCrop++;
       
   178 		line--;
       
   179 		}
       
   180 	int column = iBitmapWidth - 1;
       
   181 	while (BitmapColumnEmpty(column) && column >= 0)
       
   182 		{
       
   183 		rightCrop++;
       
   184 		column--;
       
   185 		}
       
   186 	column = 0;
       
   187 	while (BitmapColumnEmpty(column) && column < iBitmapWidth - 1 - rightCrop)
       
   188 		{
       
   189 		leftCrop++;
       
   190 		column++;
       
   191 		}
       
   192 
       
   193 	int croppedBitmapHeight = iBitmapHeight - topCrop - bottomCrop;
       
   194 	int croppedBitmapWidth = iBitmapWidth - leftCrop - rightCrop;
       
   195 	int croppedLeftAdjust = bitmapXOffset + leftCrop;
       
   196 	int croppedRightAdjust = (xMoveInPixels - croppedLeftAdjust - croppedBitmapWidth);
       
   197 	int croppedAscent = croppedBitmapHeight + bitmapYOffset + bottomCrop;
       
   198 
       
   199 	if(state)
       
   200 		{
       
   201 		aCharacterMetrics->iAscentInPixels = (chardim) croppedAscent;
       
   202 		aCharacterMetrics->iHeightInPixels = (chardim) croppedBitmapHeight;
       
   203 		aCharacterMetrics->iLeftAdjustInPixels = (chardim) croppedLeftAdjust;
       
   204 		aCharacterMetrics->iMoveInPixels = (chardim) xMoveInPixels;
       
   205 		aCharacterMetrics->iRightAdjustInPixels = (chardim) croppedRightAdjust;
       
   206 		if (aCropped)
       
   207 			{
       
   208 			aCropped->iBottomCrop = bottomCrop;
       
   209 			aCropped->iLeftCrop = leftCrop;
       
   210 			aCropped->iRightCrop = rightCrop;
       
   211 			aCropped->iTopCrop = topCrop;
       
   212 			}
       
   213 		}
       
   214 	return state;
       
   215 	}
       
   216 
       
   217 boolean FontReader::ReadBDFCharacter(int /*aCode*/)
       
   218 	{
       
   219 	boolean state = etrue;
       
   220 	ObjectList<String*> character;
       
   221 	iCharacterMetrics = new CharacterMetrics;
       
   222 	CroppedValues* croppedValues = new CroppedValues;
       
   223 
       
   224 	state = ReadMetricFromBDFCharacter(iCharacterMetrics, croppedValues);
       
   225 
       
   226 	if (state)
       
   227 		{
       
   228 		BitmapOffset* offset = new BitmapOffset((uint16)iCodeSection->iCharactersBitmap.iByteList.Length());
       
   229 		
       
   230 		
       
   231 		iCodeSection->iCharactersBitmap.iByteList.NewByte();
       
   232 		iCodeSection->iCharacters.iBitmapOffsetList.Add(offset);
       
   233 
       
   234 		int index = iFontBitmap->iCharacterMetrics->Index(*iCharacterMetrics);
       
   235 		if (index == -1)
       
   236 			{
       
   237 			Error("Internal Compiler Error");
       
   238 			state = 0;
       
   239 			}
       
   240 		delete iCharacterMetrics;
       
   241 
       
   242 		if (state)
       
   243 			{
       
   244 			iCodeSection->iCharactersBitmap.AddIndex(index);
       
   245 
       
   246 			int line = croppedValues->iTopCrop;
       
   247 			boolean repeatLines;
       
   248 			int countLines = 0;
       
   249 			const int bottomCrop = croppedValues->iBottomCrop;
       
   250 			while (line < (iBitmapHeight - bottomCrop))
       
   251 				{
       
   252 				if ((line + 1) == (iBitmapHeight - bottomCrop))
       
   253 					{
       
   254 					repeatLines = efalse;
       
   255 					countLines = 1;
       
   256 					}
       
   257 				else if (!CompareBitmapLines(line, line + 1))
       
   258 					{
       
   259 					repeatLines = efalse;
       
   260 					for (countLines = 2; ((line + countLines) < (iBitmapHeight - bottomCrop)) && (countLines < KMaxNumberRepeatedLines); countLines++)
       
   261 						{
       
   262 						if (CompareBitmapLines(line + countLines - 1, line + countLines))
       
   263 							break;
       
   264 						}
       
   265 					}
       
   266 				else
       
   267 					{
       
   268 					repeatLines = etrue;
       
   269 					for (countLines = 2; ((line + countLines) < (iBitmapHeight - bottomCrop)) && (countLines < KMaxNumberRepeatedLines); countLines++)
       
   270 						{
       
   271 						if (!CompareBitmapLines(line, line + countLines))
       
   272 							break;
       
   273 						}
       
   274 					}
       
   275 				char bit;
       
   276 				if (repeatLines)
       
   277 					bit = 0;
       
   278 				else
       
   279 					bit = 1;
       
   280 				iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
       
   281 				for (int digit = 0; digit < 4; digit++)
       
   282 					{
       
   283 					bit = char(countLines >> digit);
       
   284 					iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
       
   285 					}
       
   286 				int lineFromTop;
       
   287 				for (lineFromTop = line; lineFromTop < (line + countLines); lineFromTop++)
       
   288 					{
       
   289 					if ((!repeatLines) || (lineFromTop == line))
       
   290 						{
       
   291 						int column;
       
   292 						for (column = croppedValues->iLeftCrop;
       
   293 							column < iBitmapWidth - croppedValues->iRightCrop; column++)
       
   294 							{
       
   295 							if (iBitArray[column][lineFromTop] == 1)
       
   296 								bit = 1;
       
   297 							else
       
   298 								bit = 0;
       
   299 							iCodeSection->iCharactersBitmap.iByteList.AddBit(bit);
       
   300 							}
       
   301 						}
       
   302 					}
       
   303 				line = line+countLines;
       
   304 				}
       
   305 			}
       
   306 		}
       
   307 	delete croppedValues;
       
   308 	return state;
       
   309 	}
       
   310 
       
   311 boolean FontReader::ReadBDFChars(const int aNumberOfGlyphsInFile, const int aMaxConsecutiveFillChars)
       
   312 	{
       
   313 	boolean state = etrue;
       
   314 	boolean newCodeSection = etrue;
       
   315 	int currentEncodingValue = 0; // each glyph has an unique encoding value
       
   316 	int lastEncodingValue = KMarkFirstCharacterInTypeface;
       
   317 	const int maxCharacterBitmapsize =
       
   318 		((KMaxBitmapWidth * KMaxBitmapHeight) / KNumberOfBitsInByte) + KBytesAddedForMetricIndex + KBytesForIndexForFillCharacters;
       
   319 
       
   320 	iCodeSection = NULL;
       
   321 	for (int numberGlyphsRead = 0; state && numberGlyphsRead < aNumberOfGlyphsInFile && !_EOF(); numberGlyphsRead++)
       
   322 		{
       
   323 		if (state && iCodeSection && iCodeSection->iCharactersBitmap.iByteList.Length() + maxCharacterBitmapsize >= KMaxSizeCodeSectionBitmap)
       
   324 			{
       
   325 			newCodeSection = etrue;
       
   326 			}
       
   327 
       
   328 		state = IdentComp(IdentBDFCharLabel);
       
   329 		if (!state)
       
   330 			ErrorIdentifierExpected(IdentBDFCharLabel);
       
   331 		if (state)
       
   332 			iLexAnal->ReadNextLine(); // Skip to next line
       
   333 
       
   334  		if (IdentComp(IdentBDFChar))
       
   335 			{
       
   336 			state = Number(currentEncodingValue);
       
   337 			}
       
   338 		else
       
   339 			{
       
   340 			state = efalse;
       
   341 			ErrorIdentifierExpected(IdentBDFChar);
       
   342 			}
       
   343 
       
   344 		if (KLowestPermittedCharacterEncoding > currentEncodingValue ||
       
   345 			KHighestPermittedCharacterEncoding < currentEncodingValue)
       
   346 			{
       
   347 			while (!IdentComp(IdentBDFEndChar) && !_EOF() && state) 
       
   348 				// Skip fill character.
       
   349 				{
       
   350 				iLexAnal->ReadNextLine(); // Skip to next line
       
   351 				}
       
   352 			iLexAnal->ReadNextLine();
       
   353 			continue;
       
   354 			}
       
   355 
       
   356 		if (!iCodeSection || state && (currentEncodingValue > (lastEncodingValue + 1 + aMaxConsecutiveFillChars)))
       
   357 			{
       
   358 			// First character skip to new code section
       
   359 			newCodeSection = etrue;
       
   360 			}
       
   361 		else if (state && !newCodeSection && (currentEncodingValue > lastEncodingValue + 1))
       
   362 			{
       
   363 			WriteFillCharacters(currentEncodingValue - (lastEncodingValue + 1));
       
   364 			}
       
   365 		else if (state && currentEncodingValue <= lastEncodingValue)
       
   366 			{
       
   367 			Error("CodeSection out of sequence");
       
   368 			state = efalse;
       
   369 			}
       
   370 
       
   371 		if (state && newCodeSection)
       
   372 			{
       
   373 			if (iCodeSection)
       
   374 				{
       
   375 				iCodeSection->iEnd = (uint16) lastEncodingValue;
       
   376 				iFontBitmap->iCodeSectionList.Add(iCodeSection);
       
   377 				PrintoutCodeSection(iCodeSection);
       
   378 				}
       
   379 			iCodeSection = new BitmapCodeSection;
       
   380 			iCodeSection->iStart = (uint16) currentEncodingValue;
       
   381 			}
       
   382 
       
   383 		if (state)
       
   384 			state = ReadBDFCharacter(currentEncodingValue);
       
   385 
       
   386 		newCodeSection = efalse;
       
   387 		lastEncodingValue = currentEncodingValue;
       
   388 		}
       
   389 
       
   390 	if (state)
       
   391 		{
       
   392 		iCodeSection->iEnd = (uint16) lastEncodingValue;
       
   393 		iFontBitmap->iCodeSectionList.Add(iCodeSection);
       
   394 		PrintoutCodeSection(iCodeSection);
       
   395 		}
       
   396 
       
   397 	return state;
       
   398 	}
       
   399 
       
   400 void FontReader::PrintoutCodeSection(const BitmapCodeSection* aCodeSection) const
       
   401 	{
       
   402 	cout << hex << "Codesection 0x" << aCodeSection->iStart << ": 0x" << aCodeSection->iEnd << " read" << endl;
       
   403 	cout.flush();
       
   404 	}
       
   405 
       
   406 boolean FontReader::ReadBDFFontBitmap()
       
   407 	{
       
   408 	boolean state = etrue;
       
   409 	String label;
       
   410 	iFontBitmap = new FontBitmap;
       
   411 	int pointSize;
       
   412 	int xresolution; // in dots per inch
       
   413 	int yresolution; // in dots per inch
       
   414 	int widthBoundingBox = 0; // In pixels
       
   415 	int heightBoundingBox = 0; // in pixels
       
   416 	int boundingBoxXOffset = 0; // From origin (cursor position at baseline)
       
   417 	int boundingBoxYOffset = 0;	// From origin (cursor position at baseline)
       
   418 	int numberChars = 0;
       
   419 	String fontLabel;
       
   420 	int maxNormalCharWidth = KUndefinedInteger;
       
   421 	uid fontUid = KNullUid;
       
   422 	int posture = PostureUpright;
       
   423 	int strokeWeight = StrokeWeightNormal;
       
   424 	int defaultXMoveInPixels = KUndefinedInteger;
       
   425 	int defaultYMoveInPixels = KUndefinedInteger;
       
   426 	int writingDirection = 0;
       
   427 	int maxConsecutiveFillChars = 0;	// Max permitted "fill" characters with zero size to prevent
       
   428 										// break between code sections.
       
   429 	int fontAscent = 0;
       
   430 	int fontDescent = 0;
       
   431 
       
   432 	while (!IdentComp(IdentBDFNumChars) && !_EOF() && state)
       
   433 		{
       
   434 		iLexAnal->ReadNextLine(); // Skip to next line
       
   435 		if (iLex->iType == ELexIdent)
       
   436 			{
       
   437 			if (IdentComp(IdentBDFFontBitmap))
       
   438 				{
       
   439 				state = IdentCopy(fontLabel);
       
   440 				}
       
   441 			if (IdentComp(IdentBDFPointSize))
       
   442 				{
       
   443 				state = Number(pointSize);
       
   444 				if (state)
       
   445 					state = Number(xresolution);
       
   446 				if (state)
       
   447 					state = Number(yresolution);
       
   448 				}
       
   449 			else if (IdentComp(IdentBDFFontDesignBox))
       
   450 				{
       
   451 				state = Number(widthBoundingBox);
       
   452 				if (state)
       
   453 					state = Number(heightBoundingBox);
       
   454 				if (state)
       
   455 					state = Number(boundingBoxXOffset);
       
   456 				if (state)
       
   457 					state = Number(boundingBoxYOffset);
       
   458 				}
       
   459 			else if (IdentComp(IdentBDFWritingDirection))
       
   460 				{
       
   461 				Number(writingDirection);
       
   462 				if (writingDirection != 0)
       
   463 					cout << "Warning: Only left to right writing direction supported by EPOC32";
       
   464 				}
       
   465 			else if (IdentComp(IdentBDFCursorMove))
       
   466 				{
       
   467 				state = Number(defaultXMoveInPixels);
       
   468 				if (state)
       
   469 					state = Number(defaultYMoveInPixels);
       
   470 				}
       
   471 			else if (IdentComp(IdentBDFStartProperties))	// Adding additional properties
       
   472 				{
       
   473 				int numberOfProperties;
       
   474 				state = Number(numberOfProperties);
       
   475 				if (state)
       
   476 					state = NewLine();
       
   477 				{for (int properties = 0; properties < numberOfProperties && !_EOF() && state; properties++)
       
   478 					{
       
   479 					if (IdentComp(IdentBDFPropertyUid) || IdentComp(IdentUid))
       
   480 						state = Number(fontUid);
       
   481 					else if (IdentComp(IdentBDFPropertyBold) || IdentComp(IdentBold))
       
   482 						state = Number(strokeWeight);
       
   483 					else if (IdentComp(IdentBDFPropertyItalic) || IdentComp(IdentItalic))
       
   484 						state = Number(posture);
       
   485 					else if (IdentComp(IdentBDFPropertyFontAscent))
       
   486 						state = Number(fontAscent);
       
   487 					else if (IdentComp(IdentBDFPropertyFontDescent))
       
   488 						state = Number(fontDescent);
       
   489 					else if	(IdentComp(IdentBDFPropertyMaxNormalCharWidth) || IdentComp(IdentMaxNormalCharWidth))
       
   490 						state = Number(maxNormalCharWidth);
       
   491 					else if (IdentComp(IdentBDFPropertyMaxConsecutiveFillChars) || IdentComp(IdentMaxConsecutiveFillChars))
       
   492 						state = Number(maxConsecutiveFillChars);
       
   493 
       
   494 					iLexAnal->ReadNextLine();	// Skip to next line
       
   495 					}
       
   496 				}
       
   497 				if (state)
       
   498 					{
       
   499 					state = IdentComp(IdentBDFEndProperties);
       
   500 					if (!state)
       
   501 						ErrorIdentifierExpected(IdentBDFEndProperties);
       
   502 					}
       
   503 				}
       
   504 
       
   505 			}
       
   506 		else
       
   507 			{
       
   508 			Error("Identifier expected");
       
   509 			state = efalse;
       
   510 			}
       
   511 		}
       
   512 //
       
   513 // Check that maximum size of bitmap glyph not exceeded.
       
   514 //
       
   515 	if (widthBoundingBox>KMaxBitmapWidth || widthBoundingBox>KMaxBitmapWidth)
       
   516 		{
       
   517 		state = efalse;
       
   518 		cout << "Error: A font bounding box dimension exceeds maximum permitted in EPOC32";
       
   519 		}
       
   520 
       
   521 // Check that have everthing that we need and set some bitmap properties.
       
   522 
       
   523 	iFontBitmap->iMaxCharWidthInPixels = (chardim) widthBoundingBox;
       
   524 	if (fontAscent + fontDescent)
       
   525 		{
       
   526 		iFontBitmap->iCellHeightInPixels =( chardim) (fontAscent+fontDescent);
       
   527 		iFontBitmap->iAscentInPixels = (chardim) (fontAscent);
       
   528 		}
       
   529 	else
       
   530 		{	// Old file so use the old calculation
       
   531 		iFontBitmap->iCellHeightInPixels =( chardim) heightBoundingBox;
       
   532 		iFontBitmap->iAscentInPixels = (chardim) (heightBoundingBox + boundingBoxYOffset);
       
   533 		}
       
   534 	iFontBitmap->iPosture = (boolean) posture;
       
   535 	iFontBitmap->iStrokeWeight =( boolean) strokeWeight;
       
   536 	iFontBitmap->iLabel = fontLabel;
       
   537 
       
   538 	iDefaultXMoveInPixels = defaultXMoveInPixels;
       
   539 	iDefaultYMoveInPixels = defaultYMoveInPixels;
       
   540 
       
   541 	if (fontUid != KNullUid)
       
   542 		iFontBitmap->iUid = fontUid;
       
   543 	else
       
   544 		{
       
   545 		cerr << "Warning: No font bitmap UID specified in properties\n";
       
   546 		iFontBitmap->iUid = rand();
       
   547 		}
       
   548 
       
   549 	if (maxNormalCharWidth != KUndefinedInteger)
       
   550 		iFontBitmap->iMaxNormalCharWidthInPixels = (chardim) maxNormalCharWidth;
       
   551 	else
       
   552 		{
       
   553 		cerr << "Warning: No Maximum Normal Character Width specified in properties\n";
       
   554 		iFontBitmap->iMaxNormalCharWidthInPixels = iFontBitmap->iMaxCharWidthInPixels;
       
   555 		}
       
   556 
       
   557 	if (state)
       
   558 		state = Number(numberChars);
       
   559 	if (state)
       
   560 		state = NewLine();
       
   561 	else
       
   562 		return state;
       
   563 
       
   564 	// store position of Lex here and then set it back for the reading of the BDF chars!
       
   565 	int saveLineNo = iLexAnal->iLineNo;
       
   566 	
       
   567 	ParseMetricsFromBDF(numberChars, maxConsecutiveFillChars);
       
   568 	// now reset the lexical
       
   569 	state = Open(iFileName.Text());
       
   570 	do
       
   571 		{
       
   572 		iLexAnal->Read();
       
   573 		}
       
   574 	while(saveLineNo > iLexAnal->iLineNo);
       
   575 
       
   576 	ReadBDFChars(numberChars, maxConsecutiveFillChars);
       
   577 
       
   578 	if (state)
       
   579 		{
       
   580 		state = IdentComp(IdentBDFEndFontBitmap);
       
   581 		if (!state)
       
   582 			Error("ENDFONT identifier expected");
       
   583 		}
       
   584 
       
   585 	int globalMove = KUndefinedInteger;
       
   586 	int monospaced= etrue;
       
   587 	if (state)
       
   588 		{
       
   589 		for (int i = 0; i <iFontBitmap->iCodeSectionList.Size(); i++)
       
   590 			{
       
   591 			const int end = iFontBitmap->iCharacterMetrics->iCharacterMetricsList.Size();
       
   592 			for (int j = 0; j< end; j++)
       
   593 				{
       
   594 				int move = iFontBitmap->iCharacterMetrics->iCharacterMetricsList[j]->Metric()->iMoveInPixels;
       
   595 				if (globalMove == KUndefinedInteger)
       
   596 					globalMove = move;
       
   597 				if (move > iFontBitmap->iMaxCharWidthInPixels)
       
   598 					iFontBitmap->iMaxCharWidthInPixels = (chardim) move;
       
   599 				if (globalMove!= move)
       
   600 					monospaced = efalse;
       
   601 				}
       
   602 			}
       
   603 		}
       
   604 	if (monospaced)
       
   605 		iFontBitmap->iIsProportional = efalse;
       
   606 	else
       
   607 		iFontBitmap->iIsProportional = etrue;
       
   608 
       
   609 	if (state)
       
   610 		{
       
   611 		iFontStore.AddFontBitmap(iFontBitmap);
       
   612 		cout << "FONT read\n";
       
   613 		}
       
   614 	else
       
   615 		delete iFontBitmap;
       
   616 	return state;
       
   617 	}
       
   618 
       
   619 boolean FontReader::ReadTypeface()
       
   620 	{
       
   621 	boolean state = etrue;
       
   622 	iTypeface = new FntTypeface;
       
   623 	String label;
       
   624 	int num;
       
   625 	state = IdentCopy(iTypeface->iLabel);
       
   626 	if (state)
       
   627 		state = NewLine();
       
   628 	while (!IdentComp(IdentEndTypeface) && !_EOF() && state)
       
   629 		{
       
   630 		if (IdentComp(IdentName))
       
   631 			{
       
   632 			state = StringCopy(iTypeface->iName);
       
   633 			while ((iLex->iType != ELexNL) && !_EOF() && state)
       
   634 				{
       
   635 				if (IdentComp(IdentTypefaceProportional))
       
   636 					iTypeface->iFlags = (boolean) (iTypeface->iFlags | Proportional);
       
   637 				else if (IdentComp(IdentSerif))
       
   638 					iTypeface->iFlags = (boolean) (iTypeface->iFlags | Serif);
       
   639 				else if (IdentComp(IdentSymbol))
       
   640 					iTypeface->iFlags = (boolean) (iTypeface->iFlags | Symbol);
       
   641 				else
       
   642 					{ 
       
   643 					Error("Typeface identifier or newline expected");
       
   644 					state = efalse;
       
   645 					}
       
   646 				}
       
   647 			}
       
   648 		else if (IdentComp(IdentFontBitmaps))
       
   649 			{
       
   650 			state = NewLine();
       
   651 			while (!IdentComp(IdentEndFontBitmaps) && !_EOF() && state)
       
   652 				{
       
   653 				TypefaceFontBitmap* typefacefontbitmap = NULL;
       
   654 				if (iLex->iType == ELexIdent)
       
   655 					{
       
   656 					state = IdentCopy(label);
       
   657 					FontBitmap* fontbitmap = (FontBitmap*) iFontStore.FindFontBitmap(label);
       
   658 					if (fontbitmap)
       
   659 						{
       
   660 						typefacefontbitmap = new TypefaceFontBitmap(fontbitmap);
       
   661 						state = etrue;
       
   662 						}
       
   663 					else
       
   664 						{
       
   665 						Error("Fontbitmap not found");
       
   666 						state = efalse;
       
   667 						}
       
   668 					}
       
   669 				else
       
   670 					{
       
   671 					uid fontbitmapuid;
       
   672 					state = Number(fontbitmapuid);
       
   673 					if (state)
       
   674 						typefacefontbitmap = new TypefaceFontBitmap(fontbitmapuid);
       
   675 					}
       
   676 				if (state)
       
   677 					{
       
   678 					while ((iLex->iType != ELexNL) && !_EOF() && state)
       
   679 						{
       
   680 						if (IdentComp(IdentWidthFactor))
       
   681 							{
       
   682 							state = Number(num);
       
   683 							typefacefontbitmap->iWidthFactor = (char) num;
       
   684 							}
       
   685 						else if (IdentComp(IdentHeightFactor))
       
   686 							{
       
   687 							state = Number(num);
       
   688 							typefacefontbitmap->iHeightFactor =( char) num;
       
   689 							}
       
   690 						else
       
   691 							{ 
       
   692 							Error("Typefacefontbitmap identifier or newline expected");
       
   693 							state = efalse;
       
   694 							}
       
   695 						}
       
   696 					if (state)
       
   697 						iTypeface->iTypefaceFontBitmapList.Add(typefacefontbitmap);
       
   698 					else
       
   699 						delete typefacefontbitmap;
       
   700 					}
       
   701 				if (state)
       
   702 					state = NewLine();
       
   703 				}
       
   704 			}
       
   705 		else
       
   706 			{
       
   707 			Error("Typeface identifier expected");
       
   708 			state = efalse;
       
   709 			}
       
   710 		if (state)
       
   711 			state = NewLine();
       
   712 		}
       
   713 	if (state)
       
   714 		{
       
   715 		iFontStore.AddTypeface(iTypeface);
       
   716 		cout << "Typeface read\n";
       
   717 		}	
       
   718 	else
       
   719 		delete iTypeface;
       
   720 	return state;
       
   721 	}
       
   722 
       
   723 boolean FontReader::ReadFontStoreFile()
       
   724 	{
       
   725 	boolean state = etrue;
       
   726 	int num;
       
   727 	if (iFontStoreFile)
       
   728 		{
       
   729 		state = efalse;
       
   730 		Error("Fontstorefile already read");
       
   731 		}
       
   732 	else
       
   733 		{
       
   734 		iFontStoreFile = new FontStoreFile;
       
   735 		String label;
       
   736 		Record* typeface;
       
   737 		state = NewLine();
       
   738 		while (!IdentComp(IdentEndFontStoreFile) && !_EOF() && state)
       
   739 			{
       
   740 			if (IdentComp(IdentCollectionUid))
       
   741 				{
       
   742 				state = Number(iFontStoreFile->iCollectionUid);
       
   743 				}
       
   744 			else if (IdentComp(IdentKPixelAspectRatio))
       
   745 				{
       
   746 				state = Number(num);
       
   747 				if (state)
       
   748 					iFontStoreFile->iKPixelAspectRatio = num;
       
   749 				}
       
   750 			else if (IdentComp(IdentCopyrightInfo))
       
   751 				{
       
   752 				state = NewLine();
       
   753 				while (!IdentComp(IdentEndCopyrightInfo) && !_EOF() && state)
       
   754 					{
       
   755 					String* string = new String;
       
   756 					state = StringCopy(*string);
       
   757 					if (state)
       
   758 						iFontStoreFile->iCopyrightInfo.Add(string);
       
   759 					else
       
   760 						delete string;
       
   761 					state = NewLine();
       
   762 					}
       
   763 				}
       
   764 			else if (IdentComp(IdentTypefaces))
       
   765 				{
       
   766 				state = NewLine();
       
   767 				while (!IdentComp(IdentEndTypefaces) && !_EOF() && state)
       
   768 					{
       
   769 					state =IdentCopy(label);
       
   770 					if (state)
       
   771 						{
       
   772 						typeface = iFontStore.FindTypeface(label);
       
   773 						if (typeface)
       
   774 							{
       
   775 							iFontStoreFile->AddTypeface((FntTypeface*) typeface);
       
   776 							}
       
   777 						else
       
   778 							{
       
   779 							Error("Typeface not found");
       
   780 							state = efalse;
       
   781 							}
       
   782 						}
       
   783 					if (state)
       
   784 						state = NewLine();
       
   785 					}
       
   786 				}
       
   787 			else if (IdentComp(IdentExtraFontBitmaps))
       
   788 				{
       
   789 				state = NewLine();
       
   790 				while (!IdentComp(IdentEndExtraFontBitmaps) && !_EOF() && state)
       
   791 					{
       
   792 					state = IdentCopy(label);
       
   793 					FontBitmap* fontbitmap = (FontBitmap*) iFontStore.FindFontBitmap(label);
       
   794 					if (fontbitmap)
       
   795 						{
       
   796 						iFontStoreFile->AddFontBitmap((FontBitmap*) fontbitmap);
       
   797 						}
       
   798 					else
       
   799 						{
       
   800 						Error("Fontbitmap not found");
       
   801 						state = efalse;
       
   802 						}
       
   803 					if (state)
       
   804 						state = NewLine();
       
   805 					}
       
   806 				}
       
   807 			else
       
   808 				{
       
   809 				Error("Fontstorefile identifier expected");
       
   810 				state = efalse;
       
   811 				}
       
   812 			if (state)
       
   813 				state = NewLine();
       
   814 			}
       
   815 		if (state)
       
   816 			{
       
   817 			iFontStore.AddFontStoreFile(iFontStoreFile);
       
   818 			cout << "Fontstorefile read\n";
       
   819 			}
       
   820 		else
       
   821 			delete iFontStoreFile;
       
   822 		}
       
   823 	return state;
       
   824 	}
       
   825 
       
   826 int FontReader::Store(const String& aFilename)
       
   827 	{
       
   828 	boolean state = etrue;
       
   829 	if (!iFontStoreFile)
       
   830 		{
       
   831 		state = efalse;
       
   832 		Error("No fontstore file record");
       
   833 		}
       
   834 	else
       
   835 		state = iFontStore.Store(aFilename);
       
   836 	return state;
       
   837 	}
       
   838 
       
   839 boolean FontReader::CharLine(String& aCharLine)
       
   840 	{
       
   841 	boolean state = etrue;
       
   842 	while (state && (iLex->iType != ELexNL))
       
   843 		{
       
   844 		char ch;
       
   845 		state = Operator(ch);
       
   846 		if (state)
       
   847 			{
       
   848 			if ((ch == '.') || (ch == '*'))
       
   849 				aCharLine += ch;
       
   850 			else
       
   851 				{
       
   852 				state = efalse;
       
   853 				Error("Operator '.' or '*' expected");
       
   854 				}
       
   855 			}
       
   856 		}
       
   857 	return state;
       
   858 	}
       
   859 
       
   860 void FontReader::ErrorIdentifierExpected(const String& aIdentifier)
       
   861 	{
       
   862 	cerr << "Error: Identifier Expected " << aIdentifier;
       
   863 	iLexAnal->Report();
       
   864 	while ((iLex->iType != ELexNL) && (iLex->iType != ELexEOF))
       
   865 		iLexAnal->Read();
       
   866 	}
       
   867 
       
   868 boolean FontReader::CompareBitmapLines(int aLine1, int aLine2)
       
   869 	{
       
   870 
       
   871 	int column = 0;
       
   872 	boolean identical = etrue;
       
   873 	for (column=0; column < iBitmapWidth; column++)
       
   874 		{
       
   875 		if (iBitArray[column][aLine1] != iBitArray[column][aLine2])
       
   876 			{
       
   877 			identical = efalse;
       
   878 			break;
       
   879 			}
       
   880 		}
       
   881 
       
   882 	return identical;
       
   883 	}
       
   884 
       
   885 boolean FontReader::BitmapLineEmpty(int aLine)
       
   886 	{
       
   887 
       
   888 	int column = 0;
       
   889 	boolean empty = etrue;
       
   890 	for (column = 0; column < iBitmapWidth; column++)
       
   891 		{
       
   892 		if (iBitArray[column][aLine] != 0)
       
   893 			{
       
   894 			empty = efalse;
       
   895 			break;
       
   896 			}
       
   897 		}
       
   898 
       
   899 	return empty;
       
   900 	}
       
   901 
       
   902 boolean FontReader::BitmapColumnEmpty(int aColumn)
       
   903 	{
       
   904 
       
   905 	int line = 0;
       
   906 	boolean empty = etrue;
       
   907 	for (line = 0; line < iBitmapHeight; line++)
       
   908 		{
       
   909 		if (iBitArray[aColumn][line] != 0)
       
   910 			{
       
   911 			empty = efalse;
       
   912 			break;
       
   913 			}
       
   914 		}
       
   915 
       
   916 	return empty;
       
   917 	}
       
   918 
       
   919 void FontReader::WriteFillCharacters(int aNumberConsecutive)
       
   920 	{
       
   921 	for (int counter = 0; counter < aNumberConsecutive; counter++)
       
   922 		{
       
   923 		BitmapOffset* offset = new BitmapOffset(KFillCharacterOffset);
       
   924 		iCodeSection->iCharacters.iBitmapOffsetList.Add(offset);
       
   925 		}
       
   926 	}
       
   927 
       
   928 boolean FontReader::ParseMetricsFromBDF(int aNumberCharsInFile, int aMaxConsecutiveFillChars)
       
   929 	{
       
   930 	boolean state = etrue;
       
   931 	int character = 0;
       
   932 	int numberCharactersRead;
       
   933 	int lastCharacter = KMarkFirstCharacterInTypeface;
       
   934 	int reportRate = ((aNumberCharsInFile - 1) / KReportRateFrequencyInPercent) + 1;
       
   935 
       
   936 	CharacterMetrics* metric = 0;
       
   937 	
       
   938 	cout << "Analysing character metrics...\n";
       
   939 	cout.flush();
       
   940 
       
   941 	for (numberCharactersRead = 0; numberCharactersRead < aNumberCharsInFile && !_EOF() && state; numberCharactersRead++)
       
   942 		{
       
   943 		state = IdentComp(IdentBDFCharLabel);
       
   944 		if (!state)
       
   945 			ErrorIdentifierExpected(IdentBDFCharLabel);
       
   946 		if (state)
       
   947 			iLexAnal->ReadNextLine();	// Skip to next line
       
   948 
       
   949 		if (IdentComp(IdentBDFChar))
       
   950 			{
       
   951 			state = Number(character);
       
   952 			}
       
   953 		else
       
   954 			{
       
   955 			state = efalse;
       
   956 			ErrorIdentifierExpected(IdentBDFChar);
       
   957 			}
       
   958 
       
   959 		if (character < KLowestPermittedCharacterEncoding || character > KHighestPermittedCharacterEncoding)
       
   960 			{
       
   961 			while (!IdentComp(IdentBDFEndChar) && !_EOF() && state) 
       
   962 				// Skip fill character.
       
   963 				{
       
   964 				iLexAnal->ReadNextLine(); // Skip to next line
       
   965 				}
       
   966 				iLexAnal->ReadNextLine();
       
   967 			continue;
       
   968 			}
       
   969 
       
   970 		if (character<lastCharacter)
       
   971 			{
       
   972 			Error("CodeSection out of sequence");
       
   973 			state = efalse;
       
   974 			}
       
   975 
       
   976 		if ((character > lastCharacter + 1) 
       
   977 			&& (character <= lastCharacter + 1 + aMaxConsecutiveFillChars) && state)
       
   978 			{
       
   979 			// Would result in fill characters being used if not at end of code section!
       
   980 			metric = new CharacterMetrics;
       
   981 			metric->iLeftAdjustInPixels = (chardim)0;
       
   982 			metric->iMoveInPixels = (chardim)0;
       
   983 			metric->iRightAdjustInPixels = (chardim)0;
       
   984 			metric->iAscentInPixels = (chardim)0;
       
   985 			metric->iHeightInPixels = (chardim)0;
       
   986 			iFontBitmap->iCharacterMetrics->AddOrIncrementMetric(*metric);
       
   987 			delete metric;
       
   988 			metric = 0;
       
   989 			}
       
   990 
       
   991 		if (state)
       
   992 			{
       
   993 			metric = new CharacterMetrics;
       
   994 			state = ReadMetricFromBDFCharacter(metric);
       
   995 			iFontBitmap->iCharacterMetrics->AddOrIncrementMetric(*metric);
       
   996 			delete metric;
       
   997 			metric = 0;
       
   998 			}
       
   999 		
       
  1000 		lastCharacter = character;
       
  1001 		if(numberCharactersRead == ((numberCharactersRead / reportRate) * reportRate))
       
  1002 			{
       
  1003 			cout << "Done " << (numberCharactersRead * 100 / aNumberCharsInFile) << "% \n";
       
  1004 			cout.flush();
       
  1005 			}
       
  1006 		}
       
  1007 
       
  1008 	if (state)
       
  1009 		{
       
  1010 		iFontBitmap->iCharacterMetrics->SortMetricsByFrequency();
       
  1011 		}
       
  1012 	return state;
       
  1013 	}