00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package uk.co.blogspot.fractiousg.texample;
00011
00012 import android.content.res.AssetManager;
00013 import android.graphics.Bitmap;
00014 import android.graphics.Canvas;
00015 import android.graphics.Paint;
00016 import android.graphics.Typeface;
00017 import android.opengl.GLUtils;
00018 import android.util.Log;
00019
00020 import javax.microedition.khronos.opengles.GL10;
00021
00022 public class GLText {
00023
00024
00025 public final static int CHAR_START = 32;
00026 public final static int CHAR_END = 126;
00027 public final static int CHAR_CNT = ( ( ( CHAR_END - CHAR_START ) + 1 ) + 1 );
00028
00029 public final static int CHAR_NONE = 32;
00030 public final static int CHAR_UNKNOWN = ( CHAR_CNT - 1 );
00031
00032 public final static int FONT_SIZE_MIN = 6;
00033 public final static int FONT_SIZE_MAX = 180;
00034
00035 public final static int CHAR_BATCH_SIZE = 100;
00036
00037
00038 GL10 gl;
00039 AssetManager assets;
00040 SpriteBatch batch;
00041
00042 int fontPadX, fontPadY;
00043
00044 float fontHeight;
00045 float fontAscent;
00046 float fontDescent;
00047
00048 int textureId;
00049 int textureSize;
00050 TextureRegion textureRgn;
00051
00052 float charWidthMax;
00053 float charHeight;
00054 final float[] charWidths;
00055 TextureRegion[] charRgn;
00056 int cellWidth, cellHeight;
00057 int rowCnt, colCnt;
00058
00059 float scaleX, scaleY;
00060 float spaceX;
00061
00062
00063
00064
00065
00066 public GLText(GL10 gl, AssetManager assets) {
00067 this.gl = gl;
00068 this.assets = assets;
00069
00070 batch = new SpriteBatch( gl, CHAR_BATCH_SIZE );
00071
00072 charWidths = new float[CHAR_CNT];
00073 charRgn = new TextureRegion[CHAR_CNT];
00074
00075
00076 fontPadX = 0;
00077 fontPadY = 0;
00078
00079 fontHeight = 0.0f;
00080 fontAscent = 0.0f;
00081 fontDescent = 0.0f;
00082
00083 textureId = -1;
00084 textureSize = 0;
00085
00086 charWidthMax = 0;
00087 charHeight = 0;
00088
00089 cellWidth = 0;
00090 cellHeight = 0;
00091 rowCnt = 0;
00092 colCnt = 0;
00093
00094 scaleX = 1.0f;
00095 scaleY = 1.0f;
00096 spaceX = 0.0f;
00097 }
00098
00099 public boolean load(String file, int size, int padX, int padY) {
00100 Typeface tf = Typeface.createFromAsset( assets, file );
00101 return load(tf, size, padX, padY);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 public boolean load(Typeface tf, int size, int padX, int padY) {
00113
00114
00115 fontPadX = padX;
00116 fontPadY = padY;
00117
00118
00119 Paint paint = new Paint();
00120 paint.setAntiAlias( true );
00121 paint.setTextSize( size );
00122 paint.setColor( 0xffffffff );
00123 paint.setTypeface( tf );
00124
00125
00126 Paint.FontMetrics fm = paint.getFontMetrics();
00127 fontHeight = (float)Math.ceil( Math.abs( fm.bottom ) + Math.abs( fm.top ) );
00128 fontAscent = (float)Math.ceil( Math.abs( fm.ascent ) );
00129 fontDescent = (float)Math.ceil( Math.abs( fm.descent ) );
00130
00131
00132
00133 char[] s = new char[2];
00134 charWidthMax = charHeight = 0;
00135 float[] w = new float[2];
00136 int cnt = 0;
00137 for ( char c = CHAR_START; c <= CHAR_END; c++ ) {
00138 s[0] = c;
00139 paint.getTextWidths( s, 0, 1, w );
00140 charWidths[cnt] = w[0];
00141 if ( charWidths[cnt] > charWidthMax )
00142 charWidthMax = charWidths[cnt];
00143 cnt++;
00144 }
00145 s[0] = CHAR_NONE;
00146 paint.getTextWidths( s, 0, 1, w );
00147 charWidths[cnt] = w[0];
00148 if ( charWidths[cnt] > charWidthMax )
00149 charWidthMax = charWidths[cnt];
00150 cnt++;
00151
00152
00153 charHeight = fontHeight;
00154
00155
00156 cellWidth = (int)charWidthMax + ( 2 * fontPadX );
00157 cellHeight = (int)charHeight + ( 2 * fontPadY );
00158 int maxSize = cellWidth > cellHeight ? cellWidth : cellHeight;
00159 if ( maxSize < FONT_SIZE_MIN || maxSize > FONT_SIZE_MAX )
00160 return false;
00161
00162
00163
00164
00165 if ( maxSize <= 24 )
00166 textureSize = 256;
00167 else if ( maxSize <= 40 )
00168 textureSize = 512;
00169 else if ( maxSize <= 80 )
00170 textureSize = 1024;
00171 else
00172 textureSize = 2048;
00173
00174
00175 Bitmap bitmap = Bitmap.createBitmap( textureSize, textureSize, Bitmap.Config.ALPHA_8 );
00176 Canvas canvas = new Canvas( bitmap );
00177 bitmap.eraseColor( 0x00000000 );
00178
00179
00180
00181 colCnt = textureSize / cellWidth;
00182 rowCnt = (int)Math.ceil( (float)CHAR_CNT / (float)colCnt );
00183
00184
00185 float x = fontPadX;
00186 float y = ( cellHeight - 1 ) - fontDescent - fontPadY;
00187 for ( char c = CHAR_START; c <= CHAR_END; c++ ) {
00188 s[0] = c;
00189 canvas.drawText( s, 0, 1, x, y, paint );
00190 x += cellWidth;
00191 if ( ( x + cellWidth - fontPadX ) > textureSize ) {
00192 x = fontPadX;
00193 y += cellHeight;
00194 }
00195 }
00196 s[0] = CHAR_NONE;
00197 canvas.drawText( s, 0, 1, x, y, paint );
00198
00199
00200 int[] textureIds = new int[1];
00201 gl.glGenTextures( 1, textureIds, 0 );
00202 Log.i("text handle", "" + textureIds[0]);
00203 textureId = textureIds[0];
00204
00205
00206 gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId );
00207 gl.glTexParameterf( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST );
00208 gl.glTexParameterf( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR );
00209 gl.glTexParameterf( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE );
00210 gl.glTexParameterf( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE );
00211
00212
00213 GLUtils.texImage2D( GL10.GL_TEXTURE_2D, 0, bitmap, 0 );
00214 gl.glBindTexture( GL10.GL_TEXTURE_2D, 0 );
00215
00216
00217 bitmap.recycle();
00218
00219
00220 x = 0;
00221 y = 0;
00222 for ( int c = 0; c < CHAR_CNT; c++ ) {
00223 charRgn[c] = new TextureRegion( textureSize, textureSize, x, y, cellWidth-1, cellHeight-1 );
00224 x += cellWidth;
00225 if ( x + cellWidth > textureSize ) {
00226 x = 0;
00227 y += cellHeight;
00228 }
00229 }
00230
00231
00232 textureRgn = new TextureRegion( textureSize, textureSize, 0, 0, textureSize, textureSize );
00233
00234
00235 return true;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 public void begin() {
00245 begin( 1.0f, 1.0f, 1.0f, 1.0f );
00246 }
00247 public void begin(float alpha) {
00248 begin( 1.0f, 1.0f, 1.0f, alpha );
00249 }
00250 public void begin(float red, float green, float blue, float alpha) {
00251 gl.glColor4f( red, green, blue, alpha );
00252 gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId );
00253 batch.beginBatch();
00254 }
00255 public void end() {
00256 batch.endBatch();
00257 gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
00258 gl.glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
00259 }
00260
00261
00262
00263
00264
00265
00266 public void draw(String text, float x, float y) {
00267 float chrHeight = cellHeight * scaleY;
00268 float chrWidth = cellWidth * scaleX;
00269 int len = text.length();
00270 x += ( chrWidth / 2.0f ) - ( fontPadX * scaleX );
00271 y += ( chrHeight / 2.0f ) - ( fontPadY * scaleY );
00272 for ( int i = 0; i < len; i++ ) {
00273 int c = (int)text.charAt( i ) - CHAR_START;
00274 if ( c < 0 || c >= CHAR_CNT )
00275 c = CHAR_UNKNOWN;
00276 batch.drawSprite( x, y, chrWidth, chrHeight, charRgn[c] );
00277 x += ( charWidths[c] + spaceX ) * scaleX;
00278 }
00279 }
00280
00281
00282
00283
00284
00285
00286 public float drawC(String text, float x, float y) {
00287 float len = getLength( text );
00288 draw( text, x - ( len / 2.0f ), y - ( getCharHeight() / 2.0f ) );
00289 return len;
00290 }
00291 public float drawCX(String text, float x, float y) {
00292 float len = getLength( text );
00293 draw( text, x - ( len / 2.0f ), y );
00294 return len;
00295 }
00296 public void drawCY(String text, float x, float y) {
00297 draw( text, x, y - ( getCharHeight() / 2.0f ) );
00298 }
00299
00300
00301
00302
00303
00304
00305 public void setScale(float scale) {
00306 scaleX = scaleY = scale;
00307 }
00308 public void setScale(float sx, float sy) {
00309 scaleX = sx;
00310 scaleY = sy;
00311 }
00312
00313
00314
00315
00316
00317 public float getScaleX() {
00318 return scaleX;
00319 }
00320 public float getScaleY() {
00321 return scaleY;
00322 }
00323
00324
00325
00326
00327
00328 public void setSpace(float space) {
00329 spaceX = space;
00330 }
00331
00332
00333
00334
00335
00336 public float getSpace() {
00337 return spaceX;
00338 }
00339
00340
00341
00342
00343
00344 public float getLength(String text) {
00345 float len = 0.0f;
00346 int strLen = text.length();
00347 for ( int i = 0; i < strLen; i++ ) {
00348 int c = (int)text.charAt( i ) - CHAR_START;
00349 len += ( charWidths[c] * scaleX );
00350 }
00351 len += ( strLen > 1 ? ( ( strLen - 1 ) * spaceX ) * scaleX : 0 );
00352 return len;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 public float getCharWidth(char chr) {
00362 int c = chr - CHAR_START;
00363 return ( charWidths[c] * scaleX );
00364 }
00365 public float getCharWidthMax() {
00366 return ( charWidthMax * scaleX );
00367 }
00368 public float getCharHeight() {
00369 return ( charHeight * scaleY );
00370 }
00371
00372
00373
00374
00375
00376 public float getAscent() {
00377 return ( fontAscent * scaleY );
00378 }
00379 public float getDescent() {
00380 return ( fontDescent * scaleY );
00381 }
00382 public float getHeight() {
00383 return ( fontHeight * scaleY );
00384 }
00385 }