diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar
index 7618ac35..9747a846 100644
Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ
diff --git a/diylc/diylc-library/src/org/diylc/awt/ShadedPaint.java b/diylc/diylc-library/src/org/diylc/awt/ShadedPaint.java
new file mode 100644
index 00000000..aff0558f
--- /dev/null
+++ b/diylc/diylc-library/src/org/diylc/awt/ShadedPaint.java
@@ -0,0 +1,86 @@
+/*
+
+ DIY Layout Creator (DIYLC).
+ Copyright (c) 2009-2018 held jointly by the individual authors.
+
+ This file is part of DIYLC.
+
+ DIYLC 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.
+
+ DIYLC 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 DIYLC. If not, see .
+
+*/
+package org.diylc.awt;
+
+import java.awt.Color;
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+public class ShadedPaint implements Paint {
+
+ private ShadedPaintContext context;
+ private Point2D p1;
+ private Point2D p2;
+ private Color c1;
+ private Color c2;
+
+ public ShadedPaint(Point2D p1, Point2D p2, Color c, double shadeFactor) {
+ this.p1 = p1;
+ this.p2 = p2;
+ int r = c.getRed();
+ int g = c.getGreen();
+ int b = c.getBlue();
+
+ this.c1 = new Color(
+ Math.max((int) (r * shadeFactor), 0),
+ Math.max((int) (g * shadeFactor), 0),
+ Math.max((int) (b * shadeFactor), 0));
+
+
+ int i = (int)(1.0/(1.0-shadeFactor));
+ if ( r == 0 && g == 0 && b == 0) {
+ this.c2 = new Color(i, i, i);
+ } else {
+ if ( r > 0 && r < i ) r = i;
+ if ( g > 0 && g < i ) g = i;
+ if ( b > 0 && b < i ) b = i;
+
+ this.c2 = new Color(Math.min((int)(r / shadeFactor), 255),
+ Math.min((int)(g / shadeFactor), 255),
+ Math.min((int)(b / shadeFactor), 255));
+ }
+ }
+
+ public ShadedPaint(Point2D p1, Point2D p2, Color c2) {
+ this(p1, p2, c2, 0.9f);
+ }
+
+ @Override
+ public int getTransparency() {
+ return OPAQUE;
+ }
+
+ @Override
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
+ AffineTransform xform, RenderingHints hints) {
+ if (context == null || !context.getColorModel().equals(cm))
+ context = new ShadedPaintContext(cm, p1, p2, xform, c1, c2);
+ return context;
+ }
+
+}
diff --git a/diylc/diylc-library/src/org/diylc/awt/ShadedPaintContext.java b/diylc/diylc-library/src/org/diylc/awt/ShadedPaintContext.java
new file mode 100644
index 00000000..6171b9b8
--- /dev/null
+++ b/diylc/diylc-library/src/org/diylc/awt/ShadedPaintContext.java
@@ -0,0 +1,264 @@
+/*
+
+ DIY Layout Creator (DIYLC).
+ Copyright (c) 2009-2018 held jointly by the individual authors.
+
+ This file is part of DIYLC.
+
+ DIYLC 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.
+
+ DIYLC 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 DIYLC. If not, see .
+
+*/
+package org.diylc.awt;
+
+import java.awt.Color;
+import java.awt.PaintContext;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.lang.ref.WeakReference;
+
+import sun.awt.image.IntegerComponentRaster;
+
+public class ShadedPaintContext implements PaintContext {
+
+ static ColorModel xrgbmodel =
+ new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
+ static ColorModel xbgrmodel =
+ new DirectColorModel(24, 0x000000ff, 0x0000ff00, 0x00ff0000);
+
+ static ColorModel cachedModel;
+ static WeakReference cached;
+
+ static synchronized Raster getCachedRaster(ColorModel cm, int w, int h) {
+ if (cm == cachedModel) {
+ if (cached != null) {
+ Raster ras = (Raster) cached.get();
+ if (ras != null &&
+ ras.getWidth() >= w &&
+ ras.getHeight() >= h)
+ {
+ cached = null;
+ return ras;
+ }
+ }
+ }
+ return cm.createCompatibleWritableRaster(w, h);
+ }
+
+ static synchronized void putCachedRaster(ColorModel cm, Raster ras) {
+ if (cached != null) {
+ Raster cras = (Raster) cached.get();
+ if (cras != null) {
+ int cw = cras.getWidth();
+ int ch = cras.getHeight();
+ int iw = ras.getWidth();
+ int ih = ras.getHeight();
+ if (cw >= iw && ch >= ih) {
+ return;
+ }
+ if (cw * ch >= iw * ih) {
+ return;
+ }
+ }
+ }
+ cachedModel = cm;
+ cached = new WeakReference(ras);
+ }
+
+ double x1;
+ double y1;
+ double dx;
+ double dy;
+ int interp[];
+ Raster saved;
+ ColorModel model;
+
+ public ShadedPaintContext(ColorModel cm,
+ Point2D p1, Point2D p2, AffineTransform xform,
+ Color c1, Color c2) {
+ // First calculate the distance moved in user space when
+ // we move a single unit along the X & Y axes in device space.
+ Point2D xvec = new Point2D.Double(1, 0);
+ Point2D yvec = new Point2D.Double(0, 1);
+ try {
+ AffineTransform inverse = xform.createInverse();
+ inverse.deltaTransform(xvec, xvec);
+ inverse.deltaTransform(yvec, yvec);
+ } catch (NoninvertibleTransformException e) {
+ xvec.setLocation(0, 0);
+ yvec.setLocation(0, 0);
+ }
+
+ // Now calculate the (square of the) user space distance
+ // between the anchor points. This value equals:
+ // (UserVec . UserVec)
+ double udx = p2.getX() - p1.getX();
+ double udy = p2.getY() - p1.getY();
+ double ulenSq = udx * udx + udy * udy;
+
+ if (ulenSq <= Double.MIN_VALUE) {
+ dx = 0;
+ dy = 0;
+ } else {
+ // Now calculate the proportional distance moved along the
+ // vector from p1 to p2 when we move a unit along X & Y in
+ // device space.
+ //
+ // The length of the projection of the Device Axis Vector is
+ // its dot product with the Unit User Vector:
+ // (DevAxisVec . (UserVec / Len(UserVec))
+ //
+ // The "proportional" length is that length divided again
+ // by the length of the User Vector:
+ // (DevAxisVec . (UserVec / Len(UserVec))) / Len(UserVec)
+ // which simplifies to:
+ // ((DevAxisVec . UserVec) / Len(UserVec)) / Len(UserVec)
+ // which simplifies to:
+ // (DevAxisVec . UserVec) / LenSquared(UserVec)
+ dx = (xvec.getX() * udx + xvec.getY() * udy) / ulenSq;
+ dy = (yvec.getX() * udx + yvec.getY() * udy) / ulenSq;
+
+
+ // We are acyclic
+ if (dx < 0) {
+ // If we are using the acyclic form below, we need
+ // dx to be non-negative for simplicity of scanning
+ // across the scan lines for the transition points.
+ // To ensure that constraint, we negate the dx/dy
+ // values and swap the points and colors.
+ Point2D p = p1; p1 = p2; p2 = p;
+ Color c = c1; c1 = c2; c2 = c;
+ dx = -dx;
+ dy = -dy;
+ }
+ }
+
+ Point2D dp1 = xform.transform(p1, null);
+ this.x1 = dp1.getX();
+ this.y1 = dp1.getY();
+
+ int rgb1 = c1.getRGB();
+ int rgb2 = c2.getRGB();
+ int a1 = (rgb1 >> 24) & 0xff;
+ int r1 = (rgb1 >> 16) & 0xff;
+ int g1 = (rgb1 >> 8) & 0xff;
+ int b1 = (rgb1 ) & 0xff;
+ int da = ((rgb2 >> 24) & 0xff) - a1;
+ int dr = ((rgb2 >> 16) & 0xff) - r1;
+ int dg = ((rgb2 >> 8) & 0xff) - g1;
+ int db = ((rgb2 ) & 0xff) - b1;
+ if (a1 == 0xff && da == 0) {
+ model = xrgbmodel;
+ if (cm instanceof DirectColorModel) {
+ DirectColorModel dcm = (DirectColorModel) cm;
+ int tmp = dcm.getAlphaMask();
+ if ((tmp == 0 || tmp == 0xff) &&
+ dcm.getRedMask() == 0xff &&
+ dcm.getGreenMask() == 0xff00 &&
+ dcm.getBlueMask() == 0xff0000)
+ {
+ model = xbgrmodel;
+ tmp = r1; r1 = b1; b1 = tmp;
+ tmp = dr; dr = db; db = tmp;
+ }
+ }
+ } else {
+ model = ColorModel.getRGBdefault();
+ }
+ interp = new int[257];
+ for (int i = 0; i <= 256; i++) {
+ float rel = i / 256.0f;
+ int rgb =
+ (((int) (a1 + da * rel)) << 24) |
+ (((int) (r1 + dr * rel)) << 16) |
+ (((int) (g1 + dg * rel)) << 8) |
+ (((int) (b1 + db * rel)) );
+ interp[i] = rgb;
+ }
+ }
+
+ /**
+ * Release the resources allocated for the operation.
+ */
+ public void dispose() {
+ if (saved != null) {
+ putCachedRaster(model, saved);
+ saved = null;
+ }
+ }
+
+ /**
+ * Return the ColorModel of the output.
+ */
+ public ColorModel getColorModel() {
+ return model;
+ }
+
+ /**
+ * Return a Raster containing the colors generated for the graphics
+ * operation.
+ * @param x,y,w,h The area in device space for which colors are
+ * generated.
+ */
+ public Raster getRaster(int x, int y, int w, int h) {
+ double rowrel = (x - x1) * dx + (y - y1) * dy;
+
+ Raster rast = saved;
+ if (rast == null || rast.getWidth() < w || rast.getHeight() < h) {
+ rast = getCachedRaster(model, w, h);
+ saved = rast;
+ }
+ IntegerComponentRaster irast = (IntegerComponentRaster) rast;
+ int off = irast.getDataOffset(0);
+ int adjust = irast.getScanlineStride() - w;
+ int[] pixels = irast.getDataStorage();
+
+ clipFillRaster(pixels, off, adjust, w, h, rowrel, dx, dy);
+
+// irast.markDirty();
+
+ return rast;
+ }
+
+ void clipFillRaster(int[] pixels, int off, int adjust, int w, int h,
+ double rowrel, double dx, double dy) {
+ while (--h >= 0) {
+ double colrel = rowrel;
+ int j = w;
+ if (colrel <= 0.0) {
+ int rgb = interp[0];
+ do {
+ pixels[off++] = rgb;
+ colrel += dx;
+ } while (--j > 0 && colrel <= 0.0);
+ }
+ while (colrel < 1.0 && --j >= 0) {
+ pixels[off++] = interp[(int) (colrel < 0.5 ? colrel * 2 * 256 : (2 - colrel * 2) * 256)];
+ colrel += dx;
+ }
+ if (j > 0) {
+ int rgb = interp[256];
+ do {
+ pixels[off++] = rgb;
+ } while (--j > 0);
+ }
+
+ off += adjust;
+ rowrel += dy;
+ }
+ }
+}
\ No newline at end of file
diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java b/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java
similarity index 91%
rename from diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java
rename to diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java
index f0f38665..e36e3699 100644
--- a/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java
+++ b/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java
@@ -28,7 +28,9 @@ import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
@@ -147,16 +149,30 @@ public abstract class AbstractLeadedComponent extends AbstractTransparentComp
float leadThickness = getLeadThickness();
double leadLength = (distance - calculatePinSpacing(shapeRect)) / 2;
- g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
- Color leadColor =
- shouldShadeLeads() ? getLeadColorForPainting(componentState).darker()
- : getLeadColorForPainting(componentState);
- g2d.setColor(leadColor);
- drawLeads(g2d, theta, leadLength);
-
if (shouldShadeLeads()) {
- g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
- leadColor = getLeadColorForPainting(componentState);
+ Stroke leadStroke = ObjectCache.getInstance().fetchBasicStroke(leadThickness - 1);
+ Color leadColor = getLeadColorForPainting(componentState);
+
+ Area leadArea = new Area();
+
+ int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
+ int endY = (int) (points[0].y + Math.sin(theta) * leadLength);
+ Line2D line = new Line2D.Double(points[0].x, points[0].y, endX, endY);
+ leadArea.add(new Area(leadStroke.createStrokedShape(line)));
+
+ endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
+ endY = (int) (points[1].y + Math.sin(theta - Math.PI) * leadLength);
+ line = new Line2D.Double(points[1].x, points[1].y, endX, endY);
+ leadArea.add(new Area(leadStroke.createStrokedShape(line)));
+
+ g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
+ g2d.setColor(leadColor);
+ g2d.fill(leadArea);
+ g2d.setColor(leadColor.darker());
+ g2d.draw(leadArea);
+ } else {
+ g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
+ Color leadColor = getLeadColorForPainting(componentState);
g2d.setColor(leadColor);
drawLeads(g2d, theta, leadLength);
}
@@ -278,7 +294,7 @@ public abstract class AbstractLeadedComponent extends AbstractTransparentComp
if (isCopperArea)
observer.startTrackingContinuityArea(true);
- float thickness = getLeadThickness();
+ float thickness = getLeadThickness() - 1;
Stroke stroke = null;
switch (getStyle()) {
case SOLID:
@@ -293,33 +309,22 @@ public abstract class AbstractLeadedComponent extends AbstractTransparentComp
break;
}
- g2d.setStroke(stroke);
+ Line2D line = new Line2D.Double(points[0].x, points[0].y, points[1].x, points[1].y);
+ Shape lineShape = stroke.createStrokedShape(line);
+
Color leadColor =
- shouldShadeLeads() ? getLeadColorForPainting(componentState).darker() : getLeadColorForPainting(componentState);
+ shouldShadeLeads() ? getLeadColorForPainting(componentState) : getLeadColorForPainting(componentState);
g2d.setColor(leadColor);
- g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
+ g2d.fill(lineShape);
if (isCopperArea)
observer.stopTrackingContinuityArea();
if (shouldShadeLeads()) {
- switch (getStyle()) {
- case SOLID:
- stroke = ObjectCache.getInstance().fetchBasicStroke(thickness - 2);
- break;
- case DASHED:
- stroke =
- ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness * 2, thickness * 4},
- thickness * 4);
- break;
- case DOTTED:
- stroke = ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness / 4, thickness * 4}, 0);
- break;
- }
- g2d.setStroke(stroke);
+ g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
leadColor = getLeadColorForPainting(componentState);
- g2d.setColor(leadColor);
- g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
+ g2d.setColor(leadColor.darker());
+ g2d.draw(lineShape);
}
}
diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractRadialComponent.java b/diylc/diylc-library/src/org/diylc/components/AbstractRadialComponent.java
similarity index 100%
rename from diylc/diylc-core/src/org/diylc/components/AbstractRadialComponent.java
rename to diylc/diylc-library/src/org/diylc/components/AbstractRadialComponent.java
diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractSchematicLeadedSymbol.java b/diylc/diylc-library/src/org/diylc/components/AbstractSchematicLeadedSymbol.java
similarity index 100%
rename from diylc/diylc-core/src/org/diylc/components/AbstractSchematicLeadedSymbol.java
rename to diylc/diylc-library/src/org/diylc/components/AbstractSchematicLeadedSymbol.java
diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java b/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java
index f5fa2d07..4e854e6c 100644
--- a/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java
+++ b/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java
@@ -19,6 +19,7 @@ package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
+import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Path2D;
@@ -54,10 +55,10 @@ public class HookupWire extends AbstractCurvedComponent {
@Override
protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) {
int thickness =
- (int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT));
+ (int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)) - 1;
Color curveColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
- : color.darker();
+ : color;
g2d.setColor(curveColor);
Stroke stroke = null;
switch (getStyle()) {
@@ -72,24 +73,25 @@ public class HookupWire extends AbstractCurvedComponent {
stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness / 4, thickness * 3}, 0);
break;
}
- g2d.setStroke(stroke);
- g2d.draw(curve);
+ Shape s = stroke.createStrokedShape(curve);
+ g2d.fill(s);
if (componentState == ComponentState.NORMAL) {
- g2d.setColor(color);
- switch (getStyle()) {
- case SOLID:
- stroke = ObjectCache.getInstance().fetchBasicStroke(thickness - 2);
- break;
- case DASHED:
- stroke =
- ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness * 2, thickness * 3},
- thickness * 4);
- break;
- case DOTTED:
- stroke = ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness / 4, thickness * 3}, 0);
- }
- g2d.setStroke(stroke);
- g2d.draw(curve);
+ g2d.setColor(color.darker());
+ g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
+// switch (getStyle()) {
+// case SOLID:
+// stroke = ObjectCache.getInstance().fetchBasicStroke(thickness - 2);
+// break;
+// case DASHED:
+// stroke =
+// ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness * 2, thickness * 3},
+// thickness * 4);
+// break;
+// case DOTTED:
+// stroke = ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness / 4, thickness * 3}, 0);
+// }
+// g2d.setStroke(stroke);
+ g2d.draw(s);
}
}
diff --git a/diylc/diylc-swing/fonts/consola.ttf b/diylc/diylc-swing/fonts/consola.ttf
new file mode 100644
index 00000000..90b7b862
Binary files /dev/null and b/diylc/diylc-swing/fonts/consola.ttf differ
diff --git a/diylc/diylc-swing/fonts/lucon.ttf b/diylc/diylc-swing/fonts/lucon.ttf
new file mode 100644
index 00000000..3e26f955
Binary files /dev/null and b/diylc/diylc-swing/fonts/lucon.ttf differ
diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar
index 7618ac35..9747a846 100644
Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ
diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar
index d55df134..6fb9a847 100644
Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ