Add a way to precise mark border color for scatter plots
[scilab.git] / scilab / modules / scirenderer / src / org / scilab / forge / scirenderer / implementation / g2d / texture / G2DTextureDrawingTools.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  */
11
12 package org.scilab.forge.scirenderer.implementation.g2d.texture;
13
14 import org.scilab.forge.scirenderer.implementation.g2d.motor.G2DStroke;
15 import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureManager;
16 import org.scilab.forge.scirenderer.shapes.appearance.Appearance;
17 import org.scilab.forge.scirenderer.shapes.appearance.Color;
18 import org.scilab.forge.scirenderer.texture.Texture;
19 import org.scilab.forge.scirenderer.texture.TextureDrawer;
20 import org.scilab.forge.scirenderer.texture.TextureDrawingTools;
21 import org.scilab.forge.scirenderer.texture.TextEntity;
22
23 import javax.swing.Icon;
24 import javax.swing.JLabel;
25 import java.awt.Dimension;
26 import java.awt.Graphics2D;
27 import java.awt.RenderingHints;
28 import java.awt.font.TextLayout;
29 import java.awt.geom.Ellipse2D;
30 import java.awt.geom.Rectangle2D;
31
32 /**
33  *
34  * Implementation of {@link TextureDrawingTools}.
35  * This implementation create a {@link TextureBufferedImage} an fill it with sprite drawing.
36  *
37  * @author Pierre Lando
38  */
39 public class G2DTextureDrawingTools implements TextureDrawingTools {
40
41     private Graphics2D g2d;
42     private int width;
43     private int height;
44     private java.awt.Color fillColor;
45     private java.awt.Color borderColor;
46
47     /**
48      * Default constructor.
49      * @param width the image width.
50      * @param height the image height.
51      * @param useSquareTexture true if square texture is needed.
52      */
53     public G2DTextureDrawingTools(Graphics2D g2d) {
54         this.g2d = g2d;
55     }
56
57     public void setGraphics(Graphics2D g2d) {
58         this.g2d = g2d;
59     }
60
61     public void accept(Texture texture) {
62         accept(texture, null, null);
63     }
64
65     public void accept(Texture texture, java.awt.Color borderColor, java.awt.Color fillColor) {
66         G2DTextureManager.G2DTexture t = (G2DTextureManager.G2DTexture) texture;
67         TextureDrawer drawer = t.getDrawer();
68         Dimension d = drawer.getTextureSize();
69         this.width = (int) d.getWidth();
70         this.height = (int) d.getHeight();
71         accept(drawer, this.width, this.height, borderColor, fillColor);
72     }
73
74     /**
75      * Ask this image to accept a sprite drawer.
76      * This image will contain the drawing of the given drawer.
77      * @param spriteDrawer the given sprite drawer.
78      */
79     public void accept(TextureDrawer textureDrawer, int width, int height, java.awt.Color borderColor, java.awt.Color fillColor) {
80         // Change center coordinate to (0, 0).
81         if (textureDrawer.getOriginPosition() == TextureDrawer.OriginPosition.CENTER) {
82             g2d.translate(width / 2.0, height / 2.0);
83         }
84
85         boolean aa = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON;
86         if (!aa) {
87             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
88         }
89         this.fillColor = fillColor;
90         this.borderColor = borderColor;
91         textureDrawer.draw(this);
92         this.borderColor = null;
93         this.fillColor = null;
94
95         if (!aa) {
96             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
97         }
98     }
99
100     @Override
101     public void drawPlus(int size, Appearance appearance) {
102         if (size > 1) {
103             int r = size / 2;
104             int[] coords1 = new int[] { -r, 0, r, 0};
105             int[] coords2 = new int[] {0, -r, 0, r};
106
107             drawPolyline(coords1, appearance);
108             drawPolyline(coords2, appearance);
109         } else {
110             fillDisc(0, 0, 1, appearance.getLineColor());
111         }
112     }
113
114     @Override
115     public void drawPolyline(int[] coordinates, Appearance appearance) {
116         if (coordinates.length == 2) {
117
118         }
119
120         int nbPoint = coordinates.length / 2;
121
122         int[] xCoordinates = new int[nbPoint];
123         int[] yCoordinates = new int[nbPoint];
124
125         int k = 0;
126         for (int i = 0; i < coordinates.length; i += 2) {
127             xCoordinates[k] = coordinates[i];
128             yCoordinates[k] = coordinates[i + 1];
129             k++;
130         }
131
132         g2d.setColor(getColor(appearance.getLineColor()));
133         g2d.setStroke(G2DStroke.getStroke(appearance, 0));
134
135         g2d.drawPolyline(xCoordinates, yCoordinates, nbPoint);
136     }
137
138     @Override
139     public void fillPolygon(int[] coordinates, Appearance appearance) {
140         int nbPoint = coordinates.length / 2;
141
142         int[] xCoordinates = new int[nbPoint];
143         int[] yCoordinates = new int[nbPoint];
144
145         int k = 0;
146         for (int i = 0; i < coordinates.length; i += 2) {
147             xCoordinates[k] = coordinates[i];
148             yCoordinates[k] = coordinates[i + 1];
149             k++;
150         }
151
152         if (appearance.getFillColor().getAlphaAsFloat() != 0) {
153             g2d.setColor(getColor(appearance.getFillColor()));
154             g2d.fillPolygon(xCoordinates, yCoordinates, nbPoint);
155         }
156
157         if (!appearance.getLineColor().equals(appearance.getFillColor())) {
158             int usedLength = coordinates.length - (coordinates.length % 2);
159             int[] borderCoordinate = new int[usedLength + 2];
160             System.arraycopy(coordinates, 0, borderCoordinate, 0, usedLength);
161             borderCoordinate[usedLength]     = coordinates[0];
162             borderCoordinate[usedLength + 1] = coordinates[1];
163
164             drawPolyline(borderCoordinate, appearance);
165         }
166     }
167
168     @Override
169     public void drawCircle(int x, int y, int diameter, Appearance appearance) {
170         g2d.setColor(getColor(appearance.getLineColor()));
171         g2d.setStroke(G2DStroke.getStroke(appearance, 0));
172         double r = ((double) diameter) / 2;
173         g2d.draw(new Ellipse2D.Double(x - r, y - r, diameter, diameter));
174     }
175
176     @Override
177     public void fillDisc(int x, int y, int diameter, Color color) {
178         if (color.getAlphaAsFloat() != 0) {
179             g2d.setColor(getColor(color));
180             double r = ((double) diameter) / 2;
181             g2d.fill(new Ellipse2D.Double(x - r, y - r, diameter, diameter));
182         }
183     }
184
185     @Override
186     public void draw(TextEntity textEntity, int x, int y) {
187         if (textEntity != null && textEntity.isValid()) {
188             if (textEntity.isTextAntiAliased()) {
189                 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
190             } else {
191                 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
192             }
193
194             if (textEntity.isTextUseFractionalMetrics()) {
195                 g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
196             } else {
197                 g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
198             }
199             g2d.setColor(getColor(textEntity.getTextColor()));
200             TextLayout textLayout = new TextLayout(textEntity.getText(), textEntity.getFont(), g2d.getFontRenderContext());
201             Rectangle2D bounds = textLayout.getBounds();
202             g2d.setFont(textEntity.getFont());
203             g2d.drawString(textEntity.getText(), (float) (x - bounds.getX()), y + textLayout.getAscent());
204         }
205     }
206
207     @Override
208     public void draw(Icon icon, int x, int y) {
209         icon.paintIcon(new JLabel(), g2d, x, y);
210     }
211
212     @Override
213     public void clear(Color color) {
214         g2d.setColor(getColor(color));
215         g2d.fillRect(0, 0, width, height);
216     }
217
218     public java.awt.Color getColor(Color color) {
219         if (color.equals(Color.BLACK)) {
220             if (fillColor == null) {
221                 return color;
222             }
223             return fillColor;
224         } else if (color.equals(Color.WHITE)) {
225             if (borderColor == null) {
226                 return color;
227             }
228             return borderColor;
229         }
230         return color;
231     }
232 }