Package com.cburch.logisim.std.gates

Source Code of com.cburch.logisim.std.gates.PainterDin

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.std.gates;

import java.awt.Color;
import java.awt.Graphics;
import java.util.HashMap;

import com.cburch.logisim.data.Location;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.util.GraphicsUtil;

class PainterDin {
  private PainterDin() { }
 
  static final int AND = 0;
  static final int OR = 1;
  static final int XOR = 2;
  static final int XNOR = 3;
 
  private static HashMap<Integer,int[]> orLenArrays = new HashMap<Integer,int[]>();
 
  static void paintAnd(InstancePainter painter, int width, int height,
      boolean drawBubble) {
    paint(painter, width, height, drawBubble, AND);
  }

  static void paintOr(InstancePainter painter, int width, int height,
      boolean drawBubble) {
    paint(painter, width, height, drawBubble, OR);
  }

  static void paintXor(InstancePainter painter, int width, int height,
      boolean drawBubble) {
    paint(painter, width, height, drawBubble, XOR);
  }

  static void paintXnor(InstancePainter painter, int width, int height,
      boolean drawBubble) {
    paint(painter, width, height, drawBubble, XNOR);
  }

  private static void paint(InstancePainter painter, int width, int height,
      boolean drawBubble, int dinType) {
    Graphics g = painter.getGraphics();
    int x = 0;
    int xMid = -width;
    int y0 = -height / 2;
    if (drawBubble) {
      x -= 4;
      width -= 8;
    }
    int diam = Math.min(height, 2 * width);
    if (dinType == AND) {
      ; // nothing to do
    } else if (dinType == OR) {
      paintOrLines(painter, width, height, drawBubble);
    } else if (dinType == XOR || dinType == XNOR) {
      int elen = Math.min(diam / 2 - 10, 20);
      int ex0 = xMid + (diam / 2 - elen) / 2;
      int ex1 = ex0 + elen;
      g.drawLine(ex0, -5, ex1, -5);
      g.drawLine(ex0, 0, ex1, 0);
      g.drawLine(ex0, 5, ex1, 5);
      if (dinType == XOR) {
        int exMid = ex0 + elen / 2;
        g.drawLine(exMid, -8, exMid, 8);
      }
    } else {
      throw new IllegalArgumentException("unrecognized shape");
    }

    GraphicsUtil.switchToWidth(g, 2);
    int x0 = xMid - diam / 2;
    Color oldColor = g.getColor();
    if (painter.getShowState()) {
      Value val = painter.getPort(0);
      g.setColor(val.getColor());
    }
    g.drawLine(x0 + diam, 0, 0, 0);
    g.setColor(oldColor);
    if (height <= diam) {
      g.drawArc(x0, y0, diam, diam, -90, 180);
    } else {
      int x1 = x0 + diam;
      int yy0 = -(height - diam) / 2;
      int yy1 = (height - diam) / 2;
      g.drawArc(x0, y0, diam, diam, 0, 90);
      g.drawLine(x1, yy0, x1, yy1);
      g.drawArc(x0, y0 + height - diam, diam, diam, -90, 90);
    }
    g.drawLine(xMid, y0, xMid, y0 + height);
    if (drawBubble) {
      g.fillOval(x0 + diam - 4, -4, 8, 8);
      xMid += 4;
    }
  }

  private static void paintOrLines(InstancePainter painter,
      int width, int height, boolean hasBubble) {
    GateAttributes baseAttrs = (GateAttributes) painter.getAttributeSet();
    int inputs = baseAttrs.inputs;
    GateAttributes attrs = (GateAttributes) OrGate.FACTORY.createAttributeSet();
    attrs.inputs = inputs;
    attrs.size = baseAttrs.size;

    Graphics g = painter.getGraphics();
    // draw state if appropriate
    // ignore lines if in print view
    int r = Math.min(height / 2, width);
    Integer hash = Integer.valueOf(r << 4 | inputs);
    int[] lens = orLenArrays.get(hash);
    if (lens == null) {
      lens = new int[inputs];
      orLenArrays.put(hash, lens);
      int yCurveStart = height / 2 - r;
      for (int i = 0; i < inputs; i++) {
        int y = OrGate.FACTORY.getInputOffset(attrs, i).getY();
        if (y < 0) y = -y;
        if (y <= yCurveStart) {
          lens[i] = r;
        } else {
          int dy = y - yCurveStart;
          lens[i] = (int) (Math.sqrt(r * r - dy * dy) + 0.5);
        }
      }
    }
   
    AbstractGate factory = hasBubble ? NorGate.FACTORY : OrGate.FACTORY;
    boolean printView = painter.isPrintView() && painter.getInstance() != null;
    GraphicsUtil.switchToWidth(g, 2);
    for (int i = 0; i < inputs; i++) {
      if (!printView || painter.isPortConnected(i)) {
        Location loc = factory.getInputOffset(attrs, i);
        int x = loc.getX();
        int y = loc.getY();
        g.drawLine(x, y, x + lens[i], y);
      }
    }
  }
}
TOP

Related Classes of com.cburch.logisim.std.gates.PainterDin

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.