Blame |
Last modification |
View Log
| RSS feed
#include "ImageFont.h"
#include "Graphics.h"
#include "Image.h"
#include "SexyAppBase.h"
#include "MemoryImage.h"
#include "..\SexyAppFramework\AutoCrit.h"
using namespace Sexy;
////
DataElement::DataElement() :
mIsList(false)
{
}
DataElement::~DataElement()
{
}
SingleDataElement::SingleDataElement()
{
mIsList = false;
}
SingleDataElement::SingleDataElement(const std::string theString) :
mString(theString)
{
mIsList = false;
}
SingleDataElement::~SingleDataElement()
{
}
DataElement* SingleDataElement::Duplicate()
{
SingleDataElement* aSingleDataElement = new SingleDataElement(*this);
return aSingleDataElement;
}
ListDataElement::ListDataElement()
{
mIsList = true;
}
ListDataElement::~ListDataElement()
{
for (ulong i = 0; i < mElementVector.size(); i++)
delete mElementVector[i];
}
ListDataElement::ListDataElement(const ListDataElement& theListDataElement)
{
mIsList = true;
for (ulong i = 0; i < theListDataElement.mElementVector.size(); i++)
mElementVector.push_back(theListDataElement.mElementVector[i]->Duplicate());
}
ListDataElement& ListDataElement::operator=(const ListDataElement& theListDataElement)
{
ulong i;
for (i = 0; i < mElementVector.size(); i++)
delete mElementVector[i];
mElementVector.clear();
for (i = 0; i < theListDataElement.mElementVector.size(); i++)
mElementVector.push_back(theListDataElement.mElementVector[i]->Duplicate());
return *this;
}
DataElement* ListDataElement::Duplicate()
{
ListDataElement* aListDataElement = new ListDataElement(*this);
return aListDataElement;
}
///
CharData::CharData()
{
mWidth = 0;
mOrder = 0;
for (ulong i = 0; i < 256; i++)
mKerningOffsets[i] = 0;
}
FontLayer::FontLayer(FontData* theFontData)
{
mFontData = theFontData;
mDrawMode = -1;
mSpacing = 0;
mPointSize = 0;
mAscent = 0;
mAscentPadding = 0;
mMinPointSize = -1;
mMaxPointSize = -1;
mHeight = 0;
mDefaultHeight = 0;
mColorMult = Color::White;
mColorAdd = Color(0, 0, 0, 0);
mLineSpacingOffset = 0;
mBaseOrder = 0;
}
FontLayer::FontLayer(const FontLayer& theFontLayer) :
mFontData(theFontLayer.mFontData),
mRequiredTags(theFontLayer.mRequiredTags),
mExcludedTags(theFontLayer.mExcludedTags),
mImage(theFontLayer.mImage),
mDrawMode(theFontLayer.mDrawMode),
mOffset(theFontLayer.mOffset),
mSpacing(theFontLayer.mSpacing),
mMinPointSize(theFontLayer.mMinPointSize),
mMaxPointSize(theFontLayer.mMaxPointSize),
mPointSize(theFontLayer.mPointSize),
mAscent(theFontLayer.mAscent),
mAscentPadding(theFontLayer.mAscentPadding),
mHeight(theFontLayer.mHeight),
mDefaultHeight(theFontLayer.mDefaultHeight),
mColorMult(theFontLayer.mColorMult),
mColorAdd(theFontLayer.mColorAdd),
mLineSpacingOffset(theFontLayer.mLineSpacingOffset),
mBaseOrder(theFontLayer.mBaseOrder)
{
ulong i;
for (i = 0; i < 256; i++)
mCharData[i] = theFontLayer.mCharData[i];
}
FontData::FontData()
{
mInitialized = false;
mApp = NULL;
mRefCount = 0;
mDefaultPointSize = 0;
for (ulong i = 0; i < 256; i++)
mCharMap[i] = (uchar) i;
}
FontData::~FontData()
{
DataElementMap::iterator anItr = mDefineMap.begin();
while (anItr != mDefineMap.end())
{
std::string aDefineName = anItr->first;
DataElement* aDataElement = anItr->second;
delete aDataElement;
++anItr;
}
}
void FontData::Ref()
{
mRefCount++;
}
void FontData::DeRef()
{
if (--mRefCount == 0)
{
delete this;
}
}
bool FontData::Error(const std::string& theError)
{
if (mApp != NULL)
{
std::string anErrorString = mFontErrorHeader + theError;
if (mCurrentLine.length() > 0)
{
anErrorString += " on Line " + StrFormat("%d:\r\n\r\n", mCurrentLineNum) + mCurrentLine;
}
mApp->Popup(anErrorString);
}
return false;
}
bool FontData::DataToLayer(DataElement* theSource, FontLayer** theFontLayer)
{
*theFontLayer = NULL;
if (theSource->mIsList)
return false;
std::string aLayerName = StringToUpper(((SingleDataElement*) theSource)->mString);
FontLayerMap::iterator anItr = mFontLayerMap.find(aLayerName);
if (anItr == mFontLayerMap.end())
{
Error("Undefined Layer");
return false;
}
*theFontLayer = anItr->second;
return true;
}
bool FontData::GetColorFromDataElement(DataElement *theElement, Color &theColor)
{
if (theElement->mIsList)
{
DoubleVector aFactorVector;
if (!DataToDoubleVector(theElement, &aFactorVector) && (aFactorVector.size() == 4))
return false;
theColor = Color(
(int) (aFactorVector[0] * 255),
(int) (aFactorVector[1] * 255),
(int) (aFactorVector[2] * 255),
(int) (aFactorVector[3] * 255));
return true;
}
int aColor = 0;
if (!StringToInt(((SingleDataElement*) theElement)->mString, &aColor))
return false;
theColor = aColor;
return true;
}
bool FontData::HandleCommand(const ListDataElement& theParams)
{
std::string aCmd = ((SingleDataElement*) theParams.mElementVector[0])->mString;
bool invalidNumParams = false;
bool invalidParamFormat = false;
bool literalError = false;
bool sizeMismatch = false;
if (stricmp(aCmd.c_str(), "Define") == 0)
{
if (theParams.mElementVector.size() == 3)
{
if (!theParams.mElementVector[1]->mIsList)
{
std::string aDefineName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
if (!IsImmediate(aDefineName))
{
DataElementMap::iterator anItr = mDefineMap.find(aDefineName);
if (anItr != mDefineMap.end())
{
delete anItr->second;
mDefineMap.erase(anItr);
}
if (theParams.mElementVector[2]->mIsList)
{
ListDataElement* aValues = new ListDataElement();
if (!GetValues(((ListDataElement*) theParams.mElementVector[2]), aValues))
{
delete aValues;
return false;
}
mDefineMap.insert(DataElementMap::value_type(aDefineName, aValues));
}
else
{
SingleDataElement* aDefParam = (SingleDataElement*) theParams.mElementVector[2];
DataElement* aDerefVal = Dereference(aDefParam->mString);
if (aDerefVal)
mDefineMap.insert(DataElementMap::value_type(aDefineName, aDerefVal->Duplicate()));
else
mDefineMap.insert(DataElementMap::value_type(aDefineName, aDefParam->Duplicate()));
}
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "CreateHorzSpanRectList") == 0)
{
if (theParams.mElementVector.size() == 4)
{
IntVector aRectIntVector;
IntVector aWidthsVector;
if ((!theParams.mElementVector[1]->mIsList) &&
(DataToIntVector(theParams.mElementVector[2], &aRectIntVector)) &&
(aRectIntVector.size() == 4) &&
(DataToIntVector(theParams.mElementVector[3], &aWidthsVector)))
{
std::string aDefineName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
int aXPos = 0;
ListDataElement* aRectList = new ListDataElement();
for (ulong aWidthNum = 0; aWidthNum < aWidthsVector.size(); aWidthNum++)
{
ListDataElement* aRectElement = new ListDataElement();
aRectList->mElementVector.push_back(aRectElement);
char aStr[256];
sprintf(aStr, "%d", aRectIntVector[0] + aXPos);
aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
sprintf(aStr, "%d", aRectIntVector[1]);
aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
sprintf(aStr, "%d", aWidthsVector[aWidthNum]);
aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
sprintf(aStr, "%d", aRectIntVector[3]);
aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
aXPos += aWidthsVector[aWidthNum];
}
DataElementMap::iterator anItr = mDefineMap.find(aDefineName);
if (anItr != mDefineMap.end())
{
delete anItr->second;
mDefineMap.erase(anItr);
}
mDefineMap.insert(DataElementMap::value_type(aDefineName, aRectList));
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "SetDefaultPointSize") == 0)
{
if (theParams.mElementVector.size() == 2)
{
int aPointSize;
if ((!theParams.mElementVector[1]->mIsList) &&
(StringToInt(((SingleDataElement*) theParams.mElementVector[1])->mString, &aPointSize)))
{
mDefaultPointSize = aPointSize;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "SetCharMap") == 0)
{
if (theParams.mElementVector.size() == 3)
{
StringVector aFromVector;
StringVector aToVector;
if ((DataToStringVector(theParams.mElementVector[1], &aFromVector)) &&
(DataToStringVector(theParams.mElementVector[2], &aToVector)))
{
if (aFromVector.size() == aToVector.size())
{
for (ulong aMapIdx = 0; aMapIdx < aFromVector.size(); aMapIdx++)
{
if ((aFromVector[aMapIdx].length() == 1) && (aToVector[aMapIdx].length() == 1))
{
mCharMap[(uchar) aFromVector[aMapIdx][0]] = (uchar) aToVector[aMapIdx][0];
}
else
invalidParamFormat = true;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "CreateLayer") == 0)
{
if (theParams.mElementVector.size() == 2)
{
if (!theParams.mElementVector[1]->mIsList)
{
std::string aLayerName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
mFontLayerList.push_back(FontLayer(this));
FontLayer* aFontLayer = &mFontLayerList.back();
if (!mFontLayerMap.insert(FontLayerMap::value_type(aLayerName, aFontLayer)).second)
{
Error("Layer Already Exists");
}
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "CreateLayerFrom") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aSourceLayer;
if ((!theParams.mElementVector[1]->mIsList) && (DataToLayer(theParams.mElementVector[2], &aSourceLayer)))
{
std::string aLayerName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
mFontLayerList.push_back(FontLayer(*aSourceLayer));
FontLayer* aFontLayer = &mFontLayerList.back();
if (!mFontLayerMap.insert(FontLayerMap::value_type(aLayerName, aFontLayer)).second)
{
Error("Layer Already Exists");
}
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerRequireTags") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
StringVector aStringVector;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aStringVector)))
{
for (ulong i = 0; i < aStringVector.size(); i++)
aLayer->mRequiredTags.push_back(StringToUpper(aStringVector[i]));
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerExcludeTags") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
StringVector aStringVector;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aStringVector)))
{
for (ulong i = 0; i < aStringVector.size(); i++)
aLayer->mExcludedTags.push_back(StringToUpper(aStringVector[i]));
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerPointRange") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList) &&
(!theParams.mElementVector[3]->mIsList))
{
int aMinPointSize;
int aMaxPointSize;
if ((StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aMinPointSize)) &&
(StringToInt(((SingleDataElement*) theParams.mElementVector[3])->mString, &aMaxPointSize)))
{
aLayer->mMinPointSize = aMinPointSize;
aLayer->mMaxPointSize = aMaxPointSize;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetPointSize") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int aPointSize;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aPointSize))
{
aLayer->mPointSize = aPointSize;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetHeight") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int aHeight;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aHeight))
{
aLayer->mHeight = aHeight;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetImage") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
std::string aFileNameString;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToString(theParams.mElementVector[2], &aFileNameString)))
{
std::string aFileName = GetPathFrom(aFileNameString, GetFileDir(mSourceFile));
bool isNew;
SharedImageRef anImage = mApp->GetSharedImage(aFileName, "", &isNew);
if ((Image*) anImage != NULL)
{
if (isNew)
anImage->Palletize();
aLayer->mImage = anImage;
}
else
{
Error("Failed to Load Image");
return false;
}
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetDrawMode") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) && (!theParams.mElementVector[2]->mIsList))
{
int anDrawMode;
if ((StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anDrawMode)) &&
(anDrawMode >= 0) && (anDrawMode <= 1))
{
aLayer->mDrawMode = anDrawMode;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetColorMult") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if (DataToLayer(theParams.mElementVector[1], &aLayer))
{
if (!GetColorFromDataElement(theParams.mElementVector[2],aLayer->mColorMult))
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetColorAdd") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if (DataToLayer(theParams.mElementVector[1], &aLayer))
{
if (!GetColorFromDataElement(theParams.mElementVector[2],aLayer->mColorAdd))
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetAscent") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int anAscent;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
{
aLayer->mAscent = anAscent;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetAscentPadding") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int anAscent;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
{
aLayer->mAscentPadding = anAscent;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetLineSpacingOffset") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int anAscent;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
{
aLayer->mLineSpacingOffset = anAscent;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetOffset") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
IntVector anOffset;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) && (DataToIntVector(theParams.mElementVector[2], &anOffset)) && (anOffset.size() == 2))
{
aLayer->mOffset.mX = anOffset[0];
aLayer->mOffset.mY = anOffset[1];
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetCharWidths") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
StringVector aCharsVector;
IntVector aCharWidthsVector;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
(DataToIntVector(theParams.mElementVector[3], &aCharWidthsVector)))
{
if (aCharsVector.size() == aCharWidthsVector.size())
{
for (ulong i = 0; i < aCharsVector.size(); i++)
{
if (aCharsVector[i].length() == 1)
{
aLayer->mCharData[(uchar) aCharsVector[i][0]].mWidth =
aCharWidthsVector[i];
}
else
invalidParamFormat = true;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetSpacing") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
IntVector anOffset;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int aSpacing;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aSpacing))
{
aLayer->mSpacing = aSpacing;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetImageMap") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
StringVector aCharsVector;
ListDataElement aRectList;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
(DataToList(theParams.mElementVector[3], &aRectList)))
{
if (aCharsVector.size() == aRectList.mElementVector.size())
{
if ((Image*) aLayer->mImage != NULL)
{
int anImageWidth = aLayer->mImage->GetWidth();
int anImageHeight = aLayer->mImage->GetHeight();
for (ulong i = 0; i < aCharsVector.size(); i++)
{
IntVector aRectElement;
if ((aCharsVector[i].length() == 1) &&
(DataToIntVector(aRectList.mElementVector[i], &aRectElement)) &&
(aRectElement.size() == 4))
{
Rect aRect = Rect(aRectElement[0], aRectElement[1], aRectElement[2], aRectElement[3]);
if ((aRect.mX < 0) || (aRect.mY < 0) ||
(aRect.mX + aRect.mWidth > anImageWidth) || (aRect.mY + aRect.mHeight > anImageHeight))
{
Error("Image rectangle out of bounds");
return false;
}
aLayer->mCharData[(uchar) aCharsVector[i][0]].mImageRect = aRect;;
}
else
invalidParamFormat = true;
}
aLayer->mDefaultHeight = 0;
for (int aCharNum = 0; aCharNum < 256; aCharNum++)
if (aLayer->mCharData[aCharNum].mImageRect.mHeight + aLayer->mCharData[aCharNum].mOffset.mY > aLayer->mDefaultHeight)
aLayer->mDefaultHeight = aLayer->mCharData[aCharNum].mImageRect.mHeight + aLayer->mCharData[aCharNum].mOffset.mY;
}
else
{
Error("Layer image not set");
return false;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetCharOffsets") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
StringVector aCharsVector;
ListDataElement aRectList;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
(DataToList(theParams.mElementVector[3], &aRectList)))
{
if (aCharsVector.size() == aRectList.mElementVector.size())
{
for (ulong i = 0; i < aCharsVector.size(); i++)
{
IntVector aRectElement;
if ((aCharsVector[i].length() == 1) &&
(DataToIntVector(aRectList.mElementVector[i], &aRectElement)) &&
(aRectElement.size() == 2))
{
aLayer->mCharData[(uchar) aCharsVector[i][0]].mOffset =
Point(aRectElement[0], aRectElement[1]);
}
else
invalidParamFormat = true;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetKerningPairs") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
StringVector aPairsVector;
IntVector anOffsetsVector;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aPairsVector)) &&
(DataToIntVector(theParams.mElementVector[3], &anOffsetsVector)))
{
if (aPairsVector.size() == anOffsetsVector.size())
{
for (ulong i = 0; i < aPairsVector.size(); i++)
{
if (aPairsVector[i].length() == 2)
{
aLayer->mCharData[(uchar) aPairsVector[i][0]].mKerningOffsets
[(uchar) aPairsVector[i][1]] = anOffsetsVector[i];
}
else
invalidParamFormat = true;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetBaseOrder") == 0)
{
if (theParams.mElementVector.size() == 3)
{
FontLayer* aLayer;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(!theParams.mElementVector[2]->mIsList))
{
int aBaseOrder;
if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aBaseOrder))
{
aLayer->mBaseOrder = aBaseOrder;
}
else
invalidParamFormat = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else if (stricmp(aCmd.c_str(), "LayerSetCharOrders") == 0)
{
if (theParams.mElementVector.size() == 4)
{
FontLayer* aLayer;
StringVector aCharsVector;
IntVector aCharOrdersVector;
if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
(DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
(DataToIntVector(theParams.mElementVector[3], &aCharOrdersVector)))
{
if (aCharsVector.size() == aCharOrdersVector.size())
{
for (ulong i = 0; i < aCharsVector.size(); i++)
{
if (aCharsVector[i].length() == 1)
{
aLayer->mCharData[(uchar) aCharsVector[i][0]].mOrder =
aCharOrdersVector[i];
}
else
invalidParamFormat = true;
}
}
else
sizeMismatch = true;
}
else
invalidParamFormat = true;
}
else
invalidNumParams = true;
}
else
{
Error("Unknown Command");
return false;
}
if (invalidNumParams)
{
Error("Invalid Number of Parameters");
return false;
}
if (invalidParamFormat)
{
Error("Invalid Paramater Type");
return false;
}
if (literalError)
{
Error("Undefined Value");
return false;
}
if (sizeMismatch)
{
Error("List Size Mismatch");
return false;
}
return true;
}
bool FontData::Load(SexyAppBase* theSexyApp, const std::string& theFontDescFileName)
{
if (mInitialized)
return false;
bool hasErrors = false;
mApp = theSexyApp;
mCurrentLine = "";
mFontErrorHeader = "Font Descriptor Error in " + theFontDescFileName + "\r\n";
mSourceFile = theFontDescFileName;
mInitialized = LoadDescriptor(theFontDescFileName); ;
return !hasErrors;
}
bool FontData::LoadLegacy(Image* theFontImage, const std::string& theFontDescFileName)
{
if (mInitialized)
return false;
mFontLayerList.push_back(FontLayer(this));
FontLayer* aFontLayer = &mFontLayerList.back();
FontLayerMap::iterator anItr = mFontLayerMap.insert(FontLayerMap::value_type("", aFontLayer)).first;
if (anItr == mFontLayerMap.end())
return false;
aFontLayer->mImage = (MemoryImage*) theFontImage;
aFontLayer->mDefaultHeight = aFontLayer->mImage->GetHeight();
aFontLayer->mAscent = aFontLayer->mImage->GetHeight();
int aCharPos = 0;
FILE *aStream = fopen(theFontDescFileName.c_str(), "r");
if (aStream==NULL)
return false;
mSourceFile = theFontDescFileName;
int aSpaceWidth = 0;
fscanf(aStream,"%d%d",&aFontLayer->mCharData[' '].mWidth,&aFontLayer->mAscent);
while (!feof(aStream))
{
char aBuf[2] = { 0, 0 }; // needed because fscanf will null terminate the string it reads
char aChar = 0;
int aWidth = 0;
fscanf(aStream,"%1s%d",aBuf,&aWidth);
aChar = aBuf[0];
if (aChar == 0)
break;
aFontLayer->mCharData[(uchar) aChar].mImageRect = Rect(aCharPos, 0, aWidth, aFontLayer->mImage->GetHeight());
aFontLayer->mCharData[(uchar) aChar].mWidth = aWidth;
aCharPos += aWidth;
}
char c;
for (c = 'A'; c <= 'Z'; c++)
if ((aFontLayer->mCharData[c].mWidth == 0) && (aFontLayer->mCharData[c - 'A' + 'a'].mWidth != 0))
mCharMap[c] = c - 'A' + 'a';
for (c = 'a'; c <= 'z'; c++)
if ((aFontLayer->mCharData[c].mWidth == 0) && (aFontLayer->mCharData[c - 'a' + 'A'].mWidth != 0))
mCharMap[c] = c - 'a' + 'A';
mInitialized = true;
fclose(aStream);
return true;
}
////
ActiveFontLayer::ActiveFontLayer()
{
mScaledImage = NULL;
mOwnsImage = false;
}
ActiveFontLayer::ActiveFontLayer(const ActiveFontLayer& theActiveFontLayer) :
mBaseFontLayer(theActiveFontLayer.mBaseFontLayer),
mScaledImage(theActiveFontLayer.mScaledImage),
mOwnsImage(theActiveFontLayer.mOwnsImage)
{
if (mOwnsImage)
mScaledImage = mBaseFontLayer->mFontData->mApp->CopyImage(mScaledImage);
for (int aCharNum = 0; aCharNum < 256; aCharNum++)
mScaledCharImageRects[aCharNum] = theActiveFontLayer.mScaledCharImageRects[aCharNum];
}
ActiveFontLayer::~ActiveFontLayer()
{
if (mOwnsImage)
delete mScaledImage;
}
////
ImageFont::ImageFont(SexyAppBase* theSexyApp, const std::string& theFontDescFileName)
{
mScale = 1.0;
mFontData = new FontData();
mFontData->Ref();
mFontData->Load(theSexyApp, theFontDescFileName);
mPointSize = mFontData->mDefaultPointSize;
GenerateActiveFontLayers();
mActiveListValid = true;
mForceScaledImagesWhite = false;
}
ImageFont::ImageFont(Image *theFontImage)
{
mScale = 1.0;
mFontData = new FontData();
mFontData->Ref();
mFontData->mInitialized = true;
mPointSize = mFontData->mDefaultPointSize;
mActiveListValid = false;
mForceScaledImagesWhite = false;
mFontData->mFontLayerList.push_back(FontLayer(mFontData));
FontLayer* aFontLayer = &mFontData->mFontLayerList.back();
mFontData->mFontLayerMap.insert(FontLayerMap::value_type("", aFontLayer)).first;
aFontLayer->mImage = (MemoryImage*) theFontImage;
aFontLayer->mDefaultHeight = aFontLayer->mImage->GetHeight();
aFontLayer->mAscent = aFontLayer->mImage->GetHeight();
}
ImageFont::ImageFont(const ImageFont& theImageFont) :
Font(theImageFont),
mScale(theImageFont.mScale),
mFontData(theImageFont.mFontData),
mPointSize(theImageFont.mPointSize),
mTagVector(theImageFont.mTagVector),
mActiveListValid(theImageFont.mActiveListValid),
mForceScaledImagesWhite(theImageFont.mForceScaledImagesWhite)
{
mFontData->Ref();
if (mActiveListValid)
mActiveLayerList = theImageFont.mActiveLayerList;
}
ImageFont::ImageFont(Image* theFontImage, const std::string& theFontDescFileName)
{
mScale = 1.0;
mFontData = new FontData();
mFontData->Ref();
mFontData->LoadLegacy(theFontImage, theFontDescFileName);
mPointSize = mFontData->mDefaultPointSize;
GenerateActiveFontLayers();
mActiveListValid = true;
}
ImageFont::~ImageFont()
{
mFontData->DeRef();
}
/*ImageFont::ImageFont(const ImageFont& theImageFont, Image* theImage) :
Font(theImageFont),
mImage(theImage)
{
for (int i = 0; i < 256; i++)
{
mCharPos[i] = theImageFont.mCharPos[i];
mCharWidth[i] = theImageFont.mCharWidth[i];
}
}*/
void ImageFont::GenerateActiveFontLayers()
{
if (!mFontData->mInitialized)
return;
mActiveLayerList.clear();
ulong i;
mAscent = 0;
mAscentPadding = 0;
mHeight = 0;
mLineSpacingOffset = 0;
FontLayerList::iterator anItr = mFontData->mFontLayerList.begin();
bool firstLayer = true;
while (anItr != mFontData->mFontLayerList.end())
{
FontLayer* aFontLayer = &*anItr;
if ((mPointSize >= aFontLayer->mMinPointSize) &&
((mPointSize <= aFontLayer->mMaxPointSize) || (aFontLayer->mMaxPointSize == -1)))
{
bool active = true;
// Make sure all required tags are included
for (i = 0; i < aFontLayer->mRequiredTags.size(); i++)
if (std::find(mTagVector.begin(), mTagVector.end(), aFontLayer->mRequiredTags[i]) == mTagVector.end())
active = false;
// Make sure no excluded tags are included
for (i = 0; i < mTagVector.size(); i++)
if (std::find(aFontLayer->mExcludedTags.begin(), aFontLayer->mExcludedTags.end(),
mTagVector[i]) != aFontLayer->mExcludedTags.end())
active = false;
if (active)
{
mActiveLayerList.push_back(ActiveFontLayer());
ActiveFontLayer* anActiveFontLayer = &mActiveLayerList.back();
anActiveFontLayer->mBaseFontLayer = aFontLayer;
double aLayerPointSize = 1;
double aPointSize = mScale;
if ((mScale == 1.0) && ((aFontLayer->mPointSize == 0) || (mPointSize == aFontLayer->mPointSize)))
{
anActiveFontLayer->mScaledImage = aFontLayer->mImage;
anActiveFontLayer->mOwnsImage = false;
// Use the specified point size
for (int aCharNum = 0; aCharNum < 256; aCharNum++)
anActiveFontLayer->mScaledCharImageRects[aCharNum] = aFontLayer->mCharData[aCharNum].mImageRect;
}
else
{
if (aFontLayer->mPointSize != 0)
{
aLayerPointSize = aFontLayer->mPointSize;
aPointSize = mPointSize * mScale;
}
// Resize font elements
int aCharNum;
MemoryImage* aMemoryImage = new MemoryImage(mFontData->mApp);
int aCurX = 0;
int aMaxHeight = 0;
for (aCharNum = 0; aCharNum < 256; aCharNum++)
{
Rect* anOrigRect = &aFontLayer->mCharData[aCharNum].mImageRect;
Rect aScaledRect(aCurX, 0,
(int) ((anOrigRect->mWidth * aPointSize) / aLayerPointSize),
(int) ((anOrigRect->mHeight * aPointSize) / aLayerPointSize));
anActiveFontLayer->mScaledCharImageRects[aCharNum] = aScaledRect;
if (aScaledRect.mHeight > aMaxHeight)
aMaxHeight = aScaledRect.mHeight;
aCurX += aScaledRect.mWidth;
}
anActiveFontLayer->mScaledImage = aMemoryImage;
anActiveFontLayer->mOwnsImage = true;
// Create the image now
aMemoryImage->Create(aCurX, aMaxHeight);
Graphics g(aMemoryImage);
for (aCharNum = 0; aCharNum < 256; aCharNum++)
{
if ((Image*) aFontLayer->mImage != NULL)
g.DrawImage(aFontLayer->mImage, anActiveFontLayer->mScaledCharImageRects[aCharNum],
aFontLayer->mCharData[aCharNum].mImageRect);
}
if (mForceScaledImagesWhite)
{
int aCount = aMemoryImage->mWidth*aMemoryImage->mHeight;
ulong* aBits = aMemoryImage->GetBits();
for (int i = 0; i < aCount; i++)
*(aBits++) = *aBits | 0x00FFFFFF;
}
aMemoryImage->Palletize();
}
int aLayerAscent = (aFontLayer->mAscent * aPointSize) / aLayerPointSize;
if (aLayerAscent > mAscent)
mAscent = aLayerAscent;
if (aFontLayer->mHeight != 0)
{
int aLayerHeight = (aFontLayer->mHeight * aPointSize) / aLayerPointSize;
if (aLayerHeight > mHeight)
mHeight = aLayerHeight;
}
else
{
int aLayerHeight = (aFontLayer->mDefaultHeight * aPointSize) / aLayerPointSize;
if (aLayerHeight > mHeight)
mHeight = aLayerHeight;
}
int anAscentPadding = (aFontLayer->mAscentPadding * aPointSize) / aLayerPointSize;
if ((firstLayer) || (anAscentPadding < mAscentPadding))
mAscentPadding = anAscentPadding;
int aLineSpacingOffset = (aFontLayer->mLineSpacingOffset * aPointSize) / aLayerPointSize;
if ((firstLayer) || (aLineSpacingOffset > mLineSpacingOffset))
mLineSpacingOffset = aLineSpacingOffset;
firstLayer = false;
}
}
++anItr;
}
}
int ImageFont::StringWidth(const SexyString& theString)
{
int aWidth = 0;
char aPrevChar = 0;
for(int i=0; i<(int)theString.length(); i++)
{
char aChar = theString[i];
aWidth += CharWidthKern(aChar,aPrevChar);
aPrevChar = aChar;
}
return aWidth;
}
int ImageFont::CharWidthKern(char theChar, char thePrevChar)
{
Prepare();
int aMaxXPos = 0;
double aPointSize = mPointSize * mScale;
theChar = mFontData->mCharMap[(uchar)theChar];
if (thePrevChar != 0)
thePrevChar = mFontData->mCharMap[(uchar)thePrevChar];
ActiveFontLayerList::iterator anItr = mActiveLayerList.begin();
while (anItr != mActiveLayerList.end())
{
ActiveFontLayer* anActiveFontLayer = &*anItr;
int aLayerXPos = 0;
int aCharWidth;
int aSpacing;
int aLayerPointSize = anActiveFontLayer->mBaseFontLayer->mPointSize;
if (aLayerPointSize == 0)
{
aCharWidth = anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) theChar].mWidth * mScale;
if (thePrevChar != 0)
{
aSpacing = (anActiveFontLayer->mBaseFontLayer->mSpacing +
anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) thePrevChar].mKerningOffsets[(uchar) theChar]) * mScale;
}
else
aSpacing = 0;
}
else
{
aCharWidth = (anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) theChar].mWidth * aPointSize / aLayerPointSize);
if (thePrevChar != 0)
{
aSpacing = (anActiveFontLayer->mBaseFontLayer->mSpacing +
anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) thePrevChar].mKerningOffsets[(uchar) theChar]) * aPointSize / aLayerPointSize;
}
else
aSpacing = 0;
}
aLayerXPos += aCharWidth + aSpacing;
if (aLayerXPos > aMaxXPos)
aMaxXPos = aLayerXPos;
++anItr;
}
return aMaxXPos;
}
int ImageFont::CharWidth(char theChar)
{
return CharWidthKern(theChar,0);
}
CritSect gRenderCritSec;
static const int POOL_SIZE = 4096;
static RenderCommand gRenderCommandPool[POOL_SIZE];
static RenderCommand* gRenderTail[256];
static RenderCommand* gRenderHead[256];
void ImageFont::DrawStringEx(Graphics* g, int theX, int theY, const SexyString& theString, const Color& theColor, const Rect* theClipRect, RectList* theDrawnAreas, int* theWidth)
{
AutoCrit anAutoCrit(gRenderCritSec);
int aPoolIdx;
for (aPoolIdx = 0; aPoolIdx < 256; aPoolIdx++)
{
gRenderHead[aPoolIdx] = NULL;
gRenderTail[aPoolIdx] = NULL;
}
int aXPos = theX;
if (theDrawnAreas != NULL)
theDrawnAreas->clear();
/*if (theDrawnArea != NULL)
*theDrawnArea = Rect(0, 0, 0, 0);*/
if (!mFontData->mInitialized)
{
if (theWidth != NULL)
*theWidth = 0;
return;
}
Prepare();
bool colorizeImages = g->GetColorizeImages();
g->SetColorizeImages(true);
int aCurXPos = theX;
int aCurPoolIdx = 0;
for (ulong aCharNum = 0; aCharNum < theString.length(); aCharNum++)
{
char aChar = mFontData->mCharMap[(uchar) theString[aCharNum]];
char aNextChar = 0;
if (aCharNum < theString.length() - 1)
aNextChar = mFontData->mCharMap[(uchar) theString[aCharNum+1]];
int aMaxXPos = aCurXPos;
ActiveFontLayerList::iterator anItr = mActiveLayerList.begin();
while (anItr != mActiveLayerList.end())
{
ActiveFontLayer* anActiveFontLayer = &*anItr;
int aLayerXPos = aCurXPos;
int anImageX;
int anImageY;
int aCharWidth;
int aSpacing;
int aLayerPointSize = anActiveFontLayer->mBaseFontLayer->mPointSize;
double aScale = mScale;
if (aLayerPointSize != 0)
aScale *= mPointSize / aLayerPointSize;
if (aScale == 1.0)
{
anImageX = aLayerXPos + anActiveFontLayer->mBaseFontLayer->mOffset.mX + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mX;
anImageY = theY - (anActiveFontLayer->mBaseFontLayer->mAscent - anActiveFontLayer->mBaseFontLayer->mOffset.mY - anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mY);
aCharWidth = anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mWidth;
if (aNextChar != 0)
{
aSpacing = anActiveFontLayer->mBaseFontLayer->mSpacing +
anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mKerningOffsets[(uchar) aNextChar];
}
else
aSpacing = 0;
}
else
{
anImageX = aLayerXPos + (int) ((anActiveFontLayer->mBaseFontLayer->mOffset.mX + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mX) * aScale);
anImageY = theY - (int) ((anActiveFontLayer->mBaseFontLayer->mAscent - anActiveFontLayer->mBaseFontLayer->mOffset.mY - anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mY) * aScale);
aCharWidth = (anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mWidth * aScale);
if (aNextChar != 0)
{
aSpacing = (int) ((anActiveFontLayer->mBaseFontLayer->mSpacing +
anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mKerningOffsets[(uchar) aNextChar]) * aScale);
}
else
aSpacing = 0;
}
Color aColor;
aColor.mRed = min((theColor.mRed * anActiveFontLayer->mBaseFontLayer->mColorMult.mRed / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mRed, 255);
aColor.mGreen = min((theColor.mGreen * anActiveFontLayer->mBaseFontLayer->mColorMult.mGreen / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mGreen, 255);
aColor.mBlue = min((theColor.mBlue * anActiveFontLayer->mBaseFontLayer->mColorMult.mBlue / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mBlue, 255);
aColor.mAlpha = min((theColor.mAlpha * anActiveFontLayer->mBaseFontLayer->mColorMult.mAlpha / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mAlpha, 255);
int anOrder = anActiveFontLayer->mBaseFontLayer->mBaseOrder + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOrder;
if (aCurPoolIdx >= POOL_SIZE)
break;
RenderCommand* aRenderCommand = &gRenderCommandPool[aCurPoolIdx++];
aRenderCommand->mImage = anActiveFontLayer->mScaledImage;
aRenderCommand->mColor = aColor;
aRenderCommand->mDest[0] = anImageX;
aRenderCommand->mDest[1] = anImageY;
aRenderCommand->mSrc[0] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mX;
aRenderCommand->mSrc[1] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mY;
aRenderCommand->mSrc[2] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mWidth;
aRenderCommand->mSrc[3] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mHeight;
aRenderCommand->mMode = anActiveFontLayer->mBaseFontLayer->mDrawMode;
aRenderCommand->mNext = NULL;
int anOrderIdx = min(max(anOrder + 128, 0), 255);
if (gRenderTail[anOrderIdx] == NULL)
{
gRenderTail[anOrderIdx] = aRenderCommand;
gRenderHead[anOrderIdx] = aRenderCommand;
}
else
{
gRenderTail[anOrderIdx]->mNext = aRenderCommand;
gRenderTail[anOrderIdx] = aRenderCommand;
}
//aRenderCommandMap.insert(RenderCommandMap::value_type(aPriority, aRenderCommand));
/*int anOldDrawMode = g->GetDrawMode();
if (anActiveFontLayer->mBaseFontLayer->mDrawMode != -1)
g->SetDrawMode(anActiveFontLayer->mBaseFontLayer->mDrawMode);
Color anOrigColor = g->GetColor();
g->SetColor(aColor);
if (anActiveFontLayer->mScaledImage != NULL)
g->DrawImage(anActiveFontLayer->mScaledImage, anImageX, anImageY, anActiveFontLayer->mScaledCharImageRects[aChar]);
g->SetColor(anOrigColor);
g->SetDrawMode(anOldDrawMode);*/
if (theDrawnAreas != NULL)
{
Rect aDestRect = Rect(anImageX, anImageY, anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mWidth, anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mHeight);
theDrawnAreas->push_back(aDestRect);
/*if (theDrawnArea->mWidth == 0)
*theDrawnArea = theDestRect;
else
{
if (theDestRect.mX < theDrawnArea->mX)
{
int aDiff = theDestRect.mX - theDrawnArea->mX;
theDrawnArea->mX += aDiff;
theDrawnArea->mWidth += aDiff;
}
if (theDestRect.mX + theDestRect.mWidth > theDrawnArea->mX + theDrawnArea->mWidth)
theDrawnArea->mWidth = theDestRect.mX + theDestRect.mWidth - theDrawnArea->mX;
if (theDestRect.mY < theDrawnArea->mY)
{
int aDiff = theDestRect.mY - theDrawnArea->mY;
theDrawnArea->mY += aDiff;
theDrawnArea->mHeight += aDiff;
}
if (theDestRect.mY + theDestRect.mHeight > theDrawnArea->mY + theDrawnArea->mHeight)
theDrawnArea->mHeight = theDestRect.mY + theDestRect.mHeight - theDrawnArea->mY;
}*/
}
aLayerXPos += aCharWidth + aSpacing;
if (aLayerXPos > aMaxXPos)
aMaxXPos = aLayerXPos;
++anItr;
}
aCurXPos = aMaxXPos;
}
if (theWidth != NULL)
*theWidth = aCurXPos - theX;
Color anOrigColor = g->GetColor();
for (aPoolIdx = 0; aPoolIdx < 256; aPoolIdx++)
{
RenderCommand* aRenderCommand = gRenderHead[aPoolIdx];
while (aRenderCommand != NULL)
{
int anOldDrawMode = g->GetDrawMode();
if (aRenderCommand->mMode != -1)
g->SetDrawMode(aRenderCommand->mMode);
g->SetColor(Color(aRenderCommand->mColor));
if (aRenderCommand->mImage != NULL)
g->DrawImage(aRenderCommand->mImage, aRenderCommand->mDest[0], aRenderCommand->mDest[1], Rect(aRenderCommand->mSrc[0], aRenderCommand->mSrc[1], aRenderCommand->mSrc[2], aRenderCommand->mSrc[3]));
g->SetDrawMode(anOldDrawMode);
aRenderCommand = aRenderCommand->mNext;
}
}
g->SetColor(anOrigColor);
/*RenderCommandMap::iterator anItr = aRenderCommandMap.begin();
while (anItr != aRenderCommandMap.end())
{
RenderCommand* aRenderCommand = &anItr->second;
int anOldDrawMode = g->GetDrawMode();
if (aRenderCommand->mMode != -1)
g->SetDrawMode(aRenderCommand->mMode);
Color anOrigColor = g->GetColor();
g->SetColor(aRenderCommand->mColor);
if (aRenderCommand->mImage != NULL)
g->DrawImage(aRenderCommand->mImage, aRenderCommand->mDest.mX, aRenderCommand->mDest.mY, aRenderCommand->mSrc);
g->SetColor(anOrigColor);
g->SetDrawMode(anOldDrawMode);
++anItr;
}*/
g->SetColorizeImages(colorizeImages);
}
void ImageFont::DrawString(Graphics* g, int theX, int theY, const SexyString& theString, const Color& theColor, const Rect& theClipRect)
{
DrawStringEx(g, theX, theY, theString, theColor, &theClipRect, NULL, NULL);
}
Font* ImageFont::Duplicate()
{
return new ImageFont(*this);
}
void ImageFont::SetPointSize(int thePointSize)
{
mPointSize = thePointSize;
mActiveListValid = false;
}
void ImageFont::SetScale(double theScale)
{
mScale = theScale;
mActiveListValid = false;
}
int ImageFont::GetPointSize()
{
return mPointSize;
}
int ImageFont::GetDefaultPointSize()
{
return mFontData->mDefaultPointSize;
}
bool ImageFont::AddTag(const std::string& theTagName)
{
if (HasTag(theTagName))
return false;
std::string aTagName = StringToUpper(theTagName);
mTagVector.push_back(aTagName);
mActiveListValid = false;
return true;
}
bool ImageFont::RemoveTag(const std::string& theTagName)
{
std::string aTagName = StringToUpper(theTagName);
StringVector::iterator anItr = std::find(mTagVector.begin(), mTagVector.end(), aTagName);
if (anItr == mTagVector.end())
return false;
mTagVector.erase(anItr);
mActiveListValid = false;
return true;
}
bool ImageFont::HasTag(const std::string& theTagName)
{
StringVector::iterator anItr = std::find(mTagVector.begin(), mTagVector.end(), theTagName);
return anItr != mTagVector.end();
}
std::string ImageFont::GetDefine(const std::string& theName)
{
DataElement* aDataElement = mFontData->Dereference(theName);
if (aDataElement == NULL)
return "";
return mFontData->DataElementToString(aDataElement);
}
void ImageFont::Prepare()
{
if (!mActiveListValid)
{
GenerateActiveFontLayers();
mActiveListValid = true;
}
}