2 * Sixth 3D engine. Copyright ©2012-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public License
6 * or later as published by the Free Software Foundation.
10 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas;
12 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
13 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
14 import eu.svjatoslav.sixth.e3d.gui.TextPointer;
15 import eu.svjatoslav.sixth.e3d.math.Transform;
16 import eu.svjatoslav.sixth.e3d.math.TransformPipe;
17 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
18 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.TexturedRectangle;
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.StringReader;
25 public class TextCanvas extends TexturedRectangle {
27 public static final int FONT_CHAR_WIDTH = 8;
28 public static final int FONT_CHAR_HEIGHT = 16;
29 public static final Font FONT = CanvasCharacter.getFont(15);
30 private static final String GROUP_TEXTURE = "texture";
31 private static final String GROUP_CHARACTERS = "characters";
32 private final TextPointer size;
33 private final TextPointer cursorLocation = new TextPointer();
34 CanvasCharacter lines[][];
35 private RenderMode renderMode = null;
36 private Color backgroundColor = Color.BLACK;
38 private Color foregroundColor = Color.WHITE;
40 public TextCanvas(final Transform location, final String text,
41 final Color foregroundColor, final Color backgroundColor) {
42 this(location, getTextDimensions(text), foregroundColor,
47 public TextCanvas(final Transform location, final TextPointer dimensions,
48 final Color foregroundColor, final Color backgroundColor) {
50 getRelativityTracker().enableOrientationTracking();
53 final int columns = dimensions.column;
54 final int rows = dimensions.row;
56 this.backgroundColor = backgroundColor;
57 this.foregroundColor = foregroundColor;
59 // initialize underlying textured rectangle
60 initialize(columns * FONT_CHAR_WIDTH, rows * FONT_CHAR_HEIGHT, 0);
62 getTexture().primaryBitmap.fillColor(backgroundColor);
63 getTexture().resetResampledBitmapCache();
65 setGroupForUngrouped(GROUP_TEXTURE);
67 lines = new CanvasCharacter[rows][];
68 for (int row = 0; row < rows; row++) {
69 lines[row] = new CanvasCharacter[columns];
71 for (int column = 0; column < columns; column++) {
72 final Point3D characterCoordinate = getCharLocation(row, column);
74 final CanvasCharacter character = new CanvasCharacter(
75 characterCoordinate, ' ', foregroundColor,
78 lines[row][column] = character;
83 setGroupForUngrouped(GROUP_CHARACTERS);
85 setRenderMode(RenderMode.TEXTURE);
88 public static TextPointer getTextDimensions(final String text) {
90 final BufferedReader reader = new BufferedReader(new StringReader(text));
98 line = reader.readLine();
99 } catch (IOException e) {
100 throw new RuntimeException(e);
104 return new TextPointer(rows, columns);
107 columns = Math.max(columns, line.length());
112 public void beforeTransformHook(final TransformPipe transformPipe,
113 final RenderingContext context) {
115 final double textRelativeSize = context.width
116 / getRelativityTracker().getDistanceToUser();
118 if (textRelativeSize < 2d) {
119 if (renderMode == RenderMode.CHARACTERS)
120 setRenderMode(RenderMode.TEXTURE);
124 final double piHalf = Math.PI / 2;
126 final double deviation = Math.abs(getRelativityTracker().getAngleXZ()
128 + Math.abs(getRelativityTracker().getAngleYZ() + piHalf);
130 final double maxDeviation = 0.5;
132 if (deviation > maxDeviation) {
133 if (renderMode == RenderMode.CHARACTERS)
134 setRenderMode(RenderMode.TEXTURE);
135 } else if (renderMode == RenderMode.TEXTURE)
136 setRenderMode(RenderMode.CHARACTERS);
140 for (final CanvasCharacter[] line : lines)
141 for (final CanvasCharacter character : line) {
142 character.setValue(' ');
143 character.setBackgroundColor(backgroundColor);
144 character.setForegroundColor(foregroundColor);
147 // set background color
148 getTexture().primaryBitmap.fillColor(backgroundColor);
149 getTexture().resetResampledBitmapCache();
152 private void drawCharToTexture(final int row, final int column,
153 final char character, final Color foreground) {
154 final Graphics2D graphics = getTexture().graphics;
156 getTexture().primaryBitmap.drawRectangle(column * FONT_CHAR_WIDTH, row
157 * FONT_CHAR_HEIGHT, (column * FONT_CHAR_WIDTH)
158 + FONT_CHAR_WIDTH, (row * FONT_CHAR_HEIGHT) + FONT_CHAR_HEIGHT,
161 graphics.setFont(FONT);
162 graphics.setColor(foreground.toAwtColor());
163 graphics.drawChars(new char[]{character,}, 0, 1,
164 (column * FONT_CHAR_WIDTH) - 0, (row * FONT_CHAR_HEIGHT) + 13);
166 getTexture().resetResampledBitmapCache();
169 public Point3D getCharLocation(final int row, final int column) {
170 final Point3D coordinate = topLeft.clone();
172 coordinate.translateY((row * FONT_CHAR_HEIGHT)
173 + ((FONT_CHAR_HEIGHT / 2) - 3));
175 coordinate.translateX((column * FONT_CHAR_WIDTH)
176 + (FONT_CHAR_WIDTH / 2));
181 public TextPointer getSize() {
185 public void locate(final int row, final int column) {
186 cursorLocation.row = row;
187 cursorLocation.column = column;
190 public void print(final String text) {
191 for (final char c : text.toCharArray())
195 public void putChar(final char character) {
196 putChar(cursorLocation, character);
198 cursorLocation.column++;
199 if (cursorLocation.column >= size.column) {
200 cursorLocation.column = 0;
201 cursorLocation.row++;
205 public void putChar(final int row, final int column, final char character) {
206 if ((row >= lines.length) || (row < 0))
209 final CanvasCharacter[] line = lines[row];
211 if ((column >= line.length) || (column < 0))
214 final CanvasCharacter canvasCharacter = line[column];
215 canvasCharacter.setValue(character);
216 canvasCharacter.setBackgroundColor(backgroundColor);
217 canvasCharacter.setForegroundColor(foregroundColor);
218 drawCharToTexture(row, column, character,
222 public void putChar(final TextPointer location, final char character) {
223 putChar(location.row, location.column, character);
226 public void setBackgroundColor(
227 final eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor) {
228 this.backgroundColor = backgroundColor;
231 public void setForegroundColor(
232 final eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor) {
233 this.foregroundColor = foregroundColor;
236 private void setRenderMode(final RenderMode mode) {
237 if (mode == renderMode)
242 hideGroup(GROUP_TEXTURE);
243 showGroup(GROUP_CHARACTERS);
246 hideGroup(GROUP_CHARACTERS);
247 showGroup(GROUP_TEXTURE);
254 public void setText(final String text) {
255 final BufferedReader reader = new BufferedReader(new StringReader(text));
262 line = reader.readLine();
263 } catch (IOException e) {
264 throw new RuntimeException(e);
271 for (final char c : line.toCharArray()) {
272 putChar(row, column, c);
279 public void setTextColor(final Color color) {
280 for (final CanvasCharacter[] line : lines)
281 for (final CanvasCharacter character : line)
282 character.setForegroundColor(color);
286 // public void transform(final TransformPipe transformPipe,
287 // final RenderAggregator aggregator, final RenderingContext buffer) {
289 // super.transform(transformPipe, aggregator, buffer);