mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 10:42:09 +10:00
Parts placed on the bottom of the board are drawn faded on the canvas and solid in the Underside Display mirror
This commit is contained in:
@@ -153,12 +153,16 @@ public class DrawingCache {
|
||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||
g2d.getCanvasGraphics().scale(1 / zoom, 1 / zoom);
|
||||
}
|
||||
// the image was rendered with the far-side fade already applied, so pasting it must not
|
||||
// fade it again
|
||||
g2d.startDrawingBothSides();
|
||||
try {
|
||||
// draw cached image
|
||||
g2d.scale(1 / scaleFactor, 1 / scaleFactor);
|
||||
g2d.getCanvasGraphics().drawImage(value.getImage(), (int) ((firstPoint.getX() - value.getDx()) * zoom * scaleFactor),
|
||||
(int) ((firstPoint.getY() - value.getDy())* zoom * scaleFactor), null);
|
||||
} finally {
|
||||
g2d.stopDrawingSide();
|
||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||
g2d.getCanvasGraphics().scale(zoom, zoom);
|
||||
}
|
||||
@@ -347,6 +351,7 @@ public class DrawingCache {
|
||||
|
||||
// initialize wrapper
|
||||
wrapper.startedDrawingComponent(zOrder);
|
||||
wrapper.setUndeclaredSide(DrawingManager.getMountedSide(component));
|
||||
|
||||
long componentStart = System.nanoTime();
|
||||
|
||||
|
||||
@@ -303,6 +303,8 @@ public class DrawingManager {
|
||||
if (lockedComponents.contains(component) && drawOptions.contains(DrawOption.LOCKED_ALPHA)) {
|
||||
g2d.setComposite(lockedComposite);
|
||||
}
|
||||
// after the locked composite, which is set on the canvas and would replace the fade
|
||||
g2dWrapper.setUndeclaredSide(getMountedSide(component));
|
||||
// Draw the component through the g2dWrapper.
|
||||
long componentStart = System.nanoTime();
|
||||
try {
|
||||
@@ -334,6 +336,7 @@ public class DrawingManager {
|
||||
}
|
||||
}
|
||||
ComponentArea area = g2dWrapper.finishedDrawingComponent();
|
||||
g2dWrapper.setUndeclaredSide(PCBLayer._2);
|
||||
// after finishedDrawingComponent, which reverts the transform the clip was taken in
|
||||
if (visibleClip != null) {
|
||||
g2d.setClip(visibleClip);
|
||||
@@ -527,6 +530,15 @@ public class DrawingManager {
|
||||
return failedComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the side of the board the component is mounted on; components that do not say are
|
||||
* on top
|
||||
*/
|
||||
static PCBLayer getMountedSide(IDIYComponent<?> component) {
|
||||
return component instanceof IBoardSideComponent
|
||||
? ((IBoardSideComponent) component).getBoardSide() : PCBLayer._2;
|
||||
}
|
||||
|
||||
private static void drawSelectedControlPoint(G2DWrapper g2dWrapper, Point2D controlPoint) {
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval((int) Math.round(controlPoint.getX() - CONTROL_POINT_SIZE / 2),
|
||||
@@ -565,9 +577,10 @@ public class DrawingManager {
|
||||
g2dWrapper.setMirrorDirection(mirrorDirection);
|
||||
try {
|
||||
g2dWrapper.transform(mirrorTx);
|
||||
// the mirror is the copper side, so copper is drawn solid and the component side faded
|
||||
// the mirror is the copper side, so copper and the parts mounted on it are drawn solid and
|
||||
// the component side faded
|
||||
g2dWrapper.setViewedSide(PCBLayer._1, Boolean.TRUE.equals(board.getUndersideTransparency()),
|
||||
component instanceof IBoard ? PCBLayer._1 : PCBLayer._2);
|
||||
component instanceof IBoard ? PCBLayer._1 : getMountedSide(component));
|
||||
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing mirrored " + component.getName(), e);
|
||||
|
||||
@@ -186,6 +186,19 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
updateFarSideFade();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the side assumed for paint that is not bracketed with
|
||||
* {@link #startDrawingSide(PCBLayer)}, keeping the viewed side. A part mounted on the bottom of
|
||||
* the board is drawn on the bottom side as a whole.
|
||||
*
|
||||
* @param undeclaredSide
|
||||
*/
|
||||
public void setUndeclaredSide(PCBLayer undeclaredSide) {
|
||||
this.undeclaredSide = undeclaredSide;
|
||||
this.paintedSide = undeclaredSide;
|
||||
updateFarSideFade();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns to the top-side view, fading the bottom side only if the draw options ask for it.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.diylc.common.PCBLayer;
|
||||
import org.diylc.core.BoardUndersideDisplay;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IBoard;
|
||||
import org.diylc.core.IBoardSideComponent;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
@@ -683,6 +684,66 @@ public class DrawingManagerTest {
|
||||
assertSolid(img, 155, 665);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBottomMountedPartFadedOnlyWithOption() {
|
||||
Project project = new Project();
|
||||
project.getComponents().add(new MountedComponent(new Rectangle2D.Double(150, 150, 10, 10), PCBLayer._2));
|
||||
project.getComponents().add(new MountedComponent(new Rectangle2D.Double(200, 200, 10, 10), PCBLayer._1));
|
||||
|
||||
BufferedImage faded = renderSides(project, EnumSet.of(DrawOption.ZOOM, DrawOption.FADE_FAR_SIDE));
|
||||
assertSolid(faded, 155, 155);
|
||||
assertFaded(faded, 205, 205);
|
||||
|
||||
BufferedImage plain = renderSides(project, EnumSet.of(DrawOption.ZOOM));
|
||||
assertSolid(plain, 205, 205);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCachedBottomMountedPartFaded() {
|
||||
Project project = new Project();
|
||||
project.getComponents().add(new MountedComponent(new Rectangle2D.Double(200, 200, 10, 10), PCBLayer._1));
|
||||
|
||||
BufferedImage img = renderSides(project,
|
||||
EnumSet.of(DrawOption.ZOOM, DrawOption.FADE_FAR_SIDE, DrawOption.ENABLE_CACHING));
|
||||
assertFaded(img, 205, 205);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMirrorShowsBottomMountedPartSolid() {
|
||||
Project project = new Project();
|
||||
MockBoard board = new MockBoard();
|
||||
board.setBoardRectangle(new Rectangle2D.Double(100, 100, 200, 300));
|
||||
board.setUndersideDisplay(BoardUndersideDisplay.BELOW);
|
||||
board.setUndersideOffset(new Size(20.0, SizeUnit.px));
|
||||
board.setUndersideTransparency(true);
|
||||
project.getComponents().add(board);
|
||||
project.getComponents().add(new MountedComponent(new Rectangle2D.Double(150, 150, 10, 10), PCBLayer._2));
|
||||
project.getComponents().add(new MountedComponent(new Rectangle2D.Double(200, 200, 10, 10), PCBLayer._1));
|
||||
|
||||
// reflection across y = 410 puts the top part at y 660..670 and the bottom one at 610..620
|
||||
BufferedImage img = renderSides(project, EnumSet.of(DrawOption.ZOOM, DrawOption.FADE_FAR_SIDE));
|
||||
assertFaded(img, 155, 665);
|
||||
assertSolid(img, 205, 615);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockedBottomMountedPartNotFadedTwice() {
|
||||
Project project = new Project();
|
||||
MountedComponent bottom = new MountedComponent(new Rectangle2D.Double(200, 200, 10, 10), PCBLayer._1);
|
||||
project.getComponents().add(bottom);
|
||||
|
||||
DrawingManager drawingManager = createDrawingManager();
|
||||
BufferedImage img = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
drawingManager.drawProject(g2d, project,
|
||||
EnumSet.of(DrawOption.ZOOM, DrawOption.FADE_FAR_SIDE, DrawOption.LOCKED_ALPHA), null, null,
|
||||
Collections.emptyList(), Collections.singleton(bottom), Collections.emptySet(), null, null,
|
||||
false, Collections.emptySet(), 1.0, 1.0, null);
|
||||
g2d.dispose();
|
||||
|
||||
assertFaded(img, 205, 205, Math.min(0.5f, farSideAlpha()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockedBottomSideNotFadedTwice() {
|
||||
Project project = new Project();
|
||||
@@ -990,6 +1051,34 @@ public class DrawingManagerTest {
|
||||
}
|
||||
|
||||
// paints an opaque black square, declared on the given side or, when null, left undeclared
|
||||
// paints an undeclared black square, like a part that leaves its side to the Board Side property
|
||||
@ComponentDescriptor(name = "Mounted", author = "test", category = "Test", instanceNamePrefix = "M",
|
||||
description = "Part mounted on one side of the board", zOrder = IDIYComponent.COMPONENT,
|
||||
enableCache = true)
|
||||
public static class MountedComponent extends SidePaintingComponent implements IBoardSideComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Rectangle2D bounds;
|
||||
private PCBLayer boardSide;
|
||||
|
||||
public MountedComponent(Rectangle2D shape, PCBLayer boardSide) {
|
||||
super(shape, null);
|
||||
this.bounds = shape;
|
||||
this.boardSide = boardSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PCBLayer getBoardSide() {
|
||||
return boardSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
return bounds;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SidePaintingComponent extends MockDIYComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
Reference in New Issue
Block a user