DrawingCanvas.java
     1: //========================================================================================
     2: //  DrawingCanvas.java
     3: //    en:Drawing canvas
     4: //    ja:ドローイングキャンバス
     5: //  Copyright (C) 2003-2019 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: //----------------------------------------------------------------------------------------
    14: //  ScrollCanvasに任意のShapeを任意のStrokeとPaintで描画する
    15: //  ShapeはスケーリングされるがStrokeの太さやPaintのグラデーションやテクスチャの大きさは変化しない
    16: //----------------------------------------------------------------------------------------
    17: 
    18: package xeij;
    19: 
    20: import java.awt.*;  //BasicStroke,BorderLayout,BoxLayout,Color,Component,Container,Cursor,Desktop,Dimension,Font,Frame,Graphics,Graphics2D,GraphicsDevice,GraphicsEnvironment,GridLayout,Image,Insets,Paint,Point,Rectangle,RenderingHints,Robot,Shape,Stroke,TexturePaint,Toolkit
    21: import java.awt.geom.*;  //AffineTransform,GeneralPath,Point2D,Rectangle2D
    22: import java.awt.image.*;  //BufferedImage,DataBuffer,DataBufferByte,DataBufferInt,IndexColorModel
    23: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    24: import java.util.*;  //ArrayList,Arrays,Calendar,GregorianCalendar,HashMap,Map,Map.Entry,Timer,TimerTask,TreeMap
    25: 
    26: public class DrawingCanvas extends ScrollCanvas {
    27: 
    28:   //インスタンス変数
    29:   protected AffineTransform transformToView;  //キャンバス座標からビュー座標への変換
    30:   protected HashMap<Integer,Shape> shapes;  //Shapeのマップ。null=描画しない
    31:   protected HashMap<Integer,GeneralPath> scaledShapes;  //スケーリングされたShapeのマップ
    32:   protected HashMap<Integer,Stroke> strokes;  //Strokeのマップ
    33:   protected HashMap<Integer,Paint> drawPaints;  //draw用のPaintのマップ。null=drawしない
    34:   protected HashMap<Integer,Paint> fillPaints;  //fill用のPaintのマップ。null=fillしない
    35: 
    36:   //コンストラクタ
    37:   public DrawingCanvas () {
    38:     init ();
    39:   }
    40:   public DrawingCanvas (int width, int height) {
    41:     super (width, height);
    42:     init ();
    43:   }
    44:   public DrawingCanvas (BufferedImage image) {
    45:     super (image);
    46:     init ();
    47:   }
    48:   private void init () {
    49:     shapes = new HashMap<Integer,Shape> ();
    50:     scaledShapes = new HashMap<Integer,GeneralPath> ();
    51:     strokes = new HashMap<Integer,Stroke> ();
    52:     drawPaints = new HashMap<Integer,Paint> ();
    53:     fillPaints = new HashMap<Integer,Paint> ();
    54:   }
    55: 
    56:   //ビューを描画する
    57:   protected void paintView (Graphics g) {
    58:     super.paintView (g);
    59:     if (canvasImage != null) {
    60:       Graphics2D g2 = (Graphics2D) g;
    61:       Integer[] keyArray = shapes.keySet ().toArray (new Integer[0]);
    62:       Arrays.sort (keyArray);
    63:       for (int i : keyArray) {
    64:         Shape scaledShape = scaledShapes.get (i);
    65:         if (scaledShape != null) {
    66:           Stroke stroke = strokes.get (i);
    67:           if (stroke != null) {
    68:             g2.setStroke (stroke);
    69:           }
    70:           Paint fillPaint = fillPaints.get (i);
    71:           if (fillPaint != null) {
    72:             g2.setPaint (fillPaint);
    73:             g2.fill (scaledShape);
    74:           }
    75:           Paint drawPaint = drawPaints.get (i);
    76:           if (drawPaint != null) {
    77:             g2.setPaint (drawPaint);
    78:             g2.draw (scaledShape);
    79:           }
    80:         }
    81:       }
    82:     }
    83:   }
    84: 
    85:   //追加のサイズ計算
    86:   protected void calcAdditionalSize () {
    87:     transformToView = new AffineTransform (scaleFactor, 0.0F, 0.0F, scaleFactor,
    88:                                            (float) originX, (float) originY);
    89:     for (int i : shapes.keySet ()) {
    90:       calcScaledShape (i);
    91:     }
    92:   }
    93: 
    94:   //Shapeを設定する
    95:   public void setShape (int i, Shape shape, Stroke stroke, Paint drawPaint, Paint fillPaint) {
    96:     shapes.put (i, shape);
    97:     scaledShapes.put (i, new GeneralPath ());
    98:     calcScaledShape (i);
    99:     strokes.put (i, stroke);
   100:     drawPaints.put (i, drawPaint);
   101:     fillPaints.put (i, fillPaint);
   102:     view.repaint ();
   103:   }
   104: 
   105:   //Shapeをスケーリングする
   106:   protected void calcScaledShape (int i) {
   107:     Shape shape = shapes.get (i);
   108:     if (shape != null) {
   109:       GeneralPath scaledShape = scaledShapes.get (i);
   110:       if (scaledShape != null) {
   111:         scaledShape.reset ();
   112:         float[] coords = new float[6];
   113:         for (PathIterator iterator = shape.getPathIterator (transformToView);
   114:              !iterator.isDone (); iterator.next ()) {
   115:           switch (iterator.currentSegment (coords)) {
   116:           case PathIterator.SEG_CLOSE:
   117:             scaledShape.closePath ();
   118:             break;
   119:           case PathIterator.SEG_CUBICTO:
   120:             scaledShape.curveTo (coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
   121:             break;
   122:           case PathIterator.SEG_LINETO:
   123:             scaledShape.lineTo (coords[0], coords[1]);
   124:             break;
   125:           case PathIterator.SEG_MOVETO:
   126:             scaledShape.moveTo (coords[0], coords[1]);
   127:             break;
   128:           case PathIterator.SEG_QUADTO:
   129:             scaledShape.quadTo (coords[0], coords[1], coords[2], coords[3]);
   130:             break;
   131:           }  //switch
   132:         }  //iterator
   133:       }  //scaledShape!= null
   134:     }  //shape!=null
   135:   }  //calcScaledShape
   136: 
   137: }  //class DrawingCanvas
   138: 
   139: 
   140: