Compare commits

...

1 Commits

Author SHA1 Message Date
Bane Stojkovic 15354ebff8 mirror 2025-03-09 21:11:27 +01:00
13 changed files with 306 additions and 527 deletions
@@ -0,0 +1,10 @@
package org.diylc.core;
public enum BoardUndersideDisplay {
NONE, ABOVE, BELOW, LEFT, RIGHT;
@Override
public String toString() {
return super.toString().charAt(0) + super.toString().substring(1).toLowerCase();
}
}
@@ -0,0 +1,12 @@
package org.diylc.core;
import java.awt.geom.Rectangle2D;
public interface IBoard {
Rectangle2D getBoardRectangle();
BoardUndersideDisplay getBoardUndersideDisplay();
boolean shouldExportToGerber();
}
@@ -14,6 +14,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoard;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IView;
import org.diylc.core.Project;
@@ -29,12 +30,15 @@ public class GerberExporter {
public static void exportGerber(String fileNameBase, Project currentProject, IView view,
Graphics2D graphics2d, String diylcVersion) {
List<IGerberBoard> gerberBoards =
currentProject.getComponents().stream().filter(c -> c instanceof IGerberBoard)
.map(x -> (IGerberBoard) x).collect(Collectors.toList());
List<IBoard> gerberBoards =
currentProject.getComponents().stream()
.filter(IBoard.class::isInstance)
.map(IBoard.class::cast)
.filter(IBoard::shouldExportToGerber).collect(Collectors.toList());
Map<IGerberBoard, List<IDIYComponent<?>>> boardComponentMap =
new HashMap<IGerberBoard, List<IDIYComponent<?>>>();
Map<IBoard, List<IDIYComponent<?>>> boardComponentMap =
new HashMap<IBoard, List<IDIYComponent<?>>>();
// DefaultGerberBoard defaultGerberBoard = new DefaultGerberBoard();
@@ -43,7 +47,7 @@ public class GerberExporter {
currentProject.getComponents().stream().filter(c -> c instanceof IGerberComponent)
.forEach(c -> {
Point2D firstPoint = c.getControlPoint(0);
IGerberBoard board = gerberBoards.stream()
IBoard board = gerberBoards.stream()
.filter(b -> b.getBoardRectangle().contains(firstPoint)).findFirst().orElse(null);
if (board == null) {
componentsWithoutBoard.add(c);
@@ -174,7 +174,6 @@ public class GerberG2DWrapper extends Graphics2D
if (str == null || str.trim().isEmpty()) {
return;
}
GlyphVector gv = font.createGlyphVector(graphics2d.getFontRenderContext(), str);
@@ -1,8 +0,0 @@
package org.diylc.core.gerber;
import java.awt.geom.Rectangle2D;
public interface IGerberBoard {
Rectangle2D getBoardRectangle();
}
@@ -54,8 +54,11 @@ import org.diylc.common.GridType;
import org.diylc.common.IComponentFilter;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.BoardUndersideDisplay;
import org.diylc.core.ComponentForRender;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoard;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.ILayeredComponent;
@@ -81,7 +84,7 @@ public class DrawingManager {
public static int CONTROL_POINT_SIZE = 7;
public static double EXTRA_SPACE = 0.25;
public static final String ZOOM_KEY = "zoom";
public static final String ZOOM_KEY = "zoom";
private static boolean SHADE_EXTRA_SPACE = true;
@@ -90,6 +93,9 @@ public class DrawingManager {
public static Color CONTROL_POINT_COLOR = Color.blue;
public static Color SELECTED_CONTROL_POINT_COLOR = Color.green;
public static Size BOARD_MIRROR_SPACING = new Size(0.1, SizeUnit.in);
private static final Byte MIRRORED_ALPHA = 64;
private Theme theme;
@@ -170,12 +176,14 @@ public class DrawingManager {
* @param visibleRect
* @return
*/
@SuppressWarnings("unlikely-arg-type")
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
Set<DrawOption> drawOptions, IComponentFilter filter, Rectangle selectionRect,
Collection<IDIYComponent<?>> selectedComponents, Set<IDIYComponent<?>> lockedComponents,
Set<IDIYComponent<?>> groupedComponents, List<Point2D> controlPointSlot,
List<IDIYComponent<?>> componentSlot, boolean dragInProgress, Double externalZoom,
Double scaleFactor, Rectangle2D visibleRect) {
long totalStartTime = System.nanoTime();
failedComponents.clear();
if (project == null) {
@@ -194,38 +202,35 @@ public class DrawingManager {
G2DWrapper g2dWrapper = new G2DWrapper(g2d, zoom);
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
} else {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
configureG2D(g2d, drawOptions);
// group components with boards that contain them
Map<IBoard, List<IDIYComponent<?>>> boardMap = project.getComponents().stream()
.filter(IBoard.class::isInstance)
.map(IBoard.class::cast)
.filter(b -> b.getBoardUndersideDisplay() != BoardUndersideDisplay.NONE)
.collect(Collectors.toMap(x -> x, x -> new ArrayList<IDIYComponent<?>>()));
Map<IDIYComponent<?>, List<IBoard>> componentBoardMap = new HashMap<IDIYComponent<?>, List<IBoard>>();
for (IBoard board : boardMap.keySet()) {
Rectangle2D boardRect = board.getBoardRectangle();
for (IDIYComponent<?> c : project.getComponents()) {
if (c == board) {
continue;
}
boolean include = true;
for (int i = 0; i < c.getControlPointCount(); i++) {
if (!boardRect.contains(c.getControlPoint(i))) {
include = false;
break;
}
}
if (include) {
boardMap.get(board).add(c);
componentBoardMap.computeIfAbsent(c, key -> new ArrayList<IBoard>()).add(board);
}
}
}
if (configManager.readBoolean(IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
// RenderingHints.VALUE_STROKE_PURE);
} else {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
// AffineTransform initialTx = g2d.getTransform();
Dimension canvasDimension =
@@ -291,6 +296,7 @@ public class DrawingManager {
if (filter != null && !filter.testComponent(component)) {
continue;
}
ComponentState state = componentStateMap.get(component);
// Do not track the area if component is not invalidated and was
// drawn in the same state.
@@ -311,15 +317,21 @@ public class DrawingManager {
long componentStart = System.nanoTime();
try {
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache
DrawingCache.Instance.draw(component, g2dWrapper, state,
drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, scaleFactor, i, visibleRect);
else // go straight to the wrapper
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
if (g2dWrapper.isTrackingContinuityArea()) {
LOG.info("Component " + component.getName() + " of type "
+ component.getClass().getName() + " did not stop tracking continuity area.");
drawComponent(project, drawOptions, scaleFactor, visibleRect, zoom, g2dWrapper,
outlineMode, i, component, state);
double boardMirrorSpacing = BOARD_MIRROR_SPACING.convertToPixels();
List<IBoard> boards = componentBoardMap.get(component);
if (boards != null) {
for (IBoard board : boards) {
drawMirroredComponent(project, drawOptions, scaleFactor, visibleRect, zoom,
g2dWrapper, outlineMode, i, state, boardMirrorSpacing, component, board);
}
}
if (boardMap.keySet().contains(component)) {
drawMirroredComponent(project, drawOptions, scaleFactor, visibleRect, zoom,
g2dWrapper, outlineMode, i, state, boardMirrorSpacing, component, (IBoard)component);
}
} catch (Exception e) {
LOG.error("Error drawing " + component.getName(), e);
@@ -509,6 +521,114 @@ public class DrawingManager {
return failedComponents;
}
private void drawMirroredComponent(Project project, Set<DrawOption> drawOptions,
Double scaleFactor, Rectangle2D visibleRect, double zoom, G2DWrapper g2dWrapper,
boolean outlineMode, int i, ComponentState state, double boardMirrorSpacing,
IDIYComponent<?> componentToDraw, IBoard board) {
Rectangle2D boardRectangle = board.getBoardRectangle();
AffineTransform mirrorTx = null;
switch (board.getBoardUndersideDisplay()) {
case ABOVE:
mirrorTx = new AffineTransform();
mirrorTx.translate(boardRectangle.getMinX(), boardRectangle.getMinY());
mirrorTx.scale(1, -1);
mirrorTx.translate(-boardRectangle.getMinX(), -boardRectangle.getMinY());
mirrorTx.translate(0, boardMirrorSpacing);
break;
case BELOW:
mirrorTx = new AffineTransform();
mirrorTx.translate(boardRectangle.getMinX(), boardRectangle.getMaxY());
mirrorTx.scale(1, -1);
mirrorTx.translate(-boardRectangle.getMinX(), -boardRectangle.getMaxY());
mirrorTx.translate(0, -boardMirrorSpacing);
break;
case LEFT:
mirrorTx = new AffineTransform();
mirrorTx.translate(boardRectangle.getMinX(), boardRectangle.getMinY());
mirrorTx.scale(-1, 1);
mirrorTx.translate(-boardRectangle.getMinX(), -boardRectangle.getMinY());
mirrorTx.translate(boardMirrorSpacing, 0);
break;
case RIGHT:
mirrorTx = new AffineTransform();
mirrorTx.translate(boardRectangle.getMaxX(), boardRectangle.getMinY());
mirrorTx.scale(-1, 1);
mirrorTx.translate(-boardRectangle.getMaxX(), -boardRectangle.getMinY());
mirrorTx.translate(-boardMirrorSpacing, 0);
break;
default:
LOG.warn("Unexpected board underside display: " + board.getBoardUndersideDisplay());
break;
}
AffineTransform txBefore = new AffineTransform(g2dWrapper.getTransform());
byte alphaBefore = 0;
if (AbstractTransparentComponent.class.isInstance(componentToDraw)) {
alphaBefore = ((AbstractTransparentComponent<?>)componentToDraw).getAlpha();
((AbstractTransparentComponent<?>)componentToDraw).setAlpha(MIRRORED_ALPHA);
}
try {
g2dWrapper.setMirrorTransform(mirrorTx);
g2dWrapper.transform(mirrorTx);
componentToDraw.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
} finally {
g2dWrapper.setTransform(txBefore);
g2dWrapper.setMirrorTransform(null);
if (AbstractTransparentComponent.class.isInstance(componentToDraw)) {
((AbstractTransparentComponent<?>)componentToDraw).setAlpha(alphaBefore);
}
}
}
private void drawComponent(Project project, Set<DrawOption> drawOptions, Double scaleFactor,
Rectangle2D visibleRect, double zoom, G2DWrapper g2dWrapper, boolean outlineMode, int i,
IDIYComponent<?> component, ComponentState state) {
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache
DrawingCache.Instance.draw(component, g2dWrapper, state,
drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, scaleFactor, i, visibleRect);
else // go straight to the wrapper
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
if (g2dWrapper.isTrackingContinuityArea()) {
LOG.debug("Component " + component.getName() + " of type "
+ component.getClass().getName() + " did not stop tracking continuity area.");
}
}
private void configureG2D(Graphics2D g2d, Set<DrawOption> drawOptions) {
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
} else {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
if (configManager.readBoolean(IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
// RenderingHints.VALUE_STROKE_PURE);
} else {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
}
private double zoomCached = 0;
private Dimension canvasDimensionCached;
private double extraSpaceCached;
@@ -105,6 +105,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
private double zoom;
private int zOrder;
private AffineTransform mirrorTransform;
/**
* Creates a wrapper around specified {@link Graphics2D} object.
@@ -218,8 +220,12 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
@Override
public void setContinuityMarker(String marker) {
continuityMarker = marker;
}
}
public void setMirrorTransform(AffineTransform mirrorTransform) {
this.mirrorTransform = mirrorTransform;
}
/**
* Appends shape interior to the current component area.
*
@@ -344,22 +350,73 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
@Override
public void drawString(String str, int x, int y) {
canvasGraphics.drawString(str, x, y);
if (drawingComponent && trackingAllowed) {
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
Point2D point = new Point2D.Double(x, y);
// currentTx.transform(point, point);
Rectangle2D finalRec =
new Rectangle2D.Double(rect.getX() + point.getX(), rect.getY() + point.getY(), rect.getWidth(),
rect.getHeight());
appendShape(finalRec);
}
this.drawString(str, (float)x, (float)y);
}
@Override
public void drawString(String str, float x, float y) {
canvasGraphics.drawString(str, x, y);
if (this.mirrorTransform == null) {
canvasGraphics.drawString(str, x, y);
} else {
drawStringUnmirrored(str, x, y);
}
handleDrawString(str, x, y);
}
private void drawStringUnmirrored(String str, float x, float y) {
// Save the current transform (T), which includes the mirror.
AffineTransform originalTransform = new AffineTransform(getTransform());
// Compute the non-mirrored transform A by "canceling" the mirror:
// Since T = A × M and M is self-inverse, we have A = T × M.
AffineTransform nonMirroredTransform = new AffineTransform(originalTransform);
nonMirroredTransform.concatenate(mirrorTransform);
GlyphVector gv = getFont().createGlyphVector(this.getFontRenderContext(), str);
Rectangle2D visualBounds = gv.getVisualBounds();
// Use a temporary Graphics2D (with transform A) to obtain correct FontMetrics.
Graphics2D gTemp = (Graphics2D) canvasGraphics.create();
gTemp.setTransform(nonMirroredTransform);
FontMetrics fm = gTemp.getFontMetrics();
double textWidth = fm.stringWidth(str);
// Use ascent + descent as the bounding box height.
double textHeight = visualBounds.getHeight();//fm.getAscent() + fm.getDescent();
double ascent = fm.getAscent();
gTemp.dispose();
// 1. Compute the center of the text’s bounding box in the mirrored (T) space.
Point2D centerMirrored = new Point2D.Double(x + textWidth / 2.0,
y + textHeight / 2.0);
// 2. Convert that center to screen coordinates using the original transform T.
Point2D centerScreen = originalTransform.transform(centerMirrored, null);
// 3. Map the screen coordinate into the non-mirrored coordinate system (A).
Point2D centerNonMirrored;
try {
centerNonMirrored = nonMirroredTransform.createInverse().transform(centerScreen, null);
} catch (NoninvertibleTransformException e) {
e.printStackTrace();
centerNonMirrored = centerMirrored; // Fallback if inversion fails.
}
// 4. Compute the new top-left in A so that the bounding box (width x height)
// remains centered at centerNonMirrored.
double newTopLeftX = centerNonMirrored.getX() - textWidth / 2.0;
double newTopLeftY = centerNonMirrored.getY() - textHeight / 2.0;
// Adjust for the baseline (drawString uses the baseline for y)
float drawX = (float) newTopLeftX;
float drawY = (float) (newTopLeftY + ascent);
// 5. Set the transform to the non-mirrored transform (A) so that mirror is canceled.
canvasGraphics.setTransform(nonMirroredTransform);
canvasGraphics.drawString(str, drawX, drawY);
// 6. Restore the original transform.
setTransform(originalTransform);
}
private void handleDrawString(String str, float x, float y) {
if (drawingComponent && trackingAllowed) {
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
Binary file not shown.
@@ -34,7 +34,9 @@ import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.BoardUndersideDisplay;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoard;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
@@ -42,7 +44,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
public abstract class AbstractBoard extends AbstractTransparentComponent<String> {
public abstract class AbstractBoard extends AbstractTransparentComponent<String> implements IBoard {
private static final long serialVersionUID = 1L;
@@ -72,6 +74,8 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
protected Size length;
protected Size width;
protected BoardSizingMode mode = BoardSizingMode.TwoPoints;
protected BoardUndersideDisplay boardUndersideDisplay = BoardUndersideDisplay.NONE;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -363,6 +367,32 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
this.mode = mode;
}
@EditableProperty(name = "Underside Display")
@Override
public BoardUndersideDisplay getBoardUndersideDisplay() {
if (this.boardUndersideDisplay == null) {
this.boardUndersideDisplay = BoardUndersideDisplay.NONE;
}
return this.boardUndersideDisplay;
}
public void setBoardUndersideDisplay(BoardUndersideDisplay boardUndersideDisplay) {
this.boardUndersideDisplay = boardUndersideDisplay;
}
@Override
public Rectangle2D getBoardRectangle() {
Point2D finalSecondPoint = getFinalSecondPoint();
return new Rectangle2D.Double(firstPoint.getX(), firstPoint.getY(),
finalSecondPoint.getX() - firstPoint.getX(), finalSecondPoint.getY() - firstPoint.getY());
}
@Override
public boolean shouldExportToGerber() {
return false;
}
@Override
public Rectangle2D getCachingBounds() {
Point2D finalSecondPoint = getFinalSecondPoint();
@@ -37,12 +37,11 @@ import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.gerber.IGerberBoard;
@ComponentDescriptor(name = "Blank Board", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Blank circuit board",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, transformer = SimpleComponentTransformer.class)
public class BlankBoard extends AbstractBoard implements IGerberBoard {
public class BlankBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -132,6 +131,11 @@ public class BlankBoard extends AbstractBoard implements IGerberBoard {
public String getControlPointNodeName(int index) {
return null;
}
@Override
public boolean shouldExportToGerber() {
return true;
}
static enum Type {
ROUND, SQUARE;
@@ -141,12 +145,4 @@ public class BlankBoard extends AbstractBoard implements IGerberBoard {
return name().substring(0, 1) + name().substring(1).toLowerCase();
}
}
@Override
public Rectangle2D getBoardRectangle() {
Point2D finalSecondPoint = getFinalSecondPoint();
return new Rectangle2D.Double(firstPoint.getX(), firstPoint.getY(),
finalSecondPoint.getX() - firstPoint.getX(), finalSecondPoint.getY() - firstPoint.getY());
}
}
+5 -446
View File
@@ -13,18 +13,13 @@
#34 / 0.16mm
#36 / 0.13mm
#8 / 3.26mm
(Building Blocks)
(Favorites)
(Recently Used)
1 throws / 2 positions
10 throws / 10 positions
11 throws / 11 positions
12 throws / 12 positions
180 degrees clockwise
1P12T
2 throws / 2 positions
2 throws / 3 positions / OFF even positions
270 degrees clockwise
2P5T
2P6T
3 throws / 3 positions
@@ -50,117 +45,27 @@
7 throws / 7 positions
8 throws / 8 positions
9 throws / 9 positions
90 degrees clockwise
A variant with that name already exists. Overwrite?
A-O-I REGULATOR
AC
ANSI
AWG
About
Above
Access User Files
Add Flexible Leads
Add Validation Step
All Connected
Alpha
Alternate
Analyze
Analyze Guitar Diagrams
And
Angle
Angle Offset
Anti-Aliasing
Apply Model
Apply Variant
Arrow Size
Author
Auto-Create Pads
Auto-Edit Mode
B-C-E BJT
Background
Base
Below
Board
Board Color
Board Width
Boards
Bobbin 1
Bobbin 2
Body
Border
Border Thickness
Both
Both Sides
Bottom
Bottom Left
Bottom Right
Board1
Box
Bracket
Bring Forward
Bring Selection to Front
Buffer
C-B-E BJT
Center
Center Negative
Center Positive
Center Terminal
Central
Change Password
Channel
Chassis
Check Trace Proximity
C1
C2
C3
Circle
Circular
Click on a component to highlight area directly or indirectly connected to the area below the cursor. To continue editing, this mode needs to be switched OFF
Click on the canvas to create a new %s or press %s to cancel
Click on the canvas to set the %s control point of a new %s or press %s to cancel
Click the lightbulb icon in the bottom-right corner of the window for more info.
Click to fetch the most recent public announcement
Click to show recent changes and updates
Click to toggle to the next option
Coil
Coil Border
Coil Length
Coil Width
Coil(s)
Color
Color 1
Color 2
Color code
Column Spacing
Columns
Component
Component API
Component reordering is possible only when Project Explorer is sorted by z-index.
Components
Config
Configuration
Connectivity
Connector
Connector (Mirrored)
Contacts
Continuous Creation
Coordinate Color
Coordinate Origin
Coordinates
Copy
Core
Core Border
Core Thickness
Core Width
Could not apply changes. Check the log for details.
Could not create a new file. Check the log for details.
Could not create component. Check log for details.
Could not fetch public announcements.
Could not save the project to file. Check the log for details.
Could not set component type slot. Check log for details.
Cover
Create B.O.M.
Create New Account
Current
Cut
Cut Between Holes
Cut Orientation
D-G-S JFET
D-G-S MOSFET
D-S-G JFET
@@ -169,12 +74,8 @@ DC
DFM A
DFM B
DIP
DIP (Mirrored)
DP3T
DP3T (Import 5-Position Strat)
DP3T (Standard 3-Position Strat)
DP3T (Standard 5-Position Strat)
DP4T (4-Position Tele)
DP4T (6-Position Oak Grigsby)
DP5T
DPDT
@@ -182,83 +83,24 @@ DPDT (On/Off/On)
DPDT (On/On)
DPDT (On/On/On Type 1)
DPDT (On/On/On Type 2)
Dashed
Decimals
Default
Default Font
Default Font Size
Delete Selection
Description
Designation
Deutsch
Diameter
Dimension Mode
Directional
Directly heated
Display
Display Pin #s
Dog Ear
Donate
Dot Spacing
Dots (Gradual)
Dots (Uniform)
Dotted
Double Rails
Double Rods
Drag control point(s) of
Drag the mouse over the canvas to place a new
Draw Standard
Drop
Duodecar B12C
Duplicate
E+
E-B-C BJT
Edges
Edit
Edit Project Settings
Edit Selection
Eight
Electro-Mechanical
Electrode Labels
Enable Cache Boost
End Arrow
English
Enjoying DIYLC? Click here to buy me a coffee :)
Error
Error occurred while editing selection. Check the log for details.
Español
Exit
Expand Selection
Explicit Dimensions
Explicit Length
Explicit Width
Export
Export Building Blocks
Export Grid
Export Variants
Export to Gerber
Export to PDF
Export to PNG
Exporting outline for board %s to file %s
Extra Working Area
Eyelet color
FAQ
Filament Voltage
File
Filtertron
Find
Five
Flip
Folded
Font
Font Bold
Font Italic
Font Size
Font Size Override
Four
Français
Full
Fuse
G-D-S JFET
G-D-S MOSFET
G-I-O REGULATOR
@@ -267,206 +109,50 @@ G-S-D JFET
G-S-D MOSFET
Generate DIYLC Netlist (excl. Switches)
Generate DIYLC Netlist (incl. Switches)
Generate Spice Netlist
Gerber Export
Gerber export completed successfully. The following files were created:%s
Gray
Grid
Grid Spacing
Group Selection
Guitar
Half
Heaters
Height
Help
Hi-Quality Rendering
Highlight Connected Areas
Hole
Hole Size
Hole Spacing
Hole Type
Holes Per Strip
Horizontal
Horizontal Alignment
Horizontal Large
Horizontal Medium
Horizontal Small 1
Horizontal Small 2
Horizontal X-Small
Humbucking - 4 leads
I-G-O REGULATOR
IEC
If this box is checked application will use the current value as a<br>default when creating new components of the same type
Image
Immediate Only
Import
Import Building Blocks
Import Netlist
Import Variants
In-Line D-44
In-line
Indent
Information
Inline
Inner 1
Inner 2
Inner 3
Inner 4
Inner 5
Inner 6
Input error for "%s": %s
Inside Color
Integration
Invert Polarity
Italiano
Label
Label Color
Label Orientation
Label Position
Labels
Language
Language selection will be applied after the application is restarted.
Layer
Layers
Lead Color
Lead Count
Lead Length
Lead Spacing
Left
Left click to instantiate this component, right click for more options
Left-to-Right
Legs
Length
Letters
Lin
Loadline Editor
Lock
Log
Log In
Log Out
Lug Size
Lugs
MPJA
Make a Donation
Manage Account
Manage My Uploads
Mark Common Lugs
Marker
Marker Size
Markers
Maximum number of switching combinations exceeded. Allowed: %s, actual: %s
Mini
Miniature
Mirror Horizontally
Mirror Selection
Mirror Vertically
Mirroring operation will change the circuit. Do you want to continue?
Misc
Model
Mono
Mount
Mounting Lugs
Mouse Wheel Zoom
Moveable Label
NPN
Name
Nand
Nederlands
Negative
New
New version available
Nine
No
No new public announcements available.
Non-Plated Through Hole
Non-shorting
None
Nor
Not
Noval B9A
Nudge
Numbers
Numeric (0-10)
Numeric (1-10)
Numeric (1-11)
Numeric (1-12)
Numeric (Even, No Ticks)
Numeric (Even, With Ticks)
Nut
O-G-I REGULATOR
Octal
Offset
One
One Side
Open
Opposing Points
Or
Orientation
Outer Foil
Outer Foil Mark
Outline Mode
Outside
Oval horizontal
Oval vertical
PAF
PCB
PNP
Pad Color
Pad color
Panel
Passive
Paste
Pin Arrangement
Pin Color
Pin Spacing
Pin spacing
Pinout
Pins
Pitch
Plated Through Hole
Play Test
Plugin API
Point Count
Polarity
Polarized
Pole Color
Pole Pieces
Pole Pieces 1
Pole Pieces 2
Poles
Português
Positions
Positive
Power Rating
Power Strip
Primary CT
Print...
Project Cloud
Public Announcement
RS
Radius
Rail
Recent Files
Recent Updates
Rectangle
Redo
Renumber On Paste
Renumber Selection
Resistance
Rev log
Reverse (standing)
Right
Rim
Rods
Rotate Clockwise
Rotate Counterclockwise
Rotate Selection
Round
Round WOG A
Round WOG B
Row Spacing
Rows
Ruler Inch Subdivision...
S-G-D JFET
S-G-D MOSFET
SMD
@@ -474,155 +160,28 @@ SPDT
SPDT (On/Off/On)
SPDT (On/On)
SPST
Same Type Only
Save
Save As
Save as Variant
Scale
Schematic Symbols
Screw Position
Screws
Search The Cloud
Searchable Tree
Secondary CT
Select
Select All
Selected component(s) have reached the bottom of their layer. Do you want to force the selection to the back?
Selected component(s) have reached the top of their layer. Do you want to force the selection to the top?
Selection
Selection Size
Selection contains components that cannot be mirrored. Do you want to exclude them?
Selection contains components that cannot be rotated. Do you want to exclude them?
Selection is empty.
Semiconductors
Send Backward
Send Selection to Back
Seven
Shaft Down
Shaft Up
Shape
Shapes
Shorting
Show Bracket
Show Grid
Show Project Explorer
Show Rulers
Shroud
Shrouded
Single - North
Single - South
Single Rail
Single Rods
Six
Size
Sizing Mode
Small-button B7G
Smooth
Snap To
Soap Bar
Solid
Sort by Name
Sort by Type
Sort by Z-index
Source Style
Source Type
Spacing
Square
Square BR-3
Srpski
Standard
Start Arrow
Start Recording
Stereo
Sticky Points
Stop Recording
Stratocaster
Strip Color
Stripe
Stripe 1
Stripe 2
Stripe Color
Stripe Color 1
Stripe Color 2
Stroke
Style
Submit a Bug
Suppressor grid
Switched
Switches
Tab
Tab Border
Tabbed Toolbar
Taper
Telecaster
Ten
Terminal
Terminal Spacing
Terminals
Test
Text
Text Color
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?
There are unsaved changes. Would you like to save them?
Thickness
Three
Through Hole
Tick
Tick Width
Ticks
Timing
Title
Toolbox
Top
Top Lead
Top Left
Top Right
Top-to-Bottom
Trace
Trace Color
Trace Mask
Trace1
Transform Selection
Triangle
Tubes
Tubular
Tubular Beveled
Two
Type
Ultra-miniature
Underside Pad Color
Underside Trace Color
Undo
Ungroup Selection
Unit
Unlock
Upload A Project
User Manual
Value
Version history is not available.
Vertical
Vertical Alignment
Vertical Inline
Vertical Offset 1
Vertical Offset 2
View
Visible
Voltage
Wafer
Warning
Width
Winding Spacing
Wiring
X-axis
Underside Display
Xnor
Xor
Y-axis
Zoom
base of 10
base of 2
cm
ft
hold %s and drag to unstick from
in
mm
px
Binary file not shown.
Binary file not shown.