BezierLineElement.java :  » Tools » feelsketch » com » nullfish » app » feel_sketch » editor » elements » bezier_line » Android Open Source

Android Open Source » Tools » feelsketch 
feelsketch » com » nullfish » app » feel_sketch » editor » elements » bezier_line » BezierLineElement.java
/**
***                      "Feel Sketch" authoring tool.
***    Copyright (C) 2009, Shunji Yamaura
***    Copyright (C) 2009, Noritsuna Imamura (noritsuna@siprop.org)
***
***    This program is free software: you can redistribute it and/or modify
***    it under the terms of the GNU General Public License as published by
***    the Free Software Foundation, either version 3 of the License, or
***    (at your option) any later version.
***
***    This program is distributed in the hope that it will be useful,
***    but WITHOUT ANY WARRANTY; without even the implied warranty of
***    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
***    GNU General Public License for more details.
***
***    You should have received a copy of the GNU General Public License
***    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.nullfish.app.feel_sketch.editor.elements.bezier_line;

import java.awt.BasicStroke;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.List;

import com.nullfish.app.feel_sketch.editor.AbstractElement;
import com.nullfish.app.feel_sketch.editor.Layer;
import com.nullfish.app.feel_sketch.editor.Pen;

/**
 * A class of bezier line.
 * @author shunji
 *
 */
public class BezierLineElement extends AbstractElement {
  /**
   * A shape of this object.
   */
  private Area area = new Area();
  
  /**
   * A line which is drawn in bezier line.
   */
  private Path2D path = new Path2D.Double();

  /**
   * A shape of the bezier line.
   */
  private Area bezierArea = new Area();
  
  /**
   * A line which hasn't become a bezier line yet.
   */
  private Path2D newLine = new Path2D.Double();
  
  /**
   * A stroke of the line.
   */
  private Stroke stroke;
  
  /**
   * Alpha composite of the line.
   */
  private Composite composite;

  public BezierLineElement(BezierLineElementModel model, Layer layer) {
    super(model, layer);
    
    stroke = new BasicStroke(model.getPen().getRealWidth(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
    
    composite = model.getPen().getComposite();
    
    for(Point2D[] line : model.getPoints()) {
      bezierAdded(line);
    }
    
    for(Point2D p : model.getNewPoints()) {
      pointAdded(p);
    }
  }

  @Override
  public void paint(Graphics2D g) {
    Composite orgComposite = g.getComposite();
    
    g.setColor(((BezierLineElementModel)getModel()).getColor());
    g.setStroke(stroke);
    g.setComposite(composite);
    if(g.getClipBounds() == null || bezierArea.intersects(g.getClipBounds())) {
      g.draw(path);
    }
    
    g.draw(newLine);
    g.setComposite(orgComposite);
/*    
    Rectangle clip = g.getClipBounds();
    List<Point2D[]> pointList = ((BezierLineElementModel)getModel()).getPoints();
    for(Point2D[] ps : pointList) {
      g.setColor(Color.BLUE);
      g.fillRect((int)ps[0].getX() - 2, (int)ps[0].getY() - 2, 4, 4);
      g.setColor(Color.RED);
      g.fillRect((int)ps[1].getX() - 2, (int)ps[1].getY() - 2, 4, 4);
      g.fillRect((int)ps[2].getX() - 2, (int)ps[2].getY() - 2, 4, 4);
    }
    
    g.setColor(Color.BLUE);
    if(pointList.size() > 0) {
      g.fillRect(
          (int)pointList.get(pointList.size() - 1)[3].getX() - 2,
          (int)pointList.get(pointList.size() - 1)[3].getY() - 2,
          4, 4);
    }
*/
  }


  @Override
  public void modelAdded(String name, Object added) {
    if(name.equals(BezierLineElementModel.BEZIER)) {
      Point2D[] points = (Point2D[]) added;
      bezierAdded(points);
    }
  }

  private void bezierAdded(Point2D[] points) {
    if(path.getCurrentPoint() == null) {
      path.moveTo(points[0].getX(), points[0].getY());
    }
    path.curveTo(
        points[1].getX(), points[1].getY(),
        points[2].getX(), points[2].getY(),
        points[3].getX(), points[3].getY());

    Path2D newBezier = new Path2D.Double();
    newBezier.moveTo(points[0].getX(), points[0].getY());
    newBezier.curveTo(
        points[1].getX(), points[1].getY(),
        points[2].getX(), points[2].getY(),
        points[3].getX(), points[3].getY());
    
    Shape shape = stroke.createStrokedShape(path);
    bezierArea = new Area(shape);
    Rectangle bounds = shape.getBounds();
    addDirtyRegion(bounds);
    
    clearShape();
    getShape();
  }

  @Override
  public void modelChanged(String name, Object oldValue, Object newValue) {
    if(name.equals(BezierLineElementModel.COLOR)) {
      clearShape();
      repaint();
    } else if(name.equals(BezierLineElementModel.END_POINT)) {
      Point2D newPoint = (Point2D) newValue;
      
      pointAdded(newPoint);
    } else if(name.equals(BezierLineElementModel.PEN)) {
      Pen pen = (Pen)newValue;
      stroke = new BasicStroke(pen.getRealWidth(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
      addDirtyRegion(stroke.createStrokedShape(path).getBounds());
      clearShape();
      repaint();
    }
  }

  private void pointAdded(Point2D newPoint) {
    Point2D oldPoint = newLine.getCurrentPoint();
    if(oldPoint != null) {
      newLine.lineTo(newPoint.getX(), newPoint.getY());
    } else {
      newLine.moveTo(newPoint.getX(), newPoint.getY());
    }
    
    Rectangle rect = new Rectangle();
    rect.x = (int)newPoint.getX();
    rect.y = (int)newPoint.getY();
    if(oldPoint != null) {
      rect.add(oldPoint);
    }
    
    int width = ((BezierLineElementModel)getModel()).getPen().getRealWidth();
    rect.add(rect.x - width, rect.y - width);
    rect.add(rect.x + rect.width + width, rect.y + rect.width + width);
    addDirtyRegion(rect);

    clearShape();
  }
  
  private void repaint() {
    addDirtyRegion(bezierArea.getBounds());
  }

  @Override
  public void modelRemoved(String name, Object removed) {
    if(name.equals(BezierLineElementModel.NEW_LINE)) {
      addDirtyRegion(stroke.createStrokedShape(newLine).getBounds());
      newLine = new Path2D.Double();
      List<Point2D> points = ((BezierLineElementModel)getModel()).getNewPoints();
      if(points.size() > 0) {
        newLine.moveTo(points.get(0).getX(), points.get(0).getY());
        for(int i=1; i<points.size(); i++) {
          newLine.lineTo(points.get(1).getX(), points.get(1).getY());
        }
      }
      clearShape();
    }
  }

  @Override
  protected Shape getCurrentShape() {
    area.reset();
    area.add(bezierArea);
    if(newLine.getCurrentPoint() != null) {
      area.add(new Area(stroke.createStrokedShape(newLine)));
    }
    
    return area;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.