    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}