486 lines
11 KiB
C++
486 lines
11 KiB
C++
// 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.
|
|
|
|
****************************************************************************************/
|
|
#ifdef WIN32
|
|
#pragma warning(disable : 4786)
|
|
#endif
|
|
|
|
#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 (U8)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<U32> offsetsList;
|
|
|
|
// get values for offsets and place them in a list
|
|
// write list of shapeGlyphs to shape buffer
|
|
offsetsList.push_back(offsetsBufferSize);
|
|
|
|
std::list<FShape *>::iterator cursor;
|
|
std::list<FShape *>::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<U32> 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<Glyph>::iterator glyphCursor;
|
|
for (glyphCursor = glyphs.begin(), i = 0; glyphCursor != glyphs.end(); glyphCursor++, i++) {
|
|
offsetTable[i] = (S8)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<FKerningRec *>::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 (U8)characterID;
|
|
}
|
|
|
|
void FDTDefineFontInfo::WriteToSWFStream(FSWFStream *_SWFStream)
|
|
{
|
|
|
|
U16 wideCodesFlag = 0;
|
|
FSWFStream body;
|
|
|
|
//determine whether 8 or 16 bit code fields are needed
|
|
std::list<U16>::iterator cursor;
|
|
for (cursor = codeTable.begin(); (cursor != codeTable.end()) && (wideCodesFlag == 0) // fixed from DV
|
|
;
|
|
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);
|
|
}
|