Package org.rascalmpl.library.vis.graphics

Source Code of org.rascalmpl.library.vis.graphics.SWTGraphicsContext

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.rascalmpl.library.vis.graphics;

import static org.rascalmpl.library.vis.util.FigureMath.CLOSE;
import static org.rascalmpl.library.vis.util.FigureMath.OPEN;
import static org.rascalmpl.library.vis.util.FigureMath.degrees;

import java.util.ArrayList;
import java.util.Stack;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Resource;
import org.eclipse.swt.graphics.Transform;
import org.rascalmpl.library.vis.swt.SWTFontsAndColors;
import org.rascalmpl.library.vis.util.FigureColorUtils;

public class SWTGraphicsContext implements GraphicsContext {
 

 
  private volatile GC gc;
  private int shadowColor;
  private double shadowLeft;
  private double shadowTop;
  private Stack<Transform> stackMatrix = new Stack<Transform>();
  private Stack<Route> stackPath = new Stack<Route>();
  private int alphaStroke = FigureColorUtils.OPAQUE, alphaFill = FigureColorUtils.OPAQUE, alphaFont = FigureColorUtils.OPAQUE;
  private boolean shadow;
  private boolean fill = true, stroke = true;
  private boolean debug;
  private Font currentFont;
  private FontData currentFontData;
  private Device device;
  private Color foregroundColor;
  private Color backgroundColor;
  private Color fontColor;
  double translateX, translateY;
 
 
  FontData fontData;
  int foreGroundCI, backgroundCI, fontCI;
 

 
  public SWTGraphicsContext() {
  }
 
  public void setGC(GC gc){
    this.gc = gc;
    this.device = gc.getDevice();
    gc.setAdvanced(true);
    gc.setAntialias(SWT.ON);
    gc.setInterpolation(SWT.HIGH);
    disposeIfNessary(currentFont);
    currentFontData = null;
    currentFont = null;
    translateX = translateY = 0;
    stackMatrix.clear();
    gc.setTransform(null);
  }
 
  public GC getGC(){
    return gc;
  }
 
 

  @SuppressWarnings("serial")
  class Route extends ArrayList<TypedPoint> {
    void add(double x, double y, TypedPoint.kind curved) {
      super.add(new TypedPoint(x, y, curved));
    }
  }

 
  enum SHAPE {
    ELLIPSE, RECTANGLE
  }


  public void line(double arg0, double arg1, double arg2, double arg3) {
    gc.drawLine((int) arg0, (int) arg1, (int) arg2, (int) arg3);
  }

  public void rect(double x, double y, double width, double height) {
    int alpha0 = gc.getAlpha();
    int xi, yi, wi,hi;
    xi = (int)(x);
    yi = (int)(y);
    wi = (int)(x + width) - (int)x;
    hi = (int)(y + height) - (int)y;

    if (fill) {
      gc.setAlpha(alphaFill);
      if (shadow) {
        drawShadowFigure(SHAPE.RECTANGLE, xi, yi, wi, hi);
      }
      gc.fillRectangle( xi, yi, wi, hi);
      gc.setAlpha(alpha0);
    }
    if (stroke) {
      gc.setAlpha(alphaStroke);
     
      gc.drawRectangle(xi, yi, wi, hi);
      gc.setAlpha(alpha0);
    }

  }

  public void ellipse(double x, double y, double width, double height) {
    int xi, yi, wi,hi;
    xi = (int)(x);
    yi = (int)(y);
    wi = (int)(x + width) - (int)x;
    hi = (int)(y + height) - (int)y;
    int alpha0 = gc.getAlpha();
    if (fill) {
      gc.setAlpha(alphaFill);
      if (shadow) {
        drawShadowFigure(SHAPE.ELLIPSE, xi, yi, wi, hi);
      }
      gc.fillOval(xi, yi, wi, hi);
      gc.setAlpha(alpha0);
    }
    if (stroke) {
      gc.setAlpha(alphaStroke);
      gc.drawOval(xi, yi, wi, hi);
      gc.setAlpha(alpha0);
    }
  }
 
  private void disposeIfNessary(Resource r){
    if(!(r == null || r.isDisposed())){
      r.dispose();
    }
  }

  public void fill(int arg0) {
    fill = true;
    alphaFill = FigureColorUtils.getAlpha(arg0);
    int backgroundCI = FigureColorUtils.withoutAlpha(arg0);
    if(this.backgroundCI == backgroundCI  && backgroundColor != null) return;
    this.backgroundCI = backgroundCI;
    disposeIfNessary(backgroundColor);
    backgroundColor = SWTFontsAndColors.getRgbColor(arg0);
    gc.setBackground(backgroundColor);
   
  }

  public void stroke(int arg0) {
    stroke = true;
    alphaStroke = FigureColorUtils.getAlpha(arg0);
    int foreGroundCI = FigureColorUtils.withoutAlpha(arg0);
    if(this.foreGroundCI == foreGroundCI && foregroundColor != null) return;
    this.foreGroundCI = foreGroundCI;
    disposeIfNessary(foregroundColor);
    foregroundColor = SWTFontsAndColors.getRgbColor(arg0);
    gc.setForeground(foregroundColor);
   
  }
 
  public void font(int color){
    alphaFont = FigureColorUtils.getAlpha(color);
    int fontCI = FigureColorUtils.withoutAlpha(color);
    if(this.fontCI == fontCI && fontColor != null) return;
    this.fontCI = fontCI;
    disposeIfNessary(fontColor);
    fontColor = SWTFontsAndColors.getRgbColor(color);
  }

  public void strokeWeight(double arg0) {
    int d = (int) arg0;
    stroke = (d != 0);
    gc.setLineWidth(d);
  }

   int getSWTLineStyle(String s) {
         if (s.equals("dash")) return SWT.LINE_DASH;
         if (s.equals("dot")) return SWT.LINE_DOT;
         if (s.equals("dashdot")) return SWT.LINE_DASHDOT;
         if (s.equals("dashdotdot")) return SWT.LINE_DASHDOTDOT;
         return SWT.LINE_SOLID;
     }
 
  public void strokeStyle(String style) {
    gc.setLineStyle(getSWTLineStyle(style));
  }

  public void textSize(double arg0) {
    if (gc.getFont().getFontData().length < 1)
      return;
    gc.getFont().getFontData()[0].setHeight((int) arg0);

  }
 
  public void text(String arg0, double x, double y) {
    gc.setAlpha(alphaFont);
    gc.setForeground(fontColor);
    gc.drawText(arg0, (int) x, (int) y, true);
    gc.setForeground(foregroundColor);
    gc.setAlpha(alphaStroke);
  }

  public void pushMatrix() {
    Transform transform = new Transform(gc.getDevice());
    gc.getTransform(transform);
    stackMatrix.push(transform);
  }

  public void popMatrix() {
    Transform transform = stackMatrix.pop();
    gc.setTransform(transform);
  }

  public void rotate(double angle) {
    Transform transform = new Transform(gc.getDevice());
    Transform transform2 = new Transform(gc.getDevice());
    gc.getTransform(transform);
    transform2.rotate((float)angle);
    transform.multiply(transform2);
    gc.setTransform(transform);
  }

  public void translate(double x, double y) {
    translateX+=x;
    translateY+=y;
    Transform transform = new Transform(gc.getDevice());
    Transform transform2 = new Transform(gc.getDevice());
    gc.getTransform(transform2);
    transform2.translate((float) x, (float) y);
    transform.multiply(transform2);
    gc.setTransform(transform);
  }

  public void scale(double scaleX, double scaleY) {
    Transform transform = new Transform(gc.getDevice());
    Transform transform2 = new Transform(gc.getDevice());
    gc.getTransform(transform);
    transform2.scale((float) scaleX, (float) scaleY);
    transform.multiply(transform2);
    gc.setTransform(transform);
  }

  public void bezierVertex(double cx1, double cy1, double cx2, double cy2,
      double x, double y) {
    Route r = stackPath.peek();
    r.add(cx1, cy1, TypedPoint.kind.BEZIER);
    r.add(cx2, cy2, TypedPoint.kind.BEZIER);
    r.add(x, y, TypedPoint.kind.BEZIER);
  }

  public void vertex(double x, double y) {
    Route r = stackPath.peek();
    r.add(x, y, TypedPoint.kind.NORMAL);
  }

  public void curveVertex(double x, double y) {
    Route r = stackPath.peek();
    r.add(x, y, TypedPoint.kind.CURVED);
  }

  public void noFill() {
    fill = false;
  }

  public void arc(double x, double y, double width, double height,
      double startAngle, double stopAngle) {
    gc.drawArc((int) x, (int) y, (int) width, (int) height,
        (int) degrees(startAngle),
        (int) degrees(stopAngle));

  }

  public void beginShape() {
    stackPath.clear();
    Route p = new Route();
    stackPath.push(p);
  }

  public void beginShape(int arg0) {
    beginShape();

  }

  private void drawNotCurved(Route r, Path p) {
    // System.err.println("drawNotCurved:" + r.size());
    while (!r.isEmpty()) {
      TypedPoint z = r.get(0);
      // System.err.println("Curved:" + z.curved);
      if (z.curved == TypedPoint.kind.NORMAL) {
        p.lineTo((float) z.x, (float) z.y);
        r.remove(0);
      } else if (z.curved == TypedPoint.kind.BEZIER) {
        double c1x = z.x, c1y = z.y;
        r.remove(0);
        z = r.remove(0);
        double c2x = z.x, c2y = z.y;
        z = r.remove(0);
        double x = z.x, y = z.y;
        p.cubicTo((float) c1x, (float) c1y, (float) c2x, (float) c2y,
            (float) x, (float) y);
      } else {
        break;
      }
    }
  }

  private void drawCurved(Route r, Path p, boolean closed) {
    // System.err.println("drawCurved:" + r.size());
    if (r.size() < 3)
      return;
    Interpolation.solve(r, closed);
    int n = Interpolation.P0.length;
    for (int i = 0; i < n; i++)
      p.cubicTo((float) Interpolation.P1[i].x,
          (float) Interpolation.P1[i].y,
          (float) Interpolation.P2[i].x,
          (float) Interpolation.P2[i].y,
          (float) Interpolation.P3[i].x,
          (float) Interpolation.P3[i].y);
  }

  public void endShape() {
    endShape(OPEN);
  }

  public void endShape(int arg0) {
    Route r = stackPath.pop();
    Path p = new Path(gc.getDevice());
    if (debug)
      System.err.println("endShape1:" + r.size());
    TypedPoint q = r.get(0);
    if (q.curved != TypedPoint.kind.CURVED)
      r.remove(0);
    p.moveTo((float) q.x, (float) q.y);
    if (debug)
      System.err.println("q=(" + q.x + "," + q.y + " " + q.curved + ")");
    if (arg0 == CLOSE) {
      r.add(new TypedPoint(q.x, q.y, TypedPoint.kind.NORMAL));
    }
    while (!r.isEmpty()) {
      drawNotCurved(r, p);
      drawCurved(r, p, arg0 == CLOSE);
    }
    int alpha0 = gc.getAlpha();
    if (fill /* arg0 == CLOSE */) {
      gc.setAlpha(alphaFill);
      gc.fillPath(p);
      gc.setAlpha(alpha0);
    }
    if (stroke) {
      gc.setAlpha(alphaStroke);
      gc.drawPath(p);
      gc.setAlpha(alpha0);
    }
    p.dispose();
  }


  public void setShadow(boolean shadow) {
    this.shadow = shadow;

  }

  public void setShadowColor(int color) {
    this.shadowColor = color;
  }

  public void setShadowLeft(double x) {
    this.shadowLeft = x;

  }

  public void setShadowTop(double y) {
    this.shadowTop = y;
  }

  /*
  enum PRIMITIVE {
    rect, ellipse, line, fill, stroke, strokeWeight, text, textColor, textFont, textSize;
    void draw(FigureSWTApplet p, IConstructor c) {
      double[] d = new double[4];
      int[] n = new int[4];
      String[] s = new String[4];
      int z = c.arity();
      for (int i = 0; i < z; i++) {
        if (c.get(i) instanceof INumber)
          d[i] = ((INumber) c.get(i)).toReal().doubleValue();
        if (c.get(i) instanceof IInteger)
          n[i] = ((IInteger) c.get(i)).intValue();
        if (c.get(i) instanceof IString)
          s[i] = ((IString) c.get(i)).getValue();
      }
      switch (this) {
      case line:
        p.line(d[0], d[1], d[2], d[3]);
        return;
      case rect:
        p.rect(d[0], d[1], d[2], d[3]);
        return;
      case ellipse:
        p.ellipse(d[0], d[1], d[2], d[3]);
        return;
      case stroke:
        p.stroke(n[0]);
        return;
      case strokeWeight:
        p.strokeWeight(d[0]);
        return;
      case fill:
        p.fill(n[0]);
        return;
      case text:
        p.text(s[0], d[1], d[2]);
        return;
      case textFont:
        p.textFont(p.createFont(s[0], d[1]));
        return;
      case textSize:
        p.textSize(d[0]);
        return;
      case textColor:
        p.textColor(n[0]);
        return;
      }
    }
  }
  */

  private void drawShadowFigure(SHAPE shape, int x, int y, int width,
      int height) {
    translate(shadowLeft, shadowTop);
    int arg0 = shadowColor;
    int alpha0 = gc.getAlpha();
    Color color0 = gc.getBackground();
    int alpha = FigureColorUtils.getAlpha(arg0);
    gc.setAlpha(alpha);
    Color color = new Color(device, FigureColorUtils.getRed(arg0),
        FigureColorUtils.getGreen(arg0), FigureColorUtils.getBlue(arg0));
    gc.setBackground(color);
    switch (shape) {
    case RECTANGLE:
      gc.fillRectangle(x, y, width, height);
      break;
    case ELLIPSE:
      gc.fillOval(x, y, width, height);
      break;
    }
    translate(-shadowLeft, -shadowTop);
    gc.setAlpha(alpha0);
    gc.setBackground(color0);
  }

 
 
  public void setFont(String fontName, int fontSize, FontStyle... styles) {
    int styleMask = FontStyle.toStyleMask(styles);
    if(currentFontData != null && currentFontData.getName().equals(fontName) && currentFontData.getHeight() == (int)fontSize && currentFontData.getStyle() == styleMask){
      return;
    }
    FontData fd = new FontData(fontName, (int) fontSize, styleMask );
    currentFontData = fd;
    //if(fd.equals(this.fontData)) return;
    this.fontData = fd;
    disposeIfNessary(currentFont);
    currentFont = new Font(device, fd);
    gc.setFont(currentFont);
  }
 
  public void dispose(){
    gc.dispose();
  }

  @Override
  public double getTranslateX() {
    return translateX;
  }

  @Override
  public double getTranslateY() {
    return translateY;
  }

  @Override
  public Font getFont() {
    return gc.getFont();
  }

  @Override
  public FontData getFontData() {
    return currentFontData;
  }

 
}
TOP

Related Classes of org.rascalmpl.library.vis.graphics.SWTGraphicsContext

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.