Improved code readability
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / renderer / raster / shapes / composite / textcanvas / CanvasCharacter.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas;
6
7 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
8 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
9 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
10 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
11 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon.SolidPolygon;
12
13 import java.awt.*;
14
15 import static java.lang.String.valueOf;
16
17 /**
18  * Represents a single character on the text canvas.
19  */
20 public class CanvasCharacter extends AbstractCoordinateShape {
21
22     private static final int MAX_FONT_SIZE = 500;
23
24     /**
25      * Cached fonts.
26      */
27     private static final Font[] fonts = new Font[MAX_FONT_SIZE];
28
29     /**
30      * The character to be rendered.
31      */
32     private char value;
33
34     private eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor;
35
36     private eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor;
37
38     public CanvasCharacter(final Point3D point, final char character,
39                            final eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor,
40                            final eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor) {
41
42         super(5);
43         coordinates[0].coordinate = point;
44
45         value = character;
46
47         this.foregroundColor = foregroundColor;
48
49         this.backgroundColor = backgroundColor;
50
51         // set corner coordinates (for drawing background)
52         {
53             final double widthHalf = TextCanvas.FONT_CHAR_WIDTH / 2d;
54             final double heightHalf = TextCanvas.FONT_CHAR_HEIGHT / 2d;
55
56             // upper left
57             coordinates[1].coordinate = point.clone().translateX(-widthHalf)
58                     .translateY(-heightHalf);
59
60             // upper right
61             coordinates[2].coordinate = point.clone().translateX(widthHalf)
62                     .translateY(-heightHalf);
63
64             // lower right
65             coordinates[3].coordinate = point.clone().translateX(widthHalf)
66                     .translateY(heightHalf);
67
68             // lower left
69             coordinates[4].coordinate = point.clone().translateX(-widthHalf)
70                     .translateY(heightHalf);
71
72         }
73     }
74
75     /**
76      * Returns a font of the specified size.
77      * <p>
78      *     If the font of the specified size is already cached, it will be
79      *     returned. Otherwise, a new font will be created, cached and returned.
80      *
81      *
82      * @param size the size of the font
83      * @return the font
84      */
85     public static Font getFont(final int size) {
86         if (fonts[size] != null)
87             return fonts[size];
88
89         final Font font = new Font("Courier", Font.BOLD, size);
90         fonts[size] = font;
91         return font;
92     }
93
94     /**
95      * Returns color of the background.
96      */
97     public eu.svjatoslav.sixth.e3d.renderer.raster.Color getBackgroundColor() {
98         return backgroundColor;
99     }
100
101     /**
102      * Sets color of the background.
103      */
104     public void setBackgroundColor(
105             final eu.svjatoslav.sixth.e3d.renderer.raster.Color backgroundColor) {
106         this.backgroundColor = backgroundColor;
107     }
108
109     /**
110      * Returns color of the foreground.
111      * @return the color
112      */
113     public eu.svjatoslav.sixth.e3d.renderer.raster.Color getForegroundColor() {
114         return foregroundColor;
115     }
116
117     /**
118      * Sets color of the foreground.
119      * @param foregroundColor the color
120      */
121     public void setForegroundColor(
122             final eu.svjatoslav.sixth.e3d.renderer.raster.Color foregroundColor) {
123         this.foregroundColor = foregroundColor;
124     }
125
126     @Override
127     public void paint(final RenderingContext renderingContext) {
128
129         SolidPolygon.drawPolygon(renderingContext,
130                 coordinates[1].onScreenCoordinate,
131                 coordinates[2].onScreenCoordinate,
132                 coordinates[3].onScreenCoordinate, mouseInteractionController,
133                 backgroundColor);
134
135         SolidPolygon.drawPolygon(renderingContext,
136                 coordinates[1].onScreenCoordinate,
137                 coordinates[3].onScreenCoordinate,
138                 coordinates[4].onScreenCoordinate, mouseInteractionController,
139                 backgroundColor);
140
141         final int size = (int) ((renderingContext.width * 4.5) / onScreenZ);
142
143         // do not render too large characters
144         if (size >= MAX_FONT_SIZE)
145             return;
146
147         final Point2D onScreenLocation = coordinates[0].onScreenCoordinate;
148
149         // screen borders check
150         if (onScreenLocation.x < 0)
151             return;
152         if (onScreenLocation.y < 0)
153             return;
154
155         if (onScreenLocation.x > renderingContext.width)
156             return;
157         if (onScreenLocation.y > renderingContext.height)
158             return;
159
160         renderingContext.graphics.setFont(getFont(size));
161         renderingContext.graphics.setColor(foregroundColor.toAwtColor());
162         renderingContext.graphics.drawString(
163                 valueOf(value),
164                 (int) onScreenLocation.x - (int) (size / 3.2),
165                 (int) onScreenLocation.y + (int) (size / 2.5));
166
167     }
168
169     public void setValue(final char value) {
170         this.value = value;
171     }
172
173 }