aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core/com/jme3/font/BitmapText.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/core/com/jme3/font/BitmapText.java')
-rw-r--r--engine/src/core/com/jme3/font/BitmapText.java361
1 files changed, 361 insertions, 0 deletions
diff --git a/engine/src/core/com/jme3/font/BitmapText.java b/engine/src/core/com/jme3/font/BitmapText.java
new file mode 100644
index 0000000..7601324
--- /dev/null
+++ b/engine/src/core/com/jme3/font/BitmapText.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.font;
+
+import com.jme3.font.BitmapFont.Align;
+import com.jme3.font.BitmapFont.VAlign;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.renderer.RenderManager;
+import com.jme3.scene.Node;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author YongHoon
+ */
+public class BitmapText extends Node {
+ private BitmapFont font;
+ private StringBlock block;
+ private boolean needRefresh = true;
+ private final BitmapTextPage[] textPages;
+ private Letters letters;
+
+ public BitmapText(BitmapFont font) {
+ this(font, false, false);
+ }
+
+ public BitmapText(BitmapFont font, boolean rightToLeft) {
+ this(font, rightToLeft, false);
+ }
+
+ public BitmapText(BitmapFont font, boolean rightToLeft, boolean arrayBased) {
+ textPages = new BitmapTextPage[font.getPageSize()];
+ for (int page = 0; page < textPages.length; page++) {
+ textPages[page] = new BitmapTextPage(font, arrayBased, page);
+ attachChild(textPages[page]);
+ }
+
+ this.font = font;
+ this.block = new StringBlock();
+ block.setSize(font.getPreferredSize());
+ letters = new Letters(font, block, rightToLeft);
+ }
+
+ @Override
+ public BitmapText clone() {
+ BitmapText clone = (BitmapText) super.clone();
+ for (int i = 0; i < textPages.length; i++) {
+ clone.textPages[i] = textPages[i].clone();
+ }
+ clone.block = block.clone();
+ clone.needRefresh = true;
+ return clone;
+ }
+
+ public BitmapFont getFont() {
+ return font;
+ }
+
+ /**
+ * Changes text size
+ * @param size text size
+ */
+ public void setSize(float size) {
+ block.setSize(size);
+ needRefresh = true;
+ letters.invalidate();
+ }
+
+ /**
+ *
+ * @param text charsequence to change text to
+ */
+ public void setText(CharSequence text) {
+ // note: text.toString() is free if text is already a java.lang.String.
+ setText( text != null ? text.toString() : null );
+ }
+
+ /**
+ *
+ * @param text String to change text to
+ */
+ public void setText(String text) {
+ text = text == null ? "" : text;
+ if (text == block.getText() || block.getText().equals(text)) {
+ return;
+ }
+
+ block.setText(text);
+ letters.setText(text);
+ needRefresh = true;
+ }
+
+ /**
+ * @return returns text
+ */
+ public String getText() {
+ return block.getText();
+ }
+
+ /**
+ * @return color of the text
+ */
+ public ColorRGBA getColor() {
+ return letters.getBaseColor();
+ }
+
+ /**
+ * changes text color. all substring colors are deleted.
+ * @param color new color of text
+ */
+ public void setColor(ColorRGBA color) {
+ letters.setColor(color);
+ letters.invalidate(); // TODO: Don't have to align.
+ needRefresh = true;
+ }
+
+ /**
+ * Define area where bitmaptext will be rendered
+ * @param rect position and size box where text is rendered
+ */
+ public void setBox(Rectangle rect) {
+ block.setTextBox(rect);
+ letters.invalidate();
+ needRefresh = true;
+ }
+
+ /**
+ * @return height of the line
+ */
+ public float getLineHeight() {
+ return font.getLineHeight(block);
+ }
+
+ /**
+ * @return height of whole textblock
+ */
+ public float getHeight() {
+ if (needRefresh) {
+ assemble();
+ }
+ float height = getLineHeight()*block.getLineCount();
+ Rectangle textBox = block.getTextBox();
+ if (textBox != null) {
+ return Math.max(height, textBox.height);
+ }
+ return height;
+ }
+
+ /**
+ * @return width of line
+ */
+ public float getLineWidth() {
+ if (needRefresh) {
+ assemble();
+ }
+ Rectangle textBox = block.getTextBox();
+ if (textBox != null) {
+ return Math.max(letters.getTotalWidth(), textBox.width);
+ }
+ return letters.getTotalWidth();
+ }
+
+ /**
+ * @return line count
+ */
+ public int getLineCount() {
+ if (needRefresh) {
+ assemble();
+ }
+ return block.getLineCount();
+ }
+
+ public LineWrapMode getLineWrapMode() {
+ return block.getLineWrapMode();
+ }
+
+ /**
+ * Set horizontal alignment. Applicable only when text bound is set.
+ * @param align
+ */
+ public void setAlignment(BitmapFont.Align align) {
+ if (block.getTextBox() == null && align != Align.Left) {
+ throw new RuntimeException("Bound is not set");
+ }
+ block.setAlignment(align);
+ letters.invalidate();
+ needRefresh = true;
+ }
+
+ /**
+ * Set vertical alignment. Applicable only when text bound is set.
+ * @param align
+ */
+ public void setVerticalAlignment(BitmapFont.VAlign align) {
+ if (block.getTextBox() == null && align != VAlign.Top) {
+ throw new RuntimeException("Bound is not set");
+ }
+ block.setVerticalAlignment(align);
+ letters.invalidate();
+ needRefresh = true;
+ }
+
+ public BitmapFont.Align getAlignment() {
+ return block.getAlignment();
+ }
+
+ public BitmapFont.VAlign getVerticalAlignment() {
+ return block.getVerticalAlignment();
+ }
+
+ /**
+ * Set the font style of substring. If font doesn't contain style, default style is used
+ * @param start start index to set style. inclusive.
+ * @param end end index to set style. EXCLUSIVE.
+ * @param style
+ */
+ public void setStyle(int start, int end, int style) {
+ letters.setStyle(start, end, style);
+ }
+
+ /**
+ * Set the font style of substring. If font doesn't contain style, default style is applied
+ * @param regexp regular expression
+ * @param style
+ */
+ public void setStyle(String regexp, int style) {
+ Pattern p = Pattern.compile(regexp);
+ Matcher m = p.matcher(block.getText());
+ while (m.find()) {
+ setStyle(m.start(), m.end(), style);
+ }
+ }
+
+ /**
+ * Set the color of substring.
+ * @param start start index to set style. inclusive.
+ * @param end end index to set style. EXCLUSIVE.
+ * @param color
+ */
+ public void setColor(int start, int end, ColorRGBA color) {
+ letters.setColor(start, end, color);
+ letters.invalidate();
+ needRefresh = true;
+ }
+
+ /**
+ * Set the color of substring.
+ * @param regexp regular expression
+ * @param color
+ */
+ public void setColor(String regexp, ColorRGBA color) {
+ Pattern p = Pattern.compile(regexp);
+ Matcher m = p.matcher(block.getText());
+ while (m.find()) {
+ letters.setColor(m.start(), m.end(), color);
+ }
+ letters.invalidate();
+ needRefresh = true;
+ }
+
+ /**
+ * @param tabs tab positions
+ */
+ public void setTabPosition(float... tabs) {
+ block.setTabPosition(tabs);
+ letters.invalidate();
+ needRefresh = false;
+ }
+
+ /**
+ * used for the tabs over the last tab position.
+ * @param width tab size
+ */
+ public void setTabWidth(float width) {
+ block.setTabWidth(width);
+ letters.invalidate();
+ needRefresh = false;
+ }
+
+ /**
+ * for setLineWrapType(LineWrapType.NoWrap),
+ * set the last character when the text exceeds the bound.
+ * @param c
+ */
+ public void setEllipsisChar(char c) {
+ block.setEllipsisChar(c);
+ letters.invalidate();
+ needRefresh = false;
+ }
+
+ /**
+ * Available only when bounding is set. <code>setBox()</code> method call is needed in advance.
+ * true when
+ * @param wrap NoWrap : Letters over the text bound is not shown. the last character is set to '...'(0x2026)
+ * Character: Character is split at the end of the line.
+ * Word : Word is split at the end of the line.
+ */
+ public void setLineWrapMode(LineWrapMode wrap) {
+ if (block.getLineWrapMode() != wrap) {
+ block.setLineWrapMode(wrap);
+ letters.invalidate();
+ needRefresh = true;
+ }
+ }
+
+ @Override
+ public void updateLogicalState(float tpf) {
+ super.updateLogicalState(tpf);
+ if (needRefresh) {
+ assemble();
+ }
+ }
+
+ private void assemble() {
+ // first generate quadlist
+ letters.update();
+
+ for (int i = 0; i < textPages.length; i++) {
+ textPages[i].assemble(letters);
+ }
+ needRefresh = false;
+ }
+
+ public void render(RenderManager rm) {
+ for (BitmapTextPage page : textPages) {
+ Material mat = page.getMaterial();
+ mat.setTexture("Texture", page.getTexture());
+ mat.render(page, rm);
+ }
+ }
+}