Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1671 chris 1
package com.gebauz.bauzoid.graphics;
2
 
3
import java.util.Hashtable;
4
 
5
import com.badlogic.gdx.graphics.Texture.TextureFilter;
6
import com.gebauz.bauzoid.graphics.sprite.Sprite;
7
import com.gebauz.bauzoid.graphics.sprite.SpriteInstance;
8
import com.gebauz.bauzoid.graphics.sprite.TileBatch;
9
import com.gebauz.bauzoid.math.Vector4;
10
 
11
public class Font extends GraphicsObject
12
{
13
        public static final Vector4 DEFAULT_COLOR = new Vector4(1, 1, 1, 1);
14
 
15
        public static class KerningPair
16
        {
17
                public char first;
18
                public char second;
19
 
20
                public KerningPair(char a, char b)
21
                {
22
                        first = a;
23
                        second = b;
24
                }
25
 
26
                @Override
27
                public boolean equals(Object other)
28
                {
29
                    // Not strictly necessary, but often a good optimization
30
                    if (this == other)
31
                      return true;
32
 
33
                    if (!(other instanceof KerningPair))
34
                      return false;
35
 
36
                    KerningPair p = (KerningPair)other;
37
 
38
                    return ((first == p.first) && (second == p.second));
39
                }
40
 
41
                @Override
42
                public int hashCode()
43
                {
44
                        return (first * 256) + second;                 
45
                }
46
        }
47
 
48
        public static class CharacterInfo
49
        {
50
                private char mCharacter;
51
                private SpriteInstance mSpriteInstance = null;
52
 
53
                public float offsetX = 0;
54
                public float offsetY = 0;
55
 
56
                public float width;
57
 
58
                public CharacterInfo(char c)
59
                {
60
                        mCharacter = c;
61
                }
62
 
63
                public final char getCharacter()
64
                {
65
                        return mCharacter;
66
                }
67
 
68
                public void setSpriteInstance(SpriteInstance instance)
69
                {
70
                        mSpriteInstance = instance;
71
                }
72
 
73
                public final SpriteInstance getSpriteInstance()
74
                {
75
                        return mSpriteInstance;
76
                }
77
 
78
                public void render()
79
                {
80
                        if (mSpriteInstance == null)
81
                                return;
82
 
83
                        mSpriteInstance.render();
84
                }
85
        }
86
 
87
        private CharacterInfo[] mCharacters = null;
88
        private float mAscent = 0.0f;
89
        private float mGlobalMultiplier = 2.0f;
90
        private Sprite mSprite = null;
91
 
92
        private Hashtable<KerningPair, Integer> mKernings = new Hashtable<KerningPair, Integer>();
93
 
94
        /** The y difference of a line break in multiples of line height. */
95
        private float mLineBreakFactor = 1.0f;
96
 
97
        public Font(Graphics graphics)
98
        {
99
                super(graphics);
100
 
101
        }
102
 
103
        public void dispose()
104
        {
105
                mCharacters = null;            
106
        }
107
 
108
        public void setAscent(float ascent)
109
        {
110
                mAscent = ascent;
111
        }
112
 
113
        public void setCharacters(CharacterInfo[] characters)
114
        {
115
                mCharacters = characters;
116
        }
117
 
118
        public void setSprite(Sprite sprite)
119
        {
120
                mSprite = sprite;
121
        }
122
 
123
        public void setGlobalMultiplier(float multiplier)
124
        {
125
                mGlobalMultiplier = multiplier;
126
        }
127
 
128
        public void drawText(String text, float x, float y, float scale)
129
        {
130
                drawText(text, x, y, DEFAULT_COLOR, scale);
131
        }
132
 
133
        public void drawText(String text, float x, float y)
134
        {
135
                drawText(text, x, y, DEFAULT_COLOR);
136
        }
137
 
138
        public void drawText(String text, float x, float y, Vector4 color)
139
        {
140
                drawText(text, x, y, color, 1.0f);
141
        }
142
 
143
        public void drawTextDirect(String text, float x, float y, Vector4 color, float scale)
144
        {
145
                float posX = x;
146
                float posY = y;
147
 
148
                for (int i = 0; i < text.length(); i++)
149
                {
150
                        if (text.charAt(i) == '\n')
151
                        {
152
                                posY += mAscent * mLineBreakFactor * scale;
153
                                posX = x;
154
                                continue;
155
                        }
156
 
157
                        int n = getCharacterIndexNoCase(text.charAt(i));
158
                        if (n == -1)
159
                        {
160
                                continue;
161
                        }
162
 
163
                        CharacterInfo c = mCharacters[n];
164
 
165
                        int kerning = 0;
166
                        if (i < (text.length()-1))
167
                        {
168
                                // apply kerning if any
169
                                char first = c.getCharacter();
170
                                char second = text.charAt(i+1);
171
 
172
                                kerning = getKerning(first, second);
173
                        }
174
                        if (c.mSpriteInstance != null)
175
                        {                      
176
                                c.mSpriteInstance.transform.x = posX;
177
                                c.mSpriteInstance.transform.y = posY;
178
                                c.mSpriteInstance.color = color;
179
                                c.mSpriteInstance.transform.w = c.mSpriteInstance.getSpriteRegion().getWidth() * scale * mGlobalMultiplier * c.mSpriteInstance.getSprite().getTextureWidth();
180
                                c.mSpriteInstance.transform.h = c.mSpriteInstance.getSpriteRegion().getHeight() * scale * mGlobalMultiplier * c.mSpriteInstance.getSprite().getTextureHeight();
181
                                //c.mSpriteInstance.param.w = mSprite.getRegionWidth(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
182
                                //c.mSpriteInstance.param.h = mSprite.getRegionHeight(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
183
                                c.mSpriteInstance.transform.pivotX = 0;
184
                                c.mSpriteInstance.transform.pivotY = 0;
185
                                c.mSpriteInstance.render();
186
                        }
187
 
188
                        posX += c.width * scale + kerning - c.offsetX;
189
                }
190
        }
191
 
192
        public void drawText(String text, float x, float y, Vector4 color, float scale)
193
        {
194
                float posX = x;
195
                float posY = y;
196
 
197
                TileBatch batch = getGraphics().getBatch();
198
 
199
                batch.begin();
200
 
201
                for (int i = 0; i < text.length(); i++)
202
                {
203
                        if (text.charAt(i) == '\n')
204
                        {
205
                                posY += mAscent * mLineBreakFactor * scale;
206
                                posX = x;
207
                                continue;
208
                        }
209
 
210
                        int n = getCharacterIndexNoCase(text.charAt(i));
211
                        if (n == -1)
212
                        {
213
                                continue;
214
                        }
215
 
216
                        CharacterInfo c = mCharacters[n];
217
 
218
                        int kerning = 0;
219
                        if (i < (text.length()-1))
220
                        {
221
                                // apply kerning if any
222
                                char first = c.getCharacter();
223
                                char second = text.charAt(i+1);
224
 
225
                                kerning = getKerning(first, second);
226
                        }
227
                        if (c.mSpriteInstance != null)
228
                        {                      
229
                                c.mSpriteInstance.transform.x = posX;
230
                                c.mSpriteInstance.transform.y = posY;
231
                                c.mSpriteInstance.color = color;
232
                                /*c.mSpriteInstance.transform.w = c.mSpriteInstance.getSpriteRegion().getWidth() * scale * mGlobalMultiplier;
233
                                c.mSpriteInstance.transform.h = c.mSpriteInstance.getSpriteRegion().getHeight() * scale * mGlobalMultiplier;*/
234
                                c.mSpriteInstance.transform.w = c.mSpriteInstance.getSpriteRegion().getWidth() * scale * mGlobalMultiplier * c.mSpriteInstance.getSprite().getTextureWidth();
235
                                c.mSpriteInstance.transform.h = c.mSpriteInstance.getSpriteRegion().getHeight() * scale * mGlobalMultiplier * c.mSpriteInstance.getSprite().getTextureHeight();
236
 
237
                                //c.mSpriteInstance.param.w = mSprite.getRegionWidth(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
238
                                //c.mSpriteInstance.param.h = mSprite.getRegionHeight(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
239
                                c.mSpriteInstance.transform.pivotX = 0;
240
                                c.mSpriteInstance.transform.pivotY = 0;
241
 
242
                                batch.drawSprite(c.mSpriteInstance);
243
                        }
244
 
245
                        posX += c.width * scale + kerning - c.offsetX;
246
                }
247
 
248
                batch.end();
249
        }
250
 
251
        public float getTextWidth(String text, float scale)
252
        {
253
                float maxWidth = 0;
254
                float width = 0;
255
                float posX = 0;
256
 
257
                for (int i = 0; i < text.length(); i++)
258
                {
259
                        if (text.charAt(i) == '\n')
260
                        {
261
                                posX = 0;
262
                                continue;
263
                        }
264
 
265
                        int n = getCharacterIndexNoCase(text.charAt(i));
266
                        if (n == -1)
267
                        {
268
                                continue;
269
                        }
270
 
271
                        CharacterInfo c = mCharacters[n];
272
                        int kerning = 0;
273
                        if (i < (text.length()-1))
274
                        {
275
                                // apply kerning if any
276
                                char first = c.getCharacter();
277
                                char second = text.charAt(i+1);
278
 
279
                                kerning = getKerning(first, second);
280
                        }
281
 
282
                        width = posX + c.width * scale;
283
 
284
                        if (maxWidth < width)
285
                        {
286
                                maxWidth = width;
287
                        }
288
 
289
                        posX += c.width * scale + kerning - c.offsetX;
290
                }
291
 
292
                return maxWidth;
293
        }
294
 
295
        public float getTextHeight(String text, float scale)
296
        {
297
                float maxHeight = 0;
298
                float posY = 0;
299
 
300
 
301
 
302
                for (int i = 0; i < text.length(); i++)
303
                {
304
                        if (text.charAt(i) == '\n')
305
                        {
306
                                posY += mAscent * mLineBreakFactor * scale;
307
                                continue;
308
                        }
309
 
310
                        int n = getCharacterIndexNoCase(text.charAt(i));
311
                        if (n == -1)
312
                        {
313
                                continue;
314
                        }
315
 
316
                        float charHeight = this.mAscent * scale;
317
 
318
                        if ((posY + charHeight) > maxHeight)
319
                        {
320
                                maxHeight = posY + charHeight;
321
                        }
322
                }
323
 
324
                return maxHeight;
325
        }
326
 
327
        public int getCharacterIndex(char c)
328
        {
329
                for (int i = 0; i < mCharacters.length; i++)
330
                {
331
                        if (mCharacters[i].getCharacter() == c)
332
                                return i;
333
                }
334
 
335
                return -1;
336
        }
337
 
338
        public int getCharacterIndexNoCase(char c)
339
        {
340
                int n = getCharacterIndex(c);
341
                if (n == -1)
342
                {
343
                        n = getCharacterIndex(Character.toLowerCase(c));
344
                        if (n == -1)
345
                        {
346
                                n = getCharacterIndex(Character.toUpperCase(c));
347
                        }
348
                }
349
                return n;
350
        }
351
 
352
        public CharacterInfo getCharacter(char c)
353
        {
354
                int i = getCharacterIndex(c);
355
 
356
                if (i != -1)
357
                        return mCharacters[i];
358
 
359
                return null;
360
        }
361
 
362
        public void setKerning(char first, char second, int value)
363
        {
364
                mKernings.put(new KerningPair(first, second), value);
365
        }
366
 
367
        public int getKerning(char first, char second)
368
        {
369
                Integer value = mKernings.get(new KerningPair(first, second));
370
 
371
                if (value == null)
372
                        return 0;
373
 
374
                return value;
375
        }
376
 
377
        public void setFiltering(boolean filter)
378
        {
379
                /*
380
                // HACK: should use own texture class
381
                if (filter)
382
                        getGraphics().renderStates.getTextureStage(0).setTextureFilter(mSprite.getTexture(), TextureFilter.Linear, TextureFilter.Linear);
383
                else
384
                        getGraphics().renderStates.getTextureStage(0).setTextureFilter(mSprite.getTexture(), TextureFilter.Nearest, TextureFilter.Nearest);*/
385
 
386
                if (filter)
387
                        mSprite.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
388
                else
389
                        mSprite.getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
390
        }
391
 
392
        public final void setLineBreak(float multiple) { mLineBreakFactor = multiple; }
393
        public final float getLineBreak() { return mLineBreakFactor; }
394
 
395
 
396
}
397
 
398