Subversion Repositories AndroidProjects

Rev

Rev 1456 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1454 chris 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
using System.IO;
1489 chris 7
using System.Drawing;
1454 chris 8
 
9
using BauzoidNET.file;
10
using BauzoidNET.graphics.sprite;
11
 
1456 chris 12
using EndianHandling;
1454 chris 13
 
14
namespace BauzoidNET.graphics
15
{
16
    public class FontUtil
17
    {
18
        public static readonly string LOG_TAG =  "FontUtil";
19
            public static bool verbose = true;
20
 
21
            private class CharacterRect
22
            {
23
                    public float x;
24
                    public float y;
25
                    public float w;
26
                    public float h;
27
 
28
                    public CharacterRect(float _x, float _y, float _w, float _h)
29
                    {
30
                            x = _x;
31
                            y = _y;
32
                            w = _w;
33
                            h = _h;
34
                    }
35
            }
36
 
37
            private class CharacterOffset
38
            {
39
                    public float x;
40
                    public float y;
41
 
42
                    public CharacterOffset(float _x, float _y)
43
                    {
44
                            x = _x;
45
                            y = _y;
46
                    }
47
            }
48
 
49
            private class KerningPair
50
            {
51
                    public char first;
52
                    public char second;
53
                    public int value;
54
 
55
                    public KerningPair(char a, char b, int n)
56
                    {
57
                            first = a;
58
                            second = b;
59
                            value = n;
60
                    }
61
            }
62
 
63
 
64
            private FontUtil() {}
65
 
66
        public static void log(String msg)
67
        {
68
            log(LOG_TAG, msg);
69
        }
70
 
71
            public static void log(String tag, String msg)
72
            {
73
                    if (verbose)
74
                            System.Console.WriteLine(tag + ": " + msg);
75
            }
1489 chris 76
 
77
        public static Font createFontFromBinaryResource(Graphics graphics, byte[] file, Bitmap bmOverride)
78
        {
79
            MemoryStream stream = new MemoryStream(file);
80
            Font font = createFontFromBinaryStream(graphics, stream, null, bmOverride);
81
            stream.Close();
82
            return font;
83
        }
84
 
85
        public static Font createFontFromBinaryFile(Graphics graphics, string filename, Stream input, Bitmap bmOverride = null)
86
        {
87
            FileStream stream = File.Open(filename, FileMode.Open);
88
            Font font = createFontFromBinaryStream(graphics, stream, Path.GetDirectoryName(filename), bmOverride);
89
            stream.Close();
90
            return font;
91
        }
1454 chris 92
 
1489 chris 93
            public static Font createFontFromBinaryStream(Graphics graphics, Stream input, string bmDirectory, Bitmap bmOverride = null)
1454 chris 94
            {
95
                    List<char> charList = new List<char>();
96
                    List<float> widthList = new List<float>();
97
                    List<CharacterRect> rectList = new List<CharacterRect>();
98
                    List<CharacterOffset> offsetList = new List<CharacterOffset>();
99
                    List<KerningPair> kerningPairs = new List<KerningPair>();
100
 
101
                    //Font font = new Font(graphics);
102
                    //Texture texture = null;
103
                    String textureFileFull = null;
104
 
105
                    float multiplier = 1.0f;
106
                    float ascent = 10.0f;
107
 
108
                    try
109
                    {
110
                            //File f = new File(file.read());
1489 chris 111
                EndianBinaryReader reader = new EndianBinaryReader(input, Encoding.Default, true);
1454 chris 112
 
113
                            //int version = f.readInt();
1456 chris 114
                int version = 0;
115
                reader.ReadInt32(out version);
1454 chris 116
                            if (version != 100)
117
                            {
118
                                    //Gdx.app.log(LOG_TAG, "Version mismatch: 100 != " + version);
119
                    log("Version mismatch: 100 != " + version);
120
                                    return null;
121
                            }                  
122
 
123
                            //String textureFile = f.readString();
1456 chris 124
                string textureFile = FileUtil.readString(reader);
1454 chris 125
 
126
                            //textureFileFull = FileUtil.extractPath(file.path()) + "/" + textureFile;
1489 chris 127
                if (bmDirectory != null)
128
                    textureFileFull = bmDirectory + "\\" + textureFile;
129
                else
130
                    textureFileFull = textureFile;
1454 chris 131
 
132
 
133
                            //ascent = f.readFloat();
1456 chris 134
                //ascent = reader.ReadSingle();
135
                reader.ReadSingle(out ascent);
1454 chris 136
                            //multiplier = f.readFloat();
1456 chris 137
                //multiplier = reader.ReadSingle();
138
                reader.ReadSingle(out multiplier);
1454 chris 139
 
140
                            // Read character list (char * num)
141
                            //int numChars = f.readInt(); // number of characters
1456 chris 142
                int numChars;
143
                reader.ReadInt32(out numChars);
1454 chris 144
                            for (int i = 0; i < numChars; i++)
145
                            {
146
                                    //Character c = f.readChar();
1456 chris 147
                    char c;
148
                    reader.ReadChar(out c);
1454 chris 149
                                    charList.Add(c);                           
150
                            }
151
 
152
                            // Read width list (float * num)
153
                            //int numWidths = f.readInt(); // number of widths
1456 chris 154
                int numWidths;
155
                reader.ReadInt32(out numWidths);
1454 chris 156
                            for (int i = 0; i < numWidths; i++)
157
                            {
158
                                    //Float width = f.readFloat();
1456 chris 159
                    float width;
160
                    reader.ReadSingle(out width);
1454 chris 161
                                    widthList.Add(width);
162
                            }
163
 
164
                            // Read rect list (CharRect * num)
165
                            //int numRects = f.readInt(); // number of rects
1456 chris 166
                int numRects;
167
                reader.ReadInt32(out numRects);
1454 chris 168
                            for (int i = 0; i < numRects; i++)
169
                            {
1456 chris 170
                                    float x;
171
                    reader.ReadSingle(out x);
172
                    float y;
173
                    reader.ReadSingle(out y);
174
                    float w;
175
                    reader.ReadSingle(out w);
176
                    float h;
177
                    reader.ReadSingle(out h);
1454 chris 178
 
179
                                    rectList.Add(new CharacterRect(x, y, w, h));
180
                            }
181
 
182
                            // Read offset list (CharOffset * num)
1456 chris 183
                            int numOffsets;
184
                reader.ReadInt32(out numOffsets); // number of offsets
1454 chris 185
                            for (int i = 0; i < numOffsets; i++)
186
                            {
1456 chris 187
                                    float x;
188
                    reader.ReadSingle(out x);
189
                    float y;
190
                    reader.ReadSingle(out y);
1454 chris 191
 
192
                                    offsetList.Add(new CharacterOffset(x, y));                         
193
                            }
194
 
195
                            // number of kerning pairs
1456 chris 196
                            int numKerning;
197
                reader.ReadInt32(out numKerning);
1454 chris 198
 
199
                            // Read kerning pairs + values
200
                            for (int i = 0; i < numKerning; i++)
201
                            {
1456 chris 202
                                    char a;
203
                    reader.ReadChar(out a);
204
                    char b;
205
                    reader.ReadChar(out b);
206
                    int v;
207
                    reader.ReadInt32(out v);
1454 chris 208
 
209
                                    kerningPairs.Add(new KerningPair(a, b, v));                        
210
                            }
211
 
212
                            //f.close();
1456 chris 213
                reader.Close();
1454 chris 214
                    }
1456 chris 215
                    catch
1454 chris 216
                    {
217
                            //Gdx.app.log(LOG_TAG, "Could not read font!");             
218
                log("Could not read font!");
219
                    }
1489 chris 220
 
221
            Sprite sprite = null;
222
            if (bmOverride == null)
223
            {
224
                sprite = new Sprite(graphics, textureFileFull);
225
            }
226
            else
227
            {
228
                sprite = new Sprite(graphics, bmOverride);
229
            }
230
 
231
            return buildFont(graphics, sprite, charList, widthList, rectList, offsetList, multiplier, ascent, kerningPairs);
1454 chris 232
            }
1456 chris 233
 
1489 chris 234
        private static Font buildFont(Graphics graphics, Sprite sprite, List<char> charList, List<float> widthList, List<CharacterRect> rectList, List<CharacterOffset> offsetList,
235
                float multiplier, float ascent, List<KerningPair> kerningPairs)
1454 chris 236
            {
237
                    // Build font
1489 chris 238
            if (sprite == null)
1454 chris 239
                    {
1489 chris 240
                            log("No sprite specified!");
1454 chris 241
                            return null;
242
                    }
243
 
244
                    Font font = new Font(graphics);
245
 
1456 chris 246
                    Font.CharacterInfo[] characters = new Font.CharacterInfo[charList.Count];
247
                    SpriteRegion[] regions = new SpriteRegion[rectList.Count];
1454 chris 248
 
1489 chris 249
                    //Sprite sprite = new Sprite(graphics, textureFile);
1454 chris 250
                    sprite.init();
251
 
1456 chris 252
                    for (int i = 0; i < characters.Length; i++)
1454 chris 253
                    {
1456 chris 254
                            characters[i] = new Font.CharacterInfo(charList.ElementAt(i));
255
 
256
                characters[i].width = widthList.ElementAt(i);
1454 chris 257
 
1456 chris 258
                            if (i < offsetList.Count)
1454 chris 259
                            {
1456 chris 260
                    characters[i].offsetX = offsetList.ElementAt(i).x;
261
                    characters[i].offsetY = offsetList.ElementAt(i).y;
1454 chris 262
                            }
263
 
1456 chris 264
                            if (i < rectList.Count)
1454 chris 265
                            {
1456 chris 266
                    CharacterRect rect = rectList.ElementAt(i);
1454 chris 267
 
268
                                    /*characters[i].texX = rectList.elementAt(i).x;
269
                                    characters[i].texY = rectList.elementAt(i).y;
270
                                    characters[i].texW = rectList.elementAt(i).w;
271
                                    characters[i].texH = rectList.elementAt(i).h;*/
272
                                    regions[i] = new SpriteRegion(sprite, i, rect.x / multiplier, rect.y / multiplier, rect.w / multiplier, rect.h / multiplier, true);
273
                            }
274
                    }
275
                    sprite.setRegions(regions);
276
 
277
                    //AtlasSprite sprite = new AtlasSprite(graphics, texture, regions);
278
 
1456 chris 279
                    for (int i = 0; i < regions.Length; i++)
1454 chris 280
                    {
281
                            characters[i].setSpriteInstance(sprite.createSpriteInstance(i));
282
                    }
283
 
284
                    font.setCharacters(characters);
285
                    font.setSprite(sprite);            
286
                    font.setAscent(ascent);
287
                    font.setGlobalMultiplier(multiplier);
288
 
1456 chris 289
                    for (int i = 0; i < kerningPairs.Count; i++)
1454 chris 290
                    {
1456 chris 291
                            KerningPair pair = kerningPairs.ElementAt(i);
1454 chris 292
                            font.setKerning(pair.first, pair.second, pair.value);
293
                    }
294
 
295
                    return font;
296
            }
297
 
1456 chris 298
/*          private static Vector<Character> parseCharList(Tokenizer t) throws ScanException
1454 chris 299
            {
300
                    Vector<Character> charList = new Vector<Character>();
301
 
302
                    t.readToken("(");
303
 
304
                    while (!t.checkToken(")"))
305
                    {
306
                            String character = t.readString();
307
 
308
                            if (character.length() > 1)
309
                                    throw new ScanException("Character can only have length 1!", t.getSurroundings());
310
 
311
                            charList.add(character.charAt(0));
312
 
313
                            if (t.checkToken(")"))
314
                                    break;
315
 
316
                            t.readToken(",");
317
                    }                          
318
 
319
                    t.readToken(")");
320
 
321
                    return charList;
322
            }
323
 
324
            private static Vector<Float> parseWidthList(Tokenizer t) throws ScanException
325
            {
326
                    Vector<Float> widthList = new Vector<Float>();
327
 
328
                    t.readToken("(");
329
 
330
                    while (!t.checkToken(")"))
331
                    {
332
                            float width = t.readNumber();
333
 
334
                            widthList.add(width);
335
 
336
                            if (t.checkToken(")"))
337
                                    break;
338
 
339
                            //Gdx.app.log(LOG_TAG, "[" + width + "]");
340
 
341
                            t.readToken(",");
342
                    }                          
343
 
344
                    t.readToken(")");
345
 
346
                    return widthList;
347
            }
348
 
349
            private static Vector<CharacterRect> parseRectList(Tokenizer t) throws ScanException
350
            {
351
                    Vector<CharacterRect> rectList = new Vector<CharacterRect>();
352
 
353
                    t.readToken("(");
354
 
355
                    while (t.checkToken("("))
356
                    {
357
                            t.readToken("(");
358
 
359
                            float x = t.readNumber();
360
                            t.readToken(",");
361
                            float y = t.readNumber();
362
                            t.readToken(",");
363
                            float w = t.readNumber();
364
                            t.readToken(",");
365
                            float h = t.readNumber();
366
 
367
                            rectList.add(new CharacterRect(x, y, w, h));
368
 
369
                            t.readToken(")");
370
 
371
                            if (!t.checkToken(","))
372
                                    break;
373
 
374
                            t.readToken(",");
375
                    }          
376
 
377
                    if (!t.checkToken(")"))
378
                            throw new ScanException("Syntax error in RectList!", t.getSurroundings());
379
 
380
                    t.readToken(")");
381
 
382
                    return rectList;
383
            }
384
 
385
            private static Vector<CharacterOffset> parseOffsetList(Tokenizer t) throws ScanException
386
            {
387
                    Vector<CharacterOffset> offsetList = new Vector<CharacterOffset>();
388
 
389
                    t.readToken("(");
390
 
391
                    while (t.checkToken("("))
392
                    {
393
                            t.readToken("(");
394
 
395
                            float x = t.readNumber();
396
                            t.readToken(",");
397
                            float y = t.readNumber();
398
 
399
                            offsetList.add(new CharacterOffset(x, y));
400
 
401
                            t.readToken(")");
402
 
403
                            if (!t.checkToken(","))
404
                                    break;
405
 
406
                            t.readToken(",");
407
                    }          
408
 
409
                    if (!t.checkToken(")"))
410
                            throw new ScanException("Syntax error in OffsetList!", t.getSurroundings());
411
 
412
                    t.readToken(")");
413
 
414
                    return offsetList;
415
            }
416
 
417
            private static Vector<KerningPair> parseKerningPairs(Tokenizer t) throws ScanException
418
            {
419
                    Vector<KerningPair> kerningPairs = new Vector<KerningPair>();
420
 
421
                    t.readToken("(");
422
 
423
                    while (!t.checkToken(")"))
424
                    {
425
                            String pair = t.readString();
426
 
427
                            kerningPairs.add(new KerningPair(pair.charAt(0), pair.charAt(1), 0));
428
 
429
                            if (t.checkToken(")"))
430
                                    break;
431
 
432
                            //Gdx.app.log(LOG_TAG, "[" + width + "]");
433
 
434
                            t.readToken(",");
435
                    }                          
436
 
437
                    t.readToken(")");
438
 
439
                    return kerningPairs;
440
            }
441
 
442
            private static Vector<Integer> parseKerningValues(Tokenizer t) throws ScanException
443
            {
444
                    Vector<Integer> kerningValues = new Vector<Integer>();
445
 
446
                    t.readToken("(");
447
 
448
                    while (!t.checkToken(")"))
449
                    {
450
                            int value = (int)t.readNumber();
451
 
452
                            kerningValues.add(value);
453
 
454
                            if (t.checkToken(")"))
455
                                    break;
456
 
457
                            //Gdx.app.log(LOG_TAG, "[" + width + "]");
458
 
459
                            t.readToken(",");
460
                    }                          
461
 
462
                    t.readToken(")");
463
 
464
                    return kerningValues;
1456 chris 465
            }*/
1454 chris 466
    }
467
}