2 * Sixth 3D engine. Copyright ©2012-2020, 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 import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.BLACK;
26 import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.WHITE;
28 public class TextCanvas extends TexturedRectangle {
30 public static final int FONT_CHAR_WIDTH_PIXELS = 8;
31 public static final int FONT_CHAR_HEIGHT_PIXELS = 16;
32 public static final Font FONT = CanvasCharacter.getFont(15);
33 private static final String GROUP_TEXTURE = "texture";
34 private static final String GROUP_CHARACTERS = "characters";
35 private final TextPointer size;
36 private final TextPointer cursorLocation = new TextPointer();
37 CanvasCharacter lines[][];
38 private RenderMode renderMode = null;
39 private Color backgroundColor = BLACK;
40 private Color foregroundColor = WHITE;
42 public TextCanvas(final Transform location, final String text,
43 final Color foregroundColor, final Color backgroundColor) {
44 this(location, getTextDimensions(text), foregroundColor,
49 public TextCanvas(final Transform location, final TextPointer dimensions,
50 final Color foregroundColor, final Color backgroundColor) {
52 getRelativityTracker().enableOrientationTracking();
55 final int columns = dimensions.column;
56 final int rows = dimensions.row;
58 this.backgroundColor = backgroundColor;
59 this.foregroundColor = foregroundColor;
61 // initialize underlying textured rectangle
62 initialize(columns * FONT_CHAR_WIDTH_PIXELS, rows * FONT_CHAR_HEIGHT_PIXELS, 0);
64 getTexture().primaryBitmap.fillColor(backgroundColor);
65 getTexture().resetResampledBitmapCache();
67 setGroupForUngrouped(GROUP_TEXTURE);
69 lines = new CanvasCharacter[rows][];
70 for (int row = 0; row < rows; row++) {
71 lines[row] = new CanvasCharacter[columns];
73 for (int column = 0; column < columns; column++) {
74 final Point3D characterCoordinate = getCharLocation(row, column);
76 final CanvasCharacter character = new CanvasCharacter(
77 characterCoordinate, ' ', foregroundColor,
80 lines[row][column] = character;
85 setGroupForUngrouped(GROUP_CHARACTERS);
87 setRenderMode(RenderMode.TEXTURE);
90 public static TextPointer getTextDimensions(final String text) {
92 final BufferedReader reader = new BufferedReader(new StringReader(text));
100 line = reader.readLine();
101 } catch (IOException e) {
102 throw new RuntimeException(e);
106 return new TextPointer(rows, columns);
109 columns = Math.max(columns, line.length());
114 public void beforeTransformHook(final TransformPipe transformPipe,
115 final RenderingContext context) {
117 final double textRelativeSize = context.width
118 / getRelativityTracker().getDistanceToUser();
120 if (textRelativeSize < 2d) {
121 if (renderMode == RenderMode.CHARACTERS)
122 setRenderMode(RenderMode.TEXTURE);
126 final double piHalf = Math.PI / 2;
128 final double deviation = Math.abs(getRelativityTracker().getAngleXZ()
130 + Math.abs(getRelativityTracker().getAngleYZ() + piHalf);
132 final double maxDeviation = 0.5;
134 if (deviation > maxDeviation) {
135 if (renderMode == RenderMode.CHARACTERS)
136 setRenderMode(RenderMode.TEXTURE);
137 } else if (renderMode == RenderMode.TEXTURE)
138 setRenderMode(RenderMode.CHARACTERS);
142 for (final CanvasCharacter[] line : lines)
143 for (final CanvasCharacter character : line) {
144 character.setValue(' ');
145 character.setBackgroundColor(backgroundColor);
146 character.setForegroundColor(foregroundColor);
149 // set background color
150 getTexture().primaryBitmap.fillColor(backgroundColor);
151 getTexture().resetResampledBitmapCache();
154 private void drawCharToTexture(final int row, final int column,
155 final char character, final Color foreground) {
156 final Graphics2D graphics = getTexture().graphics;
158 getTexture().primaryBitmap.drawRectangle(column * FONT_CHAR_WIDTH_PIXELS, row
159 * FONT_CHAR_HEIGHT_PIXELS, (column * FONT_CHAR_WIDTH_PIXELS)
160 + FONT_CHAR_WIDTH_PIXELS, (row * FONT_CHAR_HEIGHT_PIXELS) + FONT_CHAR_HEIGHT_PIXELS,
163 graphics.setFont(FONT);
164 graphics.setColor(foreground.toAwtColor());
165 graphics.drawChars(new char[]{character,}, 0, 1,
166 (column * FONT_CHAR_WIDTH_PIXELS) - 0, (row * FONT_CHAR_HEIGHT_PIXELS) + 13);
168 getTexture().resetResampledBitmapCache();
171 public Point3D getCharLocation(final int row, final int column) {
172 final Point3D coordinate = topLeft.clone();
174 coordinate.translateY((row * FONT_CHAR_HEIGHT_PIXELS)
175 + ((FONT_CHAR_HEIGHT_PIXELS / 2) - 3));
177 coordinate.translateX((column * FONT_CHAR_WIDTH_PIXELS)
178 + (FONT_CHAR_WIDTH_PIXELS / 2));
183 public TextPointer getSize() {
187 public void locate(final int row, final int column) {
188 cursorLocation.row = row;
189 cursorLocation.column = column;
192 public void print(final String text) {
193 for (final char c : text.toCharArray())
197 public void putChar(final char character) {
198 putChar(cursorLocation, character);
200 cursorLocation.column++;
201 if (cursorLocation.column >= size.column) {
202 cursorLocation.column = 0;
203 cursorLocation.row++;
207 public void putChar(final int row, final int column, final char character) {
208 if ((row >= lines.length) || (row < 0))
211 final CanvasCharacter[] line = lines[row];
213 if ((column >= line.length) || (column < 0))
216 final CanvasCharacter canvasCharacter = line[column];
217 canvasCharacter.setValue(character);
218 canvasCharacter.setBackgroundColor(backgroundColor);
219 canvasCharacter.setForegroundColor(foregroundColor);
220 drawCharToTexture(row, column, character,
224 public void putChar(final TextPointer location, final char character) {
225 putChar(location.row, location.column, character);
228 public void setBackgroundColor(
229 final eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor) {
230 this.backgroundColor = backgroundColor;
233 public void setForegroundColor(
234 final eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor) {
235 this.foregroundColor = foregroundColor;
238 private void setRenderMode(final RenderMode mode) {
239 if (mode == renderMode)
244 hideGroup(GROUP_TEXTURE);
245 showGroup(GROUP_CHARACTERS);
248 hideGroup(GROUP_CHARACTERS);
249 showGroup(GROUP_TEXTURE);
256 public void setText(final String text) {
257 final BufferedReader reader = new BufferedReader(new StringReader(text));
264 line = reader.readLine();
265 } catch (IOException e) {
266 throw new RuntimeException(e);
273 for (final char c : line.toCharArray()) {
274 putChar(row, column, c);
281 public void setTextColor(final Color color) {
282 for (final CanvasCharacter[] line : lines)
283 for (final CanvasCharacter character : line)
284 character.setForegroundColor(color);
288 // public void transform(final TransformPipe transformPipe,
289 // final RenderAggregator aggregator, final RenderingContext buffer) {
291 // super.transform(transformPipe, aggregator, buffer);