Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
#include "ImageFont.h"
2
#include "Graphics.h"
3
#include "Image.h"
4
#include "SexyAppBase.h"
5
#include "MemoryImage.h"
6
#include "..\SexyAppFramework\AutoCrit.h"
7
 
8
using namespace Sexy;
9
 
10
////
11
 
12
DataElement::DataElement() :
13
        mIsList(false)
14
{      
15
}
16
 
17
DataElement::~DataElement()
18
{
19
}
20
 
21
SingleDataElement::SingleDataElement()
22
{      
23
        mIsList = false;
24
}
25
 
26
SingleDataElement::SingleDataElement(const std::string theString) :    
27
        mString(theString)
28
{      
29
        mIsList = false;
30
}
31
 
32
SingleDataElement::~SingleDataElement()
33
{      
34
}
35
 
36
DataElement* SingleDataElement::Duplicate()
37
{
38
        SingleDataElement* aSingleDataElement = new SingleDataElement(*this);
39
        return aSingleDataElement;
40
}
41
 
42
ListDataElement::ListDataElement()     
43
{      
44
        mIsList = true;
45
}
46
 
47
ListDataElement::~ListDataElement()
48
{
49
        for (ulong i = 0; i < mElementVector.size(); i++)
50
                delete mElementVector[i];
51
}
52
 
53
ListDataElement::ListDataElement(const ListDataElement& theListDataElement)
54
{
55
        mIsList = true;
56
        for (ulong i = 0; i < theListDataElement.mElementVector.size(); i++)
57
                mElementVector.push_back(theListDataElement.mElementVector[i]->Duplicate());
58
}
59
 
60
ListDataElement& ListDataElement::operator=(const ListDataElement& theListDataElement)
61
{
62
        ulong i;
63
 
64
        for (i = 0; i < mElementVector.size(); i++)
65
                delete mElementVector[i];
66
        mElementVector.clear();
67
 
68
        for (i = 0; i < theListDataElement.mElementVector.size(); i++)
69
                mElementVector.push_back(theListDataElement.mElementVector[i]->Duplicate());
70
 
71
        return *this;
72
}
73
 
74
DataElement* ListDataElement::Duplicate()
75
{
76
        ListDataElement* aListDataElement = new ListDataElement(*this);
77
        return aListDataElement;
78
}
79
 
80
///
81
 
82
CharData::CharData()
83
{
84
        mWidth = 0;
85
        mOrder = 0;
86
 
87
        for (ulong i = 0; i < 256; i++)
88
                mKerningOffsets[i] = 0;
89
}
90
 
91
FontLayer::FontLayer(FontData* theFontData)
92
{      
93
        mFontData = theFontData;       
94
        mDrawMode = -1;
95
        mSpacing = 0;
96
        mPointSize = 0;
97
        mAscent = 0;
98
        mAscentPadding = 0;
99
        mMinPointSize = -1;
100
        mMaxPointSize = -1;    
101
        mHeight = 0;
102
        mDefaultHeight = 0;
103
        mColorMult = Color::White;
104
        mColorAdd = Color(0, 0, 0, 0);
105
        mLineSpacingOffset = 0;
106
        mBaseOrder = 0;
107
}
108
 
109
FontLayer::FontLayer(const FontLayer& theFontLayer) :  
110
        mFontData(theFontLayer.mFontData),
111
        mRequiredTags(theFontLayer.mRequiredTags),
112
        mExcludedTags(theFontLayer.mExcludedTags),
113
        mImage(theFontLayer.mImage),
114
        mDrawMode(theFontLayer.mDrawMode),
115
        mOffset(theFontLayer.mOffset),
116
        mSpacing(theFontLayer.mSpacing),
117
        mMinPointSize(theFontLayer.mMinPointSize),
118
        mMaxPointSize(theFontLayer.mMaxPointSize),
119
        mPointSize(theFontLayer.mPointSize),
120
        mAscent(theFontLayer.mAscent),
121
        mAscentPadding(theFontLayer.mAscentPadding),
122
        mHeight(theFontLayer.mHeight),
123
        mDefaultHeight(theFontLayer.mDefaultHeight),
124
        mColorMult(theFontLayer.mColorMult),
125
        mColorAdd(theFontLayer.mColorAdd),
126
        mLineSpacingOffset(theFontLayer.mLineSpacingOffset),
127
        mBaseOrder(theFontLayer.mBaseOrder)
128
{
129
        ulong i;
130
 
131
        for (i = 0; i < 256; i++)
132
                mCharData[i] = theFontLayer.mCharData[i];      
133
}
134
 
135
FontData::FontData()
136
{
137
        mInitialized = false;
138
 
139
        mApp = NULL;
140
        mRefCount = 0;
141
        mDefaultPointSize = 0;
142
 
143
        for (ulong i = 0; i < 256; i++)
144
                mCharMap[i] = (uchar) i;
145
}
146
 
147
FontData::~FontData()
148
{
149
        DataElementMap::iterator anItr = mDefineMap.begin();
150
        while (anItr != mDefineMap.end())
151
        {
152
                std::string aDefineName = anItr->first;
153
                DataElement* aDataElement = anItr->second;
154
 
155
                delete aDataElement;
156
                ++anItr;
157
        }
158
}
159
 
160
void FontData::Ref()
161
{
162
        mRefCount++;
163
}
164
 
165
void FontData::DeRef()
166
{
167
        if (--mRefCount == 0)
168
        {
169
                delete this;
170
        }
171
}
172
 
173
bool FontData::Error(const std::string& theError)
174
{
175
        if (mApp != NULL)
176
        {
177
                std::string anErrorString = mFontErrorHeader + theError;
178
 
179
                if (mCurrentLine.length() > 0)
180
                {
181
                        anErrorString += " on Line " + StrFormat("%d:\r\n\r\n", mCurrentLineNum) + mCurrentLine;
182
                }
183
 
184
                mApp->Popup(anErrorString);
185
        }
186
 
187
        return false;
188
}
189
 
190
bool FontData::DataToLayer(DataElement* theSource, FontLayer** theFontLayer)
191
{
192
        *theFontLayer = NULL;
193
 
194
        if (theSource->mIsList)
195
                return false;
196
 
197
        std::string aLayerName = StringToUpper(((SingleDataElement*) theSource)->mString);
198
 
199
        FontLayerMap::iterator anItr = mFontLayerMap.find(aLayerName);
200
        if (anItr == mFontLayerMap.end())
201
        {
202
                Error("Undefined Layer");
203
                return false;
204
        }
205
 
206
        *theFontLayer = anItr->second;
207
 
208
        return true;
209
}
210
 
211
bool FontData::GetColorFromDataElement(DataElement *theElement, Color &theColor)
212
{
213
        if (theElement->mIsList)
214
        {                              
215
                DoubleVector aFactorVector;                                    
216
                if (!DataToDoubleVector(theElement, &aFactorVector) && (aFactorVector.size() == 4))
217
                        return false;
218
 
219
                theColor = Color(
220
                        (int) (aFactorVector[0] * 255),
221
                        (int) (aFactorVector[1] * 255),
222
                        (int) (aFactorVector[2] * 255),
223
                        (int) (aFactorVector[3] * 255));
224
 
225
                return true;
226
        }
227
 
228
        int aColor = 0;
229
        if (!StringToInt(((SingleDataElement*) theElement)->mString, &aColor))
230
                return false;
231
 
232
        theColor = aColor;
233
        return true;
234
}
235
 
236
 
237
bool FontData::HandleCommand(const ListDataElement& theParams) 
238
{
239
        std::string aCmd = ((SingleDataElement*) theParams.mElementVector[0])->mString;
240
 
241
        bool invalidNumParams = false;
242
        bool invalidParamFormat = false;
243
        bool literalError = false;
244
        bool sizeMismatch = false;
245
 
246
        if (stricmp(aCmd.c_str(), "Define") == 0)
247
        {
248
                if (theParams.mElementVector.size() == 3)
249
                {
250
                        if (!theParams.mElementVector[1]->mIsList)
251
                        {
252
                                std::string aDefineName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
253
 
254
                                if (!IsImmediate(aDefineName))
255
                                {
256
                                        DataElementMap::iterator anItr = mDefineMap.find(aDefineName);
257
                                        if (anItr != mDefineMap.end())
258
                                        {
259
                                                delete anItr->second;
260
                                                mDefineMap.erase(anItr);
261
                                        }
262
 
263
                                        if (theParams.mElementVector[2]->mIsList)
264
                                        {
265
                                                ListDataElement* aValues = new ListDataElement();
266
                                                if (!GetValues(((ListDataElement*) theParams.mElementVector[2]), aValues))
267
                                                {
268
                                                        delete aValues;
269
                                                        return false;
270
                                                }
271
 
272
                                                mDefineMap.insert(DataElementMap::value_type(aDefineName, aValues));
273
                                        }
274
                                        else
275
                                        {                                                      
276
                                                SingleDataElement* aDefParam = (SingleDataElement*) theParams.mElementVector[2];
277
 
278
                                                DataElement* aDerefVal = Dereference(aDefParam->mString);
279
 
280
                                                if (aDerefVal)
281
                                                        mDefineMap.insert(DataElementMap::value_type(aDefineName, aDerefVal->Duplicate()));
282
                                                else
283
                                                        mDefineMap.insert(DataElementMap::value_type(aDefineName, aDefParam->Duplicate()));
284
                                        }
285
                                }
286
                                else
287
                                        invalidParamFormat = true;
288
                        }
289
                        else
290
                                invalidParamFormat = true;
291
                }
292
                else
293
                        invalidNumParams = true;
294
        }
295
        else if (stricmp(aCmd.c_str(), "CreateHorzSpanRectList") == 0)
296
        {
297
                if (theParams.mElementVector.size() == 4)
298
                {      
299
                        IntVector aRectIntVector;
300
                        IntVector aWidthsVector;                                                                                                               
301
 
302
                        if ((!theParams.mElementVector[1]->mIsList) &&
303
                                (DataToIntVector(theParams.mElementVector[2], &aRectIntVector)) &&
304
                                (aRectIntVector.size() == 4) &&
305
                                (DataToIntVector(theParams.mElementVector[3], &aWidthsVector)))
306
                        {
307
                                std::string aDefineName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);  
308
 
309
                                int aXPos = 0;
310
 
311
                                ListDataElement* aRectList = new ListDataElement();
312
 
313
                                for (ulong aWidthNum = 0; aWidthNum < aWidthsVector.size(); aWidthNum++)
314
                                {                                                      
315
                                        ListDataElement* aRectElement = new ListDataElement();
316
                                        aRectList->mElementVector.push_back(aRectElement);
317
 
318
                                        char aStr[256];
319
 
320
                                        sprintf(aStr, "%d", aRectIntVector[0] + aXPos);
321
                                        aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
322
 
323
                                        sprintf(aStr, "%d", aRectIntVector[1]);
324
                                        aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
325
 
326
                                        sprintf(aStr, "%d", aWidthsVector[aWidthNum]);
327
                                        aRectElement->mElementVector.push_back(new SingleDataElement(aStr));
328
 
329
                                        sprintf(aStr, "%d", aRectIntVector[3]);
330
                                        aRectElement->mElementVector.push_back(new SingleDataElement(aStr));                                                           
331
 
332
                                        aXPos += aWidthsVector[aWidthNum];
333
                                }
334
 
335
                                DataElementMap::iterator anItr = mDefineMap.find(aDefineName);
336
                                if (anItr != mDefineMap.end())
337
                                {
338
                                        delete anItr->second;
339
                                        mDefineMap.erase(anItr);
340
                                }
341
 
342
                                mDefineMap.insert(DataElementMap::value_type(aDefineName, aRectList));
343
                        }
344
                        else
345
                                invalidParamFormat = true;
346
                }
347
                else
348
                        invalidNumParams = true;
349
        }
350
        else if (stricmp(aCmd.c_str(), "SetDefaultPointSize") == 0)
351
        {
352
                if (theParams.mElementVector.size() == 2)
353
                {                                      
354
                        int aPointSize;
355
 
356
                        if ((!theParams.mElementVector[1]->mIsList) &&
357
                                (StringToInt(((SingleDataElement*) theParams.mElementVector[1])->mString, &aPointSize)))
358
                        {                                                                                              
359
                                mDefaultPointSize = aPointSize;                                        
360
                        }
361
                        else
362
                                invalidParamFormat = true;
363
                }
364
                else
365
                        invalidNumParams = true;
366
        }
367
        else if (stricmp(aCmd.c_str(), "SetCharMap") == 0)
368
        {
369
                if (theParams.mElementVector.size() == 3)
370
                {
371
                        StringVector aFromVector;
372
                        StringVector aToVector;
373
 
374
                        if ((DataToStringVector(theParams.mElementVector[1], &aFromVector)) &&
375
                                (DataToStringVector(theParams.mElementVector[2], &aToVector)))
376
                        {                                              
377
                                if (aFromVector.size() == aToVector.size())
378
                                {
379
                                        for (ulong aMapIdx = 0; aMapIdx < aFromVector.size(); aMapIdx++)
380
                                        {
381
                                                if ((aFromVector[aMapIdx].length() == 1) && (aToVector[aMapIdx].length() == 1))
382
                                                {
383
                                                        mCharMap[(uchar) aFromVector[aMapIdx][0]] = (uchar) aToVector[aMapIdx][0];
384
                                                }
385
                                                else
386
                                                        invalidParamFormat = true;
387
                                        }
388
                                }
389
                                else                                           
390
                                        sizeMismatch = true;                                           
391
                        }
392
                        else
393
                                invalidParamFormat = true;
394
                }
395
                else
396
                        invalidNumParams = true;
397
        }
398
        else if (stricmp(aCmd.c_str(), "CreateLayer") == 0)
399
        {
400
                if (theParams.mElementVector.size() == 2)
401
                {
402
                        if (!theParams.mElementVector[1]->mIsList)
403
                        {
404
                                std::string aLayerName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
405
 
406
                                mFontLayerList.push_back(FontLayer(this));
407
                                FontLayer* aFontLayer = &mFontLayerList.back();
408
 
409
                                if (!mFontLayerMap.insert(FontLayerMap::value_type(aLayerName, aFontLayer)).second)
410
                                {
411
                                        Error("Layer Already Exists");                                                 
412
                                }
413
                        }
414
                        else
415
                                invalidParamFormat = true;
416
                }
417
                else
418
                        invalidNumParams = true;
419
        }
420
        else if (stricmp(aCmd.c_str(), "CreateLayerFrom") == 0)
421
        {
422
                if (theParams.mElementVector.size() == 3)
423
                {
424
                        FontLayer* aSourceLayer;
425
 
426
                        if ((!theParams.mElementVector[1]->mIsList) && (DataToLayer(theParams.mElementVector[2], &aSourceLayer)))
427
                        {
428
                                std::string aLayerName = StringToUpper(((SingleDataElement*) theParams.mElementVector[1])->mString);
429
 
430
                                mFontLayerList.push_back(FontLayer(*aSourceLayer));
431
                                FontLayer* aFontLayer = &mFontLayerList.back();
432
 
433
                                if (!mFontLayerMap.insert(FontLayerMap::value_type(aLayerName, aFontLayer)).second)
434
                                {
435
                                        Error("Layer Already Exists");                                                 
436
                                }
437
                        }
438
                        else
439
                                invalidParamFormat = true;
440
                }
441
                else
442
                        invalidNumParams = true;
443
        }
444
        else if (stricmp(aCmd.c_str(), "LayerRequireTags") == 0)
445
        {
446
                if (theParams.mElementVector.size() == 3)
447
                {
448
                        FontLayer* aLayer;
449
                        StringVector aStringVector;
450
 
451
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
452
                                (DataToStringVector(theParams.mElementVector[2], &aStringVector)))
453
                        {
454
                                for (ulong i = 0; i < aStringVector.size(); i++)
455
                                        aLayer->mRequiredTags.push_back(StringToUpper(aStringVector[i]));
456
                        }
457
                        else
458
                                invalidParamFormat = true;
459
                }
460
                else
461
                        invalidNumParams = true;
462
        }
463
        else if (stricmp(aCmd.c_str(), "LayerExcludeTags") == 0)
464
        {
465
                if (theParams.mElementVector.size() == 3)
466
                {
467
                        FontLayer* aLayer;
468
                        StringVector aStringVector;
469
 
470
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
471
                                (DataToStringVector(theParams.mElementVector[2], &aStringVector)))
472
                        {
473
                                for (ulong i = 0; i < aStringVector.size(); i++)
474
                                        aLayer->mExcludedTags.push_back(StringToUpper(aStringVector[i]));
475
                        }
476
                        else
477
                                invalidParamFormat = true;
478
                }
479
                else
480
                        invalidNumParams = true;
481
        }
482
        else if (stricmp(aCmd.c_str(), "LayerPointRange") == 0)
483
        {
484
                if (theParams.mElementVector.size() == 4)
485
                {
486
                        FontLayer* aLayer;
487
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
488
                                (!theParams.mElementVector[2]->mIsList) &&
489
                                (!theParams.mElementVector[3]->mIsList))
490
                        {
491
                                int aMinPointSize;
492
                                int aMaxPointSize;
493
 
494
                                if ((StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aMinPointSize)) &&
495
                                        (StringToInt(((SingleDataElement*) theParams.mElementVector[3])->mString, &aMaxPointSize)))
496
                                {
497
                                        aLayer->mMinPointSize = aMinPointSize;
498
                                        aLayer->mMaxPointSize = aMaxPointSize;
499
                                }
500
                                else
501
                                        invalidParamFormat = true;                                             
502
                        }
503
                        else
504
                                invalidParamFormat = true;
505
                }
506
                else
507
                        invalidNumParams = true;
508
        }
509
        else if (stricmp(aCmd.c_str(), "LayerSetPointSize") == 0)
510
        {
511
                if (theParams.mElementVector.size() == 3)
512
                {
513
                        FontLayer* aLayer;
514
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
515
                                (!theParams.mElementVector[2]->mIsList))
516
                        {
517
                                int aPointSize;
518
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aPointSize))
519
                                {
520
                                        aLayer->mPointSize = aPointSize;
521
                                }
522
                                else
523
                                        invalidParamFormat = true;                                             
524
                        }
525
                        else
526
                                invalidParamFormat = true;
527
                }
528
                else
529
                        invalidNumParams = true;
530
        }
531
        else if (stricmp(aCmd.c_str(), "LayerSetHeight") == 0)
532
        {
533
                if (theParams.mElementVector.size() == 3)
534
                {
535
                        FontLayer* aLayer;
536
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
537
                                (!theParams.mElementVector[2]->mIsList))
538
                        {
539
                                int aHeight;
540
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aHeight))
541
                                {
542
                                        aLayer->mHeight = aHeight;
543
                                }
544
                                else
545
                                        invalidParamFormat = true;                                             
546
                        }
547
                        else
548
                                invalidParamFormat = true;
549
                }
550
                else
551
                        invalidNumParams = true;
552
        }
553
        else if (stricmp(aCmd.c_str(), "LayerSetImage") == 0)
554
        {
555
                if (theParams.mElementVector.size() == 3)
556
                {
557
                        FontLayer* aLayer;
558
                        std::string aFileNameString;
559
 
560
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
561
                                (DataToString(theParams.mElementVector[2], &aFileNameString)))
562
                        {                                              
563
                                std::string aFileName = GetPathFrom(aFileNameString, GetFileDir(mSourceFile));
564
 
565
                                bool isNew;
566
                                SharedImageRef anImage = mApp->GetSharedImage(aFileName, "", &isNew);
567
 
568
                                if ((Image*) anImage != NULL)
569
                                {
570
                                        if (isNew)
571
                                                anImage->Palletize();
572
                                        aLayer->mImage = anImage;                                      
573
                                }
574
                                else
575
                                {
576
                                        Error("Failed to Load Image");
577
                                        return false;
578
                                }                              
579
                        }
580
                        else
581
                                invalidParamFormat = true;
582
                }
583
                else
584
                        invalidNumParams = true;
585
        }
586
        else if (stricmp(aCmd.c_str(), "LayerSetDrawMode") == 0)
587
        {
588
                if (theParams.mElementVector.size() == 3)
589
                {
590
                        FontLayer* aLayer;
591
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) && (!theParams.mElementVector[2]->mIsList))
592
                        {                                              
593
                                int anDrawMode;
594
                                if ((StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anDrawMode)) &&
595
                                        (anDrawMode >= 0) && (anDrawMode <= 1))
596
                                {
597
                                        aLayer->mDrawMode = anDrawMode;
598
                                }
599
                                else
600
                                        invalidParamFormat = true;                                             
601
                        }
602
                        else
603
                                invalidParamFormat = true;
604
                }
605
                else
606
                        invalidNumParams = true;
607
        }
608
        else if (stricmp(aCmd.c_str(), "LayerSetColorMult") == 0)
609
        {
610
                if (theParams.mElementVector.size() == 3)
611
                {
612
                        FontLayer* aLayer;
613
                        if (DataToLayer(theParams.mElementVector[1], &aLayer))
614
                        {
615
                                if (!GetColorFromDataElement(theParams.mElementVector[2],aLayer->mColorMult))
616
                                        invalidParamFormat = true;
617
                        }
618
                        else
619
                                invalidParamFormat = true;
620
                }
621
                else
622
                        invalidNumParams = true;
623
        }
624
        else if (stricmp(aCmd.c_str(), "LayerSetColorAdd") == 0)
625
        {
626
                if (theParams.mElementVector.size() == 3)
627
                {
628
                        FontLayer* aLayer;
629
                        if (DataToLayer(theParams.mElementVector[1], &aLayer))
630
                        {
631
                                if (!GetColorFromDataElement(theParams.mElementVector[2],aLayer->mColorAdd))
632
                                        invalidParamFormat = true;
633
                        }
634
                        else
635
                                invalidParamFormat = true;
636
                }
637
                else
638
                        invalidNumParams = true;
639
        }
640
        else if (stricmp(aCmd.c_str(), "LayerSetAscent") == 0)
641
        {
642
                if (theParams.mElementVector.size() == 3)
643
                {
644
                        FontLayer* aLayer;
645
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
646
                                (!theParams.mElementVector[2]->mIsList))
647
                        {
648
                                int anAscent;
649
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
650
                                {
651
                                        aLayer->mAscent = anAscent;
652
                                }
653
                                else
654
                                        invalidParamFormat = true;                                             
655
                        }
656
                        else
657
                                invalidParamFormat = true;
658
                }
659
                else
660
                        invalidNumParams = true;
661
        }
662
        else if (stricmp(aCmd.c_str(), "LayerSetAscentPadding") == 0)
663
        {
664
                if (theParams.mElementVector.size() == 3)
665
                {
666
                        FontLayer* aLayer;
667
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
668
                                (!theParams.mElementVector[2]->mIsList))
669
                        {
670
                                int anAscent;
671
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
672
                                {
673
                                        aLayer->mAscentPadding = anAscent;
674
                                }
675
                                else
676
                                        invalidParamFormat = true;                                             
677
                        }
678
                        else
679
                                invalidParamFormat = true;
680
                }
681
                else
682
                        invalidNumParams = true;
683
        }
684
        else if (stricmp(aCmd.c_str(), "LayerSetLineSpacingOffset") == 0)
685
        {
686
                if (theParams.mElementVector.size() == 3)
687
                {
688
                        FontLayer* aLayer;
689
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
690
                                (!theParams.mElementVector[2]->mIsList))
691
                        {
692
                                int anAscent;
693
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &anAscent))
694
                                {
695
                                        aLayer->mLineSpacingOffset = anAscent;
696
                                }
697
                                else
698
                                        invalidParamFormat = true;                                             
699
                        }
700
                        else
701
                                invalidParamFormat = true;
702
                }
703
                else
704
                        invalidNumParams = true;
705
        }
706
        else if (stricmp(aCmd.c_str(), "LayerSetOffset") == 0)
707
        {
708
                if (theParams.mElementVector.size() == 3)
709
                {
710
                        FontLayer* aLayer;
711
                        IntVector anOffset;
712
 
713
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) && (DataToIntVector(theParams.mElementVector[2], &anOffset)) && (anOffset.size() == 2))
714
                        {
715
                                aLayer->mOffset.mX = anOffset[0];
716
                                aLayer->mOffset.mY = anOffset[1];
717
                        }
718
                        else
719
                                invalidParamFormat = true;
720
                }
721
                else
722
                        invalidNumParams = true;
723
        }
724
        else if (stricmp(aCmd.c_str(), "LayerSetCharWidths") == 0)
725
        {
726
                if (theParams.mElementVector.size() == 4)
727
                {
728
                        FontLayer* aLayer;
729
                        StringVector aCharsVector;
730
                        IntVector aCharWidthsVector;
731
 
732
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
733
                                (DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
734
                                (DataToIntVector(theParams.mElementVector[3], &aCharWidthsVector)))
735
                        {
736
                                if (aCharsVector.size() == aCharWidthsVector.size())
737
                                {
738
                                        for (ulong i = 0; i < aCharsVector.size(); i++)
739
                                        {
740
                                                if (aCharsVector[i].length() == 1)
741
                                                {
742
                                                        aLayer->mCharData[(uchar) aCharsVector[i][0]].mWidth =
743
                                                                aCharWidthsVector[i];
744
                                                }
745
                                                else
746
                                                        invalidParamFormat = true;
747
                                        }
748
                                }
749
                                else
750
                                        sizeMismatch = true;
751
                        }
752
                        else
753
                                invalidParamFormat = true;
754
                }
755
                else
756
                        invalidNumParams = true;
757
        }
758
        else if (stricmp(aCmd.c_str(), "LayerSetSpacing") == 0)
759
        {
760
                if (theParams.mElementVector.size() == 3)
761
                {
762
                        FontLayer* aLayer;
763
                        IntVector anOffset;
764
 
765
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
766
                                (!theParams.mElementVector[2]->mIsList))
767
                        {
768
                                int aSpacing;
769
 
770
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aSpacing))
771
                                {
772
                                        aLayer->mSpacing = aSpacing;
773
                                }
774
                                else
775
                                        invalidParamFormat = true;
776
                        }
777
                        else
778
                                invalidParamFormat = true;
779
                }
780
                else
781
                        invalidNumParams = true;
782
        }
783
        else if (stricmp(aCmd.c_str(), "LayerSetImageMap") == 0)
784
        {
785
                if (theParams.mElementVector.size() == 4)
786
                {
787
                        FontLayer* aLayer;
788
                        StringVector aCharsVector;
789
                        ListDataElement aRectList;
790
 
791
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
792
                                (DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
793
                                (DataToList(theParams.mElementVector[3], &aRectList)))
794
                        {                                                                                                      
795
                                if (aCharsVector.size() == aRectList.mElementVector.size())
796
                                {
797
                                        if ((Image*) aLayer->mImage != NULL)
798
                                        {
799
                                                int anImageWidth = aLayer->mImage->GetWidth();
800
                                                int anImageHeight = aLayer->mImage->GetHeight();
801
 
802
                                                for (ulong i = 0; i < aCharsVector.size(); i++)
803
                                                {
804
                                                        IntVector aRectElement;
805
 
806
                                                        if ((aCharsVector[i].length() == 1) &&
807
                                                                (DataToIntVector(aRectList.mElementVector[i], &aRectElement)) &&
808
                                                                (aRectElement.size() == 4))
809
 
810
                                                        {
811
                                                                Rect aRect = Rect(aRectElement[0], aRectElement[1], aRectElement[2], aRectElement[3]);
812
 
813
                                                                if ((aRect.mX < 0) || (aRect.mY < 0) ||
814
                                                                        (aRect.mX + aRect.mWidth > anImageWidth) || (aRect.mY + aRect.mHeight > anImageHeight))
815
                                                                {
816
                                                                        Error("Image rectangle out of bounds");
817
                                                                        return false;
818
                                                                }
819
 
820
                                                                aLayer->mCharData[(uchar) aCharsVector[i][0]].mImageRect = aRect;;                                                                     
821
                                                        }
822
                                                        else
823
                                                                invalidParamFormat = true;
824
                                                }
825
 
826
                                                aLayer->mDefaultHeight = 0;
827
                                                for (int aCharNum = 0; aCharNum < 256; aCharNum++)
828
                                                        if (aLayer->mCharData[aCharNum].mImageRect.mHeight + aLayer->mCharData[aCharNum].mOffset.mY > aLayer->mDefaultHeight)
829
                                                                aLayer->mDefaultHeight = aLayer->mCharData[aCharNum].mImageRect.mHeight + aLayer->mCharData[aCharNum].mOffset.mY;
830
                                        }
831
                                        else
832
                                        {
833
                                                Error("Layer image not set");
834
                                                return false;
835
                                        }
836
                                }
837
                                else
838
                                        sizeMismatch = true;
839
                        }
840
                        else
841
                                invalidParamFormat = true;
842
                }
843
                else
844
                        invalidNumParams = true;
845
        }
846
        else if (stricmp(aCmd.c_str(), "LayerSetCharOffsets") == 0)
847
        {
848
                if (theParams.mElementVector.size() == 4)
849
                {
850
                        FontLayer* aLayer;
851
                        StringVector aCharsVector;
852
                        ListDataElement aRectList;
853
 
854
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
855
                                (DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
856
                                (DataToList(theParams.mElementVector[3], &aRectList)))
857
                        {      
858
                                if (aCharsVector.size() == aRectList.mElementVector.size())
859
                                {
860
                                        for (ulong i = 0; i < aCharsVector.size(); i++)
861
                                        {
862
                                                IntVector aRectElement;
863
 
864
                                                if ((aCharsVector[i].length() == 1) &&
865
                                                        (DataToIntVector(aRectList.mElementVector[i], &aRectElement)) &&
866
                                                        (aRectElement.size() == 2))
867
                                                {
868
                                                        aLayer->mCharData[(uchar) aCharsVector[i][0]].mOffset =
869
                                                                Point(aRectElement[0], aRectElement[1]);
870
                                                }
871
                                                else
872
                                                        invalidParamFormat = true;
873
                                        }                                                      
874
                                }
875
                                else
876
                                        sizeMismatch = true;
877
                        }
878
                        else
879
                                invalidParamFormat = true;
880
                }
881
                else
882
                        invalidNumParams = true;
883
        }
884
        else if (stricmp(aCmd.c_str(), "LayerSetKerningPairs") == 0)
885
        {
886
                if (theParams.mElementVector.size() == 4)
887
                {
888
                        FontLayer* aLayer;
889
                        StringVector aPairsVector;
890
                        IntVector anOffsetsVector;
891
 
892
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
893
                                (DataToStringVector(theParams.mElementVector[2], &aPairsVector)) &&
894
                                (DataToIntVector(theParams.mElementVector[3], &anOffsetsVector)))
895
                        {
896
                                if (aPairsVector.size() == anOffsetsVector.size())
897
                                {
898
                                        for (ulong i = 0; i < aPairsVector.size(); i++)
899
                                        {
900
                                                if (aPairsVector[i].length() == 2)
901
                                                {
902
                                                        aLayer->mCharData[(uchar) aPairsVector[i][0]].mKerningOffsets
903
                                                                [(uchar) aPairsVector[i][1]] = anOffsetsVector[i];
904
                                                }
905
                                                else
906
                                                        invalidParamFormat = true;
907
                                        }
908
                                }
909
                                else
910
                                        sizeMismatch = true;
911
                        }
912
                        else
913
                                invalidParamFormat = true;
914
                }
915
                else
916
                        invalidNumParams = true;
917
        }
918
        else if (stricmp(aCmd.c_str(), "LayerSetBaseOrder") == 0)
919
        {
920
                if (theParams.mElementVector.size() == 3)
921
                {
922
                        FontLayer* aLayer;
923
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
924
                                (!theParams.mElementVector[2]->mIsList))
925
                        {
926
                                int aBaseOrder;
927
                                if (StringToInt(((SingleDataElement*) theParams.mElementVector[2])->mString, &aBaseOrder))
928
                                {
929
                                        aLayer->mBaseOrder = aBaseOrder;
930
                                }
931
                                else
932
                                        invalidParamFormat = true;                                             
933
                        }
934
                        else
935
                                invalidParamFormat = true;
936
                }
937
                else
938
                        invalidNumParams = true;
939
        }
940
        else if (stricmp(aCmd.c_str(), "LayerSetCharOrders") == 0)
941
        {
942
                if (theParams.mElementVector.size() == 4)
943
                {
944
                        FontLayer* aLayer;
945
                        StringVector aCharsVector;
946
                        IntVector aCharOrdersVector;
947
 
948
                        if ((DataToLayer(theParams.mElementVector[1], &aLayer)) &&
949
                                (DataToStringVector(theParams.mElementVector[2], &aCharsVector)) &&
950
                                (DataToIntVector(theParams.mElementVector[3], &aCharOrdersVector)))
951
                        {
952
                                if (aCharsVector.size() == aCharOrdersVector.size())
953
                                {
954
                                        for (ulong i = 0; i < aCharsVector.size(); i++)
955
                                        {
956
                                                if (aCharsVector[i].length() == 1)
957
                                                {
958
                                                        aLayer->mCharData[(uchar) aCharsVector[i][0]].mOrder =
959
                                                                aCharOrdersVector[i];
960
                                                }
961
                                                else
962
                                                        invalidParamFormat = true;
963
                                        }
964
                                }
965
                                else
966
                                        sizeMismatch = true;
967
                        }
968
                        else
969
                                invalidParamFormat = true;
970
                }
971
                else
972
                        invalidNumParams = true;
973
        }
974
        else
975
        {
976
                Error("Unknown Command");
977
                return false;
978
        }
979
 
980
        if (invalidNumParams)
981
        {
982
                Error("Invalid Number of Parameters");
983
                return false;
984
        }
985
 
986
        if (invalidParamFormat)
987
        {
988
                Error("Invalid Paramater Type");
989
                return false;
990
        }
991
 
992
        if (literalError)
993
        {
994
                Error("Undefined Value");
995
                return false;
996
        }
997
 
998
        if (sizeMismatch)
999
        {
1000
                Error("List Size Mismatch");
1001
                return false;
1002
        }
1003
 
1004
        return true;
1005
}
1006
 
1007
bool FontData::Load(SexyAppBase* theSexyApp, const std::string& theFontDescFileName)
1008
{
1009
        if (mInitialized)
1010
                return false;
1011
 
1012
        bool hasErrors = false;
1013
 
1014
        mApp = theSexyApp;
1015
        mCurrentLine = "";
1016
 
1017
        mFontErrorHeader = "Font Descriptor Error in " + theFontDescFileName + "\r\n";
1018
 
1019
        mSourceFile = theFontDescFileName;     
1020
 
1021
        mInitialized = LoadDescriptor(theFontDescFileName);     ;
1022
 
1023
        return !hasErrors;
1024
}
1025
 
1026
bool FontData::LoadLegacy(Image* theFontImage, const std::string& theFontDescFileName)
1027
{
1028
        if (mInitialized)
1029
                return false;
1030
 
1031
        mFontLayerList.push_back(FontLayer(this));
1032
        FontLayer* aFontLayer = &mFontLayerList.back();
1033
 
1034
        FontLayerMap::iterator anItr = mFontLayerMap.insert(FontLayerMap::value_type("", aFontLayer)).first;
1035
        if (anItr == mFontLayerMap.end())
1036
                return false;  
1037
 
1038
        aFontLayer->mImage = (MemoryImage*) theFontImage;      
1039
        aFontLayer->mDefaultHeight = aFontLayer->mImage->GetHeight();  
1040
        aFontLayer->mAscent = aFontLayer->mImage->GetHeight(); 
1041
 
1042
        int aCharPos = 0;
1043
        FILE *aStream = fopen(theFontDescFileName.c_str(), "r");
1044
 
1045
        if (aStream==NULL)
1046
                return false;
1047
 
1048
        mSourceFile = theFontDescFileName;
1049
 
1050
        int aSpaceWidth = 0;
1051
        fscanf(aStream,"%d%d",&aFontLayer->mCharData[' '].mWidth,&aFontLayer->mAscent);
1052
 
1053
        while (!feof(aStream))
1054
        {
1055
                char aBuf[2] = { 0, 0 }; // needed because fscanf will null terminate the string it reads
1056
                char aChar = 0;
1057
                int aWidth = 0;
1058
 
1059
                fscanf(aStream,"%1s%d",aBuf,&aWidth);
1060
                aChar = aBuf[0];
1061
 
1062
 
1063
                if (aChar == 0)
1064
                        break;
1065
 
1066
                aFontLayer->mCharData[(uchar) aChar].mImageRect = Rect(aCharPos, 0, aWidth, aFontLayer->mImage->GetHeight());
1067
                aFontLayer->mCharData[(uchar) aChar].mWidth = aWidth;
1068
 
1069
                aCharPos += aWidth;
1070
        }
1071
 
1072
        char c;
1073
 
1074
        for (c = 'A'; c <= 'Z'; c++)
1075
                if ((aFontLayer->mCharData[c].mWidth == 0) && (aFontLayer->mCharData[c - 'A' + 'a'].mWidth != 0))
1076
                        mCharMap[c] = c - 'A' + 'a';
1077
 
1078
        for (c = 'a'; c <= 'z'; c++)
1079
                if ((aFontLayer->mCharData[c].mWidth == 0) && (aFontLayer->mCharData[c - 'a' + 'A'].mWidth != 0))
1080
                        mCharMap[c] = c - 'a' + 'A';
1081
 
1082
        mInitialized = true;
1083
        fclose(aStream);
1084
 
1085
        return true;
1086
}
1087
 
1088
////
1089
 
1090
ActiveFontLayer::ActiveFontLayer()
1091
{
1092
        mScaledImage = NULL;
1093
        mOwnsImage = false;
1094
}
1095
 
1096
ActiveFontLayer::ActiveFontLayer(const ActiveFontLayer& theActiveFontLayer) :
1097
        mBaseFontLayer(theActiveFontLayer.mBaseFontLayer),
1098
        mScaledImage(theActiveFontLayer.mScaledImage),
1099
        mOwnsImage(theActiveFontLayer.mOwnsImage)
1100
{
1101
        if (mOwnsImage)
1102
                mScaledImage = mBaseFontLayer->mFontData->mApp->CopyImage(mScaledImage);       
1103
 
1104
        for (int aCharNum = 0; aCharNum < 256; aCharNum++)
1105
                mScaledCharImageRects[aCharNum] = theActiveFontLayer.mScaledCharImageRects[aCharNum];
1106
}
1107
 
1108
ActiveFontLayer::~ActiveFontLayer()
1109
{
1110
        if (mOwnsImage)
1111
                delete mScaledImage;
1112
}
1113
 
1114
////
1115
 
1116
ImageFont::ImageFont(SexyAppBase* theSexyApp, const std::string& theFontDescFileName)
1117
{      
1118
        mScale = 1.0;
1119
        mFontData = new FontData();
1120
        mFontData->Ref();
1121
        mFontData->Load(theSexyApp, theFontDescFileName);
1122
        mPointSize = mFontData->mDefaultPointSize;
1123
        GenerateActiveFontLayers();
1124
        mActiveListValid = true;
1125
        mForceScaledImagesWhite = false;
1126
}
1127
 
1128
ImageFont::ImageFont(Image *theFontImage)
1129
{
1130
        mScale = 1.0;
1131
        mFontData = new FontData();
1132
        mFontData->Ref();
1133
        mFontData->mInitialized = true;
1134
        mPointSize = mFontData->mDefaultPointSize;
1135
        mActiveListValid = false;
1136
        mForceScaledImagesWhite = false;
1137
 
1138
        mFontData->mFontLayerList.push_back(FontLayer(mFontData));
1139
        FontLayer* aFontLayer = &mFontData->mFontLayerList.back();
1140
 
1141
        mFontData->mFontLayerMap.insert(FontLayerMap::value_type("", aFontLayer)).first;       
1142
        aFontLayer->mImage = (MemoryImage*) theFontImage;      
1143
        aFontLayer->mDefaultHeight = aFontLayer->mImage->GetHeight();  
1144
        aFontLayer->mAscent = aFontLayer->mImage->GetHeight(); 
1145
}
1146
 
1147
ImageFont::ImageFont(const ImageFont& theImageFont) :
1148
        Font(theImageFont),
1149
        mScale(theImageFont.mScale),
1150
        mFontData(theImageFont.mFontData),
1151
        mPointSize(theImageFont.mPointSize),   
1152
        mTagVector(theImageFont.mTagVector),
1153
        mActiveListValid(theImageFont.mActiveListValid),
1154
        mForceScaledImagesWhite(theImageFont.mForceScaledImagesWhite)
1155
{
1156
        mFontData->Ref();      
1157
 
1158
        if (mActiveListValid)
1159
                mActiveLayerList = theImageFont.mActiveLayerList;      
1160
}
1161
 
1162
ImageFont::ImageFont(Image* theFontImage, const std::string& theFontDescFileName)
1163
{
1164
 
1165
        mScale = 1.0;
1166
        mFontData = new FontData();
1167
        mFontData->Ref();
1168
        mFontData->LoadLegacy(theFontImage, theFontDescFileName);      
1169
        mPointSize = mFontData->mDefaultPointSize;
1170
        GenerateActiveFontLayers();
1171
        mActiveListValid = true;
1172
}
1173
 
1174
ImageFont::~ImageFont()
1175
{
1176
        mFontData->DeRef();
1177
}
1178
 
1179
/*ImageFont::ImageFont(const ImageFont& theImageFont, Image* theImage) :
1180
        Font(theImageFont),
1181
        mImage(theImage)
1182
{
1183
        for (int i = 0; i < 256; i++)
1184
        {
1185
                mCharPos[i] = theImageFont.mCharPos[i];
1186
                mCharWidth[i] = theImageFont.mCharWidth[i];
1187
        }
1188
}*/
1189
 
1190
void ImageFont::GenerateActiveFontLayers()
1191
{
1192
        if (!mFontData->mInitialized)
1193
                return;
1194
 
1195
        mActiveLayerList.clear();
1196
 
1197
        ulong i;
1198
 
1199
        mAscent = 0;   
1200
        mAscentPadding = 0;
1201
        mHeight = 0;   
1202
        mLineSpacingOffset = 0;
1203
 
1204
        FontLayerList::iterator anItr = mFontData->mFontLayerList.begin();
1205
 
1206
        bool firstLayer = true;
1207
 
1208
        while (anItr != mFontData->mFontLayerList.end())
1209
        {
1210
                FontLayer* aFontLayer = &*anItr;               
1211
 
1212
                if ((mPointSize >= aFontLayer->mMinPointSize) &&
1213
                        ((mPointSize <= aFontLayer->mMaxPointSize) || (aFontLayer->mMaxPointSize == -1)))
1214
                {
1215
                        bool active = true;
1216
 
1217
                        // Make sure all required tags are included
1218
                        for (i = 0; i < aFontLayer->mRequiredTags.size(); i++)
1219
                                if (std::find(mTagVector.begin(), mTagVector.end(), aFontLayer->mRequiredTags[i]) == mTagVector.end())
1220
                                        active = false;
1221
 
1222
                        // Make sure no excluded tags are included
1223
                        for (i = 0; i < mTagVector.size(); i++)
1224
                                if (std::find(aFontLayer->mExcludedTags.begin(), aFontLayer->mExcludedTags.end(),
1225
                                        mTagVector[i]) != aFontLayer->mExcludedTags.end())
1226
                                        active = false;
1227
 
1228
                        if (active)
1229
                        {                              
1230
                                mActiveLayerList.push_back(ActiveFontLayer());
1231
 
1232
                                ActiveFontLayer* anActiveFontLayer = &mActiveLayerList.back();
1233
 
1234
                                anActiveFontLayer->mBaseFontLayer = aFontLayer;
1235
 
1236
                                double aLayerPointSize = 1;
1237
                                double aPointSize = mScale;
1238
 
1239
                                if ((mScale == 1.0) && ((aFontLayer->mPointSize == 0) || (mPointSize == aFontLayer->mPointSize)))
1240
                                {
1241
                                        anActiveFontLayer->mScaledImage = aFontLayer->mImage;
1242
                                        anActiveFontLayer->mOwnsImage = false;
1243
 
1244
                                        // Use the specified point size
1245
 
1246
                                        for (int aCharNum = 0; aCharNum < 256; aCharNum++)
1247
                                                anActiveFontLayer->mScaledCharImageRects[aCharNum] = aFontLayer->mCharData[aCharNum].mImageRect;
1248
                                }
1249
                                else
1250
                                {                              
1251
                                        if (aFontLayer->mPointSize != 0)
1252
                                        {
1253
                                                aLayerPointSize = aFontLayer->mPointSize;
1254
                                                aPointSize = mPointSize * mScale;
1255
                                        }
1256
 
1257
                                        // Resize font elements
1258
                                        int aCharNum;
1259
 
1260
                                        MemoryImage* aMemoryImage = new MemoryImage(mFontData->mApp);
1261
 
1262
                                        int aCurX = 0;
1263
                                        int aMaxHeight = 0;
1264
 
1265
                                        for (aCharNum = 0; aCharNum < 256; aCharNum++)
1266
                                        {
1267
                                                Rect* anOrigRect = &aFontLayer->mCharData[aCharNum].mImageRect;
1268
 
1269
                                                Rect aScaledRect(aCurX, 0,  
1270
                                                        (int) ((anOrigRect->mWidth * aPointSize) / aLayerPointSize),
1271
                                                        (int) ((anOrigRect->mHeight * aPointSize) / aLayerPointSize));
1272
 
1273
                                                anActiveFontLayer->mScaledCharImageRects[aCharNum] = aScaledRect;
1274
 
1275
                                                if (aScaledRect.mHeight > aMaxHeight)
1276
                                                        aMaxHeight = aScaledRect.mHeight;
1277
 
1278
                                                aCurX += aScaledRect.mWidth;
1279
                                        }
1280
 
1281
                                        anActiveFontLayer->mScaledImage = aMemoryImage;
1282
                                        anActiveFontLayer->mOwnsImage = true;
1283
 
1284
                                        // Create the image now
1285
 
1286
                                        aMemoryImage->Create(aCurX, aMaxHeight);
1287
 
1288
                                        Graphics g(aMemoryImage);
1289
 
1290
                                        for (aCharNum = 0; aCharNum < 256; aCharNum++)
1291
                                        {
1292
                                                if ((Image*) aFontLayer->mImage != NULL)
1293
                                                        g.DrawImage(aFontLayer->mImage, anActiveFontLayer->mScaledCharImageRects[aCharNum],
1294
                                                                aFontLayer->mCharData[aCharNum].mImageRect);                                           
1295
                                        }
1296
 
1297
                                        if (mForceScaledImagesWhite)
1298
                                        {
1299
                                                int aCount = aMemoryImage->mWidth*aMemoryImage->mHeight;
1300
                                                ulong* aBits = aMemoryImage->GetBits();
1301
 
1302
                                                for (int i = 0; i < aCount; i++)
1303
                                                        *(aBits++) = *aBits | 0x00FFFFFF;
1304
                                        }
1305
 
1306
                                        aMemoryImage->Palletize();
1307
                                }
1308
 
1309
                                int aLayerAscent = (aFontLayer->mAscent * aPointSize) / aLayerPointSize;
1310
                                if (aLayerAscent > mAscent)
1311
                                        mAscent = aLayerAscent;
1312
 
1313
                                if (aFontLayer->mHeight != 0)
1314
                                {
1315
                                        int aLayerHeight = (aFontLayer->mHeight * aPointSize) / aLayerPointSize;
1316
                                        if (aLayerHeight > mHeight)
1317
                                                mHeight = aLayerHeight;
1318
                                }
1319
                                else
1320
                                {
1321
                                        int aLayerHeight = (aFontLayer->mDefaultHeight * aPointSize) / aLayerPointSize;
1322
                                        if (aLayerHeight > mHeight)
1323
                                                mHeight = aLayerHeight;
1324
                                }
1325
 
1326
                                int anAscentPadding = (aFontLayer->mAscentPadding * aPointSize) / aLayerPointSize;
1327
                                if ((firstLayer) || (anAscentPadding < mAscentPadding))
1328
                                        mAscentPadding = anAscentPadding;
1329
 
1330
                                int aLineSpacingOffset = (aFontLayer->mLineSpacingOffset * aPointSize) / aLayerPointSize;
1331
                                if ((firstLayer) || (aLineSpacingOffset > mLineSpacingOffset))
1332
                                        mLineSpacingOffset = aLineSpacingOffset;
1333
 
1334
                                firstLayer = false;
1335
                        }
1336
                }
1337
 
1338
                ++anItr;
1339
        }      
1340
}
1341
 
1342
int ImageFont::StringWidth(const SexyString& theString)
1343
{
1344
        int aWidth = 0;
1345
        char aPrevChar = 0;
1346
        for(int i=0; i<(int)theString.length(); i++)
1347
        {
1348
                char aChar = theString[i];
1349
                aWidth += CharWidthKern(aChar,aPrevChar);
1350
                aPrevChar = aChar;
1351
        }
1352
 
1353
        return aWidth;
1354
}
1355
 
1356
int ImageFont::CharWidthKern(char theChar, char thePrevChar)
1357
{
1358
        Prepare();
1359
 
1360
        int aMaxXPos = 0;
1361
        double aPointSize = mPointSize * mScale;
1362
 
1363
        theChar = mFontData->mCharMap[(uchar)theChar];
1364
        if (thePrevChar != 0)
1365
                thePrevChar = mFontData->mCharMap[(uchar)thePrevChar];
1366
 
1367
        ActiveFontLayerList::iterator anItr = mActiveLayerList.begin();
1368
        while (anItr != mActiveLayerList.end())
1369
        {
1370
                ActiveFontLayer* anActiveFontLayer = &*anItr;
1371
 
1372
                int aLayerXPos = 0;
1373
 
1374
                int aCharWidth;
1375
                int aSpacing;
1376
 
1377
                int aLayerPointSize = anActiveFontLayer->mBaseFontLayer->mPointSize;
1378
 
1379
                if (aLayerPointSize == 0)
1380
                {
1381
                        aCharWidth = anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) theChar].mWidth * mScale;
1382
 
1383
                        if (thePrevChar != 0)
1384
                        {
1385
                                aSpacing = (anActiveFontLayer->mBaseFontLayer->mSpacing +
1386
                                        anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) thePrevChar].mKerningOffsets[(uchar) theChar]) * mScale;
1387
                        }
1388
                        else
1389
                                aSpacing = 0;
1390
                }
1391
                else
1392
                {
1393
                        aCharWidth = (anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) theChar].mWidth * aPointSize / aLayerPointSize);
1394
 
1395
                        if (thePrevChar != 0)
1396
                        {
1397
                                aSpacing = (anActiveFontLayer->mBaseFontLayer->mSpacing +
1398
                                        anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) thePrevChar].mKerningOffsets[(uchar) theChar]) * aPointSize / aLayerPointSize;
1399
                        }
1400
                        else
1401
                                aSpacing = 0;
1402
                }                                              
1403
 
1404
                aLayerXPos += aCharWidth + aSpacing;
1405
 
1406
                if (aLayerXPos > aMaxXPos)
1407
                        aMaxXPos = aLayerXPos;
1408
 
1409
                ++anItr;
1410
        }
1411
 
1412
        return aMaxXPos;
1413
}
1414
 
1415
int ImageFont::CharWidth(char theChar)
1416
{
1417
        return CharWidthKern(theChar,0);
1418
}
1419
 
1420
CritSect gRenderCritSec;
1421
static const int POOL_SIZE = 4096;
1422
static RenderCommand gRenderCommandPool[POOL_SIZE];
1423
static RenderCommand* gRenderTail[256];
1424
static RenderCommand* gRenderHead[256];
1425
 
1426
void ImageFont::DrawStringEx(Graphics* g, int theX, int theY, const SexyString& theString, const Color& theColor, const Rect* theClipRect, RectList* theDrawnAreas, int* theWidth)
1427
{
1428
        AutoCrit anAutoCrit(gRenderCritSec);
1429
 
1430
        int aPoolIdx;
1431
 
1432
        for (aPoolIdx = 0; aPoolIdx < 256; aPoolIdx++)
1433
        {
1434
                gRenderHead[aPoolIdx] = NULL;
1435
                gRenderTail[aPoolIdx] = NULL;
1436
        }
1437
 
1438
        int aXPos = theX;      
1439
 
1440
        if (theDrawnAreas != NULL)
1441
                theDrawnAreas->clear();
1442
 
1443
 
1444
        /*if (theDrawnArea != NULL)
1445
                *theDrawnArea = Rect(0, 0, 0, 0);*/
1446
 
1447
        if (!mFontData->mInitialized)
1448
        {
1449
                if (theWidth != NULL)
1450
                        *theWidth = 0;
1451
                return;
1452
        }
1453
 
1454
        Prepare();
1455
 
1456
        bool colorizeImages = g->GetColorizeImages();
1457
        g->SetColorizeImages(true);    
1458
 
1459
        int aCurXPos = theX;
1460
        int aCurPoolIdx = 0;
1461
 
1462
        for (ulong aCharNum = 0; aCharNum < theString.length(); aCharNum++)
1463
        {
1464
                char aChar = mFontData->mCharMap[(uchar) theString[aCharNum]];
1465
 
1466
                char aNextChar = 0;
1467
                if (aCharNum < theString.length() - 1)
1468
                        aNextChar = mFontData->mCharMap[(uchar) theString[aCharNum+1]];
1469
 
1470
                int aMaxXPos = aCurXPos;
1471
 
1472
                ActiveFontLayerList::iterator anItr = mActiveLayerList.begin();
1473
                while (anItr != mActiveLayerList.end())
1474
                {
1475
                        ActiveFontLayer* anActiveFontLayer = &*anItr;
1476
 
1477
                        int aLayerXPos = aCurXPos;
1478
 
1479
                        int anImageX;
1480
                        int anImageY;
1481
                        int aCharWidth;
1482
                        int aSpacing;
1483
 
1484
                        int aLayerPointSize = anActiveFontLayer->mBaseFontLayer->mPointSize;
1485
 
1486
                        double aScale = mScale;
1487
                        if (aLayerPointSize != 0)
1488
                                aScale *= mPointSize / aLayerPointSize;
1489
 
1490
                        if (aScale == 1.0)
1491
                        {
1492
                                anImageX = aLayerXPos + anActiveFontLayer->mBaseFontLayer->mOffset.mX + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mX;
1493
                                anImageY = theY - (anActiveFontLayer->mBaseFontLayer->mAscent - anActiveFontLayer->mBaseFontLayer->mOffset.mY - anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mY);
1494
                                aCharWidth = anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mWidth;                               
1495
 
1496
                                if (aNextChar != 0)
1497
                                {
1498
                                         aSpacing = anActiveFontLayer->mBaseFontLayer->mSpacing +
1499
                                                 anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mKerningOffsets[(uchar) aNextChar];
1500
                                }
1501
                                else
1502
                                        aSpacing = 0;
1503
                        }
1504
                        else
1505
                        {
1506
                                anImageX = aLayerXPos + (int) ((anActiveFontLayer->mBaseFontLayer->mOffset.mX + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mX) * aScale);
1507
                                anImageY = theY - (int) ((anActiveFontLayer->mBaseFontLayer->mAscent - anActiveFontLayer->mBaseFontLayer->mOffset.mY - anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOffset.mY) * aScale);
1508
                                aCharWidth = (anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mWidth * aScale);
1509
 
1510
                                if (aNextChar != 0)
1511
                                {
1512
                                         aSpacing = (int) ((anActiveFontLayer->mBaseFontLayer->mSpacing +
1513
                                                 anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mKerningOffsets[(uchar) aNextChar]) * aScale);
1514
                                }
1515
                                else
1516
                                        aSpacing = 0;
1517
                        }                                              
1518
 
1519
                        Color aColor;
1520
                        aColor.mRed = min((theColor.mRed * anActiveFontLayer->mBaseFontLayer->mColorMult.mRed / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mRed, 255);
1521
                        aColor.mGreen = min((theColor.mGreen * anActiveFontLayer->mBaseFontLayer->mColorMult.mGreen / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mGreen, 255);
1522
                        aColor.mBlue = min((theColor.mBlue * anActiveFontLayer->mBaseFontLayer->mColorMult.mBlue / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mBlue, 255);
1523
                        aColor.mAlpha = min((theColor.mAlpha * anActiveFontLayer->mBaseFontLayer->mColorMult.mAlpha / 255) + anActiveFontLayer->mBaseFontLayer->mColorAdd.mAlpha, 255);
1524
 
1525
                        int anOrder = anActiveFontLayer->mBaseFontLayer->mBaseOrder + anActiveFontLayer->mBaseFontLayer->mCharData[(uchar) aChar].mOrder;
1526
 
1527
                        if (aCurPoolIdx >= POOL_SIZE)
1528
                                break;
1529
 
1530
                        RenderCommand* aRenderCommand = &gRenderCommandPool[aCurPoolIdx++];
1531
 
1532
                        aRenderCommand->mImage = anActiveFontLayer->mScaledImage;
1533
                        aRenderCommand->mColor = aColor;
1534
                        aRenderCommand->mDest[0] = anImageX;
1535
                        aRenderCommand->mDest[1] = anImageY;
1536
                        aRenderCommand->mSrc[0] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mX;
1537
                        aRenderCommand->mSrc[1] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mY;
1538
                        aRenderCommand->mSrc[2] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mWidth;
1539
                        aRenderCommand->mSrc[3] = anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mHeight;
1540
                        aRenderCommand->mMode = anActiveFontLayer->mBaseFontLayer->mDrawMode;
1541
                        aRenderCommand->mNext = NULL;
1542
 
1543
                        int anOrderIdx = min(max(anOrder + 128, 0), 255);
1544
 
1545
                        if (gRenderTail[anOrderIdx] == NULL)
1546
                        {
1547
                                gRenderTail[anOrderIdx] = aRenderCommand;
1548
                                gRenderHead[anOrderIdx] = aRenderCommand;
1549
                        }
1550
                        else
1551
                        {
1552
                                gRenderTail[anOrderIdx]->mNext = aRenderCommand;
1553
                                gRenderTail[anOrderIdx] = aRenderCommand;
1554
                        }
1555
 
1556
                        //aRenderCommandMap.insert(RenderCommandMap::value_type(aPriority, aRenderCommand));
1557
 
1558
                        /*int anOldDrawMode = g->GetDrawMode();
1559
                        if (anActiveFontLayer->mBaseFontLayer->mDrawMode != -1)
1560
                                g->SetDrawMode(anActiveFontLayer->mBaseFontLayer->mDrawMode);
1561
                        Color anOrigColor = g->GetColor();
1562
                        g->SetColor(aColor);                   
1563
                        if (anActiveFontLayer->mScaledImage != NULL)
1564
                                g->DrawImage(anActiveFontLayer->mScaledImage, anImageX, anImageY, anActiveFontLayer->mScaledCharImageRects[aChar]);    
1565
                        g->SetColor(anOrigColor);
1566
                        g->SetDrawMode(anOldDrawMode);*/
1567
 
1568
                        if (theDrawnAreas != NULL)
1569
                        {
1570
                                Rect aDestRect = Rect(anImageX, anImageY, anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mWidth, anActiveFontLayer->mScaledCharImageRects[(uchar) aChar].mHeight);
1571
 
1572
                                theDrawnAreas->push_back(aDestRect);
1573
 
1574
                                /*if (theDrawnArea->mWidth == 0)
1575
                                        *theDrawnArea = theDestRect;
1576
                                else
1577
                                {
1578
                                        if (theDestRect.mX < theDrawnArea->mX)
1579
                                        {
1580
                                                int aDiff = theDestRect.mX - theDrawnArea->mX;
1581
                                                theDrawnArea->mX += aDiff;
1582
                                                theDrawnArea->mWidth += aDiff;
1583
                                        }
1584
 
1585
                                        if (theDestRect.mX + theDestRect.mWidth > theDrawnArea->mX + theDrawnArea->mWidth)
1586
                                                theDrawnArea->mWidth = theDestRect.mX + theDestRect.mWidth - theDrawnArea->mX;
1587
 
1588
                                        if (theDestRect.mY < theDrawnArea->mY)
1589
                                        {
1590
                                                int aDiff = theDestRect.mY - theDrawnArea->mY;
1591
                                                theDrawnArea->mY += aDiff;
1592
                                                theDrawnArea->mHeight += aDiff;
1593
                                        }
1594
 
1595
                                        if (theDestRect.mY + theDestRect.mHeight > theDrawnArea->mY + theDrawnArea->mHeight)
1596
                                                theDrawnArea->mHeight = theDestRect.mY + theDestRect.mHeight - theDrawnArea->mY;
1597
                                }*/
1598
                        }
1599
 
1600
                        aLayerXPos += aCharWidth + aSpacing;
1601
 
1602
                        if (aLayerXPos > aMaxXPos)
1603
                                aMaxXPos = aLayerXPos;
1604
 
1605
                        ++anItr;
1606
                }
1607
 
1608
                aCurXPos = aMaxXPos;
1609
        }
1610
 
1611
        if (theWidth != NULL)
1612
                *theWidth = aCurXPos - theX;
1613
 
1614
        Color anOrigColor = g->GetColor();
1615
 
1616
        for (aPoolIdx = 0; aPoolIdx < 256; aPoolIdx++)
1617
        {              
1618
                RenderCommand* aRenderCommand = gRenderHead[aPoolIdx];
1619
 
1620
                while (aRenderCommand != NULL)
1621
                {
1622
                        int anOldDrawMode = g->GetDrawMode();
1623
                        if (aRenderCommand->mMode != -1)
1624
                                g->SetDrawMode(aRenderCommand->mMode);                 
1625
                        g->SetColor(Color(aRenderCommand->mColor));
1626
                        if (aRenderCommand->mImage != NULL)
1627
                                g->DrawImage(aRenderCommand->mImage, aRenderCommand->mDest[0], aRenderCommand->mDest[1], Rect(aRenderCommand->mSrc[0], aRenderCommand->mSrc[1], aRenderCommand->mSrc[2], aRenderCommand->mSrc[3]));                            
1628
                        g->SetDrawMode(anOldDrawMode);
1629
 
1630
                        aRenderCommand = aRenderCommand->mNext;
1631
                }
1632
        }
1633
 
1634
        g->SetColor(anOrigColor);
1635
 
1636
        /*RenderCommandMap::iterator anItr = aRenderCommandMap.begin();
1637
        while (anItr != aRenderCommandMap.end())
1638
        {
1639
                RenderCommand* aRenderCommand = &anItr->second;
1640
 
1641
                int anOldDrawMode = g->GetDrawMode();
1642
                if (aRenderCommand->mMode != -1)
1643
                        g->SetDrawMode(aRenderCommand->mMode);
1644
                Color anOrigColor = g->GetColor();
1645
                g->SetColor(aRenderCommand->mColor);                   
1646
                if (aRenderCommand->mImage != NULL)
1647
                        g->DrawImage(aRenderCommand->mImage, aRenderCommand->mDest.mX, aRenderCommand->mDest.mY, aRenderCommand->mSrc);
1648
                g->SetColor(anOrigColor);
1649
                g->SetDrawMode(anOldDrawMode);
1650
 
1651
                ++anItr;
1652
        }*/            
1653
 
1654
        g->SetColorizeImages(colorizeImages);
1655
}
1656
 
1657
void ImageFont::DrawString(Graphics* g, int theX, int theY, const SexyString& theString, const Color& theColor, const Rect& theClipRect)
1658
{
1659
        DrawStringEx(g, theX, theY, theString, theColor, &theClipRect, NULL, NULL);    
1660
}
1661
 
1662
Font* ImageFont::Duplicate()
1663
{
1664
        return new ImageFont(*this);
1665
}
1666
 
1667
void ImageFont::SetPointSize(int thePointSize)
1668
{
1669
        mPointSize = thePointSize;
1670
        mActiveListValid = false;
1671
}
1672
 
1673
void ImageFont::SetScale(double theScale)
1674
{
1675
        mScale = theScale;
1676
        mActiveListValid = false;
1677
}
1678
 
1679
int     ImageFont::GetPointSize()
1680
{
1681
        return mPointSize;
1682
}
1683
 
1684
int     ImageFont::GetDefaultPointSize()
1685
{
1686
        return mFontData->mDefaultPointSize;
1687
}
1688
 
1689
bool ImageFont::AddTag(const std::string& theTagName)
1690
{
1691
        if (HasTag(theTagName))
1692
                return false;
1693
 
1694
        std::string aTagName = StringToUpper(theTagName);
1695
        mTagVector.push_back(aTagName);
1696
        mActiveListValid = false;
1697
        return true;
1698
}
1699
 
1700
bool ImageFont::RemoveTag(const std::string& theTagName)
1701
{
1702
        std::string aTagName = StringToUpper(theTagName);
1703
 
1704
        StringVector::iterator anItr = std::find(mTagVector.begin(), mTagVector.end(), aTagName);
1705
        if (anItr == mTagVector.end())
1706
                return false;
1707
 
1708
        mTagVector.erase(anItr);
1709
        mActiveListValid = false;
1710
        return true;
1711
}
1712
 
1713
bool ImageFont::HasTag(const std::string& theTagName)
1714
{
1715
        StringVector::iterator anItr = std::find(mTagVector.begin(), mTagVector.end(), theTagName);
1716
        return anItr != mTagVector.end();
1717
}
1718
 
1719
std::string ImageFont::GetDefine(const std::string& theName)
1720
{
1721
        DataElement* aDataElement = mFontData->Dereference(theName);
1722
 
1723
        if (aDataElement == NULL)
1724
                return "";
1725
 
1726
        return mFontData->DataElementToString(aDataElement);
1727
}
1728
 
1729
void ImageFont::Prepare()
1730
{
1731
        if (!mActiveListValid)
1732
        {
1733
                GenerateActiveFontLayers();
1734
                mActiveListValid = true;
1735
        }
1736
}