Fixes tab stops in BitmapText / BitmapFont.
The first explicitely set tab stop was always skipped. For all non-explicitely set tab stops it inserted a fixed spacing. This commit changes the behaviour so tabs are aligned to columns. It also adds handling of tabs to BitmapFont.getLineWidth() which ignored tabs before.
This commit is contained in:
parent
92b5d40003
commit
e60d67b1bb
@ -86,6 +86,8 @@ public class BitmapFont implements Savable {
|
|||||||
Bottom
|
Bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final float DEFAULT_TAB_WIDTH = 50.0f;
|
||||||
|
|
||||||
private BitmapCharacterSet charSet;
|
private BitmapCharacterSet charSet;
|
||||||
private Material[] pages;
|
private Material[] pages;
|
||||||
|
|
||||||
@ -215,6 +217,11 @@ public class BitmapFont implements Savable {
|
|||||||
firstCharOfLine = true;
|
firstCharOfLine = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(theChar == '\t') {
|
||||||
|
lineWidth = (float)Math.floor(lineWidth / DEFAULT_TAB_WIDTH) * DEFAULT_TAB_WIDTH;
|
||||||
|
lineWidth += DEFAULT_TAB_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
BitmapCharacter c = charSet.getCharacter((int) theChar);
|
BitmapCharacter c = charSet.getCharacter((int) theChar);
|
||||||
if (c != null){
|
if (c != null){
|
||||||
if (theChar == '\\' && i<text.length()-1 && text.charAt(i+1)=='#'){
|
if (theChar == '\\' && i<text.length()-1 && text.charAt(i+1)=='#'){
|
||||||
|
@ -369,7 +369,9 @@ public class BitmapText extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tabs tab positions
|
* Sets the positions at where the text continues after a tab character.<br>
|
||||||
|
* These tab stops need to be sorted from smallest to biggest value.
|
||||||
|
* @param tabs Sorted tab positions. Use <code>null</code> to reset tab positions.
|
||||||
*/
|
*/
|
||||||
public void setTabPosition(float... tabs) {
|
public void setTabPosition(float... tabs) {
|
||||||
block.setTabPosition(tabs);
|
block.setTabPosition(tabs);
|
||||||
@ -378,7 +380,9 @@ public class BitmapText extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* used for the tabs over the last tab position.
|
* Used for all tabs after the last custom tab position
|
||||||
|
* (see {@link #setTabPosition(float...) setTabPosition}).<br>
|
||||||
|
* This value is also used when no custom tab positions are set.
|
||||||
* @param width tab size
|
* @param width tab size
|
||||||
*/
|
*/
|
||||||
public void setTabWidth(float width) {
|
public void setTabWidth(float width) {
|
||||||
|
@ -306,8 +306,6 @@ class LetterQuad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update(StringBlock block) {
|
void update(StringBlock block) {
|
||||||
final float[] tabs = block.getTabPosition();
|
|
||||||
final float tabWidth = block.getTabWidth();
|
|
||||||
final Rectangle bound = getBound(block);
|
final Rectangle bound = getBound(block);
|
||||||
sizeScale = block.getSize() / font.getCharSet().getRenderedSize();
|
sizeScale = block.getSize() / font.getCharSet().getRenderedSize();
|
||||||
lineY = computeLineY(block);
|
lineY = computeLineY(block);
|
||||||
@ -320,16 +318,9 @@ class LetterQuad {
|
|||||||
xAdvance = 0;
|
xAdvance = 0;
|
||||||
} else if (isTab()) {
|
} else if (isTab()) {
|
||||||
x0 = previous.getNextX();
|
x0 = previous.getNextX();
|
||||||
width = tabWidth;
|
width = block.calcNextTabPosition(x0) - x0;
|
||||||
y0 = lineY;
|
y0 = lineY;
|
||||||
height = 0;
|
height = 0;
|
||||||
if (tabs != null && x0 < tabs[tabs.length-1]) {
|
|
||||||
for (int i = 0; i < tabs.length-1; i++) {
|
|
||||||
if (x0 > tabs[i] && x0 < tabs[i+1]) {
|
|
||||||
width = tabs[i+1] - x0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xAdvance = width;
|
xAdvance = width;
|
||||||
} else if (bitmapChar == null) {
|
} else if (bitmapChar == null) {
|
||||||
x0 = getPrevious().getX1();
|
x0 = getPrevious().getX1();
|
||||||
|
@ -53,7 +53,7 @@ class StringBlock implements Cloneable {
|
|||||||
private int lineCount;
|
private int lineCount;
|
||||||
private LineWrapMode wrapType = LineWrapMode.Word;
|
private LineWrapMode wrapType = LineWrapMode.Word;
|
||||||
private float[] tabPos;
|
private float[] tabPos;
|
||||||
private float tabWidth = 50;
|
private float tabWidth = BitmapFont.DEFAULT_TAB_WIDTH;
|
||||||
private char ellipsisChar = 0x2026;
|
private char ellipsisChar = 0x2026;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,6 +91,7 @@ class StringBlock implements Cloneable {
|
|||||||
clone.color = color.clone();
|
clone.color = color.clone();
|
||||||
if (textBox != null)
|
if (textBox != null)
|
||||||
clone.textBox = textBox.clone();
|
clone.textBox = textBox.clone();
|
||||||
|
// tabPos is read-only and replaced on write.
|
||||||
return clone;
|
return clone;
|
||||||
} catch (CloneNotSupportedException ex) {
|
} catch (CloneNotSupportedException ex) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
@ -173,22 +174,6 @@ class StringBlock implements Cloneable {
|
|||||||
this.wrapType = wrap;
|
this.wrapType = wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTabWidth(float tabWidth) {
|
|
||||||
this.tabWidth = tabWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTabPosition(float[] tabs) {
|
|
||||||
this.tabPos = tabs;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getTabWidth() {
|
|
||||||
return tabWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
float[] getTabPosition() {
|
|
||||||
return tabPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEllipsisChar(char c) {
|
void setEllipsisChar(char c) {
|
||||||
this.ellipsisChar = c;
|
this.ellipsisChar = c;
|
||||||
}
|
}
|
||||||
@ -196,4 +181,30 @@ class StringBlock implements Cloneable {
|
|||||||
int getEllipsisChar() {
|
int getEllipsisChar() {
|
||||||
return ellipsisChar;
|
return ellipsisChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTabWidth(float tabWidth) {
|
||||||
|
this.tabWidth = tabWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTabPosition(float[] tabs) {
|
||||||
|
if(tabs != null && tabs.length > 0) {
|
||||||
|
this.tabPos = tabs.clone();
|
||||||
|
} else {
|
||||||
|
this.tabPos = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcNextTabPosition(float posX) {
|
||||||
|
// If there is an upcoming user-set tab stop, use that one.
|
||||||
|
if (tabPos != null && posX < tabPos[tabPos.length-1]) {
|
||||||
|
for (int i = 0; i < tabPos.length; i++) {
|
||||||
|
if (posX < tabPos[i]) {
|
||||||
|
return tabPos[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No upcoming tab stops available, use default tab width.
|
||||||
|
return (float)Math.floor(posX / tabWidth) * tabWidth + tabWidth;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user