1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.graphics.Color; 21 import com.badlogic.gdx.graphics.Colors; 22 import com.badlogic.gdx.graphics.GL20; 23 import com.badlogic.gdx.graphics.Texture.TextureFilter; 24 import com.badlogic.gdx.graphics.g2d.BitmapFont; 25 import com.badlogic.gdx.graphics.g2d.BitmapFontCache; 26 import com.badlogic.gdx.graphics.g2d.GlyphLayout; 27 import com.badlogic.gdx.graphics.g2d.GlyphLayout.GlyphRun; 28 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 29 import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 30 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; 31 import com.badlogic.gdx.scenes.scene2d.Stage; 32 import com.badlogic.gdx.scenes.scene2d.ui.Label; 33 import com.badlogic.gdx.scenes.scene2d.ui.Skin; 34 import com.badlogic.gdx.scenes.scene2d.ui.Window; 35 import com.badlogic.gdx.tests.utils.GdxTest; 36 import com.badlogic.gdx.utils.Align; 37 import com.badlogic.gdx.utils.viewport.ScreenViewport; 38 39 public class BitmapFontTest extends GdxTest { 40 private Stage stage; 41 private SpriteBatch spriteBatch; 42 private BitmapFont font; 43 private ShapeRenderer renderer; 44 private BitmapFont multiPageFont; 45 private GlyphLayout layout; 46 private Label label; 47 48 @Override create()49 public void create () { 50 spriteBatch = new SpriteBatch(); 51 // font = new BitmapFont(Gdx.files.internal("data/verdana39.fnt"), false); 52 font = new BitmapFont(Gdx.files.internal("data/arial-32-pad.fnt"), false); 53 // font = new FreeTypeFontGenerator(Gdx.files.internal("data/arial.ttf")).generateFont(new FreeTypeFontParameter()); 54 font.getData().markupEnabled = true; 55 font.getData().breakChars = new char[] {'-'}; 56 57 multiPageFont = new BitmapFont(Gdx.files.internal("data/multipagefont.fnt")); 58 59 // Add user defined color 60 Colors.put("PERU", Color.valueOf("CD853F")); 61 62 renderer = new ShapeRenderer(); 63 renderer.setProjectionMatrix(spriteBatch.getProjectionMatrix()); 64 65 stage = new Stage(new ScreenViewport()); 66 67 Skin skin = new Skin(Gdx.files.internal("data/uiskin.json")); 68 69 BitmapFont labelFont = skin.get("default-font", BitmapFont.class); 70 labelFont.getData().markupEnabled = true; 71 72 // Notice that the last [] has been deliberately added to test the effect of excessive pop operations. 73 // They are silently ignored, as expected. 74 label = new Label("<<[BLUE]M[RED]u[YELLOW]l[GREEN]t[OLIVE]ic[]o[]l[]o[]r[]*[MAROON]Label[][] [Unknown Color]>>", skin); 75 label.setPosition(100, 200); 76 stage.addActor(label); 77 78 Window window = new Window("[RED]Multicolor[GREEN] Title", skin); 79 window.setPosition(400, 300); 80 window.pack(); 81 stage.addActor(window); 82 83 layout = new GlyphLayout(); 84 } 85 86 @Override render()87 public void render () { 88 // red.a = (red.a + Gdx.graphics.getDeltaTime() * 0.1f) % 1; 89 90 int viewHeight = Gdx.graphics.getHeight(); 91 92 Gdx.gl.glClearColor(0, 0, 0, 1); 93 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 94 95 // Test wrapping or truncation with the font directly. 96 if (!true) { 97 // BitmapFont font = label.getStyle().font; 98 BitmapFont font = this.font; 99 font.getRegion().getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest); 100 101 font.getData().setScale(2f); 102 renderer.begin(ShapeRenderer.ShapeType.Line); 103 renderer.setColor(0, 1, 0, 1); 104 float w = Gdx.input.getX(); 105 // w = 855; 106 renderer.rect(10, 10, w, 500); 107 renderer.end(); 108 109 spriteBatch.begin(); 110 String text = "your new"; 111 text = "How quickly [RED]daft jumping zebras vex."; 112 // text = "Another font wrap is-sue, this time with multiple whitespace characters."; 113 text = "test with AGWlWi AGWlWi issue"; 114 if (true) { // Test wrap. 115 layout.setText(font, text, 0, text.length(), font.getColor(), w, Align.center, true, null); 116 } else { // Test truncation. 117 layout.setText(font, text, 0, text.length(), font.getColor(), w, Align.center, false, "..."); 118 } 119 float meowy = (500 / 2 + layout.height / 2 + 5); 120 font.draw(spriteBatch, layout, 10, 10 + meowy); 121 spriteBatch.end(); 122 123 renderer.begin(ShapeRenderer.ShapeType.Line); 124 renderer.setColor(0, 1, 0, 1); 125 for (int i = 0, n = layout.runs.size; i < n; i++) { 126 GlyphRun r = layout.runs.get(i); 127 renderer.rect(10 + r.x, 10 + meowy + r.y, r.width, -font.getLineHeight()); 128 } 129 renderer.end(); 130 font.getData().setScale(1f); 131 return; 132 } 133 134 // Test wrapping with label. 135 if (false) { 136 label.debug(); 137 label.getStyle().font = font; 138 label.setStyle(label.getStyle()); 139 label.setText("How quickly [RED]daft[] jumping zebras vex."); 140 label.setWrap(true); 141 // label.setEllipsis(true); 142 label.setAlignment(Align.center, Align.right); 143 label.setWidth(Gdx.input.getX() - label.getX()); 144 label.setHeight(label.getPrefHeight()); 145 } else { 146 // Test various font features. 147 spriteBatch.begin(); 148 149 String text = "Sphinx of black quartz, judge my vow."; 150 font.setColor(Color.RED); 151 152 float x = 100, y = 20; 153 float alignmentWidth; 154 155 if (false) { 156 alignmentWidth = 0; 157 font.draw(spriteBatch, text, x, viewHeight - y, alignmentWidth, Align.right, false); 158 } 159 160 if (true) { 161 alignmentWidth = 280; 162 font.draw(spriteBatch, text, x, viewHeight - y, alignmentWidth, Align.right, true); 163 } 164 165 font.draw(spriteBatch, "[", 50, 60, 100, Align.left, true); 166 font.getData().markupEnabled = true; 167 font.draw(spriteBatch, "[", 100, 60, 100, Align.left, true); 168 font.getData().markupEnabled = false; 169 170 // 'R' and 'p' are in different pages 171 String txt2 = "this font uses " + multiPageFont.getRegions().size + " texture pages: RpRpRpRpRpNM"; 172 spriteBatch.renderCalls = 0; 173 174 // regular draw function 175 multiPageFont.setColor(Color.BLUE); 176 multiPageFont.draw(spriteBatch, txt2, 10, 100); 177 178 // expert usage.. drawing with bitmap font cache 179 BitmapFontCache cache = multiPageFont.getCache(); 180 cache.clear(); 181 cache.setColor(Color.BLACK); 182 cache.setText(txt2, 10, 50); 183 cache.setColors(Color.PINK, 3, 6); 184 cache.setColors(Color.ORANGE, 9, 12); 185 cache.setColors(Color.GREEN, 16, txt2.length()); 186 cache.draw(spriteBatch, 5, txt2.length() - 5); 187 188 cache.clear(); 189 cache.setColor(Color.BLACK); 190 float textX = 10; 191 textX += cache.setText("[black] ", textX, 150).width; 192 multiPageFont.getData().markupEnabled = true; 193 textX += cache.addText("[[[PINK]pink[]] ", textX, 150).width; 194 textX += cache.addText("[PERU][[peru] ", textX, 150).width; 195 cache.setColor(Color.GREEN); 196 textX += cache.addText("green ", textX, 150).width; 197 textX += cache.addText("[#A52A2A]br[#A52A2ADF]ow[#A52A2ABF]n f[#A52A2A9F]ad[#A52A2A7F]in[#A52A2A5F]g o[#A52A2A3F]ut ", 198 textX, 150).width; 199 multiPageFont.getData().markupEnabled = false; 200 201 cache.draw(spriteBatch); 202 203 // tinting 204 cache.tint(new Color(1f, 1f, 1f, 0.3f)); 205 cache.translate(0f, 40f); 206 cache.draw(spriteBatch); 207 208 spriteBatch.end(); 209 // System.out.println(spriteBatch.renderCalls); 210 211 renderer.begin(ShapeType.Line); 212 renderer.setColor(Color.BLACK); 213 renderer.rect(x, viewHeight - y - 200, alignmentWidth, 200); 214 renderer.end(); 215 } 216 217 stage.act(Gdx.graphics.getDeltaTime()); 218 stage.draw(); 219 } 220 resize(int width, int height)221 public void resize (int width, int height) { 222 spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, width, height); 223 renderer.setProjectionMatrix(spriteBatch.getProjectionMatrix()); 224 stage.getViewport().update(width, height, true); 225 } 226 227 @Override dispose()228 public void dispose () { 229 spriteBatch.dispose(); 230 renderer.dispose(); 231 font.dispose(); 232 233 // Restore predefined colors 234 Colors.reset(); 235 } 236 } 237