/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: EGraphics.java
*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) 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.
*
* Electric(tm) 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 Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.database.geometry;
import com.sun.electric.technology.Technology;
import com.sun.electric.technology.technologies.Schematics;
import com.sun.electric.util.TextUtils;
import java.awt.Color;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Class to define the appearance of a piece of geometry.
*/
public class EGraphics implements Serializable
{
public static final J3DTransparencyOption DEFAULT_MODE = J3DTransparencyOption.NONE; // 3D default transparency mode DEFAULT_FACTOR
public static final double DEFAULT_FACTOR = 0.0; // 3D default transparency factor
private static Map<String,Outline> outlineNames = new HashMap<String,Outline>();
/**
* Class to define the type of outline around a stipple pattern.
*/
public static enum Outline
{
/** Draw stipple pattern with no outline. */
NOPAT("None", 0, 32, 1),
/** Draw stipple pattern with solid outline. */
PAT_S("Solid", -1, 32, 1),
/** Draw stipple pattern with solid thick outline. */
PAT_T1("Solid-Thick", -1, 32, 3),
/** Draw stipple pattern with solid thicker outline. */
PAT_T2("Solid-Thicker", -1, 32, 5),
/** Draw stipple pattern with close dotted outline. */
PAT_DO1("Dotted-Close", 0x55, 8, 1),
/** Draw stipple pattern with far dotted outline. */
PAT_DO2("Dotted-Far", 0x11, 8, 1),
/** Draw stipple pattern with short dashed outline. */
PAT_DA1("Dashed-Short", 0x33, 8, 1),
/** Draw stipple pattern with long dashed outline. */
PAT_DA2("Dashed-Long", 0xF, 6, 1),
/** Draw stipple pattern with short dotted-dashed outline. */
PAT_DD1("Dotted-Dashed-Short", 0x39, 8, 1),
/** Draw stipple pattern with long dotted-dashed outline. */
PAT_DD2("Dotted-Dashed-Long", 0xF3, 10, 1),
/** Draw stipple pattern with close dotted thick outline. */
PAT_DO1_T1("Dotted-Close-Thick", 0xF, 6, 3),
/** Draw stipple pattern with far dotted thick outline. */
PAT_DO2_T1("Dotted-Far-Thick", 0xF, 8, 3),
/** Draw stipple pattern with dashed thick outline. */
PAT_DA1_T1("Dashed-Thick", 0x1FFFF, 19, 3),
/** Draw stipple pattern with close dotted thicker outline. */
PAT_DO1_T2("Dotted-Close-Thicker", 0x1F, 8, 5),
/** Draw stipple pattern with far dotted thicker outline. */
PAT_DO2_T2("Dotted-Far-Thicker", 0x7F, 9, 5);
private final String name;
private final int pattern, len;
private final int thickness;
private final boolean solid;
private Outline(String name, int pattern, int len, int thickness)
{
this.name = name;
outlineNames.put(name, this);
this.pattern = pattern;
this.len = len;
this.thickness = thickness;
this.solid = (pattern == -1);
}
public String getName() { return name; }
public String getConstName() { return name(); }
public int getIndex() { return ordinal(); }
public boolean isSolidPattern() { return solid; }
public int getPattern() { return pattern; }
public int getLen() { return len; }
public int getThickness() { return thickness; }
public static Outline findOutline(int index)
{
return Outline.class.getEnumConstants()[index];
}
public static Outline findOutline(String name)
{
// return valueOf(name);
return outlineNames.get(name);
}
public static List<Outline> getOutlines() { return Arrays.asList(Outline.class.getEnumConstants()); }
@Override
public String toString() { return name; }
}
public enum J3DTransparencyOption {
FASTEST,
NICEST,
BLENDED,
SCREEN_DOOR,
NONE;
public final int mode = ordinal();
public static J3DTransparencyOption valueOf(int mode) {
return J3DTransparencyOption.class.getEnumConstants()[mode];
}
}
/** display: true to use patterns; false for solid */ private final boolean displayPatterned;
/** printer: true to use patterns; false for solid */ private final boolean printPatterned;
/** the outline pattern */ private final Outline patternOutline;
/** transparent layer to use (0 for none) */ private final int transparentLayer;
/** color to use */ private final Color color;
/** opacity (0 to 1) of color */ private final double opacity;
/** whether to draw color in foreground */ private final boolean foreground;
/** stipple pattern to draw */ private final int [] pattern;
/** stipple pattern to draw with proper bit order */ private final int [] reversedPattern;
/** 3D transparency mode */ private final J3DTransparencyOption transparencyMode;
/** 3D transparency factor */ private final double transparencyFactor;
/**
* There are 3 ways to encode color in an integer.
* If the lowest bit (FULLRGBBIT) is set, this is a full RGB color in the high 3 bytes.
* If the next lowest bit (OPAQUEBIT) is set, this is an "old C Electric" opaque color
* (such as WHITE, BLACK, etc., listed below).
* If neither of these bits is set, this is a transparent layer
* (LAYERT1, LAYERT2, etc., listed below).
*/
/** Describes the full RGB escape bit. */ public final static int FULLRGBBIT = 01;
/** Describes opaque color escape bit. */ public final static int OPAQUEBIT = 02;
// the opaque colors (all have the OPAQUEBIT set in them)
/** Describes the color white. */ public final static int WHITE = 0002;
/** Describes the color black. */ public final static int BLACK = 0006;
/** Describes the color red. */ public final static int RED = 0012;
/** Describes the color blue. */ public final static int BLUE = 0016;
/** Describes the color green. */ public final static int GREEN = 0022;
/** Describes the color cyan. */ public final static int CYAN = 0026;
/** Describes the color magenta. */ public final static int MAGENTA = 0032;
/** Describes the color yellow. */ public final static int YELLOW = 0036;
/** Describes the cell and port names. */ public final static int CELLTXT = 0042;
/** Describes the cell outline. */ public final static int CELLOUT = 0046;
/** Describes the window border color. */ public final static int WINBOR = 0052;
/** Describes the highlighted window border color. */ public final static int HWINBOR = 0056;
/** Describes the menu border color. */ public final static int MENBOR = 0062;
/** Describes the highlighted menu border color. */ public final static int HMENBOR = 0066;
/** Describes the menu text color. */ public final static int MENTXT = 0072;
/** Describes the menu glyph color. */ public final static int MENGLY = 0076;
/** Describes the cursor color. */ public final static int CURSOR = 0102;
/** Describes the color gray. */ public final static int GRAY = 0106;
/** Describes the color orange. */ public final static int ORANGE = 0112;
/** Describes the color purple. */ public final static int PURPLE = 0116;
/** Describes the color brown. */ public final static int BROWN = 0122;
/** Describes the color light gray. */ public final static int LGRAY = 0126;
/** Describes the color dark gray. */ public final static int DGRAY = 0132;
/** Describes the color light red. */ public final static int LRED = 0136;
/** Describes the color dark red. */ public final static int DRED = 0142;
/** Describes the color light green. */ public final static int LGREEN = 0146;
/** Describes the color dark green. */ public final static int DGREEN = 0152;
/** Describes the color light blue. */ public final static int LBLUE = 0156;
/** Describes the color dark blue. */ public final static int DBLUE = 0162;
// the transparent layers
/** Describes transparent layer 1. */ public final static int LAYERT1 = 04;
/** Describes transparent layer 2. */ public final static int LAYERT2 = 010;
/** Describes transparent layer 3. */ public final static int LAYERT3 = 020;
/** Describes transparent layer 4. */ public final static int LAYERT4 = 040;
/** Describes transparent layer 5. */ public final static int LAYERT5 = 0100;
/** Describes transparent layer 6. */ public final static int LAYERT6 = 0200;
/** Describes transparent layer 7. */ public final static int LAYERT7 = 0400;
/** Describes transparent layer 8. */ public final static int LAYERT8 = 01000;
/** Describes transparent layer 9. */ public final static int LAYERT9 = 02000;
/** Describes transparent layer 10. */ public final static int LAYERT10 = 04000;
/** Describes transparent layer 11. */ public final static int LAYERT11 = 010000;
/** Describes transparent layer 12. */ public final static int LAYERT12 = 020000;
// Constants used in technologies and in creating an EGraphics
/** defines the 1st transparent layer. */ public static final int TRANSPARENT_1 = 1;
/** defines the 2nd transparent layer. */ public static final int TRANSPARENT_2 = 2;
/** defines the 3rd transparent layer. */ public static final int TRANSPARENT_3 = 3;
/** defines the 4th transparent layer. */ public static final int TRANSPARENT_4 = 4;
/** defines the 5th transparent layer. */ public static final int TRANSPARENT_5 = 5;
/** defines the 6th transparent layer. */ public static final int TRANSPARENT_6 = 6;
/** defines the 7th transparent layer. */ public static final int TRANSPARENT_7 = 7;
/** defines the 8th transparent layer. */ public static final int TRANSPARENT_8 = 8;
/** defines the 9th transparent layer. */ public static final int TRANSPARENT_9 = 9;
/** defines the 10th transparent layer. */ public static final int TRANSPARENT_10 = 10;
/** defines the 11th transparent layer. */ public static final int TRANSPARENT_11 = 11;
/** defines the 12th transparent layer. */ public static final int TRANSPARENT_12 = 12;
/**
* Method to create a graphics object.
* @param displayPatterned true if drawn with a pattern on the display.
* @param printPatterned true if drawn with a pattern on a printer.
* @param outlineWhenPatterned the outline texture to use when patterned.
* @param transparentLayer the transparent layer number (0 for none).
* @param red the red component of this EGraphics.
* @param green the green component of this EGraphics.
* @param blue the blue component of this EGraphics.
* @param opacity the opacity of this EGraphics (1 for opaque, 0 for transparent).
* @param foreground the foreground factor of this EGraphics (1 for to be in foreground).
* @param pattern the 16x16 stipple pattern of this EGraphics (16 integers).
*/
public EGraphics(boolean displayPatterned, boolean printPatterned, Outline outlineWhenPatterned,
int transparentLayer, int red, int green, int blue, double opacity, boolean foreground, int[] pattern)
{
this(displayPatterned, printPatterned, outlineWhenPatterned,
transparentLayer, red, green, blue, opacity, foreground, pattern, DEFAULT_MODE, DEFAULT_FACTOR);
}
/**
* Method to create a graphics object.
* @param displayPatterned true if drawn with a pattern on the display.
* @param printPatterned true if drawn with a pattern on a printer.
* @param outlineWhenPatterned the outline texture to use when patterned.
* @param transparentLayer the transparent layer number (0 for none).
* @param red the red component of this EGraphics.
* @param green the green component of this EGraphics.
* @param blue the blue component of this EGraphics.
* @param opacity the opacity of this EGraphics (1 for opaque, 0 for transparent).
* @param foreground the foreground factor of this EGraphics (1 for to be in foreground).
* @param pattern the 16x16 stipple pattern of this EGraphics (16 integers).
* @param transparencyMode 3D transparency mode
* @param transparencyFactor 3D transparency factor
*/
public EGraphics(boolean displayPatterned, boolean printPatterned, Outline outlineWhenPatterned,
int transparentLayer, int red, int green, int blue, double opacity, boolean foreground, int[] pattern,
J3DTransparencyOption transparencyMode, double transparencyFactor)
{
this.displayPatterned = displayPatterned;
this.printPatterned = printPatterned;
this.patternOutline = (outlineWhenPatterned != null) ? outlineWhenPatterned : Outline.NOPAT;
if (transparentLayer < 0 || transparentLayer > TRANSPARENT_12) {
System.out.println("Graphics transparent color bad: " + transparentLayer);
transparentLayer = 0;
}
this.transparentLayer = transparentLayer;
if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {
System.out.println("Graphics color bad: (" + red + "," + green + "," + blue + ")");
red = Math.min(Math.max(red, 0), 255);
green = Math.max(Math.max(green, 0), 255);
blue = Math.max(Math.max(blue, 0), 255);
}
this.color = new Color(red, green, blue);
this.opacity = validateOpacity(opacity);
this.foreground = foreground;
if (pattern.length != 16)
throw new IllegalArgumentException("Graphics bad: has " + pattern.length + " pattern entries instead of 16");
this.pattern = pattern.clone();
for (int i = 0; i < this.pattern.length; i++)
this.pattern[i] &= 0xFFFF;
this.reversedPattern = makeReversedPattern(this.pattern);
this.transparencyMode = transparencyMode != null ? transparencyMode : J3DTransparencyOption.NONE;
this.transparencyFactor = transparencyFactor;
}
/**
* Method to create a graphics object.
* @param displayPatterned true if drawn with a pattern on the display.
* @param printPatterned true if drawn with a pattern on a printer.
* @param outlineWhenPatterned the outline texture to use when patterned.
* @param transparentLayer the transparent layer number (0 for none).
* @param red the red component of this EGraphics.
* @param green the green component of this EGraphics.
* @param blue the blue component of this EGraphics.
* @param opacity the opacity of this EGraphics (1 for opaque, 0 for transparent).
* @param foreground the foreground factor of this EGraphics (1 for to be in foreground).
* @param pattern the 16x16 stipple pattern of this EGraphics (16 integers).
*/
private EGraphics(boolean displayPatterned, boolean printPatterned, Outline outlineWhenPatterned,
int transparentLayer, Color opaqueColor, double opacity, boolean foreground, int[] pattern, int[] reversedPattern,
J3DTransparencyOption transparencyMode, double transparencyFactor)
{
this.displayPatterned = displayPatterned;
this.printPatterned = printPatterned;
this.patternOutline = outlineWhenPatterned;
this.transparentLayer = transparentLayer;
this.color = opaqueColor;
this.opacity = validateOpacity(opacity);
this.foreground = foreground;
this.pattern = pattern;
this.reversedPattern = reversedPattern;
this.transparencyMode = transparencyMode;
this.transparencyFactor = transparencyFactor;
}
private String makePatString(int [] pattern)
{
StringBuffer sb = new StringBuffer();
for(int i=0; i<16; i++)
{
if (i > 0) sb.append("/");
sb.append(Integer.toString(pattern[i]));
}
return sb.toString();
}
private void parsePatString(String patString, int [] pattern)
{
int pos = 0;
for(int i=0; i<16; i++)
{
pattern[i] = TextUtils.atoi(patString.substring(pos)) & 0xFFFF;
pos = patString.indexOf('/', pos) + 1;
}
}
/**
* Method describes how this EGraphics appears on a display.
* This EGraphics can be drawn as a solid fill or as a pattern.
* @return true to draw this EGraphics patterned on a display.
* False to draw this EGraphics as a solid fill on a display.
*/
public boolean isPatternedOnDisplay() { return displayPatterned; }
/**
* Method returns EGraphics which differs from this EGraphics by appearance on a display.
* This EGraphics can be drawn as a solid fill or as a pattern.
* @param p true to draw this EGraphics patterned on a display.
* False to draw this EGraphics as a solid fill on a display.
* @return EGraphics with specified appearance on a display
*/
public EGraphics withPatternedOnDisplay(boolean p) {
if (p == displayPatterned) return this;
return new EGraphics(p, printPatterned, patternOutline, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method describes how this EGraphics appears on a printer.
* This EGraphics can be drawn as a solid fill or as a pattern.
* @return true to draw this EGraphics patterned on a printer.
* False to draw this EGraphics as a solid fill on a printer.
*/
public boolean isPatternedOnPrinter() { return printPatterned; }
/**
* Method returns EGraphics which differs from this EGraphics by appearance on a printer.
* This EGraphics can be drawn as a solid fill or as a pattern.
* @param p true to draw this EGraphics patterned on a printer.
* False to draw this EGraphics as a solid fill on a printer.
* @return EGraphics with specified appearance on a printer.
*/
public EGraphics withPatternedOnPrinter(boolean p) {
if (p == printPatterned) return this;
return new EGraphics(displayPatterned, p, patternOutline, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to tell the type of outline pattern.
* When the EGraphics is drawn as a pattern, the outline can be defined more clearly by drawing a line around the edge.
* @return the type of outline pattern.
*/
public Outline getOutlined() { return patternOutline; }
/**
* Method returns EGraphics which differs from this EGraphics by Outline pattern
* When the EGraphics is drawn as a pattern, the outline can be defined more clearly by drawing a line around the edge.
* @param o the outline pattern.
* @return EGraphics with specified outline pattern
*/
public EGraphics withOutlined(Outline o) {
if (o == null)
o = Outline.NOPAT;
if (o == patternOutline) return this;
return new EGraphics(displayPatterned, printPatterned, o, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to return the transparent layer number associated with this EGraphics.
* @return the transparent layer number associated with this EGraphics.
* A value of zero means that this EGraphics is not drawn transparently.
* Instead, use the "getColor()" method to get its solid color.
*/
public int getTransparentLayer() { return transparentLayer; }
/**
* Method returns EGraphics which differs from this EGraphics by transparent Layer.
* @param transparentLayer the transparent layer number associated with this EGraphics.
* A value of zero means that this EGraphics is not drawn transparently.
* Then, use the "setColor()" method to set its solid color.
* @return EGraphcos with specified transparentLayer
*/
public EGraphics withTransparentLayer(int transparentLayer) {
if (transparentLayer < 0 || transparentLayer > TRANSPARENT_12) {
System.out.println("Graphics transparent color bad: " + transparentLayer);
transparentLayer = 0;
}
if (transparentLayer == this.transparentLayer) return this;
return new EGraphics(displayPatterned, printPatterned, patternOutline, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to get the stipple pattern of this EGraphics.
* The stipple pattern is a 16 x 16 pattern that is stored in 16 integers.
* @return the stipple pattern of this EGraphics.
*/
public int [] getPattern() { return pattern; }
/**
* Method to get the reversed stipple pattern of this EGraphics.
* The reversed stipple pattern is a 16 x 32 pattern that is stored in 16 integers.
* @return the stipple pattern of this EGraphics.
*/
public int [] getReversedPattern() { return reversedPattern; }
/**
* Method to get the String representation of the stipple pattern of this EGraphics.
* @return the String representation the stipple pattern of this EGraphics.
*/
public String getPatternString() { return makePatString(pattern); }
/**
* Method returns EGraphics which differs from this EGraphics by stipple pattern.
* The stipple pattern is a 16 x 16 pattern that is stored in 16 integers.
* @param pattern the stipple pattern of this EGraphics.
* @return EGraphics with specified stipple pattern.
*/
public EGraphics withPattern(int [] pattern) {
if (pattern.length != 16)
throw new IllegalArgumentException("Graphics bad: has " + pattern.length + " pattern entries instead of 16");
pattern = pattern.clone();
for (int i = 0; i < this.pattern.length; i++)
pattern[i] &= 0xFFFF;
if (Arrays.equals(pattern, this.pattern)) return this;
int[] reversedPattern = makeReversedPattern(pattern);
return new EGraphics(displayPatterned, printPatterned, patternOutline, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method returns EGraphics which differs from this EGraphics by stipple pattern.
* The stipple pattern is a 16 x 16 pattern that is stored in 16 integers.
* @param patternStr text representation of the stipple pattern of this EGraphics.
* @return EGraphics with specified stipple pattern.
*/
public EGraphics withPattern(String patternStr) {
int[] pattern = new int[16];
parsePatString(patternStr, pattern);
return withPattern(pattern);
}
private int[] makeReversedPattern(int[] pattern) {
int[] reversedPattern = new int[16];
for (int i = 0; i < reversedPattern.length; i++) {
int shortPattern = pattern[i];
if ((shortPattern >>> 16) != 0) {
System.out.println("Graphics bad: has " + Integer.toHexString(shortPattern) + " pattern line");
shortPattern &= 0xFFFF;
}
for (int j = 0; j < 16; j++) {
if ((shortPattern & (1 << (15 - j))) != 0)
reversedPattern[i] |= 0x10001 << j;
}
}
return reversedPattern;
}
/**
* Method to get the opacity of this EGraphics.
* Opacity runs from 0 (transparent) to 1 (opaque).
* @return the opacity of this EGraphics.
*/
public double getOpacity() { return opacity; }
/**
* Method to check range of opacity provided.
* If < 0, reset it to zero.
* If > 1, reset it to one.
* @param opacity
* @return
*/
private static double validateOpacity(double opacity)
{
if (opacity < 0)
{
System.out.println("Opacity " + opacity + " smaller than 0. Resetting to 0");
return 0;
}
else if (opacity > 1)
{
System.out.println("Opacity " + opacity + " bigger than 1. Resetting to 1");
return 1;
}
return opacity;
}
/**
* Method returns EGraphics which differs from this EGraphics by opacity.
* Opacity runs from 0 (transparent) to 1 (opaque).
* @param opacity the opacity of this EGraphics.
* @return EGraphics with specified opacity.
*/
public EGraphics withOpacity(double opacity) {
opacity = validateOpacity(opacity);
if (opacity == this.opacity) return this;
return new EGraphics(displayPatterned, printPatterned, patternOutline, transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to get whether this EGraphics should be drawn in the foreground.
* The foreground is the main "mix" of layers, such as metal and polysilicon.
* The background is typically used by implant and well layers.
* @return the whether this EGraphics should be drawn in the foreground.
*/
public boolean getForeground() { return foreground; }
/**
* Method returns EGraphics which differs from this EGraphics that it should be drawn in the foreground.
* The foreground is the main "mix" of layers, such as metal and polysilicon.
* The background is typically used by implant and well layers.
* @param f true if this EGraphics should be drawn in the foreground.
* @return EGraphics with specified foreground
*/
public EGraphics withForeground(boolean f) {
if (f == this.foreground) return this;
return new EGraphics(displayPatterned, printPatterned, patternOutline, transparentLayer, color, opacity, f,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to return the color associated with this EGraphics.
* Alpha component is determined by opacity
* @return the color associated with this EGraphics.
*/
public Color getAlphaColor() {
int alpha = (int)(opacity * 255.0);
return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
}
/**
* Method to return the color associated with this EGraphics.
* Alpha component is 255.
* @return the color associated with this EGraphics.
*/
public Color getColor() { return color; }
/**
* Method to return the color associated with this EGraphics considering
* Colors of transparentLayers.
* @param transparentColors Colors of transparentLayers.
* @return the color associated with this EGraphics.
*/
public Color getColor(Color[] transparentColors) {
if (transparentLayer > 0 && transparentLayer <= transparentColors.length)
return transparentColors[transparentLayer - 1];
return color;
}
/**
* Returns the RGB value representing the color associated with this EGraphics.
* (Bits 16-23 are red, 8-15 are green, 0-7 are blue).
* Alpha/opacity component is 0
* @return the RGB value of the color
*/
public int getRGB() {
return color.getRGB() & 0xFFFFFF;
}
/**
* Method returns EGraphics which differs from this EGraphics by to the associated color.
* The alpha component of the color is set to full opacity,
* alpha component of the argument is ignored.
* @param color the color to set.
* @return EGraphics with specified color.
*/
public EGraphics withColor(Color color) {
if (color.getAlpha() != 0xFF)
color = new Color(color.getRGB());
if (color.equals(this.color)) return this;
assert color.getAlpha() == 0xFF;
return new EGraphics(displayPatterned, printPatterned, patternOutline,
transparentLayer, new Color(color.getRed(), color.getGreen(), color.getBlue()), opacity, foreground,
pattern, reversedPattern, transparencyMode, transparencyFactor);
}
/**
* Method to convert a color index into a Color.
* Color indices are more general than colors, because they can handle
* transparent layers, C-Electric-style opaque layers, and full color values.
* @param colorIndex the color index to convert.
* @param colorMap an optional color map to use for transparent colors (if null, figure it out)
* @return a Color that describes the index
* Returns null if the index is a transparent layer.
*/
public static Color getColorFromIndex(int colorIndex, Color [] colorMap)
{
if ((colorIndex&OPAQUEBIT) != 0)
{
// an opaque color
switch (colorIndex)
{
case WHITE: return new Color(255, 255, 255);
case BLACK: return new Color( 0, 0, 0);
case RED: return new Color(255, 0, 0);
case BLUE: return new Color( 0, 0, 255);
case GREEN: return new Color( 0, 255, 0);
case CYAN: return new Color( 0, 255, 255);
case MAGENTA: return new Color(255, 0, 255);
case YELLOW: return new Color(255, 255, 0);
case CELLTXT: return new Color( 0, 0, 0);
case CELLOUT: return new Color( 0, 0, 0);
case WINBOR: return new Color( 0, 0, 0);
case HWINBOR: return new Color( 0, 255, 0);
case MENBOR: return new Color( 0, 0, 0);
case HMENBOR: return new Color(255, 255, 255);
case MENTXT: return new Color( 0, 0, 0);
case MENGLY: return new Color( 0, 0, 0);
case CURSOR: return new Color( 0, 0, 0);
case GRAY: return new Color(180, 180, 180);
case ORANGE: return new Color(255, 190, 6);
case PURPLE: return new Color(186, 0, 255);
case BROWN: return new Color(139, 99, 46);
case LGRAY: return new Color(230, 230, 230);
case DGRAY: return new Color(100, 100, 100);
case LRED: return new Color(255, 150, 150);
case DRED: return new Color(159, 80, 80);
case LGREEN: return new Color(175, 255, 175);
case DGREEN: return new Color( 89, 159, 85);
case LBLUE: return new Color(150, 150, 255);
case DBLUE: return new Color( 2, 15, 159);
}
return null;
}
if ((colorIndex&FULLRGBBIT) != 0)
{
// a full RGB color (opaque)
return new Color((colorIndex >> 24) & 0xFF, (colorIndex >> 16) & 0xFF, (colorIndex >> 8) & 0xFF);
}
// handle transparent colors
if (colorMap == null)
{
Technology curTech = Technology.getCurrent();
colorMap = curTech.getColorMap();
if (colorMap == null)
{
Technology altTech = Schematics.getDefaultSchematicTechnology();
if (altTech != curTech)
{
colorMap = altTech.getColorMap();
}
if (colorMap == null) return null;
}
}
int trueIndex = colorIndex >> 2;
if (trueIndex < colorMap.length) return colorMap[trueIndex];
return null;
}
/**
* Method returns EGraphics which differs from this EGraphics by a "color index".
* Color indices are more general than colors, because they can handle
* transparent layers, C-Electric-style opaque layers, and full color values.
* Artwork nodes and arcs represent individualized color by using color indices.
* @param colorIndex the color index to set.
*/
public EGraphics withColorIndex(int colorIndex)
{
if ((colorIndex&(OPAQUEBIT|FULLRGBBIT)) != 0)
{
// an opaque or full RGB color
return withColor(getColorFromIndex(colorIndex, null)).withTransparentLayer(0);
}
// a transparent color
int transparentLayer = this.transparentLayer;
if ((colorIndex&LAYERT1) != 0) transparentLayer = TRANSPARENT_1; else
if ((colorIndex&LAYERT2) != 0) transparentLayer = TRANSPARENT_2; else
if ((colorIndex&LAYERT3) != 0) transparentLayer = TRANSPARENT_3; else
if ((colorIndex&LAYERT4) != 0) transparentLayer = TRANSPARENT_4; else
if ((colorIndex&LAYERT5) != 0) transparentLayer = TRANSPARENT_5; else
if ((colorIndex&LAYERT6) != 0) transparentLayer = TRANSPARENT_6; else
if ((colorIndex&LAYERT7) != 0) transparentLayer = TRANSPARENT_7; else
if ((colorIndex&LAYERT8) != 0) transparentLayer = TRANSPARENT_8; else
if ((colorIndex&LAYERT9) != 0) transparentLayer = TRANSPARENT_9; else
if ((colorIndex&LAYERT10) != 0) transparentLayer = TRANSPARENT_10; else
if ((colorIndex&LAYERT11) != 0) transparentLayer = TRANSPARENT_11; else
if ((colorIndex&LAYERT12) != 0) transparentLayer = TRANSPARENT_12;
return withTransparentLayer(transparentLayer);
}
/**
* Method to convert a Color to a color index.
* Color indices are more general than colors, because they can handle
* transparent layers, C-Electric-style opaque layers, and full color values.
* Artwork nodes and arcs represent individualized color by using color indices.
* @param color a Color object
* @return the color index that describes that color.
*/
public static int makeIndex(Color color)
{
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int index = (red << 24) | (green << 16) | (blue << 8) | FULLRGBBIT;
return index;
}
/**
* Method to convert a transparent layer to a color index.
* Color indices are more general than colors, because they can handle
* transparent layers, C-Electric-style opaque layers, and full color values.
* @param transparentLayer the transparent layer number.
* @return the color index that describes that transparent layer.
*/
public static int makeIndex(int transparentLayer)
{
switch (transparentLayer)
{
case TRANSPARENT_1: return LAYERT1;
case TRANSPARENT_2: return LAYERT2;
case TRANSPARENT_3: return LAYERT3;
case TRANSPARENT_4: return LAYERT4;
case TRANSPARENT_5: return LAYERT5;
case TRANSPARENT_6: return LAYERT6;
case TRANSPARENT_7: return LAYERT7;
case TRANSPARENT_8: return LAYERT8;
case TRANSPARENT_9: return LAYERT9;
case TRANSPARENT_10: return LAYERT10;
case TRANSPARENT_11: return LAYERT11;
case TRANSPARENT_12: return LAYERT12;
}
return 0;
}
/**
* Method to find the index of a color, given its name.
* @param name the name of the color.
* @return the index of the color.
*/
public static int findColorIndex(String name)
{
if (name.equals("white")) return WHITE;
if (name.equals("black")) return BLACK;
if (name.equals("red")) return RED;
if (name.equals("blue")) return BLUE;
if (name.equals("green")) return GREEN;
if (name.equals("cyan")) return CYAN;
if (name.equals("magenta")) return MAGENTA;
if (name.equals("yellow")) return YELLOW;
if (name.equals("gray")) return GRAY;
if (name.equals("orange")) return ORANGE;
if (name.equals("purple")) return PURPLE;
if (name.equals("brown")) return BROWN;
if (name.equals("light-gray")) return LGRAY;
if (name.equals("dark-gray")) return DGRAY;
if (name.equals("light-red")) return LRED;
if (name.equals("dark-red")) return DRED;
if (name.equals("light-green")) return LGREEN;
if (name.equals("dark-green")) return DGREEN;
if (name.equals("light-blue")) return LBLUE;
if (name.equals("dark-blue")) return DBLUE;
if (name.equals("transparent-1")) return LAYERT1;
if (name.equals("transparent-2")) return LAYERT2;
if (name.equals("transparent-3")) return LAYERT3;
if (name.equals("transparent-4")) return LAYERT4;
if (name.equals("transparent-5")) return LAYERT5;
if (name.equals("transparent-6")) return LAYERT6;
if (name.equals("transparent-7")) return LAYERT7;
if (name.equals("transparent-8")) return LAYERT8;
if (name.equals("transparent-9")) return LAYERT9;
if (name.equals("transparent-10")) return LAYERT10;
if (name.equals("transparent-11")) return LAYERT11;
if (name.equals("transparent-12")) return LAYERT12;
return 0;
}
/**
* Method to tell the name of the color with a given index.
* Color indices are more general than colors, because they can handle
* transparent layers, C-Electric-style opaque layers, and full color values.
* @param colorIndex the color number.
* @return the name of that color.
*/
public static String getColorIndexName(int colorIndex)
{
if ((colorIndex&FULLRGBBIT) != 0)
{
int red = (colorIndex >> 24) & 0xFF;
int green = (colorIndex >> 16) & 0xFF;
int blue = (colorIndex >> 8) & 0xFF;
return "Color (" + red + "," + green + "," + blue + ")";
}
switch (colorIndex)
{
case WHITE: return "white";
case BLACK: return "black";
case RED: return "red";
case BLUE: return "blue";
case GREEN: return "green";
case CYAN: return "cyan";
case MAGENTA: return "magenta";
case YELLOW: return "yellow";
case GRAY: return "gray";
case ORANGE: return "orange";
case PURPLE: return "purple";
case BROWN: return "brown";
case LGRAY: return "light-gray";
case DGRAY: return "dark-gray";
case LRED: return "light-red";
case DRED: return "dark-red";
case LGREEN: return "light-green";
case DGREEN: return "dark-green";
case LBLUE: return "light-blue";
case DBLUE: return "dark-blue";
case LAYERT1: return "transparent-1";
case LAYERT2: return "transparent-2";
case LAYERT3: return "transparent-3";
case LAYERT4: return "transparent-4";
case LAYERT5: return "transparent-5";
case LAYERT6: return "transparent-6";
case LAYERT7: return "transparent-7";
case LAYERT8: return "transparent-8";
case LAYERT9: return "transparent-9";
case LAYERT10: return "transparent-10";
case LAYERT11: return "transparent-11";
case LAYERT12: return "transparent-12";
}
return "ColorIndex "+colorIndex;
}
/**
* Method to return the array of color indices.
* @return an array of the possible color indices.
*/
public static int [] getColorIndices()
{
return new int [] {WHITE, BLACK, RED, BLUE, GREEN, CYAN, MAGENTA, YELLOW,
GRAY, ORANGE, PURPLE, BROWN, LGRAY, DGRAY, LRED, DRED, LGREEN, DGREEN, LBLUE, DBLUE,
LAYERT1, LAYERT2, LAYERT3, LAYERT4, LAYERT5, LAYERT6, LAYERT7, LAYERT8, LAYERT9,
LAYERT10, LAYERT11, LAYERT12};
}
/**
* Method to return the array of transparent color indices.
* @return an array of the possible transparent color indices.
*/
public static int [] getTransparentColorIndices()
{
return new int [] {LAYERT1, LAYERT2, LAYERT3, LAYERT4, LAYERT5, LAYERT6, LAYERT7, LAYERT8, LAYERT9,
LAYERT10, LAYERT11, LAYERT12};
}
/**
* Method to return the transparency mode of this EGraphics for the 3D View.
* Possible values "NONE, "FASTEST", "NICEST", "BLENDED", "SCREEN_DOOR".
* @return the transparency mode of this layer for the 3D view.
*/
public J3DTransparencyOption getTransparencyMode() { return transparencyMode; }
/**
* Method returns EGraphics which differs form this EGraphics by transparency mode.
* Possible values "NONE, "FASTEST", "NICEST", "BLENDED", "SCREEN_DOOR".
* @param mode the transparency mode of this layer.
*/
public EGraphics withTransparencyMode(J3DTransparencyOption mode) {
if (mode == null)
mode = J3DTransparencyOption.NONE;
if (mode == transparencyMode) return this;
return new EGraphics(displayPatterned, printPatterned, patternOutline,
transparentLayer, color, opacity, foreground,
pattern, reversedPattern, mode, transparencyFactor);
}
/**
* Method to return the transparency factor of this EGraphics.
* Possible values from 0 (opaque) -> 1 (transparent)
* @return the transparency factor of this layer for the 3D view.
*/
public double getTransparencyFactor() { return transparencyFactor; }
/**
* Method returns EGraphics which differs from this EGraphics by transparency factor.
* Layers can have a transparency from 0 (opaque) to 1(transparent).
* @param factor the transparency factor of this layer.
* @return EGraphics with specified transparency factor.
*/
public EGraphics withTransparencyFactor(double factor) {
if (factor == transparencyFactor) return this;
return new EGraphics(displayPatterned, printPatterned, patternOutline,
transparentLayer, color, opacity, foreground,
pattern, reversedPattern, transparencyMode, factor);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o instanceof EGraphics) {
EGraphics that = (EGraphics)o;
return this.displayPatterned == that.displayPatterned &&
this.printPatterned == that.printPatterned &&
this.patternOutline == that.patternOutline &&
this.transparentLayer == that.transparentLayer &&
this.color.equals(that.color) &&
this.opacity == that.opacity &&
this.foreground == that.foreground &&
Arrays.equals(this.pattern, that.pattern) &&
this.transparencyMode == that.transparencyMode &&
this.transparencyFactor == that.transparencyFactor;
}
return false;
}
@Override
public int hashCode() {
int hash = color.hashCode();
if (pattern != null)
hash += 79*pattern[0];
return hash;
}
}