Multi-byte languages such as Korean, Chinese needs multiple number of bitmap textures for text.
I’d like to add the functionality to BitmapText, but then I have to change it from geometry to Node,
So I introduced MultiPageBitmapText.
Please change the class name if it is ugly.
[patch]
Index: src/core-plugins/com/jme3/font/plugins/BitmapFontLoader.java
===================================================================
— src/core-plugins/com/jme3/font/plugins/BitmapFontLoader.java (revision 6397)
+++ src/core-plugins/com/jme3/font/plugins/BitmapFontLoader.java (working copy)
@@ -142,6 +142,8 @@
ch.setYOffset(Integer.parseInt(tokens));
}else if (token.equals(“xadvance”)){
ch.setXAdvance(Integer.parseInt(tokens));
-
} else if (token.equals("page")) {<br />
-
ch.setPage(Integer.parseInt(tokens<i>));<br />
}
}
}else if (tokens[0].equals("kerning")){
Index: src/core/com/jme3/font/MultiPageBitmapText.java
===================================================================
— src/core/com/jme3/font/MultiPageBitmapText.java (revision 0)
+++ src/core/com/jme3/font/MultiPageBitmapText.java (revision 0)
@@ -0,0 +1,96 @@
+package com.jme3.font;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import com.jme3.math.ColorRGBA;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.VertexBuffer;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.util.BufferUtils;
+
+public class MultiPageBitmapText extends Node {
- private final BitmapText[] bitmapTexts;
+
- public MultiPageBitmapText(BitmapFont font) {
-
this(font, false, false);<br />
- }
+
- public MultiPageBitmapText(BitmapFont font, boolean rightToLeft) {
-
this(font, rightToLeft, false);<br />
- }
+
- public MultiPageBitmapText(BitmapFont font, boolean rightToLeft, boolean arrayBased) {
-
bitmapTexts = new BitmapText[font.getPageSize()];<br />
-
for (int page = 0; page < bitmapTexts.length; page++) {<br />
-
bitmapTexts[page] = new BitmapText(font, rightToLeft, arrayBased, page);<br />
-
attachChild(bitmapTexts[page]);<br />
-
}<br />
- }
+
- public void setBox(Rectangle rectangle) {
-
for (BitmapText t : bitmapTexts) {<br />
-
t.setBox(rectangle);<br />
-
}<br />
- }
+
- public void setSize(float size) {
-
for (BitmapText t : bitmapTexts) {<br />
-
t.setSize(size);<br />
-
}<br />
- }
+
- public void setText(CharSequence text) {
-
for (BitmapText t : bitmapTexts) {<br />
-
t.setText(text);<br />
-
}<br />
- }
+
- public float getLineWidth() {
-
return bitmapTexts[0].getLineWidth();<br />
- }
+
- public float getLineHeight() {
-
return bitmapTexts[0].getLineHeight();<br />
- }
+
-
@Override
- public MultiPageBitmapText clone() {
-
MultiPageBitmapText clone = (MultiPageBitmapText) super.clone();<br />
-
for (int i = 0; i < bitmapTexts.length; i++) {<br />
-
clone.bitmapTexts<i> = bitmapTexts<i>.clone();<br />
-
}<br />
-
return clone;<br />
- }
+
- public BitmapFont getFont() {
-
return bitmapTexts[0].getFont();<br />
- }
+
- public String getText() {
-
return bitmapTexts[0].getText();<br />
- }
+
- public ColorRGBA getColor() {
-
return bitmapTexts[0].getColor();<br />
- }
+
- public void setColor(ColorRGBA color) {
-
for (BitmapText t : bitmapTexts) {<br />
-
t.setColor(color);<br />
-
}<br />
- }
+
- public void setAlignment(BitmapFont.Align align) {
-
for (BitmapText t : bitmapTexts) {<br />
-
t.setAlignment(align);<br />
-
}<br />
- }
+
- public BitmapFont.Align getAlignment() {
-
return bitmapTexts[0].getAlignment();<br />
- }
+
+}
Index: src/core/com/jme3/font/QuadList.java
===================================================================
— src/core/com/jme3/font/QuadList.java (revision 6397)
+++ src/core/com/jme3/font/QuadList.java (working copy)
@@ -39,10 +39,6 @@
private ArrayList<FontQuad> quads = new ArrayList<FontQuad>();
private int actualSize = 0;
- public void addQuad(FontQuad quad){
-
quads.add(quad);<br />
- }
-
public FontQuad getQuad(int index){
return quads.get(index);
}
@@ -50,17 +46,25 @@
public int getQuantity(){
return quads.size();
}
-
- public void setActualSize(int size){
-
if (quads.size() < size){<br />
-
int quadSize = quads.size();<br />
-
for (int i = 0; i < size - quadSize; i++){<br />
-
quads.add(new FontQuad());<br />
-
}<br />
-
}<br />
-
for (int i = 0; i < quads.size(); i++){<br />
-
quads.get(i).setSize(0, 0);<br />
+
- public void clear() {
-
actualSize = 0;<br />
- }
+
- public int getActualSize() {
-
return actualSize;<br />
- }
+
- public FontQuad newQuad() {
-
FontQuad q = null;<br />
-
if (actualSize == quads.size()) {<br />
-
q = new FontQuad();<br />
-
quads.add(q);<br />
-
} else {<br />
-
q = quads.get(actualSize);<br />
-
q.setSize(0, 0);<br />
}
-
actualSize++;<br />
-
return q;<br />
}
-
}
Index: src/core/com/jme3/font/BitmapText.java
===================================================================
— src/core/com/jme3/font/BitmapText.java (revision 6397)
+++ src/core/com/jme3/font/BitmapText.java (working copy)
@@ -55,8 +55,13 @@
private final float[] tc;
private final short[] idx;
private final byte[] color;
- private int page;
public BitmapText(BitmapFont font, boolean rightToLeft, boolean arrayBased) {
-
this(font, rightToLeft, arrayBased, 0);<br />
- }
+
- public BitmapText(BitmapFont font, boolean rightToLeft, boolean arrayBased, int page) {
super("BitmapFont", new Mesh());
if (font == null) {
@@ -70,8 +75,9 @@
this.font = font;
this.block = new StringBlock();
block.setSize(font.getPreferredSize());
-
this.page = page;<br />
- Material mat = font.getPage(0);
+ Material mat = font.getPage(page);
if (mat == null) {
throw new IllegalStateException("The font's texture was not found!");
}
@@ -191,9 +197,9 @@
private void assemble() {
// first generate quadlist
if (block.getTextBox() == null) {
- lineWidth = font.updateText(block, quadList, rightToLeft);
+ lineWidth = font.updateText(block, quadList, rightToLeft, page);
} else {
- lineWidth = font.updateTextRect(block, quadList);
+ lineWidth = font.updateTextRect(block, quadList, page);
}
Mesh m = getMesh();
Index: src/core/com/jme3/font/BitmapFont.java
===================================================================
--- src/core/com/jme3/font/BitmapFont.java (revision 6397)
+++ src/core/com/jme3/font/BitmapFont.java (working copy)
@@ -80,6 +80,10 @@
public Material getPage(int index) {
return pages[index];
}
+
+ public int getPageSize() {
+ return pages.length;
+ }
public BitmapCharacterSet getCharSet() {
return charSet;
@@ -109,6 +113,8 @@
private int findKerningAmount(int newLineLastChar, int nextChar) {
BitmapCharacter c = charSet.getCharacter(newLineLastChar);
+ if (c == null)
+ return 0;
return c.getKerning(nextChar);
}
@@ -163,7 +169,7 @@
return Math.max(maxLineWidth, lineWidth);
}
- public float updateText(StringBlock block, QuadList target, boolean rightToLeft) {
+ public float updateText(StringBlock block, QuadList target, boolean rightToLeft, int page) {
CharSequence text = block.getCharacters();
Align alignment = block.getAlignment();
@@ -175,10 +181,9 @@
BitmapCharacter lastChar = null;
int lineNumber = 1;
int wordNumber = 1;
- int quadIndex = -1;
float wordWidth = 0f;
boolean useKerning = block.isKerning();
- target.setActualSize(text.length());
+ target.clear();
float incrScale = rightToLeft ? -1f : 1f;
textColor.set(block.getColor());
@@ -274,13 +279,23 @@
wordWidth += kernAmount;
}
}
+
+ final float x0 = x;
+ final float wordWidth0 = wordWidth;
+
+ x += xAdvance * incrScale;
+ wordWidth += xAdvance;
+ lineWidth += xAdvance;
+
+ if (c.getPage() != page) {
+ continue;
+ }
// Create the quad
- quadIndex++;
- FontQuad q = target.getQuad(quadIndex);
+ FontQuad q = target.newQuad();
// Determine quad position
- float quadPosX = x + (xOffset * incrScale);
+ float quadPosX = x0 + (xOffset * incrScale);
if (rightToLeft){
quadPosX -= width;
}
@@ -302,21 +317,17 @@
// since this is a space,
// increment wordnumber and reset wordwidth
wordNumber++;
- wordWidth = 0f;
+ wordWidth = xAdvance;
}
// set data
- q.setWordNumber(wordNumber);
+ q.setWordWidth(wordWidth0);
q.setWordWidth(wordWidth);
q.setBitmapChar(c);
q.setSizeScale(sizeScale);
q.setCharacter(text.charAt(i));
q.setTotalWidth(kernAmount + xAdvance);
- x += xAdvance * incrScale;
- wordWidth += xAdvance;
- lineWidth += xAdvance;
-
lastChar = c;
}
}
@@ -324,7 +335,7 @@
return Math.max(lineWidth, maxLineWidth);
}
- public float updateTextRect(StringBlock b, QuadList target) {
+ public float updateTextRect(StringBlock b, QuadList target, int page) {
String text = b.getText();
float x = b.getTextBox().x;
@@ -337,13 +348,12 @@
char lastChar = 0;
int lineNumber = 1;
int wordNumber = 1;
- int quadIndex = -1;
float wordWidth = 0f;
boolean firstCharOfLine = true;
boolean useKerning = b.isKerning();
Align alignment = b.getAlignment();
- target.setActualSize(text.length());
+ target.clear();
for (int i = 0; i < text.length(); i++){
BitmapCharacter c = charSet.getCharacter((int) text.charAt(i));
@@ -382,7 +392,7 @@
lineWidth = 0f;
- for (int j = 0; j <= quadIndex; j++){
+ for (int j = 0; j <= target.getActualSize(); j++){
FontQuad q = target.getQuad(j);
BitmapCharacter localChar = q.getBitmapChar();
@@ -468,12 +478,19 @@
}
}
firstCharOfLine = false;
+
+ final float x0 = x;
+
+ x += xAdvance;
+ lineWidth += xAdvance;
+ if (c.getPage() != page) {
+ continue;
+ }
// edit the quad
- quadIndex++;
- FontQuad q = target.getQuad(quadIndex);
+ FontQuad q = target.newQuad();
- float quadPosX = x + (xOffset);
+ float quadPosX = x0 + (xOffset);
float quadPosY = y - yOffset;
q.setPosition(quadPosX, quadPosY);
q.setSize(width, height);
@@ -497,8 +514,6 @@
q.setSizeScale(sizeScale);
q.setCharacter(text.charAt(i));
- x += xAdvance;
- lineWidth += xAdvance;
lastChar = text.charAt(i);
}
Index: src/core/com/jme3/font/BitmapCharacter.java
===================================================================
--- src/core/com/jme3/font/BitmapCharacter.java (revision 6397)
+++ src/core/com/jme3/font/BitmapCharacter.java (working copy)
@@ -54,6 +54,7 @@
private int yOffset;
private int xAdvance;
private IntMap<Integer> kerning = new IntMap<Integer>();
+ private int page;
@Override
public BitmapCharacter clone() {
@@ -121,6 +122,14 @@
public void setXAdvance(int advance) {
xAdvance = advance;
}
+
+ public void setPage(int page) {
+ this.page = page;
+ }
+
+ public int getPage() {
+ return page;
+ }
public void addKerning(int second, int amount){
kerning.put(second, amount);
[/patch]