www.pudn.com > FlashFormat.rar > FDTFonts.cpp


// Copyright © 1999 Middlesoft, Inc. All rights reserved.
// First Created By Lee Thomason.
// First Created On 09/08/1999.
// Last Modified On 11/09/1999.

/****************************************************************************************

				File Summary: FDTFonts.cpp

  This source file contains the definition for all low-level font-related functions,
  grouped by classes:

  		Class						Member Function

	FDTDefineFont				FDTDefineFont();
								~FDTDefineFont();
								U16 ID();
								void AddShapeGlyph(FShape*);
								void WriteToSWFStream(FSWFStream*);

	FDTDefineFont2				FDTDefineFont2(char*, U16, U16, U16);
								FDTDefineFont2(char*, U16, U16, U16, S16, S16, S16);
								~FDTDefineFont2();
								void AddShapeGlyph(FShape*, U16, S16, FRect*);
								void AddKerningRec(FKerningRec*);
								U16 nIndexBits();
								U16 ID(void);
								void WriteToSWFStream(FSWFStream*);

	FDTDefineFontInfo			FDTDefineFontInfo(const char*, U16, U16, U16, U16);
								void FDTDefineFontInfo::AddCode(U16);
								U16 FDTDefineFontInfo::ID();
								void WriteToSWFStream(FSWFStream*);

//	FGlyphEntry					FGlyphEntry(U16, S16);
//								S16 AdvanceValue();
//								void IncludeNBitInfo(U16, U16);
//								void WriteToSWFStream(FSWFStream*);

	FKerningRec					FKerningRec (U16, U16, short);
								void CodesWide (U16);
								void WriteToSWFStream(FSWFStream*);

	
	Note: All member functions of FGlyphEntry have been commented out. Need to fix.

****************************************************************************************/

#pragma warning (disable:4786)	

#include "FDTFonts.h"
#include "FDTShapes.h"


//////////////////////////////////////////////////////////////////////////////////////
//  --------  FButtonRecord1 ---------------------------------------------------------

FDTDefineFont::FDTDefineFont()
{

	characterID = FObjCollection::Increment();

	nFillBits = 1;
	nLineBits = 0;

}

FDTDefineFont::~FDTDefineFont()
{

	while ( !shapeGlyphs.empty() )
	{

		delete shapeGlyphs.front();
		shapeGlyphs.pop_front();

	}

}

U16 FDTDefineFont::ID()
{

	return characterID;

}

void FDTDefineFont::AddShapeGlyph(FShape* _shape)
{

	_shape->SetFillBits(nFillBits);
	_shape->SetLineBits(nLineBits);
	shapeGlyphs.push_back(_shape);

}

void FDTDefineFont::WriteToSWFStream(FSWFStream* _SWFStream)
{

	U32 offsetsBufferSize = shapeGlyphs.size() * 2;

	FSWFStream body;
	FSWFStream shapeBuffer;
	std::list offsetsList;


	// get values for offsets and place them in a list
	// write list of shapeGlyphs to shape buffer
	offsetsList.push_back(offsetsBufferSize);

	std::list::iterator cursor;
	std::list::iterator nextToLast = shapeGlyphs.end();
	nextToLast--;
	for ( cursor = shapeGlyphs.begin();  cursor != nextToLast;  cursor++ )
	{

		(*cursor)->WriteToSWFStream(&shapeBuffer);
		offsetsList.push_back(offsetsBufferSize + shapeBuffer.Size());
	}

	(*cursor)->WriteToSWFStream(&shapeBuffer);

	body.WriteWord((U32)characterID );

	// write offsetsList to body
	while ( !offsetsList.empty() )
	{

		body.WriteWord((U32) offsetsList.front());
		offsetsList.pop_front();

	}

	//write shape buffer to body
	body.Append(&shapeBuffer);

	//put tag on body and write to stream
	_SWFStream->AppendTag( stagDefineFont, body.Size(), &body );    
}


//////////////////////////////////////////////////////////////////////////////////////
//  --------  FDTDefineFont2 ---------------------------------------------------------

FDTDefineFont2::FDTDefineFont2( const char* _fontName, U16 _encodeType, U16 _italicFlag, U16 _boldFlag )
{
	fontID			= FObjCollection::Increment();
	hasLayoutFlag	= 1;
	encodeType		= _encodeType;
	italicFlag		= _italicFlag;
	boldFlag		= _boldFlag;
	fontName		= new FString((U8*) _fontName);
	nFillBits = 1;
	nLineBits = 0;
    ascenderHeight = 0;
    descenderHeight = 0;
    leadingHeight = 0;
}

FDTDefineFont2::FDTDefineFont2( const char* _fontName, U16 _encodeType, U16 _italicFlag,
							   U16 _boldFlag, S16 _ascenderHeight, 
							   S16 _descenderHeight, S16 _leadingHeight)
{

	fontID = FObjCollection::Increment();
	hasLayoutFlag = 1;
	encodeType = _encodeType;
	italicFlag = _italicFlag;
	boldFlag = _boldFlag;
	fontName =  new FString((U8*) _fontName);

	ascenderHeight = _ascenderHeight;
	descenderHeight = _descenderHeight;
	leadingHeight = _leadingHeight;

	nFillBits = 1;
	nLineBits = 0;

}

FDTDefineFont2::~FDTDefineFont2()
{

	delete fontName;

	while ( !glyphs.empty() )
	{
		delete glyphs.front().shape;
		delete glyphs.front().bounds;
		glyphs.pop_front();
	}

	while ( !kerningTable.empty() )
	{

		delete kerningTable.front();
		kerningTable.pop_front();
	}

}


void FDTDefineFont2::AddShapeGlyph( FShape* _shape, U16 _shapeCode,S16 _shapeAdvance,
								    FRect* _shapeBounds)
{
	// FIXME, don't know what nFillBits and nLineBits are
	_shape->SetFillBits(nFillBits);
	_shape->SetLineBits(nLineBits);
	Glyph g;
	g.advance = _shapeAdvance;
	g.bounds  = _shapeBounds;
	g.code    = _shapeCode;
	g.shape   = _shape;
	glyphs.push_back(g);
}

void FDTDefineFont2::AddKerningRec(FKerningRec* _kerningRecord)
{

	if ( hasLayoutFlag )
		kerningTable.push_back(_kerningRecord);

}

U16 FDTDefineFont2::nIndexBits()
{

	return(U16) FSWFStream::MinBits(glyphs.size() - 1, false);

}

U16 FDTDefineFont2::ID(void)
{

	return fontID;

}

void FDTDefineFont2::WriteToSWFStream(FSWFStream* _SWFStream)
{
//	U32 offsetsSize		= (glyphs.size() * 2);
//	U32 offsetsSizeWide = glyphs.size() * 4;
//	U16 wideOffsetsFlag = 0;
//	U16 wideCodesFlag	= 0;
//	std::list offsetsList;

	// FIXME: add wide offset later
	S16* offsetTable;
	if (glyphs.size() > 0)
		offsetTable = new S16[glyphs.size()];
	else
		offsetTable = 0;

	int i;

	FSWFStream body;
	FSWFStream shapeBuffer;

	std::list::iterator glyphCursor;
	for ( glyphCursor = glyphs.begin(), i = 0; glyphCursor != glyphs.end(); glyphCursor++, i++ )
	{
		offsetTable[i] = shapeBuffer.Size();
		glyphCursor->shape->WriteToSWFStream(&shapeBuffer);

	}

	body.WriteWord((U32)fontID);
	//write flags to body
	body.WriteBits((U32) hasLayoutFlag, 1);

	switch ( encodeType )
	{
	
	case ShiftJIS: 
		body.WriteBits((U32) 1, 1);
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 0, 1);
		break;
	case Unicode:
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 1, 1);
		body.WriteBits((U32) 0, 1);
		break; 
	case ANSI:
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 1, 1);
		break;

	}
	body.WriteBits((U32) 0, 1);			// 0 for narrowOffsetFlag
	body.WriteBits((U32) 0, 1);			// 0 for narrowOffsetCode
	body.WriteBits((U32) italicFlag, 1);
	body.WriteBits((U32) boldFlag, 1);
	body.WriteByte(0);					// FontFlagsReserved UB[8]
	

	body.WriteByte((U32) fontName->Length());
	fontName->WriteToSWFStream(&body, false );	// write the name

	body.WriteWord((U32) glyphs.size());

	// write offsetsList to body
	if (glyphs.size() > 0 )
		body.WriteLargeData( (U8*)offsetTable, 2*glyphs.size() );

	//write shape glyph buffer to body
	body.Append(&shapeBuffer);

	for ( glyphCursor = glyphs.begin(), i = 0; glyphCursor != glyphs.end(); glyphCursor++, i++ )
	{
		body.WriteWord(glyphCursor->code);
	}


	// write layout information to body
	if ( hasLayoutFlag )
	{
		body.WriteWord((U32) ascenderHeight);
		body.WriteWord((U32) descenderHeight);
		body.WriteWord((U32) leadingHeight);

		for ( glyphCursor = glyphs.begin(), i = 0; glyphCursor != glyphs.end(); glyphCursor++, i++ )
		{
			body.WriteWord(glyphCursor->advance);
		}

		for ( glyphCursor = glyphs.begin(), i = 0; glyphCursor != glyphs.end(); glyphCursor++, i++ )
		{
			glyphCursor->bounds->WriteToSWFStream(&body);
		}


	    body.WriteWord((U32) kerningTable.size());

		std::list::iterator kernCursor;

		for ( kernCursor = kerningTable.begin();  kernCursor!= kerningTable.end();  kernCursor++ )
		{

			(*kernCursor)->CodesWide(0);		// 0 is narraw offset flag
			(*kernCursor)->WriteToSWFStream(&body);
		}

	}


	// create entire tag with record header
	_SWFStream->AppendTag( stagDefineFont2, body.Size(), &body );
	delete [] offsetTable;
}


//////////////////////////////////////////////////////////////////////////////////////
//  --------  FButtonRecord1 ---------------------------------------------------------

FDTDefineFontInfo::FDTDefineFontInfo(const char* _fontName, U16 _fontID, 
									 U16 _encodeType, U16 _italicFlag,
									 U16 _boldFlag)
{



	characterID = FObjCollection::Increment();
	encodeType = _encodeType;
	italicFlag = _italicFlag;
	boldFlag = _boldFlag;

	fontID = _fontID;

	fontName = new FString((U8*) _fontName);

}

FDTDefineFontInfo::~FDTDefineFontInfo()
{
	delete fontName;
}

void FDTDefineFontInfo::AddCode(U16 _someCode)
{


	codeTable.push_back(_someCode);



}

U16 FDTDefineFontInfo::ID()
{
	return characterID;
}

void FDTDefineFontInfo::WriteToSWFStream(FSWFStream* _SWFStream)
{

	U16 wideCodesFlag = 0;
	FSWFStream body;


	//determine whether 8 or 16 bit code fields are needed
	std::list::iterator cursor;
	for ( cursor = codeTable.begin(); (cursor != codeTable.end()) && (wideCodesFlag = 0)
		; cursor++ )
	{
		if ( (*cursor) > 65530 )
			wideCodesFlag = 1;
	}

	body.WriteWord((U32) fontID);

	body.WriteByte((U32) fontName->Length());

	fontName->WriteToSWFStream(&body, false);

// 	body.WriteBits((U32) reservedFlags, 2);
	body.WriteBits((U32) 0, 2);

	switch ( encodeType )
	{
	
	case ShiftJIS: 
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 1, 1);
		body.WriteBits((U32) 0, 1);
		break;
	case Unicode:
		body.WriteBits((U32) 1, 1);
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 0, 1);
		break; 
	case ANSI:
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 0, 1);
		body.WriteBits((U32) 1, 1);
		break;

	}

	body.WriteBits((U32) italicFlag, 1);
	body.WriteBits((U32) boldFlag, 1);

	body.WriteBits((U32) wideCodesFlag, 1);

	//write code table to body
	while ( !codeTable.empty() )
	{
		if ( wideCodesFlag )
		{
			body.WriteWord((U32) codeTable.front());
			codeTable.pop_front();
		}
		else
		{
			body.WriteByte((U32) codeTable.front());
			codeTable.pop_front();
		}
	}

	// create entire tag with record header
	_SWFStream->AppendTag( stagDefineFontInfo, body.Size(), &body );    
}

//////////////////////////////////////////////////////////////////////////////////////
//  --------  FGlyphEntry ------------------------------------------------------------

// FGlyphEntry::FGlyphEntry(U16 index, S16 advance)
// {
// 
// 	glyphIndex = index;
// 	glyphAdvance = advance;
// 
// }
// 
// 
// S16 FGlyphEntry::AdvanceValue()
// {
// 
// 	return glyphAdvance;
// 
// }

//	Used to specify the nBit info for the entries.  This is determined and passed to
//	the glyph entry just before write time.

// void FGlyphEntry::IncludeNBitInfo(U16 _nIndexBits, U16 _nAdvanceBits)
// {
// 
// 	nIndexBits = _nIndexBits;
// 	nAdvanceBits = _nAdvanceBits;
// }
// 
// void FGlyphEntry::WriteToSWFStream(FSWFStream *_SWFStream)
// {
// 
// 	_SWFStream->WriteBits((U32) glyphIndex, nIndexBits);
// 	_SWFStream->WriteBits((U32) glyphAdvance, nAdvanceBits);
// 
// }

//////////////////////////////////////////////////////////////////////////////////////
//  --------  FKerningRec ------------------------------------------------------------

FKerningRec::FKerningRec (U16 cd1, U16 cd2, short krnAdj)
{

	wideCodesFlag = 0; // default not wide
	code1 = cd1;
	code2 = cd2;
	kerningAdjust = krnAdj;
}

void FKerningRec::CodesWide (U16 _flag)
{

	if ( _flag )
		wideCodesFlag = 1;
	else
		wideCodesFlag = 0;

}


void FKerningRec::WriteToSWFStream(FSWFStream* b)
{
	if ( wideCodesFlag )
	{
		b->WriteWord((U32) code1);
		b->WriteWord((U32) code2);
	}
	else
	{
		b->WriteByte((U32) code1 );
		b->WriteByte((U32) code2 );
	}

	b->WriteWord((U32) kerningAdjust );
}