Example #1
0
public interface StdAttr {
  Attribute<Direction> FACING = Attributes.forDirection("facing", Strings.getter("stdFacingAttr"));

  Attribute<BitWidth> WIDTH = Attributes.forBitWidth("width", Strings.getter("stdDataWidthAttr"));

  AttributeOption TRIG_RISING = new AttributeOption("rising", Strings.getter("stdTriggerRising"));
  AttributeOption TRIG_FALLING =
      new AttributeOption("falling", Strings.getter("stdTriggerFalling"));
  AttributeOption TRIG_HIGH = new AttributeOption("high", Strings.getter("stdTriggerHigh"));
  AttributeOption TRIG_LOW = new AttributeOption("low", Strings.getter("stdTriggerLow"));
  Attribute<AttributeOption> TRIGGER =
      Attributes.forOption(
          "trigger",
          Strings.getter("stdTriggerAttr"),
          new AttributeOption[] {TRIG_RISING, TRIG_FALLING, TRIG_HIGH, TRIG_LOW});
  Attribute<AttributeOption> EDGE_TRIGGER =
      Attributes.forOption(
          "trigger",
          Strings.getter("stdTriggerAttr"),
          new AttributeOption[] {TRIG_RISING, TRIG_FALLING});

  Attribute<String> LABEL = Attributes.forString("label", Strings.getter("stdLabelAttr"));

  Attribute<Font> LABEL_FONT = Attributes.forFont("labelfont", Strings.getter("stdLabelFontAttr"));
  Font DEFAULT_LABEL_FONT = new Font("SansSerif", Font.PLAIN, 12);
}
Example #2
0
class NotGate extends InstanceFactory {
  public static final AttributeOption SIZE_NARROW =
      new AttributeOption(Integer.valueOf(20), Strings.getter("gateSizeNarrowOpt"));
  public static final AttributeOption SIZE_WIDE =
      new AttributeOption(Integer.valueOf(30), Strings.getter("gateSizeWideOpt"));
  public static final Attribute<AttributeOption> ATTR_SIZE =
      Attributes.forOption(
          "size", Strings.getter("gateSizeAttr"), new AttributeOption[] {SIZE_NARROW, SIZE_WIDE});

  private static final String RECT_LABEL = "1";
  private static final Icon toolIcon = Icons.getIcon("notGate.gif");
  private static final Icon toolIconRect = Icons.getIcon("notGateRect.gif");
  private static final Icon toolIconDin = Icons.getIcon("dinNotGate.gif");

  public static InstanceFactory FACTORY = new NotGate();

  private NotGate() {
    super("NOT Gate", Strings.getter("notGateComponent"));
    setAttributes(
        new Attribute[] {
          StdAttr.FACING,
          StdAttr.WIDTH,
          ATTR_SIZE,
          GateAttributes.ATTR_OUTPUT,
          StdAttr.LABEL,
          StdAttr.LABEL_FONT,
        },
        new Object[] {
          Direction.EAST,
          BitWidth.ONE,
          SIZE_WIDE,
          GateAttributes.OUTPUT_01,
          "",
          StdAttr.DEFAULT_LABEL_FONT,
        });
    setFacingAttribute(StdAttr.FACING);
    setKeyConfigurator(new BitWidthConfigurator(StdAttr.WIDTH));
  }

  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Object value = attrs.getValue(ATTR_SIZE);
    if (value == SIZE_NARROW) {
      Direction facing = attrs.getValue(StdAttr.FACING);
      if (facing == Direction.SOUTH) return Bounds.create(-9, -20, 18, 20);
      if (facing == Direction.NORTH) return Bounds.create(-9, 0, 18, 20);
      if (facing == Direction.WEST) return Bounds.create(0, -9, 20, 18);
      return Bounds.create(-20, -9, 20, 18);
    } else {
      Direction facing = attrs.getValue(StdAttr.FACING);
      if (facing == Direction.SOUTH) return Bounds.create(-9, -30, 18, 30);
      if (facing == Direction.NORTH) return Bounds.create(-9, 0, 18, 30);
      if (facing == Direction.WEST) return Bounds.create(0, -9, 30, 18);
      return Bounds.create(-30, -9, 30, 18);
    }
  }

  @Override
  public void propagate(InstanceState state) {
    Value in = state.getPort(1);
    Value out = in.not();
    out = Buffer.repair(state, out);
    state.setPort(0, out, GateAttributes.DELAY);
  }

  //
  // methods for instances
  //
  @Override
  protected void configureNewInstance(Instance instance) {
    configurePorts(instance);
    instance.addAttributeListener();
    String gateShape = AppPreferences.GATE_SHAPE.get();
    configureLabel(instance, gateShape.equals(AppPreferences.SHAPE_RECTANGULAR), null);
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == ATTR_SIZE || attr == StdAttr.FACING) {
      instance.recomputeBounds();
      configurePorts(instance);
      String gateShape = AppPreferences.GATE_SHAPE.get();
      configureLabel(instance, gateShape.equals(AppPreferences.SHAPE_RECTANGULAR), null);
    }
  }

  private void configurePorts(Instance instance) {
    Object size = instance.getAttributeValue(ATTR_SIZE);
    Direction facing = instance.getAttributeValue(StdAttr.FACING);
    int dx = size == SIZE_NARROW ? -20 : -30;

    Port[] ports = new Port[2];
    ports[0] = new Port(0, 0, Port.OUTPUT, StdAttr.WIDTH);
    Location out = Location.create(0, 0).translate(facing, dx);
    ports[1] = new Port(out.getX(), out.getY(), Port.INPUT, StdAttr.WIDTH);
    instance.setPorts(ports);
  }

  @Override
  protected Object getInstanceFeature(final Instance instance, Object key) {
    if (key == ExpressionComputer.class) {
      return new ExpressionComputer() {
        public void computeExpression(Map<Location, Expression> expressionMap) {
          Expression e = expressionMap.get(instance.getPortLocation(1));
          if (e != null) {
            expressionMap.put(instance.getPortLocation(0), Expressions.not(e));
          }
        }
      };
    }
    return super.getInstanceFeature(instance, key);
  }

  //
  // painting methods
  //
  @Override
  public void paintIcon(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    g.setColor(Color.black);
    if (painter.getGateShape() == AppPreferences.SHAPE_RECTANGULAR) {
      if (toolIconRect != null) {
        toolIconRect.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        g.drawRect(0, 2, 16, 16);
        GraphicsUtil.drawCenteredText(g, RECT_LABEL, 8, 8);
        g.drawOval(16, 8, 4, 4);
      }
    } else if (painter.getGateShape() == AppPreferences.SHAPE_DIN40700) {
      if (toolIconDin != null) {
        toolIconDin.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        g.drawRect(0, 2, 16, 16);
        GraphicsUtil.drawCenteredText(g, RECT_LABEL, 8, 8);
        g.drawOval(16, 8, 4, 4);
      }
    } else {
      if (toolIcon != null) {
        toolIcon.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        int[] xp = new int[4];
        int[] yp = new int[4];
        xp[0] = 15;
        yp[0] = 10;
        xp[1] = 1;
        yp[1] = 3;
        xp[2] = 1;
        yp[2] = 17;
        xp[3] = 15;
        yp[3] = 10;
        g.drawPolyline(xp, yp, 4);
        g.drawOval(15, 8, 4, 4);
      }
    }
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    paintBase(painter);
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    painter.getGraphics().setColor(Color.BLACK);
    paintBase(painter);
    painter.drawPorts();
    painter.drawLabel();
  }

  private void paintBase(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    Direction facing = painter.getAttributeValue(StdAttr.FACING);
    Location loc = painter.getLocation();
    int x = loc.getX();
    int y = loc.getY();
    g.translate(x, y);
    double rotate = 0.0;
    if (facing != null && facing != Direction.EAST && g instanceof Graphics2D) {
      rotate = -facing.toRadians();
      ((Graphics2D) g).rotate(rotate);
    }

    Object shape = painter.getGateShape();
    if (shape == AppPreferences.SHAPE_RECTANGULAR) {
      paintRectangularBase(g, painter);
    } else if (shape == AppPreferences.SHAPE_DIN40700) {
      int width = painter.getAttributeValue(ATTR_SIZE) == SIZE_NARROW ? 20 : 30;
      PainterDin.paintAnd(painter, width, 18, true);
    } else {
      PainterShaped.paintNot(painter);
    }

    if (rotate != 0.0) {
      ((Graphics2D) g).rotate(-rotate);
    }
    g.translate(-x, -y);
  }

  private void paintRectangularBase(Graphics g, InstancePainter painter) {
    GraphicsUtil.switchToWidth(g, 2);
    if (painter.getAttributeValue(ATTR_SIZE) == SIZE_NARROW) {
      g.drawRect(-20, -9, 14, 18);
      GraphicsUtil.drawCenteredText(g, RECT_LABEL, -13, 0);
      g.drawOval(-6, -3, 6, 6);
    } else {
      g.drawRect(-30, -9, 20, 18);
      GraphicsUtil.drawCenteredText(g, RECT_LABEL, -20, 0);
      g.drawOval(-10, -5, 9, 9);
    }
    GraphicsUtil.switchToWidth(g, 1);
  }

  static void configureLabel(Instance instance, boolean isRectangular, Location control) {
    Object facing = instance.getAttributeValue(StdAttr.FACING);
    Bounds bds = instance.getBounds();
    int x;
    int y;
    int halign;
    if (facing == Direction.NORTH || facing == Direction.SOUTH) {
      x = bds.getX() + bds.getWidth() / 2 + 2;
      y = bds.getY() - 2;
      halign = TextField.H_LEFT;
    } else { // west or east
      y = isRectangular ? bds.getY() - 2 : bds.getY();
      if (control != null && control.getY() == bds.getY()) {
        // the control line will get in the way
        x = control.getX() + 2;
        halign = TextField.H_LEFT;
      } else {
        x = bds.getX() + bds.getWidth() / 2;
        halign = TextField.H_CENTER;
      }
    }
    instance.setTextField(StdAttr.LABEL, StdAttr.LABEL_FONT, x, y, halign, TextField.V_BASELINE);
  }
}
Example #3
0
class GateAttributes extends AbstractAttributeSet {
  static final int MAX_INPUTS = 32;
  static final int DELAY = 1;

  static final AttributeOption SIZE_NARROW =
      new AttributeOption(Integer.valueOf(30), __("gateSizeNarrowOpt"));
  static final AttributeOption SIZE_MEDIUM =
      new AttributeOption(Integer.valueOf(50), __("gateSizeNormalOpt"));
  static final AttributeOption SIZE_WIDE =
      new AttributeOption(Integer.valueOf(70), __("gateSizeWideOpt"));
  public static final Attribute<AttributeOption> ATTR_SIZE =
      Attributes.forOption(
          "size", __("gateSizeAttr"), new AttributeOption[] {SIZE_NARROW, SIZE_MEDIUM, SIZE_WIDE});

  public static final Attribute<Integer> ATTR_INPUTS =
      Attributes.forIntegerRange("inputs", __("gateInputsAttr"), 2, MAX_INPUTS);

  static final AttributeOption XOR_ONE = new AttributeOption("1", __("xorBehaviorOne"));
  static final AttributeOption XOR_ODD = new AttributeOption("odd", __("xorBehaviorOdd"));
  public static final Attribute<AttributeOption> ATTR_XOR =
      Attributes.forOption("xor", __("xorBehaviorAttr"), new AttributeOption[] {XOR_ONE, XOR_ODD});

  static final AttributeOption OUTPUT_01 = new AttributeOption("01", __("gateOutput01"));
  static final AttributeOption OUTPUT_0Z = new AttributeOption("0Z", __("gateOutput0Z"));
  static final AttributeOption OUTPUT_Z1 = new AttributeOption("Z1", __("gateOutputZ1"));
  public static final Attribute<AttributeOption> ATTR_OUTPUT =
      Attributes.forOption(
          "out", __("gateOutputAttr"), new AttributeOption[] {OUTPUT_01, OUTPUT_0Z, OUTPUT_Z1});

  Direction facing = Direction.EAST;
  BitWidth width = BitWidth.ONE;
  AttributeOption size = SIZE_NARROW;
  int inputs = 2;
  int negated = 0;
  AttributeOption out = OUTPUT_01;
  AttributeOption xorBehave;
  String label = "";
  Font labelFont = StdAttr.DEFAULT_LABEL_FONT;

  GateAttributes(boolean isXor) {
    xorBehave = isXor ? XOR_ONE : null;
  }

  @Override
  protected void copyInto(AbstractAttributeSet dest) {
    // nothing to do
    ;
  }

  @Override
  public List<Attribute<?>> getAttributes() {
    return new GateAttributeList(this);
  }

  @Override
  @SuppressWarnings("unchecked")
  public <V> V getValue(Attribute<V> attr) {
    if (attr == StdAttr.FACING) return (V) facing;
    if (attr == StdAttr.WIDTH) return (V) width;
    if (attr == StdAttr.LABEL) return (V) label;
    if (attr == StdAttr.LABEL_FONT) return (V) labelFont;
    if (attr == ATTR_SIZE) return (V) size;
    if (attr == ATTR_INPUTS) return (V) Integer.valueOf(inputs);
    if (attr == ATTR_OUTPUT) return (V) out;
    if (attr == ATTR_XOR) return (V) xorBehave;
    if (attr instanceof NegateAttribute) {
      int index = ((NegateAttribute) attr).index;
      int bit = (negated >> index) & 1;
      return (V) Boolean.valueOf(bit == 1);
    }
    return null;
  }

  @Override
  public <V> void setValue(Attribute<V> attr, V value) {
    if (attr == StdAttr.WIDTH) {
      width = (BitWidth) value;
      int bits = width.getWidth();
      int mask = bits >= 32 ? -1 : ((1 << inputs) - 1);
      negated &= mask;
    } else if (attr == StdAttr.FACING) {
      facing = (Direction) value;
    } else if (attr == StdAttr.LABEL) {
      label = (String) value;
    } else if (attr == StdAttr.LABEL_FONT) {
      labelFont = (Font) value;
    } else if (attr == ATTR_SIZE) {
      size = (AttributeOption) value;
    } else if (attr == ATTR_INPUTS) {
      inputs = ((Integer) value).intValue();
      fireAttributeListChanged();
    } else if (attr == ATTR_XOR) {
      xorBehave = (AttributeOption) value;
    } else if (attr == ATTR_OUTPUT) {
      out = (AttributeOption) value;
    } else if (attr instanceof NegateAttribute) {
      int index = ((NegateAttribute) attr).index;
      if (((Boolean) value).booleanValue()) {
        negated |= 1 << index;
      } else {
        negated &= ~(1 << index);
      }
    } else {
      throw new IllegalArgumentException("unrecognized argument");
    }
    fireAttributeValueChanged(attr, value);
  }
}
Example #4
0
public class PullResistor extends InstanceFactory {
  public static final Attribute<AttributeOption> ATTR_PULL_TYPE =
      Attributes.forOption(
          "pull",
          Strings.getter("pullTypeAttr"),
          new AttributeOption[] {
            new AttributeOption(Value.FALSE, "0", Strings.getter("pullZeroType")),
            new AttributeOption(Value.TRUE, "1", Strings.getter("pullOneType")),
            new AttributeOption(Value.ERROR, "X", Strings.getter("pullErrorType"))
          });

  public static final PullResistor FACTORY = new PullResistor();

  private static final Icon ICON_SHAPED = Icons.getIcon("pullshap.gif");
  private static final Icon ICON_RECTANGULAR = Icons.getIcon("pullrect.gif");

  public PullResistor() {
    super("Pull Resistor", Strings.getter("pullComponent"));
    setAttributes(
        new Attribute[] {StdAttr.FACING, ATTR_PULL_TYPE},
        new Object[] {Direction.SOUTH, ATTR_PULL_TYPE.parse("0")});
    setFacingAttribute(StdAttr.FACING);
  }

  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Direction facing = attrs.getValue(StdAttr.FACING);
    if (facing == Direction.EAST) {
      return Bounds.create(-42, -6, 42, 12);
    } else if (facing == Direction.WEST) {
      return Bounds.create(0, -6, 42, 12);
    } else if (facing == Direction.NORTH) {
      return Bounds.create(-6, 0, 12, 42);
    } else {
      return Bounds.create(-6, -42, 12, 42);
    }
  }

  //
  // graphics methods
  //
  @Override
  public void paintIcon(InstancePainter painter) {
    Icon icon;
    if (painter.getGateShape() == AppPreferences.SHAPE_SHAPED) {
      icon = ICON_SHAPED;
    } else {
      icon = ICON_RECTANGULAR;
    }
    icon.paintIcon(painter.getDestination(), painter.getGraphics(), 2, 2);
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    Value pull = getPullValue(painter.getAttributeSet());
    paintBase(painter, pull, null, null);
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    Location loc = painter.getLocation();
    int x = loc.getX();
    int y = loc.getY();
    Graphics g = painter.getGraphics();
    g.translate(x, y);
    Value pull = getPullValue(painter.getAttributeSet());
    Value actual = painter.getPort(0);
    paintBase(painter, pull, pull.getColor(), actual.getColor());
    g.translate(-x, -y);
    painter.drawPorts();
  }

  private void paintBase(InstancePainter painter, Value pullValue, Color inColor, Color outColor) {
    boolean color = painter.shouldDrawColor();
    Direction facing = painter.getAttributeValue(StdAttr.FACING);
    Graphics g = painter.getGraphics();
    Color baseColor = g.getColor();
    GraphicsUtil.switchToWidth(g, 3);
    if (color && inColor != null) g.setColor(inColor);
    if (facing == Direction.EAST) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), -32, 0, GraphicsUtil.H_RIGHT, GraphicsUtil.V_CENTER);
    } else if (facing == Direction.WEST) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 32, 0, GraphicsUtil.H_LEFT, GraphicsUtil.V_CENTER);
    } else if (facing == Direction.NORTH) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 0, 32, GraphicsUtil.H_CENTER, GraphicsUtil.V_TOP);
    } else {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 0, -32, GraphicsUtil.H_CENTER, GraphicsUtil.V_BASELINE);
    }

    double rotate = 0.0;
    if (g instanceof Graphics2D) {
      rotate = Direction.SOUTH.toRadians() - facing.toRadians();
      if (rotate != 0.0) ((Graphics2D) g).rotate(rotate);
    }
    g.drawLine(0, -30, 0, -26);
    g.drawLine(-6, -30, 6, -30);
    if (color && outColor != null) g.setColor(outColor);
    g.drawLine(0, -4, 0, 0);
    g.setColor(baseColor);
    GraphicsUtil.switchToWidth(g, 2);
    if (painter.getGateShape() == AppPreferences.SHAPE_SHAPED) {
      int[] xp = {0, -5, 5, -5, 5, -5, 0};
      int[] yp = {-25, -23, -19, -15, -11, -7, -5};
      g.drawPolyline(xp, yp, xp.length);
    } else {
      g.drawRect(-5, -25, 10, 20);
    }
    if (rotate != 0.0) {
      ((Graphics2D) g).rotate(-rotate);
    }
  }

  //
  // methods for instances
  //
  @Override
  protected void configureNewInstance(Instance instance) {
    instance.addAttributeListener();
    instance.setPorts(new Port[] {new Port(0, 0, Port.INOUT, BitWidth.UNKNOWN)});
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == StdAttr.FACING) {
      instance.recomputeBounds();
    } else if (attr == ATTR_PULL_TYPE) {
      instance.fireInvalidated();
    }
  }

  @Override
  public void propagate(InstanceState state) {
    ; // nothing to do - handled by CircuitWires
  }

  public static Value getPullValue(Instance instance) {
    return getPullValue(instance.getAttributeSet());
  }

  private static Value getPullValue(AttributeSet attrs) {
    AttributeOption opt = attrs.getValue(ATTR_PULL_TYPE);
    return (Value) opt.getValue();
  }
}
Example #5
0
public class BitExtender extends InstanceFactory {
  private static final Attribute<BitWidth> ATTR_IN_WIDTH =
      Attributes.forBitWidth("in_width", Strings.getter("extenderInAttr"));
  private static final Attribute<BitWidth> ATTR_OUT_WIDTH =
      Attributes.forBitWidth("out_width", Strings.getter("extenderOutAttr"));
  static final Attribute<AttributeOption> ATTR_TYPE =
      Attributes.forOption(
          "type",
          Strings.getter("extenderTypeAttr"),
          new AttributeOption[] {
            new AttributeOption("zero", "zero", Strings.getter("extenderZeroType")),
            new AttributeOption("one", "one", Strings.getter("extenderOneType")),
            new AttributeOption("sign", "sign", Strings.getter("extenderSignType")),
            new AttributeOption("input", "input", Strings.getter("extenderInputType")),
          });

  public static final BitExtender FACTORY = new BitExtender();

  public BitExtender() {
    super("Bit Extender", Strings.getter("extenderComponent"));
    setIconName("extender.gif");
    setAttributes(
        new Attribute[] {ATTR_IN_WIDTH, ATTR_OUT_WIDTH, ATTR_TYPE},
        new Object[] {BitWidth.create(8), BitWidth.create(16), ATTR_TYPE.parse("sign")});
    setFacingAttribute(StdAttr.FACING);
    setKeyConfigurator(
        JoinedConfigurator.create(
            new BitWidthConfigurator(ATTR_OUT_WIDTH),
            new BitWidthConfigurator(ATTR_IN_WIDTH, 1, Value.MAX_WIDTH, 0)));
    setOffsetBounds(Bounds.create(-40, -20, 40, 40));
  }

  //
  // methods for instances
  //
  @Override
  protected void configureNewInstance(Instance instance) {
    configurePorts(instance);
    instance.addAttributeListener();
  }

  private void configurePorts(Instance instance) {
    Port p0 = new Port(0, 0, Port.OUTPUT, ATTR_OUT_WIDTH);
    Port p1 = new Port(-40, 0, Port.INPUT, ATTR_IN_WIDTH);
    String type = getType(instance.getAttributeSet());
    if (type.equals("input")) {
      instance.setPorts(new Port[] {p0, p1, new Port(-20, -20, Port.INPUT, 1)});
    } else {
      instance.setPorts(new Port[] {p0, p1});
    }
  }

  private String getType(AttributeSet attrs) {
    AttributeOption topt = attrs.getValue(ATTR_TYPE);
    return (String) topt.getValue();
  }

  @Override
  public boolean HDLSupportedComponent(String HDLIdentifier, AttributeSet attrs, char Vendor) {
    if (MyHDLGenerator == null) MyHDLGenerator = new BitExtenderHDLGeneratorFactory();
    return MyHDLGenerator.HDLTargetSupported(HDLIdentifier, attrs, Vendor);
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == ATTR_TYPE) {
      configurePorts(instance);
      instance.fireInvalidated();
    } else {
      instance.fireInvalidated();
    }
  }

  //
  // graphics methods
  //
  @Override
  public void paintInstance(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    FontMetrics fm = g.getFontMetrics();
    int asc = fm.getAscent();

    painter.drawBounds();

    String s0;
    String type = getType(painter.getAttributeSet());
    if (type.equals("zero")) s0 = Strings.get("extenderZeroLabel");
    else if (type.equals("one")) s0 = Strings.get("extenderOneLabel");
    else if (type.equals("sign")) s0 = Strings.get("extenderSignLabel");
    else if (type.equals("input")) s0 = Strings.get("extenderInputLabel");
    else s0 = "???"; // should never happen
    String s1 = Strings.get("extenderMainLabel");
    Bounds bds = painter.getBounds();
    int x = bds.getX() + bds.getWidth() / 2;
    int y0 = bds.getY() + (bds.getHeight() / 2 + asc) / 2;
    int y1 = bds.getY() + (3 * bds.getHeight() / 2 + asc) / 2;
    GraphicsUtil.drawText(g, s0, x, y0, GraphicsUtil.H_CENTER, GraphicsUtil.V_BASELINE);
    GraphicsUtil.drawText(g, s1, x, y1, GraphicsUtil.H_CENTER, GraphicsUtil.V_BASELINE);

    BitWidth w0 = painter.getAttributeValue(ATTR_OUT_WIDTH);
    BitWidth w1 = painter.getAttributeValue(ATTR_IN_WIDTH);
    painter.drawPort(0, "" + w0.getWidth(), Direction.WEST);
    painter.drawPort(1, "" + w1.getWidth(), Direction.EAST);
    if (type.equals("input")) painter.drawPort(2);
  }

  @Override
  public void propagate(InstanceState state) {
    Value in = state.getPortValue(1);
    BitWidth wout = state.getAttributeValue(ATTR_OUT_WIDTH);
    String type = getType(state.getAttributeSet());
    Value extend;
    if (type.equals("one")) {
      extend = Value.TRUE;
    } else if (type.equals("sign")) {
      int win = in.getWidth();
      extend = win > 0 ? in.get(win - 1) : Value.ERROR;
    } else if (type.equals("input")) {
      extend = state.getPortValue(2);
      if (extend.getWidth() != 1) extend = Value.ERROR;
    } else {
      extend = Value.FALSE;
    }

    Value out = in.extendWidth(wout.getWidth(), extend);
    state.setPort(0, out, 1);
  }
}
Example #6
0
public final class Wire implements Component, AttributeSet, CustomHandles, Iterable<Location> {
  private class EndList extends AbstractList<EndData> {
    @Override
    public EndData get(int i) {
      return getEnd(i);
    }

    @Override
    public int size() {
      return 2;
    }
  }

  public static Wire create(Location e0, Location e1) {
    return (Wire) cache.get(new Wire(e0, e1));
  }

  /** Stroke width when drawing wires. */
  public static final int WIDTH = 3;

  public static final int WIDTH_BUS = 4;
  public static final int HIGHLIGHTED_WIDTH = 4;
  public static final int HIGHLIGHTED_WIDTH_BUS = 5;
  public static final double DOT_MULTIPLY_FACTOR =
      1.35; /* multiply factor for the intersection points */
  public static final AttributeOption VALUE_HORZ =
      new AttributeOption("horz", Strings.getter("wireDirectionHorzOption"));
  public static final AttributeOption VALUE_VERT =
      new AttributeOption("vert", Strings.getter("wireDirectionVertOption"));

  public static final Attribute<AttributeOption> dir_attr =
      Attributes.forOption(
          "direction",
          Strings.getter("wireDirectionAttr"),
          new AttributeOption[] {VALUE_HORZ, VALUE_VERT});
  public static final Attribute<Integer> len_attr =
      Attributes.forInteger("length", Strings.getter("wireLengthAttr"));

  private static final List<Attribute<?>> ATTRIBUTES =
      Arrays.asList(new Attribute<?>[] {dir_attr, len_attr});

  private static final Cache cache = new Cache();

  final Location e0;
  final Location e1;
  final boolean is_x_equal;
  private boolean ShowAsMarked = false;
  private Color MarkColor = Netlist.DRC_WIRE_MARK_COLOR;

  private Wire(Location e0, Location e1) {
    this.is_x_equal = e0.getX() == e1.getX();
    if (is_x_equal) {
      if (e0.getY() > e1.getY()) {
        this.e0 = e1;
        this.e1 = e0;
      } else {
        this.e0 = e0;
        this.e1 = e1;
      }
    } else {
      if (e0.getX() > e1.getX()) {
        this.e0 = e1;
        this.e1 = e0;
      } else {
        this.e0 = e0;
        this.e1 = e1;
      }
    }
  }

  public void SetMarked(boolean Mark) {
    ShowAsMarked = Mark;
  }

  public boolean IsSetAsMarked() {
    return ShowAsMarked;
  }

  public void SetMarkColor(Color col) {
    MarkColor = col;
  }

  public Color GetMarkColor() {
    return MarkColor;
  }

  public void addAttributeListener(AttributeListener l) {}

  //
  // Component methods
  //
  // (Wire never issues ComponentEvents, so we don't need to track listeners)
  public void addComponentListener(ComponentListener e) {}

  //
  // AttributeSet methods
  //
  // It makes some sense for a wire to be its own attribute, since
  // after all it is immutable.
  //
  @Override
  public Object clone() {
    return this;
  }

  public boolean contains(Location q) {
    int qx = q.getX();
    int qy = q.getY();
    if (is_x_equal) {
      int wx = e0.getX();
      return qx >= wx - 2 && qx <= wx + 2 && e0.getY() <= qy && qy <= e1.getY();
    } else {
      int wy = e0.getY();
      return qy >= wy - 2 && qy <= wy + 2 && e0.getX() <= qx && qx <= e1.getX();
    }
  }

  public boolean contains(Location pt, Graphics g) {
    return contains(pt);
  }

  public boolean containsAttribute(Attribute<?> attr) {
    return ATTRIBUTES.contains(attr);
  }

  public void draw(ComponentDrawContext context) {
    CircuitState state = context.getCircuitState();
    Graphics g = context.getGraphics();
    GraphicsUtil.switchToWidth(g, WIDTH);
    g.setColor(state.getValue(e0).getColor());
    g.drawLine(e0.getX(), e0.getY(), e1.getX(), e1.getY());
  }

  public void drawHandles(ComponentDrawContext context) {
    context.drawHandle(e0);
    context.drawHandle(e1);
  }

  public boolean endsAt(Location pt) {
    return e0.equals(pt) || e1.equals(pt);
  }

  @Override
  public boolean equals(Object other) {
    if (!(other instanceof Wire)) return false;
    Wire w = (Wire) other;
    return w.e0.equals(this.e0) && w.e1.equals(this.e1);
  }

  //
  // user interface methods
  //
  public void expose(ComponentDrawContext context) {
    java.awt.Component dest = context.getDestination();
    int x0 = e0.getX();
    int y0 = e0.getY();
    dest.repaint(x0 - 5, y0 - 5, e1.getX() - x0 + 10, e1.getY() - y0 + 10);
  }

  public Attribute<?> getAttribute(String name) {
    for (Attribute<?> attr : ATTRIBUTES) {
      if (name.equals(attr.getName())) return attr;
    }
    return null;
  }

  public List<Attribute<?>> getAttributes() {
    return ATTRIBUTES;
  }

  public AttributeSet getAttributeSet() {
    return this;
  }

  public Bounds getBounds() {
    int x0 = e0.getX();
    int y0 = e0.getY();
    return Bounds.create(x0 - 2, y0 - 2, e1.getX() - x0 + 5, e1.getY() - y0 + 5);
  }

  public Bounds getBounds(Graphics g) {
    return getBounds();
  }

  public EndData getEnd(int index) {
    Location loc = getEndLocation(index);
    return new EndData(loc, BitWidth.UNKNOWN, EndData.INPUT_OUTPUT);
  }

  public Location getEnd0() {
    return e0;
  }

  public Location getEnd1() {
    return e1;
  }

  public Location getEndLocation(int index) {
    return index == 0 ? e0 : e1;
  }

  //
  // propagation methods
  //
  public List<EndData> getEnds() {
    return new EndList();
  }

  public ComponentFactory getFactory() {
    return WireFactory.instance;
  }

  public Object getFeature(Object key) {
    if (key == CustomHandles.class) return this;
    return null;
  }

  public int getLength() {
    return (e1.getY() - e0.getY()) + (e1.getX() - e0.getX());
  }

  // location/extent methods
  public Location getLocation() {
    return e0;
  }

  public Location getOtherEnd(Location loc) {
    return (loc.equals(e0) ? e1 : e0);
  }

  @SuppressWarnings("unchecked")
  public <V> V getValue(Attribute<V> attr) {
    if (attr == dir_attr) {
      return (V) (is_x_equal ? VALUE_VERT : VALUE_HORZ);
    } else if (attr == len_attr) {
      return (V) Integer.valueOf(getLength());
    } else {
      return null;
    }
  }

  @Override
  public int hashCode() {
    return e0.hashCode() * 31 + e1.hashCode();
  }

  public boolean isParallel(Wire other) {
    return this.is_x_equal == other.is_x_equal;
  }

  public boolean isReadOnly(Attribute<?> attr) {
    return true;
  }

  public boolean isToSave(Attribute<?> attr) {
    return false;
  }

  //
  // other methods
  //
  public boolean isVertical() {
    return is_x_equal;
  }

  public Iterator<Location> iterator() {
    return new WireIterator(e0, e1);
  }

  private boolean overlaps(Location q0, Location q1, boolean includeEnds) {
    if (is_x_equal) {
      int x0 = q0.getX();
      if (x0 != q1.getX() || x0 != e0.getX()) return false;
      if (includeEnds) {
        return e1.getY() >= q0.getY() && e0.getY() <= q1.getY();
      } else {
        return e1.getY() > q0.getY() && e0.getY() < q1.getY();
      }
    } else {
      int y0 = q0.getY();
      if (y0 != q1.getY() || y0 != e0.getY()) return false;
      if (includeEnds) {
        return e1.getX() >= q0.getX() && e0.getX() <= q1.getX();
      } else {
        return e1.getX() > q0.getX() && e0.getX() < q1.getX();
      }
    }
  }

  public boolean overlaps(Wire other, boolean includeEnds) {
    return overlaps(other.e0, other.e1, includeEnds);
  }

  public void propagate(CircuitState state) {
    // Normally this is handled by CircuitWires, and so it won't get
    // called. The exception is when a wire is added or removed
    state.markPointAsDirty(e0);
    state.markPointAsDirty(e1);
  }

  public void removeAttributeListener(AttributeListener l) {}

  public void removeComponentListener(ComponentListener e) {}

  public void setReadOnly(Attribute<?> attr, boolean value) {
    throw new UnsupportedOperationException();
  }

  public <V> void setValue(Attribute<V> attr, V value) {
    throw new IllegalArgumentException("read only attribute");
  }

  public boolean sharesEnd(Wire other) {
    return this.e0.equals(other.e0)
        || this.e1.equals(other.e0)
        || this.e0.equals(other.e1)
        || this.e1.equals(other.e1);
  }

  @Override
  public String toString() {
    return "Wire[" + e0 + "-" + e1 + "]";
  }
}