'Solder Pad' on the top layer put its solder mask opening on the bottom layer in Gerber export

This commit is contained in:
Bane Stojkovic
2026-11-11 15:15:10 +01:00
parent b76d315f44
commit 16f54fa479
3 changed files with 79 additions and 3 deletions
@@ -645,6 +645,10 @@
<changeType>BUG_FIX</changeType>
<description>'Highlight Connected Areas', netlists and AI analysis could ignore trace cuts after the board under them was moved or edited, or when the cuts were scrolled out of view, and showed the whole strip as connected</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>BUG_FIX</changeType>
<description>'Solder Pad' on the top layer put its solder mask opening on the bottom layer in Gerber export</description>
</org.diylc.appframework.update.Change>
</changes>
<url>https://github.com/bancika/diy-layout-creator/releases</url>
</org.diylc.appframework.update.Version>
@@ -92,9 +92,12 @@ public class SolderPad extends AbstractTransparentComponent<Void>
: color);
drawingObserver.startTrackingContinuityArea(true);
GerberLayer gerberCopperLayer = this.getLayer().toGerberCopperLayer();
// the mask is opened on the side the pad is on
GerberLayer gerberMaskLayer = gerberCopperLayer == GerberLayer.CopperTop
? GerberLayer.SolderMaskTop : GerberLayer.SolderMaskBot;
if (gerberDrawingObserver != null) {
gerberDrawingObserver.startGerberOutput(gerberCopperLayer, GerberFunctions.CONNECTOR_PAD, false);
gerberDrawingObserver.startGerberOutput(org.diylc.core.gerber.GerberLayer.SolderMaskBot, "Material", false);
gerberDrawingObserver.startGerberOutput(gerberMaskLayer, "Material", false);
}
Composite oldComposite = applyAlpha(g2d, componentState);
drawingObserver.startDrawingSide(getLayer());
@@ -115,8 +118,9 @@ public class SolderPad extends AbstractTransparentComponent<Void>
drawingObserver.stopDrawingSide();
drawingObserver.stopTracking();
drawingObserver.stopTrackingContinuityArea();
if (gerberDrawingObserver != null)
gerberDrawingObserver.stopGerberOutput(org.diylc.core.gerber.GerberLayer.SolderMaskBot);
if (gerberDrawingObserver != null) {
gerberDrawingObserver.stopGerberOutput(gerberMaskLayer);
}
if (getHoleSize().getValue() > 0 && !HoleType.NONE.equals(getHoleType())) {
if (gerberDrawingObserver != null) {
gerberDrawingObserver.setGerberNegative(gerberCopperLayer, true);
@@ -0,0 +1,68 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2025 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 <http://www.gnu.org/licenses/>.
*/
package org.diylc.components.connectivity;
import static org.junit.Assert.assertTrue;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Set;
import org.diylc.common.PCBLayer;
import org.diylc.core.ComponentState;
import org.diylc.core.Project;
import org.diylc.core.gerber.GerberG2DWrapper;
import org.diylc.core.gerber.GerberLayer;
import org.junit.Test;
public class SolderPadGerberTest {
@Test
public void testTopPadOpensTopMask() {
Set<GerberLayer> layers = drawGerber(PCBLayer._2);
assertTrue(layers.contains(GerberLayer.CopperTop));
assertTrue(layers.contains(GerberLayer.SolderMaskTop));
assertTrue(!layers.contains(GerberLayer.SolderMaskBot));
}
@Test
public void testBottomPadOpensBottomMask() {
Set<GerberLayer> layers = drawGerber(PCBLayer._1);
assertTrue(layers.contains(GerberLayer.CopperBot));
assertTrue(layers.contains(GerberLayer.SolderMaskBot));
assertTrue(!layers.contains(GerberLayer.SolderMaskTop));
}
private static Set<GerberLayer> drawGerber(PCBLayer layer) {
SolderPad pad = new SolderPad();
pad.setLayer(layer);
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();
GerberG2DWrapper g2d =
new GerberG2DWrapper(graphics, "test", new Rectangle2D.Double(-50, -50, 100, 100));
g2d.startedDrawingComponent();
pad.draw(g2d, ComponentState.NORMAL, false, new Project(), g2d, g2d);
graphics.dispose();
return g2d.getLayerMap().keySet();
}
}