tahoma2d/toonz/sources/common/flash/FDTText.cpp
Toshihiro Shimizu 890dddabbd first commit
2016-03-19 02:57:51 +09:00

448 lines
12 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: FDTText.cpp
This source file contains the definition for all low-level text-related functions,
grouped by classes:
Class Member Function
FDTDefineEditText FDTDefineEditText(FRect*, U8, U8, U8, U8, U8, U8, U8, U8,
U8, U8, U8, U8, U16, U16, FColor*, U16, U8, U16, U16,
U16, U16, FString*, FString*);
~FDTDefineEditText();
void WriteToSWFStream(FSWFStream*);
FDTDefineText FDTDefineText(FRect*, FMatrix*, int);
~FDTDefineText();
void AddTextRecord(FTextRecord*);
U16 ID();
void WriteToSWFStream( FSWFStream*);
FDTDefineText2 FDTDefineText2(FRect*, FMatrix*, int);
~FDTDefineText2();
void AddTextRecord(FTextRecord*);
U16 ID();
void WriteToSWFStream(FSWFStream*);
FTextChangeRecord FTextChangeRecord(U16, U16, U16, U16, U16, U16, FColor*,
S16, S16);
~FTextChangeRecord()
// FTextChangeRecord void IncludeNBitInfo(U16, U16);
void WriteToSWFStream(FSWFStream* , int, int);
FTextGlyphRecord FTextGlyphRecord();
~FTextGlyphRecord();
void AddGlyphEntry(U16, U16);
U32 MinAdvanceBits();
U32 MinCodeBits();
void WriteToSWFStream(FSWFStream*, int, int);
****************************************************************************************/
#include "FDTText.h"
#include "FDTFonts.h"
// Constructor.
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineEditText -----------------------------------------------------
FDTDefineEditText::FDTDefineEditText(FRect *_bounds, U8 _hasFont, U8 _hasMaxLength, U8 _hasTextColor,
U8 _readOnly, U8 _password, U8 _multiline, U8 _wordWrap, U8 _hasText,
U8 _useOutlines, U8 _border, U8 _noSelect, U8 _hasLayout, U16 _fontID,
U16 _fontHeight, FColor *_textColor, U16 _maxLength, U8 _alignment,
U16 _leftMargin, U16 _rightMargin, U16 _indent, U16 _leading,
FString *_variableName, FString *_initialText) : textColor(_textColor)
{
bounds = _bounds;
hasFont = _hasFont;
hasMaxLength = _hasMaxLength;
hasTextColor = _hasTextColor;
readOnly = _readOnly;
password = _password;
multiline = _multiline;
wordWrap = _wordWrap;
hasText = _hasText;
useOutlines = _useOutlines;
border = _border;
noSelect = _noSelect;
hasLayout = _hasLayout;
fontID = _fontID;
fontHeight = _fontHeight;
textColor = _textColor;
maxLength = _maxLength;
alignment = _alignment;
leftMargin = _leftMargin;
rightMargin = _rightMargin;
indent = _indent;
leading = _leading;
variableName = _variableName;
initialText = _initialText;
characterID = FObjCollection::Increment();
}
// deletes the FRECT and 2 FString's if they exist.
FDTDefineEditText::~FDTDefineEditText(void)
{
delete bounds;
delete variableName;
delete initialText;
delete textColor;
}
// Writes to the given FSWFStream.
void FDTDefineEditText::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream tempBuffer;
tempBuffer.WriteWord((U32)characterID);
//character ID
//write the bounds, it's an object that knows how to write itself
bounds->WriteToSWFStream(&tempBuffer);
//write all flags
tempBuffer.WriteBits(hasText, 1);
tempBuffer.WriteBits(wordWrap, 1);
tempBuffer.WriteBits(multiline, 1);
tempBuffer.WriteBits(password, 1);
tempBuffer.WriteBits(readOnly, 1);
tempBuffer.WriteBits(hasTextColor, 1);
tempBuffer.WriteBits(hasMaxLength, 1);
tempBuffer.WriteBits(hasFont, 1);
tempBuffer.WriteBits(0, 2); //unknown flags
tempBuffer.WriteBits(hasLayout, 1);
tempBuffer.WriteBits(noSelect, 1);
tempBuffer.WriteBits(border, 1);
tempBuffer.WriteBits(0, 2); //unknown flags
tempBuffer.WriteBits(useOutlines, 1);
//tempBuffer.WriteBits(hasFont, 1);
//tempBuffer.WriteBits(hasMaxLength, 1);
//tempBuffer.WriteBits(hasTextColor, 1);
//tempBuffer.WriteBits(readOnly, 1);
//tempBuffer.WriteBits(password, 1);
//tempBuffer.WriteBits(multiline, 1);
//tempBuffer.WriteBits(wordWrap, 1);
//tempBuffer.WriteBits(hasText, 1);
//tempBuffer.WriteBits(useOutlines, 1);
//tempBuffer.WriteBits(border, 1);
//tempBuffer.WriteBits(noSelect, 1);
//tempBuffer.WriteBits(hasLayout, 1);
//tempBuffer.WriteBits(0, 4); //check on this, 3 in docs but 4 gives 16 bits
if (hasFont) {
tempBuffer.WriteWord((U32)fontID);
tempBuffer.WriteWord((U32)fontHeight);
}
if (hasTextColor) { // here changed.
textColor->AlphaChannel(true);
textColor->WriteToSWFStream(&tempBuffer);
}
if (hasMaxLength) {
tempBuffer.WriteWord((U32)maxLength);
}
if (hasLayout) {
tempBuffer.WriteByte(alignment);
tempBuffer.WriteWord(leftMargin);
tempBuffer.WriteWord(rightMargin);
tempBuffer.WriteWord(indent);
tempBuffer.WriteWord(leading);
}
variableName->WriteToSWFStream(&tempBuffer, true);
if (hasText) {
initialText->WriteToSWFStream(&tempBuffer, true);
}
_SWFStream->AppendTag(stagDefineEditText, tempBuffer.Size(), &tempBuffer);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineText ---------------------------------------------------------
FDTDefineText::FDTDefineText(FRect *_textBounds, FMatrix *_textMatrix, int glyhpsInFont)
{
characterID = FObjCollection::Increment();
textBounds = _textBounds;
textMatrix = _textMatrix;
nIndexBits = (U8)FSWFStream::MinBits(glyhpsInFont, 0);
}
FDTDefineText::~FDTDefineText()
{
delete textBounds;
delete textMatrix;
while (!textRecords.empty()) {
delete textRecords.front();
textRecords.pop_front();
}
}
void FDTDefineText::AddTextRecord(FTextRecord *_textRec)
{
textRecords.push_back(_textRec);
}
U16 FDTDefineText::ID(void)
{
return (U16)characterID;
}
void FDTDefineText::WriteToSWFStream(FSWFStream *_SWFStream)
{
U16 nAdvanceBits = 0;
U16 nCodeBits = 0;
FSWFStream body;
body.WriteWord((U32)characterID);
textBounds->WriteToSWFStream(&body);
textMatrix->WriteToSWFStream(&body);
// Get the bits needed to write the advance and character codes
std::list<FTextRecord *>::iterator cursor1;
for (cursor1 = textRecords.begin(); cursor1 != textRecords.end(); cursor1++) {
nAdvanceBits = (U16)std::max((*cursor1)->MinAdvanceBits(), (U32)nAdvanceBits);
nCodeBits = (U16)std::max((*cursor1)->MinCodeBits(), (U32)nCodeBits);
}
body.WriteByte((U32)nCodeBits);
body.WriteByte((U32)nAdvanceBits);
std::list<FTextRecord *>::iterator cursor;
for (cursor = textRecords.begin(); cursor != textRecords.end(); cursor++) {
(*cursor)->WriteToSWFStream(&body, nCodeBits, nAdvanceBits);
}
body.FlushBits();
body.WriteByte((U32)0);
_SWFStream->AppendTag(stagDefineText, body.Size(), &body);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineText2 --------------------------------------------------------
FDTDefineText2::FDTDefineText2(FRect *_textBounds, FMatrix *_textMatrix, int glyhpsInFont)
{
characterID = FObjCollection::Increment();
textBounds = _textBounds;
textMatrix = _textMatrix;
nIndexBits = (int)FSWFStream::MinBits(glyhpsInFont, 0);
}
FDTDefineText2::~FDTDefineText2()
{
delete textBounds;
delete textMatrix;
while (!textRecords.empty()) {
delete textRecords.front();
textRecords.pop_front();
}
}
void FDTDefineText2::AddTextRecord(FTextRecord *_textRec)
{
textRecords.push_back(_textRec);
}
U16 FDTDefineText2::ID(void)
{
return (U16)characterID;
}
void FDTDefineText2::WriteToSWFStream(FSWFStream *_SWFStream)
{
U16 nAdvanceBits = 0;
U16 nCodeBits = 0;
FSWFStream body;
body.WriteWord((U32)characterID);
textBounds->WriteToSWFStream(&body);
textMatrix->WriteToSWFStream(&body);
// Get the bits needed to write the advance and character codes
std::list<FTextRecord *>::iterator cursor1;
for (cursor1 = textRecords.begin(); cursor1 != textRecords.end(); cursor1++) {
nAdvanceBits = (U16)std::max((*cursor1)->MinAdvanceBits(), (U32)nAdvanceBits);
nCodeBits = (U16)std::max((*cursor1)->MinCodeBits(), (U32)nCodeBits);
}
body.WriteByte((U32)nCodeBits);
body.WriteByte((U32)nAdvanceBits);
std::list<FTextRecord *>::iterator cursor;
for (cursor = textRecords.begin(); cursor != textRecords.end(); cursor++) {
(*cursor)->WriteToSWFStream(&body, nCodeBits, nAdvanceBits);
}
body.FlushBits();
body.WriteByte((U32)0);
_SWFStream->AppendTag(stagDefineText2, body.Size(), &body);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FTextChangeRecord -----------------------------------------------------
FTextChangeRecord::FTextChangeRecord(U16 _hasFontFlag, U16 _hasColorFlag,
U16 _hasXOffsetFlag, U16 _hasYOffsetFlag,
U16 _fontID, U16 _fontHeight, FColor *_fontColor,
S16 _xOffset, S16 _yOffset)
{
hasFontFlag = _hasFontFlag;
hasColorFlag = _hasColorFlag;
hasXOffsetFlag = _hasXOffsetFlag;
hasYOffsetFlag = _hasYOffsetFlag;
fontID = _fontID;
fontColor = _fontColor;
xOffset = _xOffset;
yOffset = _yOffset;
fontHeight = _fontHeight;
}
FTextChangeRecord::~FTextChangeRecord()
{
delete fontColor;
}
// void FTextChangeRecord::IncludeNBitInfo(U16 _nIndexBits, U16 _nAdvanceBits){
// Does absolutely nothing
// TextGlyphRecord needs this method
// Had to be virtual so it could be called on any TextRecord
// }
void FTextChangeRecord::WriteToSWFStream(FSWFStream *_SWFStream, int /*codeBits*/, int /*advanceBits */)
{
_SWFStream->WriteBits((U32)1, 1);
// _SWFStream->WriteBits((U32) reserved, 3);
_SWFStream->WriteBits((U32)0, 3);
_SWFStream->WriteBits((U32)hasFontFlag, 1);
_SWFStream->WriteBits((U32)hasColorFlag, 1);
_SWFStream->WriteBits((U32)hasYOffsetFlag, 1);
_SWFStream->WriteBits((U32)hasXOffsetFlag, 1);
if (hasFontFlag)
_SWFStream->WriteWord((U32)fontID);
if (hasColorFlag) { // here changed.
fontColor->AlphaChannel(true);
fontColor->WriteToSWFStream(_SWFStream);
}
if (hasXOffsetFlag)
_SWFStream->WriteWord((U32)xOffset);
if (hasYOffsetFlag)
_SWFStream->WriteWord((U32)yOffset);
if (hasFontFlag)
_SWFStream->WriteWord((U32)fontHeight);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FTextGlyphRecord ------------------------------------------------------
FTextGlyphRecord::FTextGlyphRecord()
{
}
FTextGlyphRecord::~FTextGlyphRecord()
{
while (!glyphEntries.empty()) {
glyphEntries.pop_front();
}
}
void FTextGlyphRecord::AddGlyphEntry(U16 code, U16 advance)
{
GlyphEntry glyph = {code, advance};
glyphEntries.push_back(glyph);
}
U32 FTextGlyphRecord::MinAdvanceBits()
{
std::list<GlyphEntry>::iterator it;
int maxBit = 0;
for (it = glyphEntries.begin(); it != glyphEntries.end(); ++it) {
maxBit = (int)std::max(FSWFStream::MinBits(it->advance, 1), (U32)maxBit);
}
return maxBit;
}
U32 FTextGlyphRecord::MinCodeBits()
{
// return FSWFStream::MinBits( glyphEntries.size(), 0 );
std::list<GlyphEntry>::iterator it;
int maxBit = 0;
for (it = glyphEntries.begin(); it != glyphEntries.end(); ++it) {
int code = it->code;
maxBit = (int)std::max(FSWFStream::MinBits(code, 1), (U32)maxBit);
}
return maxBit;
}
void FTextGlyphRecord::WriteToSWFStream(FSWFStream *_SWFStream, int codeBits, int advanceBits)
{
FLASHASSERT((int)MinAdvanceBits() <= advanceBits);
FLASHASSERT((int)MinCodeBits() <= codeBits);
// Bug: The number of glyphs used to limit the the max code size, but this changes with
// DefineFont2, where we could use glyph 38 as our sole glyph. So the re-write begins....
int numberOfGlyphs = glyphEntries.size();
_SWFStream->WriteBits((U32)0, 1);
_SWFStream->WriteBits((U32)numberOfGlyphs, 7);
std::list<GlyphEntry>::iterator cursor;
for (cursor = glyphEntries.begin(); cursor != glyphEntries.end(); cursor++) {
_SWFStream->WriteBits((U32)cursor->code, codeBits);
_SWFStream->WriteBits((U32)cursor->advance, advanceBits);
}
}