Package org.timepedia.chronoscope.java2d.canvas

Source Code of org.timepedia.chronoscope.java2d.canvas.LayerJava2D

package org.timepedia.chronoscope.java2d.canvas;

import org.timepedia.chronoscope.client.Chart;
import org.timepedia.chronoscope.client.Cursor;
import org.timepedia.chronoscope.client.canvas.AbstractLayer;
import org.timepedia.chronoscope.client.canvas.Bounds;
import org.timepedia.chronoscope.client.canvas.Canvas;
import org.timepedia.chronoscope.client.canvas.CanvasImage;
import org.timepedia.chronoscope.client.canvas.CanvasPattern;
import org.timepedia.chronoscope.client.canvas.Layer;
import org.timepedia.chronoscope.client.canvas.RadialGradient;
import org.timepedia.chronoscope.client.render.LinearGradient;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.font.TextLayout;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author Ray Cromwell <ray@timepedia.org>
*/
public class LayerJava2D extends AbstractLayer {

  private static final boolean DEBUG = false;

  static class State {

    public Graphics2D ctx;

    public java.awt.Paint strokeColor;

    public java.awt.Paint fillColor;

    public BasicStroke currentStroke;

    public State(Graphics2D ctx, java.awt.Paint strokeColor,
        java.awt.Paint fillColor, BasicStroke currentStroke) {

      this.ctx = ctx;
      this.strokeColor = strokeColor;
      this.fillColor = fillColor;
      this.currentStroke = currentStroke;
    }
  }

  Pattern rgbPattern = Pattern
      .compile("rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)");

  Pattern rgbaPattern = Pattern.compile(
      "rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)");

  Stack<State> ctxStack = new Stack<State>();

  private String layerId;

  private Bounds bounds;

  private BufferedImage img;

  private Graphics2D ctx;

  private GeneralPath currentShape = new GeneralPath();

  private java.awt.Paint fillColor;

  private java.awt.Paint strokeColor;

  private BasicStroke currentStroke = new BasicStroke();

  private int compMode;

  private int zorder;

  private float layerAlpha;

  private boolean visible;

  public LayerJava2D(Canvas canvas, String layerId, Bounds b) {
    super(canvas);
    this.layerId = layerId;
    bounds = b;
    layerAlpha = 1.0f;
    visible = true;
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    int w = Math.max((int) b.width, 1);
    int h = Math.max((int) b.height, 1);

    if (ge.isHeadlessInstance()) {
      img = new BufferedImage(w, h,
          layerId.equals("backing") ? BufferedImage.TYPE_INT_RGB
              : BufferedImage.TYPE_INT_ARGB);
    } else {
      GraphicsConfiguration gc = ge.getDefaultScreenDevice()
          .getDefaultConfiguration();
//        int imageType = layerId.equals("backing") && false ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
//        img = new BufferedImage((int)b.width, (int)b.height, imageType);
      img = gc.createCompatibleImage(w, h,
          layerId.equals("backing") ? Transparency.OPAQUE
              : Transparency.TRANSLUCENT);
    }
    ctx = (Graphics2D) img.createGraphics();
    ctx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    ctx.setRenderingHint(RenderingHints.KEY_RENDERING,
        RenderingHints.VALUE_RENDER_QUALITY);
    ctx.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
        RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    setFillColor("rgba(0,0,0,0)");
    clearRect(0, 0, b.width, b.height);
  }

  public void arc(double x, double y, double radius, double startAngle,
      double endAngle, int clockwise) {

    //     Arc2D.Double a2d=new Arc2D.Double(x, y, radius, radius, startAngle/360.0*Math.PI*2.0, endAngle/360.0*2.0*Math.PI, Arc2D.OPEN);
    Ellipse2D.Double a2d = new Ellipse2D.Double(x - radius, y - radius,
        radius * 2, radius * 2);
    if (currentShape.getPathIterator(ctx.getTransform()).isDone()) {
      currentShape.moveTo((float) x, (float) y);
    }
    currentShape.append(a2d, false);
  }

  public void beginPath() {
//        currentShape.reset();
    currentShape = new GeneralPath();
  }

  public void clearRect(double x, double y, double width, double height) {

    ctx.setPaint(fillColor);
    save();
    setComposite(COPY);
    ctx.fillRect((int) x, (int) y, (int) width, (int) height);
    restore();
  }

  public void clearTextLayer(String layer) {
    //To change body of implemented methods use File | Settings | File Templates.
  }

  public void clip(int x, int y, int width, int height) {
    ctx.clipRect(x, y, width, height);
  }

  public void closePath() {
    currentShape.closePath();
  }

  public LinearGradient createLinearGradient(double startx, double starty,
      double endx, double endy) {
    return new LinearGradientJava2D(startx, starty, endx, endy);
  }

  public org.timepedia.chronoscope.client.canvas.PaintStyle createPattern(
      String imageUri) {
    return null//NI
  }

  public RadialGradient createRadialGradient(double x0, double y0, double r0,
      double x1, double y1, double r1) {
    return null//NI
  }

  public void dipose() {
    ctx.dispose();
  }

  public void drawImage(Layer backingCanvas, double x, double y, double width,
      double height) {

    ctx.drawImage(((LayerJava2D) backingCanvas).getImage(), (int) x, (int) y,
        (int) width, (int) height, null);
  }

  public void drawImage(Layer layer, double sx, double sy, double swidth,
      double sheight, double dx, double dy, double dwidth, double dheight) {
    ctx.drawImage(((LayerJava2D) layer).getImage(), (int) dx, (int) dy,
        (int) dx + (int) dwidth, (int) dy + (int) dheight, (int) sx, (int) sy,
        (int) sx + (int) swidth, (int) sy + (int) sheight,
        new Color(0, 0, 0, 0), null);
//        AffineTransform xform=new AffineTransform();
//        xform.translate(-sx, -sy);
//        xform.scale((double)dwidth/(double)swidth, (double)dheight/(double)sheight);
//        ctx.drawImage((BufferedImage)((CanvasJava2D)canvas).getImage(),
//                      new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR),
//                      dx, dy);
  }

  public void drawImage(CanvasImage image, double dx, double dy, double dwidth,
      double dheight) {
    //TODO: not implemented
  }

  public void drawRotatedText(double x, double y, double angle, String label,
      String fontFamily, String fontWeight, String fontSize, String layerName,
      Chart chart) {
    Font font = new Font(fontFamily, Font.PLAIN,
        Integer.parseInt(fontSize.substring(0, fontSize.length() - 2)) * 12 / 9)
        ;
    save();
    ctx.setFont(font);
    ctx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    ctx.setRenderingHint(RenderingHints.KEY_RENDERING,
        RenderingHints.VALUE_RENDER_QUALITY);
    ctx.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
        RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    ctx.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    ctx.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    FontMetrics fm = ctx.getFontMetrics();

    int width = fm.stringWidth(label);
    ctx.translate(x + width / 2 * Math.cos(angle),
        y + width / 2 * Math.sin(Math.abs(angle)));
    ctx.rotate(angle);
    ctx.translate(-width / 2, fm.getMaxAscent());
    ctx.setPaint(strokeColor);
    ctx.drawString(label, 0, 0);
    restore();
  }

  public void setFillColor(
      org.timepedia.chronoscope.client.canvas.Color color) {
    setFillColor(color.getCSSColor());
  }

  public void setStrokeColor(
      org.timepedia.chronoscope.client.canvas.Color color) {
    setStrokeColor(color.getCSSColor());
  }

  public void drawText(double x, double y, String label, String fontFamily,
      String fontWeight, String fontSize, String layer, Cursor cursor) {
    Font font = new Font(fontFamily, Font.PLAIN,
        Integer.parseInt(fontSize.substring(0, fontSize.length() - 2)));
    ctx.setPaint(strokeColor);
    ctx.setFont(font);

    ctx.drawString(label, (int) x,
        (int) y + ctx.getFontMetrics().getMaxAscent());
    if (DEBUG && label != null && !"".equals(label.trim())) {
      ctx.setPaint(Color.RED);

      TextLayout tl = new TextLayout(label, font, ctx.getFontRenderContext());
      Rectangle2D b = tl.getBounds();
      int h = (int) (tl.getAscent() + tl.getDescent() + tl.getLeading());
      ctx.drawRect((int) x, (int) y, (int) b.getWidth(), h);
    }
//    System.out.println("Drawing text " + label + " at " + x + ", "
//        + (y + ctx.getFontMetrics().getMaxAscent()) + " y=" + y + ", maxAscent="
//        + ctx.getFontMetrics().getMaxAscent() + " leading is " + ctx
//        .getFontMetrics().getLeading());

  }

  public void fill() {
    ctx.setPaint(fillColor);
    currentShape.closePath();
    ctx.fill(currentShape);
  }

  public void fillRect(double x, double y, double w, double h) {
    Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, h);
    ctx.setPaint(fillColor);
    ctx.fill(rect);
  }

  public Bounds getBounds() {
    return bounds;
  }

  public double getHeight() {
    return img.getHeight();
  }

  public Image getImage() {
    return img;
  }

  public float getLayerAlpha() {
    return layerAlpha;
  }

  public String getLayerId() {
    return layerId;
  }

  public int getLayerOrder() {
    return zorder;
  }

  public int getScrollLeft() {
    return 0//To change body of implemented methods use File | Settings | File Templates.
  }

  public String getStrokeColor() {
    return strokeColor.toString();
  }

  public String getTransparency() {
    return "1.0"; //NI
  }

  public double getWidth() {
    return img.getWidth();
  }

  public boolean isVisible() {
    return visible;
  }

  public void lineTo(double x, double y) {
    currentShape.lineTo((float) x, (float) y);
  }

  public void moveTo(double x, double y) {
    currentShape.moveTo((float) x, (float) y);
  }

  public void rect(double x, double y, double width, double height) {
    Rectangle2D.Double r2d = new Rectangle2D.Double(x, y, width, height);
    currentShape.append(r2d, true);
  }

  public void restore() {
    State s = ctxStack.pop();
    ctx = s.ctx;
    strokeColor = s.strokeColor;
    fillColor = s.fillColor;
    currentStroke = s.currentStroke;
  }

  public void save() {
    Graphics2D newCtx = (Graphics2D) ctx.create();
    State s = new State(ctx, strokeColor, fillColor, currentStroke);
    ctxStack.push(s);
    ctx = newCtx;
  }

  public void scale(double sx, double sy) {
    ctx.scale(sx, sy);
  }

  public void setCanvasPattern(CanvasPattern canvasPattern) {
    //NI
  }

  public void setComposite(int mode) {
    Composite comp = ctx.getComposite();
    float alpha = comp instanceof AlphaComposite ? ((AlphaComposite) comp)
        .getAlpha() : 1.0f;
    switch (mode) {
      case SRC_ATOP:
        compMode = AlphaComposite.SRC_ATOP;
        break;
      case SRC_IN:
        compMode = AlphaComposite.SRC_IN;
        break;
      case SRC_OUT:
        compMode = AlphaComposite.SRC_OUT;
        break;
      case SRC_OVER:
        compMode = AlphaComposite.SRC_OVER;
        break;
      case DEST_ATOP:
        compMode = AlphaComposite.DST_ATOP;
        break;
      case DEST_IN:
        compMode = AlphaComposite.DST_IN;
        break;
      case DEST_OUT:
        compMode = AlphaComposite.DST_OUT;
        break;
      case DEST_OVER:
        compMode = AlphaComposite.DST_OVER;
        break;
      case XOR:
        compMode = AlphaComposite.XOR;
        break;
      case COPY:
        compMode = AlphaComposite.SRC;
        break;
      default:
        compMode = AlphaComposite.SRC_OVER;
    }
    ctx.setComposite(AlphaComposite.getInstance(compMode, alpha));
  }

  public void setFillColor(String color) {

    Matcher m = rgbPattern.matcher(color);
    Matcher m2 = rgbaPattern.matcher(color);

    if (m.matches()) {
      fillColor = new Color(Integer.parseInt(m.group(1)),
          Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)));
    } else if (m2.matches()) {
      fillColor = new Color((float) Integer.parseInt(m2.group(1)) / 255.0f,
          (float) Integer.parseInt(m2.group(2)) / 255.0f,
          (float) Integer.parseInt(m2.group(3)) / 255.0f,
          (float) Integer.parseInt(m2.group(4)) / 255.0f);
    } else if (color.equals("transparent")) {
      fillColor = new Color(0, 0, 0, 0);
    } else {

      fillColor = Color.decode(color);
    }
  }

  public void setLayerAlpha(float alpha) {
    this.layerAlpha = alpha;
  }

  public void setLayerOrder(int zorder) {
    this.zorder = zorder;
  }

  public void setLinearGradient(LinearGradient lingrad) {
//        ctx.setPaint(((LinearGradientJava2D)lingrad).getNative());
    fillColor = ((LinearGradientJava2D) lingrad).getNative();
  }

  public void setLineWidth(double width) {
    currentStroke = new BasicStroke((float) width);
  }

  public void setRadialGradient(RadialGradient radialGradient) {
    //NI
  }

  public void setScrollLeft(int i) {
    //To change body of implemented methods use File | Settings | File Templates.
  }

  public void setShadowBlur(double width) {
    //NI
  }

  public void setShadowColor(String color) {
    //NI
  }

  public void setShadowOffsetX(double x) {
    //NI
  }

  public void setShadowOffsetY(double y) {
    //NI
  }

  public void setStrokeColor(String color) {

    Matcher m = rgbPattern.matcher(color);
    Matcher m2 = rgbaPattern.matcher(color);

    if (m.matches()) {
      strokeColor = new Color(Integer.parseInt(m.group(1)),
          Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)));
    } else if (m2.matches()) {
      strokeColor = new Color(Integer.parseInt(m2.group(1)),
          Integer.parseInt(m2.group(2)), Integer.parseInt(m2.group(3)),
          Integer.parseInt(m2.group(4)));
    } else if (color.equals("transparent")) {
      strokeColor = new Color(0, 0, 0, 0);
    } else {
      strokeColor = Color.decode(color);
    }
  }

  public void setTextLayerBounds(String layerName, Bounds panelPosition) {
    //NI
  }

  public void setTransparency(float value) {

    ctx.setComposite(
        AlphaComposite.getInstance(AlphaComposite.SRC_OVER, value));
  }

  public void setVisibility(boolean visibility) {
    visible = visibility;
  }

  public int stringHeight(String string, String font, String bold,
      String size) {
    if (string == null || string.length() == 0) {
      return 0;
    }

    ctx.setFont(new Font(font, Font.PLAIN,
        Integer.parseInt(size.substring(0, size.length() - 2))));
    FontMetrics fm = ctx.getFontMetrics();
    Font f = ctx.getFont();
    TextLayout tl = new TextLayout(string, f, ctx.getFontRenderContext());
    Rectangle2D b = tl.getBounds();
    int h = (int) (tl.getAscent() + tl.getDescent() + tl.getLeading());
    // b.getHeight();//(int) fm.getMaxAscent() + fm.getMaxDescent() + 2;
//    System.out.println("height of " + string + " is " + h + "  vs " + fm
//        .getStringBounds(string, ctx));
    return h;
//        .getHeight();
  }

  public int stringWidth(String string, String font, String bold, String size) {
    if (string == null || string.length() == 0) {
      return 0;
    }

    ctx.setFont(new Font(font, Font.PLAIN,
        Integer.parseInt(size.substring(0, size.length() - 2))));
    return ctx.getFontMetrics().stringWidth(string);
  }

  public void stroke() {
    ctx.setStroke(currentStroke);
    ctx.setPaint(strokeColor);
    ctx.draw(currentShape);
  }

  public void translate(double x, double y) {
    ctx.translate(x, y);
  }
}
TOP

Related Classes of org.timepedia.chronoscope.java2d.canvas.LayerJava2D

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.