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.extensions; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.graphics.Color; 21 import com.badlogic.gdx.graphics.GL20; 22 import com.badlogic.gdx.graphics.g2d.BitmapFont; 23 import com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph; 24 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 25 import com.badlogic.gdx.graphics.g2d.TextureRegion; 26 import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; 27 import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeBitmapFontData; 28 import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; 29 import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 30 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; 31 import com.badlogic.gdx.tests.utils.GdxTest; 32 import com.badlogic.gdx.utils.Align; 33 import com.badlogic.gdx.utils.Array; 34 35 public class FreeTypeIncrementalTest extends GdxTest { 36 SpriteBatch batch; 37 ShapeRenderer shapes; 38 BitmapFont font; 39 FreeTypeFontGenerator generator; 40 create()41 public void create () { 42 batch = new SpriteBatch(); 43 shapes = new ShapeRenderer(); 44 shapes.setColor(Color.RED); 45 46 FreeTypeFontGenerator.setMaxTextureSize(128); 47 48 generator = new FreeTypeFontGenerator(Gdx.files.internal("data/arial.ttf")); 49 50 FreeTypeFontParameter param = new FreeTypeFontParameter(); 51 param.incremental = true; 52 param.size = 24; 53 param.characters = "howdY\u0000"; 54 55 FreeTypeBitmapFontData data = new FreeTypeBitmapFontData() { 56 public int getWrapIndex (Array<Glyph> glyphs, int start) { 57 return SimplifiedChinese.getWrapIndex(glyphs, start); 58 } 59 }; 60 61 // By default latin chars are used for x and cap height, causing some fonts to display non-latin chars out of bounds. 62 data.xChars = new char[] {'动'}; 63 data.capChars = new char[] {'动'}; 64 65 font = generator.generateFont(param, data); 66 } 67 render()68 public void render () { 69 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 70 71 // Draw rects. 72 shapes.begin(ShapeType.Line); 73 float x = 0, y = Gdx.graphics.getHeight() - font.getRegion().getRegionHeight() - 1; 74 for (int i = 0, n = font.getRegions().size; i < n; i++) { 75 TextureRegion region = font.getRegions().get(i); 76 shapes.rect(x, y, region.getRegionWidth(), region.getRegionHeight()); 77 x += region.getRegionWidth() + 2; 78 } 79 shapes.rect(10, 250, Gdx.graphics.getWidth() - 20, -240); 80 shapes.end(); 81 82 batch.begin(); 83 x = 0; 84 for (int i = 0, n = font.getRegions().size; i < n; i++) { 85 TextureRegion region = font.getRegions().get(i); 86 batch.draw(region, x, y); 87 x += region.getRegionWidth() + 2; 88 } 89 font.draw(batch, "LYA", 10, 300); // Shows kerning. 90 font.draw(batch, "hello world", 100, 300); 91 font.draw(batch, 92 "动画能给游戏带来生机和灵气。我们相信创作一段美妙的动画,不仅需要强大的软件工具,更需要一套牛 B 的工作流程。" // 93 + "Spine专注于此,为您创建惊艳的骨骼动画,并将其整合到游戏当中,提供了一套高效的工作流程。", 94 10, 250, // 95 Gdx.graphics.getWidth() - 20, Align.left, true); 96 batch.end(); 97 } 98 resize(int width, int height)99 public void resize (int width, int height) { 100 batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height); 101 shapes.setProjectionMatrix(batch.getProjectionMatrix()); 102 } 103 104 static public class SimplifiedChinese { getWrapIndex(Array<Glyph> glyphs, int start)105 public static int getWrapIndex (Array<Glyph> glyphs, int start) { 106 int i = start - 1; 107 for (; i >= 1; i--) { 108 int startChar = glyphs.get(i).id; 109 if (!SimplifiedChinese.legalAtStart(startChar)) continue; 110 int endChar = glyphs.get(i - 1).id; 111 if (!SimplifiedChinese.legalAtEnd(endChar)) continue; 112 // Don't wrap between ASCII chars. 113 if (startChar < 127 && endChar < 127 && !Character.isWhitespace(startChar)) continue; 114 return i; 115 } 116 return start; 117 } 118 legalAtStart(int ch)119 static private boolean legalAtStart (int ch) { 120 switch (ch) { 121 case '!': 122 case '%': 123 case ')': 124 case ',': 125 case '.': 126 case ':': 127 case ';': 128 case '>': 129 case '?': 130 case ']': 131 case '}': 132 case '¢': 133 case '¨': 134 case '°': 135 case '·': 136 case 'ˇ': 137 case 'ˉ': 138 case '―': 139 case '‖': 140 case '’': 141 case '”': 142 case '„': 143 case '‟': 144 case '†': 145 case '‡': 146 case '›': 147 case '℃': 148 case '∶': 149 case '、': 150 case '。': 151 case '〃': 152 case '〆': 153 case '〈': 154 case '《': 155 case '「': 156 case '『': 157 case '〕': 158 case '〗': 159 case '〞': 160 case '﹘': 161 case '﹚': 162 case '﹜': 163 case '!': 164 case '"': 165 case '%': 166 case ''': 167 case ')': 168 case ',': 169 case '.': 170 case ':': 171 case ';': 172 case '?': 173 case ']': 174 case '`': 175 case '|': 176 case '}': 177 case '~': 178 return false; 179 } 180 return true; 181 } 182 legalAtEnd(int ch)183 static private boolean legalAtEnd (int ch) { 184 switch (ch) { 185 case '$': 186 case '(': 187 case '*': 188 case ',': 189 case '£': 190 case '¥': 191 case '·': 192 case '‘': 193 case '“': 194 case '〈': 195 case '《': 196 case '「': 197 case '『': 198 case '【': 199 case '〔': 200 case '〖': 201 case '〝': 202 case '﹗': 203 case '﹙': 204 case '﹛': 205 case '$': 206 case '(': 207 case '.': 208 case '[': 209 case '{': 210 case '£': 211 case '¥': 212 return false; 213 } 214 return true; 215 } 216 } 217 } 218