diff --git a/engine/src/core/com/jme3/font/BitmapText.java b/engine/src/core/com/jme3/font/BitmapText.java index c03107210..7b8b51b53 100644 --- a/engine/src/core/com/jme3/font/BitmapText.java +++ b/engine/src/core/com/jme3/font/BitmapText.java @@ -181,6 +181,22 @@ public class BitmapText extends Node { letters.invalidate(); // TODO: Don't have to align. needRefresh = true; } + + /** + * Sets an overall alpha that will be applied to all + * letters. If the alpha passed is -1 then alpha reverts + * to default... which will be 1 for anything unspecified + * and color tags will be reset to 1 or their encoded + * alpha. + */ + public void setAlpha(float alpha) { + letters.setBaseAlpha(alpha); + needRefresh = true; + } + + public float getAlpha() { + return letters.getBaseAlpha(); + } /** * Define area where bitmaptext will be rendered diff --git a/engine/src/core/com/jme3/font/ColorTags.java b/engine/src/core/com/jme3/font/ColorTags.java index e2312ea88..83f46b3d0 100644 --- a/engine/src/core/com/jme3/font/ColorTags.java +++ b/engine/src/core/com/jme3/font/ColorTags.java @@ -49,6 +49,8 @@ class ColorTags { "\\\\#([0-9a-fA-F]{4})#|\\\\#([0-9a-fA-F]{3})#"); private LinkedList colors = new LinkedList(); private String text; + private String original; + private float baseAlpha = -1; ColorTags() { } @@ -68,6 +70,7 @@ class ColorTags { } void setText(final String charSeq) { + original = charSeq; colors.clear(); if (charSeq == null) { return; @@ -92,6 +95,34 @@ class ColorTags { text = charSeq; } } + + void setBaseAlpha( float alpha ) { + this.baseAlpha = alpha; + if( alpha == -1 ) { + // Need to reinitialize from the original text + setText(original); + return; + } + + // Else set the alpha for all of them + for( Range r : colors ) { + r.color.a = alpha; + } + } + + /** + * Sets the colors of all ranges, overriding any color tags + * that were in the original text. + */ + void setBaseColor( ColorRGBA color ) { + // There are times when the alpha is directly modified + // and the caller may have passed a constant... so we + // should clone it. + color = color.clone(); + for( Range r : colors ) { + r.color = color; + } + } class Range { int start; @@ -104,19 +135,23 @@ class ColorTags { Integer.parseInt(colorStr.subSequence(2,4).toString(), 16) / 255f, Integer.parseInt(colorStr.subSequence(4,6).toString(), 16) / 255f, 1); - if (colorStr.length() == 8) { - color.a = Integer.parseInt(colorStr.subSequence(6,8).toString(), 16) / 255f; + if (baseAlpha != -1) { + color.a = baseAlpha; } + else if (colorStr.length() == 8) { + color.a = Integer.parseInt(colorStr.subSequence(6,8).toString(), 16) / 255f; + } } else { color.set(Integer.parseInt(Character.toString(colorStr.charAt(0)), 16) / 15f, Integer.parseInt(Character.toString(colorStr.charAt(1)), 16) / 15f, Integer.parseInt(Character.toString(colorStr.charAt(2)), 16) / 15f, 1); - if (colorStr.length() == 4) { + if (baseAlpha != -1) { + color.a = baseAlpha; + } else if (colorStr.length() == 4) { color.a = Integer.parseInt(Character.toString(colorStr.charAt(3)), 16) / 15f; } } - } } } diff --git a/engine/src/core/com/jme3/font/LetterQuad.java b/engine/src/core/com/jme3/font/LetterQuad.java index 5cc356531..ac68f0ebb 100644 --- a/engine/src/core/com/jme3/font/LetterQuad.java +++ b/engine/src/core/com/jme3/font/LetterQuad.java @@ -249,6 +249,12 @@ class LetterQuad { invalidate(); } + void setAlpha(float alpha) { + int i = (int)(alpha * 255) & 0xFF; + colorInt = (colorInt & 0xffffff00) | i; + invalidate(); + } + void setBitmapChar(char c) { BitmapCharacterSet charSet = font.getCharSet(); BitmapCharacter bm = charSet.getCharacter(c, style); diff --git a/engine/src/core/com/jme3/font/Letters.java b/engine/src/core/com/jme3/font/Letters.java index f17751848..2d36959f7 100644 --- a/engine/src/core/com/jme3/font/Letters.java +++ b/engine/src/core/com/jme3/font/Letters.java @@ -51,6 +51,8 @@ class Letters { private float totalHeight; private ColorTags colorTags = new ColorTags(); private ColorRGBA baseColor = null; + private float baseAlpha = -1; + private String plainText; Letters(BitmapFont font, StringBlock bound, boolean rightToLeft) { final String text = bound.getText(); @@ -63,7 +65,7 @@ class Letters { void setText(final String text) { colorTags.setText(text); - String plainText = colorTags.getPlainText(); + plainText = colorTags.getPlainText(); head.setNext(tail); tail.setPrevious(head); @@ -338,6 +340,7 @@ class Letters { */ void setColor( ColorRGBA color ) { baseColor = color; + colorTags.setBaseColor(color); setColor( 0, block.getText().length(), color ); } @@ -359,4 +362,46 @@ class Letters { cursor = cursor.getNext(); } } -} \ No newline at end of file + + float getBaseAlpha() { + return baseAlpha; + } + + void setBaseAlpha( float alpha ) { this.baseAlpha = alpha; + colorTags.setBaseAlpha(alpha); + + if (alpha == -1) { + alpha = baseColor != null ? baseColor.a : 1; + } + + // Forward the new alpha to the letter quads + LetterQuad cursor = head.getNext(); + while (!cursor.isTail()) { + cursor.setAlpha(alpha); + cursor = cursor.getNext(); + } + + // If the alpha was reset to "default", ie: -1 + // then the color tags are potentially reset and + // we need to reapply them. This has to be done + // second since it may override any alpha values + // set above... but you still need to do the above + // since non-color tagged text is treated differently + // even if part of a color tagged string. + if (baseAlpha == -1) { + LinkedList ranges = colorTags.getTags(); + if (!ranges.isEmpty()) { + for (int i = 0; i < ranges.size()-1; i++) { + Range start = ranges.get(i); + Range end = ranges.get(i+1); + setColor(start.start, end.start, start.color); + } + Range end = ranges.getLast(); + setColor(end.start, plainText.length(), end.color); + } + } + + invalidate(); + } + +}