2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas;
7 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
8 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
9 import eu.svjatoslav.sixth.e3d.gui.TextPointer;
10 import eu.svjatoslav.sixth.e3d.math.Transform;
11 import eu.svjatoslav.sixth.e3d.math.TransformPipe;
12 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
13 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.TexturedRectangle;
16 import java.io.BufferedReader;
17 import java.io.IOException;
18 import java.io.StringReader;
20 import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.BLACK;
21 import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.WHITE;
23 public class TextCanvas extends TexturedRectangle {
25 public static final int FONT_CHAR_WIDTH_PIXELS = 8;
26 public static final int FONT_CHAR_HEIGHT_PIXELS = 16;
27 public static final Font FONT = CanvasCharacter.getFont(15);
28 private static final String GROUP_TEXTURE = "texture";
29 private static final String GROUP_CHARACTERS = "characters";
30 private final TextPointer size;
31 private final TextPointer cursorLocation = new TextPointer();
32 CanvasCharacter lines[][];
33 private RenderMode renderMode = null;
34 private Color backgroundColor = BLACK;
35 private Color foregroundColor = WHITE;
37 public TextCanvas(final Transform location, final String text,
38 final Color foregroundColor, final Color backgroundColor) {
39 this(location, getTextDimensions(text), foregroundColor,
44 public TextCanvas(final Transform location, final TextPointer dimensions,
45 final Color foregroundColor, final Color backgroundColor) {
47 getRelativityTracker().enableOrientationTracking();
50 final int columns = dimensions.column;
51 final int rows = dimensions.row;
53 this.backgroundColor = backgroundColor;
54 this.foregroundColor = foregroundColor;
56 // initialize underlying textured rectangle
57 initialize(columns * FONT_CHAR_WIDTH_PIXELS, rows * FONT_CHAR_HEIGHT_PIXELS, 0);
59 getTexture().primaryBitmap.fillColor(backgroundColor);
60 getTexture().resetResampledBitmapCache();
62 setGroupForUngrouped(GROUP_TEXTURE);
64 lines = new CanvasCharacter[rows][];
65 for (int row = 0; row < rows; row++) {
66 lines[row] = new CanvasCharacter[columns];
68 for (int column = 0; column < columns; column++) {
69 final Point3D characterCoordinate = getCharLocation(row, column);
71 final CanvasCharacter character = new CanvasCharacter(
72 characterCoordinate, ' ', foregroundColor,
75 lines[row][column] = character;
80 setGroupForUngrouped(GROUP_CHARACTERS);
82 setRenderMode(RenderMode.TEXTURE);
85 public static TextPointer getTextDimensions(final String text) {
87 final BufferedReader reader = new BufferedReader(new StringReader(text));
95 line = reader.readLine();
96 } catch (IOException e) {
97 throw new RuntimeException(e);
101 return new TextPointer(rows, columns);
104 columns = Math.max(columns, line.length());
109 public void beforeTransformHook(final TransformPipe transformPipe,
110 final RenderingContext context) {
112 final double textRelativeSize = context.width
113 / getRelativityTracker().getDistanceToUser();
115 if (textRelativeSize < 2d) {
116 if (renderMode == RenderMode.CHARACTERS)
117 setRenderMode(RenderMode.TEXTURE);
121 final double piHalf = Math.PI / 2;
123 final double deviation = Math.abs(getRelativityTracker().getAngleXZ()
125 + Math.abs(getRelativityTracker().getAngleYZ() + piHalf);
127 final double maxDeviation = 0.5;
129 if (deviation > maxDeviation) {
130 if (renderMode == RenderMode.CHARACTERS)
131 setRenderMode(RenderMode.TEXTURE);
132 } else if (renderMode == RenderMode.TEXTURE)
133 setRenderMode(RenderMode.CHARACTERS);
137 for (final CanvasCharacter[] line : lines)
138 for (final CanvasCharacter character : line) {
139 character.setValue(' ');
140 character.setBackgroundColor(backgroundColor);
141 character.setForegroundColor(foregroundColor);
144 // set background color
145 getTexture().primaryBitmap.fillColor(backgroundColor);
146 getTexture().resetResampledBitmapCache();
149 private void drawCharToTexture(final int row, final int column,
150 final char character, final Color foreground) {
151 final Graphics2D graphics = getTexture().graphics;
153 getTexture().primaryBitmap.drawRectangle(column * FONT_CHAR_WIDTH_PIXELS, row
154 * FONT_CHAR_HEIGHT_PIXELS, (column * FONT_CHAR_WIDTH_PIXELS)
155 + FONT_CHAR_WIDTH_PIXELS, (row * FONT_CHAR_HEIGHT_PIXELS) + FONT_CHAR_HEIGHT_PIXELS,
158 graphics.setFont(FONT);
159 graphics.setColor(foreground.toAwtColor());
160 graphics.drawChars(new char[]{character,}, 0, 1,
161 (column * FONT_CHAR_WIDTH_PIXELS) - 0, (row * FONT_CHAR_HEIGHT_PIXELS) + 13);
163 getTexture().resetResampledBitmapCache();
166 public Point3D getCharLocation(final int row, final int column) {
167 final Point3D coordinate = topLeft.clone();
169 coordinate.translateY((row * FONT_CHAR_HEIGHT_PIXELS)
170 + ((FONT_CHAR_HEIGHT_PIXELS / 2) - 3));
172 coordinate.translateX((column * FONT_CHAR_WIDTH_PIXELS)
173 + (FONT_CHAR_WIDTH_PIXELS / 2));
178 public TextPointer getSize() {
182 public void locate(final int row, final int column) {
183 cursorLocation.row = row;
184 cursorLocation.column = column;
187 public void print(final String text) {
188 for (final char c : text.toCharArray())
192 public void putChar(final char character) {
193 putChar(cursorLocation, character);
195 cursorLocation.column++;
196 if (cursorLocation.column >= size.column) {
197 cursorLocation.column = 0;
198 cursorLocation.row++;
202 public void putChar(final int row, final int column, final char character) {
203 if ((row >= lines.length) || (row < 0))
206 final CanvasCharacter[] line = lines[row];
208 if ((column >= line.length) || (column < 0))
211 final CanvasCharacter canvasCharacter = line[column];
212 canvasCharacter.setValue(character);
213 canvasCharacter.setBackgroundColor(backgroundColor);
214 canvasCharacter.setForegroundColor(foregroundColor);
215 drawCharToTexture(row, column, character,
219 public void putChar(final TextPointer location, final char character) {
220 putChar(location.row, location.column, character);
223 public void setBackgroundColor(
224 final eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor) {
225 this.backgroundColor = backgroundColor;
228 public void setForegroundColor(
229 final eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor) {
230 this.foregroundColor = foregroundColor;
233 private void setRenderMode(final RenderMode mode) {
234 if (mode == renderMode)
239 hideGroup(GROUP_TEXTURE);
240 showGroup(GROUP_CHARACTERS);
243 hideGroup(GROUP_CHARACTERS);
244 showGroup(GROUP_TEXTURE);
251 public void setText(final String text) {
252 final BufferedReader reader = new BufferedReader(new StringReader(text));
259 line = reader.readLine();
260 } catch (IOException e) {
261 throw new RuntimeException(e);
268 for (final char c : line.toCharArray()) {
269 putChar(row, column, c);
276 public void setTextColor(final Color color) {
277 for (final CanvasCharacter[] line : lines)
278 for (final CanvasCharacter character : line)
279 character.setForegroundColor(color);
283 // public void transform(final TransformPipe transformPipe,
284 // final RenderAggregator aggregator, final RenderingContext buffer) {
286 // super.transform(transformPipe, aggregator, buffer);