mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
Merge branch 'master' into controllers
This commit is contained in:
@@ -397,6 +397,10 @@
|
||||
<releaseDate>2026-08-06 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added support for stacked guitar pickups: 'Stacked - North' and 'Stacked - South' are two new options to pick in the Coil(s) property of Single Coil, P-90, P-Bass and Jazz Bass pickups</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Node Name Tooltips' feature that can be toggled in the Config menu; when enabled a tooltip is shown next to the cursor with names of component nodes under the cursor</description>
|
||||
@@ -417,6 +421,10 @@
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Renamed Mac OS build files to start with a 'mac' prefix instead of 'osx'</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Images can randomly disappear when zooming in and scrolling</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
|
||||
+6
-1
@@ -294,8 +294,13 @@ public abstract class AbstractGuitarPickup extends AbstractLabeledComponent<Stri
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
|
||||
}
|
||||
|
||||
public boolean isStacked() {
|
||||
return getPolarity() == Polarity.StackedNorth || getPolarity() == Polarity.StackedSouth;
|
||||
}
|
||||
|
||||
public enum Polarity {
|
||||
North("Single - North"), South("Single - South"), Humbucking("Humbucking - 4 leads");
|
||||
North("Single - North"), South("Single - South"), Humbucking("Humbucking - 4 leads"),
|
||||
StackedNorth("Stacked - North"), StackedSouth("Stacked - South");
|
||||
|
||||
private String label;
|
||||
|
||||
|
||||
+10
-6
@@ -60,8 +60,10 @@ public abstract class AbstractSingleOrHumbuckerPickup extends AbstractGuitarPick
|
||||
break;
|
||||
}
|
||||
|
||||
if (getPolarity() == Polarity.North || getPolarity() == Polarity.South) {
|
||||
StringUtils.drawCenteredText(g2d, getPolarity().name().substring(0, 1), (points[1].getX() + points[2].getX()) / 2 + dx, (points[1].getY() + points[2].getY()) / 2 + dy, HorizontalAlignment.CENTER,
|
||||
if (getPolarity() == Polarity.North || getPolarity() == Polarity.South
|
||||
|| getPolarity() == Polarity.StackedNorth || getPolarity() == Polarity.StackedSouth) {
|
||||
String label = (getPolarity() == Polarity.North || getPolarity() == Polarity.StackedNorth) ? "N" : "S";
|
||||
StringUtils.drawCenteredText(g2d, label, (points[1].getX() + points[2].getX()) / 2 + dx, (points[1].getY() + points[2].getY()) / 2 + dy, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
} else {
|
||||
StringUtils.drawCenteredText(g2d, "N", (points[0].getX() + points[1].getX()) / 2 + dx, (points[0].getY() + points[1].getY()) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
@@ -91,15 +93,15 @@ public abstract class AbstractSingleOrHumbuckerPickup extends AbstractGuitarPick
|
||||
return null;
|
||||
return"North Start";
|
||||
case 1:
|
||||
if (getPolarity() == Polarity.South)
|
||||
if (getPolarity() == Polarity.South || getPolarity() == Polarity.StackedSouth)
|
||||
return "South Start";
|
||||
if (getPolarity() == Polarity.North)
|
||||
if (getPolarity() == Polarity.North || getPolarity() == Polarity.StackedNorth)
|
||||
return "North Start";
|
||||
return "North Finish";
|
||||
case 2:
|
||||
if (getPolarity() == Polarity.South)
|
||||
if (getPolarity() == Polarity.South || getPolarity() == Polarity.StackedSouth)
|
||||
return "South Finish";
|
||||
if (getPolarity() == Polarity.North)
|
||||
if (getPolarity() == Polarity.North || getPolarity() == Polarity.StackedNorth)
|
||||
return "North Finish";
|
||||
return "South Finish";
|
||||
case 3:
|
||||
@@ -125,6 +127,8 @@ public abstract class AbstractSingleOrHumbuckerPickup extends AbstractGuitarPick
|
||||
break;
|
||||
case North:
|
||||
case South:
|
||||
case StackedNorth:
|
||||
case StackedSouth:
|
||||
if (index1 == 1 && index2 == 2)
|
||||
return getPolarity().name() + "->";
|
||||
else if (index1 == 2 && index2 == 1)
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.awt.AlphaComposite;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -105,56 +106,56 @@ public class Image extends AbstractTransparentComponent<Void> {
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
ImageIcon imageIcon = getImage();
|
||||
if (imageIcon == null || imageIcon.getImage() == null || imageIcon.getIconWidth() <= 0
|
||||
|| imageIcon.getIconHeight() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getImageRectangle().intersects(g2d.getClipBounds())) {
|
||||
Shape clip = g2d.getClip();
|
||||
if (clip != null && !clip.intersects(getImageRectangle())) {
|
||||
return;
|
||||
}
|
||||
|
||||
double scaleX;
|
||||
double scaleY;
|
||||
ImageIcon imageIcon = getImage();
|
||||
if (getSizingMode() == ImageSizingMode.Scale) {
|
||||
scaleX = scaleY = 1d * getScale().getValue() / 100d;
|
||||
} else {
|
||||
Point2D secondPoint = getControlPoint(1);
|
||||
scaleX = 1d * Math.abs(point.getX() - secondPoint.getX()) / imageIcon.getIconWidth();
|
||||
scaleY = 1d * Math.abs(point.getY() - secondPoint.getY()) / imageIcon.getIconHeight();
|
||||
}
|
||||
|
||||
Shape clip = g2d.getClip().getBounds();
|
||||
if (!clip.intersects(new Rectangle2D.Double(point.getX(), point.getY(), imageIcon.getIconWidth() * scaleX, imageIcon
|
||||
.getIconHeight() * scaleY))) {
|
||||
return;
|
||||
}
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
|
||||
double x;
|
||||
double y;
|
||||
if (getSizingMode() == ImageSizingMode.Scale)
|
||||
{
|
||||
if (getSizingMode() == ImageSizingMode.Scale) {
|
||||
scaleX = scaleY = 1d * getScale().getValue() / 100d;
|
||||
x = point.getX();
|
||||
y = point.getY();
|
||||
} else {
|
||||
Point2D secondPoint = getControlPoint(1);
|
||||
scaleX = 1d * Math.abs(point.getX() - secondPoint.getX()) / imageIcon.getIconWidth();
|
||||
scaleY = 1d * Math.abs(point.getY() - secondPoint.getY()) / imageIcon.getIconHeight();
|
||||
x = Math.min(point.getX(), secondPoint.getX());
|
||||
y = Math.min(point.getY(), secondPoint.getY());
|
||||
}
|
||||
|
||||
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
AffineTransform oldTx = g2d.getTransform();
|
||||
|
||||
if (getOrientation() != Orientation.DEFAULT) {
|
||||
double theta = getOrientation().toRadians();
|
||||
g2d.rotate(theta, x, y);
|
||||
}
|
||||
|
||||
g2d.scale(scaleX, scaleY);
|
||||
|
||||
g2d.drawImage(imageIcon.getImage(), (int) (x / scaleX), (int) (y / scaleY), null);
|
||||
|
||||
g2d.drawImage(imageIcon.getImage(), (int) Math.round(x / scaleX), (int) Math.round(y / scaleY), null);
|
||||
if (componentState == ComponentState.SELECTED) {
|
||||
g2d.setComposite(oldComposite);
|
||||
g2d.scale(1 / scaleX, 1 / scaleY);
|
||||
g2d.setColor(SELECTION_COLOR);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
|
||||
g2d.drawRect((int)x, (int)y, (int) (imageIcon.getIconWidth() * scaleX), (int) (imageIcon.getIconHeight() * scaleY));
|
||||
g2d.drawRect((int) Math.round(x), (int) Math.round(y),
|
||||
(int) Math.round(imageIcon.getIconWidth() * scaleX),
|
||||
(int) Math.round(imageIcon.getIconHeight() * scaleY));
|
||||
}
|
||||
|
||||
g2d.setTransform(oldTx);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -296,22 +297,34 @@ public class Image extends AbstractTransparentComponent<Void> {
|
||||
protected Point2D getFinalSecondPoint() {
|
||||
Point2D finalSecondPoint;
|
||||
if (getSizingMode() == ImageSizingMode.TwoPoints) {
|
||||
finalSecondPoint = secondPoint;
|
||||
finalSecondPoint = getControlPoint(1);
|
||||
} else {
|
||||
double scale = 1d * getScale().getValue() / 100d;
|
||||
ImageIcon iconImage = getImage();
|
||||
finalSecondPoint = new Point2D.Double(point.getX() + iconImage.getIconWidth() * scale,
|
||||
point.getY() + iconImage.getIconHeight() * scale);
|
||||
double w = (iconImage != null && iconImage.getIconWidth() > 0) ? iconImage.getIconWidth() * scale : 0;
|
||||
double h = (iconImage != null && iconImage.getIconHeight() > 0) ? iconImage.getIconHeight() * scale : 0;
|
||||
finalSecondPoint = new Point2D.Double(point.getX() + w, point.getY() + h);
|
||||
}
|
||||
return finalSecondPoint;
|
||||
}
|
||||
|
||||
protected Rectangle2D getImageRectangle() {
|
||||
Point2D finalSecondPoint = getFinalSecondPoint();
|
||||
return new Rectangle2D.Double(Math.min(point.getX(), finalSecondPoint.getX()),
|
||||
Math.min(point.getY(), finalSecondPoint.getY()),
|
||||
Math.abs(point.getX() - finalSecondPoint.getX()),
|
||||
Math.abs(point.getY() - finalSecondPoint.getY()));
|
||||
double x = Math.min(point.getX(), finalSecondPoint.getX());
|
||||
double y = Math.min(point.getY(), finalSecondPoint.getY());
|
||||
double w = Math.abs(point.getX() - finalSecondPoint.getX());
|
||||
double h = Math.abs(point.getY() - finalSecondPoint.getY());
|
||||
Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
|
||||
if (getOrientation() != null && getOrientation() != Orientation.DEFAULT) {
|
||||
AffineTransform tx = AffineTransform.getRotateInstance(getOrientation().toRadians(), x, y);
|
||||
return tx.createTransformedShape(rect).getBounds2D();
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
return getImageRectangle();
|
||||
}
|
||||
|
||||
public static enum ImageSizingMode {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -89,35 +90,35 @@ public class SVGImage extends AbstractTransparentComponent<Void> {
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
double scaleX;
|
||||
double scaleY;
|
||||
SVGDiagram svgDiagram = getSvgDiagram();
|
||||
if (getSizingMode() == ImageSizingMode.Scale) {
|
||||
scaleX = scaleY = 1d * getScale().getValue() / 100d;
|
||||
} else {
|
||||
Point2D secondPoint = getControlPoint(1);
|
||||
scaleX = 1d * Math.abs(point.getX() - secondPoint.getX()) / svgDiagram.getWidth();
|
||||
scaleY = 1d * Math.abs(point.getY() - secondPoint.getY()) / svgDiagram.getHeight();
|
||||
}
|
||||
|
||||
Shape clip = g2d.getClip().getBounds();
|
||||
if (!clip.intersects(new Rectangle2D.Double(point.getX(), point.getY(),
|
||||
svgDiagram.getWidth() * scaleX, svgDiagram.getHeight() * scaleY))) {
|
||||
if (svgDiagram == null || svgDiagram.getWidth() <= 0 || svgDiagram.getHeight() <= 0) {
|
||||
return;
|
||||
}
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
|
||||
Shape clip = g2d.getClip();
|
||||
if (clip != null && !clip.intersects(getImageRectangle())) {
|
||||
return;
|
||||
}
|
||||
|
||||
double scaleX;
|
||||
double scaleY;
|
||||
double x;
|
||||
double y;
|
||||
if (getSizingMode() == ImageSizingMode.Scale) {
|
||||
scaleX = scaleY = 1d * getScale().getValue() / 100d;
|
||||
x = point.getX();
|
||||
y = point.getY();
|
||||
} else {
|
||||
Point2D secondPoint = getControlPoint(1);
|
||||
scaleX = 1d * Math.abs(point.getX() - secondPoint.getX()) / svgDiagram.getWidth();
|
||||
scaleY = 1d * Math.abs(point.getY() - secondPoint.getY()) / svgDiagram.getHeight();
|
||||
x = Math.min(point.getX(), secondPoint.getX());
|
||||
y = Math.min(point.getY(), secondPoint.getY());
|
||||
}
|
||||
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
AffineTransform oldTx = g2d.getTransform();
|
||||
|
||||
if (getOrientation() != Orientation.DEFAULT) {
|
||||
double theta = getOrientation().toRadians();
|
||||
g2d.rotate(theta, x, y);
|
||||
@@ -139,9 +140,13 @@ public class SVGImage extends AbstractTransparentComponent<Void> {
|
||||
g2d.scale(1 / scaleX, 1 / scaleY);
|
||||
g2d.setColor(SELECTION_COLOR);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
|
||||
g2d.drawRect((int) x, (int) y, (int) (svgDiagram.getWidth() * scaleX),
|
||||
(int) (svgDiagram.getHeight() * scaleY));
|
||||
g2d.drawRect((int) Math.round(x), (int) Math.round(y),
|
||||
(int) Math.round(svgDiagram.getWidth() * scaleX),
|
||||
(int) Math.round(svgDiagram.getHeight() * scaleY));
|
||||
}
|
||||
|
||||
g2d.setTransform(oldTx);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -280,6 +285,39 @@ public class SVGImage extends AbstractTransparentComponent<Void> {
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
protected Point2D getFinalSecondPoint() {
|
||||
Point2D finalSecondPoint;
|
||||
if (getSizingMode() == ImageSizingMode.TwoPoints) {
|
||||
finalSecondPoint = getControlPoint(1);
|
||||
} else {
|
||||
double scale = 1d * getScale().getValue() / 100d;
|
||||
SVGDiagram diagram = getSvgDiagram();
|
||||
double w = (diagram != null && diagram.getWidth() > 0) ? diagram.getWidth() * scale : 0;
|
||||
double h = (diagram != null && diagram.getHeight() > 0) ? diagram.getHeight() * scale : 0;
|
||||
finalSecondPoint = new Point2D.Double(point.getX() + w, point.getY() + h);
|
||||
}
|
||||
return finalSecondPoint;
|
||||
}
|
||||
|
||||
protected Rectangle2D getImageRectangle() {
|
||||
Point2D finalSecondPoint = getFinalSecondPoint();
|
||||
double x = Math.min(point.getX(), finalSecondPoint.getX());
|
||||
double y = Math.min(point.getY(), finalSecondPoint.getY());
|
||||
double w = Math.abs(point.getX() - finalSecondPoint.getX());
|
||||
double h = Math.abs(point.getY() - finalSecondPoint.getY());
|
||||
Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
|
||||
if (getOrientation() != null && getOrientation() != Orientation.DEFAULT) {
|
||||
AffineTransform tx = AffineTransform.getRotateInstance(getOrientation().toRadians(), x, y);
|
||||
return tx.createTransformedShape(rect).getBounds2D();
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
return getImageRectangle();
|
||||
}
|
||||
|
||||
public static enum ImageSizingMode {
|
||||
TwoPoints("Opposing Points"), Scale("Scale");
|
||||
|
||||
|
||||
@@ -182,20 +182,25 @@ public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements IN
|
||||
|
||||
@Override
|
||||
public void visit(TreeLeaf l) {
|
||||
if ((l.toString().toLowerCase().contains("north")
|
||||
&& (l.toString().toLowerCase().contains("->")))
|
||||
|| (l.toString().toLowerCase().contains("south")
|
||||
&& (l.toString().toLowerCase().contains("<-"))))
|
||||
noiseCount++;
|
||||
if ((l.toString().toLowerCase().contains("north")
|
||||
&& (l.toString().toLowerCase().contains("<-")))
|
||||
|| (l.toString().toLowerCase().contains("south")
|
||||
&& (l.toString().toLowerCase().contains("->"))))
|
||||
noiseCount--;
|
||||
String s = l.toString().toLowerCase();
|
||||
boolean isStacked = s.contains("stacked");
|
||||
|
||||
if (l.toString().toLowerCase().contains("->"))
|
||||
if (!isStacked) {
|
||||
if ((s.contains("north")
|
||||
&& (s.contains("->")))
|
||||
|| (s.contains("south")
|
||||
&& (s.contains("<-"))))
|
||||
noiseCount++;
|
||||
if ((s.contains("north")
|
||||
&& (s.contains("<-")))
|
||||
|| (s.contains("south")
|
||||
&& (s.contains("->"))))
|
||||
noiseCount--;
|
||||
}
|
||||
|
||||
if (s.contains("->"))
|
||||
positiveCount++;
|
||||
if (l.toString().toLowerCase().contains("<-"))
|
||||
if (s.contains("<-"))
|
||||
negativeCount++;
|
||||
}
|
||||
});
|
||||
@@ -224,8 +229,9 @@ public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements IN
|
||||
} else {
|
||||
TreeLeaf leaf = new TreeLeaf(pickup, 1, 2);
|
||||
Tree t = tree.locate(leaf, false);
|
||||
if (t != null)
|
||||
if (t != null) {
|
||||
pickupRoots.put(pickup, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
package org.diylc.components.misc;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.Percentage;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ImageTest {
|
||||
|
||||
private static final IDrawingObserver NOOP_OBSERVER = new IDrawingObserver() {
|
||||
@Override public void startTracking() {}
|
||||
@Override public void stopTracking() {}
|
||||
@Override public void startTrackingContinuityArea(boolean positive) {}
|
||||
@Override public void stopTrackingContinuityArea() {}
|
||||
@Override public boolean isTrackingContinuityArea() { return false; }
|
||||
@Override public void setContinuityMarker(String marker) {}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testImageRectangleScaleModeDefaultOrientation() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(100, 200), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(100.0, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(200.0, bounds.getY(), 0.01);
|
||||
Assert.assertEquals((double) w, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals((double) h, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageRectangleScaleMode50Percent() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(100, 200), 0);
|
||||
image.setScale(new Percentage(50));
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(100.0, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(200.0, bounds.getY(), 0.01);
|
||||
Assert.assertEquals(w * 0.5, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals(h * 0.5, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageRectangleRotated180() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(500, 500), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
image.setOrientation(Orientation._180);
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(500.0 - w, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(500.0 - h, bounds.getY(), 0.01);
|
||||
Assert.assertEquals((double) w, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals((double) h, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageRectangleRotated90() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(500, 500), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
image.setOrientation(Orientation._90);
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(500.0 - h, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(500.0, bounds.getY(), 0.01);
|
||||
Assert.assertEquals((double) h, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals((double) w, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageRectangleRotated270() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(500, 500), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
image.setOrientation(Orientation._270);
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(500.0, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(500.0 - w, bounds.getY(), 0.01);
|
||||
Assert.assertEquals((double) h, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals((double) w, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageRectangleTwoPointsMode() {
|
||||
Image image = new Image();
|
||||
image.setSizingMode(Image.ImageSizingMode.TwoPoints);
|
||||
image.setControlPoint(new Point2D.Double(400, 500), 0);
|
||||
image.setControlPoint(new Point2D.Double(100, 200), 1);
|
||||
|
||||
Rectangle2D bounds = image.getImageRectangle();
|
||||
Assert.assertEquals(100.0, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(200.0, bounds.getY(), 0.01);
|
||||
Assert.assertEquals(300.0, bounds.getWidth(), 0.01);
|
||||
Assert.assertEquals(300.0, bounds.getHeight(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDrawWithNullClipDoesNotThrow() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(50, 50), 0);
|
||||
|
||||
BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
g2d.setClip(null);
|
||||
|
||||
// Should not throw NPE
|
||||
image.draw(g2d, ComponentState.NORMAL, false, new Project(), NOOP_OBSERVER);
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDrawRotatedImageRendersWhenRotatedIntoClip() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(100, 100), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
image.setOrientation(Orientation._180);
|
||||
|
||||
ImageIcon icon = image.getImage();
|
||||
int w = icon.getIconWidth();
|
||||
int h = icon.getIconHeight();
|
||||
|
||||
// The image at (100, 100) rotated 180 extends to (100 - w, 100 - h).
|
||||
// The unrotated rectangle would be (100, 100, w, h).
|
||||
// Clip at (0, 0, 100, 100) overlaps the rotated image, but NOT the unrotated rect.
|
||||
BufferedImage target = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = target.createGraphics();
|
||||
g2d.setClip(new Rectangle(0, 0, 100, 100));
|
||||
|
||||
// Must not skip rendering
|
||||
image.draw(g2d, ComponentState.NORMAL, false, new Project(), NOOP_OBSERVER);
|
||||
g2d.dispose();
|
||||
|
||||
// Verify some pixels were drawn in the (0, 0, 100, 100) region
|
||||
boolean hasNonZeroPixel = false;
|
||||
for (int x = 0; x < 100; x++) {
|
||||
for (int y = 0; y < 100; y++) {
|
||||
if ((target.getRGB(x, y) & 0xFF000000) != 0) {
|
||||
hasNonZeroPixel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasNonZeroPixel) break;
|
||||
}
|
||||
Assert.assertTrue("Rotated image should have rendered pixels in the clip region", hasNonZeroPixel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDrawSkipsWhenCompletelyOutsideClip() {
|
||||
Image image = new Image();
|
||||
image.setControlPoint(new Point2D.Double(500, 500), 0);
|
||||
image.setScale(new Percentage(100));
|
||||
|
||||
BufferedImage target = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = target.createGraphics();
|
||||
g2d.setClip(new Rectangle(0, 0, 100, 100));
|
||||
|
||||
image.draw(g2d, ComponentState.NORMAL, false, new Project(), NOOP_OBSERVER);
|
||||
g2d.dispose();
|
||||
|
||||
// Target image should remain completely blank
|
||||
for (int x = 0; x < 100; x++) {
|
||||
for (int y = 0; y < 100; y++) {
|
||||
Assert.assertEquals(0, target.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.diylc.components.misc;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.Percentage;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SVGImageTest {
|
||||
|
||||
private static final IDrawingObserver NOOP_OBSERVER = new IDrawingObserver() {
|
||||
@Override public void startTracking() {}
|
||||
@Override public void stopTracking() {}
|
||||
@Override public void startTrackingContinuityArea(boolean positive) {}
|
||||
@Override public void stopTrackingContinuityArea() {}
|
||||
@Override public boolean isTrackingContinuityArea() { return false; }
|
||||
@Override public void setContinuityMarker(String marker) {}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testSVGImageRectangleScaleMode() {
|
||||
SVGImage svg = new SVGImage();
|
||||
svg.setControlPoint(new Point2D.Double(100, 200), 0);
|
||||
svg.setScale(new Percentage(100));
|
||||
|
||||
Rectangle2D bounds = svg.getImageRectangle();
|
||||
Assert.assertEquals(100.0, bounds.getX(), 0.01);
|
||||
Assert.assertEquals(200.0, bounds.getY(), 0.01);
|
||||
Assert.assertTrue(bounds.getWidth() > 0);
|
||||
Assert.assertTrue(bounds.getHeight() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSVGImageDrawWithNullClipDoesNotThrow() {
|
||||
SVGImage svg = new SVGImage();
|
||||
svg.setControlPoint(new Point2D.Double(50, 50), 0);
|
||||
|
||||
BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
g2d.setClip(null);
|
||||
|
||||
svg.draw(g2d, ComponentState.NORMAL, false, new Project(), NOOP_OBSERVER);
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSVGImageRotated180Clipping() {
|
||||
SVGImage svg = new SVGImage();
|
||||
svg.setControlPoint(new Point2D.Double(100, 100), 0);
|
||||
svg.setScale(new Percentage(100));
|
||||
svg.setOrientation(Orientation._180);
|
||||
|
||||
Rectangle2D bounds = svg.getImageRectangle();
|
||||
Assert.assertTrue(bounds.getX() < 100.0);
|
||||
Assert.assertTrue(bounds.getY() < 100.0);
|
||||
|
||||
BufferedImage target = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = target.createGraphics();
|
||||
g2d.setClip(new Rectangle(0, 0, 100, 100));
|
||||
|
||||
svg.draw(g2d, ComponentState.NORMAL, false, new Project(), NOOP_OBSERVER);
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,16 @@
|
||||
package org.diylc.netlist;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.components.passive.AxialFilmCapacitor;
|
||||
import org.diylc.components.passive.Resistor;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.diylc.components.electromechanical.OpenJack1_4;
|
||||
import org.diylc.components.guitar.AbstractGuitarPickup.Polarity;
|
||||
import org.diylc.components.guitar.HumbuckerPickup;
|
||||
import org.diylc.components.guitar.SingleCoilPickup;
|
||||
import org.diylc.components.passive.PotentiometerPanel;
|
||||
@@ -328,4 +331,155 @@ public class GuitarDiagramAnalyzerTests {
|
||||
"((Volume.3-2 + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-1 + Cap1) || (Tone2.2-1 + Cap2))) || Volume.2-1)",
|
||||
s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStackedNorthPickup() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup = new SingleCoilPickup();
|
||||
pickup.setName("Pickup");
|
||||
pickup.setPolarity(Polarity.StackedNorth);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("Pickup.StackedNorth<-", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
assertTrue(notes.contains("'Pickup' is the only engaged pickup"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStackedSouthPickup() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup = new SingleCoilPickup();
|
||||
pickup.setName("Pickup");
|
||||
pickup.setPolarity(Polarity.StackedSouth);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("Pickup.StackedSouth<-", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStackedPickupReverse() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup = new SingleCoilPickup();
|
||||
pickup.setName("Pickup");
|
||||
pickup.setPolarity(Polarity.StackedNorth);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup, 2);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("Pickup.StackedNorth->", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoStackedPickupsParallel() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup1 = new SingleCoilPickup();
|
||||
pickup1.setName("Pickup1");
|
||||
pickup1.setPolarity(Polarity.StackedNorth);
|
||||
SingleCoilPickup pickup2 = new SingleCoilPickup();
|
||||
pickup2.setName("Pickup2");
|
||||
pickup2.setPolarity(Polarity.StackedSouth);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 1).connect(pickup2, 1);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("(Pickup1.StackedNorth<- || Pickup2.StackedSouth<-)", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
assertTrue(notes.contains("All pickup coils are wired in-phase"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoStackedPickupsParallelOutOfPhase() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup1 = new SingleCoilPickup();
|
||||
pickup1.setName("Pickup1");
|
||||
pickup1.setPolarity(Polarity.StackedNorth);
|
||||
SingleCoilPickup pickup2 = new SingleCoilPickup();
|
||||
pickup2.setName("Pickup2");
|
||||
pickup2.setPolarity(Polarity.StackedSouth);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 1).connect(pickup2, 2);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 1);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("(Pickup1.StackedNorth<- || Pickup2.StackedSouth->)", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
assertTrue(notes.contains("Some pickup coils are wired OUT-of-phase"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackedPickupAndSingleCoilParallel() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup1 = new SingleCoilPickup();
|
||||
pickup1.setName("Pickup1");
|
||||
pickup1.setPolarity(Polarity.StackedNorth);
|
||||
SingleCoilPickup pickup2 = new SingleCoilPickup();
|
||||
pickup2.setName("Pickup2");
|
||||
pickup2.setPolarity(Polarity.North);
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 1).connect(pickup2, 1);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2);
|
||||
netlist.add(tipGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("(Pickup1.StackedNorth<- || Pickup2.North<-)", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("This configuration is NOT hum-cancelling"));
|
||||
assertTrue(notes.contains("All pickup coils are wired in-phase"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackedPickupAndHumbuckerParallel() throws TreeException {
|
||||
OpenJack1_4 jack = new OpenJack1_4();
|
||||
SingleCoilPickup pickup1 = new SingleCoilPickup();
|
||||
pickup1.setName("Pickup1");
|
||||
pickup1.setPolarity(Polarity.StackedNorth);
|
||||
HumbuckerPickup pickup2 = new HumbuckerPickup();
|
||||
pickup2.setName("Pickup2");
|
||||
Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
|
||||
Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 1).connect(pickup2, 0);
|
||||
Group coilTapGroup = new Group().connect(pickup2, 1).connect(pickup2, 2);
|
||||
Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 3);
|
||||
netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup);
|
||||
GuitarDiagramAnalyzer analyzer = new GuitarDiagramAnalyzer();
|
||||
Tree tree = analyzer.constructTree(netlist);
|
||||
String s = tree.toString();
|
||||
assertEquals("((Pickup2.North<- + Pickup2.South<-) || Pickup1.StackedNorth<-)", s);
|
||||
|
||||
List<String> notes = analyzer.collectNotes(netlist);
|
||||
assertTrue(notes.contains("'Pickup2' pickup wired in humbucking mode with series coils"));
|
||||
assertTrue(notes.contains("This configuration is hum-cancelling"));
|
||||
assertTrue(notes.contains("All pickup coils are wired in-phase"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user