001package org.vishia.gral.ifc;
002
003import java.util.List;
004import java.util.concurrent.ConcurrentLinkedQueue;
005
006import org.vishia.gral.base.GralGridProperties;
007import org.vishia.gral.base.GralMng;
008import org.vishia.gral.base.GralPos;
009import org.vishia.gral.widget.GralPlotArea;
010
011
012
013/**The canvas storage is a storage, which stores orders to paint. This orders are painted
014 * if the paint-routine from the windows-system is invoked. An application can call
015 * forex the {@link #drawLine(Color, int, int, int, int)}-routine to draw a line. This line
016 * will be drawn immediately, if the graphical window or widget gets the redraw-request.
017 * Firstly the line will be stored only. 
018 * @author Hartmut Schorrig
019 *
020 */
021public class GralCanvasStorage implements GralCanvas_ifc
022{
023  /**Version, history and license.
024   * <ul>
025   * <li>2012-09-27 Hartmut new: {@link PolyLineFloatArray}
026   * <li>2012-04-22 new {@link #drawLine(GralPos, GralColor, List)}, improved {@link PaintOrder}-derivates.
027   * <li>2011-06-00 Hartmut created
028   * </ul>
029   * 
030   * <b>Copyright/Copyleft</b>:<br>
031   * For this source the LGPL Lesser General Public License,
032   * published by the Free Software Foundation is valid.
033   * It means:
034   * <ol>
035   * <li> You can use this source without any restriction for any desired purpose.
036   * <li> You can redistribute copies of this source to everybody.
037   * <li> Every user of this source, also the user of redistribute copies
038   *    with or without payment, must accept this license for further using.
039   * <li> But the LPGL is not appropriate for a whole software product,
040   *    if this source is only a part of them. It means, the user
041   *    must publish this part of source,
042   *    but doesn't need to publish the whole source of the own product.
043   * <li> You can study and modify (improve) this source
044   *    for own using or for redistribution, but you have to license the
045   *    modified sources likewise under this LGPL Lesser General Public License.
046   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
047   * </ol>
048   * If you intent to use this source without publishing its usage, you can get
049   * a second license subscribing a special contract with the author. 
050   * 
051   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
052   */
053  public static final String version = "2015-09-26";
054
055        /**Data class to store an order.
056         */
057        public static class PaintOrder
058        {
059                /**One of the static int of this class. Determines what to paint. 
060                 * See {@link GralCanvasStorage#paintLine}, {@link GralCanvasStorage#paintImage}, 
061                 * */
062                public final int paintWhat;
063                
064                /**Coordinates. */
065                public final int x1,y1,x2,y2;
066                
067                public final GralPos pos;
068                
069                public final GralColor color;
070
071                /**The implementation data are graphic-platform-specific. It may be prepared data for a defined
072                 * size appearance to support fast redrawing. */
073                private Object implData;
074                
075                public Object getImplData() { return implData; }
076
077    public void setImplData(Object implData) { this.implData = implData; }
078
079    PaintOrder(int paintWhat, int x1, int y1, int x2, int y2, GralColor color) {
080      this.paintWhat = paintWhat;
081      this.x1 = x1;
082      this.y1 = y1;
083      this.x2 = x2;
084      this.y2 = y2;
085      this.color = color;
086      this.pos = null;
087    }
088
089    PaintOrder(int paintWhat, GralPos pos, GralColor color) {
090      this.paintWhat = paintWhat;
091      this.pos = pos == null ? null: pos.clone();
092      this.x1 = -1;
093      this.y1 = -1;
094      this.x2 = -1;
095      this.y2 = -1;
096      this.color = color;
097    }
098
099        }//class PaintOrder
100
101        
102  public static class PolyLine extends PaintOrder
103  {
104    public final List<GralPoint> points;
105    
106    public boolean bPointsAreGralPosUnits = true;
107    
108    PolyLine(GralPos pos, GralColor color, List<GralPoint> points){
109      super(paintPolyline, pos, color);
110      this.points = points;
111    }
112  }
113  
114  
115  
116  public static class PolyLineFloatArray extends PaintOrder
117  {
118    private final float[][] points;
119    
120    private final int iy;
121    
122    final GralPlotArea.UserUnits userUnits;
123    
124    private Object implStore;
125    
126    /**Creates an Paint order which paints a line from array points.
127     * @param color
128     * @param userUnits
129     * @param points The elements[...][0] contains the x-value. The elements[...][iy] contains the y-value.
130     */
131    public PolyLineFloatArray(GralColor color, GralPlotArea.UserUnits userUnits, float[][] points, int iy){
132      super(paintPolyline, null, color);
133      this.userUnits = userUnits;
134      this.points = points;
135      this.iy = iy;
136    }
137    
138    /**Sets any instance which stores implementation specific data. This method should only called by the implementation layer. */
139    public void setImplStore(Object store){ implStore = store; }
140    
141    /**Gets the implementation specific instance. */
142    public Object getImplStore(){ return implStore; }
143
144    /**Gets the implementation specific instance. */
145    public int[] getImplStoreInt1Array(){ 
146      if(implStore == null) {
147        int[] store = new int[2*points.length];
148        implStore = store;
149        int ixd = -1;
150        GralGridProperties props = GralMng.get().propertiesGui;
151        int fxp = props.xPixelUnit();
152        int fyp = props.yPixelUnit();
153        for(float[] point: points){
154          float x = point[0], y = point[iy];
155          store[++ixd] = (int)(userUnits.fx * fxp * (x - userUnits.x0) + 0.5f);
156          store[++ixd] = (int)(userUnits.fy * fyp * (y - userUnits.y0) + 0.5f);
157        }
158      }
159      return (int[])implStore; 
160    }
161  }
162  
163  
164  
165        public static class PaintOrderImage extends PaintOrder
166        {
167          public final GralImageBase image;
168          public final int dxImage, dyImage;
169          PaintOrderImage(GralImageBase image, int line, int column, int heigth, int width, GralRectangle pixelImage)
170          { super(paintImage, line, column, heigth, width, null);
171            this.image = image;
172      this.dxImage = pixelImage.dx;
173      this.dyImage = pixelImage.dy;
174          }
175        }//class PaintOrderImage
176        
177        public final static int paintLine = 0xee, paintImage = 0x1ae;
178        
179        public final static int paintPolyline = 'y';
180        
181        /**List of all orders to paint in {@link #drawBackground(GC, int, int, int, int)}.
182         * 
183         */
184        public final ConcurrentLinkedQueue<PaintOrder> paintOrders = new ConcurrentLinkedQueue<PaintOrder>();
185        
186        
187        
188  /**Accepts a order to draw a line. The coordinates are stored only. 
189   * This method can be called in any thread. It is thread-safe.
190   * @param color
191   * @param x1 TODO yet it is pixel coordinates, use GralGrid coordinates.
192   * @param y1
193   * @param x2
194   * @param y2
195   */
196  public void drawLine(GralColor color, int x1, int y1, int x2, int y2){
197    PaintOrder order = new PaintOrder(paintLine, x1,y1,x2,y2, color);
198    paintOrders.add(order);  //paint it when drawBackground is invoked.
199  }
200  
201
202  /**Accepts a order to draw a line. The coordinates are stored only. 
203   * This method can be called in any thread. It is thread-safe.
204   * @param color
205   */
206  public void drawLine(GralPos pos, GralColor color, List<GralPoint> points){
207    PaintOrder order = new PolyLine(pos, color, points);
208    paintOrders.add(order);  //paint it when drawBackground is invoked.
209  }
210  
211
212  /**Accepts a order to draw a line. The coordinates are stored only. 
213   * This method can be called in any thread. It is thread-safe.
214   * @param color
215   */
216  public void drawLine(GralColor color, GralPlotArea.UserUnits userUnits, float[][] points, int iy){
217    PolyLineFloatArray order = new PolyLineFloatArray(color, userUnits, points, iy);
218    paintOrders.add(order);  //paint it when drawBackground is invoked.
219  }
220  
221
222        public void drawImage(GralImageBase image, int x, int y, int dx, int dy, GralRectangle imagePixelSize)
223        {
224    PaintOrder order = new PaintOrderImage(image, x, y, dx, dy, imagePixelSize);
225    paintOrders.add(order);  //paint it when drawBackground is invoked.
226        }
227
228
229  @Override
230  public void drawText(String text)
231  {
232    // TODO Auto-generated method stub
233    
234  }
235
236
237  @Override
238  public void setTextStyle(GralColor color, GralFont font, int origin)
239  {
240    // TODO Auto-generated method stub
241    
242  }
243        
244        
245        //public abstract void redraw();
246        
247}