/* -*- 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; } }