From fbe9a2ecde59754ca0c167731f68f15c806194c3 Mon Sep 17 00:00:00 2001 From: Michael Hoffer Date: Sun, 15 Oct 2017 13:49:49 +0200 Subject: [PATCH] refactoring --- .gitignore | 8 +- build.gradle | 147 ++ build.xml | 32 - gradle/project-info.gradle | 25 + gradle/publishing.gradle | 122 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54708 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 ++ gradlew.bat | 84 + lib/eu.mihosoft.freerouting.deps.jh.jar | Bin 0 -> 532625 bytes settings.gradle | 2 + .../autoroute/AutorouteControl.java | 42 +- .../autoroute/AutorouteEngine.java | 42 +- .../autoroute/BatchAutorouter.java | 50 +- .../freerouting/autoroute/BatchFanout.java | 32 +- .../freerouting/autoroute/BatchOptRoute.java | 40 +- .../autoroute/CompleteExpansionRoom.java | 6 +- .../CompleteFreeSpaceExpansionRoom.java | 18 +- .../freerouting/autoroute/Connection.java | 8 +- .../autoroute/DestinationDistance.java | 8 +- .../freerouting/autoroute/DrillPage.java | 28 +- .../freerouting/autoroute/DrillPageArray.java | 12 +- .../autoroute/ExpandableObject.java | 4 +- .../freerouting/autoroute/ExpansionDoor.java | 12 +- .../freerouting/autoroute/ExpansionDrill.java | 14 +- .../freerouting/autoroute/ExpansionRoom.java | 4 +- .../autoroute/FreeSpaceExpansionRoom.java | 4 +- .../IncompleteFreeSpaceExpansionRoom.java | 4 +- .../autoroute/InsertFoundConnectionAlgo.java | 40 +- .../autoroute/ItemAutorouteInfo.java | 14 +- .../autoroute/LocateFoundConnectionAlgo.java | 20 +- .../LocateFoundConnectionAlgo45Degree.java | 22 +- .../LocateFoundConnectionAlgoAnyAngle.java | 18 +- .../autoroute/MazeListElement.java | 4 +- .../freerouting/autoroute/MazeSearchAlgo.java | 110 +- .../autoroute/MazeSearchElement.java | 2 +- .../autoroute/MazeShoveTraceAlgo.java | 42 +- .../autoroute/ObstacleExpansionRoom.java | 18 +- .../Sorted45DegreeRoomNeighbours.java | 20 +- .../SortedOrthogonalRoomNeighbours.java | 16 +- .../autoroute/SortedRoomNeighbours.java | 34 +- .../autoroute/TargetItemExpansionDoor.java | 12 +- .../freerouting/autoroute/package.html | 2 +- .../freerouting/board/AngleRestriction.java | 2 +- .../freerouting/board/BasicBoard.java | 136 +- .../board/BoardObserverAdaptor.java | 2 +- .../freerouting/board/BoardObservers.java | 4 +- .../freerouting/board/BoardOutline.java | 35 +- .../freerouting/board/CalcFromSide.java | 16 +- .../board/CalcShapeAndFromSide.java | 12 +- .../freerouting/board/ChangedArea.java | 14 +- .../freerouting/board/ClearanceViolation.java | 6 +- .../freerouting/board/Communication.java | 8 +- .../mihosoft/freerouting/board/Component.java | 38 +- .../board/ComponentObstacleArea.java | 14 +- .../freerouting/board/ComponentOutline.java | 22 +- .../freerouting/board/Components.java | 28 +- .../freerouting/board/ConductionArea.java | 18 +- .../freerouting/board/Connectable.java | 4 +- .../board/CoordinateTransform.java | 42 +- .../mihosoft/freerouting/board/DrillItem.java | 24 +- .../freerouting/board/FixedState.java | 4 +- .../freerouting/board/ForcedPadAlgo.java | 24 +- .../freerouting/board/ForcedViaAlgo.java | 28 +- .../eu/mihosoft/freerouting/board/Item.java | 74 +- .../freerouting/board/ItemIdNoGenerator.java | 4 +- .../board/ItemSearchTreesInfo.java | 8 +- .../board/ItemSelectionFilter.java | 8 +- .../eu/mihosoft/freerouting/board/Layer.java | 4 +- .../freerouting/board/LayerStructure.java | 4 +- .../freerouting/board/MoveComponent.java | 16 +- .../freerouting/board/MoveDrillItemAlgo.java | 20 +- .../freerouting/board/ObjectInfoPanel.java | 10 +- .../freerouting/board/ObstacleArea.java | 28 +- .../freerouting/board/OptViaAlgo.java | 18 +- .../eu/mihosoft/freerouting/board/Pin.java | 50 +- .../freerouting/board/PolylineTrace.java | 36 +- .../freerouting/board/PrintableShape.java | 12 +- .../freerouting/board/PullTightAlgo.java | 26 +- .../freerouting/board/PullTightAlgo45.java | 26 +- .../freerouting/board/PullTightAlgo90.java | 14 +- .../board/PullTightAlgoAnyAngle.java | 24 +- .../freerouting/board/RoutingBoard.java | 76 +- .../freerouting/board/SearchTreeManager.java | 18 +- .../freerouting/board/SearchTreeObject.java | 6 +- .../freerouting/board/ShapeSearchTree.java | 50 +- .../board/ShapeSearchTree45Degree.java | 20 +- .../board/ShapeSearchTree90Degree.java | 16 +- .../freerouting/board/ShapeTraceEntries.java | 14 +- .../freerouting/board/ShoveTraceAlgo.java | 28 +- .../mihosoft/freerouting/board/TestLevel.java | 2 +- .../eu/mihosoft/freerouting/board/Trace.java | 26 +- .../eu/mihosoft/freerouting/board/Unit.java | 2 +- .../eu/mihosoft/freerouting/board/Via.java | 32 +- .../freerouting/board/ViaObstacleArea.java | 14 +- .../mihosoft/freerouting/board/package.html | 10 +- .../boardgraphics/ColorIntensityTable.java | 2 +- .../boardgraphics/ColorTableModel.java | 4 +- .../boardgraphics/CoordinateTransform.java | 40 +- .../freerouting/boardgraphics/Drawable.java | 2 +- .../boardgraphics/GraphicsContext.java | 2 +- .../boardgraphics/ItemColorTableModel.java | 8 +- .../boardgraphics/ItemDrawInfo.java | 2 +- .../boardgraphics/OtherColorTableModel.java | 4 +- .../freerouting/boardgraphics/package.html | 2 +- .../datastructures/ArrayStack.java | 2 +- .../freerouting/datastructures/BigIntAux.java | 2 +- .../datastructures/FileFilter.java | 2 +- .../datastructures/IdNoGenerator.java | 2 +- .../datastructures/IdentifierType.java | 2 +- .../datastructures/IndentFileWriter.java | 2 +- .../datastructures/MinAreaTree.java | 6 +- .../freerouting/datastructures/Observers.java | 2 +- .../PlanarDelaunayTriangulation.java | 12 +- .../freerouting/datastructures/ShapeTree.java | 10 +- .../freerouting/datastructures/Signum.java | 2 +- .../freerouting/datastructures/Stoppable.java | 2 +- .../freerouting/datastructures/TimeLimit.java | 2 +- .../datastructures/UndoableObjects.java | 4 +- .../freerouting/datastructures/package.html | 2 +- .../specctra/AutorouteSettings.java | 324 ++++ .../designforms/specctra/Circle.java | 115 ++ .../designforms/specctra/Circuit.java | 181 ++ .../designforms/specctra/Component.java | 430 +++++ .../specctra/ComponentPlacement.java | 106 ++ .../specctra/CoordinateTransform.java | 262 +++ .../designforms/specctra/DsnFile.java | 430 +++++ .../designforms/specctra/Keyword.java | 155 ++ .../designforms/specctra/Layer.java | 100 ++ .../designforms/specctra/LayerStructure.java | 115 ++ .../designforms/specctra/Library.java | 446 +++++ .../freerouting/designforms/specctra/Net.java | 162 ++ .../designforms/specctra/NetClass.java | 249 +++ .../designforms/specctra/NetList.java | 100 ++ .../designforms/specctra/Network.java | 1536 +++++++++++++++++ .../designforms/specctra/Package.java | 504 ++++++ .../designforms/specctra/Parser.java | 271 +++ .../designforms/specctra/PartLibrary.java | 393 +++++ .../designforms/specctra/Path.java | 49 + .../designforms/specctra/PlaceControl.java | 110 ++ .../designforms/specctra/Placement.java | 52 + .../designforms/specctra/Plane.java | 109 ++ .../designforms/specctra/Polygon.java | 140 ++ .../designforms/specctra/PolygonPath.java | 169 ++ .../designforms/specctra/PolylinePath.java | 103 ++ .../specctra/ReadScopeParameter.java | 114 ++ .../designforms/specctra/Rectangle.java | 129 ++ .../designforms/specctra/Resolution.java | 88 + .../designforms/specctra/Rule.java | 383 ++++ .../designforms/specctra/RulesFile.java | 321 ++++ .../designforms/specctra/Scanner.java | 39 + .../designforms/specctra/ScopeKeyword.java | 127 ++ .../designforms/specctra/SessionFile.java | 522 ++++++ .../designforms/specctra/SessionToEagle.java | 738 ++++++++ .../designforms/specctra/Shape.java | 831 +++++++++ .../specctra/SpecctraFileDescription.flex | 311 ++++ .../specctra/SpecctraFileScanner.java | 1459 ++++++++++++++++ .../designforms/specctra/Structure.java | 1419 +++++++++++++++ .../designforms/specctra/Wiring.java | 786 +++++++++ .../specctra/WriteScopeParameter.java | 59 + .../designforms/specctra/package.html | 21 + .../freerouting/geometry/planar/Area.java | 2 +- .../geometry/planar/BigIntDirection.java | 2 +- .../freerouting/geometry/planar/Circle.java | 2 +- .../geometry/planar/ConvexShape.java | 2 +- .../geometry/planar/Direction.java | 4 +- .../freerouting/geometry/planar/Ellipse.java | 2 +- .../geometry/planar/FloatLine.java | 2 +- .../geometry/planar/FloatPoint.java | 2 +- .../FortyfiveDegreeBoundingDirections.java | 2 +- .../planar/FortyfiveDegreeDirection.java | 2 +- .../freerouting/geometry/planar/IntBox.java | 2 +- .../geometry/planar/IntDirection.java | 4 +- .../geometry/planar/IntOctagon.java | 2 +- .../freerouting/geometry/planar/IntPoint.java | 2 +- .../geometry/planar/IntVector.java | 6 +- .../freerouting/geometry/planar/Limits.java | 2 +- .../freerouting/geometry/planar/Line.java | 4 +- .../geometry/planar/LineSegment.java | 4 +- .../planar/OrthogonalBoundingDirections.java | 2 +- .../freerouting/geometry/planar/Point.java | 2 +- .../freerouting/geometry/planar/Polygon.java | 2 +- .../geometry/planar/PolygonShape.java | 2 +- .../freerouting/geometry/planar/Polyline.java | 2 +- .../geometry/planar/PolylineArea.java | 4 +- .../geometry/planar/PolylineShape.java | 2 +- .../geometry/planar/RationalPoint.java | 4 +- .../geometry/planar/RationalVector.java | 6 +- .../geometry/planar/RegularTileShape.java | 2 +- .../freerouting/geometry/planar/Shape.java | 2 +- .../planar/ShapeBoundingDirections.java | 2 +- .../freerouting/geometry/planar/Side.java | 2 +- .../freerouting/geometry/planar/Simplex.java | 2 +- .../geometry/planar/TileShape.java | 2 +- .../freerouting/geometry/planar/Vector.java | 4 +- .../mihosoft/freerouting/gui/BoardFrame.java | 4 +- .../freerouting/gui/BoardMenuBar.java | 2 +- .../freerouting/gui/BoardMenuDisplay.java | 4 +- .../freerouting/gui/BoardMenuFile.java | 4 +- .../freerouting/gui/BoardMenuHelp.java | 2 +- .../freerouting/gui/BoardMenuHelpReduced.java | 14 +- .../freerouting/gui/BoardMenuInfo.java | 4 +- .../freerouting/gui/BoardMenuOther.java | 4 +- .../freerouting/gui/BoardMenuParameter.java | 6 +- .../freerouting/gui/BoardMenuRules.java | 10 +- .../mihosoft/freerouting/gui/BoardPanel.java | 2 +- .../freerouting/gui/BoardPanelStatus.java | 4 +- .../gui/BoardSavableSubWindow.java | 2 +- .../freerouting/gui/BoardSubWindow.java | 2 +- .../gui/BoardTemporarySubWindow.java | 2 +- .../freerouting/gui/BoardToolbar.java | 4 +- .../gui/BoardToolbarSelectedItem.java | 6 +- .../freerouting/gui/ColorManager.java | 6 +- .../freerouting/gui/ComboBoxClearance.java | 2 +- .../freerouting/gui/ComboBoxLayer.java | 4 +- .../eu/mihosoft/freerouting/gui/Cursor.java | 2 +- .../gui/DefaultExceptionHandler.java | 2 +- .../mihosoft/freerouting/gui/DesignFile.java | 18 +- .../freerouting/gui/GUIDefaultsFile.java | 2 +- .../freerouting/gui/GUIDefaultsScanner.java | 4 +- .../freerouting/gui/MainApplication.java | 107 +- .../freerouting/gui/PopupMenuChangeLayer.java | 6 +- .../freerouting/gui/PopupMenuCopy.java | 4 +- .../freerouting/gui/PopupMenuDisplay.java | 4 +- .../gui/PopupMenuDynamicRoute.java | 4 +- .../gui/PopupMenuInsertCancel.java | 4 +- .../freerouting/gui/PopupMenuMain.java | 4 +- .../freerouting/gui/PopupMenuMove.java | 4 +- .../gui/PopupMenuSelectedItems.java | 4 +- .../freerouting/gui/PopupMenuStitchRoute.java | 4 +- .../gui/PupupMenuCornerItemConstruction.java | 4 +- .../freerouting/gui/StartupOptions.java | 2 +- .../mihosoft/freerouting/gui/WindowAbout.java | 4 +- .../freerouting/gui/WindowAssignNetClass.java | 4 +- .../gui/WindowAutorouteDetailParameter.java | 4 +- .../gui/WindowAutorouteParameter.java | 6 +- .../gui/WindowClearanceMatrix.java | 4 +- .../gui/WindowClearanceViolations.java | 4 +- .../freerouting/gui/WindowComponents.java | 4 +- .../freerouting/gui/WindowDisplayMisc.java | 4 +- .../freerouting/gui/WindowEditVias.java | 4 +- .../freerouting/gui/WindowIncompletes.java | 4 +- .../gui/WindowLayerVisibility.java | 4 +- .../gui/WindowLengthViolations.java | 4 +- .../freerouting/gui/WindowManualRules.java | 4 +- .../freerouting/gui/WindowMessage.java | 2 +- .../freerouting/gui/WindowMoveParameter.java | 4 +- .../freerouting/gui/WindowNetClasses.java | 6 +- .../gui/WindowNetDemonstrations.java | 2 +- .../gui/WindowNetSampleDesigns.java | 2 +- .../freerouting/gui/WindowNetSamples.java | 4 +- .../mihosoft/freerouting/gui/WindowNets.java | 4 +- .../freerouting/gui/WindowObjectInfo.java | 4 +- .../freerouting/gui/WindowObjectList.java | 4 +- .../gui/WindowObjectListWithFilter.java | 4 +- .../gui/WindowObjectVisibility.java | 4 +- .../freerouting/gui/WindowPackages.java | 4 +- .../freerouting/gui/WindowPadstacks.java | 4 +- .../freerouting/gui/WindowRouteDetail.java | 4 +- .../freerouting/gui/WindowRouteParameter.java | 8 +- .../freerouting/gui/WindowRouteStubs.java | 4 +- .../gui/WindowSelectParameter.java | 4 +- .../freerouting/gui/WindowSnapshot.java | 4 +- .../gui/WindowSnapshotSettings.java | 4 +- .../gui/WindowUnconnectedRoute.java | 4 +- .../mihosoft/freerouting/gui/WindowVia.java | 6 +- .../freerouting/gui/WindowViaRule.java | 4 +- .../freerouting/gui/WindowVisibility.java | 4 +- .../interactive/AutorouteSettings.java | 10 +- .../interactive/BatchAutorouterThread.java | 20 +- .../interactive/BoardHandling.java | 228 +-- .../interactive/BoardHandlingImpl.java | 30 +- .../interactive/CircleConstructionState.java | 18 +- .../interactive/ClearanceViolations.java | 8 +- .../interactive/CopyItemState.java | 32 +- .../CornerItemConstructionState.java | 8 +- .../interactive/CutoutRouteState.java | 14 +- .../interactive/DragItemState.java | 16 +- .../interactive/DragMenuState.java | 4 +- .../freerouting/interactive/DragState.java | 12 +- .../interactive/DynamicRouteState.java | 6 +- .../interactive/ExpandTestState.java | 32 +- .../interactive/HoleConstructionState.java | 28 +- .../interactive/IBoardHandling.java | 16 +- .../interactive/InteractiveActionThread.java | 8 +- .../interactive/InteractiveState.java | 14 +- .../freerouting/interactive/Logfile.java | 6 +- .../interactive/LogfileDescription.flex | 2 +- .../interactive/LogfileScanner.java | 4 +- .../freerouting/interactive/LogfileScope.java | 22 +- .../interactive/MakeSpaceState.java | 16 +- .../freerouting/interactive/MenuState.java | 18 +- .../interactive/MoveItemState.java | 40 +- .../interactive/NetIncompletes.java | 22 +- .../freerouting/interactive/PinSwapState.java | 10 +- .../PolygonShapeConstructionState.java | 14 +- .../freerouting/interactive/RatsNest.java | 36 +- .../freerouting/interactive/Route.java | 100 +- .../interactive/RouteMenuState.java | 4 +- .../freerouting/interactive/RouteState.java | 47 +- .../interactive/ScreenMessages.java | 8 +- .../interactive/SelectItemsInRegionState.java | 10 +- .../interactive/SelectMenuState.java | 4 +- .../interactive/SelectRegionState.java | 6 +- .../interactive/SelectedItemState.java | 53 +- .../freerouting/interactive/Settings.java | 46 +- .../freerouting/interactive/SnapShot.java | 28 +- .../interactive/StitchRouteState.java | 10 +- .../interactive/TileConstructionState.java | 22 +- .../interactive/ZoomRegionState.java | 8 +- .../freerouting/interactive/package.html | 2 +- .../freerouting/library/BoardLibrary.java | 22 +- .../freerouting/library/LogicalPart.java | 14 +- .../freerouting/library/LogicalParts.java | 2 +- .../mihosoft/freerouting/library/Package.java | 16 +- .../freerouting/library/Packages.java | 6 +- .../freerouting/library/Padstack.java | 18 +- .../freerouting/library/Padstacks.java | 14 +- .../mihosoft/freerouting/library/package.html | 2 +- .../mihosoft/freerouting/logger/FRLogger.java | 2 +- .../eu/mihosoft/freerouting/module-info.java | 6 + .../freerouting/rules/BoardRules.java | 50 +- .../freerouting/rules/ClearanceMatrix.java | 14 +- .../rules/DefaultItemClearanceClasses.java | 2 +- .../eu/mihosoft/freerouting/rules/Net.java | 44 +- .../mihosoft/freerouting/rules/NetClass.java | 14 +- .../freerouting/rules/NetClasses.java | 10 +- .../eu/mihosoft/freerouting/rules/Nets.java | 16 +- .../mihosoft/freerouting/rules/ViaInfo.java | 12 +- .../mihosoft/freerouting/rules/ViaInfos.java | 10 +- .../mihosoft/freerouting/rules/ViaRule.java | 10 +- .../mihosoft/freerouting/rules/package.html | 2 +- .../mihosoft/freerouting/tests/Validate.java | 36 +- .../mihosoft/freerouting/tests/package.html | 2 +- .../gui/resources/BoardFrame_de.properties | 10 + .../gui/resources/BoardFrame_en.properties | 10 + .../resources/BoardMenuDisplay_de.properties | 9 + .../resources/BoardMenuDisplay_en.properties | 9 + .../gui/resources/BoardMenuFile_de.properties | 45 + .../gui/resources/BoardMenuFile_en.properties | 44 + .../gui/resources/BoardMenuHelp_de.properties | 5 + .../gui/resources/BoardMenuHelp_en.properties | 5 + .../gui/resources/BoardMenuInfo_de.properties | 10 + .../gui/resources/BoardMenuInfo_en.properties | 10 + .../resources/BoardMenuOther_de.properties | 4 + .../resources/BoardMenuOther_en.properties | 4 + .../BoardMenuParameter_de.properties | 6 + .../BoardMenuParameter_en.properties | 6 + .../resources/BoardMenuRules_de.properties | 6 + .../resources/BoardMenuRules_en.properties | 6 + .../resources/BoardPanelStatus_de.properties | 5 + .../resources/BoardPanelStatus_en.properties | 5 + .../BoardToolbarSelectedItem_de.properties | 43 + .../BoardToolbarSelectedItem_en.properties | 43 + .../gui/resources/BoardToolbar_de.properties | 22 + .../gui/resources/BoardToolbar_en.properties | 23 + .../resources/CleanupWindows_de.properties | 13 + .../resources/CleanupWindows_en.properties | 13 + .../gui/resources/Default_de.properties | 40 + .../gui/resources/Default_en.properties | 41 + .../gui/resources/DisplayMisc_de.properties | 16 + .../gui/resources/DisplayMisc_en.properties | 16 + .../resources/MainApplication_de.properties | 25 + .../resources/MainApplication_en.properties | 25 + .../gui/resources/PopupMenuMain_de.properties | 9 + .../gui/resources/PopupMenuMain_en.properties | 9 + .../gui/resources/PopupMenuMove_de.properties | 13 + .../gui/resources/PopupMenuMove_en.properties | 13 + .../gui/resources/WindowAbout_de.properties | 7 + .../gui/resources/WindowAbout_en.properties | 7 + .../WindowAssignNetClass_de.properties | 6 + .../WindowAssignNetClass_en.properties | 6 + .../WindowAutorouteParameter_de.properties | 25 + .../WindowAutorouteParameter_en.properties | 25 + .../WindowClearanceMatrix_de.properties | 16 + .../WindowClearanceMatrix_en.properties | 16 + .../WindowClearanceViolations_de.properties | 14 + .../WindowClearanceViolations_en.properties | 14 + .../resources/WindowEditVias_de.properties | 15 + .../resources/WindowEditVias_en.properties | 15 + .../WindowLengthViolations_de.properties | 7 + .../WindowLengthViolations_en.properties | 7 + .../resources/WindowManualRule_de.properties | 6 + .../resources/WindowManualRule_en.properties | 6 + .../WindowMoveParameter_de.properties | 8 + .../WindowMoveParameter_en.properties | 8 + .../resources/WindowNetClasses_de.properties | 37 + .../resources/WindowNetClasses_en.properties | 36 + .../resources/WindowNetSamples_de.properties | 12 + .../resources/WindowNetSamples_en.properties | 12 + .../gui/resources/WindowNets_de.properties | 8 + .../gui/resources/WindowNets_en.properties | 8 + .../resources/WindowObjectInfo_de.properties | 10 + .../resources/WindowObjectInfo_en.properties | 10 + .../resources/WindowObjectList_de.properties | 12 + .../resources/WindowObjectList_en.properties | 12 + .../WindowObjectVisibility_de.properties | 14 + .../WindowObjectVisibility_en.properties | 14 + .../resources/WindowRouteDetail_de.properties | 10 + .../resources/WindowRouteDetail_en.properties | 10 + .../WindowRouteParameter_de.properties | 34 + .../WindowRouteParameter_en.properties | 34 + .../WindowSelectParameter_de.properties | 20 + .../WindowSelectParameter_en.properties | 20 + .../WindowSnapshotSettings_de.properties | 17 + .../WindowSnapshotSettings_en.properties | 17 + .../resources/WindowSnapshot_de.properties | 10 + .../resources/WindowSnapshot_en.properties | 10 + .../gui/resources/WindowViaRule_de.properties | 14 + .../gui/resources/WindowViaRule_en.properties | 14 + .../gui/resources/WindowVia_de.properties | 34 + .../gui/resources/WindowVia_en.properties | 33 + .../helpset/en/html_files/WindowVia.html | 2 +- .../resources/InteractiveState_de.properties | 50 +- 414 files changed, 17723 insertions(+), 1987 deletions(-) create mode 100644 build.gradle delete mode 100644 build.xml create mode 100644 gradle/project-info.gradle create mode 100644 gradle/publishing.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 lib/eu.mihosoft.freerouting.deps.jh.jar create mode 100644 settings.gradle create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/AutorouteSettings.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circle.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circuit.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Component.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/ComponentPlacement.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/CoordinateTransform.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/DsnFile.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Keyword.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Layer.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/LayerStructure.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Library.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Net.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetClass.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetList.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Network.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Package.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Parser.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/PartLibrary.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Path.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/PlaceControl.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Placement.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Plane.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Polygon.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolygonPath.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolylinePath.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/ReadScopeParameter.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rectangle.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Resolution.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rule.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/RulesFile.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Scanner.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/ScopeKeyword.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionFile.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionToEagle.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Shape.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileDescription.flex create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileScanner.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Structure.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/Wiring.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/WriteScopeParameter.java create mode 100644 src/main/java/eu/mihosoft/freerouting/designforms/specctra/package.html create mode 100644 src/main/java/eu/mihosoft/freerouting/module-info.java create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_en.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_de.properties create mode 100644 src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_en.properties diff --git a/.gitignore b/.gitignore index 54f46fc..039ab82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ build -out \ No newline at end of file +out +/.nb-gradle/ +.gradle/ +.idea/ +freerouting.iml + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..9a9e0db --- /dev/null +++ b/build.gradle @@ -0,0 +1,147 @@ +buildscript { + repositories { + mavenCentral() + jcenter() + } + + dependencies { + // + } +} + +plugins { + id "com.github.hierynomus.license" version "0.13.1" + id 'maven-publish' + id 'net.nemerosa.versioning' version '2.4.0' + id 'com.jfrog.bintray' version '1.7.3' + id 'com.github.ben-manes.versions' version '0.13.0' + + // jigsaw: +// id 'org.gradle.java.experimental-jigsaw' version '0.1.1' +} + +apply plugin: 'java' +apply from: 'gradle/publishing.gradle' + +task wrapper(type: Wrapper) { + gradleVersion = '4.2.1' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +sourceCompatibility = '1.9' +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + } +} + +// javadoc is way too strict for my taste. +if (JavaVersion.current().isJava8Compatible()) { + allprojects { + tasks.withType(Javadoc) { + options.addStringOption("encoding", "UTF-8") + options.addStringOption('Xdoclint:none', '-quiet') + } + } +} + +if (!hasProperty('mainClass')) { + ext.mainClass = 'eu.mihosoft.freerouting.gui.MainApplication' +} + +repositories { + mavenCentral() + jcenter() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.10' + + // https://mvnrepository.com/artifact/javax.help/javahelp +// compile group: 'javax.help', name: 'javahelp', version: '2.0.05' + + compile files("./lib/eu.mihosoft.freerouting.deps.jh.jar") +} + +//ext.moduleName = 'eu.mihosoft.freerouting' +//javaModule.name = 'eu.mihosoft.freerouting' +// +//compileJava { +// inputs.property("moduleName", moduleName) +// doFirst { +// +// System.err.println(": modulepath-jar: " + classpath.asPath) +// +// options.compilerArgs = [ +// '--module-path', classpath.asPath, +// ] +// classpath = files() +// } +//} + +Date buildTimeAndDate = new Date() +ext { + buildDate = new java.text.SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate) + buildTime = new java.text.SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate) +} + +// create a fat-jar (class files plus dependencies +// excludes VRL.jar (plugin jar files must not start with 'vrl-\\d+') +jar { + + + // TODO add switch for fat-jar generation + // dependencies except VRL + // from configurations.runtime.asFileTree. + // filter({file->return !file.name.startsWith("vrl-0")}). + // files.collect { zipTree(it) } + // +// from configurations.runtime.asFileTree.files.collect { zipTree(it) } + + // // project class files compiled from source + from files(sourceSets.main.output) + + manifest { + + attributes( + 'Built-By': System.properties['user.name'], + 'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")", + 'Build-Date': project.buildDate, + 'Build-Time': project.buildTime, + 'Build-Revision': versioning.info.commit, + 'Specification-Title': project.name, + 'Specification-Version': project.version, + 'Implementation-Title': project.name, + 'Implementation-Version': project.version, + 'Main-Class': mainClass + ) + } +} + + +//license { +// header = rootProject.file('config/HEADER') +// strictCheck = true +// ignoreFailures = true +// mapping { +// java = 'SLASHSTAR_STYLE' +// groovy = 'SLASHSTAR_STYLE' +// fxml = 'XML_STYLE' +// } +// ext.yearSince1 = '2017' +// ext.yearCurrent = new java.text.SimpleDateFormat("yyyy").format(new Date()) +// ext.author1 = 'Michael Hoffer ' +// exclude '**/*.svg' +//} + + task run(type: JavaExec) { + classpath = sourceSets.main.runtimeClasspath + + main = mainClass + + // arguments to pass to the application + // args 'appArg1' + // jvmArgs 'arg1' + } diff --git a/build.xml b/build.xml deleted file mode 100644 index 4e45d94..0000000 --- a/build.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/gradle/project-info.gradle b/gradle/project-info.gradle new file mode 100644 index 0000000..b04304f --- /dev/null +++ b/gradle/project-info.gradle @@ -0,0 +1,25 @@ +// ----------------------------------------------------------------------------- +// publishing information +// ----------------------------------------------------------------------------- +ext.publishing.artifactId = project.name.toLowerCase() +ext.publishing.groupId = 'eu.mihosoft.jcapture' +ext.publishing.versionId = '0.1.2' + +ext.publishing.developerName = 'Michael Hoffer' +ext.publishing.developerAlias = 'miho' +ext.publishing.developerEmail = 'info@michaelhoffer.de' +ext.publishing.inceptionYear = '2017' + +ext.publishing.bintray.repo = 'JCapture' +ext.publishing.bintray.userOrg = 'miho' +ext.publishing.bintray.name = project.name + +ext.publishing.desc = 'Simple API for capturing video devices' +ext.publishing.license = 'Apache-2.0' +ext.publishing.licenseUrl = 'https://github.com/miho/JCapture/blob/master/LICENSE.txt' +ext.publishing.labels = ['video', 'webcam', 'capture'] +ext.publishing.websiteUrl = 'https://github.com/miho/JCapture' +ext.publishing.issueTrackerUrl = 'https://github.com/miho/JCapture/issues' +ext.publishing.vcsUrl = 'https://github.com/miho/JCapture.git' + +ext.publishing.pomName = ext.publishing.artifactId diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle new file mode 100644 index 0000000..4d8d648 --- /dev/null +++ b/gradle/publishing.gradle @@ -0,0 +1,122 @@ +// ----------------------------------------------------------------------------- +// Collect publishing information +// ----------------------------------------------------------------------------- +ext.publishing = [:] +ext.publishing.bintray = [:] + +ext.publishing.pomName = ext.publishing.artifactId + +apply from: "gradle/project-info.gradle" + +// ----------------------------------------------------------------------------- +// Performs publishing +// ----------------------------------------------------------------------------- + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +// create one jar for the source files +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives jar + archives javadocJar + archives sourcesJar +} +Date buildTimeAndDate = new Date() +ext { + buildDate = new java.text.SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate) + buildTime = new java.text.SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate) +} + +jar { + manifest { + attributes( + 'Built-By': System.properties['user.name'], + 'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")", + 'Build-Date': project.buildDate, + 'Build-Time': project.buildTime, + 'Build-Revision': versioning.info.commit, + 'Specification-Title': project.name, + 'Specification-Version': project.version, + 'Implementation-Title': project.name, + 'Implementation-Version': project.version + ) + } +} + + +def pomConfig = { + name ext.publishing.pomName + description ext.publishing.desc + url ext.publishing.websiteUrl + inceptionYear ext.publishing.inceptionYear + licenses { + license([:]) { + name ext.publishing.license + url ext.publishing.licenseUrl + distribution 'repo' + } + } + scm { + url ext.publishing.vcsUrl + connection ext.publishing.vcsUrl + developerConnection ext.publishing.vcsUrl + } + developers { + developer { + id ext.publishing.developerNameAlias + name ext.publishing.developerName + } + } +} + +publishing { + publications { + mavenCustom(MavenPublication) { + groupId publishing.groupId + artifactId publishing.artifactId + version publishing.versionId + from components.java + artifact sourcesJar + artifact javadocJar + + pom.withXml { + def root = asNode() + root.appendNode 'description', publishing.desc + root.children().last() + pomConfig + } + } + } +} + +if (!project.hasProperty('bintrayUsername')) ext.bintrayUsername = '' +if (!project.hasProperty('bintrayApiKey')) ext.bintrayApiKey = '' + +bintray { + user = project.bintrayUsername + key = project.bintrayApiKey + publications = ['mavenCustom'] + pkg { + repo = publishing.bintray.repo + userOrg = publishing.bintray.userOrg + name = publishing.bintray.name + desc = publishing.desc + licenses = [publishing.license] + labels = publishing.labels + websiteUrl = publishing.websiteUrl + issueTrackerUrl = publishing.issueTrackerUrl + vcsUrl = publishing.vcsUrl + publicDownloadNumbers = true + + version { + name = publishing.versionId + vcsTag = 'v' + publishing.versionId + } + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..736fb7d3f94c051b359fc7ae7212d351bc094bdd GIT binary patch literal 54708 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 ZypaY2tb=~UE;0eV1Nd9`dw%@&{{Y^v%e4Ri literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0854462 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lib/eu.mihosoft.freerouting.deps.jh.jar b/lib/eu.mihosoft.freerouting.deps.jh.jar new file mode 100644 index 0000000000000000000000000000000000000000..185d9422047831b60e7cf37111a560c5e7918550 GIT binary patch literal 532625 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�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%0DLAIdIxsdrf|WPZGfE>gk7O zk0ktNc!gdAaz{Ej*^xv6cq{|gQEQjB`T$eT);_ci%nRMtvWNp|TM26kpn%5Yns4IT zyGoool}lUzk7z@c`=K5GRw#!#>R=`K{T$E-{N40{j%*+Kkd%$$LB3t)7>jXyJ%o+C zI=K;8vFM>QYSH4~4gzguHnfQV^VV;>_b1`=6z79a2ajQvwn1ooxzehrwEimTMuzWH zEwHZ9ci*75m6E#)|7EI5Hcu(v5k4yr+&IgoG}sQv=|!ah#229<#fYsDh(jo0Z^$>j zgfK2yw1F=gwLbSv^w_e>OYS|?nGJEK!u$xIAM3Zo_pXn>2A)K_DSQ6Bi8CQ1 zDP&A|x(~RHU}K(d*0U2gon>R5m9>l2o}7m{C?W4(ui-sp^XZ^PC#+6@Zii64375QK zf^*F_1JM1NFJ!&3SzSuws}?`}NjXS=hJXWhJ^P!RZ1;4PLw=OM({j%v+Kn*t{M&oV zRJ*$o#Mf>QzR|{FCqa7~Egnr&wrhIiO~R{PWJ^nY{V6PPvwYCs#m-!H&BC#$liUfJ z@L3byD{#{-jZ#fYOJz82WjTAe)8PSxOB zIa8Y53drzgj>S#n_EPXN3jOs$H4PCsOYsn6q^^fTO0T#ezRnygBL~t0g%v!sE>@$w z^@VNY+_n>{vFtDH5i{+bPV$oi*rSQWZp3;SxK4{8cpd21DEfYg&VFbe^u@(zFbmmt zdzi?p^LfaS8?1Wyrrp7qP&ph=j|(pzgizW;0p$t=@GuTS7KzFf)9&y?r{opBJ&_j0 zZo+9<2;rx)rHr&`l>j`;pAcGzhTX~)42RQYguCWJ_qN5Bkp0+(9Ay;GA*Y&PQpwfXFh8e6J)7X_Z|?9l&sh?90~u+z{>_DfkQ*@ty<;;mug;L z`|~-e>(SKu3^x~Jfv$?AmWDiaG`AYOV3os~RH8CcMW39V3@|ZaTJvZH$QaC212w=e zYC39@*I7yClfw^zMnz{My+evD+Xl?sffLtQfXeqdOIK;o38n(5zWxJXe51bB0`~;4 zpBpfb8Beb{?$<5#{dpYQ@6GM9VP`QpUz3zKauei)t0z#=pZ93Cv&87N`{Uyf$rfU9 zrAg|a4Y>pzq07>xDCL`xZtdZfBko(Pno&N#MK&lC7I}>`VQo69s3Gj6Pbq&K@OyP| z!slAWJ@366%ALzeY@u7w1&ZX(TV`yIiXfBxYld+a;CxcUxfh3eftEES$;1j(1@lkw zq%_9edHE`|k{7@M*&t-n%H4lj>8)4;X{eNr1!BEeC^rnkw=?%wuUvnQHZ&C=$6_x3 zN4W>`M*J@b+`*+~Q93R|ZhO;iP7G{2BZF5W!8_E!2ov7{9k1sCs=xD1mhXIZF54dd z2Lwl5taK>2dJ${$CB{kG+4yS)kMeDn|MDNJz99>&E;A8_Ymj|=xBXA@U5AH=3E$@x z!n#1X=O~x(<@ja*XlQ1j*1-yH?$ts1acr;O_YCpR_a=eU`I;?X^oN3MfltXFgF+^l zUreC5WAGF&E<%8^oJcro8N0#6aIHE(%DaKt0BGSyxi{VA>Es>1NP0N zBJ1&sB@`9tDRo87y})Yti{2^c+nDK(q?>(Eb(LWo$YCBdt>M2bp?>ZvXIC`*=jR!o z954-=><9(QuhF$)>k}oVwtVkTJq^daux_|Jhsjj2A<L^n|pr z7iHe`^49~cF9AKD&({gl?<>t~9DJ6wUr)?g;Tmnw<|*0(QGT_y=iOn4Hw=0g>^)TG z4H6x;+9KUHg#G7qa|kS(lBiR&EP=BQRPfXDxPX7{kvP#!q{td17}SW&{=ieMO9HpJ z=~9KVB?2Wr+@(f+V=!(q3q7nMs*2pD*<;T)yP!;yoykfh4FAxxrLwWtX4%YAQScxg z&w8et3@fQu!Rhq&V75QSupKh}Ust9)eNITIJJFOi)-|ieY^q;dbsPlFlyujm%55B< z&B?aaw7(jAbQ;>b^wZ3CyW9Ays+zAo=>gBz3Q@o}^}V=p3w|euWJr5n@)%QIA1@e$ zz8AwrO#EkTzUEm>vSjml`zx_x>D-r>(~go_+!!FbO8?Ut(GkNRduSwAe=@u~59><}+>DFD=xwZMBY>kfg=Pm0(SP#t@aT8_!5@h>R817pP)t zqGG1Cgy+PMn1Qn0mjCnhmZW|@5z`Ay2{F*@70stIldnQxTBNaG@9^^ z?_RXpiGxx4A0T~eHa~NEen@ew4h>R-Bxl{tLLuhYe@89Qmbf-{;HRLZRiNc(=j-w( zP3W1P6n>*4vxAqa(=S}*?)K+%*6-_)ph8Xb2Uxp>+s&0GDgv&kYyT(k`yOVusw(Q} z>Yh(o;qx}{uHz;Z`s3Em#K5;TU%|vcwuKS?=7!BH(a_1)&nqUlKXV|mzo^$=@zk+u)(Nis6(d4@m5{S!;vy;B9u|CPyNQauKgHf`yx;W>Ew_A-#9fl z=W(RNXRJu+l0g$Mq3fJ7!K8rn4QJV3bw@2r9Ckyemj^lQ)<;gZWAjG_XG$Y)39A3~G2=vvSD%0aTRyzT_ zA{7s)=zBy=57F`rK*vd})neZLc@iS!jiTjg+7=S`oA8CUGb@k73sxK|i)Rb!cY)zw za_Ig1_`4vqx>}s{yxa5h!T>*5vCbhpsw?0jMmCczHR)y^=V=GKu>Dgf&` z>qc|^7SQUrZ8FcEXM)H# zdvoJW&&7i`E~Cj`##urA0yq#*!#;*m$~?YrEZ0gi&Q>-FLe($zQBYJNpn*zX$za z{#6+Xh&I_PVMq${ZTGUl!o(i0UOx?E;H253X88(5(_E8lICK_hip0nm^8be_a?rbH zIyw}vN=ZJ@Wa@Nx{v#T|2@r8eIC`9!kmOBzE#1GOab0&N^8Q;wXy1YMInLfZv~7Kg z70B>I=Gz_QCU$qD3Q-FeSq5yu+~M=|t*=tlsu&wjXAkBLoXgs4XfTJ^XE!-?3irYD z?5GJSJ3r>U+nGB*K#PzOtIArJZp44zpF&QPjgZbhdyim#8!%_%vstu5Jx493&Z6{4 zmID))#V*INQPInl0wy<~2`$OWRmshXr(|$OoUw_PI3`nFGk+)WL%rjD^1A#cAc!7= z@4bBC`?;^>GaX?=X@s2k+Ytyt^w|xYbOte;Qd->>!AJUrAwbi{#WCWt&XL&WzE!e3 zEW>?Gr9&sCR;4Ed(OVEx_;!8Y=`mR`RK7VG(TsC@>g|>=SRo@bBFm+F`{`rErTl|; z59EIa5~on5pWS0-uwHba=PJ9ulw-W3F<{64VPl(o0jstF=IID1#MWQr{{{?rW?j_0 zR`h)4a_EdyNp45JEjib-qns@dSP|pL&e#0bdvFt6$wagesoYyQPsb32d-6SO2M0rF zvxk{&RLPq+d0*$_KD$kE)Hv>R#k1;L6Iu-RP8o5$<1-@1>3kg;T@=+a(mRFb#v+dk92~Ot<4CP>+_|&I1LwnxfbZa z#(j3MRyuV}fM!d3M*n>5Nxl7i<*}-NTT@*icM{&`$hbnd_L&Sdp)I^uUA3)+IS%&c zQmA|L=J4XFVsB%Xit;6dWEI#-ErcvF?0MkqImYhF1UWHLvmC_0`8}G*mcBut7pC{a z{+{{s4|A2Mjzx8cT`b|e_V1;~FwvK7*-wNyAGQ@S)g|MHRqTJ_EC@V0 zel0@wRj_I%tXwr{1YNhbDvL}tAHgS9FK`a& z_;4%-TnoL`2QK#GLI2k4vve&L6)oL|sVdWcqceGh5H`=hzxbt+(lex;&*s)m>qSKy zAi8NFy&#Q2ILfun#n+n=!g+mYKCJka?5>SBdo3cpu4l{~3P;LC8c~iq>UB2p6cN%L zezayL@=_u``Id?g<-m)&KuRqTG z`W0T{u2n<(8H?TkHn%A%k%v=r%IlD9n6HByzQ`2O0=8w`9>H2I*7>N zKkO!QQ%tpEwDHv{%N}SY--ZF+o3t_3 zW@!#6ZbLT#Fr{abx6=VHR1vDzwTGjxq~5C0=!4>Rj6U@+h!+7e(v{D^BB2mZ|{ zG+$HXw8RZ(1&fV0_2;}E`u~b99uMH;wQ4kxN8~04wHDm^?xnG3zOJ76g?E6IDPG7; z*dP;<79$tvji0u}z1=_W%nGt0x{I}0INt%W<+V235&vd64p;#aS%y5ZU5l$}C!ZGH z8MO;ibV2JEzbxFkc0%J({COiSNvf*MAH`6tIp#W-xG_bSkx!%$#)cku2pFu(g1t@Z z_zZUBWHdo~6=OcC$Rlxe_b7JSNCNGrrodAJ=*gygcV-<>?XSHr*Myd|mjdExe}mFt zGK{NPpVDJb+X+9F-up_W1grz%Bvqe5QMR8lfy?`V%EY#pX3zEvaqrng8vF0kG;`?TTsu+Gu3d_Zw$l!slj zN9(N-sDTc4-jSmBgX!;k3C+e-tIis zP9ja0R7h-dWv3hLP@+2uL$yM+#)hL4{_NBB_((?b@bWVEk3(!sD=;z7T_Kzh4wjov z(^=aEodRw#OZpGS+*$=(wZeE$l3b|?-!WLx8!}I%HRD&mKM%jbI#W;=VtC-WF*2=r zSn=T82SWHSa2`zd|F&k}QOSj?z{Dr^^|nya0hNLX9V7j#vBOke;t@+cD^OGDybm=3dBWqE`rAX;rNIFhU+p)P;EqMh!@TO!e zV~^4Cs5&WRc`VZZ46gE)5O+j30Wl5w`otb_=_lPMe=~{&CM`WudBH-gj2`f`M#CTs zu&nEYF|Q7Y&}y5&4Q_n@&-p*Y+=JVUw5kY8h&e+__?1FA>bwTc}#tB0l*wsJmrW8by4dudnzzGo4(L z-aF*cGx!uy6*{t9EY%krW;4DPn7i9!I4A4OitxpzGHt6RCu3m$kaurIo+N98w{nTd zivb;D5`|^%IGftcYydRhEH+9V7fe;UB>fQ&Bqco|(%t#lhLan|xCp%HKu4jItUzZj znA6G?S)f!nd7*D!MHPiAfP1tPe89n|UX8}&)Csg=Z{itQJH)Et-B~$>);_at)Y$Nk zhN9D(WQh9S&IzqOnrd0tXa#OYiR~u^_g}kp;ON+_oQDerV+g#f$QT2eA}cdqQdgSw z$7AGrCUj3hVF3eRgu_yeWH8?boWR8$`YoS9Qmb<}lA<`#q8=lc$A3=}$3wEnLOMLr z(aZ$z0*LCmcj!(WFeAwcjJ0p50fg56+Il;$vaOj2IUdb7~D(*O s3 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�@0c2rjjxT*3hy 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 z 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

    aAzyTdPRw$NwsSqg2XNY} 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

    GdUxb6qoB9g+@(`4E#IJ_5kaTm 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�fe*l}rzz7Ix*E9Egv4z=+E8SESB)|f z8g6u#8+oA8>r03-L8Wff!h9?USQsXX>Y^x8H~G%2ixstgPQrm9fAY2*ft;OYI5A*^ z2eC(`-#0<6-6N;+jmVXRNY>=2ktYY3AX=6;&rs2E(;W2*V4W^E)pudy$&ovy@Y*#x zT-guEJX>ga^WgD`3Mz8gu93k25lsa8d}O#99)2P7sUW1>Iq6BWZfl(RvD>e4$ru_e zCBg3A|0LPB9~P;-Z7>b7oh=T?-ca~_hB#$Do zkCFP8XZGX7$16)UB~kR+!9>pNzpsZwnbo0oDxb7Ck0nfbV&EaOe6v+Fj{W2Oi0 z*t{#2u20B6E}PSzr+RkLSNYCTsC+3{GM^{djg*OKQ{7ZMI>(9**e_zOT=!6R;@ny) zGHb-Vy0kuy%9ro7vkHdpdBHf_kjOM6v#|ixtFYUAxkkEi4<^HLddxCn5SvydMEzMs z({0u9MN#agYSiA+`RsW;Ga?1;JuVR;9o3w|+@Kb7!_qQcDV5}Fb3O~1RDte?eB5OJ zyXzvO`WO6+0O4<>f{Q&3dYX%0htbKQ?g$n zT-&>hcCnqEM7CPjHeJ@>((mN2n8XeVxd2aWc_N6u*>1)Kr@U4($S1;GChy2=?WefP z;+P8%wgWkJ+qJ|Csr#STe&fmNJ)^(Fyt1LaF*8Fv^+fYTbx$=DE%NyYw4ABwX2)5yPID1nkuH3yCf>7ob0eZy(rcRlioEg-dXgchkX$W!N;_Ml(U)aqRl z?$(cyT6+UlOfE6n1G<5GRD;OW=f!4pX**Nr@a}2%Lr5<*#a@nf@DLYOFG-(9#-N^Q z=e)@q-I@7spalLP1WolBFzOXDH6Wpc1v#}C^}|U}zb*Os+wPF+dDQ?lJF%PSP8Yaef#L9mvo7e` zUtp{^XbjaEZme7M>r|GTbqgUORiMPRL-RLk_tPmXXiY&a+(54<&WN_ur|2o_tyRuv z2!Zb;&WIr)=O?@OC$|MXqx_G+CCPKTQd; z_bp~rt+ph4A%ldD8YEwLRCxg%%)JB8$ERKIxKPW?UscAHUa*2&vMn7{(bQ#?h9)Ds#C+S7c}5e+YgbA?b{pezcH;QM&zQylv%kJ{ zV9~b3i$l2YXAY`uan9G3#LFZcLN7KoqFVPNIYQ?CP~ zO>uH#_ocXx+Yg=T=K8aB(>1&OtLtqc_D9qnDXdq#vb~Nlw4*^6;$lLVYX1k77;6v% z@mH?G9UE-7yTI_KYM1aJ_Z?mIYe+<5Law@k0wIeCL!qIXFk&f68kJn7duv2O1Se`r zKtl)=-clWIOF)H=QvyfAl1f(mg(m95HPtw$SY%}lUHeqJ<@1w^h3Do2t|5um4W(el3d-X?;=w+JEGQK@DfOW;Ul12=cvq-w6f`J z6xSIJ%>)V59wV(`%F#MpMS`uRUOep`+uF4wo=i424+{1~S;Xg8A<{uAvJ#xkpJH}F z#Qg(&8f>x{Pxi;ir6T1C90SHu9PHoG+cpLqL|0*)LI%Q#TNrqZ6{R?5_opLRy8U;K zJNo7R&4!%XZCV_2-5=Q5)(xV?*4&u%!9h7>VA*k|7o?4zvQf;qPl&uvl$C7c)`N_b zXh!G0u1acx$7F7_I?IhyG8|PrjAW+KTI1tOIyXhU$XVy8f4^EuMja+-D+f!o5iC|% z`E4Q^iID_Hx80cyoQzn{*FuY8fcKC(O_pcFwaSxdGgF8!m%Q~D3HFXP@}xvOQ?7o}f~b!`>;>7O~?zMTyvI$!T?C%bp161+-2w zXK&bF{3f~1HI(dw=XOtHtA=!a&pgMOj6brCcxBr? zHyVO`%8XSi8#-4&eC`h|=yV5G$UZt9yE`RUJCvz^(UllU zF{8-Y%}hV(va@i3*O-kjxYvz%STOWCSvmWK`kEzrjMD$OAbVu(bmEonk9-HKav(8M zaV;K&piKzs3h!iUtNl}8P*;PUf``K0(Ax|77wm-TM5r8U^nx+l4Rf8FvzGtGPO2sL z(mfXSRDO~g*E>OXkq4&|EC##`GgzpC#8}x5!4yn6n7qEHt7J=ZXdjJ@U9i<{nTEUp z2PagR1m;yLC`w9n>^X*=y5K@XPd=J0j9v0qVB2|8?Q~krXUXu=`Vb$Sjp!$}gLg+} zk7N*AP$VIS}so9z{YJPfH1IW`+fBqx{d%=6eS?zqxZXR;&tt3>aPf}nM z5vl7)>O5|&xl0pm9y{Lrw(MVhW94_K4eg6ljbZB(?!KG3z}?2bzm2c8?T1Dq@8tpW z74BnC&$BX%ZL7$I;)p|J$DcOlm~RTkPPpv4NqQotMA_1(p6LmKQXv%O3QEPsX$e@Q zn`=WVJPW$wv$6A;FvG;!@6|}LA|KUQvDQzm`|gLPzbl7{H{WeGRjqTwLqclzQufXD zA#0_<(C2fONWCDr6Z*>#DW34Y_){RnLf2w z*|Ur}bnsSqxN#(X%(L0;s*MV;xQA!Az6QSW82Xyy9l!kieWLIl$p7{gUj2gpJLfBN z_A5~Pj_U0e3yj0l!Lr}ha+m_tJ}rPlijYSDDxzqB3>RJzd}h&2`4~ z(u^X)%z}D$Jo65DBjneDYnKrBt@cJZ|D4SW^3#4T%U;PbAAcZY4OKeBa_m^~Q+Uy~ z%xmFbDqr7116B)sk6)hxZeU;+Bwe1(CQwoz5m5C-#0D+y26XcE0Ncjs7NkrK1(|$( zP=!&M;@!4PBgeTk|A2&`UZXH(`5jS=!m-CttzlX;UO375+Vs0UuG><5X$-f|T)5~X zOmEmKvN0pbi&)aS8`A}BP-N`~X-`FS>|ZpN7_feE;M1|F8>N*qSN-^KMbw?_(2^|JON17nA=i)reNp zbV5-@`Ls19<2_@6G!Fb3BuPLvC4;7bA}k`AMiD1MC;_5qL6%x%z=Z6{^>gcwj~6U| zUzdKeO8*a~Bc)>Va#dS;s$vt(8hSuridFdT)tQVC4CBLG>)$P>nU9{vZI3^>>UyAa zVJFTignB_-&gN}`)$CyPilOkC&c4 z32Y`cvWs;_q?s*~L5VHxHiuE6GMhMAbCMb5pCx#sCEVvIT)=9k9*qKuv-?TR1h~|K z29?PTSuQ}C=Vsw1Sj~~o>elGDt)+j91T4rww+92gin^z_5{pRU9Aq{L@7}(MvW6;| zvl$XO)ji)8gy1;UxRU1?BvvuWd52z>E2s04HFNE&5YM1o?}vQPWWoP^N$0#423>_*H6oq^EP&R_;27(W zD1l|eAeLsRKEc!|jyP=zoUos$VTu@y^=Y+0Q{+HgjhHC^PLl|7G2x537)Sa8*TGhe zr~)~at|a^VR?c}VR;JYcq7sLSsNq%+(#PI**~v33mF+vkzPF)rH_~K!TyTyE=_hI zVU_&gFW0jB0}tOYavuefGOZAUj9Z!+9yC?gow>f3yy(1YT%0^z2~yB#^O9Xr@64ul zow+2WCw~+{mP2H`sban^mAq&Rfl_)%NS>1vku5OX296Gp^?I(qHP^|iBehzFHh+St zzNjdhVg37duSXBK;#BRD2A`5q-$=dTPB@KS8x`byU)(=Kz6%d}3Bh3%Om9IT9m{da!j*oO zU{}o$HCO$%GFpqT2Aa4&5h4B*5@l$|&kkice(mBm+wTj*4YcO45$YU>Z`=%xOYUxf zFB)McPYag$P4Uw=uT`jqUc_?}s8j)CT&S>-8RD8FykM1RRB?|Rw3{92$YVI3nSmnL z35ay-&P;KGH>4Q0lu>=pWyHS1F)UIU?xSsw(%2O3V?SB;3IYlEO#GU_Q1$?fcyv$ zz8oo)05Hp~&vLTPI&}F&oZNxdl%xtZ=naOc9bh%NBXW#FytH4dL+qNqqnPyqF70rI zTWeX#>2ZWJNAs;CD=Y4C&9f5~Nsq6l6hi_%%}&nk!xQO{BrbnB=hR!=BGzr=V>ag8dV z;+n0XI;DfYix=XR-}s0>Sd{0>has64pokV^K_zPtRVYv&7s{#RY0{J&H;ZI&D>I_% z09V-S&2&<#2qBt^)eJu6oEJ_-RcyJlL>5DZO^i_ni93x`az=u|(^t|j#nqCk{kjwd zA!ez>tL?NSgDOWH_STKbYr`=qfIA|J2qp@_nip7#7TFr&_9b1p_X^aIt$gy3AZ+Ee z@U@1zZx-1}QTG}bwnY+(4$ZP}mF?4IL$%e6dg`_AGD-Op1N_Bfrpz5d)oR*>f#Was zF-fl9R7Xj$62I)36u~xyer4S39|Z`DfNSXRXLsk`7&dhdms68MuPnmu6ov0^>Fi?D z=U30hyU;-Yt8n|hXn{k7iFFujeovP&{oA?>>i@5c*uPlwX!Xe7D9fmywtCFzFtq{% z)IicOap>!}N?Sibg(%D+%n2;!_{cih#|KQ=va?}}s_iOUTGk5Gq?@ZZutaTs8VJjx zT54O^Snb09wf&0QxS6>m%bW&#y|TNR%HsU?SNPm?{q1Gn0h){YN;xR3gQbH6cEMP= zwSbNBM5sUc()l-p@2!=O`jFqGE zZJW7E0`k=2_0}Dwgx#H+FWtukrjwnZaE1UvGbSS*ofZ^Y!NE++lQ|CZGzph)2zN zs^#M#*>hi%i7`VEHV9O#xSooY=dC>;*O7ANs(qJ4V|p)86ed)wnqg^kwu0BuEv)Zf z%W1m~OgPI`+-$Yv3SNvI2?635gyMZg(j~B-l7{Ql3Q1G>(1ZgIJMm&)wuluDtKlrN zzN58EtFVv~mhf8-+~-^d_DS+2uXaDgB0!Q}pOD}7N)LqRE+UMWR^9YnM^l}@GHz4| zUMe&V$RwXQ6p6Tt5v*u42iAk2us_zUGn=UOXyls$jV8P(d*lRd(V4D=Z_LuHoP@MZ zy{IGO`91NT2318hq(DFzf*LL%)zs7^!&_ygNk6AS;kS5BZ#2FCHrQUUv}j*lkYlV) zbR=?koi?H6^0UUYcv6J?Ig`V$ES%*HG{B?BnQUu2JPFr^A1{883IH@&s=a}f%h(;Z{RP-Fz@dJ#Hw8JJaXXJ7ja_`mZq~g-Cv1i@EjmqUWDC* zY+EM}cBR5Y$H3nUE4vk-E&E7l2!NG=pt;Lz@Vh*=f-=6EYR~h2Bg7tTq)dSsxkRMK zE3Evk)CeJyPGM{*Jn#oao1iq;(si9GqrQ#{IW;-GcJbHL~o6XH6-n(Y@PcbEd7V%(%=^uO3dDtBL+wBRui4NMo=T#1VU*^#Znw|m3b2{o$8+>St0((9g?miEwj01 zYvkcUN+BD%AF4mR$-<#dag21wR)j8{-lvbwmA zEHYKDOMdkmI#s7-cd5p_VXh1N=uSKjFa8;U$!1DsF6T2o?&pS{niXnr6D}$%{GrLU zhE(wio~w7MN6pHB)}U7A>N#v9S6qqWJlJOzY(ew|iNd@^9t$srzAHd!;#hqH0NrgsyD zWDV88V!l4sd#(LqGy}3_Bc@9PQO#>Y=W0!cnP&aCn9wl@ zy%LhT%K@UVXb7DSSgx=iAT1~QHw4de3vP&=xS4gCS#E#>%q=WOD7|P%l_xd?@4IwK zU6Y+mxSHIwC>0vya#;_>JE8fcV%j_N^uAlI`LWFN9B<}M$eqA;m9DTQOR&O_5LN_R z;#tsuFPf@E|7|u%>@fkAxvvX4qqCk8H-&8ft{(C3z3GOWdYxzQ_n!cGq%R2R6N(h# z7*-6!JtUbp;Tie@A=dMcd?y2?Qlt6KdX(W*0&RV`FD#1*Ms5na1G&ZP%c zlR;6I=bo51#-#X#Wo<_|*@&K%Qg)BWk{Wx?;ta1y;9}$bLPgAuumZ@Y@0w)Q8hIn( zJeKHa3+oBOT?xlU5>^FQP_kvTQ0fr{M2bRA_VUfQI!^yguSOvQsJrEm2{pRto=1)r z9Viu$iN!Un6*CFzNhxmlWQ41cyqEhz?AFP{w6vkY_^TwASvyiy6$giOF zaP$$?7{qVVL=mZ?Fr^m#)BqB_zjj9KsZMKfVK7U* zc81C^$mhFb&DYhRsHI3N6hnK4qNfr-R|hWo1^y2(bW;lL)AUW;zajoR;-2Jx1VjII zEB`MPva>GyW0c2Hmv5ybv-*c2#k&Qwsu=zz9-s&5?uTl z&bMelNA~W%w5x0`jT2z<~WBP))G6^Ck$vH2AS zJue1FO-YBck&P?vjTb|b8B}~qgcl5)sxz4r%Qo81lz7Gi30@-cFk}H9=%6}u&(!Qm zt-L0fGdEsyWoHOkDa*3Q?g0D%h5fad5rC3n#`K*~9UeVkq)tUz6S1Td)cr1Fc6QsX z+k`<`6RNV7=)fZXYu|nOTqaPR+QwC&AUzF2;24VR9DQhubhG&CrE^ACAeL+I*PII=M zW)HYyy{_L3^1%5Q^!0^AwT6pAxYDrB8H@MHj8$Z;6yh!VqQ@p2MN;5{;}<0! z8r0*4k)ESy@Ka#5QwnJ0Fu;RTRHiK3u+ka$h@9n83JtdCAN?8ls2+_B&kv}+^&8k+ z1&1ocD|d-ua@I=$u{3ygfbvUIgm}bHp$lx@c(L>Ft(_J4FfuwRz1gHvw1E4ufOUo=m13TQz~R zRZE&yQMFUs6Gh>KHuiKj-x3m;%y6nIk6fSVXojK!e(Fa_)R{_1k-k^g!$dKR zS)|v3oa>77RUL`e3gg4Dk6JlH`Ci3~J7|U?^Oc6426kyfOM9=7<6kby6gj8n4ADuW z7>Rc>RN~1l9~yNBt+aX71tKsZJ*%X}U$k{n+~&k;<8qmQ8n*T z?oe?|7gx*Rv}3R}IM1M3=ptdXYv%NvCXgF!CRgrMaaQZm|4cagVYc7LFW#|TF5J0x z36J7!9S^2mAZFvyhw?6G7ajm}R2^8obi~+=IWoVwd_!E9r~|(k;Rc)`Uap;RFU{T! zl5Mq&jD*icL&lrO=TT>#aJzF3{{x=2dX1Jn&S$osVYu*Nvg#)Km!z0PcP+uqj^Pv- zo<@{uE^?7kiV=;}4Yb8OnjGaj8{FB0qyVec24dJUBfL@Vq*w^OHXyq)dfsye4|MwuwOiMLuJUbyn|x)_x5LT&xYu{B3GU8%gHk`n8Nr)eQ5;8PW*7RI3ZP6aRII!bA-AxW3s z02FP3tw`t*Mb|}G(5OGl3CyWvsjG$0Bn|6AIVHR%1txuZQOseiLH1XiI~K&P+}E4+ z3>t40u$nKKS%)&?=dLLI2s=t8`1y$8G6Ssj!JjeNE)8Lbv9^6>0kRlrPF|gfpF*Cn zp(D0>eK!Cn+@0t;7}6g2vF@m7?~O>on!hiu%={VW5{2Q75Tt1NG1;OoFjz>sW_jJG zI|r>!(Q_Q;Bm&~HEKR{=C|%%xeV9Lb(yPN$=WdNy^hA_J_(Nfh_yrGmgbtl)^$!|& zr<3u-u&)VDy1z2BOSHJbEzF{_{tynk)jJWFdxx+{;$$L?Gn>oN5GY|QzzH5&6!leU zU^q5vi)#R#%i-Kc+Z<#HVHJf>H}~9>=7Z}j|9CBU@r`V3yQK8 z+^Ks_aeb${0jcd*8NPA|)UxF1l{Fzhx7gn>&^rbhpA#c8yI&!yGY!;3y3pWfb?S^f z4x~lRRzq6q^3!H{tNL(Z+XYYEvDa^{ZUO()my@HNnj?0zv#`HM^}+$_E~QV@T5qVO zKB&!FHfPw?QY_H_@0*^em-HSF*ZHmetrCkn;6C^$%+&yRwNxV@aV?^B{X4!GImhHP z$4Dz@)F8{y_2iB~?toDboP0dG@Vq)UR)AJ=y26ef5rNF+xtErY31xFewIQ26l{UjC`L##V_2qxoE*{isg#UWb z>FxhA^$p~EPicO|t^dqvb`Na-1ZKq50zH8JLLYgGEZ&`EquYd&&2EO9bg8uPaVV&HjGVOmY8ql#1-%tfev*PR=H_|JlasBHsxY zAb^ks3OXzbBXikM9D~K%(AZ!tBSaRL zx_V*?QPHtHBFQM3*G6!jm>pI@B`6&LXfLtF= z_O>>JZ_?E$4JvKq-R^cglm1<{#mxWP=L1e3Rt$-`tu{XcW^Bu_I{;DaBM(wj6tVU8Z* zld(`_BRKCFU{(3`0$eF~`UfE1+(D)hSbX7vvnPhpNk*V39bq`;=1NU4eREQ?!3ConUhxA}TQY2Oi3yrjk=zuEh&7VDB z?=m7{6E#t};R+ymHf2;OxFR+te6xa*x`IaKa%iZo6a&;#2#y$`5uHdmZPY=X!bRd( zsHQGO1k)0U40?5@hmi^fCmsrio!JQ1!J-_MIZBzHqWA=4lgbS!t;Q%JXSu^FrC`BM zI;;`{U8Oplt<0%Un4DoGd9pvfOiZJPqtcZ!4eTaqM7q?bq9$aC$;A~`0}<=nr_eEN zfAi-#51J0=YTWFU51*2@Q}Ha-wW{wPSUyGExB`hC$n~Zy5MiyA&|x9hOYuT?t(W_* zja)Gy8`V&fqfC-y(i2r3^~}CXrJJSX#?&=8n#NQdFC?W=Mh|syYyFOqV-w|8p@PQ~ z473Uo){^KM^Nf#NvIeBNS7?oz6Dysh*Z_8GmTLb(9mt& z@a20C#d!n$z)S{`EgURBXdbh(F~%jNh#w~WL(CqgVz`+G8LipL3{D#J47m| z7|Fk;&blZQ^A)=Gj}F^jHQQsh_V2ERoL`@NpJ$R@xn9~DT@+yj3`aN}Oh*mfBZ2)d zpLg8BjwJD}{kieiMXxMx`V6lqcE2}y_l4387o|9o+ge*+$=pnNm9r^SMG90IJDbB2 z-_Kzl4vO!bhNtsZ2vY}B`b%&uq-wrLC~;eGtfa0Xis7NqFI53nJRjk5T7E+2*itWu z@7$*v5YD!P4_*{Hq3jJ-=MA#)TuXE2xEp?EtMfM8U_34_LgL*nk3nzCT#pL9YN5aL zyi#5J@?BQv|N7lfx@WuN{sgeP#~GX4Ck-IV=zqJfIL4)HnJy?DOC2B^!;E68JUnd` zwfm6J2?OQaL9i)O6ustDe)GpfTHq*#^!kui&Dl)Z*dX`fv+RHPC9&F0_ z*q@XEpgPuy+*(UHf9cLohFUe>KFi*C(VwUR+&1OD>`&Z)&bF;0IM#Bk@^0A2_QmdR zUoO>OaJ?Al7Xxr`^g}!BpXnaJv!HOSbM%`Mh#Z%vJ76(mcoK_>qebit2<|)cA4>Q| zJAL&wIP&8tc=_x&9D-`{X+ZSlcHP)`X$p?>e7hOn3zmT-SO2vvtw*x5zz3SK60*Uhfl|2hY3Y|0+@V z1V7g#`TpJrd^0Wo`}+4ke{+QGY)vi9#4N1;GkP%v(p_a4b@b~`cly-yVSEra5(WVS zfwTlrA%(UEDF_4!4JH9tDpR`0ILy>kB(oia!|Fzbs+CnWsx_+grnz=?K0|%MQbn-Z z)y{@bbM<#G`*vl^oYRi95YXMoAzU&@)F)k z0A-|ZBzS2aqC1Q5SqX17fMWP42_N}gn@H}ELHMjRPCN%yeClbcyAS{xNnQ#k(On8) z5q^O5E6H69AdNID#Y2AAHIzy!Cy|x(5;3Gssu$<32p|owmGssHU?c4&y`&7alJ*ea z>4x7(cG2AVgyT!RD*(ii_)}iOhvZ3p$?lxOe@VP60o0LdCEm3F>`1-I?y3Mcq~6q* zz#%K7-$^ftL%F1SsqVr6dZgdUFPTHTq@RR$^5MTx0c!7=cO^sGzUJ=Q0Dh#eWDZh? z4f4HFR1Og+p%=&u`BT3AJIGpm#;z-I6_l6xnYo}?Ld;;EzFCTUXyK^+{9#{3A}LHG z%m~Gii35xyC6ziH`eBd^B@n1#5yo+HvcC?faFU9WN;3Q9C61J1X~*b`!ya2~fuU26 z;hMpQEoFw>PHn{-)4Q_#Ah=KYcnJZ+0vlix|ofVGNT|+ zjV;T|mL`Up{*LObX5&1oXkFF#Mrmo*1qhoN)mfD!- zG#V)q*Gs;Vb3yl#CnoZKKhPij%`^cGS@)3WUEUaT)Up)`DytnAnCwC}=AtI;RqZ2}VTTEWHs`9B9u_2M z*p|l3C>!%xB&xsHCQJ%SDpi#1in)=pb<#&S!1#i|$F|mqK}CX&BS;c~v`B^}oU;EU zt_@D5ZDpCP1-Vw7UvZX>eJJAXM{Bi{#D8i#6*cYxpQsj z$VEn--bqXmHoF55`OLJkO2aZSO^J@;o(|O5UC6jFEWrLI>0?VKZcENH$WKgg5TQqN z6J0#k6xpiNz{4KG}_YB2UMV`LrWZUjoVGPtoey9Id(l>he>ONu1o`W zW^+n#n0A6sxsD=tS$A{Wa$XuFgLGb9;jQK2kw5Zwk#vtvV75WyGu(dLtxG!?ahd-# zbF}h~kss&vVU*fLdW{AehsLVJ$#3qJ7fIcP5lg|E6mIzfy8%AH_(o3b0~T}Zgv@M> zBQeA8V$@+=t7lxC=PC>XaV_ftPwcVB#Ti!-9z@0vP9mXU7=P)Q@AedJ_hnrlyf;*uMp)=%sMEYnEYXh-^b__1g&C_5%7$7gx~3)5hu)R$@%^?x$0{ z_zs=ytv4l)LMh-0pzE%}$0ZR}xZ`WYrV36f9-Kr{U9ep^Y9&JGd&#dHZ{FfAsE9{0UlU zV?^m?PK_#LpO}HQklw`dMxPM78}zs;PbtbGE+-sGDQAqgk#Je(ol(p`#Tc}sYL8>> zB%1kL8YMmqC@UpQQb<7DnTe=)dsA!`$+#{bH^lNW*cQvp(t8^yn3N@rzG)?!utIuJUf60e8PE2CLcVRfvTMHuNEN~Mf$~?I zEET3LHLXIhNbWsyF%=OSRp6<*QJ82&nt2%#07F%ZM$IUkR0>gA71N;#OI)QQOQVD; z>|n{=usuVdO5rEKoi(0AP?iX6$rvD_Dw$POf4Xy9lAFptW{)(U@Oww6m5vu z%BP1+n}ffjDoJhCXoqO2WVR|=5Ve<{Zxt`gYIq}7jGC^_6MUPNQ8|XQbsjl~rQ0d8 z0VX;$&Jn3j^S^vx)SI3Tbj9l{k4d5?fN$qHBOY;uy*3#|&hV`&&qCK@V|<-gJUm4y z_Fz#C5qDz+nzdy>x`KFI@rQHt6osODzPTsFk8!;&x#)$nT4!nDZI|I@e*lkCw|l(j zyD--$BGoqoGS) z+ZF{qVK+~M$C^vAzf$s~(alep5+(LzoJ!JV@j7aOY>!JTT6)X|1-$}X9-l7s{=rku zkV=XW^-8PzHnzR-gASgW*@F-s+rtf68<(BLQawX%k1j9%2(Z8{Xggg8{GgSpKWF0h z%(|yuXPzgFscSIsDPipOl34?4)d;j396`B5vamA#(;8LEEI+{`)il3<(Hn8iOTjLhx3~K4>yhWZ0FSX#eA@B7qlH3@rIu~u~yHv+eCZ8OFjv%=kSNKJ@Ky>9+L7v z_yYcJ6^TH~l;Yb%R(sAu%2XPhS*r~TFe)BgD=~}am!xkbkRxC~kgQT9H9wXzu;Gt* zNeROn%2X?l9du7O$0pjaYb_Fn{}D9cHwE}kmDtsJxc{)SN04=g;I!M#2z(W8h^ zOF3w(Y)K){oCL3ZJv>`|N%A;NijNm9!{#z+RFLqFAp4!+nbU8~6It#K_wBS9zR_IZ z^*7;=+<@nlpB?>|m^X^kV1xec;l=v@A?E#a_D0CX!rJ)%5>CpR%8Lr$CS1y*XoJ!* zvX%%XC>GnX7zH%ZNkEeS&s-@-%6^t|$@Bli*E@zu+AVF`-DNY&wrzLWwyiGPRb94i z+qP}n>ay*rXYZMBzIor7{V(%Z9(S&L#flYi#&soR=h5-LMi4oQn7se|Bp-GF4y=2Q z+3@&>v-LdM;`8zO0E-!Di+~8~HxpFwqs#~EC*VdrQ@rsYoga0udl%>nfx(~~v|$dY zMHm`%7U(lVSNuoSdx&a6A|*b?00JXvN)kG#eQ*79!RMRh}8H^z7b|yA0Q=r*nfh@1T`exzV z1BiK3Hk%K0u`L-d(QUgesuJVaZMf6Oeq2fp#M<&snF2F7grm3diG9^=7zKVcQdH>q zrYO0p=)dG(hPP)O&0+mRXJa-6m)P7x_%-;5$Mize3_*~JOIB%#Runw^+W22(@DmXw zU~q{%q1-%bBDkmo$>h57u7EUsqO8nY@DU2^&ba)_MHA>lr7iPAouA0n{kB-?B|@bs zO=09C_7O=TSOO8H_IXSo_`-1tW+X@OZ!WOBBO0ITy{dnZB#O<6(Du02BD; z@Y>2=x^&-VI!tr8yxd)F>;7l~;)?nyH4xJyYX7p*bHRRL1W>fw=ye1z*&RO%S@R}J z%Ft$uTe1dmOkk;nfpyW>l=Y4*pG(NQVg?;GRoGN!P85|W zF?H2+^qG(z0S2dx{OuG43wAh3+ADTF!7mdy(`%{xq&kJlb7gNBQN}4ulYpn4#}o?p zP%Dz=HS|;&9iaBjE68sfZ>0te(5*7hHJc2}xT`$Hs4hoVQaEVX?;F#fx+qjXB85Gg4gJkbSh^tQZw5Dgjfnxy6Z0?kO|~1B zuGkT$mowi1Rv0;kXdnmfv|Xc0r8t`&?g@M@%RC4Xa{Yy0s{^D%%rKcVNQd?@dgBM? z$9w@r2LY@_jbAx$t%D}vYb`WpSF@HczpXGFYaRQj>%5XVcgUnFb;sY{+JHy3s`l%} zh`ILJK2=kud^N8gM&Jinw_C1P0)_6ZsADHE?gJWW_^?$P$4=(ymrmw}b3_zR&|o+G z`yO26OgPHzRqgH(z4gFzc3A>mFnIj=y+fTc2G7Reb~EZSgx6>}QW}a!jxy}M!rK9M za0Gj$JZ7acOpX`!#k+*d)&VU#`F+(PyJ=OsR$6&ELBt{`;qx8U4!)e)4Y5kE7y`kV zc7e2v-6Vr}>qlS0#1e0cuka}p7bN$beeD`5vQNUN^g~3UV#{>sV$)B;Xjy`~SnVCb zYOL?* zh%G7ipC4MwZZ{sDSx@S9u=lqVS^U0()O9g_pwzpRc&o50DMP3xHwaWEF^76sv|WNI zd_BX_5GC%ZU-(#Pe4dz@^XTZ)TZ>=XJP;K>HpNxgY*O(qI`9aTAMIo z0D(YIlM8{uq{qPGtFYw}5=;L^A_t)_Ij-Rf2%Nm+UhW1AytsoZz2UIQM zfwHTRU^+8{X0o~PB`V0_S{oyiYVt`bqc|4=kFBVEU^k1D};LHoV2D?p~ zNlzoCd?WY#7(59$i@VW42O=0e6?=#%J}Nipx#Ss5)J)cN%oPdh%_;P4`jNBNjv%V( zwMI2j>4Qbu(&QmzgntdzA*x9t9L4<1xiFzQCF}4SC!5Z@rdc)W`}GkW5@VxQVMA*W znIH#0qS`DxRl+e!u>-T}V8>aBW?cu)@n`J)+QuN(AuV`zV?M`NG>g=y6)ZNjO%i;x zm~k7U$)qUP@pc;uL8iHzg6TU5Fxk@Qtf-{RSJfzPJH`3^^jfI>W`%5H&4r}O-O2SH zSxq&Ps2gc9ZD7}^IoY=da~Q0`A!dt01H*S&aP*nXMUih3!n#{}7D?xBAa+OUf^73> zQY41`qaZ|oH_%`}b7s~3URyPfBKggj#*;6Kr0?N1Hz5OUS>J!TX<%aINyxP*H7=pH zD&B<{%8XSRfbo_vx-OVHHU~{zPcv)Hc|>;c)FEdPj%-e4xg-L5lIL!BGgs1Dr7+?Y zaMJ<@Otnhm4IGE^xH5fz(BNBwx^6!z3YVHGk@dKk-IPbE@&?R zlQ1B6lN8l_6BWf|ORAqyFOLz~j8$tk;G4^;--yu^5CkF)8^$nbdw1@RN z1*Zr7N1P}-$W5Mt-i1op{a4GoROyX zCcUPlVh#|oGQoRJp}q++$Txso#~K!-w)o6gEc$@HpG=*+xNMbfTAK=_>8yG1OQ2NC zDf;R3#@#t`wSUI4?;xFo}l`iprc?Gd?;4|9M(8{o_}?q!tL6HksrKk9@MB{KSny zWujR;{wCc#zfL5UmDlq5FJB_CYKEG>>gGg4NW(BFVD=ACx1N#ob#GmAFKNvaMtyZy zlS*S|#xEp-$L(4h7m-E352oZ>Z6u*|+(w1!bYtLPI5P*AF-jMkJlLXf5XM?zTgCeo zhOrAFVhIZ1-7de{XTei+c!Zqd-FwQ=cj@=(Tg%GE#AgqIV|BCb9Vhm&QuL<}7X+5( zOths1)uJ&C)UDl92lxCp7O~(Z4=H6yrF)zAa`I*>&lYd5#qNU!e#svA74Q9UGC=6p zk-dmaTXy`o6i@rRR#E6*f=>VFAuT!=B57{(mn_oXh{vYjaqT)`G5q9P@UQyFE^tpk zv+1ec^4eps_x6C0zENgoU-bnjrgQ4lx`K5@Fpa1r)AM0=dKk?Ljc|O-=6@fIbrIocxe3#snd$2V7W3 z{5`Q~SO)<}ncHn2W&b5K|we zb@=lc!~z_ArQlDe8q`X)$p!nW^rzd_Xi)c<Ary{?evS-Ld6Kr++F_V&Fwn>L%=0K}{HlZkScrwvA-8Vuck2CL zjUlb<WD;{fZPRUw=g?YvHm!=?h#l12?_>wGYS?q@exGaF~S7v zJ`BT+8SBk6^=-TS-zU`UnBLILl#%?_DYFLuMe)59H`;@}kf}~=#GPLmGgQ_MlKapH z9N~KbR@k5vmV2^K6sr&(D8shQTA+bdK@yg9R{RXw!H|wTqU({^R%`^n*!IoZKpl=% zm}jiiWSZ|x=Wx^n*JE-n#O7qYxm|KI+w52``rH=$r5)KgPjD@BJ?wxtgVRsEEsMcz z$u5SF8^G~q{NFRL>G}5Xa%1nw6K4&XEOoTFKf3dt*Zw6L-%($o^Qm4IF5eqh>+DFg zkDfCYA*WegM)(z%N8rkAPRFT~o}h)I3x?TSp4Z%tmrzc}}06J1+&|>zi_9 z<0Sxfq?pWw2!Uht3FN{lIWWVqV-OPxB7_BieGp?nS^@*RAjWWU95{$@YR`o_N1Z*Z z#7K}SKgTL;Td$dvP%LBU%|2b(d2hYj-`%b@a3`8W6m7K?Vm+zpqR^&bNs?tjD@|c* z;_-+%Ha3TMPH2Ca%)TI*L2{BmHxeAA6e#4%lnm;S25Aa`e;ASL6V)y6Em0?QtJHqG5=3G>itJA^y~ep{pu%rAD%mX1O{xhp-Mlbr^p~Ora?-4u%x)B z%Kk$clGfjN1WZ&ph1wE*I@SJA*^Nlb1floM^77YmxDyD`?$bZ9{|JiX?x8qX=`*s^+qs zW(ArgD+^Cc&TGr!f*hN@Ft1f-@FL`iw8Jv7JvUH~HOTBNp40(0 z2pv|Q;G;WeQ>k{XhXSL+IKSr(auvx&@6f|f%simlta&lN-daMgn*cZGya+R^dOw*i;dKNt} zgRxGdBq>jYUX9>6F$y)>>lydNVGp`fGG!G}#-FSuNx~F>j`&1{O3D3})K}6C{!$7? zO7S~}ECLNyZYBCBBSXX=Iij#9BNioDLK%6+(tVUv0;sA*WhQJy^l04-a?7i1xOF1x zQAchBNqJ5b-Vjt5Q%;(A+6Ad`q%I#vS64NDm!j;^d8W=&kZ{5p8qiV1a%^LGI+D)@ z%?E0`p(OrG*m{p8)N#SM)+itmB~QiS=4&gQ?7kAeH;sEfvPl^6G{kr{x?^^KQNTI0 zd@%9pOzF2n)}6kYV@F7G-nz;IUKK5MNKCI`#o%BY_6r8Ei}n3JjD*tnf>UY* zwd80tpwnl_L4A#I5*u19i}cHJr$~^ku&^z#!HA<*O{w#CCofyJeh6b$D%>>Pj=fEI zebx>x`t+H>J8w@Khi_1m(z|H?=sD2uK1oUgGdZEiI<4YiP_UPA+B zZajP-wdlxy~7O%RNs zr3tlHQ~+Z%A^arNSOFnfP!R0?{lb@ocOC!MvU*|#1X!_7G!0K)qXY`~%#!Px)M?3m z3CZYh!u_HIugRvlCFGT!$r{YG&C1RYu3ry*bNV!&yP56MKms>*X2=&1_8OX$&|+Xp@p}?`cuL6-Mqn= z!@d*F8-xr^77KQxpFNMTI$da|BrG^7I`}C+JyQGqXxsaEB|d(n$#BJD4bw3zFQ8&dpUwr87r2YVWz0k%M23xq40IVJJKS z@V9RF3|Vd0c3FJ0_EUoK^AX$N?0h0=*TK(7$}7lxlMes_U@`ouP8WQxl<}pR#IVZz zw~OoD2YS^=<{shm0Y@=5%vocxw++F5IoiCvBi zOIOyw9w%cDvaapFwqrDgeM_;}Gor0_cC`FoIuBC9V!2kU_Pe@ScY-0N7i0b|xui&@ zUu&tfc>{}vxPM7wYeRRk29v$mS8H+#=>pNsq@kS*Cfj1uG5xKc8B+~?!L-vQd&F`D zTfRXxHIBwki$&WiNLIR(rFdcg)=S}ymDm`l^`vIAg&uCN@tx4J#`!2!bFK;U_0&4e z?)2S%5vt1l)H|qG$_vuczPi*zKNX=x=?2Y*Rxr*=$%0LcmWSNI5%`*@?$%>F=B{9J zvPQZ>W!N5s*)puV_C+pDgAyFyUcYdgbpjQaG6-A6pM?t&tMGHldACyp;|aOj)kZ?Q zRvUQSg5cZwD27{dO_HJu8f1tB?<+XXi|Uu+ePOde$K#*=HznN0P8ZbkO$kH%M@sm= zkg@-AUKBI7v{iOAw={P&H+J~V-fvV*V#g+vLDQHoKZFEfAy>tLsT zYp`UbL=}88NG3T5q=>DDiYh4?lwXY)O|=8XOSm3Z@`S)kV#15Ha4GxdDIWF=kxus& zcC6`mcL#ZHZ*)+y2fXT9b;o$+{!#fr%Z~Gx^|--6$sRoFc<#XV;kSP_0PPA0?sOFz zwDVN&%?G;VH^k?n#(#uf5Z-quRrHbL%Zpw#jT(yUe=u32KlNA@Qt%Jz$)jyW4?7#( zm1_rBBbOXw$fgkmVT41uvJS^FIF$c#6Wp%^s&cki?yFLp3o$|l7HLz(3vm#UMnBPq zW+I~BhzVXZEGliDOv8Xy7YQgp%!M-)n;x3Hte_yUC!N%lTdOw{v3e7u=1pOZ1JeA$ zyFgOHVx6!KUFYJJ_^pZgx7(x2#1}Lmz8sNa#4 zc#hGxrei&o#RM@)j;mS=B|U8lU!=p6P3%Z6;nK%~x|5PxCQ_odiLq5}5l=@vA`~V= zks{^GrEBz8P#|Hk*o0Q5L}|E7^l;346Y9aS(oB@l0&0TW+Q7LJC5`@l_S{|4`_Urp ze&pw{p!C{wZ~?@YAQ!{*Kil?l<%c;cCpk+QlFS{ln94luHq$-)M8AK#BFR!bmjzYt zo&klME}Nb&T*Ed%SEOjKrAw#P2E+~o*K5I zvcMd)l4-i8Z@s9^b*gEGB7tx^;o3UZ)N?7!JR&vsQHi@My|lqg)`gU*C@Vq6#w_Jq z09>s`)_t-SN`1`c;Zz=-@zzn&xMOzADBp=RUSw^Ir~g)MYTa4?IR7CN#|lcvRAxGr zOemssmr5C7PPi`59j499oS=*;+d*WP+96oe!?4J)A#RjJ*gIv|t$`T5Q7LJTrRh

    N7wG)V>-4Y8Kfz2qA60XA`fM)BkI8I`d4*&ZAjJfIwB6&Xhc2@E`YZcS5Z#P{ zr(KX0&>kOK6wgzJc3*DPCw#$}+jA7u(6>HNc8wb}%5878oYFc7DrdT!d5Y>sqAeC!obRCI-`RhiTw6^k`o zE=Vyx?-+O_gbn5BXOuFs}v8heYSg$%*GIOAkNYhcCZ^#a$ogcsaQ!sr|5(k>JkuCdJXGMx=> z>ZEOGd`2W>FmX-p#wWrPoexK*Ml73?<#2WbD0DUDa&KQv9}v>?Va z#$0x0nJz0a{?Wr0!^kc8Y$|>P5VXY{w*{lR!Oqh)on z`I8M|r&%q0I~TEAl<9LM;R{*uWt#iwQ-IOO`0z6_;8W)A%h$^_Ug$A4MOcX17@Ihj z%@gZ*2FbFjS*nZoJZY*cKrb8_io=NB^U8>5{8`)H)?d3&vBl1BHZ|L5W(byZuGiDt zg<``^LIxE~v!tRMv;=_pTZlv@jIsi8(F`HHMwNP~rKDH;erVo+!<$k?tywr5`P}M0 zw&Mp-aqSJeO6E|J7H3dtB}H+qm5N~^HI_VdbctZ5T7SsRdH}_|zPh4yCOq%oV)jKR z+`|vY<}>UKwDb00A7fCoY3HM=TSk;S8_E}l%}w>2j3WPeZ$tF>M(<93Jla=x#m2{C&MO2%v-`edVebqriD4RZp+o4 zc!1(jv`iyVg&Wk5_2AOO7~{0>+O1RBmQxTa;h^uaNv+>oGfEYzJU#RB(K`n!vn{=J zsUK$Tqe|U8>}mNDq&bcG?GBWghd-E9l5be)G?3fB@cr2&qcU0w>AyX(FTGw(x?Xz; z8oVg0J!~z~=3zB}o*voOeQ0es^p7j?AZ;wx3+JzfqRSrF=$IX$VTdUD>#mNzfYiJk zpov0vl9>>`xaMZ3x{%?eQL>jabx~)8C;1TfCY*>pzV{FmBfge2?CP`M@&H`6*GPEjE(`CeY_I;=^G_`gVBF2AHO{9 zX03S49xizwGM$fN&0-|Ii)+nBg|a*L#%n6~`@#qZ{w9!F_jG6Em^`l_r(!;Z%n7}& z!BrC@jeQKYL@bj_fIj2o^qc+&8ojn#RxdlFHobBfr|!O%>4liNOV;Y;sU6kUv7nzQ z5I~;aV&$1aRAA569<~K8?+hBJDv7Dbd6rl9TJZ;@^0RvZWIRsP0erbCVZ*7ga!Gey>qO= z%4y}Zc*z)T=ZGO8h5<=%_QUmlUK21GvG93<+G#!ftk?b{hDE;(UL*9!81I_&f@Fsf zFfbBbl&!Bv#^j^V_zDs$CG31{EjQTc z$SybDHM)dYo$(G03|F6U(=X1P-%9@)u_53Qq*@4%%+dbaaBa3lcOQ31FV=uXVVa=w z)Ugf0%&A*4w z6mdS_&FJ-|7q+_O4+i%)-G4&DiAShX|97+f$&GsaZuk2<+e=bLg#d?b4 zsr~6~YCr3na?=G~847}ftrsVzC(GAD5}!Ep)S9U&(GSgOl|Is1L4l=%4AUk+cP=O4 zG@d?j7EY$u{y5d**bYPMYp3pVp;f(*2#r~B(X9GPvNaId-~+;`Ers+6LGkE1Ln*%q z+7F%kYwD+Aoee2ablNl!tW!_RSuC?@Sa6@9WLU?bsPUoo{8(csu(T0jDO26(kr~8p zYpk+=Utsx`*Gi*{DYl#FYf5jFz;=yE1*TFfl7cA@MZw)6Uqcii#8QDwI(&=thZr|k2{&&z|tk9eY~Rc4;O|#{ELh|S_;>%h{uIKSkejsyi>Y?E67O) zf?t6bTsn`yNgP6`toy^h$4caFC;*58YQne&IUydr)?(QW>Bw30iGT%?$2iR9SGlgQ zd}5$$Xn6c_onC0Enq>@WgH*3e)PG)sD7;k6-tXbk`ru^T| zhH-mjQ2>t>j|n$MPb?lj%t{o)>^N%ZXg|7?-ygLB)*%rn(&?myxM0lagxQf0Jh7xv z#;u#5)O{jF0w~Isck-nh){u$Zas7nht<7(bJjGY#M^`?d?y!14g@NPM7Hox2Wno}; z6tL5V<(I#eMOB8iTfa1h z)8;UjSS;xSB=TlT=xan_$QYH2FYSiM9oh+i0BGoa%hbcSD(F+gOSpGlTT)k0?MYiZ zZz_Qv%4{~FWaBs7g7k_skU@$TNkpue9-zCtJD};*;a@+`dDKa2Ww4v_#)sZb*ZVBq zimfh{=GL<;I1&wMqORv!D_I7OH>^>GC+o?1V4u(@!mjOCBPP!t&S`>b)jF~R`RVLU zwOdebqBctHb32=KS5Q0_y)=&V)c0k?>!OEWN0sFU%dGA+w8h8_+t+Nv_o7Iko&Q!z zv7IFd)q5=Z9ndpGh68M5smCOT^bL@o3j31)Ob3gyapP$#B3k{x$Q-42q+Pv&L6ANH zY*>eNwj}d#pv86RRY}z{>8=4bh0jw1Pa)~-!408!*ZD!&QU&ye20A*p)(N6- zvHCkykn4Vy^6xL3{(kaUJ^D;~aCO-%?}DW+z(wh|JYsROFJJA*;GOH&O8TRCWvd^O zK%;8ewwPwyS)8ifmH}1AjGzAb2fQF=80O=Vbdm0YTKd9m4$X`$fa2AO@x@5Y`&W`W z$Ox2KC@~j^M=pLnF|4tU5V|U0#{eFG2CM+=M-{T3@Xx7Feb+w)dXIdMw4cQj!+O{$*=0u|{P z1S+oPX>a>PA3>1K6l$~MoVp}gmkF>)SIB#Z-c!GTaJu7+f1bb{AT9pNLJu8rHS(h` z{z%!TkJuiycSHCa(I@ng!Uy5->&!u0O35v!Iq{;5m*^!HGcEexLNz#6XYg6yd%g8P zhW-Cr`{;iM{(r=Z`sBU`>I*!T5MGe@4Euia@8*#qupk(swCZ)Bxk9oO#wft}j1P$I z_2z^7B-r60RsMX78|^xons9!*d3goP3F$<5S4&2KC;TG>K_x~hMj?j$j?&MVQRWBJ zo4*KIW}@C#mHKK%ED|75b(6z)8m}Om(mz+pJMsIWF1^jb4Du+QDiWukngtAJ6L9G7 z;aAOi3?gs?bSlPSsJ$WQpMwGUQf;@@%k(W>+hmeFI zUmHq;vc5tXDY zdK>=5mEYc0B+*9w`T2*h=kB!`l>1&<%^130@J)(`tV!62mfaYfLafms0QWcQ7UC3I z)~=WDm1@@Bubi=5)AzS&b$4HoQ>O9~stl7|p$6jjG!L5=jr}!$^!i)a+HEku5zn9h zL}qyy4K;)B$ZYuy*#5sG^S4{o|6gKSP*IGS;oo_>Rm`SjpB`W++eLLaAf&2&FDiV5;}-+xJT>JuedU&&nZ5la`@;!a zD2FirSNJah6#xfflW=Rko@y_y;PFDk+4>UX zlqpk~NCgi|Zmc%r6~T`(w!a^%qwd8WTZFy@WWIY~zLEQ}mqwTOFRc``s_C05+AzY1 zA^`;5K-j!9S1mWLli(Y>&e`FyALIrhqOrde0)PY+5a?b*G!-)kqM|T*5ISqDE}3ci zom$6Z9*mEe=5I+fgSbx76;Ev#rN`$auqyTupeoh5f4Yy-X*US#g08g-aVU*?=v80C zhNLkb0EBNlGH3{o=Wiq)fakm>1$+EEo`;Fa=jdot!AhY;%9VIPy78TUZ_8QOK+vp& zNePlNM%HBTOD)ADISdpY3+2^w8}F*#e3bkAvs9i6d~~MYOC|Lmmx|)QFO`tFgRP~$ z+dmgA5qlde5gS9N|5=gFRJQsDhxTUOFpf7SVE#n`kpNUkKnJ^!y!3~>+HdZUfM#u% zRiCt4+iGMwY$abW{O1oJ-)ye@o{@;k>=ZjsjI-ltx$e^aXK$#9qS*!n!at~dV!50l6 zMd>QvD@pl|j%+j*Zr*FE)UZ<)ranQDqIz8yCi9Qu5|vH|C3DiiUK>6n=s1*)Y7J#? zeQLr?YeS*U*^@!~#>60Mh!oc&&SgaSMMuEn>4oy;Tvn2UYnEo!C1w)|f!sn^YFlDx zWm}ZKu~>1V0$HwUYrqg>KjVftRcn#_H0=ZXcWq2t||Ty3u!9(eek~BI>H8dVMR&aSY{%e_4Ip^T)}e-VYid196CAB zHwb@;S*zzy5I>B0ONc&fGCg(f6}w}eUK&-Ce(OeRd-5K~uDaTmoULL%O-HVtc7J+H zWuobdMzU^By>F_2onLXK0@>+gvG=Ohm7)s8kKPGaNn6xBf*@2vRF6EP$+_iJlbEi6tniSjn+9FVrClqtZ2^iAvt?h*OhS`l;QOt1 zIF}uwt7Jb;0ZYn=1bT(7P$+g9%PoiE*Dv;Tm-F)u`a7 zcuj6$c8@a^`_Ym13~CZ)5MdrJzXuN@xph?}PmD|2)z={UE2tP!1PhDh^Qz@0443AJYG_?i-KBW zsC~#hlRO+VDNrJs>cC$AJZ{0)+up(+r!?Udvy(;T`|(WuoG4yEfH%GC0FhvKkZ1>! zu#Bv9tS;p(*c`M$fLVwNR>LDgbbvEKV8QebVgWw_X$Us&uRC7MW#BQ|4tN3mxfa=1 zq&}hGUEq}`y>pA_6*e>d?Yu~@V25)=_Z4__6F$NTZ%UB}Y!Oc(bd+U8A1=Uu<`7i(r{ttoKSP04m&)Wv$yN&tGvVlQ=p%OTxRRSZ~k&Z&k=F5zU{lb z1n5J|e`h>Hd~i)6zNVe7zXYCrNZz{%`n-qH-+=8N$%pfMRre5_bJFoeU9JJWTY|Fp zKkSJK9L%YoC{ZP1pI8pST^D#Jy4Mvvr>y+FKwwcxDma< zv`egbJC@b;z4{kVt-1jI_3L|hUi&}t)HMGwEb*H-8rv(`>l<2pTM+#FV98YVa0RHM ze8H}A)nf#8;P(jRn!6d*x9bz&_kqm?5&yzhj{z~$u)v5Tptf}G=l!E_h8%9z*w6)~ z@;abY2?Uk?O9MACsH-7KMHBB^&iQb5uXww737*^3gsokib!pn?GSlOVc}U5K zC>5JLm%+xc@&Q4P0aep#t@hx>O70F^)3ZFNOIb?K9$x>ja@tD(6df-I(znF}%K1U+ z^z{xcO8d1smvepR^v%v4<)ukt`wggd*NDT@N-deWIohT1;Tym+l&0x+XB?_4FAqo; zC$xIkJ8P@l0IzFm5}5lv$nS&l?>;{$JcX;8FbVGNU-_Zu6dZ8ZYiSgcU7&A6O`(Tm?H!6htxA#>fgO}F~ zK8YJYJ|IL{JY@$POl=htvMJ3LD|OrkA^^sx!>|+4+{6nqQLq91O3qQxbj7l3YfMcQ zGZuDNEO?f5S7SU&bsO~#Q*#uLJOWMUGMYq;FepVt6 zA!0c?RgEq)!Nl%CwwaXq$8y`zT;ya_lgKjoI6HbQ0UAPMZry!8ZLM8CP zklzm#=@*YFv&(#AD96oGF%Yca3a+5uJCErd!i1?|TOVXPQ@m3VWNH`0n1cA1*n)W@ zEZWQ!Zko!Kzd!srHsA)^%s|YL9hXI_k7Hb-tgK98B^}Sg6_QW>x-Q7URk*)=;~l^k zPft;*Vu7BSpdT)^Xui38-4?W76UB`qB@WxX)Bo|z$>k4rvw6<^j@>PHEeYE#kR8N! zUF4^0@eJ!-zU%Vb8N|0UsdT?uD?$XgI*JM6+mi*}l&LZba)}1>QOh`@3!HvY6Rcc^_BM;=Xurh-XG6XZ17_qxOp>Q^-W)&8sN(|5% z(-KtsPG5rSsRidj3}}>#_L6jR3`M+XV8P35Sc5JVxkk21!O%j zq`7U3H1VJ|nH)pe!6lYUfzh3K&$FiOqgRkJf*Jgba?!^JM4t5SoW5!p`s2b6<%tih zcgmwaRaMz62)egp96LvC`job(Dmpg9=+0Nds6ANI-+OztBQm#K3o+Rn;pVp?pcI6t z>%8uBx$^go#MJVrn5O1PSuf;AekUv5=|bu0q0hh^Qp##JRxEk5rS+y$1;-rYVB1nB zobnvx+Uf=j>J;Wq|PR{9c`OMLE4RkfeCJ-r11lLW1opS>bUHWzw9UOn(Oqrva!7& z4eSP4b|$4S;$``n#?8zyfE_4)B&w#s2-fl%5ouP_5%u|rzba>_VHzr`r-)4X$cz{! zi+2ac!kmVgz&d0npiO$(QKVG_bO`nhOfpMH#&-8U+?}nn_o#*$g3dcakp_TL$sx}* zBlj%tjU7&RGdkaZLIm_)S&Y|W^xkTW`eN|N)oQUv$92W(n0HEM`E{v$)`J7e($+M($IclI(?SL`B>D`5fsFOP;!xQ^r3L8 zmT%t8u@>0cF1U3+?I7w%j|k@1ftSm~A4k?HtL&Q^h%1|E$D9A4!_3JBw_a~&! zw_QXJ2FY`OS?)i=27IRj{%Ul%{Ozs){u}hB5MU!K8tc0Ec+L^7$14N)u<)Try$y;8 zoBNEwi<$!_97osJ9ft=4ApR^d!Q1OJTqy%GjHbG>I%uA)xt@Otz&mKvY^d-0D5~|he zCFC;xW`RPG;dMI?ngae__$R#=7^f>)QWY=GUkV1;QhTb2b>FFEsOZBCo^YS<0V&xb zzU(0lg}E>YYmu&fB*oV?Lb|^%3H#h z9!H4CQSX1q3>ok}c-DMW1<^iljB6J&_|V;I71Q(m#G8~ZP95t^5!m$W#2?0{Ws>RwclTL5YaDK(MC;s0(LtBf+T)hH^s{+T&{3|1=p5 zOd*OM0*Y&w$Bibb1BSg7>J#aP5wD0=+%h^{Zhc8X_*wpbm<4Q$M1XU73u3L7o_8H7 zr0>G#&mq5fIZwVCuE2J~=qt>tIiEV6WBy@ zIYm!+jZ&4bZq*>>>GG%~M4h$D*MqB{dm=T>5UnS8>%ZCIcSN+@CdeN@0{&wgkn%q! zg#X-A6>XgC4gaUAQl_$|4VE&(XVgVTW3wigQ(9Vq`F=oyoh2I<)M1?DXdxt|(;T4K zT>H3xjl-_FV%fw6XG|D^m{tJ)hRL-`C_YT=zSa*fFr{9m)?yg{LEqH*Xu|U@vvtMi zM&VYjRLK zZrk?3PRGqT|2xVy@B$-Cy%A%tE7=;uS$*0g$~<|rxOvgEzXSq|*J7>6B~hP#k>p~4 zRnV-oO>n9z_rbAN zROtb9+gQEpjp28fhKq#3V8Thi)= z>5IPj0&xk9yKF!H6s6i?P0$mH)^bdLn;$GJTg}wWa=Fz0g?SxN;;825(H7S?GNzbCemmp%pj`l(e8BCmnWj4NfTiYcwbs9BLb07g(?ZUV5yP6d5!SKm4)||n+uyP`vuN#-Ox6h!eNMx)veFFi zD^?7;&Uc&?j`br{G#gv)U7iiJkgqfa&V&JfHn3iOVMYq?SS~WF7nTc?`->rin^%l*1TL3V#1xI_EmXz)KrD&~_KXwoj7s>9n&*k- z)$s?UI~?&7k@nWZI}chk^pp5E)XA6+N!W-`s#nQ;uI~(!*(w=3!{!~83`{`X+suK5 zeHtF22D?y&?H`@GtgvD6^ZctH#o0ymNOws35^cVsyn!4O`v-^@!uLoQvTJ5sLhB@J z*@hWDzSLhxs?Vw^`?`i%KK>r>nt&G<^1Cbj8$5^;!lCFY7Rh9&I9$S|kF%3)gd(zE zvN2h5tm$rkOp|%Sg>+w#JnyC%huw0Air%KAH9{IB)gT`?)P%SHaB#?g;Sl@3?{aB93+xIQTaA(v7)IqPUrk;8_ior*X0YdhpUa4&Ho?JzoTh%Uf(O6sq zoa!syEEV$PZ)di-xoe%Tv^Z|r;hnC&E%as}?FlZtvbr=egYLfaxpkH`zcQzGcdXLT zji*7%CsoI(5Yv-r;buOCmwQ+__9o$b7vHR*H>p>q2VwOMZnHtm&&S04LeHt>|AkKY zgFB1B5+kHa6x}1itdS@qIG^XAI^AthPt45sbIbilHC4cW`)B?q_`nJ23Q(R?uJ$M* z9Nj!XsmCg{ zR$=GyQ4~SMG_Q3A9)Ig0>LxtudZhMMc3CiIPXF*1cq!9=@=<%NJX2e#ddeyfSii^m zffkLZ`ixhFO>5{#9ufwJ0b~Tlq|q$iML|c?tqg`w2Py_xkS*M-Q~QP=GjgT}We+$* zw7{LAJvep=4|v<-qCITf@S?x&OM~O0>yGgH!n~@D50dlbC4hiutBsEmhG0Ncb?5{v zA_v3NHtcDmhc{vQIpqdp-WUd!_RJ&n+z^8^s24&pDBUQdM}H#>7H^&NPGLs1<_tkY zXs~rhc8PKIYjzznUUB^U(gqx`b;kl5CNlnWuQTTO63 zwMKky7^e61{d*F=HNw+lZ&>pxZ2SfLA?+d~x$Q9nBJZ#D(E%gp=y2sdKJ$PuWyDTaI7AUeV^t1D7-RLpQP@P`u|MO!r^v{VLC_42?D?h<-yx+)x6SEY zLlasa^5;`9wk&LKeYfe0@&}t_wRHd&dhFB68?40p`zkm7pj13k7X2tRSf2ljE~H>6 z)UVgIcwVI;N+f)ZHHiJWk!B7iQxl+u+QLUO>r&^A*#g!RCzg6u#{8>j0{`YYnAKdz zY+NM4O34zIuSF;zkde+U?~v{hsvV5TtMbn(p6gpM>~RDICH@8C!roRZvy zB$RhncVCaApI=^Sw&J|F)6<>gt?HqtH=Kvf_3CO9qZwHQTxkl=5HXu3VJUwX9hv}{ zqyDm<12U3`jB_2zrdT7%+1plshc-1&V8!hz$K?AVhS#EY=385(QBFSY`|^)%&%vEm zlgP@mR{y}(cMq2aM{)B|&Hi;v%@wE8#+)(DyOyfV0u#sp7!jOpJZyvQp-t_pU@_zj z+Khf|T$;Wcq*?BHSAi7y^B2Uht}3h?;o8%%EZ}0ra`}RGm>XmmVNcl`!W4`s}&P6onurlE{<(Gg)rM>cxjMGPZA= zC|xMp0tk&bHM!?tW!L0J_QnSuLvjetKXbKfs$}<8c_?aE*U!0GXa?E18m7y@-f5@= z4`vqp78KT&_>>jug>xD>NuG7G_`ETN)ipsz9~=#oju~mDv)V&i;K}{-bHHMkB5zp} z$|siaSV=Q-`llwR4j|89>gwnl)n#?p%#i(rI1X=rBuQYo>gk07NC$oQ#eH%4rVB}J zpO4t|cVv0v;_mr+xfS|RGmigxO?Em)D`w?%j^9;ricPV$(ikOr6cnw$inC4~)Gnb* z6Assr#^tf~(Ex=~Jj+xB6OQsQV*ocffiDvc3d3E4n|Qo#JKGJ#Ugh-x&mRL`pJi#} z@vfmsOmM^^NnrDKf!!f`Y7A*dwYRt7dY&ls+oW7d{%7GAk?ECG`_rm@V!fG!eEEV*??B3SjOK12i>z}npj1dV zkgQC?Xf~9?l0PY}Zb;rGP>Y8xA_!mWigjJlVzZJ5u z60DG&UF=9`L|_dsp0Y9s$BC`BF%ztN?0I4!{tP@dSLBM_6DRl_(t5anuB=rj>mipX z@1BUBtV9h%c|*((lQLzhik6d?MFOEhxZ%}z)=q#P9P$XuZPi7m#noBbS2~yW55LVM zOqYgP^N7iQyRcqFQQ?>y8K~SxKIE3HDaaP$u%l(o*VHGGVdsmF!0fr^acnEEh|Ts8Xn;12HLhKja&^{#8~&i;Yq zB*JUc(288^Y#FN#DrO`swr)vOj93FP{lajmv1xj<>Q!-wYe6a1Nz|+kkYy__ZXFiq z=V#h$_=Wbz33e{Z^s5+Zdc$NoYX4IGuq;>--?%XbfQ!%-HG)&YpS#inrLZ!2lqI}=@?^G}VnP>LihwBT< zsfyg6;jrmiP|pGL&Y~vApaLF!FpTaDU1BZ+K{iY z8|bNvst_5H<*AIPJZvQQ9`}@2p0T3OYNXs z$CSJZf5Cy~B#J6AlHI`0(s=e~L?_ELo29pSv!b^l(!=x2W5lQXV0PY-S{~M-wqgo< zDJz#<91F$dq5Vn9RZ=eY_n|$s(M=R~)|2ccOhCb8&!owYzhbITm;FT&weyYJFpYBs z%&#psH)!h;GGARP1w~%$bVgb1FJ5Dy-9!6?wld$fvh=(F7m{P$0m;lFC*HvW(fG^` ztYx^Ww44fVPl~}2_`6)5pyRfbgH92c+?B2%HIgJ?AA<`wCzd}?HM-5~wUQh|c+v>9 z^iGRHy!+uqrLf^CV$NXHI`#f)sH0gyKDd(2ydXKJ&S{XIZ0X*(7+5${zmB@hf#_Gq z490##^PXcxd3o$wWfND}=qQHHBlr;aQ1FD+P0cp|Ac z%sHR(ffAP#aQfCn@foMVix}Oe>g$2h;QHs;B0Ma~7s;h-z5|Sj11{QA;Fr+@$XylD zVG0cxsEu9!0fM)2tzQuXz?i{+y0d{?fe{0&1!;! zOsZj(vDFHh2iP`p6e>;pl9Hj!F;x1pHGXe0NAZ~QFmILanWbsHJa>zY#zCnhWX$J} zIGP?I5}0Xb=EYT>jj$PglrBu3n@)4-j)kR%IPohyLpJEX$tHHoodV7xWD*U^1&J_6 z3jFH9$0%esRSs;A4e6Rct6PJ>rNIHt8CvWiA7Qp37AiB(5PifBzsk0b!KT6Xr_4nZ zxU=JGN{=)5>me_qSJMI;8R(ERfO0?K!z(atMI$h_Ga9YFGdrtdH&T~^ls7?K!{oa% zgJwt|IcY5r&`o=aCV>hl-E9+JTo51C`db6bp7D8d`U|vb+SK3^&|CP7)FOgi!1yuhQR`rFw!VO==Cg-RIWE^xc#(XXyOZaP+(dbcXYeYi z%T!93LmBjw4f&5zK1Z1`fz#q0gVZh=9;jQ&1n2&G+jRQNC);Rh-V1=;XAbJ1-ns*M zj=y8wO5^rMV^;nQ`nJ}nE17(mTkgvi-8N$nQPDSh>;`08tmv6xpR~W-EWGR;YnFb5 z>-&$~kgHX`CE^?*m2KISx0 zJv8xI%ZhIY70+eqS!kMkH(gxX#M3u+@t3GpoB6!pOdiQ#y%#+QXEX6BuI6Ieu?Xfg zC`%)4EXC+49KEvC3*O$u>wt>0-FMy3!qXhlpYbi~qM)6&hX$|UJ&dfKhA-J#G!m4Sum5h$y~vbq9wPre!S>DZ`nlh80vn{L$kHX)9DzNdlvkw?35j z@UI*NQV?P(;T6&ec8dn=riX3@@iJI9TOYj4MUlisxw0zD;HoIm7)xF(I1x%wl;CB} zU|h>Q+$ch9A5o}Su8UDTtGB|{c&tM0r~-C&vVywUn z^F_E5VzqqD8UnCXhb6hc1QXToeOC4^_<_AOiTfLfeoL=Oez|szbdRMDKU1?})uAqe zr-$ZE7))2z+(o`32$Q*W@fijC{l{yk1;D_)A_^pW<@p?yaHk8$kl?ga2!aP{7zg?R z#DU@BNammV>m^dKMx$0|<({$S3d#1B9MG zop%XigDnhEcwv`zxiY}#MA*8aWOm6Mho*KzIK~;`=dB6C9&gBPLp_XGx)szN4GETD zvgK%KM_^WoG%eSP(v4z}6tguJAj&(19~-!ykntIB{V%W?yNFuxVAK8G zsrb|Xg!Q<4Gq$@)FJd5=XIvDrpaR`HQR|zT9sEFBmSLKGZiwJDvwNRim z^*v(9%nE|ZvrutF!!l1TbDv6+P>RqGi)3>b$tLP~M}XEBoa63K$NfyxkC9i}j~T7k z?9;(B;e9mJ$CCvo$Q+a_aqR_LJkO#6hK~SnKP!v*^gQGF^v|q^qU{K!PE?|4%kgSxnb) zAjHQrr%*lt?!%wOtv?G}e^9Rp#xMO#3ce7*KNL*o2`DT4i9B$m3(+VD$%ny075j;8 zxj%1I1{H|jRR`yyPL^dqw&J4+1S1MKJmjjW89U|csMn0dmrJmUqX!6Mhz!w(giyH> ziJb?C?gpq}EW==o>M4Wql;G%@v@r=e^t)xFqcE9N#@upIuE0aHBVNd_M73#06nmNHWEpLcXbsls%VP(*bSH4B( z+BCc(wOlh+&;t+bYZhK;=F5^@hDSyxne0{glQw|hOgqEUyfYjx%;}>~F7Yqho&a|@ zptLGFn=-%%O*MUk3V}w(P9E2+=H0zMjl3mj+o~9qk5`0}5ENv`HVw>GUnTM7}E%(ewF;|L+vr3hW zHDU_r-oO4+*BLU0q#&-`D09w@+8Jugu7Ft%D($+&jThHGT!%_SQG85Fl@g1_2@;ON zr!9o^Um!6c2(Ygti3w?x$0?eVAIyEr>Ir^`c8jM=s2@l(664t932l$gFvNa~vqh&L z!R~|xKywg|@Py4naTq$^7vZGl4{jS4*d^G{zX^NB>P61)N8DFI+sD!#PG1x84eJ?R z&7kic_}tgQBkvtT-iO2^@gIiXr^q4wjA0p>`-?8dId}u}p29mVUDJebt)nEQz1@lA zdDI+K6TC0NPAnbk0BQwF+_4=ktv&Tx`3^ci55q?#$L1P{S$O#z0sdOKB}#JKA`FPj z(V*s;FsG@}u|$6%A~T^`&&tDbg5;>$i2tK-(yLxU?wTKT#n8Y>3w*xBI2pP0(CMGO ze9|$>P_d6FQ$MLoa0mlnr^rl9%sTM&22+8`Ygue=x%(C_@U;on(R(kE4*Whyw)$lV zrM(fKunu1JG?5$j8PH?TBKBI_m{Xx5-YNF z${dD#IO=Uh`Qnr4~MQPO%VO25#av8Y{a`5`PZy<|) zEXmBUbBI^5mhNVul5p^|Fd6pGNcT)%HkaZ6vaX z`!-z(n_<%L#ms}BClq>;>>ZJ|PE2Sr>GS3;*f~^sLXB}n#FL43JY>{i8;7L7U)43m zjce+tDWL`+UiC7Q))6!s%JG7!X{$cU znl0@Ly4(%2=Z~f}nWst=aq8N}ZvE0(eH^Wvur!Mlq@f8-hu@q)0vLw6mM6XE*JU)9wZmXT$rl5Pq^>){K|Ke=RjmnPuAyR;uCli2(zwa7l6+&W}=N>7=3MGn~oX)YNMBz>wc4fT}V z#Psa`p@f?R1yji;KSiUR-ZG_lO%l9*1@;iH8(ID)NY*UgxPtg-gw^-%b@PP9vb88@TrSdt4pr?4KL+Il;uun!lt0U|8HW4RAj7lpV+ z+|N6t*s}Pa=}xba%I3s&0KyN^$@lb>m&}xxuoNzYA<2ye=0Q)bep{{Jmqs{?3F>w; zp5>_tq(qioV=ftkC}x$8juM=EJi*D!FdrLcW{)91qV_&fcP`5VpTLrqlu1@DW%p}H z?4(~Mh{+S6LgOJsYJi^~e+v`I5Lf9qc1-;#%=BivrgX70i9GAo=CpWXb6Q-I^)(|5 zHPnQ}A$ds)M9V-$AbDx~$J+u*W6k;Cq(V{mC9FMM0=h_{#V-^MCD5CQL*q`F zYz~=!lcA@eD-z`_sH@I6e&^WIqTZEOIg`JpU2m-k)WmN5jgZVo}wN)E9 zap$c`YXI&4g0sz?EXOy?C}Lx{I`1upNSF4yLT@e|QH{m2Eoj~uCEJX=c$jUqq2tOT z$Fy!BF7~raP7L!1RjOmPk-MT3QaiR9sk^Xi0-1hP*pZdS7#yLT!>XlmEuClg`nNpj zx4BpImuv0eq1=4PS-k5DI~L_11e3pXiu4W?R%QFmk^m=ZsrO&?xm;Nx7A=0EHAzW96>!Bkd+GfUKrYj$Clz~Rm z9uYnowQ z{fob3%g;PLX3O}2!x~p7w7G|>9!_`69Q*e>8d>t54F4r&B@vZlD3Zf9<_?Jf^(0Cgt&ZIP#>7h;!$jf@31w0I6M4{duMW z6UiYUSlX@_{+l&dr!g-)gO#V25N?BuN$n+7^TSmef_B8xzNAChX&0)#6`~F z#mR>RjDlAM;qjX~%*PjRj4HziQ_RSBGoe^?|MLAIm&&oDi<_#Pl7}2txwr@NQ)A zRI=g7OSlBaYV&abCBjmNMq#f7>$SJ~&ZgO6^gq^C>{#9NzxWQhgUzO^^hHmJp#?l% zJ~p@gfqH9J@KEWaMw^@Z^?E$lT6rv48tp7vc5xszIjIElPd?xj0^MaaI2d7s$L#Dh z)3LLbo@xV>3>K#MUS0FaO}eY@=oo5My%li!zfBU|6&e%^Sh5#xI)!Pol`Q4b8qS(V zG0a&0nzSc5LRU576_K+80L^11kyU%}^dwr~azD>y4zITts^-yt%N^S>$RW!7?m8rz znYe@M+qp5#F45F*b0XW4T%NA%I%o?u!XCq)(vr9!y7F|c^E}7n*e}7N#ELWHc(Jz0 z+r?kVK9Zl#nuwMHsWx+Vp!}N__25jk+F6aLLO_QBaVZyHUC2en=Q<5(P&?bsBg<5(4xYOKDe1S(Pwe=$@a&H?}Jqt;@s9GN}m0sX-C zgmu7O3$}yNLmpgz7os_a3&WjBzH$OjW;O$re&E1>DF*k(8%4WQuU*0z^WLL=t)k4H z!NN)svmN7ua4#^}>y+G%?U|!KlI}rC*~Zynx}m3)HaYW`9JabzVY3GZ{F;=v@l+^0 z2#D_rf0FW_WKy+EcxKlWS(h!LX{v2G?8X8ep{xcvL#y)Xs5zvRNvlDYbJ^lDoS3rH z2s4)xQ?sU!j2_<)wZyKrhG$qtJ1`}s3MgxRN;ZlCcQ8<#~z#Q;z3<8wI^PPb>ikI3g|Uk&0Pn_&xCE+7mGAwX%_BEiBJBu8cgMR2&pZ&}0YZMdWxw916mu3R$Q!5^7* zg?k1wp{SB&e(Dx^Gb)PWA~>1DdP~VBwkGExU9jSUQHdq4iLvSnE?HQfbiuhKaGBuI zbn*Jlp^c%^{ZRZfxLb;R5aQVsKfD#g#pzyf&ldr3uXL?;&HdD)T7TrmA0B=IZ zFFNgNDx-~pEgk{cA)1*U8G7TB?$X0{;wdABpkjyM0OrXEk*BmieN3>3pg%-q+zsNd zHTA@YY`4LQ7ZhRy7qFhr?a0>vtHgkKVb|tJgZx80@Xx7V=p;Of18hu77HqKbZPh%z z@gBBU%~qNK)GbBZAp`54!z`TQbLt~z*yBO!`ufQi8271d{C<23!<_QZyn9rq>f^sBnkG~6G}*t~+WO)C zw+-n3q@RXt4o%FiClm8Jh~-0Bb22n_UsR6_n4 zNkqi_3yd`Io8k6LcQA2cniCPwdsemm*kGU9Tfd=gBiF#-n+T=?8wp!<*}7>bW@F>g zrrx%_ZQoVXs&{#i<8wW|)sgw*^?!6TDZ7cTO;pI6MmLUDO4*WeK z@DJ2;O`r#OH^r{UPyg#d)VuePz%TTh-atgKccuP(u=h+5p&!tSx+z1Gl&f)ODPunZ z9F=-~E5hlhJJtlL9g}p%VGc!H7SK|ow^&o7w^fA!nDMvnR$1B7K-p5~)Uqnpp*ZvI zp}=nX%EV(?jz*B^S{E?f8hjb3%5V-(&DPnFiqUoItGz#J-q{}~)HyGQxuBd%pLWd5QCoNzwk%5% z>Q)-4My*%0XpN~yt*pIuQp#rk01Y*dld7$^T(+p4y0HzlXuST#y>O7+HU)l+in|JX z;;2I525c58jic5RQVe%TE%Uf|xW2o#+9-r1k<0xQJed@%5a{*+FBDWff9yH$gf4Zj zbc5@B?lMJY2Y=2Bs(A3?K*2MfKG2rveG=uGJwX~L6$I2p z+9iZXYz+BDVHwp@jr8&Clw2Ffm!2q4N@fZhjwV@&aSg=MRC>{`mo(uju(`?mWF#gTbTLWAvAHWH0!VxOvs*{ zb3N`p!|581BDF2b_EPbooHLb-n8I&TDHXUFRNWArXQrF?CHmLChmcF6l4=*BhK(`d z53^Pl@0f4ku4$dQoDvBcEJv=+iz}0yqNY%S#6%rqg&0A~E=BYUHP{&1nzrK%=uQjc zg3QoHUZlisYa{q4_qVZve28PeP(~vsOI!@uB*JxlJUa{Oqkp{f;|g&-BT^F)*I-U; z*l%~aUMuzxj&RVlkuXqqoCLoq@}!RAtNu7|>ebkl*8W65G+8c#K8w}lCGnzY4!q6N z!zuCtstRxuPTa#lbycJh+JHG!3e90)?9GDMDbdbB1(XSrT%eVtdvjG>GjC+`I2gEI zxoDoc_ET(_Rl@=UD4AM!nRBQ+fq`%mpHah4F~l67bTDjnI*o!l)s#s|zYM{AGRZtw zCN}OyO=mwW>Fb*ZMo)jdPb7F3kA|_uDQC9w)*^*X2nMPQ%S18FjJe}M@ zFEerXMesaFCkVD$(Ccx(6G=Kto6X&Ha!>zzGDheW!1^X3YYF>ek_=e>7)|HtaT=7) z&XDIzxfyvZ>@!}pH`@A1AN=apd3W{l@v zL@aT(h5Dx_b(LMlOIzAWPLG$ccg3X)HG}^SB^-V+=OLw?R@Z2HP+pzvEm)!4F7vwt z0e&9Zy}AbwTe_C8E!-3U?9j~PY6r7Jr6USz88JUZD+JUApj;M7^^8Iy$+AQjEIBKc z5CN->hyYZ_zHq*^sy*?ol0EaSqCItxF;ip8DQ-k7&mV}^?Vtk7^@vZ_&z$@9&rL=^*fb1X+NCDWY&DCXc8lT?OzO7 z%aHE_X(xigJPKPF_0AT()l#;9YF!FiQE^o;8lVCLW2C`+;^Si7g($048?G| zsF0&w%A4qBm&ss7d3Ws6A%PNg-5_&5j_=dzA_i3v^7`D7V)Y3VE-0<)_2)N;sa>#;XB zdTObCdMIbYkGji=QiXBCsEQWghil`JA-M_{=wr!0j%k_1A6G0nE|Ece)H;=lvro*K zUND$m)MJ>eoMjk%CjVe6{GI_)0i|T4=HSdr?Of{in#BpqHa*>h50Ca}Cz7i5@}lIT z#ui!L$hF|78u!_JvDzjO99A8>x_js;KH%RaOL9fOVRXd3>`H9jKYCl2v!uVt<1-mNP;Bfuho)0- zy&NNteE&eJ>=7kqaI?4AxjW$BAfJoL&i#(-aLb~-MjyuF;?Q7)XM>XkdI6}tRJgv&f zXPZ@MJH=c5($mQ78NPwuCmSke*4yN_P=E8C;B}dAq?s&!4b17LB=H&gwCvN`Q+|q> z7^{*J#qlU14hRT1%A92%E)&I0-XRsK^=f>cdN1s6=Po(d85N_ybfibtTAWPZPH38I zSD1zB3tFp?c&SI6FywRMXzeu|ujX&F(vh^GAe;HcM0TNB?sq?jL1k2(k!WpBC-2j* zeU|1q`I_cQh!qL>cPuVC@LeAb&OLM}gs$+@T@O)vgg?zIxINSufTH;mysI7;{QYks z$}YuR>S(fr%z;-aF+t+?ojyl$Qiw8V%=CP z&2VhZIBH$%iuONc!Lt>?VX8YCnK1D^o~^^sEu^y z-02R1$sy8fDE3fB(4D57t7dB`(E%3YQCLPLsI-K&X4sB)Yl6!W)8yGcNlz$KWq=Rv z1%){(*tt9yQfq*J^d{8|CGAu`O(OH~K6VdQ-aXr#(+=m`IHIbpW~S_udzXLo?iJ3Y zfaRMB0<8bZ>;lG;3&J%G;uR0dJgeDjXVzx-TLZ5Z-(-BXQHot)(`rkm`$Z*oPe#`r z+$AUbi(aJnQm)9bR%O6S{RZdzEyn+7p{a7CzlZXXqldxO-MTSnQ@gM6mRGiEt?d;IVT5S&g`!;(;97*O+Q1t=8AhMj;&a8 zhE){~u)fu&LPLyq*h|~VZ>$)wpT4MlYyAvY_Uf57QVQ`L=~8E1*?Riy*TF};4m(no zZYBjs??!0e_iGQZ+4ns!c`@D9E>Te{>n+5BUx(udqj8$n{UP zMhwByV~rn^%%3>5y?JfK7raXb7+dzRHvZu4EGotJ*LLU&)Z76pR0&Essz)wCyUI0kMwMf!5erkmt+-u$%dk7pmPdFHXR;HJc(K=2+F{I+rnk=BpBh~o0;JR?h zk?joHlcL9-rFQqyKK3r3&DK1gslLY;%^RFrXLI9Zn}EB8=`~YgFt)AD>DlOfg(yOH z<(?(sn{MzL-hF8uxd$AV$>0coNXcSLXe3w+QL+P)zJ>6Nic>zk8j|wMD+xv_L(uJK zIHU7=9&p)DCVJaSw)V5-=4#B^RrmvG=5API2WuNkyEBhRar@HxQ%{v-o}3nN8cwzU z#x0ykU)bOr>_TEOcXTruy1jS}mm3PImRcQzsrvjuJ05tCSCD1Pi!&q`43Y6A=z1c_ zxxewNC^V;J)nzJ{#pw%De+JoK5so*X98r6sH&0mkrR$t}d*UHa;M3j{p5qTe84N`u z^PJnC%HjHa+#3xT-^u#TyWottML6{YH&4Ex(7(c$PdRivbjK)rBeI-&XbN8+7{8Km zqlHoRrAxyQl&5E~@UZk}F1V_4l!A3cLyAdLl~I{x)TWrEF%KcV%~@c+6_#lBsa$x` zwq}j|Zd~KW(3vyF&D?*ZvO&~dY0tl}dLl~sCT$VXz`l{e&NajCttT+gPUurLT*&!> zZE_8WPWpR#7BciOCbrgQA`+#v*lO{ZQ=YF;6JSuCE0wzzNSzLcO+r*FvKNVU{LGys zw^i?SYH7swn^YfqEm47>E7w)@xSM7#*Hg8?X(F+kCeF(%yfD>(Zxj-_p(J9DbikX0 z*Q^j#sv2$(mBNY+Fm%JZf@k(ya$T}xk!y>3`YCmNIc*#zbiv-EGO&Z)yv1d(Gg3U1 zFRwJ+?2S$tUUvEDP|M}Byzka0H&=TMFT5$@EK(L?~9^hq`tgH+4{Wi7{t=BUx-S|am~X<7|1{L_p8Cq=>8RUl0LaH(B( zJwa}A2ya`$G51c(Rs%3pa0f1$I@TcZLVTs1*WWYA2vF<|l}G{g)b&D9pf(tdykq07 z^Ti)a4dJZe4dF<&xJ`40>eCp#u{dNrq?%Lea87ADPy;+p+iICNV;Dkc1R{C7Y8O+- z68l0C36;k5ED)!p7f_c!|Lq?1tusqSVJZa^n}m-*LQYYceA1dk)QrCAizkq0&KJke z74d?lKeUMT0u{&#B|9>GL2r7``g1L5b&G?BN@E!x6SI+UTeeb~uIZtxK$pM*$upWn z^2q3c<|P65kM~oBnfhjNdFF)z_$E#^9nfJC$s_mngKP5b{U3w4)R%_uBxQBSGgv}w z{@?p2Ub_K~^{pCJl6$z|_ii}wfd2+(9l@|btRVjQAx`$cg#@_&Go_X@va;8(vNv_` z_)kV1r=q8TDul+@^s(ly2R0B4P6LC!NjDERs1gOeOgO5{N`~agq{981?7VtCS1kae zI|U4tfM`zw`Iw`GQVMPvxuF(2WFWhwd z5-NNzoKB48c>`ky!GVWp5&bNL!j}kLqm>5xw>?`_edUl@+lF!;T~~{94n|uA(_d+( zPxm)TJpDGK=B<7nG+cL8@0d;JxitKzG2?M|Bjdg~{vk-Y40HIKly27}Ku=z=elDtl;N`0~=`oe**({3a>`U+!KF^Qq^;I5Wxe?!o>tYONMna%Q0$6GC0F0Pi1+7n-60+} zhz;5*&^NapK6a1p&NJaB&hn&0w{VQK1>*)odcty~M_PQK!tx(Y)&&z;iH}9tLV;84 z#{XC&~2bNs)bh1R!H^zrelciq<9gE^=k$&iaQCmat9 zNr|2YY+e$j-w_;b+ccuSem$-W7XetK!FT(k4nmqKZ{~Xq#2N z)Cs4XRlgLP8vlCm07rbB89=RORU~bOBVD0e3L~UujU|&T>YiFa(PafAw{ilORkjet zs^>`2abgOuu>_ZDZk-_tNHw?0kZn@SDmJQ&Ew{`dKk#6cEng?TR82jy&Jbz}Gs&w~ zrE5H@YVH?KMpmXOBl=FaTBh2i z`pq%zoEFr*cn#9l%N9M@FxF|!b$5%dC!YP1oC*VDbX^-_=$#fy>0g6l=v@{L={pC- zG+@@hlc}0TcPCWHPaOEw#@63cEjaF^2DM9!Sx2z#`oxVQ^E}{NguCJkkK`a6uaWtmXg6o^@t5f+Kcc8VBMczUa zAEBXpEjqAaJ#w13B51zsM%)P3bW#0^2M+YqKTG)|G!&}obY z`8K+#tC|Syp#EWpFoI$Vl?jdSfcuabq9a)4@ox==3NwWW5taA7HP)Zk&?hsONl-qs zs$@iTdQxde54dudbO`hdImtWbQe#f!>zpjn2N#si&ZVcu=5#DwxUJ#F=W&_^nQj^Q zP~gVpj{fGN%FLAmkuzEC!8Mf#Z}9Su8-n8%4i0wA#8bXjhS7ohMr21wTt^O*wTq7SVDEC(CAqyoWI5 zZ@+Rjru4I~!`64X@Iwur@*@IT3DY3TKpuC$<=YG^`}IJ;|zF ziP9Q7TVv3wqbyQbcCuJEiPZ>>O|2nitOF}^hvqRj)J(=ATDkdm!7AkF=z}-MQNdOl ztqcw&R&w-FOsGSsm^h2OpX358c=2?%VVpwU>+zDZGmUuc0=ux`I-W_cP8iDWvV^Lb z|K5V3D}{j)R??>8e1#zyddq;x0<&V+EWbi?5=)=*c2+tHOb$E45V=ub8ww{g%1at6 zmbPCzY`Japjq|$)QqX z$)3{3#iuH{08+?8QkjWYN83U$|L>x>cxIz?tW@%Bh&6(=kSSKf&Hb58)n$uqeAG7#3G;ku~?mB<0uEHTE@tWf^( zy&YsD)ORt**0Km+vN08_l}p?j%+|+BRVA{7#e3XR)LQpwz8FersiDH*(Dm+aNy_k) zd(c{S#(za#1aWoG@X%+W^w12l6#&L0R*0KDP&xcP^Usri6QDz1v9BHVm( za}^IPxp}2S-1tc=_f_yfYHmIWfwt{b|3(yYyv-=;Dt?FTk4pgTRuNV_*yQ?))SW-*yynXHm2UMlWWkCO|#ONZ;vqAKTby$=vHZ z?nZF~%F!)b7zZ|cTGXO}is+F~DwSa5qCv7KxR8ln^l0+GG*axvo!{o7(x#QBJq&*t ztPmtPgEUtiPAtF8aq;-L>%TErpP|?zE}T=hD%stfjg5v^txM8zctT;&7SY47I8%7_ zoTy(qi>T@KoLnx@<*4S-^{7Z=XE*3Ou24t1X`C;_O7o#E>(I9A-xj9+c@Ni>A32F2613j;K zDFb=>kCre`>WgqrHZzwhJ*TdxH0RG)|5|RQ3KpX}vL5zz$39`IHk-TFrw?sQDm}TV zSX%fS<}iqpJ#^K-crnBg{C+ zgp1lVWgI=sZ$@lH%k-yW>3~}5mZnyJnuu!*w3#6e-(A?j{bq1GPL|DQ>uDWc?XxiB zpX0`b^K-IvGP}8qpN+$}l&i4^OBQXB*)nU?lcg+WvQoEymEdS`@URg*v@bd!8{rIJ zHDrUuY!2WuuRojVDLX$Ec4Q6jc&t#7*EDfiKL2GAzGIZVjAiP%g3ClJ`;mTPlRFA3 ze#kzb!^+VZ6}?iqbL8l zXV#i|);ss};jOi*z83cRom1Df_u2a?LznwZk#M;E=Z1=jMBJN-o|8AZ7CsFmlOyw~ zmE%hV8zoiPX6Nse5^0Hz#+AKd7LB#ItRx%MZ`VW#BvIC2AEX`?XUHZW?STZ^tE*gI z^m2y8;KJcD37>+1cO?l3pUrCtzI9xbi0PaQ+X`RaS=Q6=NJ79J{gAC!_@-M%~+S3z_lAh;3aW zQ}aV`5`(u|0U?Lo^^6QQdppa6@J+O>lrZ(eM@{L;!nAcwd!`MeH1I6;`Sk1wInGy; z%|p{qL0JWdm-Y7Stqi@K@ZxAE#J2M7IM`GxY7T*INhU(PEwCYjh5LS+Gz(hw8XAWj z_q>stXfRp;)hZ60bz@<}5}S#BsE$~=Db|kKTCx$ag0bbf7~qdp3uX0(fSPR zdUHxx9Mrdspx0;;%he651k8>sWJkX|z#ukxxr-%s^i5N=C(@dmQ;(m(tT_u?taq3C zu&f~oo9Q#;*gaz}^-Xh?rEGHAYg6%XguCPLyC$=P%yq5WHNUgSPb~VL0yL8KrthnB zFN$0NeM(;TK2?nA%aE9vsVoUopVi2W@H1BGx0B%_;EFMe$Gpcsv`x#1FxdlNAPbx$ zsLPolQ_EiFUS+izTvd&+$dszEzl}{%6_)VBnu80iH_N`}9`u>HPk$I7MC6U);_co! za2v#Y$DccKhY20OFy}Cg^amIlY7F9y$PY`zNU1Qc17X-ajSR z-z;Vid8cM*+e|VZYahG}KU<C6>sDh&vEKO3#M%Fv^~@PZ&+JuF}|u^{;IIv-hX4I${d5>vZ_Q?K>UzXz6ATRb;%>~y`4eW~zK z=4c1z{nG|%R|E?R#!_l>gV#8MfjETh>0l6}L9|iXOH?j=--bUh>HW`62Uw~7P&b^9 zXl`5q0|ZfKPf^!{)>6eBsso@O2m@ndg+_FhUyz~p_`?Q#UM_T|2MWqgl1mPpNZSK% z9Ma_Dtb3RtenUIf^9-&@4?{r(i}M-bKH;gp>ABw%#4)VIdalRx1>rqcL~@7Ti8q#t z-L&vLC})7#8{__u`V7ptr#vArt_$L~gPUkVC4><+N5VlngD>A({MkOcFP&sI1U*9x zBaFiI0H~Y@PV##mZXcy-=HhBJ<=7;iv@La^t#mx>RiE<15vasGo-~u5Y!dfXpYy{J z@$_C7dmG3AfMq~<>d^SwSb~}>M#BVcD~;yjzSa-NNqT?HLvA-oH1vcEV%NOvBvlC; zmvM)lX-3hZ#tg62@JYIK#W{(MF6NbrD_(8pn6|2xJ4ztgBxfNagbRMxIj8bW_$y+7 zyiDJaCx*#-U_k;M?nXbmU10+%8Nvj?>s7^30T_Lip%vW-vwKX}FH>rY3(%X+ndH zRq~m!$JU7_PDTco=S@kPOd2m^mzEL4WyND8;r|rY)Nl%y7+s z{Q=LJJ54&rw=;TGOx^;p$sACJ-@u7}z&y?Ss#iw1ed^+Zma}jzm6p5vN8BL~ncadJ z+8p-p0{ihRXzn`l{w3nr(an{}hk^7~)#It~JWk(%pOv50KFIT3Y6$+C>meJ6Sw$*JiPr%=# zZc~{8#v~;Y*`hJ_;1WYjnE}y^7|86PYG+2;Jj|+x9(F(poQFQ~VYl#+o`w#M57QfmYm*3qq%&GC z95K}p_Pz+sEYK-BhHzHZ22X8UFSb6#M<+1G5_8gxhOxop)g~esR>?PY{0huE%$e>$ zJ2(8@D{CY_I;U;5$&VwJ|5!$!j7t^j?XI)aN{)7@A0C-aOtc&wZQQFzjgjlS2-+#7 zaI|SEE29w7A;nuZi!Y&`t!GWI8_=T~0rdMB%gnOC76RlI|aFEyK3u<`IrZ33R}Qc2VA zQdEa&(15X7?yrH?&GNH)T^a3JVsu%O%n`r-^Q8~ZN6XKfJ-t*8u1&aCECP^fN)vY} zEAY$`j%0{UF+`#f0-+IusTK^wYD2E-(`iJPn{Q*6=IxZ3dP#Us61!-9wB1$gh_5J1 zMpp<+ne%8&SU)rDuHEi?UXooGeO`FB;L{PWrT-(;9`q@dI)~w$%$U?nMdBRI7+9l} zvhXynxnBNqYDyyBLawG5>PUB`h*z+Y%+sjlk$A1ZTj+%=oE^jM**lku=d3&{6ti$< zFrv7Ap)R@=gYG%$0QJP)ynqsOaT<4^TXP%nE|;d`f3vG#`J!35#X1)dhovu)(!UeY0=0m$80NB&H{8B}$tA z3qSYd;Sh{hPFIlPBjV#7`t4PvrnxphLw7{+FU{NERQAYieI34o!f8v*qMmqDC%&bG zB!OoGsS%-8S2e+hz*g3ni}ROWSJig}rD4+yMLmmjMT-pNk*B83L3k6aFIw2${6R(= zv5~oxDd3MZ2QeJ3HvQN{4;ZEXE?^_>BhxE7@)k)y9nFJ|A4Bgitf-z49*<(E3mpJK zzdnE`0?Mh6>lg%kG_NSn2MX0GN|sD+K{)UJ;u|8yyjg1&?}+T*AGnVs*ZH-#Kt9o8 zsBO&NeYpN;%MTt&fi8OtAxlHxJ3qlA!`WPMJ{EBRK8S3t#ld#4dQy3<`IK0jl6*;& zAoAs?d&VY+-G!(|-HbsiACzlaQ7vAPf*eQ)LQ@C4RMj2yT1qDD4c^gqm*f!a!(j8j zB{^O6nJekn&u?t&@!LK(sd0Z^c*A`8s;k{GBjA?Oud*=BFl?=bQ+0X_O_wkGdtJ~T zx)GjFnc>x7w2*w~RBa4#xOTXQHbycn8TYK#8kA7Y(QQ+NN<2xotW1$*Oju%MGpWo8 zptlZX+IcpQX3qGUd^`F#(77nqIUQaXYEkAGsLd===G<9&``PD#wd~1W!&1HUlVc2F zynct8&XZujpaTz$;MoRF=EDgaXOe5A1!-b-E~LVZaUiOwtHnm zJ-bT6=+g96Bn|i9+in*N4~SjzdggnSC&zd)(C+21&ne6t@M4XdkSo)MsfeUEnR*S8q@j! zWqecKw>t6&BgwWW1+PQ74pM51Y&o!fRJuMcdPNeYcs8tZ#OFF3NvnAWZAgY#B|tC? zzE=W_3$e?c?F+Ak;*&dAtF_k&as0|m7ORu;h_XwqMOl;BV_8V>^Qv#YY_K2m^L-fp z2z*8BYq#WByVuj@(| zDyzqI+;mfdtucp3w0xlHtFL;{PkKBU;%?X@MV= zX9HDI=r`n1e!x%F-~t+gVvO&+g>+@9@gU~zp_Q6kQPuw8H5c4Oy*0D7K&ZB$ay17unlClP6{ z0pq{MgL8BxYD15jkl~2n0L!h;y+K7-9j6IP1)rQrr|*k3ef4%7Pvu?s7VRY#YpWyz z?jGAVk83QfzG2u2`w>h}&&u7uIgFr8&C{5KP9a11Rn^pY{U|PDMadxv5Tj|$M(P}t z{WB@bQnm>g6k;3)Nw;0fl3;x<;2zt$ROa66h->Tc3uMBaU!7_HwcRI391xHScf%$_vv9H_Z5T(zqt<->UdS z9Uk0N_dpLJ=W*V%xSuj#_~oTVJyJoyTbnm$LdY|iF%xH`_cs#ozl!5Uz7Zsam zf~>^diy0WAWta!k^ey{4id*uf#&O$p%Dho|!NUvgg7JH63x~<%&1z*b)WL2XoxGSH zzNV%xeO_L#d48Etw~ZRIMoLV!wFXo!Yd0LXM-obgJJ8?kq6-Z>C)Y3oY^!V{eeULO z#oNLhYDf2?mxj!S`p| z(4kyCgc_aDNumm-?MT8-hrQy4x66F!Ep;jx#T0v<%cuz<}cbGqx%l={ZDyZZ_B z6N1=!2n-Gg7(B|>tG$?~O_3#mDIwfQ<+n**N-EgA``7{b;i;TiP0NsdJ-0V{#17G6 z*iOq9ZB7(vo-kQ4OC1dh=1;R6Y*^W!P2q)s@vcjjYBNjl2N@x)M|>7ThGO%5=)+yY z%kz!Ns$(3*mDo+Jw)6PO!MH+w@Cz{@fA${_9sIjX%~eDrY`MbF9Sw23pn z?_;smFAM?>TS8tRp47yUl&6bWW5=HKjk z1Be4yrdOj6X}{WJkK&RpmdV2N*PJ06Th4YP`uAq_hT`R8g8;$pW-Cn~hEFKn71?QIgy+ zBM4v-qhzdFTBOCsmdV(Y;LH}DmL-q!ZAqze)G6c_o5KbTX+qhpk#ZavWe5WyQNAHq z<)XO^odc$vN)-VGQ88h(3fjf0{C6G}=8Up6QK2D(1|~;{v77WtMW)dxcJn~FL&(_m z@!l{oRnej@MvTXtLE77e{e}S(&+yX_jBo|brMd`4*(kuiGyAp}^l&4L1q$j#F`6f=Nu~<}|x0Vf4K2dc4 zI)SC2gM%_HL8SOf$Wspg%Z}M`QXy;OXtX{2dHfHwbuu$ z8iUgsqgg1V@O-5eyXrz}BjZp?#2=wAS%*#SXr){!{UE z5iD*&-~CbP-}XnM|5wHTt2<_ELU}7ME%BXnr%oE*k1}ff4Eh~N02PEQu?nS64<(KW zxywi_1b}5?XM);|2$Ndc*9EJVsvfSenUmx%m$Hg%*1TA@oYTD8UtYFdR=v3YnCY-< zHvVxX=G*qXb+zgA`E30hlIweSdLYa!5L|yMWSiJeHzZ22Uc7oJfOI=6xqZ3cpuM?A zz-D(Rj}F1}h|#=ale}+D(XS|66ec-GA(D!^QM5`s1Wz#?zpqW;lao1vA&B9AitnBO zc$riid1#gDtwXKX!Q&03mob%kcSQRc5i0tCrl@_kUuit8W-^WU+OFAMWz zzeaduEk=!5n%A`_q`P2@lNiz-5JsPZVt({ zzDTgip-}Q6Qu5h9An3d&Mfwpt`CT5L)!!hkeMc(FB@HjkyRT2N%)5(X&A7jiy(>}V zJl#6IGa>NJ@XhRFyogZfIzCwE+vN^V+&@J``o)W!7y*W)@KAe_y6BSj(b#61PQ>dL zuHy|$Gf%j-<^$n$T^@??R%w zXos+EYcLFaulCqp+3rxEe8TezL^d#;Xm#_M+^?!4I8p!4}! z+a%82Han%y-E`h_LgDR4r*5P^{89aq_T?BmN2W?!UuNp>J`}ylv;FG)Q;+p<^XkGg z)x>8MC_YI`Kit^92Bz?b7`V@S;pTMS<Za>LymUghWVJXX!zX7zM2~$KN=BZ&c9^@}kTpHn6G%4x;6K^_k@IG*5Kd z=o&H*=cCe#;0o@XUjZZB?E2z5+U+qXUuG0Ym$k@}H-#S_BE*#fhGBysOyJ*jw{LGQ zrBl}A1S8IXW_NXxWlAE1&NUDEr!dxK{D*B3%jGi&P>q?Q4X*S6GV*H&|1d#DqiCVV z$ur69r1^v0=^zrEIsjU8=?S)|A;S%{ zF!OzmpDLzfrG6FIY#JIAWR61`WMaWw_o`Jz`nX>n+jZ0i67)kRTZ{E&fXWB^kUEm+ zvy6#BC0wkuFu7t#u(h=-_o;AvFkq>^$DXx(+A*~zcy;4w)}z`;+IF(<;V<6=bT5-0&WNY>Z(A6MPxo$of3JHu{4R5Jgix{-n@U zw`wrVUG7K|qd2lI#qW~>?zfqOOwmV~xkzFBFIdRx@ESUKhdrHkaps;6ea?T}k|0%w z6L#h>{^s6-B{%?2PhN*;C%T*2=O6t1(OXViLC;Fo#KnfFu`~f@Xjn^27xw2avS882 ztAT(jE2f$|uUKn7EPWJcMD*ZO@C~Vi;e*n+0_FZiQ|m*W!D4?<*r=XaGzEWSV>zN` zSXDY6Z6UU!AU6-akWr;f`tzo&h%*i}cuX25RxH0(ivxVjqJOdROQBKycPvu6?Z5`k zIc&>c3<%*S@INGs0^;hA-@a6HBad{EyoEC~f0I6q9MJ!+P8iV~?JK2+JadkgAWpV0 ztu~u`Rr*!3mgk34$PjobX8RT9pu>r#L#b4UuRQ3>im$%6>JT?mUJE-;SbFu~M^g z4D3t4I*xtXe)}OAH<;W3P1mvOWhlARa|=1PhEEtfU?McRv(D7H)6O&?de&VjT36O5 znUn)ljubo6B$wXnj9ZoeP=Qn&Q(rF^^{I@bR1is_R0T1hg*w}3)UrgB`|Zvl*VwAi zodL)@A;s)0%Pf|3|3S^Qy>*JFOZV{$ZNzIoQpYl^ zcpP;Qcc_qtMH;SU5fZ5-p;BKCD&>NU^Zlwj=5^0?!;Uyx)7R(s#0ru*Hf{Ri?ax2W zi{dQfiiJx6sc03lR^_(h;d1Db1mD6)DHY8M$>^3vP^6`B=6rj_qVOSr^Es`QN@aLT zMiHr2=a0X6CE^S!5f)GY6fCpyGi_@JBn&Qd86Z>?>qcr_3QkJfModW{DAO{OI+L4Q z*y)6yP@*4KpTEhCvZbaPm7@b*lSru?oXjptME#tV#I5M-TYN=P>{UrkgFdjiep9fX zJN8dY>H)TyEdJbflNoE-C4@{N^OLBqCJ4YR7vGhGUHmN}Ov#vnq0X6RqUMb^)6^bl zqGcITbXww;no@(&w#+X+UnES`v@Rz(Cr+(sSyW6*#n!42ppjgb;ZlrHVb-jW zpc#;t_A(5&?G%ELiNv@wj7+_iNYSJf^NP^iQ=CfC96OR``T9E4OzVx$)H0|@(JWTg zvW!Nh>3`B>7&U<^l!BIk;bgN-8tkT*dCau=CLy~}OEu1&4d`oIhPAk(LMOJ()X$}l z8eUK#hXRGkoDMiKnbbL&Og1jPgatC_iH%v=IhXh#6Vt>^n>Dj0JZ_b{n^_StyQgy2 zkphL9D0Y7fUrt4Ig~q z5Ofw)#Lcpu%_>D9u5GvfiQlg1dpRMddygxM?=3)#o1cF)l1DUKEI*G?3N_LJQ#_eU z_T0{VJ-2T#3BgqwL&2hGer@d_8rs$O7nR^7TG>BjdJHhm8ExS8L zoX<_%xUDVIoBi?kPCo8j1sSyv+Pi!(LAiS^DE{4?CN6Y#y2;UpT%+AXyv%;pqzrJ| zqSxhy5V8Kw$y74U1cpV^f`5#KE>_u_Xpu3Fp@F;-kX_(kY!F)D!SROQ50lKTMd1z> zcOh5ILd4kSZoMAVz=jSgy2yWQwouKZsi9rL`t$R6I~7mB*Wz8B-Rql*)A!6<;XPeG zYxpbGvEVIqc1%25m+x{dLg?pd$L2-#%pf|I?Tzxfm`WUo78nv3OTSei&s;*er$5Ff ziMnX(sDKE1FK<^!PcrXxjn6mkIzU1pp+693$ZKn3bxMqWB$pU*!3S-~VqQLy&bUsB zPdyff4NfCjXiJSJtuM+ixdo77cQA9YU430oyGHd|Yso?NJNU(Rl9kk-d$}U8wpY;;W3b6_TBZC%~rG@(h=8VMV+) zxQyH~bQRu90KXx}`O;rC=&O3|vy{;fNpZ~xNJ}Z^Xk1G9>Pf8N%{Ur29PkP1EAq0m2*i7X5omfoV zlX^xxG@LK@*C-|r;fzjLSy`#`Ud|*zk2cnNTjmo1zo#7??7yK)%FS zT!9#5=$=I$99%{DkNj9*KNW&NTL82P7h`#Ny*cL5tRrQfk~yO2cv-sWyda*hIXXqc}z{A%wZ`jZv;3YEB9y(L%e(n?L>t+AtFz6V;NHk)9_cw zXhr1%PU%7|No@!V*bpg3PjhOZ(~_tRX=<7s7)Dcs=mEFj2OSLsC~|yIE~Y*`Y~uNO zyI)ztTI7KNalFEK5%RPyz=<}1HF(fzkRK-t>g~TMEie#U0g#vA$x;@;I-=3e9Jepf z=DGsd76{}zG6wB2uCq_-cPx|LP+WV2CpdPP?1)1XW$tOw<-a4AF$bMp^2(=4 zE)b9hyDsU2ayehFD8YvMNaJ54M=-1uN)n6hUBxRVa847QeYU{iiMb>DHHwgrA}2uR z8>M38UNtcN3eVNhh0-U>W)c`J!Nc4JtSz(td?dCR7E9rE^;sUhbtvMLVJpieynrpj zV)|%$B=Y+nS^3=L_X9Fqk)9${m*l`13uURE0t;?2=A%`Hh@IgQl=k)Sdc-QojDb!v zOJ=8-UgM(c{B#~=qUHyB4-`Z%10>;|5!0JEk(+saPkf?-)_#Ikh=j4I;_Y?zzW9Q* z2CT}Q65vn^*GRW%fsD5xSb-RiEoRUR?w&em%eFiV?{gfSa5jQdW8{;2yUP!XF`;q{ z+e!eu344|*NhUMWv?ZsRBHX4juC^kN*}#;tWAebp8ltLu=2&z_orLCWu*{Y+>nBoG zKAA=QsSsS6MyJ{|X(%>BeUQaYs+|gnJ^-cxv9@G)u6}n0x-BfE-zz%sxndtV1L%eo zgeiUGA&57_DZR9}KRP312ZV~$ibv3qw|*OES% zm>ry%9he=rELYMhZr6`OYOeN+WdAIW2c%K1NIM6Lz^W|Bir|zQYp9_->txnFClXC* zKgKh=a3guUxc^pwvkmDFYgNU)EdXsXPk<;!Icl=39v2Cdmf&v=U)! zIgm3%PaWUOW9GT9ZTUu~9b=+BPgG?MgH@p;#^pRJUcXIs=;@IGh=B#ZvFUoJnqq ztlTlSMpFaM8`FmGe&PfV-c)v0J47)?K`^ri{}@3UUoLCp(SNQaaxPKkIou&rS}3fK z&n0Z{*7wrSp&-gL&!iErZ0x` z4#?JXz9Igv<6L{ohW%*^jIwYJ8g}7$aOzlARUX@I0!sbKvl5hwanfh`Qeu3bMU_N_ zggbhh4Y4&vyB(^~uJ5l@F>>>MuO`}GzUCkPB|!RxB71N266a@dBUhHj7mV;4HGF%* z9Np6k>?`8M&H35hnk9u4E^eX}QeVaomnT4( z8dA<(WUN~u55}y4HZQFr{Gh@>qY82+&637iM$o8{Jhx^^ekDI}`hz9QR<)4dfp*4; z-W>#B{?N6`djNvvPvqR4;vUny8<*nj7GSie+RCfcidHiNI>J&inF!KZv;hv&%&P+9 zb>`Qw_{Sxcq|p+dQBW~Cu04XgBIABZSezFsL9PU4QMp2K!8|-eV5%Zyxk6K%J9B*r zXTA7%F1Z3;`S{_7*!&94)y8!f_uixeocAy6#wrobWk#9{wO!Rt%^+)mYD80-c!UwBbkCLq`%*h2g^rFT`&r7~&0#`VOX6^1{KO{?BdOk>dKTI!;VQmiXcn zfeO>CGfAu}*#N#&^rT`&qMlLIcqTFLJmznoghX^`t9<^q`me7dd)%vB>Yq2dgWtgpy| ziiN4W;>01;A$kWW!~tiE-^&)iuc;WH_rttS&%bX-+l0e}YVD^iB+p#km(Q?Gs76=e zwU=ZTpw$arVC8kImcr3D*jmoT)xPAOQs#SQ7kNOnkDumWxS0Ovhss_TD*WXOdg?Y0 z)RgVG*mkILGKc6w0H=mA2WZNqTq0qX(UE02hgM%ynXThl%&Q5>(E;J1 zQDEBzwJo|>lyS~nmwGPqd9-nX;VH5$7F)!9ENV~mt?Cw-spvQbabfeRYCnT`uuhiijDx)Z;f0D#Ip}}tT?vZ6X6IZTB%}zJn7*qb;$MabWXM%sG zI>Wz~?6zq^^$F+CC#Llu5A)|4g9bXF4UD~V-H=jGu$*(1$(mTbZzs<`dY4@?6FNbI zl1}nvfvZq+E%;(yW`VeZeG_cNYf0OSr+F~}scimzcIIWCFn~^( z!X+;D12>C;zeLloa=Rxp>?b{jOY<)@ME+wsF=mrekz;Huq;6#NZDL0ATiA)Qy(4`7 zVQWrxszQ_iVj?gHKqt?KrF? z?Mg-K&I#cxMTQL8Ym0wqjDJ8lSJ(#)b3uBMa8O<6+qrFMhQtTx678HNcVO$<%kzUo z3EpFgC>x?Ks2lx^W&@w&E{sY62w5}{U>pv&DmUPkOLp!=Te&xHoAz8P#v#skgJYqs z79>y?MnJ<6%%ftk#^-RSNkVHp3lTaA)IJWTfom=ZSb>{Qfp)L}bW%c^Zk|l93=FD& zvspdx+wzXm0CC*)OdM3Pa8;?`m4MJdl#h7*4u$ux7V|uvj3-hxn4m z@~urDy->WRfSv^*eQ5lA*%S2*0+%S+9~#oEA^QUj+U22{>`65ei;TQF7BL6wuKFWK z$)dFmTCu9cVHhjJxT^SUn6rXmdEv)_vnBI%9?NjLbI4wy%rN*ly(WdFb&*rFYx_Jq zjKo<)+Tw7kxUQ4Fc#D@GY&lZ1*Qq!Wo4{}>(!BFAAlaV8z^)!%J)5NlIdzbx#iqG4 z+NvI}!0d4N4#nrdeYo3!`{1M8>7eW`$vx(0(&}e(*&q?VC!||!Ig7@YviiYU$!3Oi zTcn2L86b}gBT1Z|@tQz`$(+uwAp7y>6+({9?2}V8C*_(HxW&y~1Go+!T`jojcgH_L zhKwe2XuHnGfc3EVQZPI;@GJ+r@Am$sd-vJzk=1`g#q%iDrh`y1|E!Bb_Ga1giJIhj z+9YWPDtTLJTXBLFJMDgQp5>f{Yl5WGBGH0tHn&=X%{eb<9#6NTYmwsad0Hm)6^!Sp z19Ka)9HCbm((esz;*sb;^_B_w$vg%6+=B$>BQWRz1HdV15y{vg4S2b^jj!cE3%d6@ zea0%A%lO2{$=kMAeCi0tfDm&Ao7=f?C0{M*xe24~eg)Bbtol-UtV%m|5dA7cc#vc8 z$iDhDn0sW%n>t;Z-Rdjp167l&sONuCx~Mi%lWWgICR9BWlJA@_aT-u(U5H}@(Rmik zJlh%;g4J;fdSIBLe_3KNT+BStnstn&)~ntvX@==_>V2TOZlW!hipe&wGA!dpAz{+^+RWp~dpywSPvg6lWr9%@Iwebf>4+`8eOd&9=N z`!O8qJ^KQ~XY?Me$C$3ihW540{4!%o>Sx^k%ETmDz|HU*%E6Ug{@FV(MB(blxH_DX1P+DZR%UsT~0=S9Sj<4!hb%;_;M&-YO) zO;jFaK4x^RbjE>^tJ4dS6l>{peL`WmhVU0hesk#Q0g_`T&kSZNMaDX9d*SoO-Z5ij&g`)l$OpQ1`PzH9=w~wRu4eT=|L}SsiOkB|U13ChlV` zpLk~0FRyIcmAwzn3r?}vUG_6;uBETITqYj;N{hDQ!f|XJ-28iEK7%{ab})>fT$=&k z7mY^%;|6J^l;|j;w{WE!fL5CwJJGvEy**$v4!3TTphTBg4|jn7Px&ySFMOST>lbGJ zt$u<0e=Q#wI~OOD|4}_QiW`#ONvk{^@pWSgVhiBCjr#iCf_us@f>FCy~R zn!?Z+7e6^zk{OzjN&XgNKs2+v9-etBt|iTKJ4Z=2B!q@kg)DI|(~rwbut-`LT>Q3q zjfVt~evMTlgd6NQ*!k)m4?Z27Vyj4B7|T~ETJG6}gK9O)6f(ME!Bx!%md72COAZ}6 z#Yq9Dy2Tq6lnEk{)viG7K1G|6$3mG!RY~G`XI`?CcHe?~gwHJJ=5_vj2wXPFx#2(P zkYE<6Gfo<#s@L){0!q2&RUTr@cq6ZQYQ zmXG$|!>VR(Vq*P2MJO(cGE(2*`ed#S51U(kd^X#_HwBbKAQZS$Knqp|6r3=_vyzY& zOH_VR3n*~EfV}?$E_xKL@pgAMTcSs%w|93J$Z9}2Q7{Lt#iW^gOP&#u6jlmLm8Ck0 zxEKu^bLEd$&yDMiXVu8g7#DPB&ukw5$=5*qCUQqy)$5LKY+T66q{R7XDgSs)dzl|= z?H3CYH_Z}TFdb)Oi5qzs^D2>}R-iuZ=;Uyk>VI^M6>{H4E#JlANlrqrmcf4NyLkc77og2 ziT(z<``-dh{l5Y&WM^Y!MaHge^(URt!Z>>UOKsf?0MFjedTGb0) zVzB5rDYHe_dvYE*?+dVR5_^XwSmCTs+8T$`^yOqwXID?>5B1(ge^pp4aYJ&E76T9> zz!F1=Q2+sEa@Q<1y)gpqRlAQ-vIog;+4nqjYNjH|7DCF0QKzuBeJDCjlhf>IrITq) z&4}&^%yxM0zF12&j80EeJ!Qx-_D_{v7}^3QJWsbxlTn}L-MXF3G#P3m<6aiOqIe$F^TlOj)L3innjp>`hi zPC_Q=#4KbE9u zP+4ra;1PtJ%H?}OeQt>lCF|?0?kPqSgGf)}D+|cQ;zhSd`2;3r_y`?pnQu#s0-^Q=S!8D*%N#p`6m-4-Hv6fY~=GE{Kl_tiywP^E?d zuR&Q1d|#mGxvx%YSbvjo`RQJ%w>(b~5=xWb*&F{OAzRTxxu)W~1}y(=4=4R!Ye34x zO(&k1_(eIf{*Lj z!-z8vbl(MeDT~m6P$)0)OQF7aWIBGO_RR081H2^g*Cnt7^#ZM z;^!{w@a-nlzslxPn~v5g6`kNUZ|1Ca@gFo;fjLKQRT1@doNb!`y+ zLF82<_Le=NWQosF3O7wmSN0Z-b@-x;GWzGN*$H>mSwvUgulO3nMIQ|}7xbt8wI^Ov z3wF#+BHizI*)eg_9^_^N99FI?%B$9jMx^Z|v_)a$5=JLd@c3B-GPyuyA}8*_IUKQsE`>`0bg7=at>7$!W`{pI+M+oZoWM+u~vwGxoAGB}`DV{L%KHoy*vsqbv z>cu3$5m^Lc>X6td#y=h4#AL+rAM|JcZ3h7Sf1%ItFA)~klidn0I5;>DxUDNVt1Gyy zD0t28`+UKna?50v@=vm#J$a4%bX0ZJ@!9^7@dA*86|*zqQxvlhQsn?fMtXY2TleFm zVswrZVswmBbS6f~UrA>t#K*-KZ)7ILq^bPDaW0JHKu-(|{6HumOligjyFl~W{FtKP zs&Sy-(+L8yj7m+y=lcWZeLw&AY4!al_rEL8l}rpAjm%XoO#aj2rdm-(uK#;9!30YR z$b*9M0C?_5c--d}-3b`Pq(HMk>ww*ZSztXP5n@vF+co+udJbk;tOTVYh{i0{ z+PpraIm>XhqhU%YDOP(m(z}l#iSo`AC})2TAW&elnFGLa_IEuw!e)QnR&eRaidt=< z=&0FKV0l~rX?4~PnUA=FgEPnU=z+);@7jkAiJ`H!pf{&6J9HgNK8wyWhq`usvr&>B z*KLaE0x*sa=Mj$Ex6Za6(;X(yOm)@!gggqa*$IVA{@`1ADL*_f1`zTPe0*Rkw!NRL z0Ay2BbSy2aIE1jpAm`-veFW&SJOb$jYk$-cMBEA1IV*aDO;9R<>W1YrAz4Bq<`|%y zFzGysr4nVY(0yyZBv~Ir&oe5l1_#BjDr52|8P~Z2+=BN}#~-v&N+6k`4p2eFy+Qtg zPh+k{%JsVfkN#~1{$Gm&lH%V6#{a@l*1*-m%)r^s@n7XwtZLzwhR^SVFLd%gw%^h0p|F;X5%%NlWE-c8cZUZ$^udP7um z5Iyl$4GmdvOj~3KwxHlDJ>aH2Z4JYOOD!VKH&7igL90DC|0dw69DQZZyJ*$aj&4I1 zy_E#Jiu;l>J#Z!3G~xvF4eAI{DHSPGP?=AH&xqUD>D#Pp(%6io2(u$!`&X0f6;rY^ z?pzO8R}6&(76Q`ficrbbP#dF6uR5*PudC8&!w~J@4e=VRCwOY~)f%y!*R|^uOEO(d zX&j7->{JB~%v}Y@R~aRC&jd|%*;6N9nMuSx`+om54j4dXn8(xR#^TOIs;R}7%5cw|HX>=ZHwuqT#7p7zWukDb8M-L{jS8UHBi%2wV9Je+r7(~E!xPb;DPPH{3GFEv z(c}*&>@3A=zKrdYkW9QL;AUhvM_sf91GZO{Qr%Q!F|ip=R`d(Xdi=$6DrVGJt@SjF z*OP(nC(~L$B5EmhdhRuouQN$5^l@AxlRaW+xZ=^GS|T1C^+Cp>_=G{2rHekY0|*47 z%I_OJv?704YbdrVLMwexF}Oo}tvsh4TE&d6uw&Y8uPr<>AJ>E2!_i>lZ8y|4ftmA(py-YhVdis=FsGY79BX)PF* zVnqvZR>66s5~^vhXQPAy|LwaLuocM>(#iJ(D(nmr-%r0kraE#5i!PqD$tlm+GTX9# zYe)q?ab6?E>*;q2!}xg3Vbs{4nrJ;bFyL36eBJeCWYXy6kG-vr&B)7ef4deks48)W zzlhshEh+Ws@^ZbsGBe-CR!=Rty6W-eMgYrkhD~WdMD{X>O3(=={jmJ{RS$k7cB8^E zsPH@}Ha7{M03KQiE7;wqj~kfC40wXg+0(_s35Xz_zWTT@Ps0XquWq?x1dZ zJ?4&O&cppuyr+koYpQdyw3s$xec|3C3OE!5` z>imq^@W~+;t5*M40qVukoho`|j<+Qw#@-BR19C@2*bQmJV;7>VDc9GH`crLBq#d%l9q~)xa313yue8ZwE?y~RwB~$9e)ir&R@sSu|IrF> zH0#1zL4klAp#R+@`@bSZ#H{U{oD3X2{`)MOknNX8&H87SA$b>2>DH@<+?A{>t;R*}YMqI~Nqv9en{cO6mJ7JLGLU6EnNFV-;pf)g0G+F|&_@RNGe>Y9 z!xA&p8VQUL3VDt^>9kGQt2W!c@Z4ms^mi~JKxGJO3Qa$@-lWN3ws$kdpGmARA$UA% z-Zzs~Nk)Dz!_1d^kQ^30-{W3VYm!;RLC&kJM%V<_KYUb5L{SljVMA*k{oB_P1GYb z@TqR_`%ZyaTKj*aVn=0uXWVd#eI}oZIXiGug+vh#ACTn9C8#WKi16vJ0{JzyHTSsv;T)CC~49cJiO| z>>JDP2b%xP{~_(IqS|h_b>Gq!2u{%A9^9>1aS!fZ+@ZKbf#6Oc5WKj%6m3b1YY9@k zX`w)ID^j4F^{#K9wa*@V?K95!Zj#*OB4hkVo;jcSo6i*a=fl5VNFU!_to^M6d7U1W zjQ8;@%;WgU*4~Hrzpr4J|GTfqdwTfzT6_5V{A*`u@hW0oRgF~OhKpBZiK0d zS<{Ub=bcrDJif=d z-IMx;W`4M%_weLo;L1aaIxTQ(lRyghiQdUf_({nICRJE-!U--U2{5DZ9&*A3`9oNg zazYK+VU#35-2ixH0vQlVgqF!CM35ZDK3vo`ph+f>1yM(6nQ}r2Sz_$NM_mFuWdfNH z`GgzECuEQ=#y&jMA>ddhkQLEOxRG)~3%O$KBS75)=wz)X31)ewll@euMgS-2G944R8-9+1IMC5 z)vpuFoUsFFk){T&E2oQ)-!V00c`ntjO%rs>V|<^nOyrj`%D3>Wt0W}F@o2ykI(=X6 z7?GyDT3@zhX}pc-STr+&gE{EeN;=Q zZ*X&=`(^UN&XlBb4R{dPN%tI7rFs%->V{A2{Ky{i5xgen9)T6@xLW5s^3rHI>3vFa z4tvEJ-cY@m?K)Ug>A=ELt_s$8ug}_UzOQmniaS}^`ubQ+F~QWl{OA@ zR(AO^UnfUCkCtQ1d#~2&#mK|~ZuT!#M;VchXA;~ZwMRnkVhkPl)aT#y1xk+_@=_|~ zbpm`9vleQT*8&&hg11E^-8we{ZPiYvCCj2_Px~ty#u4W$M}hVo)+r2i*+mFrVNPYEAZk0<~3@hdXN9bzm(-ntzeA2P4p2`b>=Rdor`ZM4e z8{icUvilzFj%s#Z!&lg*l=ybh4F;2^66Bk66#9kU-=DD>EGN`5vR{hUPN`*b;9yYw zy7eO-a?gBfG#t~&Xn{$kB@fe3wiwyXb9E}IedxLAzu-B|sq8V>wC9r}3cOZkO3XR^q%MtCPoUtRvTrazwjp#|inK7MI0qV1{M z{+cmgH7{R?`EjN1{>qM2!?o<7-0M@o9}+`nW;cZu2c|e~iWk!YZzSi$UwwL6%l&8) zV6Q~~%v4Ut!1EGIn(#4KZ|oed;BqJxt7NfdN=df=QbxU=*ELw4t61@P@^)0FFJLbI z)E9nuQ|L6~IZ}GK)xVou_Um-!?Iu(KJ7jm=p-d)%C`KmcluFll)G~FF&i(F;*m;DT zL<0eP`7>}U+X5Y`E!@<1(fyPwI8I zD4znK8+}gaSVnSsdCD1c+2bR{pXttQW<0D4Qn@whgdWgSyzb7lV;wVuSuppiVwn84 zQZqnA8Dbt}2ZzV{HdhHcBRq6T!5$-9>hEV%u8*O zMdd23Y1_s#K@b*FJj_j1j9=8c%0RCX|2l zPTd+~#xyCCJJZjU=h9*d5+AcBQ`Kech7W<*p=*dz6+=}IdlROb^tIvd=>@Fah1*XP zdiz2nR%^8Rme^jYEdKqct|9?&rQl;ed7|?eg!|v?E9?KKzFJxTtI15s*$E+8A|0MF zeM*y5$zz>}NiOqsqv8d*tO^^9AtNQqj!2Hkv0WmQ%s*gj-9#0Vt{^v+|FYjmg4vK? z4!|J8{IXxHf2Mrt_y*@}t4}bX6AQZg>0r`RQ+j7ZB6wSR$qH0Te_vNXG;gGIZ||G9 zR|u|xZw&dy?yZB5t%G@yPmuITlS+n4>q=myP9=Y(BU}J{Y#S_%^a0bozNJUT<-VG{ z09K|6geC9&02jZ$Wky!zzM8tAsGJc9OWivMTfM$zM4p3r`N9(RsF6AF0mKC(@+I;) zk{L;YR0r?CE8#qRQ+yV7dG3NbGsBiR)}uf$RYZlT63$}19ZpF6i`v7 zJi#qWpV)%7KuSNQ=fzVwFZ&O{+EKi3-pnRb#aD}cJ=}1fE`b6)p;d)DK=_MG4@;J} zi~(q-hxu9+68Pip`PLn*Q|+se*CHJJ0VX6;wg{fyVFg8JQB@8i*A!2##u4!;yR~>p zzj78Cssif-yIITGEuB^mT$kT|thO^Qzx#5jTC2|W%MzO5U^R({u3znI@h5W1YTir2GQjFZcH zMAL0YWnr4Z!VpYe`V1;1FY?QJ1Fi8FnAKQ|2PS_MfyF)oMb@4e2VQvYz9F{7^3ej` z(jZY;QV0L(xdeQRSP?gc@*vp8w&`dLpMzDDr57%@gR!!D97`lHL~b%o#F;1toVrMt zCTvX+2zw+kQq&8KW`Cpe`U%@xe*ZE37BH1KOX?+&01)=NjllL)7WeD+)dWoreAZ!t zC+1|>*!zUDpqRY#4olj=$*`Yiz=x_Q`TLmM5M z{YzjaZl>)&uD>IX{dO8!X<$)Sr!W_<0X#8el6UI9RFXG_9>3(ftLqKj7l4Vsg3fvW2d^uF#)8DJF}|y!y!mmW%f*N;u)tbvfuYzkK)ovfN;Grkk@)YoN z>6*jEdmdGLI4!}{_N%+!Cat$|GMDra>j?RY^(vM-U}KTXUz8QDsiOP6e$gm{{TK<& zFmuufvWPS6Xj;fi260(cnd7fwUCoka#6AUzSt6wd%=xU2S9xiQM57h_36hYvj5(1-;do}<7Uv*%-hc1f1y|7G zQ`P9p260-ns2g9^)@R0Ma@IQgY0gVA*!eklBOZr&JEW>uw$j-KQVv$piCZNk*e=D6 z5=~f_H>K!Ovu8Fz*$(=g+X%~gUVZa5k`F33q|-?rPY3$E7jNu2jx3AP^1Hq?nSA}D z|B6!hws~^NPU~c7Cp}aT^{Go5Li{pINcV``mm}-%DRoK5(TLYd;;#_H_)C)@H@{3Y{CcAV7ti3wgSI732a@hz8;9rvhsI%#74%y_;2 zmZtP!qCuh)J(UaxNjGPmLCxqo{ncB2c5hF^O4E!KlL_HOx2Mavx^*hHhIN`5-1JwG z^PJuhFd??HCn|(?9gGa=4fFwQt$214qm+vNZzTb(h8czQ1d;W6Th{5yGK-vNY%0W~ zg^34Gm+?y3&nVNS=&4A8xJUP8j&$vKM_;A)k}eZ?KiQ&HqukFD+CH7SRhOEePk#7wr=MY#h!l>;#m62Og^$JTls zkj5w(d-4)N3^!UUmXl1w@wh7>d2;i7f`A7rjs5KV;PDJN8r zO~yNX)D<8?=9&pnO!$y|LJs-Bc!!5N2K<$|cEosNi6;)?^hMwiT zW5al25!A#8<6Zda#|rClG1N_#?{ijfH=3nx71*1Gbldu!AhUyI0>P?XN7LufBHXgp zV`}o>QL{-EC2X8Vqhfn(m!B3$uZ9;>t+mu=fXhCPBSK%r^EmC-&RVDI`(ErSP;qlD zWfdvMq;iSZku5Dc`Looq|Eyu*`eK37Z!|K5@CXiMKoyy0pJmpfv-FCv%;8C&T1o3bAx}zNP5s9BdU&1rOkR}mCqHuo+a(NoUqOtiO!n6H?_Q{h zS(E->UW%gwJ$-h~{LYl-XFfaF-m<|*zYMzie2t3(4n9djdw_w4Al%Z?ws|5c-gW2I zaXq@Qb#H8;7(*FQYQ?SVEU%hcmDo#_FSq;fZ40p-O{|%&a&_m=pZcoFW0coZGgn=@ zP58B>I4C=_rKTb@bvf}kMvm-aGq@C+E;z53*f* z=*buMtH9dxPDc2U&44SeN_66hSF^#%%=}}AxHA!}`s|KL^|EF; zo%y`DGm{P3o`!6W=&TS=m*z0JMoY3tOD^6&H@e#0ntD0eH?!|7fV##Ne^pe1Fe_@O zKEBWO+e=5uvybbORnRfxt-3}!cvHIN5s9R@v}{d;2DKE$+S=D)*VGu#87q{dAwq>*W2bvc?RTUyVN^QdItii*{qmM zjO({tSvh^_&`FbU`u;h-;$z}rT)1CxdRBv09TJI_Qaqu0IUMYwG~Yk(^VvY67@vg` z;GQ8(dC2IDX=r`@-uh=6TviBt`0IHVj``t$aSVpv^hs;WqJwFj7BSg0EC+0OkU+{R zIe}->@l$nT2KiGJu(ybX)1ovJ=nKbk$vQI1(Me2=uN^e8RxcwH_5=M;>$w*Csyo5i zXi{HRH~cH8N8sR0H`bh2B3M=_tc^C*7zVID^(vKJRgGEiKt$zf3v z_M)P?952SXkmJq$uQR=c*w5be4_)sg)tGczxLvJFbqifNhU_cW7s|4r1}lUHstUa< zmY-I#e~-XLVU3>aa|<~(hMVJ+T>K+u?;H_OG2OBduS@UC@X7*=>vflKNK*+gjaNQc z^;~&zp!kb3aeqWiqgVGe~${)n-CBx^!(+aS?qb_p^DUtG{j(k%8gAQ zjrZJ?)X8>MlfL4k5=K6tt3 z;sFH+E;o)!f${m5-;MTzi$=B_6!8VS)5bIvQ~82k5nE)Gfh|AU$z+fVhz)O%DW(ci z*n8J8vgY>1kGUrn*m+AsEfNcCyz|Bm6Z>+@NW)*u`Oz7SR$A|h#e|H5<~$#2gi~I#gCzbm=gO6#yE2ijJC4Dv<}`f8Akm4 zxzzg1dJ{XEieQilD1eTRggZ=+>_+dK{w93GdorD#IPOiNSw~5rk0(ELLRpuNayC3vpB4nej zjO8;1~FpjqeKY&losAvG4+%+FUnebKO2|px_DfB4{3MiI)94k0OX6Pl8PXGu< zAg$sxHDU)i@b=^df*d#ic`QNxqh5F)^;m)!0S97F{2-q6TuhVH@a7TgS z1w<%bo8jE`qd#Os|C9&uoua6P4mJb}qlc~c_o&;`@?_FjhNAGR^aoj69Slc4iNyO6 zDvNz>4w>0QmO0M%{kk&XTa9RaqttskNZqcv!t8s=|LIlX7U58$@bIs=8794l1rn7J>aFBx>dp&;x~QV|1D75+x@l0k7equee+82Bz#RO z)1mR{j5votTO>Bkp~UG~#miHy3Trj-_UTM-o3dw9pU%g--uZ-Y#=KJN<~i^(n=cp{ ztovN3KJrkUo8OwNqx({`2`XNM?VkCoKTNXyLRUZIN33|^+xpMeZ*BG79&yR&+z5(r zxg2jK=;)>t;WNa+&*nLNh~JCgs-oum@~1efZPrbA%Pq@;555VbFS4_&AXD>yNAsww z{xDoLu=4m#a+DoEkL7Z%D9>*}ajcIRsCe&`1hfw~ zmG@~wyV^KH#R}DwnPp{lLb_MV@Wu1Gl|gUJX=3$z&Jg=m)E$lAqY9`CL^EjK=u_v( z$+=o^-9B5Z-)k37%;6Omf34wAE$CdZVVp~py^0hpudnbesK_ebjEEG`5pHUWv;b84 zy`Z4dwkr3WNW%~=Y+&xDB@PVE;801i>jOS`CD(yV53+D4K5%okhO(a|*VQdl;LTa2 zHha%af9>JyG7%MoyZqXEBa+b;%t+ag&pcDaS@p(Yz7J0W92faq3Kq$A(YWw#XjsXQ z_(I>d!BkZz+pqxw2M5b#Ka8k3wTH7DbbBZMZjBYZ@YE-L-{r-YU`~qv(l_-nAn(Zh za93Q`2lPsgrNS?j+luFGSw^rn6FWuS%kMLdg47QaQFh(3^Na66Jn!azRJ2}2mJR5c z54;dV_ZuG1kc(6kr!V`Ho&S5fR@;?Bb#nTPs`RelqyQ&n)1;Y})6A?hEVa{6*=IKE z@u6zK4(ruE{bpWEyQlI)dwiv~Lzfoag%&r`M zmHI`Wx5`fCk=)>vrzR!67@I*npnUO1D&E?wtdd9 zVHZ+d9H^Rp+gMbdW#V2M5)vyHGpD-n8OikSK;&Im9S8e2NM&oeoJYMK94n7vd%~}( z&I`1P6i(Wa=*S!dnBCMWH78CNj{EtMEF@&pwYJ!qX4jeF8dWbCbToY76ntgL^WETS z&V;K4o1)Vj(TLE^1|Bvu}eTgME}=9gUx2H5QA(}QVADbqEivOy!!gb zAP{sTBX($2==KOwiT5ORP13!TS<0vH0&upSPk&FeI=tzVbRRl#87HnLja&Ax;whIW za{p7^=Eqf9<^ZvcNY?YBCTl8^J=@~Hjgiz5;&bQJ_bY0DeJ(!KT=9=e$?=K-_Ld6} zmcdGdIT}DNuD>-N1)G}N-mWZ6lX2)OS zMUtVpQnUkQ(Dq-n6Yq|Ois$+Yj1`=Ldvfh8*TIW|-G-wWAS!q}_MUZX!Wbn(KHPl7 zt|6Tp+$rEp>>W1bP?%2DY9G*!2Z^f(`x9kzM))94^jcS1X z1xV+ip1yMrtA(Dk-Y|wQ%O+E_SR^?Gu&<}8M%-ScrsIe)z_m}5-U=N@- zFVq>-g&l+ebrjem_D&pY%e}x6o7!3i|Hcl&hwcb0vu?ct&DgeD#oOq<_LhmC_-yN) zPdH^4J9a4N0H5UVmXEjgjvXtMn-(}_Wu>$9;-NYK+M`vyD%!JDHCmb1jFUk22dq30-?tPGVA9HDoM~+n(4X`N?4#a%6#N_Z%lXMD z;=}64m}*j(sWpW)I_fEc1EB~pVl5j5`U2h|>1~ zQ5pbGr9d2n8E_-^QL4-S%O*JSfLzh{k)y%@$I91F5SYMMkP~ajlOU>qucA*(ATtc1v?v^amBKX2<*xY=T7=<=kH*0aVR-5Z4#bM_4jZ)u_#k`D zjW{L@PdmYcNHgAHp=JOPve%r5O~QxN69R~%8LGJ9g!h>Ujeiy~Eq{r<-BlDC6-dgA za<Sh>{7F?SMmHuB?HN<=OyNYKXwD@6l72;tUd;I%_OU<-_p#yt zOBHn^Qk^tvww&^6MPT9!jW(LS%%<@EZ=rlNv+=nG41r0WKSdlv_Fd=F&}Ff?SD!j2ma&SBB0zG(NCp*=EaA!img@v~mo=%f8MiyZqyw z0;8!hmOVag;Y8B;Dx02LH2IXb%n4{&) zJ@MaI1K%Xvbk$;mvVdvcmf4M#{y`p*@$yR0+y~RkpAW(EGcMtax68iLK2;zn8NNkZ zj;ZsZW`TC-W;BZ`4oskwdgZ0Snz2t)sS{7oE2&)Bxf%VZs-6-}>t;l-Y1itF`JQfr z$zMI)EqkxD@)pXoX_gLBp3a2}n74Gt9hvGTUF4K07cD+6lmx_j$>y8UYix2faUaa- z`y*@xn%M|CXp90CQ6`34kAWiB&K**mwVx-X%J$dDzodV{=?MNL=4molshiDVD0`k@ zXFK$}y-gS1d9!!TOCdYd;<^#8yP~NN?5OJu=I>{7QN-|FT)2d>t1Z=7>>{p9Sw=>t zZ@Ky1U8=)Ybn1W&ge#xecrSIW4EtDu$3^IjtaWbH3@H9hCpjUWm$?J4T6l&8R2O4iFsgQSy&l~J{QG3f=DW!5xms7P3q1D}lvLH)8Jc$!~DSb4aOMV;$@FLZnx-45*EZ{o}N z$QL2fkbKH%H<=@QcTbw!aDO52+U(AmG$vI7R#s5BXsx^#v!(VTR`E9P=ceE56LLx# zsh$rBaIUw-dR|zs1eR5^;92bz*f|m>rx|eM{N%q6aHDQ(TIxpG&m@SDj8>x31V8 zXTpK|8CNuyyJ@U(XKTA_chNQm44-?|xU*Wc7YI`dVc~d2mRxY!SY$D}T|CG@01{in9e>a489J!*U2 zzuV9|{7;@>@g{=Wp5n=gqY6|~b!ANzIcK|~J4e>ztd7QRtfA{tx+(%gZVM<3`jHg~^7!@vR|{xbGv5V$yE#_pr_CzYyu$(;$c9WzL(yJHF-nfte7gWBxw} z5yiojPXtbm{ol}g#Mp3hG1b%8Gd^1UJdh;@bEQBj#5&+nrO{9+08hCdx>ln|(X@43pPqgp)l5PF6|*6|}we4GojsF#m)hk7+n(*EP@7Q5h$Kl@_kp=r_nTwHIexkyP@ z<9I#Isfv;(fxLZwkUK_22f8x1lOSDw1`YZO?vJ;wdFb|W4mx6aAL#nsevwKfvo*GN z>IXB+M>o0#A~>CBRsEx39ecP0NWeJ>vC`O!znhw!6@?HlkEmDEyG|k}-|euJs-E)h zWYKbK|FI+l-LoM}!wu|08ZYYBwaM9vKEzs5(;A9|i4XSc{keDkgT6f(A}hOdoI9;s zw5Mw81MZw#xqUP3ML3(sjJl_`e5dBC753{AyWyKECh)vtT13ua0)oX8gR*_Mc( zPPH=i>4v0AS+EWe$2n-mSbNJGn(bBlerQ%{O2AqPS>Pu<2wh&C39MVuNM#DEfl=SK`>zu%3EP?V&WcL(%(Z3HUq?`~hA3KE6so!fhiidG5I&5nGs*1x z->XSk{?yneHqzF$!?eg;>G9s(zpsx9rCbmvUR4|dhB<%Mf8DENnhK2(ijen1yP!RvsPIt0ndXI)L*GJ z3+aqSm9*YhW=&vTzIk{TK>Fg&EWL;}Y*qCy-tA`St}0(q2?56Sg`4ULp%kyIHop7q zV+|l8wG?(v`uH@(G7|EbvUMLFV!5BQ z&5q3~&K552IqX@ha$dGxw3K(;nqU~OC}5a8ihmMri<|8p;qvq&&*zXq!zE$T8Glgw z**Eb(vub^v#isSZdXH?`tY(4fk>sObCf!fm5|O+hGTTqDfp9ltFO zYhYY5vQydOQ;)UJ9|cSRVTX*$CaEpv+}_V7ykInpqOEJ6TlKaaU^^`bMBOpl&nG-G z%uGCN`4x+1yff|7MsbWSM_Y~Tvh0)Xi$`Bhu)|yxJRBdD-D*pbi8 z!es(`#^`7~-AYX&HX<*sCjTNltJYD=F|a z_hoL!kJcGmPI*6a4X~wVYGNHOF&LEs7ff=(3pgb(<6SoTbb@h0gHdE+ZgTPmUcg6y z)TgbL_=kUP-F(UfqSZa>|MP#hw|DwiZ=aHLV?}aBF;a}hp{2bw(APT5M2ps!X>8+O zw&Nmdp2`t;(d%GQWJvDD#Ko)1E5We0d(mJzn_E6T=||$wzEbud;*b+;1TV51=S$&B z5lG=r5!B$bu+6i}v&nPlnHKu=NF7pv+rTE3VwFMvFaA&utR)zhxQ7H6Ti?7ZROLl>@CGX;j`emNF08mKl)7Se{g-X& zah6_)J}#HCg!lzk;);=EMJCo$FY}+p?Dp$aD%-Ku?0+qBFxO22)RwMlai>Zx1D)G(&JeJR5mIbag6u@)EU-Yuh zpS_$t_?(9hX>n@h1@fk-4x4R(IB~q7{$Fd_D%^j?vYj;ftcQnGYEDj-I=ak1fnL(a zGZpv~j@ZMQDQ5IkJ(^d+VleWbCFSDzj?!)cRu@WDL+>fM4-+e?C4ySe;vAEf*;j^2 zLueYPW_u%fOLyR}mbz$6L;X3k6?dX6m*N%}+if-5dr|Qe11B=$`s@w{dQP?|S?Dv}4x)dlk2gtGJQP`GKfl00MdZmsGK>&6bl91GqNrIf1n zr_(~UleSH%XkM!dUtL-^1UqO?$(4lLhuvIu-$Zs$e&r)GcxpsuRbj}?2W`^^kPS@Y z#x>}3XuqfQbC{{d5Nv&H8V+)~ zvJwsw;iv!W$9T!qd*>_R@9#aqrtE(9TEaX74OH#2>%&M*p~bIUhhhyw zspZ5Oxr+H?u!!N404j?2^AmzBR#e+d>6_WTMGQZjgZM`?b~w-j#soE_igvLpNMSPP!zAoB#SA!`1$hAgQVHG@;3{VHXAAOy$31%y;T?&XwMkI>FwH0d% zKfNOlA|n!=<>bveN|vsx(aGbK?ff5Tph`C=fO}NmsnvGSy8mRA_+!`WVXA13= z{Uz%n$CMRuIb%!*rEBD^5qJZ( z@HH%PydyId{P*q+!IN5) z)y)a!?0E?bfhll>5Emj3pkssp838)aiQmznn4aS>#J*;F37`QK0xSS=zz4{i=Z}6o z9n&2;stK?T;E|(dh&;hUQ~{KMsSFqN)XKYx*SPNp-qE2v0nY%egqn;6axYU(#1Qld zLIee*4e$xDLpaTpOn*o7IJHoOr~`6<12XTU_!3W85HB8KL@!7aA&9V%!CX04Ay@8w zBwxxKVw5YylW;)s8XrXm=pyuB3QaqChMkbs`?(fqZXN_GeuXrtKXLTIUQ> zP9JJz!pruIWy7ilMJntF+k{)Mzoi>a{gMkL*f1)&i&%k4j*_ssB0nASuQwjGPdd3m zt=m=&fyJb!IvKmb1XspzH7VUcEgWmEHK$`+^J1tX;3+MNmh|XlMDJDK@6tDa6uLOq ztWlOMUacYeQfE(BFIiY;K+1C~{HXBnCb&sQFNfg5VbK&{0uHrHx~KkV|83H1`dyVO zHidVwT)nCR+Y1cQ;r+gu@Ht(jVEZ|<)0_ljMoH-WSYYMRO!DMq!MAP<%%8khUQayC zKZlTOG$V@XOJmHyoTYIa>*U%cu$AQetx58+-e-1FqCrDA-mf$A&l$tTSD`?>JeVTY zPLSz`QDn-^JLLIM$(tt0_Sv}u?!{iG)y*tt7Ws^q9N(dg4^rH`g&mJM6j&?2Jy1oz z&q6;kyGdCT!7m1Mk@5y|0e|!Nj^q{lKL9Jbyhl!B=`T4*Am+x|CKV!O&>IRe>2S4*?ydXJk>O;KKEzHdL9USu~CD;z< zYIrB@vPvoKMz~<3T8)WvuGa}F(cTPP87eH)7p1ItoiBZrwy8Ua>&>yv6`=TCu16%I zHPKCQSHg3pZ9Sl$>BsHe{MzM2n)kilMov|<=ey#!i<8;SZXUi6gu%XkPmoQI1Ntf% z0lE6T!&iw5V{J6yFq&G2Bo~b6)S+H7y_9N7foRRobr1pP^9=cFO@N$4U4dfKiEU3TNYsd@QjJvi~l|x@QO}k4?fo+q|sG;S4<* zm2H9&f9tGP+~?!|wD=g=6i-v(;F#H;!^VR13`WZ@QH}71j)d&QDYp%qPQFp;a?19R zN7l5UWxT)cY3ne28~`_YY%u>7C`ISaRqOzWnZqQ%{4F}4gOSUdL_VicQ{_Kh$#JHG zK9irH!{-64bmVIMjHzilo}0aw@Kw`v=qAWJjAOSVQ9U=zxGq4HPz{PqHM_SPExF3B z@|CUj!R|n5S0M&|sbwjfmgVJ?2lMsXN_$IIN+w5~SEfpj(ZtNHTg+(D$Q^8L5X=fWM@|wM2XsXIQ><)>;zxRMd*ah;ayBA7yB$VS6ZQ~k=Nq374TZ4FM}6#&L7?doT;+In%EXF4ek#1 zYEkO_!*jM9f7lJ%uJ_76njSlEeN}o7k`Y^FwZGI9B3XQgjX$>!`%C*Q#>#j;T&Cae zqHgwhZmLVBTa^y`E@Q=$tPkorA^s_XYQ4{fJVwm3JFdsYWzM3pMPAECN z9=62-l6E|M&&(@$gANtW>_e2Nj+v@j+MiKE{WANex9~t(DrX?5l|YbgraSl-ygKtg zSVh%r<_|Wl&@sKtzM=BSF=Xa}&6x=FGV?A^_3fBoX5S|}Q7B&Kfpu%nSX<^@?AR+1 z6$^@y$JM4)H8TKy;Mi)CxhZf%1KnX3`?z(Ll7b{CD57+U-iXAx{|Ecu_~Q_y^XLWG z;s2X+es8~j1=u`#0s2d%A7>^2)XSn?37{M&qWS0Z%#|#QhAq#LK=zWF4)@#KppQuS z707er$>LW=5PyS+@8%rW`W0CgP~qc|dQbmSn8sDaJL%s@pQB#SSclT&kXHU>^gn!FGE;$KuFT80f7pI4#scL> zH2*)0|Mzd-08#w_Ehg~)WiS8Hw1)y_7$xIQBoR1|5Z`}I0cMy&(NIYME4gcd|JC}p z#1DZ~UK2B`y_1C|KM2+4pj!p8rd=nI3;(cclGlmWbq|0~fa`JC?m zy18#Dca4L1+^&f|xe~Zmrnu9Ko|CGy?+Fo(Z+DZb9jwKd@Nm*57UnLKfKu}ngon|~ zmfMWJk#L(3<`Qj?)tgxSF;d2Q0qo~~XD06+hpG93{|XIn{Leu$v7ord;$tdddmVI` zNwYG$f^#r73j>e0&dh95$XL*gS=afKJB^>4Yc;E2I-e~jfm8Ex$l^q>&qjT~*u<^l zJ(lN}58o_E-$7pX|47ETL|?hDoY0g48SnmYt*NzoX!MV8tX?7KP z_O3P@yLx^h*gSD`CsgRWa&Q@?+vKuIDIn^ylz_7x%;_M3&;4P3r9=RFIb!r{o|LDV zUx}qH|6FFkK4#o*u^7--l%dq9{ZuR`E4f~DMpZ|Qt-d2%f>c;38G=#B>o}YLn|Eu< z95g`xl=q(17zW%4HFpU4Qf%IGA=M)vq8c5xfiu@7=De2|kr7&0C1hbxImD?+_r8ep zB3ZZuiIGU*g$J2j<1%_0H1wSuJGt?M&1J;b^2D)kXY9CMRKCK;;-Lr8jic6Rk<3DT zh$y~r7~AN>^-MSzuTMQc)14;{slwI&9rVdwjI&NSKBUljD24wq7*5K1nBc4g zifvG}9k`nvZKad)@I!z4$JQwc?*#SO)N{XW4IK^4bCM9#ot2jF#0?p6@9MvAly@~} zQr_zsUk-*>*r4Ev7DUmv@rSvM8Tf^}xU#!y=bw6P;fvb6FJGv{7sS8N7uY{@NOW|P zBzp2r<$sWN)$)$cP~6>G+}+*X-JRf2+=>);4Fq?0cPUOGNYUc%?ogzheBWB< z%wB7sz2}_SnMvlIN%B|TJlFl)&;7fuwosr?1rM(NpOGUYw=V96itGD?9E8`?u6*nw z_PD6fdj!g;Gu&`hOopS+?y7#@ro!bKc=ik_nGcp>*34|gJq2>du;o-Xs*{w9glI6%_1PMJ1eyd{mmgGSyjqGsvXCVI6n%JRHLcByd<7D4`CvATF62leV`LPGuJEONw;0A9Z@=uZf`Ic`;C?qeu=cklK&y)xa@pTJYTM2W-&m zZ$DIL*VpOmv=Tj9!80Eafsz|Yfz3M6{&`BD?*-<9Ebpw z>~SIsu0jf8j5_Anynr?0FAyqPN;RLLlx7wa-1m|ZRw)I3AkH&;4ShTmrDk$alw(Ji zHk>=mZ`9C=c^+!*+Fb-pN@?EoW-tKZT4RKsiDFEao93v$NCRddO9SutIz;0~KRjhd zKg&Qr;?TlO$>!kR)Z})ac_00AnN7@?V4l$$*@uZ21roa*ySfS1nd|OsNBuu@C9NP| zIV%J9X`JG$JG%N;eEJ-gJp80vVXU{c4+P(Tl=~%1WtROaV_xDyT;_QF*_+>@(SJ5q z(uXWT{uahol9+0HVH}bfCn<+R>cXJ*z2aiA;weeU7Mlj3B9$irWl@(QQvQAqi4HEA zR%J9V>K&cRL|&MPLzz0bC{DIaW2z`nwru`~1u}3xii1@bTx5{w4jD5nSFwNwW~OV< zH6)HwQE5i4CIQQ}b{AMqmkA_404=GSqgFw)73vo35D4KIyFGi9Sb+em9Vm+kl#*;= zTN<{AC0lU?Wn#5Qk3yyv>1Hy>Pq1vvA#j3^qzBv5kVP=r1511A=tR`&2t?vzqgJPO zH5DM7pe@yzf}`p#6xG+X)ruc>X{P`(2xSQT#cHEv@d@~<;HX{{3_%hyvAqR>N>ut- z-U+g}z!hxXAG@Sfo;266RH{^-bS@FH+&~-%m;jlP)J)`NI|4K)qBGq-`BOnY*}qEz z?8Nd;8_i5xt^UDE^~G|g;)gTU7t@)NANuKCv7;!GB&OFMRQ%Y}=}0U~#WFFnS)+nc zcnYxTtCc^{fTmOrv}SC)eHN``)aevYPbE>4--zcdck5ZNjsJ4Y8%5#cAb~Un68@)+ z0UzsslpKBwHojPUe~lj)CJD4Fi>dTR7QDB8@74UR35`IUP(0%UmW>^CC(y#g(<(b# zF$hGkE7M;-|4xhn9;=*)v_K?gY4N%4!Ea??{Cpp{@l^l4XX=!_QM&xu)bij>=;9{F zwd*Z+)aG3o6g%qspFrqt-a5=J-H-#co}fC!txC8l@>|kVDK98f)PAE7Ke%V~Cv;de zSag)nL=rq9PIy~z{i-3j=n(xT=m*2qenuiC66c9?dcUO^0)#6?3qv;&f8^`82|*80 z4Pl3~g3Jjzp=`N_+`w%}ctQW4Zon{F&F2{Mu1F{BEyj>m^uIa*kS;*rB}zXyD{||d0Qr~Zvo*@CBUof|fc`r>-#@jxB zjU`ZtZDw*}*6kRAaXsd!-45E8;>_a+eLag>r)qr;+4ZE8%EnIXS4xhckty`Y9B1cwUIR~_Q-Y!*2g zTq6(C(oa@XSrPGyBV^|6m_Ut#!g6tTbS9QB2C>Hc*7u6K0D2F<#fP9nd%ZE(iCPs@ z5_cClLmXKfUCP8+rZ$^}-yRDpZQY_T4w^AshKTyE-HSv#fF6F@NV2%3f|1(HS72jp z*VFWzY~s3{s%hyZxCce?fqs30F_uXOjX0gHG%jlKF@>H(TU^g2SE7!V>X(+#d>B`FQBgo}# zH16wb|3byS#&BZR*xs9=G+n#cdnZu^?6sNFy>rSl#3B4q=rx2C&2!WI=kc(tEUS!m zDOm1Hx$4aijtk@~aBU_tFEFmU(5+<3ulY%Cjq9r1BCg$h*pPy|9 zyR%1u@Hb-I@e9Q)kHcnz6(nwK`!0ASI%+#T7B7QcdGb4gnl-Ot--uv{r!^(Pg#+?4JXG=2a z?ZSicwTs9#DiVmcPBLAc=5%|JE#(;BQStB#b&t@E%7fsr&qkO~JMvh{g{rC1ne=4C z^p9K0SlUS%v?-h+vB9!x?nAZi(O+pgL*I&$-K~Xc3!=Le<>ED_a3x2tzn$V@?{nyu zCW8b_>vhig_;9E>X~L1vQ|GgIN_VfU`?444W0WWjZGZf{&E~wtas=^9S~CfD73bZ3 z?`PTv>}yL75%je5Qv|zJH_vnC=EK@8fOCjX1j3q0U96~3#uaWS;*8|stuau4B!3I` z5NRj=Syc%|O~%jn*x;>G6`-kC?}Z-{tc0T~eC1g0I4_|Sy*+DDORNSVe0Y591^hjX z1u$ffkYazu(fTU@ktTeoudtHGNa8UNiet;$bhSG)8Hth>!jT6$)_CMr1q2(;IntG( zUvu-q28)(OC4J8ZQ=AQ!DX?_3mBzc~(wfp~iUG+CE(Ks-K0h%8%v7ah!MQp3(N>RO zVpSW|*>y#aMS=QRo9(2jvT@O`7`c-A8pR{ai!bREODc*RoZZd0Qf2cg33q{56^gH1 z7+<7LR;caEdX}YFtr&?~gorMmu*zV+KOPouFm4to(>VJ|88Bj5rSe!Yc0$!~L*V4Y z?KFoiHfN;3L^$_1LKm5}Pssupf%+{Sjbxka$4r^C9qvlHT9rI(7MQzmKg>je44{^f zyg&SY?}CQ_hXC_g99^{j8%C!Ryew^`VR=kZ)?kgMC|fE;YH^YUi7bgc_NZ@?FGye3 zk(|~h) zpf8(4R&Kf^bq$lG2Vze0jkMqe&r%pu>GqKUn}AgoR|#ISBqpjdd@>{!M-)e7-Vu_N zOG?))U=$2vyA!Wr_B<^jNE5E``TJi|U%9(O4}x?TME|FghOT!1ka`Emq#>a+#2m1c zFD@6zBeXNSv`LLka5<%Rq&)BrkUF7RK?1#~35kRYvy3kfgW{!aAu;7g+r$SC5cEoit; z5)e;;aCD)dOVyBgQeUDiOb9nXL+*?4xBDN20sJRB;QY6z0K`#18@(sy5<7$%Ek^?4 zD4-5$TKFPwoxn|fhRhmf!pXyJh&^)kv-KnNd!qG3UkZj?kW0W-!r8$Ii#(F{$D{ej zTr&KFBVZ57C4YIpl?wM=?2)to3z~oQC4a~U`3uxmJY0a-BYVFw+MlRP?vU@~FVI`L zjF+`IkDdrzpCF@#JUKxn&>u_H>TD!** z@_lhtZU{X{u=@gglQH4=BV1Ei6rX^IjvABloec*Vb^8;WBH842xGd0Aw*k?IZAy-A9BNoLroUW0H`qH7E`Iva)ZU2>S@gfFI2 zejgq+W80L)FgH}tEY#pZah?z_7`Mr4;-yF)6`7#MSBKHz2h!o8aN`H2EhU^gZ>e?{ zo4kcIoX$&X-nur?9^1?@lBySMrnJq!hg*xuQ)4T})|O9GKR+&Tvm4<4K&V;rbFU$< z>yN3q&;^n!Cjr^zsX`OhpsH1|Du;E8&B!Fo%q4Ff>EkmEw#gSp|4B{P^WHogF&16K47eJ^XdNDs~mi9md&# zk{yK{LfL{-#exJwekoj3`xq02=z{B0k*CqDQVbbO5;;pF&vu~CZDDcDwOApa^|vI& zrLu`-yt-CCd2v|&n}RyiT6-TuD@jt_=^hJ7iz}lwWctFh>&4;2vlId4*7hjH_J~6Fu0?syzZYQu#NwhVB165-{uLiU#k`)xuC`kg?yx2ym z=WmcBDipaC)@&<>BX~WVK44GfOK(YI8{d@z$Uio6$;_s@ORGha(R#gwZh}#r(s-|c zEqkK51j~f)vS_cNb$(UV^;QNix`t_2!a<~pXt){3;?PV_$&lfA(`Kb_2D(IUZ;}SKu^w+oiA}~x$y`mdKtkA(7LppljJQH>pHr|mOd9SA* zsAPu1HN?I!VO1d($@TJ$PC~mo;a6JotB7|olu*&g5YoY)qOp+?dB|aJVFTFiSoZ12 z<>wTz$J}wxsALC>B1Vm`%15%nFb03x-wSWLf6g7;=EFBkJ8#KFr;ljHrN?FyM=UE` zF~Pf~E30kbr@)hJc07~qmOs}aI+O1`gI*c!Ryo%^15Lp|Vc0QZi&|`9bM9}`;5*dcFt z?@=?-QRH4Dua{-k^S;B=Z&+_9#(89!YT=8IA#HJG@m%IR_w>@uaIFC}}ZH36dq>{R}d2+%9|M8y^ghmO=@zg#G8 zgT-qnUp$G69t~rJ5O3{J{YnozfB$4p@Jae3+c$9A&O1DCdlYDV)B&F#+I;k#_>XW=y^1rn%c~|m^V*(Fn$F(csALw z>OAT4HJw(*9nZO7f+rXZ^&CyxQ;PM$e~!lm^-$`FESB>3RNVKC7{eiRgAg#_zT$L- zt(Wb`Oer8@4-R~%7uT@b=MoI!*F86b&;gF1uR8bE?Wudb4BWQ(mhJI?T97%z6o3^1 z7I>4$e+L~ju1+;5gW(}8LnZ_%@P-0U=qc4hFasRMQr*eA)rvhy2GqLKUu6Y#CU?h3ao+G1&d+398I$*STR+%FULHrhf z@T2Twz+csXBuSc3JER&&|DRR^PWJz(22vo^fQB}t8n_`yB6?3sPuiqHQrskB^FG;; zwjdsA*KJpV2Clq3Suw>QF}^=FR+0Wq?91~hjYMR=L`bzbs;K} z|GOf<48i@2Ec}0~2wFWJzw*Bfd~5NGgKQv?t(RI}L!jtU=paC0imNX#$yaZDg~%@X z23swuk13yIg%ObP7F%9#k5;>M&<1KQt-|B?4vMkYtVBkNqM+qTTzE>uG5TdxhJz(N zBMP;H5p$sY-Z)!3mymS$sn^VC3iH+SUX~(xF8CG_S+AX?wS2ea+1YQ#YZ_s1xdxSa z(Ur~J$h`g>b+MRd$d4xWkdK!U4b8jOA0bY%3y!GsPaFemeEPHEk1};JM2jkLQ%P8- zPKEd-)Ey6h*IiRg?exwYPEjhpNl%?L<_z!zr1dC`S<|UFtKAV7&b!Lv+BaHA1=8rm zaTF#Y(2a^n0&r7GtFGbVC5Z2=h`sx>RRgKdj&^vVxioU!i}4$NW@ySj0)PZHV=lh( zFiZqHzNX9uGy?i3J`1vFdILNo3JZ$^Z6ul4il??D&i&(en z26gXRl`}9`AH0Ora)^&+X#QfPROD#c);a zdlPmX6TH)DNQ}^2dqmN36}oic(=(w3DUHk8kJS=$K;%kvv_@!H~uTJ|h@9G6dl=N4WK;oKtpg5msC>=kt1g^Dgq{FJt zN;%l3IR35c#}D2}8`I`)3!V~-a}c}ah9QBJg7d)Jx%btT?tC$o2ZR}x$#&pxIIKBZ zLa)swB%6rw>?4xJb3AF-(xX0P8~M{6$HJUCw z(FkT>x+&LCP%4p^pET=!CYJMQThz6G;F$S`b;7$&k`^$3x*K(r*Lj)Dv4EI4U*tj&emFhRvLN5;LW`9ZsWJb?VAB+n`X4@Fyk1mu8gLNbKH-xML)pwDX-t| z1=a3Pyzn*ijK?Q#iG+=Q)#d4WNr_oUPSUR7aar9WVti~vA&m7~NvXr%Kf=y@tAP&Q zSUsFAH6}dzF8ZeLDF8jJemnF|GS>lqT|QURiw4;+@aN?6b?y1rnqK!(J-u2Ha5-ol z8(6A!+oCj68pajo5u}Cuqb?~=QT*coU62QIB|aa#$^bzaQ_wj>X=ZUarTj7A$b7Wn zNq3>4YL2b9A+A^){2A;6($uT5Y7Yc7gOC{rb@`fCAuj%f0Lm zr)hP(A*EOw%-EbJ#Mo*Hb9Vl#Ar`<7)??(i)rHoB2>xh;68MZ0e~xXCZM?w<%mi9v z_+_^=;PMfStasnAI@%x#He~Q@w4ZZ91$X}?`KA!b2ZH<bpkDQ~X} z5TpuW6ZM;7>bsKnEE&UfjD{OD!KM%nvDF%a2);73+K$!}0hUStS$lY34@OLeS`$d= z!2`h(9rQ|cN_0JJdHY{TGS&jn8NN2{ z+TFB^|3w*|&XYkd)xiqY1fDkO)f1PFjIIomySqR|&(POfdI zK2?&=#C8ijv?R10>;n8zT+=g3U>qEKbIqraepLPb6EH>TJJOrEyEUiGIyKv@h(Mmk zxMEM+v*^H+h`JTK_UnNKspy0Xcm5=n6(_&;jesxUb$!#XF#<2qECfrYjU&7Q*^ZSQ z#CBs&gRKHv{95d%?LC;mG|doi5k_V4R6;hV@B~*2FO^zvGPvU@_~_!;4fhc0Vz{Se zp~N#p?6-)rD0x=B(2cj!tf$P(HUC;h;|^QvP{a9a`dY#d1rN?_O^U_irm)({>C_C; zVYkuMRF(anyhNFMc{u}=446^q?!Ka8{u!8&DP;8>!e}`w?M~l;`k%XgUpy0$zW%(c zB1R_)x2^Otp}8ipx{F)ibX2%c{hcfl=d4C<#t;5MU=Dwu?gD`0`xV98QX=(YvO?v$ma+0RZ1$ z>A_{vQ3>d=Qe2}rCdIU7&!x+l&|iWalAQKav5X42X>VKBCCR?C)9UNJ{jwQ&;u}H) z?uTVDXh~;LtmU8;;^;h{ex&a&TYKSg2z={KQrXk^($YIOXG;^sx@^@bjqDr0dmg%4 zFT9x#)>{AEoM}TfZ8zZ()@zEcMswYc9zI-p2ji|>)?ZIX#?#}`e1fg_0|`)o2<1oE zs*$;A7xPU@O;#x_ZzA~h>Xm>ny7N#7`ZGhOR2jaRQ zLW@_TgdEXum&`yyqH3LXAZ=PhkcD^RKoPFuB6ZONJ#~KJK_ikYP5y;lzy-IWI7XJ? za2ZoRQ;y8ZYx`WCBZ}>StlC_RP0ZnveXe8NjTc}@%)^*Wkfd3`FdoI_sMPE0EXD`CUBF}(Yz0$|5) zs^%ZEVuw!`Zo|bPup5q->LO!j<7UOKHn-Qau3=f<%D^!oIIt807}r*-ww(p?xA96e z1tLo|h(>1FdJ48Hy`+YJY3yFvOLi7tv=$gjv6bt>lXq(hf6gD~!io8S$to4DoPWuS zZ9Hy}8?6AvuPxn?Yo@>398-Rt zvboq)CTDbG5KP`zhIgJR+=ir}!7Qs%j!Z47CO-Gud-jhnx7e^WxqWrAF5K-Xl5^0S zJ(B%`z!dhl`7Gx%9GgCLR(vZm;ke=d*1E03`}e$|uPYka zKU=#N(lvFAc@tI@s&&&bJ*G8RyWonQ<0_!Wm6_}chc_U0vR|RpaJ)3daCFR5>I6RUg z09@3wikY!6`^g-67;qG-Co(Ev|J`tZn(r3 zbWZOotS(z9Fs-%-BdYr@FV_uIy0?z%pj>Xe4>`3Z@sSAeFGZ)TT}kSftoI9>g0AEQSv%D;Iv1))Wj`xZH6$sxQXM$g4c!Y;eO!fVkKlBOGWLFdQeu#_vFAw= z&L1y+6LQ_QUaMfPNg<+Q>qkN=j#pDxEbR2bPKN#rI%p@DlHAUIY#Bz3LqReY>LHWe za~D1B&K!NVK7B(fs_cRDGR$==YuKlTPnC!~YG=@mTXi)U_D>)jnIr{rNCIh+E*bBr z!jg2>ml3T$!Vm}B$dk3f8xk_UQ24lzuTG!ZKYcz3<_QUR!liC~=4})l7d>N%n_1_` z*;2U^$myqb=^oQP{_2JEWsCPE0eVK+`wtB8h&WE_`+%%eXrm$T&^aKA_xC9#R8($X z2XU!$KC_O9xhwjo?ZR)-66c&NqOSIng+1--VO_as2EJG%x#6VM>3UT2+?c=}_KR^* zXB%3WNwg^KN9H5W9Ajzro_O#TG-!xW0rU&Kw2*`~5rj!C7T%TYGvpar_d*qMUwp-) z>6sM>{8Jszd!$6OZ~KUnVdf}JxU-0V4{p(R<1f)*5-T76);}cuivUJ`ut%l$EESsR zssdml2YPWCxJv)^{+vvY*g=k@j|D#&8Ac-d(P

    vJ2`5VoUzkNsl^*vQj(UUjrSKTg!P;hD87TmG& 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 Uc6afLcZhe0%)w%3BRX66Kj~cG8UO$Q literal 0 HcmV?d00001 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..9b2cfd7 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'freerouting' + diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteControl.java b/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteControl.java index d9f9611..527b08e 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteControl.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteControl.java @@ -17,17 +17,17 @@ * * Created on 25. Januar 2004, 09:38 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; -import rules.ViaInfo; -import rules.ViaRule; +import eu.mihosoft.freerouting.rules.ViaInfo; +import eu.mihosoft.freerouting.rules.ViaRule; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.RoutingBoard; /** - * Structure for controlling the autoroute algorithm. + * Structure for controlling the eu.mihosoft.freerouting.autoroute algorithm. * * @author Alfons Wirtz */ @@ -35,21 +35,21 @@ public class AutorouteControl { /** Creates a new instance of AutorouteControl for the input net */ - public AutorouteControl(RoutingBoard p_board, int p_net_no, interactive.Settings p_settings) + public AutorouteControl(RoutingBoard p_board, int p_net_no, eu.mihosoft.freerouting.interactive.Settings p_settings) { this(p_board, p_settings, p_settings.autoroute_settings.get_trace_cost_arr()); init_net(p_net_no, p_board, p_settings.autoroute_settings.get_via_costs()); } /** Creates a new instance of AutorouteControl for the input net */ - public AutorouteControl(RoutingBoard p_board, int p_net_no, interactive.Settings p_settings, int p_via_costs, ExpansionCostFactor[] p_trace_cost_arr) + public AutorouteControl(RoutingBoard p_board, int p_net_no, eu.mihosoft.freerouting.interactive.Settings p_settings, int p_via_costs, ExpansionCostFactor[] p_trace_cost_arr) { this(p_board, p_settings, p_trace_cost_arr); init_net(p_net_no, p_board, p_via_costs); } /** Creates a new instance of AutorouteControl */ - private AutorouteControl(RoutingBoard p_board, interactive.Settings p_settings, + private AutorouteControl(RoutingBoard p_board, eu.mihosoft.freerouting.interactive.Settings p_settings, ExpansionCostFactor[] p_trace_costs_arr) { layer_count = p_board.get_layer_count(); @@ -93,8 +93,8 @@ public class AutorouteControl private void init_net(int p_net_no, RoutingBoard p_board, int p_via_costs) { net_no = p_net_no; - rules.Net curr_net = p_board.rules.nets.get(p_net_no); - rules.NetClass curr_net_class; + eu.mihosoft.freerouting.rules.Net curr_net = p_board.rules.nets.get(p_net_no); + eu.mihosoft.freerouting.rules.NetClass curr_net_class; if (curr_net != null) { curr_net_class = curr_net.get_class(); @@ -139,7 +139,7 @@ public class AutorouteControl { this.attach_smd_allowed = true; } - library.Padstack curr_via_padstack = curr_via.get_padstack(); + eu.mihosoft.freerouting.library.Padstack curr_via_padstack = curr_via.get_padstack(); int from_layer = curr_via_padstack.from_layer(); int to_layer = curr_via_padstack.to_layer(); for (int j = from_layer; j <= to_layer; ++j) @@ -173,18 +173,18 @@ public class AutorouteControl public final ExpansionCostFactor[] trace_costs; /** Defines for each layer, if it may used for routing. */ final boolean[] layer_active; - /** The currently used net number in the autoroute algorithm */ + /** The currently used net number in the eu.mihosoft.freerouting.autoroute algorithm */ int net_no; - /** The currently used trace half widths in the autoroute algorithm on each layer */ + /** The currently used trace half widths in the eu.mihosoft.freerouting.autoroute algorithm on each layer */ final int[] trace_half_width; /** - * The currently used compensated trace half widths in the autoroute algorithm on each layer. + * The currently used compensated trace half widths in the eu.mihosoft.freerouting.autoroute algorithm on each layer. * Equal to trace_half_width if no clearance compensation is used. */ final int[] compensated_trace_half_width; - /** The currently used clearance class for traces in the autoroute algorithm */ + /** The currently used clearance class for traces in the eu.mihosoft.freerouting.autoroute algorithm */ public int trace_clearance_class_no; - /** The currently used clearance class for vias in the autoroute algorithm */ + /** The currently used clearance class for vias in the eu.mihosoft.freerouting.autoroute algorithm */ int via_clearance_class; /** The possible (partial) vias, which can be used by the autorouter */ ViaRule via_rule; @@ -220,14 +220,14 @@ public class AutorouteControl public int ripup_costs; public int ripup_pass_no; public final boolean with_neckdown; - /** If true, the autoroute algorithm completes after the first drill */ + /** If true, the eu.mihosoft.freerouting.autoroute algorithm completes after the first drill */ public boolean is_fanout; /** * Normally true, if the autorouter contains no fanout pass */ public boolean remove_unconnected_vias; - /** horizontal and vertical costs for traces on a board layer */ + /** horizontal and vertical costs for traces on a eu.mihosoft.freerouting.board layer */ public static class ExpansionCostFactor { @@ -236,9 +236,9 @@ public class AutorouteControl horizontal = p_horizontal; vertical = p_vertical; } - /** The horizontal expansion cost factor on a layer of the board */ + /** The horizontal expansion cost factor on a layer of the eu.mihosoft.freerouting.board */ public final double horizontal; - /** The verical expansion cost factor on a layer of the board */ + /** The verical expansion cost factor on a layer of the eu.mihosoft.freerouting.board */ public final double vertical; } diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteEngine.java b/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteEngine.java index 7b305ad..28d441b 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteEngine.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/AutorouteEngine.java @@ -17,11 +17,11 @@ * * Created on 11. Januar 2004, 11:14 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.Line; -import geometry.planar.Simplex; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; @@ -31,19 +31,19 @@ import java.util.TreeSet; import java.util.Set; import java.util.SortedSet; -import datastructures.Stoppable; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import board.SearchTreeObject; -import board.Item; -import board.RoutingBoard; -import board.ShapeSearchTree; -import board.ShapeSearchTree90Degree; -import board.ShapeSearchTree45Degree; -import board.TestLevel; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.ShapeSearchTree90Degree; +import eu.mihosoft.freerouting.board.ShapeSearchTree45Degree; +import eu.mihosoft.freerouting.board.TestLevel; /** - * Temporary autoroute data stored on the RoutingBoard. + * Temporary eu.mihosoft.freerouting.autoroute data stored on the RoutingBoard. * * @author Alfons Wirtz */ @@ -186,7 +186,7 @@ public class AutorouteEngine changed_nets.add(curr_ripped_item.get_net_no(i)); } } - // let the observers know the changes in the board database. + // let the observers know the changes in the eu.mihosoft.freerouting.board database. boolean observers_activated = !this.board.observers_active(); if (observers_activated) { @@ -261,7 +261,7 @@ public class AutorouteEngine /** * Draws the shapes of the expansion rooms created so far. */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { if (complete_expansion_rooms == null) { @@ -640,7 +640,7 @@ public class AutorouteEngine } /** * The current search tree used in autorouting. - * It depends on the trac clearance class used in the autoroute algorithm. + * It depends on the trac clearance class used in the eu.mihosoft.freerouting.autoroute algorithm. */ public final ShapeSearchTree autoroute_search_tree; /** If maintain_database, the autorouter database is maintained after a connection is @@ -649,7 +649,7 @@ public class AutorouteEngine public final boolean maintain_database; static final int TRACE_WIDTH_TOLERANCE = 2; /** - * The net number used for routing in this autoroute algorithm. + * The net number used for routing in this eu.mihosoft.freerouting.autoroute algorithm. */ private int net_no; /** @@ -664,11 +664,11 @@ public class AutorouteEngine * To stop the expansion algorithm after a time limit is exceeded. */ private TimeLimit time_limit; - /** The PCB-board of this autoroute algorithm. */ + /** The PCB-eu.mihosoft.freerouting.board of this eu.mihosoft.freerouting.autoroute algorithm. */ final RoutingBoard board; - /** The list of incomplete expansion rooms on the routing board */ + /** The list of incomplete expansion rooms on the routing eu.mihosoft.freerouting.board */ private List incomplete_expansion_rooms = null; - /** The list of complete expansion rooms on the routing board */ + /** The list of complete expansion rooms on the routing eu.mihosoft.freerouting.board */ private List complete_expansion_rooms = null; /** The count of expansion rooms created so far */ private int expansion_room_instance_count = 0; diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchAutorouter.java b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchAutorouter.java index 1631659..de611f7 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchAutorouter.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchAutorouter.java @@ -13,7 +13,7 @@ * GNU General Public License at * for more details. */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Iterator; import java.util.Collection; @@ -21,22 +21,22 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.TimeLimit; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; -import board.Connectable; -import board.Item; -import board.DrillItem; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.RoutingBoard; -import interactive.BoardHandling; -import interactive.InteractiveActionThread; +import eu.mihosoft.freerouting.interactive.BoardHandling; +import eu.mihosoft.freerouting.interactive.InteractiveActionThread; /** - * Handles the sequencing of the batch autoroute passes. + * Handles the sequencing of the batch eu.mihosoft.freerouting.autoroute passes. * * @author Alfons Wirtz */ @@ -44,10 +44,10 @@ public class BatchAutorouter { /** - * Autoroutes ripup passes until the board is completed or the autorouter is stopped by the user, + * Autoroutes ripup passes until the eu.mihosoft.freerouting.board is completed or the autorouter is stopped by the user, * or if p_max_pass_count is exceeded. Is currently used in the optimize via batch pass. - * Returns the number of oasses to complete the board or p_max_pass_count + 1, - * if the board is not completed. + * Returns the number of oasses to complete the eu.mihosoft.freerouting.board or p_max_pass_count + 1, + * if the eu.mihosoft.freerouting.board is not completed. */ public static int autoroute_passes_for_optimizing_item(InteractiveActionThread p_thread, int p_max_pass_count, int p_ripup_costs, boolean p_with_prefered_directions) @@ -106,13 +106,13 @@ public class BatchAutorouter } /** - * Autoroutes ripup passes until the board is completed or the autorouter is stopped by the user. - * Returns true if the board is completed. + * Autoroutes ripup passes until the eu.mihosoft.freerouting.board is completed or the autorouter is stopped by the user. + * Returns true if the eu.mihosoft.freerouting.board is completed. */ public boolean autoroute_passes() { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", hdlg.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", hdlg.get_locale()); boolean still_unrouted_items = true; while (still_unrouted_items && !this.is_interrupted) { @@ -131,15 +131,15 @@ public class BatchAutorouter } if (!(this.remove_unconnected_vias || still_unrouted_items || this.is_interrupted)) { - // clean up the route if the board is completed and if fanout is used. + // clean up the route if the eu.mihosoft.freerouting.board is completed and if fanout is used. remove_tails(Item.StopConnectionOption.NONE); } return !this.is_interrupted; } /** - * Autoroutes one ripup pass of all items of the board. - * Returns false, if the board is already completely routed. + * Autoroutes one ripup pass of all items of the eu.mihosoft.freerouting.board. + * Returns false, if the eu.mihosoft.freerouting.board is already completely routed. */ private boolean autoroute_pass(int p_pass_no, boolean p_with_screen_message) { @@ -228,7 +228,7 @@ public class BatchAutorouter } } } - if (routing_board.get_test_level() != board.TestLevel.ALL_DEBUGGING_OUTPUT) + if (routing_board.get_test_level() != eu.mihosoft.freerouting.board.TestLevel.ALL_DEBUGGING_OUTPUT) { Item.StopConnectionOption stop_connection_option; if (this.remove_unconnected_vias) @@ -263,7 +263,7 @@ public class BatchAutorouter try { boolean contains_plane = false; - rules.Net route_net = routing_board.rules.nets.get(p_route_net_no); + eu.mihosoft.freerouting.rules.Net route_net = routing_board.rules.nets.get(p_route_net_no); if (route_net != null) { contains_plane = route_net.contains_plane(); @@ -296,7 +296,7 @@ public class BatchAutorouter { for (Item curr_item : connected_set) { - if (curr_item instanceof board.ConductionArea) + if (curr_item instanceof eu.mihosoft.freerouting.board.ConductionArea) { return true; // already connected to plane @@ -326,7 +326,7 @@ public class BatchAutorouter { routing_board.opt_changed_area(new int[0], null, this.hdlg.get_settings().get_trace_pull_tight_accuracy(), autoroute_control.trace_costs, this.thread, TIME_LIMIT_TO_PREVENT_ENDLESS_LOOP); } - // tests.Validate.check("Autoroute ", hdlg.get_routing_board()); + // eu.mihosoft.freerouting.tests.Validate.check("Autoroute ", hdlg.get_routing_board()); boolean result = autoroute_result == AutorouteEngine.AutorouteResult.ROUTED || autoroute_result == AutorouteEngine.AutorouteResult.ALREADY_CONNECTED; return result; } catch (Exception e) diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchFanout.java b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchFanout.java index d888247..1586de3 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchFanout.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchFanout.java @@ -13,18 +13,18 @@ * GNU General Public License at * for more details. */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.SortedSet; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.RoutingBoard; -import interactive.InteractiveActionThread; +import eu.mihosoft.freerouting.interactive.InteractiveActionThread; /** * Handles the sequencing of the fanout inside the batch autorouter. @@ -52,11 +52,11 @@ public class BatchFanout { this.thread = p_thread; this.routing_board = p_thread.hdlg.get_routing_board(); - Collection board_smd_pin_list = routing_board.get_smd_pins(); + Collection board_smd_pin_list = routing_board.get_smd_pins(); this.sorted_components = new java.util.TreeSet(); for (int i = 1; i <= routing_board.components.count(); ++i) { - board.Component curr_board_component = routing_board.components.get(i); + eu.mihosoft.freerouting.board.Component curr_board_component = routing_board.components.get(i); Component curr_component = new Component(curr_board_component, board_smd_pin_list); if (curr_component.smd_pin_count > 0) { @@ -109,7 +109,7 @@ public class BatchFanout } --components_to_go; } - if (this.routing_board.get_test_level() != board.TestLevel.RELEASE_VERSION) + if (this.routing_board.get_test_level() != eu.mihosoft.freerouting.board.TestLevel.RELEASE_VERSION) { System.out.println("fanout pass: " + (p_pass_no + 1) + ", routed: " + routed_count + ", not routed: " + not_routed_count + ", errors: " + insert_error_count); @@ -123,14 +123,14 @@ public class BatchFanout private static class Component implements Comparable { - Component(board.Component p_board_component, Collection p_board_smd_pin_list) + Component(eu.mihosoft.freerouting.board.Component p_board_component, Collection p_board_smd_pin_list) { this.board_component = p_board_component; // calcoulate the center of gravity of all SMD pins of this component. - Collection curr_pin_list = new java.util.LinkedList(); + Collection curr_pin_list = new java.util.LinkedList(); int cmp_no = p_board_component.no; - for (board.Pin curr_board_pin : p_board_smd_pin_list) + for (eu.mihosoft.freerouting.board.Pin curr_board_pin : p_board_smd_pin_list) { if (curr_board_pin.get_component_no() == cmp_no) { @@ -139,7 +139,7 @@ public class BatchFanout } double x = 0; double y = 0; - for (board.Pin curr_pin : curr_pin_list) + for (eu.mihosoft.freerouting.board.Pin curr_pin : curr_pin_list) { FloatPoint curr_point = curr_pin.get_center().to_float(); x += curr_point.x; @@ -153,7 +153,7 @@ public class BatchFanout // calculate the sorted SMD pins of this component this.smd_pins = new java.util.TreeSet(); - for (board.Pin curr_board_pin : curr_pin_list) + for (eu.mihosoft.freerouting.board.Pin curr_board_pin : curr_pin_list) { this.smd_pins.add(new Pin(curr_board_pin)); } @@ -181,7 +181,7 @@ public class BatchFanout } return result; } - final board.Component board_component; + final eu.mihosoft.freerouting.board.Component board_component; final int smd_pin_count; final SortedSet smd_pins; /** The center of gravity of all SMD pins of this component. */ @@ -190,7 +190,7 @@ public class BatchFanout class Pin implements Comparable { - Pin(board.Pin p_board_pin) + Pin(eu.mihosoft.freerouting.board.Pin p_board_pin) { this.board_pin = p_board_pin; FloatPoint pin_location = p_board_pin.get_center().to_float(); @@ -215,7 +215,7 @@ public class BatchFanout } return result; } - final board.Pin board_pin; + final eu.mihosoft.freerouting.board.Pin board_pin; final double distance_to_component_center; } } diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchOptRoute.java b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchOptRoute.java index f9aff74..b90de61 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/BatchOptRoute.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/BatchOptRoute.java @@ -13,27 +13,27 @@ * GNU General Public License at * for more details. */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Iterator; import java.util.Collection; import java.util.Set; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import board.Item; -import board.Via; -import board.Trace; -import board.RoutingBoard; -import board.FixedState; -import board.TestLevel; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.FixedState; +import eu.mihosoft.freerouting.board.TestLevel; -import interactive.InteractiveActionThread; +import eu.mihosoft.freerouting.interactive.InteractiveActionThread; /** - * To optimize the vias and traces after the batch autorouter has completed the board. + * To optimize the vias and traces after the batch autorouter has completed the eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ @@ -41,7 +41,7 @@ public class BatchOptRoute { /** - * To optimize the route on the board after the autoroute task is finished. + * To optimize the route on the eu.mihosoft.freerouting.board after the eu.mihosoft.freerouting.autoroute task is finished. */ public BatchOptRoute(InteractiveActionThread p_thread) { @@ -51,7 +51,7 @@ public class BatchOptRoute } /** - * Optimize the route on the board. + * Optimize the route on the eu.mihosoft.freerouting.board. */ public void optimize_board() { @@ -72,7 +72,7 @@ public class BatchOptRoute } /** - * Pass to reduce the number of vias an to shorten the trace lengthon a completely routed board. + * Pass to reduce the number of vias an to shorten the trace lengthon a completely routed eu.mihosoft.freerouting.board. * Returns true, if the route was improved. */ private boolean opt_route_pass(int p_pass_no, boolean p_with_prefered_directions) @@ -114,7 +114,7 @@ public class BatchOptRoute private boolean opt_route_item(Item p_item, int p_pass_no, boolean p_with_prefered_directions) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", this.thread.hdlg.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", this.thread.hdlg.get_locale()); String start_message = resources.getString("batch_optimizer") + " " + resources.getString("stop_message") + " " + resources.getString("pass") + " " + (new Integer(p_pass_no)).toString() + ": "; this.thread.hdlg.screen_messages.set_status_message(start_message); this.thread.hdlg.remove_ratsnest(); @@ -214,12 +214,12 @@ public class BatchOptRoute /** * Calculates the cumulative trace lengths multiplied by the trace radius of all traces - * on the board, which are not shove_fixed. + * on the eu.mihosoft.freerouting.board, which are not shove_fixed. */ private static double calc_weighted_trace_length(RoutingBoard p_board) { double result = 0; - int default_clearance_class = rules.BoardRules.default_clearance_class(); + int default_clearance_class = eu.mihosoft.freerouting.rules.BoardRules.default_clearance_class(); Iterator it = p_board.item_list.start_read_object(); for (;;) { @@ -267,9 +267,9 @@ public class BatchOptRoute private static int ADDITIONAL_RIPUP_COST_FACTOR_AT_START = 10; /** - * Reads the vias and traces on the board in ascending x order. - * Because the vias and traces on the board change while optimizing the item list - * of the board is read from scratch each time the next route item is returned. + * Reads the vias and traces on the eu.mihosoft.freerouting.board in ascending x order. + * Because the vias and traces on the eu.mihosoft.freerouting.board change while optimizing the item list + * of the eu.mihosoft.freerouting.board is read from scratch each time the next route item is returned. */ private class ReadSortedRouteItems { diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteExpansionRoom.java index 75a1767..b58c376 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteExpansionRoom.java @@ -19,7 +19,7 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; @@ -38,10 +38,10 @@ public interface CompleteExpansionRoom extends ExpansionRoom /** * Returns the object of tthis complete_expansion_rooom. */ - board.SearchTreeObject get_object(); + eu.mihosoft.freerouting.board.SearchTreeObject get_object(); /** * Draws the shape of this room for test purposes */ - void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity); + void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity); } diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteFreeSpaceExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteFreeSpaceExpansionRoom.java index ad41913..135867e 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteFreeSpaceExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteFreeSpaceExpansionRoom.java @@ -18,20 +18,20 @@ * Created on 10. Februar 2004, 10:12 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import board.SearchTreeObject; -import board.ShapeSearchTree; -import board.Connectable; -import board.Item; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.Item; /** @@ -158,7 +158,7 @@ public class CompleteFreeSpaceExpansionRoom extends FreeSpaceExpansionRoom imple } /** - * Calculates the doors to the start and destination items of the autoroute algorithm. + * Calculates the doors to the start and destination items of the eu.mihosoft.freerouting.autoroute algorithm. */ public void calculate_target_doors(ShapeTree.TreeEntry p_own_net_object, int p_net_no, ShapeSearchTree p_autoroute_search_tree) { @@ -186,7 +186,7 @@ public class CompleteFreeSpaceExpansionRoom extends FreeSpaceExpansionRoom imple /** * Draws the shape of this room. */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { java.awt.Color draw_color = p_graphics_context.get_trace_colors(false)[this.get_layer()]; double layer_visibility = p_graphics_context.get_layer_visibility(this.get_layer()); diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/Connection.java b/src/main/java/eu/mihosoft/freerouting/autoroute/Connection.java index 016c586..80875c8 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/Connection.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/Connection.java @@ -19,16 +19,16 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.Set; import java.util.TreeSet; -import geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Point; -import board.Item; -import board.Trace; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.Trace; /** * Describes a routing connection ending at the next fork or terminal item. diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/DestinationDistance.java b/src/main/java/eu/mihosoft/freerouting/autoroute/DestinationDistance.java index 9548138..3978eea 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/DestinationDistance.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/DestinationDistance.java @@ -18,11 +18,11 @@ * Created on 26. Januar 2004, 10:08 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import autoroute.AutorouteControl.ExpansionCostFactor; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.autoroute.AutorouteControl.ExpansionCostFactor; diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPage.java b/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPage.java index 481e450..cf54a42 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPage.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPage.java @@ -19,22 +19,22 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.LinkedList; import java.util.Iterator; -import geometry.planar.Point; -import geometry.planar.IntBox; -import geometry.planar.TileShape; -import geometry.planar.PolylineArea; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.PolylineArea; -import datastructures.ShapeTree.TreeEntry; +import eu.mihosoft.freerouting.datastructures.ShapeTree.TreeEntry; -import board.RoutingBoard; -import board.ShapeSearchTree; -import board.Item; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.Item; /** * @@ -82,9 +82,9 @@ class DrillPage implements ExpandableObject { continue; } - if (curr_item instanceof board.Pin) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin) { - if (p_attach_smd && ((board.Pin) curr_item).drill_allowed()) + if (p_attach_smd && ((eu.mihosoft.freerouting.board.Pin) curr_item).drill_allowed()) { continue; } @@ -193,7 +193,7 @@ class DrillPage implements ExpandableObject * Test draw of the drills on this page. */ public void draw(java.awt.Graphics p_graphics, - boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { if (true || drills == null) { @@ -220,9 +220,9 @@ class DrillPage implements ExpandableObject Point result = null; for (Item curr_item : overlapping_items) { - if (curr_item instanceof board.Pin) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin) { - board.Pin curr_pin = (board.Pin) curr_item; + eu.mihosoft.freerouting.board.Pin curr_pin = (eu.mihosoft.freerouting.board.Pin) curr_item; if (curr_pin.drill_allowed() && p_drill_shape.contains_inside(curr_pin.get_center())) { result = curr_pin.get_center(); diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPageArray.java b/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPageArray.java index 5497c23..c4b6262 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPageArray.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/DrillPageArray.java @@ -19,19 +19,19 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.LinkedList; -import geometry.planar.IntBox; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.TileShape; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.RoutingBoard; /** * Describes the 2 dimensional array of pages of ExpansionDrill`s used in the maze search algorithm. - * The pages are rectangles of about equal width and height covering covering the bounding box of the board area. + * The pages are rectangles of about equal width and height covering covering the bounding box of the eu.mihosoft.freerouting.board area. * * @author Alfons Wirtz */ @@ -139,7 +139,7 @@ public class DrillPageArray /* * Test draw of the all drills */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { for (int j = 0; j < page_arr.length; ++j) { diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpandableObject.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpandableObject.java index d798b22..9a176e7 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpandableObject.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpandableObject.java @@ -17,9 +17,9 @@ * * Created on 6. April 2004, 07:30 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * An object, which can be expanded by the maze expansion algorithm. diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDoor.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDoor.java index 47d1b40..355a361 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDoor.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDoor.java @@ -17,12 +17,12 @@ * * Created on 6. Januar 2004, 07:23 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.TileShape; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; -import geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.Point; /** * An ExpansionDoor is a common edge between two ExpansionRooms @@ -52,6 +52,7 @@ public class ExpansionDoor implements ExpandableObject /** * Calculates the intersection of the shapes of the 2 rooms belonging to this door. */ + @Override public TileShape get_shape() { TileShape first_shape = first_room.get_shape(); @@ -63,6 +64,7 @@ public class ExpansionDoor implements ExpandableObject * The dimension of a door may be 1 or 2. * 2-dimensional doors can only exist between ObstacleExpansionRooms */ + @Override public int get_dimension() { return this.dimension; diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDrill.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDrill.java index 82e6033..c5152dc 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDrill.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionDrill.java @@ -17,10 +17,10 @@ * * Created on 19. April 2004, 08:00 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.Point; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; @@ -58,15 +58,15 @@ public class ExpansionDrill implements ExpandableObject public boolean calculate_expansion_rooms(AutorouteEngine p_autoroute_engine) { TileShape search_shape = TileShape.get_instance(location); - Collection overlaps = + Collection overlaps = p_autoroute_engine.autoroute_search_tree.overlapping_objects(search_shape, -1); for (int i = this.first_layer; i <= this.last_layer; ++i) { CompleteExpansionRoom found_room = null; - Iterator it = overlaps.iterator(); + Iterator it = overlaps.iterator(); while (it.hasNext()) { - board.SearchTreeObject curr_ob = it.next(); + eu.mihosoft.freerouting.board.SearchTreeObject curr_ob = it.next(); if (!(curr_ob instanceof CompleteExpansionRoom)) { it.remove(); @@ -139,7 +139,7 @@ public class ExpansionDrill implements ExpandableObject * Test draw of the the shape of this drill. */ public void draw(java.awt.Graphics p_graphics, - boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { java.awt.Color draw_color = p_graphics_context.get_hilight_color(); p_graphics_context.fill_area(this.shape, p_graphics, draw_color, p_intensity); diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionRoom.java index 54bd0de..cdc4137 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ExpansionRoom.java @@ -19,11 +19,11 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.List; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/FreeSpaceExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/FreeSpaceExpansionRoom.java index 48a7941..37215f7 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/FreeSpaceExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/FreeSpaceExpansionRoom.java @@ -18,9 +18,9 @@ * Created on 29. Dezember 2003, 08:37 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/IncompleteFreeSpaceExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/IncompleteFreeSpaceExpansionRoom.java index bf97931..cda8301 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/IncompleteFreeSpaceExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/IncompleteFreeSpaceExpansionRoom.java @@ -18,11 +18,11 @@ * Created on 10. Februar 2004, 10:13 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/InsertFoundConnectionAlgo.java b/src/main/java/eu/mihosoft/freerouting/autoroute/InsertFoundConnectionAlgo.java index e36ca3c..bfd74e7 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/InsertFoundConnectionAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/InsertFoundConnectionAlgo.java @@ -17,29 +17,29 @@ * * Created on 23. Februar 2004, 08:18 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.FloatPoint; -import geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Polyline; import java.util.Iterator; import java.util.Set; -import library.Padstack; -import rules.ViaInfo; +import eu.mihosoft.freerouting.library.Padstack; +import eu.mihosoft.freerouting.rules.ViaInfo; -import board.ForcedViaAlgo; -import board.PolylineTrace; -import board.Trace; -import board.Item; -import board.RoutingBoard; -import board.ItemSelectionFilter; -import board.TestLevel; +import eu.mihosoft.freerouting.board.ForcedViaAlgo; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.TestLevel; /** - * Inserts the traces and vias of the connection found by the autoroute algorithm. + * Inserts the traces and vias of the connection found by the eu.mihosoft.freerouting.autoroute algorithm. * * @author Alfons Wirtz */ @@ -121,8 +121,8 @@ public class InsertFoundConnectionAlgo board.rules.set_pin_edge_to_turn_dist(-1); // Look for pins att the start and the end of p_trace in case that neckdown is necessecary. - board.Pin start_pin = null; - board.Pin end_pin = null; + eu.mihosoft.freerouting.board.Pin start_pin = null; + eu.mihosoft.freerouting.board.Pin end_pin = null; if (ctrl.with_neckdown) { ItemSelectionFilter item_filter = new ItemSelectionFilter(ItemSelectionFilter.SelectableChoices.PINS); @@ -132,7 +132,7 @@ public class InsertFoundConnectionAlgo Set picked_items = this.board.pick_items(curr_end_corner, p_trace.layer, item_filter); for (Item curr_item : picked_items) { - board.Pin curr_pin = (board.Pin) curr_item; + eu.mihosoft.freerouting.board.Pin curr_pin = (eu.mihosoft.freerouting.board.Pin) curr_item; if (curr_pin.contains_net(ctrl.net_no) && curr_pin.get_center().equals(curr_end_corner)) { if (i == 0) @@ -220,7 +220,7 @@ public class InsertFoundConnectionAlgo return result; } - boolean insert_neckdown(Point p_from_corner, Point p_to_corner, int p_layer, board.Pin p_start_pin, board.Pin p_end_pin) + boolean insert_neckdown(Point p_from_corner, Point p_to_corner, int p_layer, eu.mihosoft.freerouting.board.Pin p_start_pin, eu.mihosoft.freerouting.board.Pin p_end_pin) { if (p_start_pin != null) { @@ -241,7 +241,7 @@ public class InsertFoundConnectionAlgo return false; } - private Point try_neck_down(Point p_from_corner, Point p_to_corner, int p_layer, board.Pin p_pin, boolean p_at_start) + private Point try_neck_down(Point p_from_corner, Point p_to_corner, int p_layer, eu.mihosoft.freerouting.board.Pin p_pin, boolean p_at_start) { if (!p_pin.is_on_layer(p_layer)) { diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ItemAutorouteInfo.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ItemAutorouteInfo.java index 3219944..40b5ac2 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ItemAutorouteInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ItemAutorouteInfo.java @@ -18,15 +18,15 @@ * Created on 22. Februar 2004, 12:09 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.ShapeSearchTree; -import board.Item; +import eu.mihosoft.freerouting.board.Item; /** - * Temporary data stored in board Items used in the autoroute algorithm + * Temporary data stored in eu.mihosoft.freerouting.board Items used in the eu.mihosoft.freerouting.autoroute algorithm * * @author Alfons Wirtz */ @@ -38,7 +38,7 @@ public class ItemAutorouteInfo this.item = p_item; } /** - * Looks, if the corresponding item belongs to the start or destination set of the autoroute algorithm. + * Looks, if the corresponding item belongs to the start or destination set of the eu.mihosoft.freerouting.autoroute algorithm. * Only used, if the item belongs to the net, which will be currently routed. */ public boolean is_start_info() @@ -47,7 +47,7 @@ public class ItemAutorouteInfo } /** - * Sets, if the corresponding item belongs to the start or destination set of the autoroute algorithm. + * Sets, if the corresponding item belongs to the start or destination set of the eu.mihosoft.freerouting.autoroute algorithm. * Only used, if the item belongs to the net, which will be currently routed. */ public void set_start_info(boolean p_value) @@ -114,7 +114,7 @@ public class ItemAutorouteInfo /** * Draws the shapes of the expansion rooms of this info for testing purposes. */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { if (expansion_room_arr == null) { diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo.java b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo.java index 2c79777..d0890e5 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo.java @@ -18,22 +18,22 @@ * Created on 31. Januar 2006, 08:20 * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.SortedSet; import java.util.LinkedList; import java.util.Iterator; -import geometry.planar.IntPoint; -import geometry.planar.FloatPoint; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; -import board.Connectable; -import board.Item; -import board.AngleRestriction; -import board.ShapeSearchTree; -import board.TestLevel; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.TestLevel; /** * @@ -269,7 +269,7 @@ public abstract class LocateFoundConnectionAlgo protected abstract Collection calculate_next_trace_corners(); /** Test display of the baktrack rooms. */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { for (int i = 0; i < backtrack_array.length; ++i) { diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo45Degree.java b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo45Degree.java index 051ea30..b2fc2aa 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo45Degree.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgo45Degree.java @@ -19,24 +19,24 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.LinkedList; import java.util.SortedSet; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; -import geometry.planar.TileShape; -import geometry.planar.IntBox; -import geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Simplex; -import board.ShapeSearchTree; -import board.AngleRestriction; -import board.Item; -import board.TestLevel; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.TestLevel; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgoAnyAngle.java b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgoAnyAngle.java index e907d2a..abd8984 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgoAnyAngle.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/LocateFoundConnectionAlgoAnyAngle.java @@ -18,21 +18,21 @@ * Created on 14. Februar 2004, 07:55 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.FloatLine; -import geometry.planar.FloatPoint; -import geometry.planar.Side; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.SortedSet; import java.util.LinkedList; -import board.ShapeSearchTree; -import board.AngleRestriction; -import board.Item; -import board.TestLevel; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.TestLevel; /** diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeListElement.java b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeListElement.java index 46527c6..8aff088 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeListElement.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeListElement.java @@ -18,9 +18,9 @@ * Created on 25. Januar 2004, 08:21 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; /** * Information for the maze expand Algorithm contained in expansion doors and drills diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchAlgo.java b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchAlgo.java index 56c1452..b34ca1f 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchAlgo.java @@ -17,18 +17,18 @@ * * Created on 25. Januar 2004, 13:24 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.ConvexShape; -import geometry.planar.FloatLine; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.TileShape; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Line; import java.util.Collection; import java.util.Iterator; @@ -36,14 +36,14 @@ import java.util.LinkedList; import java.util.TreeSet; import java.util.Set; -import board.Connectable; -import board.ForcedViaAlgo; -import board.Item; -import board.PolylineTrace; -import board.ShapeSearchTree; -import board.AngleRestriction; -import board.SearchTreeObject; -import board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.ForcedViaAlgo; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; /** * Class for autorouting an incomplete connection via a maze search algorithm. @@ -236,9 +236,9 @@ public class MazeSearchAlgo { // try evtl. neckdown at a start pin Item start_item = ((TargetItemExpansionDoor) p_list_element.door).item; - if (start_item instanceof board.Pin) + if (start_item instanceof eu.mihosoft.freerouting.board.Pin) { - double neckdown_half_width = ((board.Pin) start_item).get_trace_neckdown_halfwidth(layer_no); + double neckdown_half_width = ((eu.mihosoft.freerouting.board.Pin) start_item).get_trace_neckdown_halfwidth(layer_no); if (neckdown_half_width > 0) { half_width = Math.min(half_width, neckdown_half_width); @@ -341,7 +341,7 @@ public class MazeSearchAlgo if (ripup_costs != ALREADY_RIPPED_COSTS && next_room_is_thick) { Item obstacle_item = obstacle_room.get_item(); - if (!curr_door_is_small && this.ctrl.max_shove_trace_recursion_depth > 0 && obstacle_item instanceof board.PolylineTrace) + if (!curr_door_is_small && this.ctrl.max_shove_trace_recursion_depth > 0 && obstacle_item instanceof eu.mihosoft.freerouting.board.PolylineTrace) { if (!shove_trace_room(p_list_element, obstacle_room)) { @@ -398,9 +398,9 @@ public class MazeSearchAlgo else if (p_list_element.next_room instanceof ObstacleExpansionRoom) { Item curr_obstacle_item = ((ObstacleExpansionRoom) p_list_element.next_room).get_item(); - if (curr_obstacle_item instanceof board.Via) + if (curr_obstacle_item instanceof eu.mihosoft.freerouting.board.Via) { - board.Via curr_via = (board.Via) curr_obstacle_item; + eu.mihosoft.freerouting.board.Via curr_via = (eu.mihosoft.freerouting.board.Via) curr_obstacle_item; ExpansionDrill via_drill_info = curr_via.get_autoroute_drill_info(this.autoroute_engine.autoroute_search_tree); expand_to_drill(via_drill_info, p_list_element, ripup_costs); } @@ -545,7 +545,7 @@ public class MazeSearchAlgo TileShape door_shape = p_door.get_shape(); if (door_shape.is_empty()) { - if (this.autoroute_engine.board.get_test_level().ordinal() >= board.TestLevel.ALL_DEBUGGING_OUTPUT.ordinal()) + if (this.autoroute_engine.board.get_test_level().ordinal() >= eu.mihosoft.freerouting.board.TestLevel.ALL_DEBUGGING_OUTPUT.ordinal()) { System.out.println("MazeSearchAlgo:check_door_width door_shape is empty"); } @@ -628,9 +628,9 @@ public class MazeSearchAlgo // If expansion comes from a pin with trace exit directions the eapansion_value is calculated // from the nearest trace exit point instead from the center olf the pin. Item from_item = ((TargetItemExpansionDoor) p_from_element.backtrack_door).item; - if (from_item instanceof board.Pin) + if (from_item instanceof eu.mihosoft.freerouting.board.Pin) { - FloatPoint nearest_exit_corner = ((board.Pin) from_item).nearest_trace_exit_corner(p_drill.location.to_float(), trace_half_width, layer); + FloatPoint nearest_exit_corner = ((eu.mihosoft.freerouting.board.Pin) from_item).nearest_trace_exit_corner(p_drill.location.to_float(), trace_half_width, layer); if (nearest_exit_corner != null) { compare_corner = nearest_exit_corner; @@ -729,11 +729,11 @@ public class MazeSearchAlgo } Item curr_obstacle_item = ((ObstacleExpansionRoom) curr_drill.room_arr[p_list_element.section_no_of_door]).get_item(); - if (!(curr_obstacle_item instanceof board.Via)) + if (!(curr_obstacle_item instanceof eu.mihosoft.freerouting.board.Via)) { return; } - library.Padstack curr_obstacle_padstack = ((board.Via) curr_obstacle_item).get_padstack(); + eu.mihosoft.freerouting.library.Padstack curr_obstacle_padstack = ((eu.mihosoft.freerouting.board.Via) curr_obstacle_item).get_padstack(); if (!this.ctrl.via_rule.contains_padstack(curr_obstacle_padstack) || curr_obstacle_item.clearance_class_no() != this.ctrl.via_clearance_class) { return; @@ -755,16 +755,16 @@ public class MazeSearchAlgo for (;;) { TileShape curr_room_shape = curr_drill.room_arr[curr_layer - curr_drill.first_layer].get_shape(); - board.ForcedPadAlgo.CheckDrillResult drill_result = + eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult drill_result = ForcedViaAlgo.check_layer(ctrl.via_radius_arr[curr_layer], ctrl.via_clearance_class, ctrl.attach_smd_allowed, curr_room_shape, curr_drill.location, curr_layer, net_no_arr, ctrl.max_shove_trace_recursion_depth, 0, autoroute_engine.board); - if (drill_result == board.ForcedPadAlgo.CheckDrillResult.NOT_DRILLABLE) + if (drill_result == eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult.NOT_DRILLABLE) { via_lower_bound = curr_layer + 1; break; } - else if (drill_result == board.ForcedPadAlgo.CheckDrillResult.DRILLABLE_WITH_ATTACH_SMD) + else if (drill_result == eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult.DRILLABLE_WITH_ATTACH_SMD) { if (curr_layer == 0) { @@ -795,16 +795,16 @@ public class MazeSearchAlgo break; } TileShape curr_room_shape = curr_drill.room_arr[curr_layer - curr_drill.first_layer].get_shape(); - board.ForcedPadAlgo.CheckDrillResult drill_result = + eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult drill_result = ForcedViaAlgo.check_layer(ctrl.via_radius_arr[curr_layer], ctrl.via_clearance_class, ctrl.attach_smd_allowed, curr_room_shape, curr_drill.location, curr_layer, net_no_arr, ctrl.max_shove_trace_recursion_depth, 0, autoroute_engine.board); - if (drill_result == board.ForcedPadAlgo.CheckDrillResult.NOT_DRILLABLE) + if (drill_result == eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult.NOT_DRILLABLE) { via_upper_bound = curr_layer - 1; break; } - else if (drill_result == board.ForcedPadAlgo.CheckDrillResult.DRILLABLE_WITH_ATTACH_SMD) + else if (drill_result == eu.mihosoft.freerouting.board.ForcedPadAlgo.CheckDrillResult.DRILLABLE_WITH_ATTACH_SMD) { if (curr_layer == ctrl.layer_count - 1) { @@ -950,7 +950,7 @@ public class MazeSearchAlgo if (this.autoroute_engine.maintain_database) { - // add the completed start rooms carried over from the last autoroute to the start rooms. + // add the completed start rooms carried over from the last eu.mihosoft.freerouting.autoroute to the start rooms. completed_start_rooms.addAll(this.autoroute_engine.get_rooms_with_target_items(p_start_items)); } @@ -1005,17 +1005,17 @@ public class MazeSearchAlgo { for (Item curr_item : p_item_list) { - if ((curr_item instanceof board.Pin) && curr_item.net_count() > 1) + if ((curr_item instanceof eu.mihosoft.freerouting.board.Pin) && curr_item.net_count() > 1) { Collection pin_contacts = curr_item.get_normal_contacts(); - board.Pin curr_tie_pin = (board.Pin) curr_item; + eu.mihosoft.freerouting.board.Pin curr_tie_pin = (eu.mihosoft.freerouting.board.Pin) curr_item; for (Item curr_contact : pin_contacts) { - if (!(curr_contact instanceof board.PolylineTrace) || curr_contact.contains_net(p_own_net_no)) + if (!(curr_contact instanceof eu.mihosoft.freerouting.board.PolylineTrace) || curr_contact.contains_net(p_own_net_no)) { continue; } - p_autoroute_tree.reduce_trace_shape_at_tie_pin(curr_tie_pin, (board.PolylineTrace) curr_contact); + p_autoroute_tree.reduce_trace_shape_at_tie_pin(curr_tie_pin, (eu.mihosoft.freerouting.board.PolylineTrace) curr_contact); } } } @@ -1026,15 +1026,15 @@ public class MazeSearchAlgo Item obstacle_item = p_obstacle_room.get_item(); int layer = p_obstacle_room.get_layer(); double obstacle_half_width; - if (obstacle_item instanceof board.Trace) + if (obstacle_item instanceof eu.mihosoft.freerouting.board.Trace) { - obstacle_half_width = ((board.Trace) obstacle_item).get_half_width() + obstacle_half_width = ((eu.mihosoft.freerouting.board.Trace) obstacle_item).get_half_width() + this.search_tree.clearance_compensation_value(obstacle_item.clearance_class_no(), layer); } - else if (obstacle_item instanceof board.Via) + else if (obstacle_item instanceof eu.mihosoft.freerouting.board.Via) { - TileShape via_shape = ((board.Via) obstacle_item).get_tree_shape_on_layer(this.search_tree, layer); + TileShape via_shape = ((eu.mihosoft.freerouting.board.Via) obstacle_item).get_tree_shape_on_layer(this.search_tree, layer); obstacle_half_width = 0.5 * via_shape.max_width(); } else @@ -1089,9 +1089,9 @@ public class MazeSearchAlgo double fanout_via_cost_factor = 1.0; double cost_factor = 1; - if (p_obstacle_item instanceof board.Trace) + if (p_obstacle_item instanceof eu.mihosoft.freerouting.board.Trace) { - board.Trace obstacle_trace = (board.Trace) p_obstacle_item; + eu.mihosoft.freerouting.board.Trace obstacle_trace = (eu.mihosoft.freerouting.board.Trace) p_obstacle_item; cost_factor = obstacle_trace.get_half_width(); if (!this.ctrl.remove_unconnected_vias) { @@ -1099,19 +1099,19 @@ public class MazeSearchAlgo fanout_via_cost_factor = calc_fanout_via_ripup_cost_factor(obstacle_trace); } } - else if (p_obstacle_item instanceof board.Via) + else if (p_obstacle_item instanceof eu.mihosoft.freerouting.board.Via) { boolean look_if_fanout_via = !this.ctrl.remove_unconnected_vias; Collection contact_list = p_obstacle_item.get_normal_contacts(); int contact_count = 0; for (Item curr_contact : contact_list) { - if (!(curr_contact instanceof board.Trace) || curr_contact.is_user_fixed()) + if (!(curr_contact instanceof eu.mihosoft.freerouting.board.Trace) || curr_contact.is_user_fixed()) { return -1; } ++contact_count; - board.Trace obstacle_trace = (board.Trace) curr_contact; + eu.mihosoft.freerouting.board.Trace obstacle_trace = (eu.mihosoft.freerouting.board.Trace) curr_contact; cost_factor = Math.max(cost_factor, obstacle_trace.get_half_width()); if (look_if_fanout_via) { @@ -1160,7 +1160,7 @@ public class MazeSearchAlgo * Return the addditional cost factor for ripping the trace, if it is connected to a fanout via * or 1, if no fanout via was found. */ - private static double calc_fanout_via_ripup_cost_factor(board.Trace p_trace) + private static double calc_fanout_via_ripup_cost_factor(eu.mihosoft.freerouting.board.Trace p_trace) { final double FANOUT_COST_CONST = 20000; Collection curr_end_contacts; @@ -1180,11 +1180,11 @@ public class MazeSearchAlgo } Item curr_trace_contact = curr_end_contacts.iterator().next(); boolean protect_fanout_via = false; - if (curr_trace_contact instanceof board.Pin && curr_trace_contact.first_layer() == curr_trace_contact.last_layer()) + if (curr_trace_contact instanceof eu.mihosoft.freerouting.board.Pin && curr_trace_contact.first_layer() == curr_trace_contact.last_layer()) { protect_fanout_via = true; } - else if (curr_trace_contact instanceof PolylineTrace && curr_trace_contact.get_fixed_state() == board.FixedState.SHOVE_FIXED) + else if (curr_trace_contact instanceof PolylineTrace && curr_trace_contact.get_fixed_state() == eu.mihosoft.freerouting.board.FixedState.SHOVE_FIXED) { // look for shove fixed exit traces of SMD-pins PolylineTrace contact_trace = (PolylineTrace) curr_trace_contact; @@ -1288,9 +1288,9 @@ public class MazeSearchAlgo Collection target_doors = p_room.get_target_doors(); for (TargetItemExpansionDoor curr_target_door : target_doors) { - if (curr_target_door.item instanceof board.Pin) + if (curr_target_door.item instanceof eu.mihosoft.freerouting.board.Pin) { - return ((board.Pin) curr_target_door.item).get_trace_neckdown_halfwidth(p_room.get_layer()); + return ((eu.mihosoft.freerouting.board.Pin) curr_target_door.item).get_trace_neckdown_halfwidth(p_room.get_layer()); } } return 0; @@ -1439,7 +1439,7 @@ public class MazeSearchAlgo return enter_through_small_door(p_list_element, curr_item); } /** - * The autoroute engine of this expansion algorithm. + * The eu.mihosoft.freerouting.autoroute engine of this expansion algorithm. */ public final AutorouteEngine autoroute_engine; final AutorouteControl ctrl; diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchElement.java b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchElement.java index e7cccf6..f82e86a 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchElement.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeSearchElement.java @@ -18,7 +18,7 @@ * Created on 31. Januar 2004, 07:46 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; /** * Describes the structure of a section of an ExpandebleObject. diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeShoveTraceAlgo.java b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeShoveTraceAlgo.java index 9d79bce..d9c6107 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/MazeShoveTraceAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/MazeShoveTraceAlgo.java @@ -19,23 +19,23 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; -import geometry.planar.TileShape; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.Point; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; -import geometry.planar.Side; -import geometry.planar.Direction; -import geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; -import board.Item; -import board.RoutingBoard; -import board.ShoveTraceAlgo; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.ShoveTraceAlgo; /** * Auxiliary functions used in MazeSearchAlgo. @@ -58,11 +58,11 @@ public class MazeShoveTraceAlgo return true; } ExpansionDoor from_door = (ExpansionDoor) p_list_element.door; - if (!(p_obstacle_room.get_item() instanceof board.PolylineTrace)) + if (!(p_obstacle_room.get_item() instanceof eu.mihosoft.freerouting.board.PolylineTrace)) { return true; } - board.PolylineTrace obstacle_trace = (board.PolylineTrace)p_obstacle_room.get_item(); + eu.mihosoft.freerouting.board.PolylineTrace obstacle_trace = (eu.mihosoft.freerouting.board.PolylineTrace)p_obstacle_room.get_item(); int trace_layer = p_obstacle_room.get_layer(); // only traces with the same halfwidth and the same clearance class can be shoved. if (obstacle_trace.get_half_width() != p_ctrl.trace_half_width[trace_layer] @@ -291,7 +291,7 @@ public class MazeShoveTraceAlgo FloatLine curr_door_segment = curr_door_shape.diagonal_corner_segment(); if (curr_door_segment == null) { - if (p_board.get_test_level() == board.TestLevel.ALL_DEBUGGING_OUTPUT) + if (p_board.get_test_level() == eu.mihosoft.freerouting.board.TestLevel.ALL_DEBUGGING_OUTPUT) { System.out.println("MazeShoveTraceAlgo.check_shove_trace_line: door shape is empty"); } @@ -361,7 +361,7 @@ public class MazeShoveTraceAlgo * Check if the endpoints of p_trace and p_from_item are maching, so that the * shove can continue through a link door. */ - private static boolean end_points_matching(board.PolylineTrace p_trace, Item p_from_item) + private static boolean end_points_matching(eu.mihosoft.freerouting.board.PolylineTrace p_trace, Item p_from_item) { if (p_from_item == p_trace) { @@ -372,14 +372,14 @@ public class MazeShoveTraceAlgo return false; } boolean points_matching; - if (p_from_item instanceof board.DrillItem) + if (p_from_item instanceof eu.mihosoft.freerouting.board.DrillItem) { - Point from_center = ((board.DrillItem) p_from_item).get_center(); + Point from_center = ((eu.mihosoft.freerouting.board.DrillItem) p_from_item).get_center(); points_matching = from_center.equals(p_trace.first_corner()) || from_center.equals(p_trace.last_corner()); } - else if (p_from_item instanceof board.PolylineTrace) + else if (p_from_item instanceof eu.mihosoft.freerouting.board.PolylineTrace) { - board.PolylineTrace from_trace = (board.PolylineTrace) p_from_item; + eu.mihosoft.freerouting.board.PolylineTrace from_trace = (eu.mihosoft.freerouting.board.PolylineTrace) p_from_item; points_matching = p_trace.first_corner().equals(from_trace.first_corner()) || p_trace.first_corner().equals(from_trace.last_corner()) || p_trace.last_corner().equals(from_trace.first_corner()) || diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/ObstacleExpansionRoom.java b/src/main/java/eu/mihosoft/freerouting/autoroute/ObstacleExpansionRoom.java index eae913a..1fdf788 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/ObstacleExpansionRoom.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/ObstacleExpansionRoom.java @@ -19,21 +19,21 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.List; import java.util.Collection; -import board.ShapeSearchTree; -import board.SearchTreeObject; -import board.PolylineTrace; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.PolylineTrace; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; -import board.Item; +import eu.mihosoft.freerouting.board.Item; /** - * Expansion Room used for pushing and ripping obstacles in the autoroute algorithm. + * Expansion Room used for pushing and ripping obstacles in the eu.mihosoft.freerouting.autoroute algorithm. * * @author Alfons Wirtz */ @@ -91,7 +91,7 @@ public class ObstacleExpansionRoom implements CompleteExpansionRoom } /** - * Creates a 2-dim door with the other obstacle room, if that is useful for the autoroute algorithm. + * Creates a 2-dim door with the other obstacle room, if that is useful for the eu.mihosoft.freerouting.autoroute algorithm. * It is assumed that this room and p_other have a 2-dimensional overlap. * Returns false, if no door was created. */ @@ -188,7 +188,7 @@ public class ObstacleExpansionRoom implements CompleteExpansionRoom /** * Draws the shape of this room. */ - public void draw(java.awt.Graphics p_graphics, boardgraphics.GraphicsContext p_graphics_context, double p_intensity) + public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity) { java.awt.Color draw_color = java.awt.Color.WHITE; double layer_visibility = p_graphics_context.get_layer_visibility(this.get_layer()); diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/Sorted45DegreeRoomNeighbours.java b/src/main/java/eu/mihosoft/freerouting/autoroute/Sorted45DegreeRoomNeighbours.java index 170c31d..a4d9ce5 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/Sorted45DegreeRoomNeighbours.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/Sorted45DegreeRoomNeighbours.java @@ -19,7 +19,7 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.Iterator; @@ -27,17 +27,17 @@ import java.util.LinkedList; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import geometry.planar.Limits; -import geometry.planar.IntOctagon; -import geometry.planar.IntPoint; -import geometry.planar.TileShape; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Limits; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import board.ShapeSearchTree; -import board.SearchTreeObject; -import board.Item; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.Item; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/SortedOrthogonalRoomNeighbours.java b/src/main/java/eu/mihosoft/freerouting/autoroute/SortedOrthogonalRoomNeighbours.java index 2c26034..bf4ef95 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/SortedOrthogonalRoomNeighbours.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/SortedOrthogonalRoomNeighbours.java @@ -19,7 +19,7 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.Iterator; @@ -27,15 +27,15 @@ import java.util.LinkedList; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import geometry.planar.IntBox; -import geometry.planar.TileShape; -import geometry.planar.Limits; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Limits; -import board.SearchTreeObject; -import board.ShapeSearchTree; -import board.Item; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.Item; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/SortedRoomNeighbours.java b/src/main/java/eu/mihosoft/freerouting/autoroute/SortedRoomNeighbours.java index db07c7d..b4fb2d4 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/SortedRoomNeighbours.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/SortedRoomNeighbours.java @@ -19,7 +19,7 @@ * */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; import java.util.Collection; import java.util.LinkedList; @@ -27,24 +27,24 @@ import java.util.TreeSet; import java.util.SortedSet; import java.util.Iterator; -import datastructures.Signum; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import geometry.planar.Side; -import geometry.planar.Direction; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.FloatPoint; -import geometry.planar.Line; -import geometry.planar.TileShape; -import geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Simplex; -import board.ShapeSearchTree; -import board.SearchTreeObject; -import board.Connectable; -import board.Item; -import board.PolylineTrace; -import board.TestLevel; +import eu.mihosoft.freerouting.board.ShapeSearchTree; +import eu.mihosoft.freerouting.board.SearchTreeObject; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.TestLevel; /** * To calculate the neigbour rooms of an expansion room. diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/TargetItemExpansionDoor.java b/src/main/java/eu/mihosoft/freerouting/autoroute/TargetItemExpansionDoor.java index 536e833..8992ff6 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/TargetItemExpansionDoor.java +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/TargetItemExpansionDoor.java @@ -17,15 +17,15 @@ * * Created on 2. Februar 2004, 12:59 */ -package autoroute; +package eu.mihosoft.freerouting.autoroute; -import geometry.planar.Simplex; -import geometry.planar.TileShape; -import board.Item; -import board.ShapeSearchTree; +import eu.mihosoft.freerouting.geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ShapeSearchTree; /** - * An expansion door leading to a start or destination item of the autoroute algorithm. + * An expansion door leading to a start or destination item of the eu.mihosoft.freerouting.autoroute algorithm. * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/autoroute/package.html b/src/main/java/eu/mihosoft/freerouting/autoroute/package.html index 2e56d1f..1726e22 100644 --- a/src/main/java/eu/mihosoft/freerouting/autoroute/package.html +++ b/src/main/java/eu/mihosoft/freerouting/autoroute/package.html @@ -16,4 +16,4 @@ --> -Contains functionality of the autoroute algorithm. \ No newline at end of file +Contains functionality of the eu.mihosoft.freerouting.autoroute algorithm. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/board/AngleRestriction.java b/src/main/java/eu/mihosoft/freerouting/board/AngleRestriction.java index afd770f..0c794b4 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/AngleRestriction.java +++ b/src/main/java/eu/mihosoft/freerouting/board/AngleRestriction.java @@ -18,7 +18,7 @@ * Created on 14. Juli 2003, 07:40 */ -package board; +package eu.mihosoft.freerouting.board; /** * Enum for angle restrictions none, fortyfive degree and ninety degree. diff --git a/src/main/java/eu/mihosoft/freerouting/board/BasicBoard.java b/src/main/java/eu/mihosoft/freerouting/board/BasicBoard.java index b955e4b..23d611d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/BasicBoard.java +++ b/src/main/java/eu/mihosoft/freerouting/board/BasicBoard.java @@ -13,17 +13,17 @@ * GNU General Public License at * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.Area; -import geometry.planar.ConvexShape; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.Point; -import geometry.planar.Vector; -import geometry.planar.Polyline; -import geometry.planar.PolylineShape; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.awt.Graphics; @@ -34,21 +34,21 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.ShapeTree.TreeEntry; +import eu.mihosoft.freerouting.datastructures.ShapeTree.TreeEntry; -import library.BoardLibrary; -import library.Padstack; -import rules.BoardRules; -import boardgraphics.GraphicsContext; -import boardgraphics.Drawable; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.library.BoardLibrary; +import eu.mihosoft.freerouting.library.Padstack; +import eu.mihosoft.freerouting.rules.BoardRules; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.Drawable; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; /** * - * Provides basic functionality of a board with geometric items. + * Provides basic functionality of a eu.mihosoft.freerouting.board with geometric items. * Contains functions such as inserting, deleting, modifying * and picking items and elementary checking functions. - * A board may have 1 or several layers. + * A eu.mihosoft.freerouting.board may have 1 or several layers. * * @author Alfons Wirtz */ @@ -60,7 +60,7 @@ public class BasicBoard implements java.io.Serializable * p_bounding_box * Rules contains the restrictions to obey when inserting items. * Among other things it may contain a clearance matrix. - * p_observers is used for syncronisation, if the board is generated + * p_observers is used for syncronisation, if the eu.mihosoft.freerouting.board is generated * by a host database. Otherwise it is null. * If p_test_level != RELEASE_VERSION,, some features may be used, which are still in experimental state. * Also warnings for debugging may be printed depending on the size of p_test_level. @@ -82,7 +82,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a trace into the board, whose geometry is described by + * Inserts a trace into the eu.mihosoft.freerouting.board, whose geometry is described by * a Polyline. p_clearance_class is the index in the clearance_matix, * which describes the required clearance restrictions to other items. * Because no internal cleaning of items is done, the new inserted @@ -114,7 +114,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a trace into the board, whose geometry is described by + * Inserts a trace into the eu.mihosoft.freerouting.board, whose geometry is described by * a Polyline. p_clearance_class is the index in the clearance_matix, * which describes the required clearance restrictions to other items. */ @@ -141,7 +141,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a trace into the board, whose geometry is described by + * Inserts a trace into the eu.mihosoft.freerouting.board, whose geometry is described by * an array of points, and cleans up the net. */ public void insert_trace(Point[] p_points, int p_layer, @@ -159,7 +159,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a via into the board. p_attach_allowed indicates, if the via may overlap with smd pins + * Inserts a via into the eu.mihosoft.freerouting.board. p_attach_allowed indicates, if the via may overlap with smd pins * of the same net. */ public Via insert_via(Padstack p_padstack, Point p_center, int[] p_net_no_arr, int p_clearance_class, @@ -181,8 +181,8 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a pin into the board. - * p_pin_no is the number of this pin in the library package of its component (starting with 0). + * Inserts a pin into the eu.mihosoft.freerouting.board. + * p_pin_no is the number of this pin in the eu.mihosoft.freerouting.library package of its component (starting with 0). */ public Pin insert_pin(int p_component_no, int p_pin_no, int[] p_net_no_arr, int p_clearance_class, FixedState p_fixed_state) { @@ -192,7 +192,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an obstacle into the board , whose geometry is described + * Inserts an obstacle into the eu.mihosoft.freerouting.board , whose geometry is described * by a polygonyal shape, which may have holes. * If p_component_no != 0, the obstacle belongs to a component. */ @@ -209,7 +209,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an obstacle belonging to a component into the board + * Inserts an obstacle belonging to a component into the eu.mihosoft.freerouting.board * p_name is to identify the corresponding ObstacstacleArea in the component package. */ public ObstacleArea insert_obstacle(Area p_area, int p_layer, Vector p_translation, double p_rotation_in_degree, @@ -227,7 +227,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an via obstacle area into the board , whose geometry is described + * Inserts an via obstacle area into the eu.mihosoft.freerouting.board , whose geometry is described * by a polygonyal shape, which may have holes. */ public ViaObstacleArea insert_via_obstacle(Area p_area, int p_layer, int p_clearance_class, @@ -245,7 +245,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an via obstacle belonging to a component into the board + * Inserts an via obstacle belonging to a component into the eu.mihosoft.freerouting.board * p_name is to identify the corresponding ObstacstacleArea in the component package. */ public ViaObstacleArea insert_via_obstacle(Area p_area, int p_layer, Vector p_translation, double p_rotation_in_degree, @@ -264,7 +264,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a component obstacle area into the board , whose geometry is described + * Inserts a component obstacle area into the eu.mihosoft.freerouting.board , whose geometry is described * by a polygonyal shape, which may have holes. */ public ComponentObstacleArea insert_component_obstacle(Area p_area, int p_layer, @@ -282,7 +282,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a component obstacle belonging to a component into the board. + * Inserts a component obstacle belonging to a component into the eu.mihosoft.freerouting.board. * p_name is to identify the corresponding ObstacstacleArea in the component package. */ public ComponentObstacleArea insert_component_obstacle(Area p_area, int p_layer, Vector p_translation, double p_rotation_in_degree, @@ -300,7 +300,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a component ouline into the board. + * Inserts a component ouline into the eu.mihosoft.freerouting.board. */ public ComponentOutline insert_component_outline(Area p_area, boolean p_is_front, Vector p_translation, double p_rotation_in_degree, int p_component_no, FixedState p_fixed_state) @@ -322,7 +322,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts a condution area into the board , whose geometry is described + * Inserts a condution area into the eu.mihosoft.freerouting.board , whose geometry is described * by a polygonyal shape, which may have holes. * If p_is_obstacle is false, it is possible to route through the conduction area * with traces and vias of foreign nets. @@ -342,7 +342,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an Outline into the board. + * Inserts an Outline into the eu.mihosoft.freerouting.board. */ public BoardOutline insert_outline(PolylineShape[] p_outline_shapes, int p_clearance_class_no) { @@ -352,7 +352,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the outline of the board. + * Returns the outline of the eu.mihosoft.freerouting.board. */ public BoardOutline get_outline() { @@ -373,7 +373,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Removes an item from the board + * Removes an item from the eu.mihosoft.freerouting.board */ public void remove_item(Item p_item) { @@ -390,7 +390,7 @@ public class BasicBoard implements java.io.Serializable } /** - * looks, if an item with id_no p_id_no is on the board. + * looks, if an item with id_no p_id_no is on the eu.mihosoft.freerouting.board. * Returns the found item or null, if no such item is found. */ public Item get_item(int p_id_no) @@ -412,7 +412,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all items on the board + * Returns the list of all items on the eu.mihosoft.freerouting.board */ public Collection get_items() { @@ -431,7 +431,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns all connectable items on the board containing p_net_no + * Returns all connectable items on the eu.mihosoft.freerouting.board containing p_net_no */ public Collection get_connectable_items(int p_net_no) { @@ -567,7 +567,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all conduction areas on the board + * Returns the list of all conduction areas on the eu.mihosoft.freerouting.board */ public Collection get_conduction_areas() { @@ -589,7 +589,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all pins on the board + * Returns the list of all pins on the eu.mihosoft.freerouting.board */ public Collection get_pins() { @@ -611,7 +611,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all pins on the board with only 1 layer + * Returns the list of all pins on the eu.mihosoft.freerouting.board with only 1 layer */ public Collection get_smd_pins() { @@ -637,7 +637,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all vias on the board + * Returns the list of all vias on the eu.mihosoft.freerouting.board */ public Collection get_vias() { @@ -659,7 +659,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of all traces on the board + * Returns the list of all traces on the eu.mihosoft.freerouting.board */ public Collection get_traces() { @@ -681,7 +681,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the cumulative length of all traces on the board + * Returns the cumulative length of all traces on the eu.mihosoft.freerouting.board */ public double cumulative_trace_length() { @@ -1034,7 +1034,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the layer count of this board. + * Returns the layer count of this eu.mihosoft.freerouting.board. */ public int get_layer_count() { @@ -1042,7 +1042,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Draws all items of the board on their visible layers. Called in the overwritten + * Draws all items of the eu.mihosoft.freerouting.board on their visible layers. Called in the overwritten * paintComponent method of a class derived from JPanel. * The value of p_layer_visibility is expected between 0 and 1 for each layer. */ @@ -1053,7 +1053,7 @@ public class BasicBoard implements java.io.Serializable return; } - // draw all items on the board + // draw all items on the eu.mihosoft.freerouting.board for (int curr_priority = Drawable.MIN_DRAW_PRIORITY; curr_priority <= Drawable.MIDDLE_DRAW_PRIORITY; ++curr_priority) { Iterator it = item_list.start_read_object(); @@ -1081,7 +1081,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns the list of items on the board, whose shape on layer p_layer contains the point at p_location. + * Returns the list of items on the eu.mihosoft.freerouting.board, whose shape on layer p_layer contains the point at p_location. * If p_layer < 0, the layer is ignored. * If p_item_selection_filter != null, only items of types selected by the filter are picked. */ @@ -1105,7 +1105,7 @@ public class BasicBoard implements java.io.Serializable } /** - * checks, if p_point is contained in the bounding box of this board. + * checks, if p_point is contained in the bounding box of this eu.mihosoft.freerouting.board. */ public boolean contains(Point p_point) { @@ -1127,7 +1127,7 @@ public class BasicBoard implements java.io.Serializable } /** - * returns the biggest half width of all traces on the board. + * returns the biggest half width of all traces on the eu.mihosoft.freerouting.board. */ public int get_max_trace_half_width() { @@ -1135,7 +1135,7 @@ public class BasicBoard implements java.io.Serializable } /** - * returns the smallest half width of all traces on the board. + * returns the smallest half width of all traces on the eu.mihosoft.freerouting.board. */ public int get_min_trace_half_width() { @@ -1143,7 +1143,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns a surrounding box of the geometry of this board + * Returns a surrounding box of the geometry of this eu.mihosoft.freerouting.board */ public IntBox get_bounding_box() { @@ -1214,7 +1214,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Returns, if the observer of the board items is activated. + * Returns, if the observer of the eu.mihosoft.freerouting.board items is activated. */ public boolean observers_active() { @@ -1254,7 +1254,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Inserts an item into the board data base + * Inserts an item into the eu.mihosoft.freerouting.board data base */ public void insert_item(Item p_item) { @@ -1379,7 +1379,7 @@ public class BasicBoard implements java.io.Serializable } /** - * Makes the current board situation restorable by undo. + * Makes the current eu.mihosoft.freerouting.board situation restorable by undo. */ public void generate_snapshot() { @@ -1505,7 +1505,7 @@ public class BasicBoard implements java.io.Serializable throws java.io.IOException, java.lang.ClassNotFoundException { p_stream.defaultReadObject(); - // insert the items on the board into the search trees + // insert the items on the eu.mihosoft.freerouting.board into the search trees search_tree_manager = new SearchTreeManager(this); Iterator it = this.get_items().iterator(); while (it.hasNext()) @@ -1516,27 +1516,27 @@ public class BasicBoard implements java.io.Serializable } } /** - * List of items inserted into this board + * List of items inserted into this eu.mihosoft.freerouting.board */ public final UndoableObjects item_list; - /** List of placed components on the board. */ + /** List of placed components on the eu.mihosoft.freerouting.board. */ public final Components components; /** - * Class defining the rules for items to be inserted into this board. + * Class defining the eu.mihosoft.freerouting.rules for items to be inserted into this eu.mihosoft.freerouting.board. * Contains for example the clearance matrix. */ public final BoardRules rules; /** - * The library containing pastack masks, packagages and other - * templates used on the board. + * The eu.mihosoft.freerouting.library containing pastack masks, packagages and other + * templates used on the eu.mihosoft.freerouting.board. */ public final BoardLibrary library; /** - * The layer structure of this board. + * The layer structure of this eu.mihosoft.freerouting.board. */ public final LayerStructure layer_structure; /** - * Handels the search trees pointing into the items of this board + * Handels the search trees pointing into the items of this eu.mihosoft.freerouting.board */ public transient SearchTreeManager search_tree_manager; /** @@ -1544,7 +1544,7 @@ public class BasicBoard implements java.io.Serializable */ public final Communication communication; /** - * bounding orthogonal rectangle of this board + * bounding orthogonal rectangle of this eu.mihosoft.freerouting.board */ public final IntBox bounding_box; /** @@ -1555,11 +1555,11 @@ public class BasicBoard implements java.io.Serializable /** the rectangle, where the graphics may be not uptodate */ transient private IntBox update_box = IntBox.EMPTY; /** - * the biggest half width of all traces on the board + * the biggest half width of all traces on the eu.mihosoft.freerouting.board */ private int max_trace_half_width = 1000; /** - * the smallest half width of all traces on the board + * the smallest half width of all traces on the eu.mihosoft.freerouting.board */ private int min_trace_half_width = 10000; /** diff --git a/src/main/java/eu/mihosoft/freerouting/board/BoardObserverAdaptor.java b/src/main/java/eu/mihosoft/freerouting/board/BoardObserverAdaptor.java index 694c2fc..f6bf28c 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/BoardObserverAdaptor.java +++ b/src/main/java/eu/mihosoft/freerouting/board/BoardObserverAdaptor.java @@ -19,7 +19,7 @@ * */ -package board; +package eu.mihosoft.freerouting.board; /** * Empty adaptor implementing the BoardObservers interface. diff --git a/src/main/java/eu/mihosoft/freerouting/board/BoardObservers.java b/src/main/java/eu/mihosoft/freerouting/board/BoardObservers.java index e724b60..727a6de 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/BoardObservers.java +++ b/src/main/java/eu/mihosoft/freerouting/board/BoardObservers.java @@ -19,9 +19,9 @@ * */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.Observers; +import eu.mihosoft.freerouting.datastructures.Observers; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/board/BoardOutline.java b/src/main/java/eu/mihosoft/freerouting/board/BoardOutline.java index 5b91901..0b8edd6 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/BoardOutline.java +++ b/src/main/java/eu/mihosoft/freerouting/board/BoardOutline.java @@ -17,22 +17,21 @@ * * Created on 18. August 2004, 07:24 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.IntBox; -import geometry.planar.IntPoint; -import geometry.planar.LineSegment; -import geometry.planar.TileShape; -import geometry.planar.PolylineShape; -import geometry.planar.PolylineArea; -import geometry.planar.Area; -import geometry.planar.Vector; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.PolylineArea; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** - * Class describing a board outline. + * Class describing a eu.mihosoft.freerouting.board outline. * * @author alfons */ @@ -179,7 +178,7 @@ public class BoardOutline extends Item implements java.io.Serializable public int get_draw_priority() { - return boardgraphics.Drawable.MAX_DRAW_PRIORITY; + return eu.mihosoft.freerouting.boardgraphics.Drawable.MAX_DRAW_PRIORITY; } public int shape_count() @@ -218,7 +217,7 @@ public class BoardOutline extends Item implements java.io.Serializable } /** - * The board shape outside the outline curves, where a keepout will be generated + * The eu.mihosoft.freerouting.board shape outside the outline curves, where a keepout will be generated * The outline curves are holes of the keepout_area. */ Area get_keepout_area() @@ -268,7 +267,7 @@ public class BoardOutline extends Item implements java.io.Serializable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("board_outline")); print_clearance_info(p_window, p_locale); p_window.newline(); @@ -287,7 +286,7 @@ public class BoardOutline extends Item implements java.io.Serializable } /** - * Returns, if keepout is generated outside the board outline. + * Returns, if keepout is generated outside the eu.mihosoft.freerouting.board outline. * Otherwise only the line shapes of the outlines are inserted as keepout. */ public boolean keepout_outside_outline_generated() @@ -340,10 +339,10 @@ public class BoardOutline extends Item implements java.io.Serializable { return p_search_tree.calculate_tree_shapes(this); } - /** The board shapes inside the outline curves. */ + /** The eu.mihosoft.freerouting.board shapes inside the outline curves. */ private PolylineShape[] shapes; /** - * The board shape outside the outline curves, where a keepout will be generated + * The eu.mihosoft.freerouting.board shape outside the outline curves, where a keepout will be generated * The outline curves are holes of the keepout_area. */ private Area keepout_area = null; diff --git a/src/main/java/eu/mihosoft/freerouting/board/CalcFromSide.java b/src/main/java/eu/mihosoft/freerouting/board/CalcFromSide.java index 25953ee..68ff110 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/CalcFromSide.java +++ b/src/main/java/eu/mihosoft/freerouting/board/CalcFromSide.java @@ -18,15 +18,15 @@ * Created on 17. August 2003, 07:36 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; -import geometry.planar.Line; -import geometry.planar.LineSegment; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.TileShape; -import geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Side; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/board/CalcShapeAndFromSide.java b/src/main/java/eu/mihosoft/freerouting/board/CalcShapeAndFromSide.java index 7b2f271..a1f510d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/CalcShapeAndFromSide.java +++ b/src/main/java/eu/mihosoft/freerouting/board/CalcShapeAndFromSide.java @@ -16,13 +16,13 @@ * Created on 1. September 2003, 08:40 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.Side; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * Used in the shove algorithm to calculate the fromside for pushing and diff --git a/src/main/java/eu/mihosoft/freerouting/board/ChangedArea.java b/src/main/java/eu/mihosoft/freerouting/board/ChangedArea.java index 2bed394..c1e8ae0 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ChangedArea.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ChangedArea.java @@ -14,14 +14,14 @@ * for more details. */ -package board; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; +package eu.mihosoft.freerouting.board; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; /** * - * Used internally for marking changed areas on the board + * Used internally for marking changed areas on the eu.mihosoft.freerouting.board * after shoving and optimizing items. * @@ -66,7 +66,7 @@ class ChangedArea /** * enlarges the octagon on p_layer, so that it contains p_shape */ - public void join (geometry.planar.TileShape p_shape, int p_layer) + public void join (eu.mihosoft.freerouting.geometry.planar.TileShape p_shape, int p_layer) { if (p_shape == null) { @@ -121,7 +121,7 @@ class ChangedArea MutableOctagon [] arr; /** - * mutable octagon with double coordinates (see geometry.planar.IntOctagon) + * mutable octagon with double coordinates (see eu.mihosoft.freerouting.geometry.planar.IntOctagon) */ private static class MutableOctagon { diff --git a/src/main/java/eu/mihosoft/freerouting/board/ClearanceViolation.java b/src/main/java/eu/mihosoft/freerouting/board/ClearanceViolation.java index d463d4f..2055e62 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ClearanceViolation.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ClearanceViolation.java @@ -18,9 +18,9 @@ * Created on 4. Oktober 2004, 08:56 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; /** @@ -43,7 +43,7 @@ public class ClearanceViolation implements ObjectInfoPanel.Printable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("clearance_violation_2")); p_window.append(" " + resources.getString("at") + " "); p_window.append(shape.centre_of_gravity()); diff --git a/src/main/java/eu/mihosoft/freerouting/board/Communication.java b/src/main/java/eu/mihosoft/freerouting/board/Communication.java index 781e11e..4ef7166 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Communication.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Communication.java @@ -18,10 +18,10 @@ * Created on 5. Juli 2004, 07:31 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.IdNoGenerator; -import designformats.specctra.CoordinateTransform; +import eu.mihosoft.freerouting.datastructures.IdNoGenerator; +import eu.mihosoft.freerouting.designforms.specctra.CoordinateTransform; /** * Communication information to host systems or host design formats. @@ -48,7 +48,7 @@ public class Communication implements java.io.Serializable public Communication() { this(Unit.MIL, 1, new SpecctraParserInfo("\"", null, null, null, null, false), - new CoordinateTransform(1, 0, 0), new board.ItemIdNoGenerator(), new BoardObserverAdaptor()); + new CoordinateTransform(1, 0, 0), new eu.mihosoft.freerouting.board.ItemIdNoGenerator(), new BoardObserverAdaptor()); } public boolean host_cad_is_eagle() diff --git a/src/main/java/eu/mihosoft/freerouting/board/Component.java b/src/main/java/eu/mihosoft/freerouting/board/Component.java index c67ba63..a57c862 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Component.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Component.java @@ -18,20 +18,20 @@ * Created on 27. Mai 2004, 07:23 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; -import library.Package; +import eu.mihosoft.freerouting.library.Package; /** - * Describes board components consisting of an array of pins + * Describes eu.mihosoft.freerouting.board components consisting of an array of pins * und other stuff like component keepouts. * * @author Alfons Wirtz @@ -85,7 +85,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin } /** - * If false, the component will be placed on the back side of the board. + * If false, the component will be placed on the back side of the eu.mihosoft.freerouting.board. */ public boolean placed_on_front() { @@ -94,7 +94,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin /** * Translates the location of this Component by p_p_vector. - * The Pins in the board must be moved seperately. + * The Pins in the eu.mihosoft.freerouting.board must be moved seperately. */ public void translate_by(Vector p_vector) { @@ -139,7 +139,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin double turn_angle = p_angle_in_degree; if (p_flip_style_rotate_first && !this.placed_on_front()) { - // take care of the order of mirroring and rotating on the back side of the board + // take care of the order of mirroring and rotating on the back side of the eu.mihosoft.freerouting.board turn_angle = 360 - p_angle_in_degree; } this.rotation_in_degree = this.rotation_in_degree + turn_angle; @@ -199,7 +199,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin /** * Returns information for pin swap and gate swap, if != null. */ - public library.LogicalPart get_logical_part() + public eu.mihosoft.freerouting.library.LogicalPart get_logical_part() { return this.logical_part; } @@ -207,7 +207,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin /** * Sets the infomation for pin swap and gate swap. */ - public void set_logical_part(library.LogicalPart p_logical_part) + public void set_logical_part(eu.mihosoft.freerouting.library.LogicalPart p_logical_part) { this.logical_part = p_logical_part; } @@ -215,7 +215,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("component") + " "); p_window.append_bold(this.name); if (this.location != null) @@ -251,7 +251,7 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin } /** - * Returns the library package of this component. + * Returns the eu.mihosoft.freerouting.library package of this component. */ public Package get_package() { @@ -273,19 +273,19 @@ public class Component implements UndoableObjects.Storable, ObjectInfoPanel.Prin /** The location of the component. */ private Point location; - /** The rotation of the library package of the component in degree */ + /** The rotation of the eu.mihosoft.freerouting.library package of the component in degree */ private double rotation_in_degree; /** Contains information for gate swapping and pin swapping, if != null */ - private library.LogicalPart logical_part = null; + private eu.mihosoft.freerouting.library.LogicalPart logical_part = null; - /** If false, the component will be placed on the back side of the board. */ + /** If false, the component will be placed on the back side of the eu.mihosoft.freerouting.board. */ private boolean on_front; - /** The library package of the component if it is placed on the component side. */ + /** The eu.mihosoft.freerouting.library package of the component if it is placed on the component side. */ private final Package lib_package_front; - /** The library package of the component if it is placed on the solder side. */ + /** The eu.mihosoft.freerouting.library package of the component if it is placed on the solder side. */ private final Package lib_package_back; /** Internal generated unique identification number. */ diff --git a/src/main/java/eu/mihosoft/freerouting/board/ComponentObstacleArea.java b/src/main/java/eu/mihosoft/freerouting/board/ComponentObstacleArea.java index 006ad91..f422f77 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ComponentObstacleArea.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ComponentObstacleArea.java @@ -18,14 +18,14 @@ * Created on 8. Mai 2005, 07:28 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.Area; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Vector; /** - * Describes areas of the board, where components arre not allowed. + * Describes areas of the eu.mihosoft.freerouting.board, where components arre not allowed. * * @author alfons */ @@ -71,12 +71,12 @@ public class ComponentObstacleArea extends ObstacleArea } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_place_obstacle_colors(); } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_place_obstacle_color_intensity(); } @@ -93,7 +93,7 @@ public class ComponentObstacleArea extends ObstacleArea public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("component_keepout")); this.print_shape_info(p_window, p_locale); this.print_clearance_info(p_window, p_locale); diff --git a/src/main/java/eu/mihosoft/freerouting/board/ComponentOutline.java b/src/main/java/eu/mihosoft/freerouting/board/ComponentOutline.java index 66460e7..1baece7 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ComponentOutline.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ComponentOutline.java @@ -18,17 +18,17 @@ * Created on 28. November 2005, 06:42 * */ -package board; +package eu.mihosoft.freerouting.board; import java.awt.Color; -import geometry.planar.Area; -import geometry.planar.Vector; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * @@ -103,9 +103,9 @@ public class ComponentOutline extends Item implements java.io.Serializable return 0; } - protected geometry.planar.TileShape[] calculate_tree_shapes(ShapeSearchTree p_search_tree) + protected eu.mihosoft.freerouting.geometry.planar.TileShape[] calculate_tree_shapes(ShapeSearchTree p_search_tree) { - return new geometry.planar.TileShape[0]; + return new eu.mihosoft.freerouting.geometry.planar.TileShape[0]; } public double get_draw_intensity(GraphicsContext p_graphics_context) @@ -130,7 +130,7 @@ public class ComponentOutline extends Item implements java.io.Serializable public int get_draw_priority() { - return boardgraphics.Drawable.MIDDLE_DRAW_PRIORITY; + return eu.mihosoft.freerouting.boardgraphics.Drawable.MIDDLE_DRAW_PRIORITY; } public void draw(java.awt.Graphics p_g, GraphicsContext p_graphics_context, Color[] p_color_arr, double p_intensity) @@ -146,7 +146,7 @@ public class ComponentOutline extends Item implements java.io.Serializable p_graphics_context.draw_boundary(this.get_area(), draw_width, color, p_g, intensity); } - public geometry.planar.IntBox bounding_box() + public eu.mihosoft.freerouting.geometry.planar.IntBox bounding_box() { return get_area().bounding_box(); } diff --git a/src/main/java/eu/mihosoft/freerouting/board/Components.java b/src/main/java/eu/mihosoft/freerouting/board/Components.java index 3859f58..4d2eef3 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Components.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Components.java @@ -19,21 +19,21 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Iterator; import java.util.Vector; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; -import geometry.planar.Point; -import geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; -import library.Package; +import eu.mihosoft.freerouting.library.Package; /** - * Contains the lists of components on the board. + * Contains the lists of components on the eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ @@ -41,7 +41,7 @@ public class Components implements java.io.Serializable { /** * Inserts a component into the list. - * The items of the component have to be inserted seperately into the board. + * The items of the component have to be inserted seperately into the eu.mihosoft.freerouting.board. * If p_on_front is false, the component will be placed on the back side, * and p_package_back is used instead of p_package_front. */ @@ -59,7 +59,7 @@ public class Components implements java.io.Serializable /** * Adds a component to this object. - * The items of the component have to be inserted seperately into the board. + * The items of the component have to be inserted seperately into the eu.mihosoft.freerouting.board. * If p_on_front is false, the component will be placed on the back side. * The component name is generated internally. */ @@ -103,7 +103,7 @@ public class Components implements java.io.Serializable } /** - * Returns the number of components on the board. + * Returns the number of components on the eu.mihosoft.freerouting.board. */ public int count() { @@ -166,9 +166,9 @@ public class Components implements java.io.Serializable /** * Moves the component with number p_component_no. - * Works contrary to Component.translate_by with the undo algorithm of the board. + * Works contrary to Component.translate_by with the undo algorithm of the eu.mihosoft.freerouting.board. */ - public void move(int p_component_no, geometry.planar.Vector p_vector ) + public void move(int p_component_no, eu.mihosoft.freerouting.geometry.planar.Vector p_vector ) { Component curr_component = this.get(p_component_no); this.undo_list.save_for_undo(curr_component); @@ -177,7 +177,7 @@ public class Components implements java.io.Serializable /** * Turns the component with number p_component_no by p_factor times 90 degree around p_pole. - * Works contrary to Component.turn_90_degree with the undo algorithm of the board. + * Works contrary to Component.turn_90_degree with the undo algorithm of the eu.mihosoft.freerouting.board. */ public void turn_90_degree(int p_component_no, int p_factor, IntPoint p_pole) { @@ -188,7 +188,7 @@ public class Components implements java.io.Serializable /** * Rotates the component with number p_component_no by p_rotation_in_degree around p_pole. - * Works contrary to Component.rotate with the undo algorithm of the board. + * Works contrary to Component.rotate with the undo algorithm of the eu.mihosoft.freerouting.board. */ public void rotate (int p_component_no, double p_rotation_in_degree, IntPoint p_pole) { @@ -200,7 +200,7 @@ public class Components implements java.io.Serializable /** * Changes the placement side of the component the component with numberp_component_no and * mirrors it at the vertical line through p_pole. - * Works contrary to Component.change_side the undo algorithm of the board. + * Works contrary to Component.change_side the undo algorithm of the eu.mihosoft.freerouting.board. */ public void change_side(int p_component_no, IntPoint p_pole) { diff --git a/src/main/java/eu/mihosoft/freerouting/board/ConductionArea.java b/src/main/java/eu/mihosoft/freerouting/board/ConductionArea.java index 6ad8363..ce4bdbf 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ConductionArea.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ConductionArea.java @@ -18,15 +18,15 @@ * Created on 29. Juni 2003, 11:49 */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Iterator; -import geometry.planar.Area; -import geometry.planar.Point; -import geometry.planar.Vector; -import geometry.planar.FloatPoint; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Set; import java.util.TreeSet; @@ -170,12 +170,12 @@ public class ConductionArea extends ObstacleArea implements Connectable return p_filter.is_selected(ItemSelectionFilter.SelectableChoices.CONDUCTION); } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_conduction_colors(); } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_conduction_color_intensity(); } @@ -183,7 +183,7 @@ public class ConductionArea extends ObstacleArea implements Connectable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("conduction_area")); this.print_shape_info(p_window, p_locale); this.print_connectable_item_info(p_window, p_locale); diff --git a/src/main/java/eu/mihosoft/freerouting/board/Connectable.java b/src/main/java/eu/mihosoft/freerouting/board/Connectable.java index 24dee2b..d571eac 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Connectable.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Connectable.java @@ -14,9 +14,9 @@ * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Set; diff --git a/src/main/java/eu/mihosoft/freerouting/board/CoordinateTransform.java b/src/main/java/eu/mihosoft/freerouting/board/CoordinateTransform.java index c1c30a5..6d156d7 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/CoordinateTransform.java +++ b/src/main/java/eu/mihosoft/freerouting/board/CoordinateTransform.java @@ -18,12 +18,12 @@ * Created on 17. Dezember 2004, 07:34 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** - * Class for transforming objects between user coordinate space and board coordinate space. + * Class for transforming objects between user coordinate space and eu.mihosoft.freerouting.board coordinate space. * * @author Alfons Wirtz */ @@ -42,7 +42,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Scale a value from the board to the user coordinate system. + * Scale a value from the eu.mihosoft.freerouting.board to the user coordinate system. */ public double board_to_user(double p_value) { @@ -50,7 +50,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Scale a value from the user to the board coordinate system. + * Scale a value from the user to the eu.mihosoft.freerouting.board coordinate system. */ public double user_to_board(double p_value) { @@ -59,7 +59,7 @@ public class CoordinateTransform implements java.io.Serializable /** - * Transforms a geometry.planar.FloatPoint from the board coordinate space + * Transforms a eu.mihosoft.freerouting.geometry.planar.FloatPoint from the eu.mihosoft.freerouting.board coordinate space * to the user coordinate space. */ public FloatPoint board_to_user(FloatPoint p_point) @@ -68,28 +68,28 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Transforms a geometry.planar.FloatPoint from the user coordinate space. - * to the board coordinate space. + * Transforms a eu.mihosoft.freerouting.geometry.planar.FloatPoint from the user coordinate space. + * to the eu.mihosoft.freerouting.board coordinate space. */ public FloatPoint user_to_board(FloatPoint p_point) { return new FloatPoint(user_to_board(p_point.x), user_to_board(p_point.y)); } - public PrintableShape board_to_user(geometry.planar.Shape p_shape, java.util.Locale p_locale) + public PrintableShape board_to_user(eu.mihosoft.freerouting.geometry.planar.Shape p_shape, java.util.Locale p_locale) { PrintableShape result; - if (p_shape instanceof geometry.planar.Circle) + if (p_shape instanceof eu.mihosoft.freerouting.geometry.planar.Circle) { - result = board_to_user((geometry.planar.Circle) p_shape, p_locale); + result = board_to_user((eu.mihosoft.freerouting.geometry.planar.Circle) p_shape, p_locale); } - else if (p_shape instanceof geometry.planar.IntBox) + else if (p_shape instanceof eu.mihosoft.freerouting.geometry.planar.IntBox) { - result = board_to_user((geometry.planar.IntBox) p_shape, p_locale); + result = board_to_user((eu.mihosoft.freerouting.geometry.planar.IntBox) p_shape, p_locale); } - else if (p_shape instanceof geometry.planar.PolylineShape) + else if (p_shape instanceof eu.mihosoft.freerouting.geometry.planar.PolylineShape) { - result = board_to_user((geometry.planar.PolylineShape) p_shape, p_locale); + result = board_to_user((eu.mihosoft.freerouting.geometry.planar.PolylineShape) p_shape, p_locale); } else { @@ -99,19 +99,19 @@ public class CoordinateTransform implements java.io.Serializable return result; } - public PrintableShape.Circle board_to_user(geometry.planar.Circle p_circle, java.util.Locale p_locale) + public PrintableShape.Circle board_to_user(eu.mihosoft.freerouting.geometry.planar.Circle p_circle, java.util.Locale p_locale) { return new PrintableShape.Circle(board_to_user(p_circle.center.to_float()), board_to_user(p_circle.radius), p_locale); } - public PrintableShape.Rectangle board_to_user(geometry.planar.IntBox p_box, java.util.Locale p_locale) + public PrintableShape.Rectangle board_to_user(eu.mihosoft.freerouting.geometry.planar.IntBox p_box, java.util.Locale p_locale) { return new PrintableShape.Rectangle(board_to_user(p_box.ll.to_float()), board_to_user(p_box.ur.to_float()), p_locale); } - public PrintableShape.Polygon board_to_user(geometry.planar.PolylineShape p_shape, java.util.Locale p_locale) + public PrintableShape.Polygon board_to_user(eu.mihosoft.freerouting.geometry.planar.PolylineShape p_shape, java.util.Locale p_locale) { FloatPoint[] corners = p_shape.corner_approx_arr(); FloatPoint[] transformed_corners = new FloatPoint[corners.length]; @@ -129,13 +129,13 @@ public class CoordinateTransform implements java.io.Serializable /** The factor of the user unit */ public final double user_unit_factor; - /** The unit used for board coordinates */ + /** The unit used for eu.mihosoft.freerouting.board coordinates */ public final Unit board_unit; - /** The factor of the board unit */ + /** The factor of the eu.mihosoft.freerouting.board unit */ public final double board_unit_factor; - /** The factor used for transforming coordinates between user coordinate space and board coordinate space */ + /** The factor used for transforming coordinates between user coordinate space and eu.mihosoft.freerouting.board coordinate space */ private final double scale_factor; } diff --git a/src/main/java/eu/mihosoft/freerouting/board/DrillItem.java b/src/main/java/eu/mihosoft/freerouting/board/DrillItem.java index 185a14a..c2d7c67 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/DrillItem.java +++ b/src/main/java/eu/mihosoft/freerouting/board/DrillItem.java @@ -18,23 +18,23 @@ * Created on 27. Juni 2003, 11:38 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.IntBox; -import geometry.planar.FloatPoint; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Shape; -import geometry.planar.TileShape; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; -import library.Padstack; +import eu.mihosoft.freerouting.library.Padstack; /** * Common superclass for Pins and Vias @@ -387,7 +387,7 @@ public abstract class DrillItem extends Item implements Connectable, java.io.Ser return TileShape.get_instance(this.get_center()); } - /** False, if this drillitem is places on the back side of the board */ + /** False, if this drillitem is places on the back side of the eu.mihosoft.freerouting.board */ public boolean is_placed_on_front() { return true; @@ -431,10 +431,10 @@ public abstract class DrillItem extends Item implements Connectable, java.io.Ser public int get_draw_priority() { - return boardgraphics.Drawable.MIDDLE_DRAW_PRIORITY; + return eu.mihosoft.freerouting.boardgraphics.Drawable.MIDDLE_DRAW_PRIORITY; } - public void draw(java.awt.Graphics p_g, boardgraphics.GraphicsContext p_graphics_context, + public void draw(java.awt.Graphics p_g, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, java.awt.Color[] p_color_arr, double p_intensity) { if (p_graphics_context == null|| p_intensity <= 0) diff --git a/src/main/java/eu/mihosoft/freerouting/board/FixedState.java b/src/main/java/eu/mihosoft/freerouting/board/FixedState.java index 3b4fe0f..bffbfcd 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/FixedState.java +++ b/src/main/java/eu/mihosoft/freerouting/board/FixedState.java @@ -18,10 +18,10 @@ * Created on 15. Maerz 2005, 06:34 */ -package board; +package eu.mihosoft.freerouting.board; /** - * Sorted fixed states of board items. The strongest fixed states came last. + * Sorted fixed states of eu.mihosoft.freerouting.board items. The strongest fixed states came last. * * @author alfons */ diff --git a/src/main/java/eu/mihosoft/freerouting/board/ForcedPadAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/ForcedPadAlgo.java index fb17151..b8cc8aa 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ForcedPadAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ForcedPadAlgo.java @@ -18,20 +18,20 @@ * Created on 1. September 2003, 08:28 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.Direction; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.Point; -import geometry.planar.Vector; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; diff --git a/src/main/java/eu/mihosoft/freerouting/board/ForcedViaAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/ForcedViaAlgo.java index 9ff43ad..d515d8d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ForcedViaAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ForcedViaAlgo.java @@ -18,21 +18,21 @@ * Created on 25. April 2004, 09:55 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.ConvexShape; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.FloatPoint; -import geometry.planar.Shape; -import geometry.planar.TileShape; -import geometry.planar.Simplex; -import geometry.planar.IntBox; -import geometry.planar.Circle; -import geometry.planar.Vector; -import geometry.planar.Limits; -import rules.ViaInfo; -import library.Padstack; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Circle; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Limits; +import eu.mihosoft.freerouting.rules.ViaInfo; +import eu.mihosoft.freerouting.library.Padstack; /** diff --git a/src/main/java/eu/mihosoft/freerouting/board/Item.java b/src/main/java/eu/mihosoft/freerouting/board/Item.java index 7e8ae8a..c7a3126 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Item.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Item.java @@ -13,17 +13,17 @@ * GNU General Public License at * for more details. */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.LinkedList; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.FloatPoint; -import geometry.planar.TileShape; -import geometry.planar.Vector; -import geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.IntBox; import java.awt.Color; import java.awt.Graphics; @@ -32,16 +32,16 @@ import java.util.Iterator; import java.util.Set; import java.util.TreeSet; -import rules.Nets; -import boardgraphics.Drawable; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.rules.Nets; +import eu.mihosoft.freerouting.boardgraphics.Drawable; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; -import datastructures.UndoableObjects; -import datastructures.ShapeTree; -import datastructures.ShapeTree.TreeEntry; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.ShapeTree.TreeEntry; /** - * Basic class of the items on a board. + * Basic class of the items on a eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ @@ -147,7 +147,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane { if (this.board == null) { - System.out.println("Item.get_tile_shape: board is null"); + System.out.println("Item.get_tile_shape: eu.mihosoft.freerouting.board is null"); return null; } return get_tree_shape(this.board.search_tree_manager.get_default_tree(), p_index); @@ -195,7 +195,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane /** * Returns false, if this item is deleted oor not inserted into - * the board. + * the eu.mihosoft.freerouting.board. */ public boolean is_on_the_board() { @@ -240,25 +240,25 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane /** * Translates the shapes of this item by p_vector. - * Does not move the item in the board. + * Does not move the item in the eu.mihosoft.freerouting.board. */ public abstract void translate_by(Vector p_vector); /** * Turns this Item by p_factor times 90 degree around p_pole. - * Does not update the item in the board. + * Does not update the item in the eu.mihosoft.freerouting.board. */ public abstract void turn_90_degree(int p_factor, IntPoint p_pole); /** * Rotates this Item by p_angle_in_degree around p_pole. - * Does not update the item in the board. + * Does not update the item in the eu.mihosoft.freerouting.board. */ public abstract void rotate_approx(double p_angle_in_degree, FloatPoint p_pole); /** * Changes the placement side of this Item and mirrors it at the vertical line through p_pole. - * Does not update the item in the board. + * Does not update the item in the eu.mihosoft.freerouting.board. */ public abstract void change_placement_side(IntPoint p_pole); @@ -268,7 +268,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane public abstract IntBox bounding_box(); /** - * Translates this item by p_vector in the board. + * Translates this item by p_vector in the eu.mihosoft.freerouting.board. */ public void move_by(Vector p_vector) { @@ -1209,28 +1209,28 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane } /** - * Gets the information for the autoroute algorithm. + * Gets the information for the eu.mihosoft.freerouting.autoroute algorithm. * Creates it, if it does not yet exist. */ - public autoroute.ItemAutorouteInfo get_autoroute_info() + public eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo get_autoroute_info() { if (autoroute_info == null) { - autoroute_info = new autoroute.ItemAutorouteInfo(this); + autoroute_info = new eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo(this); } return autoroute_info; } /** - * Gets the information for the autoroute algorithm. + * Gets the information for the eu.mihosoft.freerouting.autoroute algorithm. */ - public autoroute.ItemAutorouteInfo get_autoroute_info_pur() + public eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo get_autoroute_info_pur() { return autoroute_info; } /** - * Clears the data allocated for the autoroute algorithm. + * Clears the data allocated for the eu.mihosoft.freerouting.autoroute algorithm. */ public void clear_autoroute_info() { @@ -1256,11 +1256,11 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane protected void print_net_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); for (int i = 0; i < this.net_count(); ++i) { p_window.append(", " + resources.getString("net") + " "); - rules.Net curr_net = board.rules.nets.get(this.get_net_no(i)); + eu.mihosoft.freerouting.rules.Net curr_net = board.rules.nets.get(this.get_net_no(i)); p_window.append(curr_net.name, resources.getString("net_info"), curr_net); } } @@ -1273,7 +1273,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane if (this.clearance_class > 0) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append(", " + resources.getString("clearance_class") + " "); String name = board.rules.clearance_matrix.get_name(this.clearance_class); p_window.append(name, resources.getString("clearance_info"), board.rules.clearance_matrix.get_row(this.clearance_class)); @@ -1288,7 +1288,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane if (this.fixed_state != FixedState.UNFIXED) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.FixedState", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.FixedState", p_locale); p_window.append(", "); p_window.append(resources.getString(this.fixed_state.toString())); } @@ -1303,7 +1303,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane if (!contacts.isEmpty()) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append(", " + resources.getString("contacts") + " "); Integer contact_count = contacts.size(); p_window.append_items(contact_count.toString(), resources.getString("contact_info"), contacts); @@ -1319,7 +1319,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane if (!clearance_violations.isEmpty()) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append(", "); Integer violation_count = clearance_violations.size(); Collection violations = new java.util.LinkedList(); @@ -1450,7 +1450,7 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane * to other items */ private int clearance_class; - /** The board this Itewm is on */ + /** The eu.mihosoft.freerouting.board this Itewm is on */ transient public BasicBoard board; /** The nets, to which this item belongs */ int[] net_no_arr; @@ -1461,11 +1461,11 @@ public abstract class Item implements Drawable, SearchTreeObject, ObjectInfoPane private int component_no = 0; private final int id_no; /** - * Folse, if the item is deleted or not inserted into the board + * Folse, if the item is deleted or not inserted into the eu.mihosoft.freerouting.board */ private boolean on_the_board = false; - /** Temporary data used in the autoroute algorithm. */ - transient private autoroute.ItemAutorouteInfo autoroute_info = null; + /** Temporary data used in the eu.mihosoft.freerouting.autoroute algorithm. */ + transient private eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo autoroute_info = null; private static double PROTECT_FANOUT_LENGTH = 400; /** diff --git a/src/main/java/eu/mihosoft/freerouting/board/ItemIdNoGenerator.java b/src/main/java/eu/mihosoft/freerouting/board/ItemIdNoGenerator.java index 57e41b3..a2c68b8 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ItemIdNoGenerator.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ItemIdNoGenerator.java @@ -18,14 +18,14 @@ * Created on 2. Juni 2003, 13:43 */ -package board; +package eu.mihosoft.freerouting.board; /** * Creates unique Item identication nunbers. * * @author Alfons Wirtz */ -public class ItemIdNoGenerator implements datastructures.IdNoGenerator, java.io.Serializable +public class ItemIdNoGenerator implements eu.mihosoft.freerouting.datastructures.IdNoGenerator, java.io.Serializable { /** diff --git a/src/main/java/eu/mihosoft/freerouting/board/ItemSearchTreesInfo.java b/src/main/java/eu/mihosoft/freerouting/board/ItemSearchTreesInfo.java index 28def97..3f47cd5 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ItemSearchTreesInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ItemSearchTreesInfo.java @@ -19,17 +19,17 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.LinkedList; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** - * Stores information about the search trees of the board items, + * Stores information about the search trees of the eu.mihosoft.freerouting.board items, * which is precalculated for performance reasons. * * @author Alfons Wirtz diff --git a/src/main/java/eu/mihosoft/freerouting/board/ItemSelectionFilter.java b/src/main/java/eu/mihosoft/freerouting/board/ItemSelectionFilter.java index e64378a..ecbd3ec 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ItemSelectionFilter.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ItemSelectionFilter.java @@ -18,13 +18,13 @@ * Created on 14. Dezember 2004, 10:57 */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Set; import java.util.TreeSet; /** - * Filter for selecting items on the board. + * Filter for selecting items on the eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ @@ -118,10 +118,10 @@ public class ItemSelectionFilter implements java.io.Serializable /** * Filters a collection of items with this filter. */ - public Set filter(java.util.Set p_items) + public Set filter(java.util.Set p_items) { Set result = new TreeSet(); - for (board.Item curr_item : p_items) + for (eu.mihosoft.freerouting.board.Item curr_item : p_items) { if (curr_item.is_selected_by_filter(this)) { diff --git a/src/main/java/eu/mihosoft/freerouting/board/Layer.java b/src/main/java/eu/mihosoft/freerouting/board/Layer.java index 22d53a2..394f730 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Layer.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Layer.java @@ -18,10 +18,10 @@ * Created on 26. Mai 2004, 06:31 */ -package board; +package eu.mihosoft.freerouting.board; /** - * Describes the structure of a board layer. + * Describes the structure of a eu.mihosoft.freerouting.board layer. * * @author alfons */ diff --git a/src/main/java/eu/mihosoft/freerouting/board/LayerStructure.java b/src/main/java/eu/mihosoft/freerouting/board/LayerStructure.java index 7fe1f3e..8cc440d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/LayerStructure.java +++ b/src/main/java/eu/mihosoft/freerouting/board/LayerStructure.java @@ -18,10 +18,10 @@ * Created on 26. Mai 2004, 06:37 */ -package board; +package eu.mihosoft.freerouting.board; /** - * Describes the layer structure of the board. + * Describes the layer structure of the eu.mihosoft.freerouting.board. * * @author alfons */ diff --git a/src/main/java/eu/mihosoft/freerouting/board/MoveComponent.java b/src/main/java/eu/mihosoft/freerouting/board/MoveComponent.java index b8c8197..f8f6cfc 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/MoveComponent.java +++ b/src/main/java/eu/mihosoft/freerouting/board/MoveComponent.java @@ -17,23 +17,23 @@ * * Created on 25. Oktober 2003, 09:03 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; /** - * Class for moving a group of items on the board + * Class for moving a group of items on the eu.mihosoft.freerouting.board * @author Alfons Wirtz */ public class MoveComponent diff --git a/src/main/java/eu/mihosoft/freerouting/board/MoveDrillItemAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/MoveDrillItemAlgo.java index 0c68310..fa5b19c 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/MoveDrillItemAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/MoveDrillItemAlgo.java @@ -19,20 +19,20 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.TileShape; -import geometry.planar.ConvexShape; -import geometry.planar.IntOctagon; -import geometry.planar.IntBox; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.Vector; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** diff --git a/src/main/java/eu/mihosoft/freerouting/board/ObjectInfoPanel.java b/src/main/java/eu/mihosoft/freerouting/board/ObjectInfoPanel.java index 408d9a6..434d78b 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ObjectInfoPanel.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ObjectInfoPanel.java @@ -18,10 +18,10 @@ * Created on 6. Januar 2005, 13:15 */ -package board; +package eu.mihosoft.freerouting.board; /** - * Output window for printing information about board objects. + * Output window for printing information about eu.mihosoft.freerouting.board objects. * * @author Alfons Wirtz */ @@ -58,14 +58,14 @@ public interface ObjectInfoPanel * after transforming to the user coordinate sytem. * Returns false, if that was not possible. */ - boolean append(geometry.planar.FloatPoint p_point); + boolean append(eu.mihosoft.freerouting.geometry.planar.FloatPoint p_point); /** * Appends p_shape to the window * after transforming to the user coordinate sytem. * Returns false, if that was not possible. */ - boolean append(geometry.planar.Shape p_shape, java.util.Locale p_locale); + boolean append(eu.mihosoft.freerouting.geometry.planar.Shape p_shape, java.util.Locale p_locale); /** * Begins a new line in the window. @@ -88,7 +88,7 @@ public interface ObjectInfoPanel * Appends a link for creating a new PrintInfoWindow with the information * of p_items to the window. Returns false, if that was not possible. */ - boolean append_items( String p_link_name, String p_window_title, java.util.Collection p_items); + boolean append_items( String p_link_name, String p_window_title, java.util.Collection p_items); /** * Appends a link for creating a new PrintInfoWindow with the information diff --git a/src/main/java/eu/mihosoft/freerouting/board/ObstacleArea.java b/src/main/java/eu/mihosoft/freerouting/board/ObstacleArea.java index 011334e..141b2b3 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ObstacleArea.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ObstacleArea.java @@ -14,23 +14,23 @@ * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.IntBox; -import geometry.planar.IntPoint; -import geometry.planar.Area; -import geometry.planar.TileShape; -import geometry.planar.Vector; -import geometry.planar.Point; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.awt.Color; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * - * An item on the board with an relative_area shape, for example keepout, conduction relative_area + * An item on the eu.mihosoft.freerouting.board with an relative_area shape, for example keepout, conduction relative_area * * * @@ -250,7 +250,7 @@ public class ObstacleArea extends Item implements java.io.Serializable public int get_draw_priority() { - return boardgraphics.Drawable.MIN_DRAW_PRIORITY; + return eu.mihosoft.freerouting.boardgraphics.Drawable.MIN_DRAW_PRIORITY; } public void draw(java.awt.Graphics p_g, GraphicsContext p_graphics_context, Color[] p_color_arr, double p_intensity) @@ -295,7 +295,7 @@ public class ObstacleArea extends Item implements java.io.Serializable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("keepout")); int cmp_no = this.get_component_no(); if (cmp_no > 0) @@ -315,9 +315,9 @@ public class ObstacleArea extends Item implements java.io.Serializable protected final void print_shape_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append(" " + resources.getString("at") + " "); - geometry.planar.FloatPoint center = this.get_area().get_border().centre_of_gravity(); + eu.mihosoft.freerouting.geometry.planar.FloatPoint center = this.get_area().get_border().centre_of_gravity(); p_window.append(center); Integer hole_count = this.relative_area.get_holes().length; if(hole_count > 0) diff --git a/src/main/java/eu/mihosoft/freerouting/board/OptViaAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/OptViaAlgo.java index f327964..eb63a9c 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/OptViaAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/OptViaAlgo.java @@ -19,20 +19,20 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.Iterator; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Vector; -import geometry.planar.Polyline; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; -import geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.Side; -import autoroute.AutorouteControl.ExpansionCostFactor; +import eu.mihosoft.freerouting.autoroute.AutorouteControl.ExpansionCostFactor; /** * Contains functions for optimizing and improving via locations. diff --git a/src/main/java/eu/mihosoft/freerouting/board/Pin.java b/src/main/java/eu/mihosoft/freerouting/board/Pin.java index 6a7b939..bb1715d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Pin.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Pin.java @@ -18,25 +18,25 @@ * Created on 6. Juni 2003, 08:04 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Shape; -import geometry.planar.ConvexShape; -import geometry.planar.TileShape; -import geometry.planar.Vector; -import geometry.planar.Direction; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import library.Package; -import library.Padstack; +import eu.mihosoft.freerouting.library.Package; +import eu.mihosoft.freerouting.library.Padstack; /** - * Class describing the functionality of an electrical Item on the board + * Class describing the functionality of an electrical Item on the eu.mihosoft.freerouting.board * with a shape on 1 or several layers. * * @author Alfons Wirtz @@ -167,7 +167,7 @@ public class Pin extends DrillItem implements java.io.Serializable } /** - * Gets index of this pin in the library package of the pins component. + * Gets index of this pin in the eu.mihosoft.freerouting.library package of the pins component. */ public int get_index_in_package() { @@ -454,12 +454,12 @@ public class Pin extends DrillItem implements java.io.Serializable { return result; } - library.LogicalPart logical_part = component.get_logical_part(); + eu.mihosoft.freerouting.library.LogicalPart logical_part = component.get_logical_part(); if (logical_part == null) { return result; } - library.LogicalPart.PartPin this_part_pin = logical_part.get_pin(this.pin_no); + eu.mihosoft.freerouting.library.LogicalPart.PartPin this_part_pin = logical_part.get_pin(this.pin_no); if (this_part_pin == null) { return result; @@ -475,7 +475,7 @@ public class Pin extends DrillItem implements java.io.Serializable { continue; } - library.LogicalPart.PartPin curr_part_pin = logical_part.get_pin(i); + eu.mihosoft.freerouting.library.LogicalPart.PartPin curr_part_pin = logical_part.get_pin(i); if (curr_part_pin != null && curr_part_pin.gate_pin_swap_code == this_part_pin.gate_pin_swap_code && curr_part_pin.gate_name.equals(this_part_pin.gate_name)) { @@ -502,7 +502,7 @@ public class Pin extends DrillItem implements java.io.Serializable return p_filter.is_selected(ItemSelectionFilter.SelectableChoices.PINS); } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { java.awt.Color[] result; if (this.net_count() > 0) @@ -517,7 +517,7 @@ public class Pin extends DrillItem implements java.io.Serializable return result; } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_pin_color_intensity(); } @@ -581,7 +581,7 @@ public class Pin extends DrillItem implements java.io.Serializable } - /** False, if this drillitem is places on the back side of the board */ + /** False, if this drillitem is places on the back side of the eu.mihosoft.freerouting.board */ public boolean is_placed_on_front() { boolean result = true; @@ -605,7 +605,7 @@ public class Pin extends DrillItem implements java.io.Serializable System.out.println("Pin.get_min_width: padstack_shape is null"); return 0; } - geometry.planar.IntBox padstack_bounding_box = padstack_shape.bounding_box(); + eu.mihosoft.freerouting.geometry.planar.IntBox padstack_bounding_box = padstack_shape.bounding_box(); if (padstack_bounding_box == null) { System.out.println("Pin.get_min_width: padstack_bounding_box is null"); @@ -637,7 +637,7 @@ public class Pin extends DrillItem implements java.io.Serializable System.out.println("Pin.get_max_width: padstack_shape is null"); return 0; } - geometry.planar.IntBox padstack_bounding_box = padstack_shape.bounding_box(); + eu.mihosoft.freerouting.geometry.planar.IntBox padstack_bounding_box = padstack_shape.bounding_box(); if (padstack_bounding_box == null) { System.out.println("Pin.get_max_width: padstack_bounding_box is null"); @@ -649,7 +649,7 @@ public class Pin extends DrillItem implements java.io.Serializable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("pin") + ": "); p_window.append(resources.getString("component_2") + " "); Component component = board.components.get(this.get_component_no()); @@ -657,7 +657,7 @@ public class Pin extends DrillItem implements java.io.Serializable p_window.append(", " + resources.getString("pin_2") + " "); p_window.append(component.get_package().get_pin(this.pin_no).name); p_window.append(", " + resources.getString("padstack") + " "); - library.Padstack padstack = this.get_padstack(); + eu.mihosoft.freerouting.library.Padstack padstack = this.get_padstack(); p_window.append(padstack.name, resources.getString("padstack_info"), padstack); p_window.append(" " + resources.getString("at") + " "); p_window.append(this.get_center().to_float()); diff --git a/src/main/java/eu/mihosoft/freerouting/board/PolylineTrace.java b/src/main/java/eu/mihosoft/freerouting/board/PolylineTrace.java index 797bc82..6d0ddbd 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PolylineTrace.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PolylineTrace.java @@ -13,23 +13,23 @@ * GNU General Public License at * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.Signum; -import datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Stoppable; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.Line; -import geometry.planar.LineSegment; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.FloatPoint; -import geometry.planar.Polyline; -import geometry.planar.Shape; -import geometry.planar.TileShape; -import geometry.planar.Direction; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.Vector; import java.awt.Color; import java.awt.Graphics; @@ -37,7 +37,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * @@ -577,7 +577,7 @@ public class PolylineTrace extends Trace implements java.io.Serializable if (found_trace_split) { // reread the overlapping tree entries and reset the iterator, - // because the board has changed + // because the eu.mihosoft.freerouting.board has changed default_tree.overlapping_tree_entries(curr_shape, get_layer(), overlapping_tree_entries); it = overlapping_tree_entries.iterator(); break; @@ -649,7 +649,7 @@ public class PolylineTrace extends Trace implements java.io.Serializable boolean ignore_areas = false; if (this.net_no_arr.length > 0) { - rules.Net curr_net = this.board.rules.nets.get(this.net_no_arr[0]); + eu.mihosoft.freerouting.rules.Net curr_net = this.board.rules.nets.get(this.net_no_arr[0]); if (curr_net != null && curr_net.get_class() != null) { ignore_areas = curr_net.get_class().get_ignore_cycles_with_areas(); diff --git a/src/main/java/eu/mihosoft/freerouting/board/PrintableShape.java b/src/main/java/eu/mihosoft/freerouting/board/PrintableShape.java index 6d82bfc..f00335c 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PrintableShape.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PrintableShape.java @@ -18,12 +18,12 @@ * Created on 5. Januar 2005, 08:02 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** - * Shape class used for printing a geometry.planar.Shape after transforming it to user coordinates. + * Shape class used for printing a eu.mihosoft.freerouting.geometry.planar.Shape after transforming it to user coordinates. * * @author Alfons Wirtz */ @@ -56,7 +56,7 @@ public abstract class PrintableShape public String toString() { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", this.locale); String result = resources.getString("circle") + ": "; if (center.x != 0 || center.y != 0) { @@ -89,7 +89,7 @@ public abstract class PrintableShape public String toString() { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", this.locale); String result = resources.getString("rectangle") + ": " + resources.getString("lower_left") + " = " + lower_left.to_string(this.locale) + ", " + resources.getString("upper_right") + " = " + upper_right.to_string(this.locale) ; @@ -112,7 +112,7 @@ public abstract class PrintableShape public String toString() { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", this.locale); String result = resources.getString("polygon") + ": "; for (int i = 0; i < corner_arr.length; ++i) { diff --git a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo.java index 2f9583f..66700b1 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo.java @@ -17,26 +17,26 @@ * * Created on 19. Juli 2003, 12:42 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; -import geometry.planar.IntOctagon; -import geometry.planar.IntPoint; -import geometry.planar.Line; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.Side; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; import java.util.Set; -import datastructures.Signum; -import datastructures.Stoppable; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import autoroute.AutorouteControl.ExpansionCostFactor; +import eu.mihosoft.freerouting.autoroute.AutorouteControl.ExpansionCostFactor; /** * Class with functionality for optimising traces and vias. diff --git a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo45.java b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo45.java index af7215a..c575ce6 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo45.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo45.java @@ -17,21 +17,21 @@ * * Created on 19. Juli 2003, 18:59 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.Stoppable; -import geometry.planar.Direction; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Limits; -import geometry.planar.Line; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.Side; -import geometry.planar.TileShape; -import geometry.planar.Vector; -import datastructures.Signum; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Limits; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo90.java b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo90.java index d54faae..0cbcd35 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo90.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgo90.java @@ -18,15 +18,15 @@ * Created on 19. Juli 2003, 18:54 */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.Stoppable; -import geometry.planar.FloatPoint; -import geometry.planar.Point; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgoAnyAngle.java b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgoAnyAngle.java index 25e52f8..1c14556 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgoAnyAngle.java +++ b/src/main/java/eu/mihosoft/freerouting/board/PullTightAlgoAnyAngle.java @@ -14,20 +14,20 @@ * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.Stoppable; -import geometry.planar.Limits; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Stoppable; +import eu.mihosoft.freerouting.geometry.planar.Limits; +import eu.mihosoft.freerouting.datastructures.Signum; -import geometry.planar.Direction; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.Line; -import geometry.planar.Polyline; -import geometry.planar.Side; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/board/RoutingBoard.java b/src/main/java/eu/mihosoft/freerouting/board/RoutingBoard.java index 16a72b0..4b0be0c 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/RoutingBoard.java +++ b/src/main/java/eu/mihosoft/freerouting/board/RoutingBoard.java @@ -13,18 +13,18 @@ * GNU General Public License at * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.IntPoint; -import geometry.planar.LineSegment; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.PolylineShape; -import geometry.planar.TileShape; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Vector; import java.util.Collection; import java.util.Iterator; @@ -32,22 +32,22 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.UndoableObjects; -import datastructures.Stoppable; -import datastructures.TimeLimit; -import datastructures.ShapeTree.TreeEntry; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.ShapeTree.TreeEntry; -import rules.ViaInfo; -import rules.BoardRules; +import eu.mihosoft.freerouting.rules.ViaInfo; +import eu.mihosoft.freerouting.rules.BoardRules; -import autoroute.AutorouteControl; -import autoroute.AutorouteEngine; -import autoroute.AutorouteControl.ExpansionCostFactor; -import autoroute.CompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.AutorouteControl; +import eu.mihosoft.freerouting.autoroute.AutorouteEngine; +import eu.mihosoft.freerouting.autoroute.AutorouteControl.ExpansionCostFactor; +import eu.mihosoft.freerouting.autoroute.CompleteFreeSpaceExpansionRoom; /** * - * Contains higher level functions of a board + * Contains higher level functions of a eu.mihosoft.freerouting.board * * @author Alfons Wirtz */ @@ -183,7 +183,7 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * marks the whole board as changed + * marks the whole eu.mihosoft.freerouting.board as changed */ public void mark_all_changed_area() { @@ -902,8 +902,8 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * Initialises the autoroute database for routing a connection. - * If p_retain_autoroute_database, the autoroute database is retained and maintained after + * Initialises the eu.mihosoft.freerouting.autoroute database for routing a connection. + * If p_retain_autoroute_database, the eu.mihosoft.freerouting.autoroute database is retained and maintained after * the algorithm for performance reasons. */ public AutorouteEngine init_autoroute(int p_net_no, int p_trace_clearance_class_no, @@ -918,7 +918,7 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * Clears the autoroute database in case it was retained. + * Clears the eu.mihosoft.freerouting.autoroute database in case it was retained. */ public void finish_autoroute() { @@ -934,7 +934,7 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable * is not yet electrically connected. * Returns an enum of type AutorouteEngine.AutorouteResult */ - public AutorouteEngine.AutorouteResult autoroute(Item p_item, interactive.Settings p_settings, int p_via_costs, Stoppable p_stoppable_thread, TimeLimit p_time_limit) + public AutorouteEngine.AutorouteResult autoroute(Item p_item, eu.mihosoft.freerouting.interactive.Settings p_settings, int p_via_costs, Stoppable p_stoppable_thread, TimeLimit p_time_limit) { if (!(p_item instanceof Connectable) || p_item.net_count() == 0) { @@ -942,18 +942,18 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } if (p_item.net_count() > 1) { - System.out.println("RoutingBoard.autoroute: net_count > 1 not yet implemented"); + System.out.println("RoutingBoard.eu.mihosoft.freerouting.autoroute: net_count > 1 not yet implemented"); } int route_net_no = p_item.get_net_no(0); AutorouteControl ctrl_settings = new AutorouteControl(this, route_net_no, p_settings, p_via_costs, p_settings.autoroute_settings.get_trace_cost_arr()); ctrl_settings.remove_unconnected_vias = false; Set route_start_set = p_item.get_connected_set(route_net_no); - rules.Net route_net = rules.nets.get(route_net_no); + eu.mihosoft.freerouting.rules.Net route_net = rules.nets.get(route_net_no); if (route_net != null && route_net.contains_plane()) { for (Item curr_item : route_start_set) { - if (curr_item instanceof board.ConductionArea) + if (curr_item instanceof eu.mihosoft.freerouting.board.ConductionArea) { return AutorouteEngine.AutorouteResult.ALREADY_CONNECTED; // already connected to plane } @@ -982,8 +982,8 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable * has only 1 layer. Ripup is allowed if p_ripup_costs is >= 0. * Returns an enum of type AutorouteEngine.AutorouteResult */ - public AutorouteEngine.AutorouteResult fanout(Pin p_pin, interactive.Settings p_settings, int p_ripup_costs, - Stoppable p_stoppable_thread, TimeLimit p_time_limit) + public AutorouteEngine.AutorouteResult fanout(Pin p_pin, eu.mihosoft.freerouting.interactive.Settings p_settings, int p_ripup_costs, + Stoppable p_stoppable_thread, TimeLimit p_time_limit) { if (p_pin.first_layer() != p_pin.last_layer() || p_pin.net_count() != 1) { @@ -1200,7 +1200,7 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * Sets, if all conduction areas on the board are obstacles for route of foreign nets. + * Sets, if all conduction areas on the eu.mihosoft.freerouting.board are obstacles for route of foreign nets. */ public void change_conduction_is_obstacle(boolean p_value) { @@ -1209,7 +1209,7 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable return; // no muultiply } boolean something_changed = false; - // Change the is_obstacle property of all conduction areas of the board. + // Change the is_obstacle property of all conduction areas of the eu.mihosoft.freerouting.board. Iterator it = item_list.start_read_object(); for (;;) { @@ -1367,8 +1367,8 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * Sets, if the autoroute database has to be maintained outside the outoroute algorithm - * while changing items on rhe board. + * Sets, if the eu.mihosoft.freerouting.autoroute database has to be maintained outside the outoroute algorithm + * while changing items on rhe eu.mihosoft.freerouting.board. */ void set_maintaining_autoroute_database(boolean p_value) { @@ -1383,8 +1383,8 @@ public class RoutingBoard extends BasicBoard implements java.io.Serializable } /** - * Returns, if the autoroute database is maintained outside the outoroute algorithm - * while changing items on rhe board. + * Returns, if the eu.mihosoft.freerouting.autoroute database is maintained outside the outoroute algorithm + * while changing items on rhe eu.mihosoft.freerouting.board. */ boolean is_maintaining_autoroute_database() { diff --git a/src/main/java/eu/mihosoft/freerouting/board/SearchTreeManager.java b/src/main/java/eu/mihosoft/freerouting/board/SearchTreeManager.java index 03e3244..fd87ff0 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/SearchTreeManager.java +++ b/src/main/java/eu/mihosoft/freerouting/board/SearchTreeManager.java @@ -19,17 +19,17 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.LinkedList; import java.util.Iterator; -import datastructures.UndoableObjects; -import datastructures.ShapeTree; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.ShapeTree; -import geometry.planar.FortyfiveDegreeBoundingDirections; -import geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.FortyfiveDegreeBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.Polyline; /** * @@ -85,7 +85,7 @@ public class SearchTreeManager } /** - * Returns the default tree used in interactive routing. + * Returns the default tree used in eu.mihosoft.freerouting.interactive routing. */ public ShapeSearchTree get_default_tree() { @@ -229,7 +229,7 @@ public class SearchTreeManager } /** - * Clears all compensated trees used in the autoroute algorithm apart from the default tree. + * Clears all compensated trees used in the eu.mihosoft.freerouting.autoroute algorithm apart from the default tree. */ public void reset_compensated_trees() { @@ -255,7 +255,7 @@ public class SearchTreeManager { if (this.board == null) { - System.out.println("SearchtreeManager.remove_all_board_items: board is null"); + System.out.println("SearchtreeManager.remove_all_board_items: eu.mihosoft.freerouting.board is null"); return; } Iterator it = this.board.item_list.start_read_object(); @@ -274,7 +274,7 @@ public class SearchTreeManager { if (this.board == null) { - System.out.println("SearchtreeManager.insert_all_board_items: board is null"); + System.out.println("SearchtreeManager.insert_all_board_items: eu.mihosoft.freerouting.board is null"); return; } Iterator it = this.board.item_list.start_read_object(); diff --git a/src/main/java/eu/mihosoft/freerouting/board/SearchTreeObject.java b/src/main/java/eu/mihosoft/freerouting/board/SearchTreeObject.java index 3e0d587..3b996d2 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/SearchTreeObject.java +++ b/src/main/java/eu/mihosoft/freerouting/board/SearchTreeObject.java @@ -18,14 +18,14 @@ * Created on 10. Januar 2004, 10:08 */ -package board; +package eu.mihosoft.freerouting.board; /** - * Common ShapeSearchTree functionality for board.Items and autoroute.ExpansionRooms + * Common ShapeSearchTree functionality for eu.mihosoft.freerouting.board.Items and eu.mihosoft.freerouting.autoroute.ExpansionRooms * * @author Alfons Wirtz */ -public interface SearchTreeObject extends datastructures.ShapeTree.Storable +public interface SearchTreeObject extends eu.mihosoft.freerouting.datastructures.ShapeTree.Storable { /** * Returns true if this object is an obstacle to objects containing diff --git a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree.java b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree.java index 6849e13..94aed41 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree.java @@ -17,22 +17,22 @@ * * Created on 1. September 2004, 10:13 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.ConvexShape; -import geometry.planar.ShapeBoundingDirections; -import geometry.planar.IntOctagon; -import geometry.planar.Line; -import geometry.planar.LineSegment; -import geometry.planar.Polyline; -import geometry.planar.PolylineShape; -import geometry.planar.RegularTileShape; -import geometry.planar.Shape; -import geometry.planar.Side; -import geometry.planar.Simplex; -import geometry.planar.TileShape; -import geometry.planar.IntBox; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.ShapeBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.RegularTileShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Simplex; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.util.Collection; import java.util.Iterator; @@ -40,22 +40,22 @@ import java.util.LinkedList; import java.util.Set; import java.util.TreeSet; -import rules.ClearanceMatrix; +import eu.mihosoft.freerouting.rules.ClearanceMatrix; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; -import autoroute.IncompleteFreeSpaceExpansionRoom; -import autoroute.CompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.IncompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.CompleteFreeSpaceExpansionRoom; /** * * Elementary geometric search functions making direct use - * of the MinAreaTree in the package datastructures. + * of the MinAreaTree in the package eu.mihosoft.freerouting.datastructures. * * * @author Alfons Wirtz */ -public class ShapeSearchTree extends datastructures.MinAreaTree +public class ShapeSearchTree extends eu.mihosoft.freerouting.datastructures.MinAreaTree { /** @@ -398,13 +398,13 @@ public class ShapeSearchTree extends datastructures.MinAreaTree } if (p_tree_entries == null) { - System.out.println("board.ShapeSearchTree.overlaps: p_obstacle_entries is null"); + System.out.println("eu.mihosoft.freerouting.board.ShapeSearchTree.overlaps: p_obstacle_entries is null"); return; } RegularTileShape bounds = p_shape.bounding_shape(bounding_directions); if (bounds == null) { - System.out.println("board.ShapeSearchTree.overlaps: p_shape not bounded"); + System.out.println("eu.mihosoft.freerouting.board.ShapeSearchTree.overlaps: p_shape not bounded"); return; } Collection tmp_list = this.overlaps(bounds); @@ -472,14 +472,14 @@ public class ShapeSearchTree extends datastructures.MinAreaTree } if (p_obstacle_entries == null) { - System.out.println("board.ShapeSearchTree.overlaps_with_clearance: p_obstacle_entries is null"); + System.out.println("eu.mihosoft.freerouting.board.ShapeSearchTree.overlaps_with_clearance: p_obstacle_entries is null"); return; } ClearanceMatrix cl_matrix = board.rules.clearance_matrix; RegularTileShape bounds = p_shape.bounding_shape(bounding_directions); if (bounds == null) { - System.out.println("board.ShapeSearchTree.overlaps_with_clearance: p_shape is not bounded"); + System.out.println("eu.mihosoft.freerouting.board.ShapeSearchTree.overlaps_with_clearance: p_shape is not bounded"); bounds = board.get_bounding_box(); } int max_clearance = diff --git a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree45Degree.java b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree45Degree.java index 0905ac4..a94d79e 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree45Degree.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree45Degree.java @@ -18,21 +18,21 @@ * Created on 15. Juli 2007, 07:26 * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.LinkedList; -import geometry.planar.FortyfiveDegreeBoundingDirections; -import geometry.planar.TileShape; -import geometry.planar.Shape; -import geometry.planar.IntOctagon; -import geometry.planar.IntBox; -import geometry.planar.Side; -import geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.FortyfiveDegreeBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Line; -import autoroute.IncompleteFreeSpaceExpansionRoom; -import autoroute.CompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.IncompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.CompleteFreeSpaceExpansionRoom; /** * A special simple ShapeSearchtree, where the shapes are of class IntOctagon. diff --git a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree90Degree.java b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree90Degree.java index 551a99c..b5cad61 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree90Degree.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ShapeSearchTree90Degree.java @@ -19,19 +19,19 @@ * */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.LinkedList; -import geometry.planar.OrthogonalBoundingDirections; -import geometry.planar.TileShape; -import geometry.planar.Shape; -import geometry.planar.IntBox; -import geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.OrthogonalBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Polyline; -import autoroute.IncompleteFreeSpaceExpansionRoom; -import autoroute.CompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.IncompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.CompleteFreeSpaceExpansionRoom; /** * A special simple ShapeSearchtree, where the shapes are of class IntBox. diff --git a/src/main/java/eu/mihosoft/freerouting/board/ShapeTraceEntries.java b/src/main/java/eu/mihosoft/freerouting/board/ShapeTraceEntries.java index 09d3f60..7f18270 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ShapeTraceEntries.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ShapeTraceEntries.java @@ -14,14 +14,14 @@ * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.ConvexShape; -import geometry.planar.FloatPoint; -import geometry.planar.Line; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/board/ShoveTraceAlgo.java b/src/main/java/eu/mihosoft/freerouting/board/ShoveTraceAlgo.java index 2607ef3..d51f44d 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ShoveTraceAlgo.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ShoveTraceAlgo.java @@ -13,21 +13,21 @@ * GNU General Public License at * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.ConvexShape; -import geometry.planar.Direction; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.Line; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Vector; -import geometry.planar.Polyline; -import geometry.planar.TileShape; -import geometry.planar.LineSegment; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.LineSegment; import java.util.Collection; import java.util.Iterator; @@ -244,7 +244,7 @@ public class ShoveTraceAlgo FloatPoint end_corner_appprox = p_line_segment.end_point_approx(); double segment_length = end_corner_appprox.distance(start_corner_appprox); - rules.ClearanceMatrix cl_matrix = p_board.rules.clearance_matrix; + eu.mihosoft.freerouting.rules.ClearanceMatrix cl_matrix = p_board.rules.clearance_matrix; double result = Integer.MAX_VALUE; diff --git a/src/main/java/eu/mihosoft/freerouting/board/TestLevel.java b/src/main/java/eu/mihosoft/freerouting/board/TestLevel.java index e72de5a..a9d5a37 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/TestLevel.java +++ b/src/main/java/eu/mihosoft/freerouting/board/TestLevel.java @@ -19,7 +19,7 @@ * */ -package board; +package eu.mihosoft.freerouting.board; /** * If > RELEASE, some features may be used, which are still in experimental state. diff --git a/src/main/java/eu/mihosoft/freerouting/board/Trace.java b/src/main/java/eu/mihosoft/freerouting/board/Trace.java index 67bc1ba..58dc8b2 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Trace.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Trace.java @@ -14,12 +14,12 @@ * for more details. */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.FloatPoint; -import geometry.planar.IntOctagon; -import geometry.planar.Point; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; @@ -177,17 +177,17 @@ public abstract class Trace extends Item implements Connectable, java.io.Seriali } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_trace_colors(this.is_user_fixed()); } public int get_draw_priority() { - return boardgraphics.Drawable.MAX_DRAW_PRIORITY; + return eu.mihosoft.freerouting.boardgraphics.Drawable.MAX_DRAW_PRIORITY; } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_trace_color_intensity(); } @@ -316,10 +316,10 @@ public abstract class Trace extends Item implements Connectable, java.io.Seriali } // check, if the trace belongs to a net, which is not shovable. - rules.Nets nets = this.board.rules.nets; + eu.mihosoft.freerouting.rules.Nets nets = this.board.rules.nets; for (int curr_net_no : this.net_no_arr) { - if (rules.Nets.is_normal_net_no(curr_net_no)) + if (eu.mihosoft.freerouting.rules.Nets.is_normal_net_no(curr_net_no)) { if (nets.get(curr_net_no).get_class().is_shove_fixed()) { @@ -376,7 +376,7 @@ public abstract class Trace extends Item implements Connectable, java.io.Seriali boolean ignore_areas = false; if (this.net_no_arr.length > 0) { - rules.Net curr_net = this.board.rules.nets.get(this.net_no_arr[0]); + eu.mihosoft.freerouting.rules.Net curr_net = this.board.rules.nets.get(this.net_no_arr[0]); if (curr_net != null && curr_net.get_class() != null) { ignore_areas = curr_net.get_class().get_ignore_cycles_with_areas(); @@ -486,7 +486,7 @@ public abstract class Trace extends Item implements Connectable, java.io.Seriali public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("trace")); p_window.append(" " + resources.getString("from")); p_window.append(this.first_corner().to_float()); @@ -545,5 +545,5 @@ public abstract class Trace extends Item implements Connectable, java.io.Seriali private final int half_width ; // half width of the trace pen - private int layer ; // board layer of the trace + private int layer ; // eu.mihosoft.freerouting.board layer of the trace } diff --git a/src/main/java/eu/mihosoft/freerouting/board/Unit.java b/src/main/java/eu/mihosoft/freerouting/board/Unit.java index efc0618..9b2ab90 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Unit.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Unit.java @@ -18,7 +18,7 @@ * Created on 13. Dezember 2004, 08:01 */ -package board; +package eu.mihosoft.freerouting.board; /** * Enum for the userunits inch, mil or millimeter. diff --git a/src/main/java/eu/mihosoft/freerouting/board/Via.java b/src/main/java/eu/mihosoft/freerouting/board/Via.java index e406784..cc6caf2 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/Via.java +++ b/src/main/java/eu/mihosoft/freerouting/board/Via.java @@ -17,20 +17,20 @@ * * Created on 5. Juni 2003, 10:36 */ -package board; +package eu.mihosoft.freerouting.board; import java.util.Collection; import java.util.Iterator; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.TileShape; -import geometry.planar.Shape; -import geometry.planar.Vector; -import library.Padstack; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.library.Padstack; /** - * Class describing the functionality of an electrical Item on the board, + * Class describing the functionality of an electrical Item on the eu.mihosoft.freerouting.board, * which may have a shape on several layer, whose geometry is described by a * padstack. * @@ -164,14 +164,14 @@ public class Via extends DrillItem implements java.io.Serializable clear_derived_data(); } - public autoroute.ExpansionDrill get_autoroute_drill_info(ShapeSearchTree p_autoroute_tree) + public eu.mihosoft.freerouting.autoroute.ExpansionDrill get_autoroute_drill_info(ShapeSearchTree p_autoroute_tree) { if (this.autoroute_drill_info == null) { - autoroute.ItemAutorouteInfo via_autoroute_info = this.get_autoroute_info(); + eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo via_autoroute_info = this.get_autoroute_info(); TileShape curr_drill_shape = TileShape.get_instance(this.get_center()); this.autoroute_drill_info = - new autoroute.ExpansionDrill(curr_drill_shape, this.get_center(), this.first_layer(), this.last_layer()); + new eu.mihosoft.freerouting.autoroute.ExpansionDrill(curr_drill_shape, this.get_center(), this.first_layer(), this.last_layer()); int via_layer_count = this.last_layer() - this.first_layer() + 1; for (int i = 0; i < via_layer_count; ++i) { @@ -203,7 +203,7 @@ public class Via extends DrillItem implements java.io.Serializable return p_filter.is_selected(ItemSelectionFilter.SelectableChoices.VIAS); } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { java.awt.Color[] result; if (this.net_count() == 0) @@ -224,7 +224,7 @@ public class Via extends DrillItem implements java.io.Serializable return result; } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { double result; if (this.net_count() == 0) @@ -248,7 +248,7 @@ public class Via extends DrillItem implements java.io.Serializable public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("via")); p_window.append(" " + resources.getString("at")); p_window.append(this.get_center().to_float()); @@ -273,6 +273,6 @@ public class Via extends DrillItem implements java.io.Serializable /** True, if coppersharing of this via with smd pins of the same net is allowed. */ public final boolean attach_allowed; transient private Shape[] precalculated_shapes = null; - /** Temporary data used in the autoroute algorithm. */ - transient private autoroute.ExpansionDrill autoroute_drill_info = null; + /** Temporary data used in the eu.mihosoft.freerouting.autoroute algorithm. */ + transient private eu.mihosoft.freerouting.autoroute.ExpansionDrill autoroute_drill_info = null; } diff --git a/src/main/java/eu/mihosoft/freerouting/board/ViaObstacleArea.java b/src/main/java/eu/mihosoft/freerouting/board/ViaObstacleArea.java index 1298edd..27d76e7 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/ViaObstacleArea.java +++ b/src/main/java/eu/mihosoft/freerouting/board/ViaObstacleArea.java @@ -18,13 +18,13 @@ * Created on 19. August 2004, 07:34 */ -package board; +package eu.mihosoft.freerouting.board; -import geometry.planar.Area; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Vector; /** - * Describes Areas on the board, where vias are not allowed. + * Describes Areas on the eu.mihosoft.freerouting.board, where vias are not allowed. * * @author alfons */ @@ -85,7 +85,7 @@ public class ViaObstacleArea extends ObstacleArea public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("via_keepout")); this.print_shape_info(p_window, p_locale); this.print_clearance_info(p_window, p_locale); @@ -93,12 +93,12 @@ public class ViaObstacleArea extends ObstacleArea p_window.newline(); } - public java.awt.Color[] get_draw_colors(boardgraphics.GraphicsContext p_graphics_context) + public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_via_obstacle_colors(); } - public double get_draw_intensity(boardgraphics.GraphicsContext p_graphics_context) + public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context) { return p_graphics_context.get_via_obstacle_color_intensity(); } diff --git a/src/main/java/eu/mihosoft/freerouting/board/package.html b/src/main/java/eu/mihosoft/freerouting/board/package.html index 3b397ae..e0ece8b 100644 --- a/src/main/java/eu/mihosoft/freerouting/board/package.html +++ b/src/main/java/eu/mihosoft/freerouting/board/package.html @@ -17,17 +17,17 @@ --> - Contains classes describing items on a printed circuit board and the board itself. + Contains classes describing items on a printed circuit eu.mihosoft.freerouting.board and the eu.mihosoft.freerouting.board itself.

    -

    The class LayeredBoard implements elementary functionality for the layout of 2-dimensional items on a board. The board may have several layers.  It allows to insert, change, or delete items, or to check, if inserting would result in violations (overlaps) with other items. For fast checking, picking  and changing items  the class contains a 2-dimensional search tree, whose entries point into the list of items on the board.  The search tree  is decoupled from the items it is pointing to and may even point into several different databases at the same time.

    +

    The class LayeredBoard implements elementary functionality for the layout of 2-dimensional items on a eu.mihosoft.freerouting.board. The eu.mihosoft.freerouting.board may have several layers.  It allows to insert, change, or delete items, or to check, if inserting would result in violations (overlaps) with other items. For fast checking, picking  and changing items  the class contains a 2-dimensional search tree, whose entries point into the list of items on the eu.mihosoft.freerouting.board.  The search tree  is decoupled from the items it is pointing to and may even point into several different databases at the same time.

    LayeredBoard contains also a list of components, a library of packages and padstacks, and a collection of rules and restrictions, which must be respected by the items on the board.

    +EN-US"> contains also a list of components, a eu.mihosoft.freerouting.library of packages and padstacks, and a collection of rules and restrictions, which must be respected by the items on the eu.mihosoft.freerouting.board.

    The class RoutingBoard derived from BasicBoard contains higher level functionality, such as shoving items and pulling tight traces, and autorouting incomplete connections.

    -

    The base classes of all physical items on the board is the abstract class  Item. Items must implement the interfaces ShapeTree.Storable and Drawable, so that they can be stored in a search ree and painted onto a graphics screen. Additionally an item contains a pointer to the physical board the item is on, an id number and a list of numbers of nets it belongs to, which may be empty.

    -

    Classes derived from Item are currently Trace, DrillItem , ObstacleArea and BoardOutline. The class ObstacleArea describe areas on the board, which may be conduction areas or obstacle areas for traces or vias. The abstact class DrillItem describes items with a layer range, a centre point and a (convex) shape on each  layer. It has the two implementations Pin and Via. Pins belong to a component, and its shapes are defined by the padstack of the corresponding pin of the components library package. The shapes of a Via are defined directly by a library padstack. The class abstract Trace is used for paths connecting  drill items and eventual conduction areas. The only implementation of the class Trace is currently the class PolylineTrace.  It adds the concrete description of the geometric path as a Polyline to the class Trace. The reason, why Polylines and not Polygons are used to implement the paths of non-curved tracess, has to do with numerical exactness and performance, as described in the package geometry.planar.

    +

    The base classes of all physical items on the eu.mihosoft.freerouting.board is the abstract class  Item. Items must implement the interfaces ShapeTree.Storable and Drawable, so that they can be stored in a search ree and painted onto a graphics screen. Additionally an item contains a pointer to the physical eu.mihosoft.freerouting.board the item is on, an id number and a list of numbers of nets it belongs to, which may be empty.

    +

    Classes derived from Item are currently Trace, DrillItem , ObstacleArea and BoardOutline. The class ObstacleArea describe areas on the eu.mihosoft.freerouting.board, which may be conduction areas or obstacle areas for traces or vias. The abstact class DrillItem describes items with a layer range, a centre point and a (convex) shape on each  layer. It has the two implementations Pin and Via. Pins belong to a component, and its shapes are defined by the padstack of the corresponding pin of the components eu.mihosoft.freerouting.library package. The shapes of a Via are defined directly by a eu.mihosoft.freerouting.library padstack. The class abstract Trace is used for paths connecting  drill items and eventual conduction areas. The only implementation of the class Trace is currently the class PolylineTrace.  It adds the concrete description of the geometric path as a Polyline to the class Trace. The reason, why Polylines and not Polygons are used to implement the paths of non-curved tracess, has to do with numerical exactness and performance, as described in the package eu.mihosoft.freerouting.geometry.planar.

    Items, which may be electrically connected must implement the interface Connectable. Connectable Items are currently Pins, Vias, Traces and ConductionAreas.

    diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorIntensityTable.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorIntensityTable.java index 654d11a..280c472 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorIntensityTable.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorIntensityTable.java @@ -18,7 +18,7 @@ * Created on 1. August 2004, 07:46 */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; /** * The color intensities for each item type. diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorTableModel.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorTableModel.java index 67d1b23..4b9787e 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorTableModel.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ColorTableModel.java @@ -17,12 +17,12 @@ * * Created on 5. August 2003, 10:18 */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; import javax.swing.table.AbstractTableModel; /** - * Abstract class to store colors used for drawing the board. + * Abstract class to store colors used for drawing the eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/CoordinateTransform.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/CoordinateTransform.java index 73afc79..bf5d844 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/CoordinateTransform.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/CoordinateTransform.java @@ -14,17 +14,17 @@ * for more details. */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.Limits; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.Limits; import java.awt.Dimension; import java.awt.geom.Point2D; /** - * Transformation function between the board and the screen coordinate systems. + * Transformation function between the eu.mihosoft.freerouting.board and the screen coordinate systems. * * @author Alfons Wirtz */ @@ -76,7 +76,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * scale a value from the board to the screen coordinate system + * scale a value from the eu.mihosoft.freerouting.board to the screen coordinate system */ public double board_to_screen(double p_val) { @@ -84,7 +84,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * scale a value the screen to the board coordinate system + * scale a value the screen to the eu.mihosoft.freerouting.board coordinate system */ public double screen_to_board(double p_val) { @@ -93,7 +93,7 @@ public class CoordinateTransform implements java.io.Serializable /** - * transform a geometry.planar.FloatPoint to a java.awt.geom.Point2D + * transform a eu.mihosoft.freerouting.geometry.planar.FloatPoint to a java.awt.geom.Point2D */ public Point2D board_to_screen(FloatPoint p_point) { @@ -120,7 +120,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Transform a java.awt.geom.Point2D to a geometry.planar.FloatPoint + * Transform a java.awt.geom.Point2D to a eu.mihosoft.freerouting.geometry.planar.FloatPoint */ public FloatPoint screen_to_board(Point2D p_point) { @@ -146,7 +146,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Transforms an angle in radian on the board to an angle on the screen. + * Transforms an angle in radian on the eu.mihosoft.freerouting.board to an angle on the screen. */ public double board_to_screen_angle(double p_angle) { @@ -171,7 +171,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Transform a geometry.planar.IntBox to a java.awt.Rectangle + * Transform a eu.mihosoft.freerouting.geometry.planar.IntBox to a java.awt.Rectangle * If the internal rotation is not a multiple of Pi/2, a bounding rectangle of the * rotated rectangular shape is returned. */ @@ -190,7 +190,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Transform a java.awt.Rectangle to a geometry.planar.IntBox + * Transform a java.awt.Rectangle to a eu.mihosoft.freerouting.geometry.planar.IntBox * If the internal rotation is not a multiple of Pi/2, a bounding box of the * rotated rectangular shape is returned. */ @@ -207,7 +207,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * If p_value is true, the left side and the right side of the board will be swapped. + * If p_value is true, the left side and the right side of the eu.mihosoft.freerouting.board will be swapped. */ public void set_mirror_left_right(boolean p_value) { @@ -215,7 +215,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Returns, if the left side and the right side of the board are swapped. + * Returns, if the left side and the right side of the eu.mihosoft.freerouting.board are swapped. */ public boolean is_mirror_left_right() { @@ -223,7 +223,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * If p_value is true, the top side and the botton side of the board will be swapped. + * If p_value is true, the top side and the botton side of the eu.mihosoft.freerouting.board will be swapped. */ public void set_mirror_top_bottom(boolean p_value) { @@ -233,7 +233,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Returns, if the top side and the botton side of the board are swapped. + * Returns, if the top side and the botton side of the eu.mihosoft.freerouting.board are swapped. */ public boolean is_mirror_top_bottom() { @@ -243,7 +243,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Sets the rotation of the displayed board to p_value. + * Sets the rotation of the displayed eu.mihosoft.freerouting.board to p_value. */ public void set_rotation(double p_value) { @@ -251,7 +251,7 @@ public class CoordinateTransform implements java.io.Serializable } /** - * Returns the rotation of the displayed board. + * Returns the rotation of the displayed eu.mihosoft.freerouting.board. */ public double get_rotation() { @@ -284,12 +284,12 @@ public class CoordinateTransform implements java.io.Serializable private final double display_y_offset; /** - * Left side and right side of the board are swapped. + * Left side and right side of the eu.mihosoft.freerouting.board are swapped. */ private boolean mirror_left_right = false; /** - * Top side and bottom side of the board are swapped. + * Top side and bottom side of the eu.mihosoft.freerouting.board are swapped. */ private boolean mirror_top_bottom = true; diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/Drawable.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/Drawable.java index b354703..20f408b 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/Drawable.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/Drawable.java @@ -14,7 +14,7 @@ * for more details. */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; import java.awt.Color; import java.awt.Graphics; diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/GraphicsContext.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/GraphicsContext.java index e56677e..cf831de 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/GraphicsContext.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/GraphicsContext.java @@ -270,7 +270,7 @@ public class GraphicsContext implements java.io.Serializable } Point2D center = coordinate_transform.board_to_screen(p_circle.center.to_float()); double radius = coordinate_transform.board_to_screen(p_circle.radius); - if (!point_near_rectangle(center.getX(), center.getY(), (Rectangle)p_g.getClip(), radius)) + if (!point_near_rectangle(center.getX(), center.getY(), p_g.getClip().getBounds(), radius)) { return; } diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemColorTableModel.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemColorTableModel.java index 49110a6..3a78738 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemColorTableModel.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemColorTableModel.java @@ -18,19 +18,19 @@ * Created on 4. August 2003, 08:26 */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; import java.awt.Color; /** - * Stores the layer dependent colors used for drawing for the items on the board. + * Stores the layer dependent colors used for drawing for the items on the eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ public class ItemColorTableModel extends ColorTableModel implements java.io.Serializable { - public ItemColorTableModel(board.LayerStructure p_layer_structure, java.util.Locale p_locale) + public ItemColorTableModel(eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, java.util.Locale p_locale) { super(p_layer_structure.arr.length, p_locale); @@ -143,7 +143,7 @@ public class ItemColorTableModel extends ColorTableModel implements java.io.Seri public String getColumnName(int p_col) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("boardgraphics.resources.ColorTableModel", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.boardgraphics.resources.ColorTableModel", this.locale); return resources.getString(ColumnNames.values()[p_col].toString()); } diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemDrawInfo.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemDrawInfo.java index 364b8dd..9ed487e 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemDrawInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/ItemDrawInfo.java @@ -18,7 +18,7 @@ * Created on 14. Juli 2004, 10:26 */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; import java.awt.Color; diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/OtherColorTableModel.java b/src/main/java/eu/mihosoft/freerouting/boardgraphics/OtherColorTableModel.java index a6c4f1d..e7bc07a 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/OtherColorTableModel.java +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/OtherColorTableModel.java @@ -18,7 +18,7 @@ * Created on 5. August 2003, 07:39 */ -package boardgraphics; +package eu.mihosoft.freerouting.boardgraphics; import java.awt.Color; @@ -73,7 +73,7 @@ public class OtherColorTableModel extends ColorTableModel implements java.io.Ser public String getColumnName(int p_col) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("boardgraphics.resources.ColorTableModel", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.boardgraphics.resources.ColorTableModel", this.locale); return resources.getString(ColumnNames.values()[p_col].toString()); } diff --git a/src/main/java/eu/mihosoft/freerouting/boardgraphics/package.html b/src/main/java/eu/mihosoft/freerouting/boardgraphics/package.html index 0867456..ec6d4f5 100644 --- a/src/main/java/eu/mihosoft/freerouting/boardgraphics/package.html +++ b/src/main/java/eu/mihosoft/freerouting/boardgraphics/package.html @@ -16,4 +16,4 @@ --> -Contains user interface independent functionality for displaying a board on a sccreen. \ No newline at end of file +Contains user interface independent functionality for displaying a eu.mihosoft.freerouting.board on a sccreen. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/ArrayStack.java b/src/main/java/eu/mihosoft/freerouting/datastructures/ArrayStack.java index 5874e96..73c89ce 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/ArrayStack.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/ArrayStack.java @@ -19,7 +19,7 @@ * */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; @SuppressWarnings("unchecked") diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/BigIntAux.java b/src/main/java/eu/mihosoft/freerouting/datastructures/BigIntAux.java index 6a70450..994e68f 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/BigIntAux.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/BigIntAux.java @@ -9,7 +9,7 @@ * Created on 5. January 2003, 11:26 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; import java.math.BigInteger; diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/FileFilter.java b/src/main/java/eu/mihosoft/freerouting/datastructures/FileFilter.java index 9c0a70c..a9c3975 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/FileFilter.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/FileFilter.java @@ -18,7 +18,7 @@ * Created on 31. Mai 2004, 09:23 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Used in the file chooser to filter all files which do not have an extension from the input array. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/IdNoGenerator.java b/src/main/java/eu/mihosoft/freerouting/datastructures/IdNoGenerator.java index 677f790..5d724a5 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/IdNoGenerator.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/IdNoGenerator.java @@ -18,7 +18,7 @@ * Created on 13. Februar 2005, 08:21 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Interface for creatiing unique identification number. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/IdentifierType.java b/src/main/java/eu/mihosoft/freerouting/datastructures/IdentifierType.java index bbb524d..895881b 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/IdentifierType.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/IdentifierType.java @@ -18,7 +18,7 @@ * Created on 25. Januar 2005, 09:50 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; import java.io.OutputStreamWriter; diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/IndentFileWriter.java b/src/main/java/eu/mihosoft/freerouting/datastructures/IndentFileWriter.java index 8f01d43..2c8f571 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/IndentFileWriter.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/IndentFileWriter.java @@ -18,7 +18,7 @@ * Created on 21. Juni 2004, 09:36 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Handles the indenting of scopes while writing to an output text file. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/MinAreaTree.java b/src/main/java/eu/mihosoft/freerouting/datastructures/MinAreaTree.java index 92932a6..b4b12a5 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/MinAreaTree.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/MinAreaTree.java @@ -18,13 +18,13 @@ * Created on 1. September 2004, 08:29 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; import java.util.Set; import java.util.TreeSet; -import geometry.planar.ShapeBoundingDirections; -import geometry.planar.RegularTileShape; +import eu.mihosoft.freerouting.geometry.planar.ShapeBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.RegularTileShape; /** * Binary search tree for shapes in the plane. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/Observers.java b/src/main/java/eu/mihosoft/freerouting/datastructures/Observers.java index 5ef1bed..0e50c16 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/Observers.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/Observers.java @@ -18,7 +18,7 @@ * Created on 13. Februar 2005, 09:14 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Interface to observe changes on objects for syncronisatiation purposes. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/PlanarDelaunayTriangulation.java b/src/main/java/eu/mihosoft/freerouting/datastructures/PlanarDelaunayTriangulation.java index ce76d8c..5e22a33 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/PlanarDelaunayTriangulation.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/PlanarDelaunayTriangulation.java @@ -18,7 +18,7 @@ * Created on 8. Januar 2005, 10:12 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; import java.util.Collection; import java.util.Collections; @@ -27,10 +27,10 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; -import geometry.planar.Point; -import geometry.planar.IntPoint; -import geometry.planar.Side; -import geometry.planar.Limits; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.Limits; /** * Creates a Delaunay triangulation in the plane for the input objects. @@ -349,7 +349,7 @@ public class PlanarDelaunayTriangulation /** * Returns an array of corners, which can be used in a planar triangulation. */ - geometry.planar.Point[] get_triangulation_corners(); + eu.mihosoft.freerouting.geometry.planar.Point[] get_triangulation_corners(); } /** diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/ShapeTree.java b/src/main/java/eu/mihosoft/freerouting/datastructures/ShapeTree.java index 07078ec..7878861 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/ShapeTree.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/ShapeTree.java @@ -18,12 +18,12 @@ * Created on 1. September 2004, 10:50 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; -import geometry.planar.ShapeBoundingDirections; -import geometry.planar.RegularTileShape; -import geometry.planar.Shape; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.ShapeBoundingDirections; +import eu.mihosoft.freerouting.geometry.planar.RegularTileShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; /** * Abstract binary search tree for shapes in the plane. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/Signum.java b/src/main/java/eu/mihosoft/freerouting/datastructures/Signum.java index 2eecd99..bfd61d1 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/Signum.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/Signum.java @@ -14,7 +14,7 @@ * for more details. */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/Stoppable.java b/src/main/java/eu/mihosoft/freerouting/datastructures/Stoppable.java index e63a0b8..4e1f3e5 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/Stoppable.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/Stoppable.java @@ -19,7 +19,7 @@ * */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Interface for stoppable threads. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/TimeLimit.java b/src/main/java/eu/mihosoft/freerouting/datastructures/TimeLimit.java index a4bdf14..09dc970 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/TimeLimit.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/TimeLimit.java @@ -19,7 +19,7 @@ * */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; /** * Class used to cancel a performance critical algorithm after a time limit is exceeded. diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/UndoableObjects.java b/src/main/java/eu/mihosoft/freerouting/datastructures/UndoableObjects.java index 23e7f97..26a76dd 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/UndoableObjects.java +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/UndoableObjects.java @@ -17,7 +17,7 @@ * * Created on 24. August 2003, 06:41 */ -package datastructures; +package eu.mihosoft.freerouting.datastructures; import java.util.Collection; import java.util.Iterator; @@ -246,7 +246,7 @@ public class UndoableObjects implements java.io.Serializable } if (p_restored_objects == null || !p_restored_objects.remove(curr_deleted_node.object)) { - // the object needs only be cancelled if it is already in the board + // the object needs only be cancelled if it is already in the eu.mihosoft.freerouting.board if (p_cancelled_objects != null) { p_cancelled_objects.add(curr_deleted_node.object); diff --git a/src/main/java/eu/mihosoft/freerouting/datastructures/package.html b/src/main/java/eu/mihosoft/freerouting/datastructures/package.html index ac85df0..205a388 100644 --- a/src/main/java/eu/mihosoft/freerouting/datastructures/package.html +++ b/src/main/java/eu/mihosoft/freerouting/datastructures/package.html @@ -17,5 +17,5 @@ --> - Contains general purpose datastructures. + Contains general purpose eu.mihosoft.freerouting.datastructures. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/AutorouteSettings.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/AutorouteSettings.java new file mode 100644 index 0000000..1c7c7ef --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/AutorouteSettings.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * AutorouteSettings.java + * + * Created on 1. Maerz 2007, 07:10 + * + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * + * @author Alfons Wirtz + */ +public class AutorouteSettings +{ + + static eu.mihosoft.freerouting.interactive.AutorouteSettings read_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + eu.mihosoft.freerouting.interactive.AutorouteSettings result = new eu.mihosoft.freerouting.interactive.AutorouteSettings(p_layer_structure.arr.length); + boolean with_fanout = false; + boolean with_autoroute = true; + boolean with_postroute = true; + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("AutorouteSettings.read_scope: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("AutorouteSettings.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.FANOUT) + { + with_fanout = DsnFile.read_on_off_scope(p_scanner); + } + else if (next_token == Keyword.AUTOROUTE) + { + with_autoroute = DsnFile.read_on_off_scope(p_scanner); + } + else if (next_token == Keyword.POSTROUTE) + { + with_postroute = DsnFile.read_on_off_scope(p_scanner); + } + else if (next_token == Keyword.VIAS) + { + result.set_vias_allowed(DsnFile.read_on_off_scope(p_scanner)); + } + else if (next_token == Keyword.VIA_COSTS) + { + result.set_via_costs(DsnFile.read_integer_scope(p_scanner)); + } + else if (next_token == Keyword.PLANE_VIA_COSTS) + { + result.set_plane_via_costs(DsnFile.read_integer_scope(p_scanner)); + } + else if (next_token == Keyword.START_RIPUP_COSTS) + { + result.set_start_ripup_costs(DsnFile.read_integer_scope(p_scanner)); + } + else if (next_token == Keyword.START_PASS_NO) + { + result.set_pass_no(DsnFile.read_integer_scope(p_scanner)); + } + else if (next_token == Keyword.LAYER_RULE) + { + result = read_layer_rule(p_scanner, p_layer_structure, result); + if (result == null) + { + return null; + } + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + } + result.set_with_fanout(with_fanout); + result.set_with_autoroute(with_autoroute); + result.set_with_postroute(with_postroute); + return result; + } + + static eu.mihosoft.freerouting.interactive.AutorouteSettings read_layer_rule(Scanner p_scanner, LayerStructure p_layer_structure, + eu.mihosoft.freerouting.interactive.AutorouteSettings p_settings) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("AutorouteSettings.read_layer_rule: IO error scanning file"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("AutorouteSettings.read_layer_rule: String expected"); + return null; + } + int layer_no = p_layer_structure.get_no((String) next_token); + if (layer_no < 0) + { + System.out.println("AutorouteSettings.read_layer_rule: layer not found"); + return null; + } + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("AutorouteSettings.read_layer_rule: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("AutorouteSettings.read_layer_rule: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.ACTIVE) + { + p_settings.set_layer_active(layer_no, DsnFile.read_on_off_scope(p_scanner)); + } + else if (next_token == Keyword.PREFERRED_DIRECTION) + { + try + { + boolean pref_dir_is_horizontal = true; + next_token = p_scanner.next_token(); + if (next_token == Keyword.VERTICAL) + { + pref_dir_is_horizontal = false; + } + else if (next_token != Keyword.HORIZONTAL) + { + System.out.println("AutorouteSettings.read_layer_rule: unexpected key word"); + return null; + } + p_settings.set_preferred_direction_is_horizontal(layer_no, pref_dir_is_horizontal); + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("AutorouteSettings.read_layer_rule: uclosing bracket expected"); + return null; + } + } catch (java.io.IOException e) + { + System.out.println("AutorouteSettings.read_layer_rule: IO error scanning file"); + return null; + } + } + else if (next_token == Keyword.PREFERRED_DIRECTION_TRACE_COSTS) + { + p_settings.set_preferred_direction_trace_costs(layer_no, DsnFile.read_float_scope(p_scanner)); + } + else if (next_token == Keyword.AGAINST_PREFERRED_DIRECTION_TRACE_COSTS) + { + p_settings.set_against_preferred_direction_trace_costs(layer_no, DsnFile.read_float_scope(p_scanner)); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + } + return p_settings; + } + + static void write_scope(IndentFileWriter p_file, eu.mihosoft.freerouting.interactive.AutorouteSettings p_settings, + eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("autoroute_settings"); + p_file.new_line(); + p_file.write("(fanout "); + if (p_settings.get_with_fanout()) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.new_line(); + p_file.write("(eu.mihosoft.freerouting.autoroute "); + if (p_settings.get_with_autoroute()) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.new_line(); + p_file.write("(postroute "); + if (p_settings.get_with_postroute()) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.new_line(); + p_file.write("(vias "); + if (p_settings.get_vias_allowed()) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.new_line(); + p_file.write("(via_costs "); + { + Integer via_costs = p_settings.get_via_costs(); + p_file.write(via_costs.toString()); + } + p_file.write(")"); + p_file.new_line(); + p_file.write("(plane_via_costs "); + { + Integer via_costs = p_settings.get_plane_via_costs(); + p_file.write(via_costs.toString()); + } + p_file.write(")"); + p_file.new_line(); + p_file.write("(start_ripup_costs "); + { + Integer ripup_costs = p_settings.get_start_ripup_costs(); + p_file.write(ripup_costs.toString()); + } + p_file.write(")"); + p_file.new_line(); + p_file.write("(start_pass_no "); + { + Integer pass_no = p_settings.get_pass_no(); + p_file.write(pass_no.toString()); + } + p_file.write(")"); + for (int i = 0; i < p_layer_structure.arr.length; ++i) + { + eu.mihosoft.freerouting.board.Layer curr_layer = p_layer_structure.arr[i]; + p_file.start_scope(); + p_file.write("layer_rule "); + p_identifier_type.write(curr_layer.name, p_file); + p_file.new_line(); + p_file.write("(active "); + if (p_settings.get_layer_active(i)) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.new_line(); + p_file.write("(preferred_direction "); + if (p_settings.get_preferred_direction_is_horizontal(i)) + { + p_file.write("horizontal)"); + } + else + { + p_file.write("vertical)"); + } + p_file.new_line(); + p_file.write("(preferred_direction_trace_costs "); + Float trace_costs = (float) p_settings.get_preferred_direction_trace_costs(i); + p_file.write(trace_costs.toString()); + p_file.write(")"); + p_file.new_line(); + p_file.write("(against_preferred_direction_trace_costs "); + trace_costs = (float) p_settings.get_against_preferred_direction_trace_costs(i); + p_file.write(trace_costs.toString()); + p_file.write(")"); + p_file.end_scope(); + } + p_file.end_scope(); + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circle.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circle.java new file mode 100644 index 0000000..8f92847 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circle.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Circle.java + * + * Created on 20. Mai 2004, 09:22 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Class for reading and writing circle scopes from dsn-files. + * + * @author alfons + */ +public class Circle extends Shape +{ + /** + * Creates a new circle from the input parameters. + * p_coor is an array of dimension 3. + * p_coor [0] is the radius of the circle, + * p_coor [1] is the x coordinate of the circle, + * p_coor [2] is the y coordinate of the circle. + */ + public Circle(Layer p_layer, double [] p_coor) + { + super(p_layer); + coor = p_coor; + } + + public Circle(Layer p_layer, double p_radius, double p_center_x, double p_center_y) + { + super(p_layer); + coor = new double[3]; + coor[0] = p_radius; + coor[1] = p_center_x; + coor[2] = p_center_y; + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform) + { + double [] location = new double[2]; + location[0] = coor[1]; + location[1] = coor[2]; + IntPoint center = p_coordinate_transform.dsn_to_board(location).round(); + int radius = (int) Math.round(p_coordinate_transform.dsn_to_board(coor[0]) / 2); + return new eu.mihosoft.freerouting.geometry.planar.Circle(center, radius); + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform) + { + int [] new_coor = new int[3]; + new_coor[0] = (int) Math.round(p_coordinate_transform.dsn_to_board(coor[0]) / 2); + for (int i = 1; i < 3; ++i) + { + new_coor[i] = (int) Math.round(p_coordinate_transform.dsn_to_board(coor[i])); + } + return new eu.mihosoft.freerouting.geometry.planar.Circle(new IntPoint(new_coor[1], new_coor[2]), new_coor[0]); + } + + public Rectangle bounding_box() + { + double[] bounds = new double[4]; + bounds[0] = coor[1] - coor[0]; + bounds[1] = coor[2] - coor[0]; + bounds[2] = coor[1] + coor[0]; + bounds[3] = coor[2] + coor[0]; + return new Rectangle(layer, bounds); + } + + public void write_scope(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(circle "); + p_identifier_type.write(this.layer.name, p_file); + for (int i = 0; i < coor.length; ++i) + { + p_file.write(" "); + p_file.write(new Double(coor[i]).toString()); + } + p_file.write(")"); + } + + public void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(circle "); + p_identifier_type.write(this.layer.name, p_file); + for (int i = 0; i < coor.length; ++i) + { + p_file.write(" "); + Integer curr_coor = (int) Math.round(coor[i]); + p_file.write(curr_coor.toString()); + } + p_file.write(")"); + } + + public final double[] coor; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circuit.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circuit.java new file mode 100644 index 0000000..b46b0e4 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Circuit.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Circuit.java + * + * Created on 30. Mai 2005, 06:30 + * + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * + * @author Alfons Wirtz + */ +public class Circuit +{ + /** + * Currently only the length matching rule is read from a circuit scope. + * If the scope does not contain a length matching rule, nulll is returned. + */ + public static ReadScopeResult read_scope( Scanner p_scanner) + { + Object next_token = null; + double min_trace_length = 0; + double max_trace_length = 0; + java.util.Collection use_via = new java.util.LinkedList(); + java.util.Collection use_layer = new java.util.LinkedList(); + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Circuit.read_scope: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("Circuit.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.LENGTH) + { + LengthMatchingRule length_rule = read_length_scope(p_scanner); + if (length_rule != null) + { + min_trace_length = length_rule.min_length; + max_trace_length = length_rule.max_length; + } + } + else if (next_token == Keyword.USE_VIA) + { + use_via.addAll(Structure.read_via_padstacks(p_scanner)); + } + else if (next_token == Keyword.USE_LAYER) + { + use_layer.addAll(DsnFile.read_string_list_scope(p_scanner)); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + } + return new ReadScopeResult(max_trace_length, min_trace_length, use_via, use_layer); + } + + static LengthMatchingRule read_length_scope( Scanner p_scanner) + { + LengthMatchingRule result = null; + double[] length_arr = new double[2]; + Object next_token = null; + for (int i = 0; i < 2; ++i) + { + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Circuit.read_length_scope: IO error scanning file"); + return null; + } + if (next_token instanceof Double) + { + length_arr[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + length_arr[i] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Circuit.read_length_scope: number expected"); + return null; + } + } + result = new LengthMatchingRule(length_arr[0], length_arr[1]); + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Circuit.read_length_scope: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("Circuit.read_length_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + ScopeKeyword.skip_scope(p_scanner); + } + } + return result; + } + + /** A max_length of -1 indicates, tha no maximum length is defined. */ + public static class ReadScopeResult + { + public ReadScopeResult(double p_max_length, double p_min_length, java.util.Collection p_use_via, java.util.Collection p_use_layer) + { + max_length = p_max_length; + min_length = p_min_length; + use_via = p_use_via; + use_layer = p_use_layer; + } + + public final double max_length; + public final double min_length; + public final java.util.Collection use_via; + public final java.util.Collection use_layer; + } + + /** A max_length of -1 indicates, tha no maximum length is defined. */ + private static class LengthMatchingRule + { + public LengthMatchingRule(double p_max_length, double p_min_length) + { + max_length = p_max_length; + min_length = p_min_length; + } + + public final double max_length; + public final double min_length; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Component.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Component.java new file mode 100644 index 0000000..ab78c96 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Component.java @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Component.java + * + * Created on 20. Mai 2004, 07:32 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + + +/** + * Handels the placement bata of a eu.mihosoft.freerouting.library component. + * + * @author alfons + */ +public class Component extends ScopeKeyword +{ + + /** Creates a new instance of Component */ + public Component() + { + super("component"); + } + + /** + * Overwrites the function read_scope in ScopeKeyword + */ + public boolean read_scope(ReadScopeParameter p_par) + { + try + { + ComponentPlacement component_placement = read_scope(p_par.scanner); + if(component_placement == null) + { + return false; + } + p_par.placement_list.add(component_placement); + } + catch (java.io.IOException e) + { + System.out.println("Component.read_scope: IO error scanning file"); + return false; + } + return true; + } + + /** + * Used also when reading a session file. + */ + public static ComponentPlacement read_scope(Scanner p_scanner) throws java.io.IOException + { + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Component.read_scope: component name expected"); + return null; + } + String name = (String) next_token; + ComponentPlacement component_placement = new ComponentPlacement(name); + Object prev_token = next_token; + next_token = p_scanner.next_token(); + while ( next_token != CLOSED_BRACKET) + { + if (prev_token == OPEN_BRACKET && next_token == PLACE) + { + ComponentPlacement.ComponentLocation next_location = read_place_scope(p_scanner); + if (next_location != null) + { + component_placement.locations.add(next_location); + } + } + prev_token = next_token; + next_token = p_scanner.next_token(); + } + return component_placement; + } + + public static void write_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.Component p_component) + throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("place "); + p_par.file.new_line(); + p_par.identifier_type.write(p_component.name, p_par.file); + if (p_component.is_placed()) + { + double [] coor = p_par.coordinate_transform.board_to_dsn(p_component.get_location().to_float()); + for (int i = 0; i < coor.length; ++i) + { + p_par.file.write(" "); + p_par.file.write((new Double(coor[i])).toString()); + } + if (p_component.placed_on_front()) + { + p_par.file.write(" front "); + } + else + { + p_par.file.write(" back "); + } + int rotation = (int) Math.round(p_component.get_rotation_in_degree()); + p_par.file.write((new Integer(rotation).toString())); + } + if (p_component.position_fixed) + { + p_par.file.new_line(); + p_par.file.write(" (lock_type position)"); + } + int pin_count = p_component.get_package().pin_count(); + for (int i = 0; i < pin_count; ++i) + { + write_pin_info(p_par, p_component, i); + } + write_keepout_infos(p_par, p_component); + p_par.file.end_scope(); + } + + private static void write_pin_info(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.Component p_component, int p_pin_no) + throws java.io.IOException + { + if (!p_component.is_placed()) + { + return; + } + eu.mihosoft.freerouting.library.Package.Pin package_pin = p_component.get_package().get_pin(p_pin_no); + if (package_pin == null) + { + System.out.println("Component.write_pin_info: package pin not found"); + return; + } + eu.mihosoft.freerouting.board.Pin component_pin = p_par.board.get_pin(p_component.no, p_pin_no); + if (component_pin == null) + { + System.out.println("Component.write_pin_info: component pin not found"); + return; + } + String cl_class_name = p_par.board.rules.clearance_matrix.get_name(component_pin.clearance_class_no()); + if (cl_class_name == null) + { + System.out.println("Component.write_pin_info: clearance class name not found"); + return; + } + p_par.file.new_line(); + p_par.file.write("(pin "); + p_par.identifier_type.write(package_pin.name, p_par.file); + p_par.file.write(" (clearance_class "); + p_par.identifier_type.write(cl_class_name, p_par.file); + p_par.file.write("))"); + } + + private static void write_keepout_infos(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.Component p_component) + throws java.io.IOException + { + if (!p_component.is_placed()) + { + return; + } + eu.mihosoft.freerouting.library.Package.Keepout[] curr_keepout_arr; + String keepout_type; + for (int j = 0; j < 3; ++j) + { + if (j == 0) + { + curr_keepout_arr = p_component.get_package().keepout_arr; + keepout_type = "(keepout "; + } + else if (j == 1) + { + curr_keepout_arr = p_component.get_package().via_keepout_arr; + keepout_type = "(via_keepout "; + } + else + { + curr_keepout_arr = p_component.get_package().place_keepout_arr; + keepout_type = "(place_keepout "; + } + for (int i = 0; i < curr_keepout_arr.length; ++i) + { + eu.mihosoft.freerouting.library.Package.Keepout curr_keepout = curr_keepout_arr[i]; + eu.mihosoft.freerouting.board.ObstacleArea curr_obstacle_area = get_keepout(p_par.board, p_component.no, curr_keepout.name); + if (curr_obstacle_area == null || curr_obstacle_area.clearance_class_no() == 0) + { + continue; + } + String cl_class_name = p_par.board.rules.clearance_matrix.get_name(curr_obstacle_area.clearance_class_no()); + if (cl_class_name == null) + { + System.out.println("Component.write_keepout_infos: clearance class name not found"); + return; + } + p_par.file.new_line(); + p_par.file.write(keepout_type); + p_par.identifier_type.write(curr_keepout.name, p_par.file); + p_par.file.write(" (clearance_class "); + p_par.identifier_type.write(cl_class_name, p_par.file); + p_par.file.write("))"); + } + } + } + + private static eu.mihosoft.freerouting.board.ObstacleArea get_keepout(eu.mihosoft.freerouting.board.BasicBoard p_board, int p_component_no, String p_name) + { + java.util.Iterator it = p_board.item_list.start_read_object(); + for(;;) + { + eu.mihosoft.freerouting.board.Item curr_item = (eu.mihosoft.freerouting.board.Item)p_board.item_list.read_object(it); + if (curr_item == null) + { + break; + } + if (curr_item.get_component_no() == p_component_no && curr_item instanceof eu.mihosoft.freerouting.board.ObstacleArea) + { + eu.mihosoft.freerouting.board.ObstacleArea curr_area = (eu.mihosoft.freerouting.board.ObstacleArea) curr_item; + if (curr_area.name != null && curr_area.name.equals(p_name)) + { + return curr_area; + } + } + } + return null; + } + + + + private static ComponentPlacement.ComponentLocation read_place_scope(Scanner p_scanner) + { + try + { + java.util.Map pin_infos = + new java.util.TreeMap(); + java.util.Map keepout_infos = + new java.util.TreeMap(); + java.util.Map via_keepout_infos = + new java.util.TreeMap(); + java.util.Map place_keepout_infos = + new java.util.TreeMap(); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Component.read_place_scope: String expected"); + return null; + } + String name = (String) next_token; + double[] location = new double[2]; + for (int i = 0; i < 2; ++i) + { + next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + location[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + location[i] = ((Integer) next_token).intValue(); + } + else if (next_token == CLOSED_BRACKET) + { + // component is not yet placed + return new ComponentPlacement.ComponentLocation(name, null, true, 0, false, pin_infos, + keepout_infos, via_keepout_infos, place_keepout_infos); + } + else + { + System.out.println("Component.read_place_scope: number expected"); + return null; + } + } + next_token = p_scanner.next_token(); + boolean is_front = true; + if (next_token == BACK) + { + is_front = false; + } + else if (next_token != FRONT) + { + System.out.println("Component.read_place_scope: Keyword.FRONT expected"); + } + double rotation; + next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + rotation = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + rotation = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Component.read_place_scope: number expected"); + return null; + } + boolean position_fixed = false; + next_token = p_scanner.next_token(); + while (next_token == OPEN_BRACKET) + { + next_token = p_scanner.next_token(); + if (next_token == LOCK_TYPE) + { + position_fixed = read_lock_type(p_scanner); + } + else if (next_token == PIN) + { + ComponentPlacement.ItemClearanceInfo curr_pin_info = read_item_clearance_info(p_scanner); + if (curr_pin_info == null) + { + return null; + } + pin_infos.put(curr_pin_info.name, curr_pin_info); + } + else if (next_token == KEEPOUT) + { + ComponentPlacement.ItemClearanceInfo curr_keepout_info = read_item_clearance_info(p_scanner); + if (curr_keepout_info == null) + { + return null; + } + keepout_infos.put(curr_keepout_info.name, curr_keepout_info); + } + else if (next_token == VIA_KEEPOUT) + { + ComponentPlacement.ItemClearanceInfo curr_keepout_info = read_item_clearance_info(p_scanner); + if (curr_keepout_info == null) + { + return null; + } + via_keepout_infos.put(curr_keepout_info.name, curr_keepout_info); + } + else if (next_token == PLACE_KEEPOUT) + { + ComponentPlacement.ItemClearanceInfo curr_keepout_info = read_item_clearance_info(p_scanner); + if (curr_keepout_info == null) + { + return null; + } + place_keepout_infos.put(curr_keepout_info.name, curr_keepout_info); + } + else + { + skip_scope(p_scanner); + } + next_token = p_scanner.next_token(); + } + if (next_token != CLOSED_BRACKET) + { + System.out.println("Component.read_place_scope: ) expected"); + return null; + } + ComponentPlacement.ComponentLocation result = + new ComponentPlacement.ComponentLocation(name, location, is_front, rotation, position_fixed, pin_infos, + keepout_infos, via_keepout_infos, place_keepout_infos); + return result; + } + catch (java.io.IOException e) + { + System.out.println("Component.read_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + private static ComponentPlacement.ItemClearanceInfo read_item_clearance_info(Scanner p_scanner) throws java.io.IOException + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Component.read_item_clearance_info: String expected"); + return null; + } + String name = (String) next_token; + String cl_class_name = null; + next_token = p_scanner.next_token(); + while (next_token == OPEN_BRACKET) + { + next_token = p_scanner.next_token(); + if (next_token == CLEARANCE_CLASS) + { + cl_class_name = DsnFile.read_string_scope(p_scanner); + } + else + { + skip_scope(p_scanner); + } + next_token = p_scanner.next_token(); + } + if (next_token != CLOSED_BRACKET) + { + System.out.println("Component.read_item_clearance_info: ) expected"); + return null; + } + if (cl_class_name == null) + { + System.out.println("Component.read_item_clearance_info: clearance class name not found"); + return null; + } + return new ComponentPlacement.ItemClearanceInfo(name, cl_class_name); + } + + private static boolean read_lock_type(Scanner p_scanner) throws java.io.IOException + { + boolean result = false; + for (;;) + { + Object next_token = p_scanner.next_token(); + if (next_token == CLOSED_BRACKET) + { + break; + } + if (next_token == POSITION) + { + result = true; + } + } + return result; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ComponentPlacement.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ComponentPlacement.java new file mode 100644 index 0000000..0bffc07 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ComponentPlacement.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * ComponentPlacement.java + * + * Created on 20. Mai 2004, 07:43 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; + +/** + * Describes the placement data of a eu.mihosoft.freerouting.library component + * + * @author alfons + */ +public class ComponentPlacement +{ + + /** Creates a new instance of ComponentPlacement */ + public ComponentPlacement(String p_lib_name) + { + lib_name = p_lib_name; + locations = new LinkedList(); + } + + /** The name of the corresponding eu.mihosoft.freerouting.library component */ + public final String lib_name; + + /** The list of ComponentLocations of the eu.mihosoft.freerouting.library component on the eu.mihosoft.freerouting.board. */ + public final Collection locations; + + /** The structure of an entry in the list locations. */ + public static class ComponentLocation + { + ComponentLocation(String p_name, double[] p_coor, boolean p_is_front, double p_rotation, boolean p_position_fixed, + Map p_pin_infos, Map p_keepout_infos, + Map p_via_keepout_infos, Map p_place_keepout_infos) + { + name = p_name; + coor = p_coor; + is_front = p_is_front; + rotation = p_rotation; + position_fixed = p_position_fixed; + pin_infos = p_pin_infos; + keepout_infos = p_keepout_infos; + via_keepout_infos = p_via_keepout_infos; + place_keepout_infos = p_place_keepout_infos; + + } + + public final String name; + + /** the x- and the y-coordinate of the location. */ + public final double [] coor; + + /** + * True, if the component is placed at the component side. + * Else the component is placed at the solder side. + */ + public final boolean is_front; + + /** The rotation of the component in degree. */ + public final double rotation; + + /** If true, the component cannot be moved. */ + public final boolean position_fixed; + + /** + * The entries of this map are of type ItemClearanceInfo, the keys are the pin names. + */ + public final Map pin_infos; + + public final Map keepout_infos; + + public final Map via_keepout_infos; + + public final Map place_keepout_infos; + } + + public static class ItemClearanceInfo + { + ItemClearanceInfo( String p_name, String p_clearance_class) + { + name = p_name; + clearance_class = p_clearance_class; + } + public final String name; + public final String clearance_class; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/CoordinateTransform.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/CoordinateTransform.java new file mode 100644 index 0000000..74b62a6 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/CoordinateTransform.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * CoordinateTransform.java + * + * Created on 14. Mai 2004, 09:09 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; + +/** + * Computes transformations between a specctra dsn-file coordinates and eu.mihosoft.freerouting.board coordinates. + * + * @author Alfons Wirtz + */ +public class CoordinateTransform implements java.io.Serializable +{ + + /** + * Creates a new instance of CoordinateTransform. + * The base point of the dsn coordinate system will be translated to zero in the eu.mihosoft.freerouting.board + * coordinate system. + */ + public CoordinateTransform(double p_scale_factor, double p_base_x, double p_base_y) + { + scale_factor = p_scale_factor; + base_x = p_base_x; + base_y = p_base_y; + } + + /** + * Scale a value from the eu.mihosoft.freerouting.board to the dsn coordinate system + */ + public double board_to_dsn(double p_val) + { + return p_val / scale_factor; + } + + /** + * Scale a value from the dsn to the eu.mihosoft.freerouting.board coordinate system + */ + public double dsn_to_board(double p_val) + { + return p_val * scale_factor; + } + + /** + * Transforms a eu.mihosoft.freerouting.geometry.planar.FloatPoint to a tuple of doubles + * in the dsn coordinate system. + */ + public double[] board_to_dsn(FloatPoint p_point) + { + double [] result = new double[2]; + result [0] = board_to_dsn(p_point.x) + base_x; + result [1] = board_to_dsn(p_point.y) + base_y; + return result; + } + + /** + * Transforms a eu.mihosoft.freerouting.geometry.planar.FloatPoint to a tuple of doubles + * in the dsn coordinate system in relative (vector) coordinates. + */ + public double[] board_to_dsn_rel(FloatPoint p_point) + { + double [] result = new double[2]; + result [0] = board_to_dsn(p_point.x); + result [1] = board_to_dsn(p_point.y); + return result; + } + + /** + * Transforms an array of n eu.mihosoft.freerouting.geometry.planar.FloatPoints to + * an array of 2*n doubles in the dsn coordinate system. + */ + public double [] board_to_dsn(FloatPoint [] p_points) + { + double [] result = new double[2 * p_points.length]; + for (int i = 0; i < p_points.length; ++ i) + { + result[2 * i] = board_to_dsn(p_points[i].x) + base_x; + result[2 * i + 1] = board_to_dsn(p_points[i].y) + base_y; + } + return result; + } + + /** + * Transforms an array of n eu.mihosoft.freerouting.geometry.planar.Lines to + * an array of 4*n doubles in the dsn coordinate system. + */ + public double [] board_to_dsn(Line [] p_lines) + { + double [] result = new double[4 * p_lines.length]; + for (int i = 0; i < p_lines.length; ++ i) + { + FloatPoint a = p_lines[i].a.to_float(); + FloatPoint b = p_lines[i].b.to_float(); + result[4 * i] = board_to_dsn(a.x) + base_x; + result[4 * i + 1] = board_to_dsn(a.y) + base_y; + result[4 * i + 2] = board_to_dsn(b.x) + base_x; + result[4 * i + 3] = board_to_dsn(b.y) + base_y; + } + return result; + } + + /** + * Transforms an array of n eu.mihosoft.freerouting.geometry.planar.FloatPoints to + * an array of 2*n doubles in the dsn coordinate system in relative (vector) coordinates. + */ + public double [] board_to_dsn_rel(FloatPoint [] p_points) + { + double [] result = new double[2 * p_points.length]; + for (int i = 0; i < p_points.length; ++ i) + { + result[2 * i] = board_to_dsn(p_points[i].x); + result[2 * i + 1] = board_to_dsn(p_points[i].y); + } + return result; + } + + /** + * Transforms a eu.mihosoft.freerouting.geometry.planar.Vector to a tuple of doubles + * in the dsn coordinate system. + */ + public double[] board_to_dsn(Vector p_vector) + { + double [] result = new double[2]; + FloatPoint v = p_vector.to_float(); + result [0] = board_to_dsn(v.x); + result [1] = board_to_dsn(v.y); + return result; + } + + /** + * Transforms a dsn tuple to a eu.mihosoft.freerouting.geometry.planar.FloatPoint + */ + public FloatPoint dsn_to_board(double [] p_tuple) + { + double x = dsn_to_board(p_tuple[0] - base_x); + double y = dsn_to_board(p_tuple[1] - base_y); + return new FloatPoint(x, y); + } + + /** + * Transforms a dsn tuple to a eu.mihosoft.freerouting.geometry.planar.FloatPoint in relative (vector) coordinates. + */ + public FloatPoint dsn_to_board_rel(double [] p_tuple) + { + double x = dsn_to_board(p_tuple[0]); + double y = dsn_to_board(p_tuple[1]); + return new FloatPoint(x, y); + } + + /** + * Transforms a eu.mihosoft.freerouting.geometry.planar.Intbox to the coordinates of a Rectangle. + */ + public double [] board_to_dsn(IntBox p_box) + { + double [] result = new double[4]; + result[0] = p_box.ll.x / scale_factor + base_x; + result[1] = p_box.ll.y / scale_factor + base_y; + result[2] = p_box.ur.x / scale_factor + base_x; + result[3] = p_box.ur.y / scale_factor + base_y; + return result; + } + + /** + * Transforms a eu.mihosoft.freerouting.geometry.planar.Intbox to a Rectangle in relative (vector) coordinates. + */ + public double [] board_to_dsn_rel(IntBox p_box) + { + double [] result = new double[4]; + result[0] = p_box.ll.x / scale_factor; + result[1] = p_box.ll.y / scale_factor ; + result[2] = p_box.ur.x / scale_factor; + result[3] = p_box.ur.y / scale_factor; + return result; + } + + /** + * Transforms a eu.mihosoft.freerouting.board shape to a dsn shape. + */ + public Shape board_to_dsn(eu.mihosoft.freerouting.geometry.planar.Shape p_board_shape, Layer p_layer) + { + Shape result; + if (p_board_shape instanceof IntBox) + { + result = new Rectangle(p_layer, board_to_dsn((IntBox) p_board_shape)); + } + else if (p_board_shape instanceof PolylineShape) + { + FloatPoint [] corners = ((PolylineShape)p_board_shape).corner_approx_arr(); + double [] coors = board_to_dsn(corners); + result = new Polygon(p_layer, coors); + } + else if (p_board_shape instanceof eu.mihosoft.freerouting.geometry.planar.Circle) + { + eu.mihosoft.freerouting.geometry.planar.Circle board_circle = (eu.mihosoft.freerouting.geometry.planar.Circle) p_board_shape; + double diameter = 2 * board_to_dsn(board_circle.radius); + double [] center_coor = board_to_dsn(board_circle.center.to_float()); + result = new Circle(p_layer, diameter, center_coor[0], center_coor[1]); + } + else + { + System.out.println("CoordinateTransform.board_to_dsn not yet implemented for p_board_shape"); + result = null; + } + return result; + } + + /** + * Transforms the relative (vector) coordinates of a eu.mihosoft.freerouting.geometry.planar.Shape to a specctra dsn shape. + */ + public Shape board_to_dsn_rel(eu.mihosoft.freerouting.geometry.planar.Shape p_board_shape, Layer p_layer) + { + Shape result; + if (p_board_shape instanceof IntBox) + { + result = new Rectangle(p_layer, board_to_dsn_rel((IntBox) p_board_shape)); + } + else if (p_board_shape instanceof PolylineShape) + { + FloatPoint [] corners = ((PolylineShape)p_board_shape).corner_approx_arr(); + double [] coors = board_to_dsn_rel(corners); + result = new Polygon(p_layer, coors); + } + else if (p_board_shape instanceof eu.mihosoft.freerouting.geometry.planar.Circle) + { + eu.mihosoft.freerouting.geometry.planar.Circle board_circle = (eu.mihosoft.freerouting.geometry.planar.Circle) p_board_shape; + double diameter = 2 * board_to_dsn(board_circle.radius); + double [] center_coor = board_to_dsn_rel(board_circle.center.to_float()); + result = new Circle(p_layer, diameter, center_coor[0], center_coor[1]); + } + else + { + System.out.println("CoordinateTransform.board_to_dsn not yet implemented for p_board_shape"); + result = null; + } + return result; + } + + private final double scale_factor; + private final double base_x; + private final double base_y; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/DsnFile.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/DsnFile.java new file mode 100644 index 0000000..9caf19e --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/DsnFile.java @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * InputDsnFile.java + * + * Created on 10. Mai 2004, 07:43 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; + +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.board.TestLevel; + +/** + * Class for reading and writing dsn-files. + * + * @author alfons + */ +public class DsnFile +{ + + public enum ReadResult + { + + OK, OUTLINE_MISSING, ERROR + } + + private DsnFile() { + } + + /** + * Creates a routing eu.mihosoft.freerouting.board from a Specctra dns file. + * The parameters p_item_observers and p_item_id_no_generator are used, + * in case the eu.mihosoft.freerouting.board is embedded into a host system. + * Returns false, if an error occured. + */ + public static ReadResult read(java.io.InputStream p_input_stream, eu.mihosoft.freerouting.interactive.IBoardHandling p_board_handling, + eu.mihosoft.freerouting.board.BoardObservers p_observers, eu.mihosoft.freerouting.datastructures.IdNoGenerator p_item_id_no_generator, TestLevel p_test_level) + { + Scanner scanner = new SpecctraFileScanner(p_input_stream); + Object curr_token = null; + for (int i = 0; i < 3; ++i) + { + try + { + curr_token = scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read: IO error scanning file"); + System.out.println(e); + return ReadResult.ERROR; + } + boolean keyword_ok = true; + if (i == 0) + { + keyword_ok = (curr_token == Keyword.OPEN_BRACKET); + } + else if (i == 1) + { + keyword_ok = (curr_token == Keyword.PCB_SCOPE); + scanner.yybegin(SpecctraFileScanner.NAME); // to overread the name of the pcb for i = 2 + } + if (!keyword_ok) + { + System.out.println("DsnFile.read: specctra dsn file format expected"); + return ReadResult.ERROR; + } + } + ReadScopeParameter read_scope_par = + new ReadScopeParameter(scanner, p_board_handling, p_observers, p_item_id_no_generator, p_test_level); + boolean read_ok = Keyword.PCB_SCOPE.read_scope(read_scope_par); + ReadResult result; + if (read_ok) + { + result = ReadResult.OK; + if (read_scope_par.autoroute_settings == null) + { + // look for power planes with incorrect layer type and adjust eu.mihosoft.freerouting.autoroute parameters + adjust_plane_autoroute_settings(p_board_handling); + } + } + else if (!read_scope_par.board_outline_ok) + { + result = ReadResult.OUTLINE_MISSING; + } + else + { + result = ReadResult.ERROR; + } + //eu.mihosoft.freerouting.tests.Validate.check("after reading dsn", read_scope_par.board_handling.get_routing_board()); + return result; + } + + /** + * Sets contains_plane to true for nets with a conduction_area covering a + * large part of a signal layer, if that layer does not contain any traces + * This is useful in case the layer type was not set correctly to plane in the dsn-file. + * Returns true, if something was changed. + */ + private static boolean adjust_plane_autoroute_settings(eu.mihosoft.freerouting.interactive.IBoardHandling p_board_handling) + { + BasicBoard routing_board = p_board_handling.get_routing_board(); + eu.mihosoft.freerouting.board.LayerStructure board_layer_structure = routing_board.layer_structure; + if (board_layer_structure.arr.length <= 2) + { + return false; + } + for (eu.mihosoft.freerouting.board.Layer curr_layer : board_layer_structure.arr) + { + if (!curr_layer.is_signal) + { + return false; + } + } + boolean[] layer_contains_wires_arr = new boolean[board_layer_structure.arr.length]; + boolean[] changed_layer_arr = new boolean[board_layer_structure.arr.length]; + for (int i = 0; i < layer_contains_wires_arr.length; ++i) + { + layer_contains_wires_arr[i] = false; + changed_layer_arr[i] = false; + } + java.util.Collection conduction_area_list = new java.util.LinkedList(); + java.util.Collection item_list = routing_board.get_items(); + for (eu.mihosoft.freerouting.board.Item curr_item : item_list) + { + if (curr_item instanceof eu.mihosoft.freerouting.board.Trace) + { + int curr_layer = ((eu.mihosoft.freerouting.board.Trace) curr_item).get_layer(); + layer_contains_wires_arr[curr_layer] = true; + } + else if (curr_item instanceof eu.mihosoft.freerouting.board.ConductionArea) + { + conduction_area_list.add((eu.mihosoft.freerouting.board.ConductionArea) curr_item); + } + } + boolean nothing_changed = true; + + eu.mihosoft.freerouting.board.BoardOutline board_outline = routing_board.get_outline(); + double board_area = 0; + for (int i = 0; i < board_outline.shape_count(); ++i) + { + eu.mihosoft.freerouting.geometry.planar.TileShape[] curr_piece_arr = board_outline.get_shape(i).split_to_convex(); + if (curr_piece_arr != null) + { + for (eu.mihosoft.freerouting.geometry.planar.TileShape curr_piece : curr_piece_arr) + { + board_area += curr_piece.area(); + } + } + } + for (eu.mihosoft.freerouting.board.ConductionArea curr_conduction_area : conduction_area_list) + { + int layer_no = curr_conduction_area.get_layer(); + if (layer_contains_wires_arr[layer_no]) + { + continue; + } + eu.mihosoft.freerouting.board.Layer curr_layer = routing_board.layer_structure.arr[layer_no]; + if (!curr_layer.is_signal || layer_no == 0 || layer_no == board_layer_structure.arr.length - 1) + { + continue; + } + eu.mihosoft.freerouting.geometry.planar.TileShape[] convex_pieces = curr_conduction_area.get_area().split_to_convex(); + double curr_area = 0; + for (eu.mihosoft.freerouting.geometry.planar.TileShape curr_piece : convex_pieces) + { + curr_area += curr_piece.area(); + } + if (curr_area < 0.5 * board_area) + { + // skip conduction areas not covering most of the eu.mihosoft.freerouting.board + continue; + } + + for (int i = 0; i < curr_conduction_area.net_count(); ++i) + { + eu.mihosoft.freerouting.rules.Net curr_net = routing_board.rules.nets.get(curr_conduction_area.get_net_no(i)); + curr_net.set_contains_plane(true); + nothing_changed = false; + } + + changed_layer_arr[layer_no] = true; + if (curr_conduction_area.get_fixed_state().ordinal() < eu.mihosoft.freerouting.board.FixedState.USER_FIXED.ordinal()) + { + curr_conduction_area.set_fixed_state(eu.mihosoft.freerouting.board.FixedState.USER_FIXED); + } + } + if (nothing_changed) + { + return false; + } + // Adjust the layer prefered directions in the eu.mihosoft.freerouting.autoroute settings. + // and deactivate the changed layers. + eu.mihosoft.freerouting.interactive.AutorouteSettings autoroute_settings = p_board_handling.get_settings().autoroute_settings; + int layer_count = routing_board.get_layer_count(); + boolean curr_preferred_direction_is_horizontal = + autoroute_settings.get_preferred_direction_is_horizontal(0); + for (int i = 0; i < layer_count; ++i) + { + if (changed_layer_arr[i]) + { + autoroute_settings.set_layer_active(i, false); + } + else if (autoroute_settings.get_layer_active(i)) + { + autoroute_settings.set_preferred_direction_is_horizontal(i, curr_preferred_direction_is_horizontal); + curr_preferred_direction_is_horizontal = !curr_preferred_direction_is_horizontal; + } + } + return true; + } + + /** + * Writes p_board to a text file in the Specctra dsn format. + * Returns false, if the write failed. + * If p_compat_mode is true, only standard speecctra dsn scopes are written, so that any + * host system with an specctra interface can read them. + */ + public static boolean write(eu.mihosoft.freerouting.interactive.BoardHandling p_board_handling, java.io.OutputStream p_file, String p_design_name, boolean p_compat_mode) + { + //eu.mihosoft.freerouting.tests.Validate.check("before writing dsn", p_board); + IndentFileWriter output_file = new IndentFileWriter(p_file); + if (output_file == null) + { + System.out.println("unable to write dsn file"); + return false; + } + + try + { + write_pcb_scope(p_board_handling, output_file, p_design_name, p_compat_mode); + } + catch (java.io.IOException e) + { + System.out.println("unable to write dsn file"); + return false; + } + try + { + output_file.close(); + } + catch (java.io.IOException e) + { + System.out.println("unable to close dsn file"); + return false; + } + return true; + } + + private static void write_pcb_scope(eu.mihosoft.freerouting.interactive.BoardHandling p_board_handling, IndentFileWriter p_file, String p_design_name, boolean p_compat_mode) + throws java.io.IOException + { + BasicBoard routing_board = p_board_handling.get_routing_board(); + WriteScopeParameter write_scope_parameter = + new WriteScopeParameter(routing_board, p_board_handling.settings.autoroute_settings, p_file, + routing_board.communication.specctra_parser_info.string_quote, + routing_board.communication.coordinate_transform, p_compat_mode); + + p_file.start_scope(); + p_file.write("PCB "); + write_scope_parameter.identifier_type.write(p_design_name, p_file); + Parser.write_scope(write_scope_parameter.file, + write_scope_parameter.board.communication.specctra_parser_info, write_scope_parameter.identifier_type, false); + Resolution.write_scope(p_file, routing_board.communication); + Structure.write_scope(write_scope_parameter); + Placement.write_scope(write_scope_parameter); + Library.write_scope(write_scope_parameter); + PartLibrary.write_scope(write_scope_parameter); + Network.write_scope(write_scope_parameter); + Wiring.write_scope(write_scope_parameter); + p_file.end_scope(); + } + + static boolean read_on_off_scope(Scanner p_scanner) + { + try + { + Object next_token = p_scanner.next_token(); + boolean result = false; + if (next_token == Keyword.ON) + { + result = true; + } + else if (next_token != Keyword.OFF) + { + System.out.println("DsnFile.read_boolean: Keyword.OFF expected"); + } + ScopeKeyword.skip_scope(p_scanner); + return result; + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_boolean: IO error scanning file"); + return false; + } + } + + static int read_integer_scope(Scanner p_scanner) + { + try + { + int value; + Object next_token = p_scanner.next_token(); + if (next_token instanceof Integer) + { + value = ((Integer) next_token).intValue(); + } + else + { + System.out.println("DsnFile.read_integer_scope: number expected"); + return 0; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("DsnFile.read_integer_scope: closing bracket expected"); + return 0; + } + return value; + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_integer_scope: IO error scanning file"); + return 0; + } + } + + static double read_float_scope(Scanner p_scanner) + { + try + { + double value; + Object next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + value = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + value = ((Integer) next_token).intValue(); + } + else + { + System.out.println("DsnFile.read_float_scope: number expected"); + return 0; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("DsnFile.read_float_scope: closing bracket expected"); + return 0; + } + return value; + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_float_scope: IO error scanning file"); + return 0; + } + } + + public static String read_string_scope(Scanner p_scanner) + { + try + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("DsnFile:read_string_scope: String expected"); + return null; + } + String result = (String) next_token; + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("DsnFile.read_string_scope: closing bracket expected"); + } + return result; + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_string_scope: IO error scanning file"); + return null; + } + } + + public static java.util.Collection read_string_list_scope(Scanner p_scanner) + { + java.util.Collection result = new java.util.LinkedList(); + try + { + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + System.out.println("DsnFileread_string_list_scope: string expected"); + return null; + } + result.add((String) next_token); + } + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_string_list_scope: IO error scanning file"); + } + return result; + } + static final String CLASS_CLEARANCE_SEPARATOR = "-"; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Keyword.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Keyword.java new file mode 100644 index 0000000..e73c953 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Keyword.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Keyword.java + * + * Created on 8. Mai 2004, 10:23 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * Enumeration class for keywords of the specctra dsn file format + * + * @author alfons + */ +public class Keyword +{ + + /** + * The only instances of the internal classes: + * + * ScopeKeywords with an inividual read_scope method are defined in an extra class, + */ + public static final Keyword ABSOLUTE = new Keyword("absolute"); + public static final Keyword ACTIVE = new Keyword("active"); + public static final Keyword AGAINST_PREFERRED_DIRECTION_TRACE_COSTS = new Keyword("against_preferred_direction_trace_costs"); + public static final Keyword ATTACH = new Keyword("attach"); + public static final Keyword AUTOROUTE = new Keyword("autoroute"); + public static final Keyword AUTOROUTE_SETTINGS = new Keyword("autoroute_settings"); + public static final Keyword BACK = new Keyword("back"); + public static final Keyword BOUNDARY = new Keyword("boundary"); + public static final Keyword CIRCUIT = new Keyword("circuit"); + public static final Keyword CIRCLE = new Keyword("circle"); + public static final Keyword CLASS = new Keyword("class"); + public static final Keyword CLASS_CLASS = new Keyword("class_class"); + public static final Keyword CLASSES = new Keyword("classes"); + public static final ScopeKeyword COMPONENT_SCOPE = new Component(); + public static final Keyword CONSTANT = new Keyword("constant"); + public static final Keyword CONTROL = new Keyword("control"); + public static final Keyword CLEARANCE = new Keyword("clearance"); + public static final Keyword CLEARANCE_CLASS = new Keyword("clearance_class"); + public static final Keyword CLOSED_BRACKET = new Keyword(")"); + public static final Keyword FANOUT = new Keyword("fanout"); + public static final Keyword FLIP_STYLE = new Keyword("flip_style"); + public static final Keyword FIX = new Keyword("fix"); + public static final Keyword FORTYFIVE_DEGREE = new Keyword("fortyfive_degree"); + public static final Keyword FROMTO = new Keyword("fromto"); + public static final Keyword FRONT = new Keyword("front"); + public static final Keyword GENERATED_BY_FREEROUTE = new Keyword("generated_by_freeroute"); + public static final Keyword HORIZONTAL = new Keyword("horizontal"); + public static final Keyword HOST_CAD = new Keyword("host_cad"); + public static final Keyword HOST_VERSION = new Keyword("host_version"); + public static final Keyword IMAGE = new Keyword("image"); + public static final Keyword KEEPOUT = new Keyword("keepout"); + public static final Keyword LAYER = new Keyword("layer"); + public static final Keyword LAYER_RULE = new Keyword("layer_rule"); + public static final Keyword LENGTH = new Keyword("length"); + public static final ScopeKeyword LIBRARY_SCOPE = new Library(); + public static final Keyword LOCK_TYPE = new Keyword("lock_type"); + public static final Keyword LOGICAL_PART = new Keyword("logical_part"); + public static final Keyword LOGICAL_PART_MAPPING = new Keyword("logical_part_mapping"); + public static final Keyword NET = new Keyword("net"); + public static final Keyword NETWORK_OUT = new Keyword("network_out"); + public static final ScopeKeyword NETWORK_SCOPE = new Network(); + public static final Keyword NINETY_DEGREE = new Keyword("ninety_degree"); + public static final Keyword NONE = new Keyword("none"); + public static final Keyword NORMAL = new Keyword("normal"); + public static final Keyword OFF = new Keyword("off"); + public static final Keyword ON = new Keyword("on"); + public static final Keyword OPEN_BRACKET = new Keyword("("); + public static final Keyword ORDER = new Keyword("order"); + public static final Keyword OUTLINE = new Keyword("outline"); + public static final Keyword PADSTACK = new Keyword("padstack"); + public static final ScopeKeyword PART_LIBRARY_SCOPE = new PartLibrary(); + public static final ScopeKeyword PARSER_SCOPE = new Parser(); + public static final ScopeKeyword PCB_SCOPE = new ScopeKeyword("pcb"); + public static final Keyword PIN = new Keyword("pin"); + public static final Keyword PINS = new Keyword("pins"); + public static final Keyword PLACE = new Keyword("place"); + public static final ScopeKeyword PLACE_CONTROL = new PlaceControl(); + public static final Keyword PLACE_KEEPOUT = new Keyword("place_keepout"); + public static final ScopeKeyword PLACEMENT_SCOPE = new Placement(); + public static final ScopeKeyword PLANE_SCOPE = new Plane(); + public static final Keyword PLANE_VIA_COSTS = new Keyword("plane_via_costs"); + public static final Keyword PREFERRED_DIRECTION = new Keyword("preferred_direction"); + public static final Keyword PREFERRED_DIRECTION_TRACE_COSTS = new Keyword("preferred_direction_trace_costs"); + public static final Keyword SNAP_ANGLE = new Keyword("snap_angle"); + public static final Keyword POLYGON = new Keyword("polygon"); + public static final Keyword POLYGON_PATH = new Keyword("polygon_path"); + public static final Keyword POLYLINE_PATH = new Keyword("polyline_path"); + public static final Keyword POSITION = new Keyword("position"); + public static final Keyword POSTROUTE = new Keyword("postroute"); + public static final Keyword POWER = new Keyword("power"); + public static final Keyword PULL_TIGHT = new Keyword("pull_tight"); + public static final Keyword RECTANGLE = new Keyword("rectangle"); + public static final Keyword RESOLUTION_SCOPE = new Resolution(); + public static final Keyword ROTATE = new Keyword("rotate"); + public static final Keyword ROTATE_FIRST = new Keyword("rotate_first"); + public static final Keyword ROUTES = new Keyword("routes"); + public static final Keyword RULE = new Keyword("rule"); + public static final Keyword RULES = new Keyword("rules"); + public static final Keyword SESSION = new Keyword("session"); + public static final Keyword SHAPE = new Keyword("shape"); + public static final Keyword SHOVE_FIXED = new Keyword("shove_fixed"); + public static final Keyword SIDE = new Keyword("side"); + public static final Keyword SIGNAL = new Keyword("signal"); + public static final Keyword SPARE = new Keyword("spare"); + public static final Keyword START_PASS_NO = new Keyword("start_pass_no"); + public static final Keyword START_RIPUP_COSTS = new Keyword("start_ripup_costs"); + public static final Keyword STRING_QUOTE = new Keyword("string_quote"); + public static final ScopeKeyword STRUCTURE_SCOPE = new Structure(); + public static final Keyword TYPE = new Keyword("type"); + public static final Keyword USE_LAYER = new Keyword("use_layer"); + public static final Keyword USE_NET = new Keyword("use_net"); + public static final Keyword USE_VIA = new Keyword("use_via"); + public static final Keyword VERTICAL = new Keyword("vertical"); + public static final Keyword VIA = new Keyword("via"); + public static final Keyword VIAS = new Keyword("vias"); + public static final Keyword VIA_AT_SMD = new Keyword("via_at_smd"); + public static final Keyword VIA_COSTS = new Keyword("via_costs"); + public static final Keyword VIA_KEEPOUT = new Keyword("via_keepout"); + public static final Keyword VIA_RULE = new Keyword("via_rule"); + public static final Keyword WIDTH = new Keyword("width"); + public static final Keyword WINDOW = new Keyword("window"); + public static final Keyword WIRE = new Keyword("wire"); + public static final ScopeKeyword WIRING_SCOPE = new Wiring(); + public static final Keyword WRITE_RESOLUTION = new Keyword("write_resolution"); + + /** + * Returns the name string of this Keyword. + * The name is used for debugging purposes. + */ + public String get_name() + { + return name; + } + private final String name; + + /** prevents creating more instances */ + protected Keyword(String p_name) + { + name = p_name; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Layer.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Layer.java new file mode 100644 index 0000000..33ee599 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Layer.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Layer.java + * + * Created on 15. Mai 2004, 08:29 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; + + +/** + * Describes a layer in a Specctra dsn file. + * + * @author alfons + */ +public class Layer +{ + /** all layers of the eu.mihosoft.freerouting.board */ + public static final Layer PCB = new Layer("pcb", -1, false); + /** the signal layers */ + public static final Layer SIGNAL = new Layer("signal", -1, true); + + /** + * Creates a new instance of Layer. + * p_no is the physical layer number starting with 0 at the component side + * and ending at the solder side. + * If p_is_signal, the layer is a signal layer, otherwise it is a powerground layer. + * For Layer objects describing more than 1 layer the number is -1. + * p_net_names is a list of nets for this layer, if the layer is a power plane. + */ + public Layer(String p_name, int p_no, boolean p_is_signal, Collection p_net_names) + { + name = p_name; + no = p_no; + is_signal = p_is_signal; + net_names = p_net_names; + } + + /** + * Creates a new instance of Layer. + * p_no is the physical layer number starting with 0 at the component side + * and ending at the solder side. + * If p_is_signal, the layer is a signal layer, otherwise it is a powerground layer. + * For Layer objects describing more than 1 layer the number is -1. + */ + public Layer(String p_name, int p_no, boolean p_is_signal) + { + name = p_name; + no = p_no; + is_signal = p_is_signal; + net_names = new LinkedList(); + } + + /** + * Writes a layer scope in the stucture scope. + */ + public static void write_scope(WriteScopeParameter p_par, int p_layer_no, + boolean p_write_rule) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("layer "); + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[p_layer_no]; + p_par.identifier_type.write(board_layer.name, p_par.file); + p_par.file.new_line(); + p_par.file.write("(type "); + if (board_layer.is_signal) + { + p_par.file.write("signal)"); + } + else + { + p_par.file.write("power)"); + } + if (p_write_rule) + { + Rule.write_default_rule(p_par, p_layer_no); + } + p_par.file.end_scope(); + } + public final String name; + public final int no; + public final boolean is_signal; + public final java.util.Collection net_names; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/LayerStructure.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/LayerStructure.java new file mode 100644 index 0000000..9a0fc48 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/LayerStructure.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * LayerStructure.java + * + * Created on 16. Mai 2004, 08:08 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Iterator; + +/** + * Describes a layer structure read from a dsn file. + * + * @author alfons + */ +public class LayerStructure +{ + + /** Creates a new instance of LayerStructure from a list of layers*/ + public LayerStructure(Collection p_layer_list) + { + arr = new Layer[p_layer_list.size()]; + Iterator it = p_layer_list.iterator(); + for (int i = 0; i < arr.length; ++i) + { + arr[i] = it.next(); + } + } + + /** + * Creates a dsn-LayerStructure from a eu.mihosoft.freerouting.board LayerStructure. + */ + public LayerStructure(eu.mihosoft.freerouting.board.LayerStructure p_board_layer_structure) + { + arr = new Layer[p_board_layer_structure.arr.length]; + for (int i = 0; i < arr.length; ++i) + { + eu.mihosoft.freerouting.board.Layer board_layer = p_board_layer_structure.arr[i]; + arr[i] = new Layer(board_layer.name, i, board_layer.is_signal); + } + } + + /** + * returns the number of the layer with the name p_name, + * -1, if no layer with name p_name exists. + */ + public int get_no(String p_name) + { + for (int i = 0; i < arr.length; ++i) + { + if (p_name.equals(arr[i].name)) + { + return i; + } + } + // check for special layers of the Electra autorouter used for the outline + if (p_name.contains("Top")) + { + return 0; + } + if (p_name.contains("Bottom")) + { + return arr.length - 1; + } + return -1; + } + + public int signal_layer_count() + { + int result = 0; + for (Layer curr_layer : arr) + { + if (curr_layer.is_signal) + { + ++result; + } + } + return result; + } + + /** + * Returns, if the net with name p_net_name contains a powwer plane. + */ + public boolean contains_plane(String p_net_name) + { + + for (Layer curr_layer : arr) + { + if (!curr_layer.is_signal) + { + if (curr_layer.net_names.contains(p_net_name)) + { + return true; + } + } + } + return false; + } + + public final Layer[] arr; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Library.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Library.java new file mode 100644 index 0000000..42907ac --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Library.java @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Library.java + * + * Created on 21. Mai 2004, 08:09 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.IntVector; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.PolygonShape; +import eu.mihosoft.freerouting.geometry.planar.Simplex; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + + +/** + * Class for reading and writing eu.mihosoft.freerouting.library scopes from dsn-files. + * + * @author Alfons Wirtz + */ +public class Library extends ScopeKeyword +{ + + /** Creates a new instance of Library */ + public Library() + { + super("library"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + eu.mihosoft.freerouting.board.RoutingBoard board = p_par.board_handling.get_routing_board(); + board.library.padstacks = new eu.mihosoft.freerouting.library.Padstacks(p_par.board_handling.get_routing_board().layer_structure); + Collection package_list = new LinkedList(); + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Library.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (next_token == null) + { + System.out.println("Library.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == Keyword.PADSTACK) + { + if (!read_padstack_scope(p_par.scanner, p_par.layer_structure, + p_par.coordinate_transform, board.library.padstacks)) + { + return false; + } + } + else if (next_token == Keyword.IMAGE) + { + Package curr_package = Package.read_scope(p_par.scanner, p_par.layer_structure); + if (curr_package == null) + { + return false; + } + package_list.add(curr_package); + } + else + { + skip_scope(p_par.scanner); + } + } + } + + // Set the via padstacks. + if (p_par.via_padstack_names != null) + { + eu.mihosoft.freerouting.library.Padstack[] via_padstacks = new eu.mihosoft.freerouting.library.Padstack[p_par.via_padstack_names.size()]; + Iterator it = p_par.via_padstack_names.iterator(); + int found_padstack_count = 0; + for (int i = 0; i < via_padstacks.length; ++i) + { + String curr_padstack_name = it.next(); + eu.mihosoft.freerouting.library.Padstack curr_padstack = board.library.padstacks.get(curr_padstack_name); + if (curr_padstack != null) + { + via_padstacks[found_padstack_count] = curr_padstack; + ++found_padstack_count; + } + else + { + System.out.print("Library.read_scope: via padstack with name "); + System.out.print(curr_padstack_name); + System.out.println(" not found"); + } + } + if (found_padstack_count != via_padstacks.length) + { + // Some via padstacks were not found in the padstacks scope of the dsn-file. + eu.mihosoft.freerouting.library.Padstack[] corrected_padstacks = new eu.mihosoft.freerouting.library.Padstack[found_padstack_count]; + System.arraycopy(via_padstacks, 0, corrected_padstacks, 0, found_padstack_count); + via_padstacks = corrected_padstacks; + } + board.library.set_via_padstacks(via_padstacks); + } + + // Create the eu.mihosoft.freerouting.library packages on the eu.mihosoft.freerouting.board + board.library.packages = new eu.mihosoft.freerouting.library.Packages(board.library.padstacks); + Iterator it = package_list.iterator(); + while (it.hasNext()) + { + Package curr_package = it.next(); + eu.mihosoft.freerouting.library.Package.Pin[] pin_arr = new eu.mihosoft.freerouting.library.Package.Pin[curr_package.pin_info_arr.length]; + for (int i = 0; i < pin_arr.length; ++i) + { + Package.PinInfo pin_info = curr_package.pin_info_arr[i]; + int rel_x = (int) Math.round(p_par.coordinate_transform.dsn_to_board(pin_info.rel_coor[0])); + int rel_y = (int) Math.round(p_par.coordinate_transform.dsn_to_board(pin_info.rel_coor[1])); + Vector rel_coor = new IntVector(rel_x, rel_y); + eu.mihosoft.freerouting.library.Padstack board_padstack = board.library.padstacks.get(pin_info.padstack_name); + if (board_padstack == null) + { + System.out.println("Library.read_scope: eu.mihosoft.freerouting.board padstack not found"); + return false; + } + pin_arr[i] = new eu.mihosoft.freerouting.library.Package.Pin(pin_info.pin_name, board_padstack.no, rel_coor, pin_info.rotation); + } + eu.mihosoft.freerouting.geometry.planar.Shape[] outline_arr = new eu.mihosoft.freerouting.geometry.planar.Shape[curr_package.outline.size()]; + + Iterator it3 = curr_package.outline.iterator(); + for (int i = 0; i < outline_arr.length; ++i) + { + Shape curr_shape = it3.next(); + if (curr_shape != null) + { + outline_arr[i] = curr_shape.transform_to_board_rel(p_par.coordinate_transform); + } + else + { + System.out.println("Library.read_scope: outline shape is null"); + } + } + generate_missing_keepout_names("keepout_", curr_package.keepouts); + generate_missing_keepout_names("via_keepout_", curr_package.via_keepouts); + generate_missing_keepout_names("place_keepout_", curr_package.place_keepouts); + eu.mihosoft.freerouting.library.Package.Keepout [] keepout_arr = new eu.mihosoft.freerouting.library.Package.Keepout [curr_package.keepouts.size()]; + Iterator it2 = curr_package.keepouts.iterator(); + for (int i = 0; i < keepout_arr.length; ++i) + { + Shape.ReadAreaScopeResult curr_keepout = it2.next(); + Layer curr_layer = curr_keepout.shape_list.iterator().next().layer; + eu.mihosoft.freerouting.geometry.planar.Area curr_area = Shape.transform_area_to_board_rel(curr_keepout.shape_list, p_par.coordinate_transform); + keepout_arr[i] = new eu.mihosoft.freerouting.library.Package.Keepout(curr_keepout.area_name, curr_area, curr_layer.no); + } + eu.mihosoft.freerouting.library.Package.Keepout [] via_keepout_arr = new eu.mihosoft.freerouting.library.Package.Keepout [curr_package.via_keepouts.size()]; + it2 = curr_package.via_keepouts.iterator(); + for (int i = 0; i < via_keepout_arr.length; ++i) + { + Shape.ReadAreaScopeResult curr_keepout = it2.next(); + Layer curr_layer = (curr_keepout.shape_list.iterator().next()).layer; + eu.mihosoft.freerouting.geometry.planar.Area curr_area = Shape.transform_area_to_board_rel(curr_keepout.shape_list, p_par.coordinate_transform); + via_keepout_arr[i] = new eu.mihosoft.freerouting.library.Package.Keepout(curr_keepout.area_name, curr_area, curr_layer.no); + } + eu.mihosoft.freerouting.library.Package.Keepout [] place_keepout_arr = new eu.mihosoft.freerouting.library.Package.Keepout [curr_package.place_keepouts.size()]; + it2 = curr_package.place_keepouts.iterator(); + for (int i = 0; i < place_keepout_arr.length; ++i) + { + Shape.ReadAreaScopeResult curr_keepout = it2.next(); + Layer curr_layer = (curr_keepout.shape_list.iterator().next()).layer; + eu.mihosoft.freerouting.geometry.planar.Area curr_area = Shape.transform_area_to_board_rel(curr_keepout.shape_list, p_par.coordinate_transform); + place_keepout_arr[i] = new eu.mihosoft.freerouting.library.Package.Keepout(curr_keepout.area_name, curr_area, curr_layer.no); + } + board.library.packages.add(curr_package.name, pin_arr, outline_arr, + keepout_arr, via_keepout_arr, place_keepout_arr, curr_package.is_front); + } + return true; + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("library"); + for (int i = 1; i <= p_par.board.library.packages.count(); ++i) + { + Package.write_scope(p_par, p_par.board.library.packages.get(i)); + } + for (int i = 1; i <= p_par.board.library.padstacks.count(); ++i) + { + write_padstack_scope(p_par, p_par.board.library.padstacks.get(i)); + } + p_par.file.end_scope(); + } + + public static void write_padstack_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.library.Padstack p_padstack) throws java.io.IOException + { + // search the layer range of the padstack + int first_layer_no = 0; + while (first_layer_no < p_par.board.get_layer_count()) + { + if (p_padstack.get_shape(first_layer_no) != null) + { + break; + } + ++first_layer_no; + } + int last_layer_no = p_par.board.get_layer_count() - 1; + while (last_layer_no >= 0 ) + { + if (p_padstack.get_shape(last_layer_no) != null) + { + break; + } + --last_layer_no; + } + if (first_layer_no >= p_par.board.get_layer_count() || last_layer_no < 0) + { + System.out.println("Library.write_padstack_scope: padstack shape not found"); + return; + } + + p_par.file.start_scope(); + p_par.file.write("padstack "); + p_par.identifier_type.write(p_padstack.name, p_par.file); + for (int i = first_layer_no; i <= last_layer_no; ++i) + { + eu.mihosoft.freerouting.geometry.planar.Shape curr_board_shape = p_padstack.get_shape(i); + if (curr_board_shape == null) + { + continue; + } + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[i]; + Layer curr_layer = new Layer(board_layer.name, i, board_layer.is_signal); + Shape curr_shape = p_par.coordinate_transform.board_to_dsn_rel(curr_board_shape, curr_layer); + p_par.file.start_scope(); + p_par.file.write("shape"); + curr_shape.write_scope(p_par.file, p_par.identifier_type); + p_par.file.end_scope(); + } + if (!p_padstack.attach_allowed) + { + p_par.file.new_line(); + p_par.file.write("(attach off)"); + } + if (p_padstack.placed_absolute) + { + p_par.file.new_line(); + p_par.file.write("(absolute on)"); + } + p_par.file.end_scope(); + } + + static boolean read_padstack_scope(Scanner p_scanner, LayerStructure p_layer_structure, + CoordinateTransform p_coordinate_transform, eu.mihosoft.freerouting.library.Padstacks p_board_padstacks) + { + String padstack_name = null; + boolean is_drilllable = true; + boolean placed_absolute = false; + Collection shape_list = new LinkedList(); + try + { + Object next_token = p_scanner.next_token(); + if (next_token instanceof String) + { + padstack_name = (String) next_token; + } + else + { + System.out.println("Library.read_padstack_scope: unexpected padstack identifier"); + return false; + } + + while (next_token != Keyword.CLOSED_BRACKET) + { + Object prev_token = next_token; + next_token = p_scanner.next_token(); + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.SHAPE) + { + Shape curr_shape = Shape.read_scope(p_scanner, p_layer_structure); + if (curr_shape != null) + { + shape_list.add(curr_shape); + } + // overread the closing bracket and unknown scopes. + Object curr_next_token = p_scanner.next_token(); + while (curr_next_token == Keyword.OPEN_BRACKET) + { + ScopeKeyword.skip_scope(p_scanner); + curr_next_token = p_scanner.next_token(); + } + if (curr_next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Library.read_padstack_scope: closing bracket expected"); + return false; + } + } + else if (next_token == Keyword.ATTACH) + { + is_drilllable = DsnFile.read_on_off_scope(p_scanner); + } + else if (next_token == Keyword.ABSOLUTE) + { + placed_absolute = DsnFile.read_on_off_scope(p_scanner); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + + } + } + catch (java.io.IOException e) + { + System.out.println("Library.read_padstack_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (p_board_padstacks.get(padstack_name) != null) + { + // Padstack exists already + return true; + } + if (shape_list.isEmpty()) + { + System.out.print("Library.read_padstack_scope: shape not found for padstack with name "); + System.out.println(padstack_name); + return true; + } + eu.mihosoft.freerouting.geometry.planar.ConvexShape[] padstack_shapes = new eu.mihosoft.freerouting.geometry.planar.ConvexShape[p_layer_structure.arr.length]; + Iterator it = shape_list.iterator(); + while (it.hasNext()) + { + Shape pad_shape = it.next(); + eu.mihosoft.freerouting.geometry.planar.Shape curr_shape = pad_shape.transform_to_board_rel(p_coordinate_transform); + eu.mihosoft.freerouting.geometry.planar.ConvexShape convex_shape; + if (curr_shape instanceof eu.mihosoft.freerouting.geometry.planar.ConvexShape) + { + convex_shape = (eu.mihosoft.freerouting.geometry.planar.ConvexShape) curr_shape; + } + else + { + if (curr_shape instanceof PolygonShape) + { + curr_shape = ((PolygonShape)curr_shape).convex_hull(); + } + eu.mihosoft.freerouting.geometry.planar.TileShape[] convex_shapes = curr_shape.split_to_convex(); + if (convex_shapes.length != 1) + { + System.out.println("Library.read_padstack_scope: convex shape expected"); + } + convex_shape = convex_shapes[0]; + if (convex_shape instanceof Simplex) + { + convex_shape = ((Simplex) convex_shape).simplify(); + } + } + eu.mihosoft.freerouting.geometry.planar.ConvexShape padstack_shape = convex_shape; + if (padstack_shape != null) + { + if (padstack_shape.dimension() < 2) + { + System.out.print("Library.read_padstack_scope: shape is not an area "); + // enllarge the shape a little bit, so that it is an area + padstack_shape = padstack_shape.offset(1); + if (padstack_shape.dimension() < 2) + { + padstack_shape = null; + } + } + } + + if (pad_shape.layer == Layer.PCB || pad_shape.layer == Layer.SIGNAL) + { + for (int i = 0; i < padstack_shapes.length; ++i) + { + padstack_shapes[i] = padstack_shape; + } + } + else + { + int shape_layer = p_layer_structure.get_no(pad_shape.layer.name); + if (shape_layer < 0 || shape_layer >= padstack_shapes.length) + { + System.out.println("Library.read_padstack_scope: layer number found"); + return false; + } + padstack_shapes[shape_layer] = padstack_shape; + } + } + p_board_padstacks.add(padstack_name, padstack_shapes, is_drilllable, placed_absolute); + return true; + } + + private void generate_missing_keepout_names(String p_keepout_type, Collection p_keepout_list) + { + boolean all_names_existing = true; + for (Shape.ReadAreaScopeResult curr_keepout : p_keepout_list) + { + if (curr_keepout.area_name == null) + { + all_names_existing = false; + break; + } + } + if (all_names_existing) + { + return; + } + // generate names + Integer curr_name_index = 1; + for (Shape.ReadAreaScopeResult curr_keepout : p_keepout_list) + { + curr_keepout.area_name = p_keepout_type + curr_name_index.toString(); + ++curr_name_index; + } + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Net.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Net.java new file mode 100644 index 0000000..ce81ec5 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Net.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Net.java + * + * Created on 19. Mai 2004, 08:58 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Set; +import java.util.TreeSet; +import java.util.Iterator; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + + +/** + * Class for reading and writing net scopes from dsn-files. + * + * @author alfons + */ +public class Net +{ + + /** Creates a new instance of Net */ + public Net(Id p_net_id) + { + id = p_net_id; + } + + public static void write_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.rules.Net p_net, Collection p_pin_list) throws java.io.IOException + { + p_par.file.start_scope(); + write_net_id(p_net, p_par.file, p_par.identifier_type); + // write the pins scope + p_par.file.start_scope(); + p_par.file.write("pins"); + Iterator it = p_pin_list.iterator(); + while (it.hasNext()) + { + eu.mihosoft.freerouting.board.Pin curr_pin = it.next(); + if (curr_pin.contains_net(p_net.net_number)) + { + write_pin(p_par, curr_pin); + } + } + p_par.file.end_scope(); + p_par.file.end_scope(); + } + + public static void write_net_id(eu.mihosoft.freerouting.rules.Net p_net, IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.write("net "); + p_identifier_type.write(p_net.name, p_file); + p_file.write(" "); + Integer subnet_number = p_net.subnet_number; + p_file.write(subnet_number.toString()); + } + + public static void write_pin(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.Pin p_pin) throws java.io.IOException + { + eu.mihosoft.freerouting.board.Component curr_component = p_par.board.components.get(p_pin.get_component_no()); + if (curr_component == null) + { + System.out.println("Net.write_scope: component not found"); + return; + } + eu.mihosoft.freerouting.library.Package.Pin lib_pin = curr_component.get_package().get_pin(p_pin.get_index_in_package()); + if (lib_pin == null) + { + System.out.println("Net.write_scope: pin number out of range"); + return; + } + p_par.file.new_line(); + p_par.identifier_type.write(curr_component.name, p_par.file); + p_par.file.write("-"); + p_par.identifier_type.write(lib_pin.name, p_par.file); + + } + + public void set_pins(Collection p_pin_list) + { + pin_list = new TreeSet(); + for (Pin curr_pin : p_pin_list) + { + pin_list.add(curr_pin); + } + } + + public Set get_pins() + { + return pin_list; + } + + public final Id id; + + /** List of elements of type Pin. */ + private Set pin_list = null; + + public static class Id implements Comparable + { + public Id(String p_name, int p_subnet_number) + { + name = p_name; + subnet_number = p_subnet_number; + } + + public int compareTo(Id p_other) + { + int result = this.name.compareTo(p_other.name); + if (result == 0) + { + result = this.subnet_number - p_other.subnet_number; + } + return result; + } + + public final String name; + public final int subnet_number; + } + + + /** + * Sorted tuple of component name and pin name. + */ + public static class Pin implements Comparable + { + public Pin(String p_component_name, String p_pin_name) + { + component_name = p_component_name; + pin_name = p_pin_name; + } + + public int compareTo(Pin p_other) + { + int result = this.component_name.compareTo(p_other.component_name); + if (result == 0) + { + result = this.pin_name.compareTo(p_other.pin_name); + } + return result; + } + + public final String component_name; + public final String pin_name; + } +} \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetClass.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetClass.java new file mode 100644 index 0000000..4210d2c --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetClass.java @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * NetClass.java + * + * Created on 13. April 2005, 06:55 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; + +/** + * Contains the information of a Specctra Class scope. + * + * @author alfons + */ +public class NetClass +{ + + public static NetClass read_scope(Scanner p_scanner) + { + + try + { + // read the class name + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("NetClass.read_scope: String expected"); + return null; + } + String class_name = (String) next_token; + Collection net_list = new LinkedList(); + boolean rules_missing = false; + // read the nets belonging to the class + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (next_token == Keyword.OPEN_BRACKET) + { + break; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + rules_missing = true; + break; + } + if (!(next_token instanceof String)) + { + System.out.println("NetClass.read_scope: String expected"); + return null; + } + net_list.add((String) next_token); + } + Collection rules = new LinkedList(); + Collection layer_rules = new LinkedList(); + Collection use_via = new LinkedList(); + Collection use_layer = new LinkedList(); + String via_rule = null; + String trace_clearance_class = null; + boolean pull_tight = true; + boolean shove_fixed = false; + double min_trace_length = 0; + double max_trace_length = 0; + if (!rules_missing) + { + Object prev_token = next_token; + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == null) + { + System.out.println("NetClass.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.RULE) + { + rules.addAll(Rule.read_scope(p_scanner)); + } + else if (next_token == Keyword.LAYER_RULE) + { + layer_rules.add(Rule.read_layer_rule_scope(p_scanner)); + } + else if (next_token == Keyword.VIA_RULE) + { + via_rule = DsnFile.read_string_scope(p_scanner); + } + else if (next_token == Keyword.CIRCUIT) + { + Circuit.ReadScopeResult curr_rule = Circuit.read_scope(p_scanner); + if (curr_rule != null) + { + max_trace_length = curr_rule.max_length; + min_trace_length = curr_rule.min_length; + use_via.addAll(curr_rule.use_via); + use_layer.addAll(curr_rule.use_layer); + } + } + else if (next_token == Keyword.CLEARANCE_CLASS) + { + trace_clearance_class = DsnFile.read_string_scope(p_scanner); + if (trace_clearance_class == null) + { + return null; + } + } + else if (next_token == Keyword.SHOVE_FIXED) + { + shove_fixed = DsnFile.read_on_off_scope(p_scanner); + } + else if (next_token == Keyword.PULL_TIGHT) + { + pull_tight = DsnFile.read_on_off_scope(p_scanner); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + prev_token = next_token; + } + } + return new NetClass(class_name, trace_clearance_class, net_list, rules, layer_rules, + use_via, use_layer, via_rule, shove_fixed, pull_tight, min_trace_length, max_trace_length); + } + catch (java.io.IOException e) + { + System.out.println("NetClass.read_scope: IO error while scanning file"); + return null; + } + } + + public static ClassClass read_class_class_scope(Scanner p_scanner) + { + try + { + Collection classes = new LinkedList(); + Collection rules = new LinkedList(); + Collection layer_rules = new LinkedList(); + Object prev_token = null; + for (;;) + { + Object next_token = p_scanner.next_token(); + if (next_token == null) + { + System.out.println("ClassClass.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.CLASSES) + { + classes.addAll(DsnFile.read_string_list_scope(p_scanner)); + } + else if (next_token == Keyword.RULE) + { + rules.addAll(Rule.read_scope(p_scanner)); + } + else if (next_token == Keyword.LAYER_RULE) + { + layer_rules.add(Rule.read_layer_rule_scope(p_scanner)); + } + } + prev_token = next_token; + } + return new ClassClass(classes, rules, layer_rules); + } + catch (java.io.IOException e) + { + System.out.println("NetClass.read_scope: IO error while scanning file"); + return null; + } + } + + /** Creates a new instance of NetClass */ + public NetClass(String p_name, String p_trace_clearance_class, Collection p_net_list, + Collection p_rules, Collection p_layer_rules, Collection p_use_via, + Collection p_use_layer, String p_via_rule, boolean p_shove_fixed, boolean p_pull_tight, + double p_min_trace_length, double p_max_trace_length) + { + name = p_name; + trace_clearance_class = p_trace_clearance_class; + net_list = p_net_list; + rules = p_rules; + layer_rules = p_layer_rules; + use_via = p_use_via; + use_layer = p_use_layer; + via_rule = p_via_rule; + shove_fixed = p_shove_fixed; + pull_tight = p_pull_tight; + min_trace_length = p_min_trace_length; + max_trace_length = p_max_trace_length; + } + + public final String name; + public final String trace_clearance_class; + public final Collection net_list; + public final Collection rules; + public final Collection layer_rules; + public final Collection use_via; + public final Collection use_layer; + public final String via_rule; + public final boolean shove_fixed; + public final boolean pull_tight; + public final double min_trace_length; + public final double max_trace_length; + + public static class ClassClass + { + public ClassClass( Collection p_class_names, Collection p_rules, + Collection p_layer_rules) + { + class_names = p_class_names; + rules = p_rules; + layer_rules = p_layer_rules; + } + public final Collection class_names; + public final Collection rules; + public final Collection layer_rules; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetList.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetList.java new file mode 100644 index 0000000..6dc9d39 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/NetList.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * NetList.java + * + * Created on 19. Mai 2004, 09:05 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Set; + +/** + * Describes a list of nets sorted by its names. + * The net number is generated internally. + * + * @author alfons + */ +public class NetList +{ + + /** + * Returns true, if the netlist contains a net with the input name. + */ + public boolean contains(Net.Id p_net_id) + { + return nets.containsKey(p_net_id); + } + + /** + * Adds a new net mit the input name to the net list. + * Returns null, if a net with p_name already exists in the net list. + * In this case no new net is added. + */ + public Net add_net(Net.Id p_net_id) + { + Net result; + if (nets.containsKey(p_net_id)) + { + result = null; + } + else + { + result = new Net(p_net_id); + nets.put(p_net_id, result); + } + return result; + } + + /** + * Returns the net with the input name, or null, + * if the netlist does not contain a net with the input name. + */ + public Net get_net(Net.Id p_net_id) + { + Object value = nets.get(p_net_id); + return ((Net) value); + } + + /** + * Returns all nets in this net list containing the input pin. + */ + public Collection get_nets(String p_component_name, String p_pin_name) + { + Collection result = new java.util.LinkedList(); + Net.Pin search_pin = new Net.Pin(p_component_name, p_pin_name); + Collection net_list = nets.values(); + Iterator it = net_list.iterator(); + while (it.hasNext()) + { + Net curr_net = it.next(); + Set net_pins = curr_net.get_pins(); + if (net_pins != null && net_pins.contains(search_pin)) + { + result.add(curr_net); + } + } + return result; + } + + /** The entries of this map are of type Net, the keys are the net_ids. */ + private final Map nets = new TreeMap(); + +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Network.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Network.java new file mode 100644 index 0000000..66924f0 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Network.java @@ -0,0 +1,1536 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Network.java + * + * Created on 22. Mai 2004, 07:44 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.Set; +import java.util.Iterator; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +import eu.mihosoft.freerouting.rules.BoardRules; +import eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass; +import eu.mihosoft.freerouting.board.RoutingBoard; + +/** + * Class for reading and writing net network from dsn-files. + * + * @author Alfons Wirtz + */ +public class Network extends ScopeKeyword +{ + + /** Creates a new instance of Network */ + public Network() + { + super("network"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + Collection classes = new LinkedList(); + Collection class_class_list = new LinkedList(); + Collection via_infos = new LinkedList(); + Collection> via_rules = new LinkedList>(); + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (next_token == null) + { + System.out.println("Network.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == Keyword.NET) + { + read_net_scope(p_par.scanner, p_par.netlist, p_par.board_handling.get_routing_board(), + p_par.coordinate_transform, p_par.layer_structure, p_par.board_handling.get_locale()); + } + else if (next_token == Keyword.VIA) + { + eu.mihosoft.freerouting.rules.ViaInfo curr_via_info = read_via_info(p_par.scanner, p_par.board_handling.get_routing_board()); + if (curr_via_info == null) + { + return false; + } + via_infos.add(curr_via_info); + } + else if (next_token == Keyword.VIA_RULE) + { + Collection curr_via_rule = read_via_rule(p_par.scanner, p_par.board_handling.get_routing_board()); + if (curr_via_rule == null) + { + return false; + } + via_rules.add(curr_via_rule); + } + else if (next_token == Keyword.CLASS) + { + NetClass curr_class = NetClass.read_scope(p_par.scanner); + if (curr_class == null) + { + return false; + } + classes.add(curr_class); + } + else if (next_token == Keyword.CLASS_CLASS) + { + NetClass.ClassClass curr_class_class = NetClass.read_class_class_scope(p_par.scanner); + if (curr_class_class == null) + { + return false; + } + class_class_list.add(curr_class_class); + } + else + { + skip_scope(p_par.scanner); + } + } + } + insert_via_infos(via_infos, p_par.board_handling.get_routing_board(), p_par.via_at_smd_allowed); + insert_via_rules(via_rules, p_par.board_handling.get_routing_board()); + insert_net_classes(classes, p_par); + insert_class_pairs(class_class_list, p_par); + insert_compoments(p_par); + insert_logical_parts(p_par); + return true; + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("network"); + Collection board_pins = p_par.board.get_pins(); + for (int i = 1; i <= p_par.board.rules.nets.max_net_no(); ++i) + { + Net.write_scope(p_par, p_par.board.rules.nets.get(i), board_pins); + } + write_via_infos(p_par.board.rules, p_par.file, p_par.identifier_type); + write_via_rules(p_par.board.rules, p_par.file, p_par.identifier_type); + write_net_classes(p_par); + p_par.file.end_scope(); + } + + public static void write_via_infos(eu.mihosoft.freerouting.rules.BoardRules p_rules, IndentFileWriter p_file, IdentifierType p_identifier_type) + throws java.io.IOException + { + for (int i = 0; i < p_rules.via_infos.count(); ++i) + { + eu.mihosoft.freerouting.rules.ViaInfo curr_via = p_rules.via_infos.get(i); + p_file.start_scope(); + p_file.write("via "); + p_file.new_line(); + p_identifier_type.write(curr_via.get_name(), p_file); + p_file.write(" "); + p_identifier_type.write(curr_via.get_padstack().name, p_file); + p_file.write(" "); + p_identifier_type.write(p_rules.clearance_matrix.get_name(curr_via.get_clearance_class()), p_file); + if (curr_via.attach_smd_allowed()) + { + p_file.write(" attach"); + } + p_file.end_scope(); + } + } + + public static void write_via_rules(eu.mihosoft.freerouting.rules.BoardRules p_rules, IndentFileWriter p_file, IdentifierType p_identifier_type) + throws java.io.IOException + { + for (eu.mihosoft.freerouting.rules.ViaRule curr_rule : p_rules.via_rules) + { + p_file.start_scope(); + p_file.write("via_rule"); + p_file.new_line(); + p_identifier_type.write(curr_rule.name, p_file); + for (int i = 0; i < curr_rule.via_count(); ++i) + { + p_file.write(" "); + p_identifier_type.write(curr_rule.get_via(i).get_name(), p_file); + } + p_file.end_scope(); + } + } + + public static void write_net_classes(WriteScopeParameter p_par) + throws java.io.IOException + { + for (int i = 0; i < p_par.board.rules.net_classes.count(); ++i) + { + write_net_class(p_par.board.rules.net_classes.get(i), p_par); + } + } + + public static void write_net_class(eu.mihosoft.freerouting.rules.NetClass p_net_class, WriteScopeParameter p_par) + throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("class "); + p_par.identifier_type.write(p_net_class.get_name(), p_par.file); + final int nets_per_row = 8; + int net_counter = 0; + for (int i = 1; i <= p_par.board.rules.nets.max_net_no(); ++i) + { + if (p_par.board.rules.nets.get(i).get_class() == p_net_class) + { + if (net_counter % nets_per_row == 0) + { + p_par.file.new_line(); + } + else + { + p_par.file.write(" "); + } + p_par.identifier_type.write(p_par.board.rules.nets.get(i).name, p_par.file); + ++net_counter; + } + } + + // write the trace clearance class + Rule.write_item_clearance_class(p_par.board.rules.clearance_matrix.get_name(p_net_class.get_trace_clearance_class()), + p_par.file, p_par.identifier_type); + + // write the via rule + p_par.file.new_line(); + p_par.file.write("(via_rule "); + p_par.file.write(p_net_class.get_via_rule().name); + p_par.file.write(")"); + + // write the rules, if they are different from the default rule. + Rule.write_scope(p_net_class, p_par); + + write_circuit(p_net_class, p_par); + + if (!p_net_class.get_pull_tight()) + { + p_par.file.new_line(); + p_par.file.write("(pull_tight off)"); + } + + if (p_net_class.is_shove_fixed()) + { + p_par.file.new_line(); + p_par.file.write("(shove_fixed on)"); + } + + p_par.file.end_scope(); + } + + private static void write_circuit(eu.mihosoft.freerouting.rules.NetClass p_net_class, WriteScopeParameter p_par) + throws java.io.IOException + { + double min_trace_length = p_net_class.get_minimum_trace_length(); + double max_trace_length = p_net_class.get_maximum_trace_length(); + p_par.file.start_scope(); + p_par.file.write("circuit "); + p_par.file.new_line(); + p_par.file.write("(use_layer"); + int layer_count = p_net_class.layer_count(); + for (int i = 0; i < layer_count; ++i) + { + if (p_net_class.is_active_routing_layer(i)) + { + p_par.file.write(" "); + p_par.file.write(p_par.board.layer_structure.arr[i].name); + } + } + p_par.file.write(")"); + if (min_trace_length > 0 || max_trace_length > 0) + { + p_par.file.new_line(); + p_par.file.write("(length "); + Double transformed_max_length; + if (max_trace_length <= 0) + { + transformed_max_length = (double) -1; + } + else + { + transformed_max_length = p_par.coordinate_transform.board_to_dsn(max_trace_length); + } + p_par.file.write(transformed_max_length.toString()); + p_par.file.write(" "); + Double transformed_min_length; + if (min_trace_length <= 0) + { + transformed_min_length = (double) 0; + } + else + { + transformed_min_length = p_par.coordinate_transform.board_to_dsn(min_trace_length); + } + p_par.file.write(transformed_min_length.toString()); + p_par.file.write(")"); + } + p_par.file.end_scope(); + } + + private boolean read_net_scope(Scanner p_scanner, NetList p_net_list, RoutingBoard p_board, + CoordinateTransform p_coordinate_transform, LayerStructure p_layer_structure, java.util.Locale p_locale) + { + // read the net name + Object next_token; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_net_scope: IO error while scanning file"); + return false; + } + if (!(next_token instanceof String)) + { + System.out.println("Network.read_net_scope: String expected"); + return false; + } + String net_name = (String) next_token; + int subnet_number = 1; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_net_scope: IO error while scanning file"); + return false; + } + boolean scope_is_empty = (next_token == CLOSED_BRACKET); + if (next_token instanceof Integer) + { + subnet_number = ((Integer) next_token).intValue(); + } + boolean pin_order_found = false; + Collection pin_list = new LinkedList(); + Collection net_rules = new LinkedList(); + Collection> subnet_pin_lists = new LinkedList>(); + if (!scope_is_empty) + { + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_net_scope: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("Network.read_net_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == Keyword.PINS) + { + if (!read_net_pins(p_scanner, pin_list)) + { + return false; + } + } + else if (next_token == Keyword.ORDER) + { + pin_order_found = true; + if (!read_net_pins(p_scanner, pin_list)) + { + return false; + } + } + else if (next_token == Keyword.FROMTO) + { + Set curr_subnet_pin_list = new java.util.TreeSet(); + if (!read_net_pins(p_scanner, curr_subnet_pin_list)) + { + return false; + } + subnet_pin_lists.add(curr_subnet_pin_list); + } + else if (next_token == Keyword.RULE) + { + net_rules.addAll(Rule.read_scope(p_scanner)); + } + else if (next_token == Keyword.LAYER_RULE) + { + System.out.println("Netwark.read_net_scope: layer_rule not yet implemented"); + skip_scope(p_scanner); + } + else + { + skip_scope(p_scanner); + } + } + } + } + if (subnet_pin_lists.isEmpty()) + { + if (pin_order_found) + { + subnet_pin_lists = create_ordered_subnets(pin_list); + } + else + { + subnet_pin_lists.add(pin_list); + } + } + for (Collection curr_pin_list : subnet_pin_lists) + { + Net.Id net_id = new Net.Id(net_name, subnet_number); + if (!p_net_list.contains(net_id)) + { + Net new_net = p_net_list.add_net(net_id); + boolean contains_plane = p_layer_structure.contains_plane(net_name); + if (new_net != null) + { + p_board.rules.nets.add(new_net.id.name, new_net.id.subnet_number, contains_plane); + } + } + Net curr_subnet = p_net_list.get_net(net_id); + if (curr_subnet == null) + { + System.out.println("Network.read_net_scope: net not found in netlist"); + return false; + } + curr_subnet.set_pins(curr_pin_list); + if (!net_rules.isEmpty()) + { + // Evaluate the net eu.mihosoft.freerouting.rules. + eu.mihosoft.freerouting.rules.Net board_net = p_board.rules.nets.get(curr_subnet.id.name, curr_subnet.id.subnet_number); + if (board_net == null) + { + System.out.println("Network.read_net_scope: board net not found"); + return false; + } + Iterator it = net_rules.iterator(); + while (it.hasNext()) + { + Rule curr_ob = it.next(); + if (curr_ob instanceof Rule.WidthRule) + { + eu.mihosoft.freerouting.rules.NetClass default_net_rule = p_board.rules.get_default_net_class(); + double wire_width = ((Rule.WidthRule) curr_ob).value; + int trace_halfwidth = (int) Math.round(p_coordinate_transform.dsn_to_board(wire_width) / 2); + eu.mihosoft.freerouting.rules.NetClass net_rule = + p_board.rules.net_classes.find(trace_halfwidth, default_net_rule.get_trace_clearance_class(), + default_net_rule.get_via_rule()); + if (net_rule == null) + { + // create a new net rule + net_rule = p_board.rules.get_new_net_class(p_locale); + } + net_rule.set_trace_half_width(trace_halfwidth); + board_net.set_class(net_rule); + } + else + { + System.out.println("Network.read_net_scope: Rule not yet implemented"); + } + } + } + ++subnet_number; + } + return true; + } + + /** + * Creates a sequence of subnets with 2 pins from p_pin_list + */ + private static Collection> create_ordered_subnets(Collection p_pin_list) + { + Collection> result = new LinkedList>(); + if (p_pin_list.isEmpty()) + { + return result; + } + + Iterator it = p_pin_list.iterator(); + Net.Pin prev_pin = it.next(); + while (it.hasNext()) + { + Net.Pin next_pin = it.next(); + Set curr_subnet_pin_list = new java.util.TreeSet(); + curr_subnet_pin_list.add(prev_pin); + curr_subnet_pin_list.add(next_pin); + result.add(curr_subnet_pin_list); + prev_pin = next_pin; + } + return result; + } + + private static boolean read_net_pins(Scanner p_scanner, Collection p_pin_list) + { + Object next_token; + for (;;) + { + try + { + p_scanner.yybegin(SpecctraFileScanner.COMPONENT_NAME); + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_net_pins: IO error while scanning file"); + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + System.out.println("Network.read_net_pins: String expected"); + return false; + } + String component_name = (String) next_token; + try + { + p_scanner.yybegin(SpecctraFileScanner.SPEC_CHAR); + next_token = p_scanner.next_token(); // overread the hyphen + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + } catch (java.io.IOException e) + { + System.out.println("Network.read_net_pins: IO error while scanning file"); + return false; + } + if (!(next_token instanceof String)) + { + System.out.println("Network.read_net_pins: String expected"); + return false; + } + String pin_name = (String) next_token; + Net.Pin curr_entry = new Net.Pin(component_name, pin_name); + p_pin_list.add(curr_entry); + } + return true; + } + + static eu.mihosoft.freerouting.rules.ViaInfo read_via_info(Scanner p_scanner, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + try + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Network.read_via_info: string expected"); + return null; + } + String name = (String) next_token; + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Network.read_via_info: string expected"); + return null; + } + String padstack_name = (String) next_token; + eu.mihosoft.freerouting.library.Padstack via_padstack = p_board.library.get_via_padstack(padstack_name); + if (via_padstack == null) + { + // The padstack may not yet be inserted into the list of via padstacks + via_padstack = p_board.library.padstacks.get(padstack_name); + if (via_padstack == null) + { + System.out.println("Network.read_via_info: padstack not found"); + return null; + } + p_board.library.add_via_padstack(via_padstack); + } + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Network.read_via_info: string expected"); + return null; + } + int clearance_class = p_board.rules.clearance_matrix.get_no((String) next_token); + if (clearance_class < 0) + { + // Clearance class not stored, because it is identical to the default clearance class. + clearance_class = BoardRules.default_clearance_class(); + } + boolean attach_allowed = false; + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + if (next_token != Keyword.ATTACH) + { + System.out.println("Network.read_via_info: Keyword.ATTACH expected"); + return null; + } + attach_allowed = true; + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Network.read_via_info: closing bracket expected"); + return null; + } + } + return new eu.mihosoft.freerouting.rules.ViaInfo(name, via_padstack, clearance_class, attach_allowed, p_board.rules); + } catch (java.io.IOException e) + { + System.out.println("Network.read_via_info: IO error while scanning file"); + return null; + } + } + + static Collection read_via_rule(Scanner p_scanner, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + try + { + Collection result = new LinkedList(); + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + System.out.println("Network.read_via_rule: string expected"); + return null; + } + result.add((String) next_token); + } + return result; + } catch (java.io.IOException e) + { + System.out.println("Network.read_via_rule: IO error while scanning file"); + return null; + } + } + + private static void insert_via_infos(Collection p_via_infos, RoutingBoard p_board, boolean p_attach_allowed) + { + if (p_via_infos.size() > 0) + { + for (eu.mihosoft.freerouting.rules.ViaInfo curr_info : p_via_infos) + { + p_board.rules.via_infos.add(curr_info); + } + } + else // no via infos found, create default via infos from the via padstacks. + { + create_default_via_infos(p_board, p_board.rules.get_default_net_class(), p_attach_allowed); + } + } + + private static void create_default_via_infos(eu.mihosoft.freerouting.board.BasicBoard p_board, eu.mihosoft.freerouting.rules.NetClass p_net_class, boolean p_attach_allowed) + { + int cl_class = p_net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.VIA); + boolean is_default_class = (p_net_class == p_board.rules.get_default_net_class()); + for (int i = 0; i < p_board.library.via_padstack_count(); ++i) + { + eu.mihosoft.freerouting.library.Padstack curr_padstack = p_board.library.get_via_padstack(i); + boolean attach_allowed = p_attach_allowed && curr_padstack.attach_allowed; + String via_name; + if (is_default_class) + { + via_name = curr_padstack.name; + } + else + { + via_name = curr_padstack.name + DsnFile.CLASS_CLEARANCE_SEPARATOR + p_net_class.get_name(); + } + eu.mihosoft.freerouting.rules.ViaInfo found_via_info = + new eu.mihosoft.freerouting.rules.ViaInfo(via_name, curr_padstack, cl_class, attach_allowed, p_board.rules); + p_board.rules.via_infos.add(found_via_info); + } + } + + private static void insert_via_rules(Collection> p_via_rules, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + boolean rule_found = false; + for (Collection curr_list : p_via_rules) + { + if (curr_list.size() < 2) + { + continue; + } + if (add_via_rule(curr_list, p_board)) + { + rule_found = true; + } + } + if (!rule_found) + { + p_board.rules.create_default_via_rule(p_board.rules.get_default_net_class(), "default"); + } + for (int i = 0; i < p_board.rules.net_classes.count(); ++i) + { + p_board.rules.net_classes.get(i).set_via_rule(p_board.rules.get_default_via_rule()); + } + } + + /** + * Inserts a via rule into the eu.mihosoft.freerouting.board. + * Replaces an already existing via rule with the same + */ + static boolean add_via_rule(Collection p_name_list, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + Iterator it = p_name_list.iterator(); + String rule_name = it.next(); + eu.mihosoft.freerouting.rules.ViaRule existing_rule = p_board.rules.get_via_rule(rule_name); + eu.mihosoft.freerouting.rules.ViaRule curr_rule = new eu.mihosoft.freerouting.rules.ViaRule(rule_name); + boolean rule_ok = true; + while (it.hasNext()) + { + eu.mihosoft.freerouting.rules.ViaInfo curr_via = p_board.rules.via_infos.get(it.next()); + if (curr_via != null) + { + curr_rule.append_via(curr_via); + } + else + { + System.out.println("Network.insert_via_rules: via_info not found"); + rule_ok = false; + } + } + if (rule_ok) + { + if (existing_rule != null) + { + // Replace already existing rule. + p_board.rules.via_rules.remove(existing_rule); + } + p_board.rules.via_rules.add(curr_rule); + } + return rule_ok; + } + + private static void insert_net_classes(Collection p_net_classes, ReadScopeParameter p_par) + { + eu.mihosoft.freerouting.board.BasicBoard routing_board = p_par.board_handling.get_routing_board(); + for (NetClass curr_class : p_net_classes) + { + insert_net_class(curr_class, p_par.layer_structure, routing_board, p_par.coordinate_transform, p_par.via_at_smd_allowed); + } + } + + static void insert_net_class(NetClass p_class, LayerStructure p_layer_structure, eu.mihosoft.freerouting.board.BasicBoard p_board, CoordinateTransform p_coordinate_transform, + boolean p_via_at_smd_allowed) + { + eu.mihosoft.freerouting.rules.NetClass board_net_class = p_board.rules.append_net_class(p_class.name); + if (p_class.trace_clearance_class != null) + { + int trace_clearance_class = p_board.rules.clearance_matrix.get_no(p_class.trace_clearance_class); + if (trace_clearance_class >= 0) + { + board_net_class.set_trace_clearance_class(trace_clearance_class); + } + else + { + System.out.println("Network.insert_net_class: clearance class not found"); + } + } + if (p_class.via_rule != null) + { + eu.mihosoft.freerouting.rules.ViaRule via_rule = p_board.rules.get_via_rule(p_class.via_rule); + if (via_rule != null) + { + board_net_class.set_via_rule(via_rule); + } + else + { + System.out.println("Network.insert_net_class: via rule not found"); + } + } + if (p_class.max_trace_length > 0) + { + board_net_class.set_maximum_trace_length(p_coordinate_transform.dsn_to_board(p_class.max_trace_length)); + } + if (p_class.min_trace_length > 0) + { + board_net_class.set_minimum_trace_length(p_coordinate_transform.dsn_to_board(p_class.min_trace_length)); + } + for (String curr_net_name : p_class.net_list) + { + Collection curr_net_list = p_board.rules.nets.get(curr_net_name); + for (eu.mihosoft.freerouting.rules.Net curr_net : curr_net_list) + { + curr_net.set_class(board_net_class); + } + } + + // read the trace width and clearance eu.mihosoft.freerouting.rules. + + boolean clearance_rule_found = false; + + for (Rule curr_rule : p_class.rules) + { + if (curr_rule instanceof Rule.WidthRule) + { + int trace_halfwidth = (int) Math.round(p_coordinate_transform.dsn_to_board(((Rule.WidthRule) curr_rule).value / 2)); + board_net_class.set_trace_half_width(trace_halfwidth); + } + else if (curr_rule instanceof Rule.ClearanceRule) + { + add_clearance_rule(p_board.rules.clearance_matrix, board_net_class, + (Rule.ClearanceRule) curr_rule, -1, p_coordinate_transform); + clearance_rule_found = true; + } + else + { + + System.out.println("Network.insert_net_class: rule type not yet implemented"); + } + } + + // read the layer dependent eu.mihosoft.freerouting.rules. + + for (Rule.LayerRule curr_layer_rule : p_class.layer_rules) + { + for (String curr_layer_name : curr_layer_rule.layer_names) + { + int layer_no = p_board.layer_structure.get_no(curr_layer_name); + if (layer_no < 0) + { + System.out.println("Network.insert_net_class: layer not found"); + continue; + } + for (Rule curr_rule : curr_layer_rule.rules) + { + if (curr_rule instanceof Rule.WidthRule) + { + int trace_halfwidth = (int) Math.round(p_coordinate_transform.dsn_to_board(((Rule.WidthRule) curr_rule).value / 2)); + board_net_class.set_trace_half_width(layer_no, trace_halfwidth); + } + else if (curr_rule instanceof Rule.ClearanceRule) + { + add_clearance_rule(p_board.rules.clearance_matrix, board_net_class, (Rule.ClearanceRule) curr_rule, layer_no, p_coordinate_transform); + clearance_rule_found = true; + } + else + { + System.out.println("Network.insert_net_class: layer rule type not yet implemented"); + } + } + } + } + + board_net_class.set_pull_tight(p_class.pull_tight); + board_net_class.set_shove_fixed(p_class.shove_fixed); + boolean via_infos_created = false; + + if (clearance_rule_found && board_net_class != p_board.rules.get_default_net_class()) + { + create_default_via_infos(p_board, board_net_class, p_via_at_smd_allowed); + via_infos_created = true; + } + + if (!p_class.use_via.isEmpty()) + { + create_via_rule(p_class.use_via, board_net_class, p_board, p_via_at_smd_allowed); + } + else if (via_infos_created) + { + p_board.rules.create_default_via_rule(board_net_class, board_net_class.get_name()); + } + if (!p_class.use_layer.isEmpty()) + { + create_active_trace_layers(p_class.use_layer, p_layer_structure, board_net_class); + } + } + + static private void insert_class_pairs(Collection p_class_classes, ReadScopeParameter p_par) + { + for (NetClass.ClassClass curr_class_class : p_class_classes) + { + java.util.Iterator it1 = curr_class_class.class_names.iterator(); + eu.mihosoft.freerouting.board.BasicBoard routing_board = p_par.board_handling.get_routing_board(); + while (it1.hasNext()) + { + String first_name = it1.next(); + eu.mihosoft.freerouting.rules.NetClass first_class = routing_board.rules.net_classes.get(first_name); + if (first_class == null) + { + System.out.println("Network.insert_class_pairs: first class not found"); + } + else + { + java.util.Iterator it2 = it1; + while (it2.hasNext()) + { + String second_name = it2.next(); + eu.mihosoft.freerouting.rules.NetClass second_class = routing_board.rules.net_classes.get(second_name); + if (second_class == null) + { + System.out.println("Network.insert_class_pairs: second class not found"); + } + else + { + insert_class_pair_info(curr_class_class, first_class, second_class, routing_board, + p_par.coordinate_transform); + } + } + } + } + } + } + + static private void insert_class_pair_info(NetClass.ClassClass p_class_class, eu.mihosoft.freerouting.rules.NetClass p_first_class, eu.mihosoft.freerouting.rules.NetClass p_second_class, + eu.mihosoft.freerouting.board.BasicBoard p_board, CoordinateTransform p_coordinate_transform) + { + for (Rule curr_rule : p_class_class.rules) + { + if (curr_rule instanceof Rule.ClearanceRule) + { + Rule.ClearanceRule curr_clearance_rule = (Rule.ClearanceRule) curr_rule; + add_mixed_clearance_rule(p_board.rules.clearance_matrix, p_first_class, p_second_class, + curr_clearance_rule, -1, p_coordinate_transform); + } + else + { + System.out.println("Network.insert_class_pair_info: unexpected rule"); + } + } + for (Rule.LayerRule curr_layer_rule : p_class_class.layer_rules) + { + for (String curr_layer_name : curr_layer_rule.layer_names) + { + int layer_no = p_board.layer_structure.get_no(curr_layer_name); + if (layer_no < 0) + { + System.out.println("Network.insert_class_pair_info: layer not found"); + continue; + } + for (Rule curr_rule : curr_layer_rule.rules) + { + if (curr_rule instanceof Rule.ClearanceRule) + { + add_mixed_clearance_rule(p_board.rules.clearance_matrix, + p_first_class, p_second_class, (Rule.ClearanceRule) curr_rule, + layer_no, p_coordinate_transform); + } + else + { + System.out.println("Network.insert_class_pair_info: unexpected layer rule type"); + } + } + } + } + } + + static private void add_mixed_clearance_rule(eu.mihosoft.freerouting.rules.ClearanceMatrix p_clearance_matrix, eu.mihosoft.freerouting.rules.NetClass p_first_class, + eu.mihosoft.freerouting.rules.NetClass p_second_class, Rule.ClearanceRule p_clearance_rule, int p_layer_no, + CoordinateTransform p_coordinate_transform) + { + int curr_clearance = (int) Math.round(p_coordinate_transform.dsn_to_board(p_clearance_rule.value)); + final String first_class_name = p_first_class.get_name(); + int first_class_no = p_clearance_matrix.get_no(first_class_name); + if (first_class_no < 0) + { + p_clearance_matrix.append_class(first_class_name); + first_class_no = p_clearance_matrix.get_no(first_class_name); + } + final String second_class_name = p_second_class.get_name(); + int second_class_no = p_clearance_matrix.get_no(second_class_name); + if (second_class_no < 0) + { + p_clearance_matrix.append_class(second_class_name); + second_class_no = p_clearance_matrix.get_no(second_class_name); + } + if (p_clearance_rule.clearance_class_pairs.isEmpty()) + { + if (p_layer_no < 0) + { + p_clearance_matrix.set_value(first_class_no, second_class_no, curr_clearance); + p_clearance_matrix.set_value(second_class_no, first_class_no, curr_clearance); + } + else + { + p_clearance_matrix.set_value(first_class_no, second_class_no, p_layer_no, curr_clearance); + p_clearance_matrix.set_value(second_class_no, first_class_no, p_layer_no, curr_clearance); + } + } + else + { + Iterator it = p_clearance_rule.clearance_class_pairs.iterator(); + while (it.hasNext()) + { + String curr_string = it.next(); + String[] curr_pair = curr_string.split("_"); + if (curr_pair.length != 2) + { + continue; + } + + int curr_first_class_no; + int curr_second_class_no; + for (int i = 0; i < 2; ++i) + { + if (i == 0) + { + curr_first_class_no = get_clearance_class(p_clearance_matrix, p_first_class, curr_pair[0]); + curr_second_class_no = get_clearance_class(p_clearance_matrix, p_second_class, curr_pair[1]); + } + else + { + curr_first_class_no = get_clearance_class(p_clearance_matrix, p_second_class, curr_pair[0]); + curr_second_class_no = get_clearance_class(p_clearance_matrix, p_first_class, curr_pair[1]); + } + if (p_layer_no < 0) + { + p_clearance_matrix.set_value(curr_first_class_no, curr_second_class_no, curr_clearance); + p_clearance_matrix.set_value(curr_second_class_no, curr_first_class_no, curr_clearance); + } + else + { + p_clearance_matrix.set_value(curr_first_class_no, curr_second_class_no, p_layer_no, curr_clearance); + p_clearance_matrix.set_value(curr_second_class_no, curr_first_class_no, p_layer_no, curr_clearance); + } + } + } + } + } + + static private void create_default_clearance_classes(eu.mihosoft.freerouting.rules.NetClass p_net_class, + eu.mihosoft.freerouting.rules.ClearanceMatrix p_clearance_matrix) + { + get_clearance_class(p_clearance_matrix, p_net_class, "via"); + get_clearance_class(p_clearance_matrix, p_net_class, "smd"); + get_clearance_class(p_clearance_matrix, p_net_class, "pin"); + get_clearance_class(p_clearance_matrix, p_net_class, "area"); + } + + private static void create_via_rule(Collection p_use_via, eu.mihosoft.freerouting.rules.NetClass p_net_class, eu.mihosoft.freerouting.board.BasicBoard p_board, boolean p_attach_allowed) + { + eu.mihosoft.freerouting.rules.ViaRule new_via_rule = new eu.mihosoft.freerouting.rules.ViaRule(p_net_class.get_name()); + int default_via_cl_class = p_net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.VIA); + for (String curr_via_name : p_use_via) + { + for (int i = 0; i < p_board.rules.via_infos.count(); ++i) + { + eu.mihosoft.freerouting.rules.ViaInfo curr_via_info = p_board.rules.via_infos.get(i); + if (curr_via_info.get_clearance_class() == default_via_cl_class) + { + if (curr_via_info.get_padstack().name.equals(curr_via_name)) + { + new_via_rule.append_via(curr_via_info); + } + } + } + } + p_board.rules.via_rules.add(new_via_rule); + p_net_class.set_via_rule(new_via_rule); + } + + private static void create_active_trace_layers(Collection p_use_layer, LayerStructure p_layer_structure, eu.mihosoft.freerouting.rules.NetClass p_net_class) + { + for (int i = 0; i < p_layer_structure.arr.length; ++i) + { + p_net_class.set_active_routing_layer(i, false); + } + for (String cur_layer_name : p_use_layer) + { + int curr_no = p_layer_structure.get_no(cur_layer_name); + p_net_class.set_active_routing_layer(curr_no, true); + } + // currently all inactive layers have tracewidth 0. + for (int i = 0; i < p_layer_structure.arr.length; ++i) + { + if (!p_net_class.is_active_routing_layer(i)) + { + p_net_class.set_trace_half_width(i, 0); + } + } + } + + private static void add_clearance_rule(eu.mihosoft.freerouting.rules.ClearanceMatrix p_clearance_matrix, eu.mihosoft.freerouting.rules.NetClass p_net_class, + Rule.ClearanceRule p_rule, int p_layer_no, CoordinateTransform p_coordinate_transform) + { + int curr_clearance = (int) Math.round(p_coordinate_transform.dsn_to_board(p_rule.value)); + final String class_name = p_net_class.get_name(); + int class_no = p_clearance_matrix.get_no(class_name); + if (class_no < 0) + { + // class not yet existing, create a new class + p_clearance_matrix.append_class(class_name); + class_no = p_clearance_matrix.get_no(class_name); + // set the clearance values of the new class to the maximum of curr_clearance and the + // the existing values. + for (int i = 1; i < p_clearance_matrix.get_class_count(); ++i) + { + for (int j = 0; j < p_clearance_matrix.get_layer_count(); ++j) + { + int curr_value = Math.max(p_clearance_matrix.value(class_no, i, j), curr_clearance); + p_clearance_matrix.set_value(class_no, i, j, curr_value); + p_clearance_matrix.set_value(i, class_no, j, curr_value); + } + } + p_net_class.default_item_clearance_classes.set_all(class_no); + } + p_net_class.set_trace_clearance_class(class_no); + if (p_rule.clearance_class_pairs.isEmpty()) + { + if (p_layer_no < 0) + { + p_clearance_matrix.set_value(class_no, class_no, curr_clearance); + } + else + { + p_clearance_matrix.set_value(class_no, class_no, p_layer_no, curr_clearance); + } + return; + } + if (Structure.contains_wire_clearance_pair(p_rule.clearance_class_pairs)) + { + create_default_clearance_classes(p_net_class, p_clearance_matrix); + } + Iterator it = p_rule.clearance_class_pairs.iterator(); + while (it.hasNext()) + { + String curr_string = it.next(); + String[] curr_pair = curr_string.split("_"); + if (curr_pair.length != 2) + { + continue; + } + + int first_class_no = get_clearance_class(p_clearance_matrix, p_net_class, curr_pair[0]); + int second_class_no = get_clearance_class(p_clearance_matrix, p_net_class, curr_pair[1]); + + if (p_layer_no < 0) + { + p_clearance_matrix.set_value(first_class_no, second_class_no, curr_clearance); + p_clearance_matrix.set_value(second_class_no, first_class_no, curr_clearance); + } + else + { + p_clearance_matrix.set_value(first_class_no, second_class_no, p_layer_no, curr_clearance); + p_clearance_matrix.set_value(second_class_no, first_class_no, p_layer_no, curr_clearance); + } + } + } + + /** + * Gets the number of the clearance class with name combined of p_net_class_name and p_item_class_name. + * Creates a new class, if that class is not yet existing. + */ + static private int get_clearance_class(eu.mihosoft.freerouting.rules.ClearanceMatrix p_clearance_matrix, + eu.mihosoft.freerouting.rules.NetClass p_net_class, String p_item_class_name) + { + String net_class_name = p_net_class.get_name(); + String new_class_name = net_class_name; + if (!p_item_class_name.equals("wire")) + { + new_class_name = new_class_name + DsnFile.CLASS_CLEARANCE_SEPARATOR + p_item_class_name; + } + int found_class_no = p_clearance_matrix.get_no(new_class_name); + if (found_class_no >= 0) + { + return found_class_no; + } + p_clearance_matrix.append_class(new_class_name); + int result = p_clearance_matrix.get_no(new_class_name); + int net_class_no = p_clearance_matrix.get_no(net_class_name); + if (net_class_no < 0 || result < 0) + { + System.out.println("Network.get_clearance_class: clearance class not found"); + return result; + } + // initalise the clearance values of p_new_class_name from p_net_class_name + for (int i = 1; i < p_clearance_matrix.get_class_count(); ++i) + { + + for (int j = 0; j < p_clearance_matrix.get_layer_count(); ++j) + { + int curr_value = p_clearance_matrix.value(net_class_no, i, j); + p_clearance_matrix.set_value(result, i, j, curr_value); + p_clearance_matrix.set_value(i, result, j, curr_value); + } + } + if (p_item_class_name.equals("via")) + { + p_net_class.default_item_clearance_classes.set(ItemClass.VIA, result); + } + else if (p_item_class_name.equals("pin")) + { + p_net_class.default_item_clearance_classes.set(ItemClass.PIN, result); + } + else if (p_item_class_name.equals("smd")) + { + p_net_class.default_item_clearance_classes.set(ItemClass.SMD, result); + } + else if (p_item_class_name.equals("area")) + { + p_net_class.default_item_clearance_classes.set(ItemClass.AREA, result); + } + return result; + } + + private static void insert_compoments(ReadScopeParameter p_par) + { + Iterator it = p_par.placement_list.iterator(); + while (it.hasNext()) + { + ComponentPlacement next_lib_component = it.next(); + Iterator it2 = next_lib_component.locations.iterator(); + while (it2.hasNext()) + { + ComponentPlacement.ComponentLocation next_component = it2.next(); + insert_component(next_component, next_lib_component.lib_name, p_par); + } + + } + } + + /** + * Create the part eu.mihosoft.freerouting.library on the eu.mihosoft.freerouting.board. Can be called after the components are inserted. + * Returns false, if an error occured. + */ + private static boolean insert_logical_parts(ReadScopeParameter p_par) + { + eu.mihosoft.freerouting.board.BasicBoard routing_board = p_par.board_handling.get_routing_board(); + for (PartLibrary.LogicalPart next_part : p_par.logical_parts) + { + eu.mihosoft.freerouting.library.Package lib_package = search_lib_package(next_part.name, p_par.logical_part_mappings, routing_board); + if (lib_package == null) + { + return false; + } + eu.mihosoft.freerouting.library.LogicalPart.PartPin[] board_part_pins = + new eu.mihosoft.freerouting.library.LogicalPart.PartPin[next_part.part_pins.size()]; + int curr_index = 0; + for (PartLibrary.PartPin curr_part_pin : next_part.part_pins) + { + int pin_no = lib_package.get_pin_no(curr_part_pin.pin_name); + if (pin_no < 0) + { + System.out.println("Network.insert_logical_parts: package pin not found"); + return false; + } + board_part_pins[curr_index] = + new eu.mihosoft.freerouting.library.LogicalPart.PartPin(pin_no, curr_part_pin.pin_name, + curr_part_pin.gate_name, curr_part_pin.gate_swap_code, + curr_part_pin.gate_pin_name, curr_part_pin.gate_pin_swap_code); + ++curr_index; + } + routing_board.library.logical_parts.add(next_part.name, board_part_pins); + } + + for (PartLibrary.LogicalPartMapping next_mapping : p_par.logical_part_mappings) + { + eu.mihosoft.freerouting.library.LogicalPart curr_logical_part = routing_board.library.logical_parts.get(next_mapping.name); + { + if (curr_logical_part == null) + { + System.out.println("Network.insert_logical_parts: logical part not found"); + } + } + for (String curr_cmp_name : next_mapping.components) + { + eu.mihosoft.freerouting.board.Component curr_component = routing_board.components.get(curr_cmp_name); + if (curr_component != null) + { + curr_component.set_logical_part(curr_logical_part); + } + else + { + System.out.println("Network.insert_logical_parts: eu.mihosoft.freerouting.board component not found"); + } + } + } + return true; + } + + /** + * Calculates the eu.mihosoft.freerouting.library package belonging to the logical part with name p_part_name. + * Returns null, if the package was not found. + */ + private static eu.mihosoft.freerouting.library.Package search_lib_package(String p_part_name, + java.util.Collection p_logical_part_mappings, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + for (PartLibrary.LogicalPartMapping curr_mapping : p_logical_part_mappings) + { + if (curr_mapping.name.equals(p_part_name)) + { + if (curr_mapping.components.isEmpty()) + { + System.out.println("Network.search_lib_package: component list empty"); + return null; + } + String component_name = curr_mapping.components.first(); + if (component_name == null) + { + System.out.println("Network.search_lib_package: component list empty"); + return null; + } + eu.mihosoft.freerouting.board.Component curr_component = p_board.components.get(component_name); + if (curr_component == null) + { + System.out.println("Network.search_lib_package: component not found"); + return null; + } + return curr_component.get_package(); + } + } + System.out.print("Network.search_lib_package: eu.mihosoft.freerouting.library package "); + System.out.print(p_part_name); + System.out.println(" not found"); + return null; + } + + /** + * Inserts all eu.mihosoft.freerouting.board components belonging to the input eu.mihosoft.freerouting.library component. + */ + private static void insert_component(ComponentPlacement.ComponentLocation p_location, String p_lib_key, + ReadScopeParameter p_par) + { + eu.mihosoft.freerouting.board.RoutingBoard routing_board = p_par.board_handling.get_routing_board(); + eu.mihosoft.freerouting.library.Package curr_front_package = routing_board.library.packages.get(p_lib_key, true); + eu.mihosoft.freerouting.library.Package curr_back_package = routing_board.library.packages.get(p_lib_key, false); + if (curr_front_package == null || curr_back_package == null) + { + System.out.println("Network.insert_component: component package not found"); + return; + } + + IntPoint component_location; + if (p_location.coor != null) + { + component_location = p_par.coordinate_transform.dsn_to_board(p_location.coor).round(); + } + else + { + component_location = null; + } + double rotation_in_degree = p_location.rotation; + + eu.mihosoft.freerouting.board.Component new_component = routing_board.components.add(p_location.name, component_location, + rotation_in_degree, p_location.is_front, curr_front_package, curr_back_package, p_location.position_fixed); + + if (component_location == null) + { + return; // component is not yet placed. + } + Vector component_translation = component_location.difference_by(Point.ZERO); + eu.mihosoft.freerouting.board.FixedState fixed_state; + if (p_location.position_fixed) + { + fixed_state = eu.mihosoft.freerouting.board.FixedState.SYSTEM_FIXED; + } + else + { + fixed_state = eu.mihosoft.freerouting.board.FixedState.UNFIXED; + } + eu.mihosoft.freerouting.library.Package curr_package = new_component.get_package(); + for (int i = 0; i < curr_package.pin_count(); ++i) + { + eu.mihosoft.freerouting.library.Package.Pin curr_pin = curr_package.get_pin(i); + eu.mihosoft.freerouting.library.Padstack curr_padstack = routing_board.library.padstacks.get(curr_pin.padstack_no); + if (curr_padstack == null) + { + System.out.println("Network.insert_component: pin padstack not found"); + return; + } + Collection pin_nets = p_par.netlist.get_nets(p_location.name, curr_pin.name); + Collection net_numbers = new LinkedList(); + for (Net curr_pin_net : pin_nets) + { + eu.mihosoft.freerouting.rules.Net curr_board_net = routing_board.rules.nets.get(curr_pin_net.id.name, curr_pin_net.id.subnet_number); + if (curr_board_net == null) + { + System.out.println("Network.insert_component: eu.mihosoft.freerouting.board net not found"); + + } + else + { + net_numbers.add(curr_board_net.net_number); + } + } + int[] net_no_arr = new int[net_numbers.size()]; + int net_index = 0; + for (Integer curr_net_no : net_numbers) + { + net_no_arr[net_index] = curr_net_no; + ++net_index; + } + eu.mihosoft.freerouting.rules.NetClass net_class; + eu.mihosoft.freerouting.rules.Net board_net; + if (net_no_arr.length > 0) + { + board_net = routing_board.rules.nets.get(net_no_arr[0]); + } + else + { + board_net = null; + } + if (board_net != null) + { + net_class = board_net.get_class(); + } + else + { + net_class = routing_board.rules.get_default_net_class(); + } + int clearance_class = -1; + ComponentPlacement.ItemClearanceInfo pin_info = p_location.pin_infos.get(curr_pin.name); + if (pin_info != null) + { + clearance_class = routing_board.rules.clearance_matrix.get_no(pin_info.clearance_class); + } + if (clearance_class < 0) + { + if (curr_padstack.from_layer() == curr_padstack.to_layer()) + { + clearance_class = net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.SMD); + } + else + { + clearance_class = net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.PIN); + } + } + routing_board.insert_pin(new_component.no, i, net_no_arr, clearance_class, fixed_state); + } + + // insert the keepouts belonging to the package (k = 1 for via keepouts) + for (int k = 0; k <= 2; ++k) + { + eu.mihosoft.freerouting.library.Package.Keepout[] keepout_arr; + java.util.Map curr_keepout_infos; + if (k == 0) + { + keepout_arr = curr_package.keepout_arr; + curr_keepout_infos = p_location.keepout_infos; + } + else if (k == 1) + { + keepout_arr = curr_package.via_keepout_arr; + curr_keepout_infos = p_location.via_keepout_infos; + } + else + { + keepout_arr = curr_package.place_keepout_arr; + curr_keepout_infos = p_location.place_keepout_infos; + } + for (int i = 0; i < keepout_arr.length; ++i) + { + eu.mihosoft.freerouting.library.Package.Keepout curr_keepout = keepout_arr[i]; + int layer = curr_keepout.layer; + if (layer >= routing_board.get_layer_count()) + { + System.out.println("Network.insert_component: keepout layer is to big"); + continue; + } + if (layer >= 0 && !p_location.is_front) + { + layer = routing_board.get_layer_count() - curr_keepout.layer - 1; + } + int clearance_class = + routing_board.rules.get_default_net_class().default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.AREA); + ComponentPlacement.ItemClearanceInfo keepout_info = curr_keepout_infos.get(curr_keepout.name); + if (keepout_info != null) + { + int curr_clearance_class = routing_board.rules.clearance_matrix.get_no(keepout_info.clearance_class); + if (curr_clearance_class > 0) + { + clearance_class = curr_clearance_class; + } + } + if (layer >= 0) + { + if (k == 0) + { + routing_board.insert_obstacle(curr_keepout.area, layer, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + else if (k == 1) + { + routing_board.insert_via_obstacle(curr_keepout.area, layer, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + else + { + routing_board.insert_component_obstacle(curr_keepout.area, layer, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + } + else + { + // insert the obstacle on all signal layers + for (int j = 0; j < routing_board.layer_structure.arr.length; ++j) + { + if (routing_board.layer_structure.arr[j].is_signal) + { + if (k == 0) + { + routing_board.insert_obstacle(curr_keepout.area, j, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + else if (k == 1) + { + routing_board.insert_via_obstacle(curr_keepout.area, j, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + else + { + routing_board.insert_component_obstacle(curr_keepout.area, j, component_translation, + rotation_in_degree, !p_location.is_front, clearance_class, new_component.no, + curr_keepout.name, fixed_state); + } + } + } + } + } + } + // insert the outline as component keepout + for (int i = 0; i < curr_package.outline.length; ++i) + { + + routing_board.insert_component_outline(curr_package.outline[i], p_location.is_front, component_translation, + rotation_in_degree, new_component.no, fixed_state); + } + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Package.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Package.java new file mode 100644 index 0000000..4b5e2b4 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Package.java @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Package.java + * + * Created on 21. Mai 2004, 09:31 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import eu.mihosoft.freerouting.board.Item; + +/** + * Class for reading and writing package scopes from dsn-files. + * + * @author alfons + */ +public class Package +{ + + /** Creates a new instance of Package */ + public Package(String p_name, PinInfo[] p_pin_info_arr, Collection p_outline, Collection p_keepouts, + Collection p_via_keepouts, Collection p_place_keepouts, boolean p_is_front) + { + name = p_name; + pin_info_arr = p_pin_info_arr; + outline = p_outline; + keepouts = p_keepouts; + via_keepouts = p_via_keepouts; + place_keepouts = p_place_keepouts; + is_front = p_is_front; + } + + public static Package read_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + boolean is_front = true; + Collection outline = new LinkedList(); + Collection keepouts = new LinkedList(); + Collection via_keepouts = new LinkedList(); + Collection place_keepouts = new LinkedList(); + Object next_token = p_scanner.next_token(); + if ( !(next_token instanceof String)) + { + System.out.println("Package.read_scope: String expected"); + return null; + } + String package_name = (String) next_token; + Collection pin_info_list = new LinkedList(); + for (;;) + { + Object prev_token = next_token; + next_token = p_scanner.next_token(); + + if (next_token == null) + { + System.out.println("Package.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.PIN) + { + PinInfo next_pin = read_pin_info(p_scanner); + if (next_pin == null) + { + return null; + } + pin_info_list.add(next_pin); + } + else if (next_token == Keyword.SIDE) + { + is_front = read_placement_side(p_scanner); + } + else if (next_token == Keyword.OUTLINE) + { + Shape curr_shape = Shape.read_scope(p_scanner, p_layer_structure); + if (curr_shape != null) + { + outline.add(curr_shape); + } + // overread closing bracket + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Package.read_scope: closed bracket expected"); + return null; + } + } + else if (next_token == Keyword.KEEPOUT) + { + Shape.ReadAreaScopeResult keepout_area = Shape.read_area_scope(p_scanner, p_layer_structure, false); + if (keepout_area != null) + { + keepouts.add(keepout_area); + } + } + else if (next_token == Keyword.VIA_KEEPOUT) + { + Shape.ReadAreaScopeResult keepout_area = Shape.read_area_scope(p_scanner, p_layer_structure, false); + if (keepout_area != null) + { + via_keepouts.add(keepout_area); + } + } + else if (next_token == Keyword.PLACE_KEEPOUT) + { + Shape.ReadAreaScopeResult keepout_area = Shape.read_area_scope(p_scanner, p_layer_structure, false); + if (keepout_area != null) + { + place_keepouts.add(keepout_area); + } + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + } + PinInfo [] pin_info_arr = new PinInfo[pin_info_list.size()]; + Iterator it = pin_info_list.iterator(); + for (int i = 0; i < pin_info_arr.length; ++i) + { + pin_info_arr[i] = it.next(); + } + return new Package(package_name, pin_info_arr, outline, keepouts, via_keepouts, place_keepouts, is_front); + } + catch (java.io.IOException e) + { + System.out.println("Package.read_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + public static void write_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.library.Package p_package) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("image "); + p_par.identifier_type.write(p_package.name, p_par.file); + // write the placement side of the package + p_par.file.new_line(); + p_par.file.write("(side "); + if (p_package.is_front) + { + p_par.file.write("front)"); + } + else + { + p_par.file.write("back)"); + } + // write the pins of the package + for (int i = 0; i < p_package.pin_count(); ++i) + { + eu.mihosoft.freerouting.library.Package.Pin curr_pin = p_package.get_pin(i); + p_par.file.new_line(); + p_par.file.write("(pin "); + eu.mihosoft.freerouting.library.Padstack curr_padstack = p_par.board.library.padstacks.get(curr_pin.padstack_no); + p_par.identifier_type.write(curr_padstack.name, p_par.file); + p_par.file.write(" "); + p_par.identifier_type.write(curr_pin.name, p_par.file); + double [] rel_coor = p_par.coordinate_transform.board_to_dsn(curr_pin.relative_location); + for(int j = 0; j < rel_coor.length; ++j) + { + p_par.file.write(" "); + p_par.file.write((new Double(rel_coor[j])).toString()); + } + int rotation = (int) Math.round(curr_pin.rotation_in_degree); + if (rotation != 0) + { + p_par.file.write("(rotate "); + p_par.file.write((new Integer(rotation)).toString()); + p_par.file.write(")"); + } + p_par.file.write(")"); + } + // write the keepouts belonging to the package. + for (int i = 0; i < p_package.keepout_arr.length; ++i) + { + write_package_keepout(p_package.keepout_arr[i], p_par, false); + } + for (int i = 0; i < p_package.via_keepout_arr.length; ++i) + { + write_package_keepout(p_package.via_keepout_arr[i], p_par, true); + } + // write the package outline. + for (int i = 0; i < p_package.outline.length; ++i) + { + p_par.file.start_scope(); + p_par.file.write("outline"); + Shape curr_outline = p_par.coordinate_transform.board_to_dsn_rel(p_package.outline[i], Layer.SIGNAL); + curr_outline.write_scope(p_par.file, p_par.identifier_type); + p_par.file.end_scope(); + } + p_par.file.end_scope(); + } + + private static void write_package_keepout(eu.mihosoft.freerouting.library.Package.Keepout p_keepout, WriteScopeParameter p_par, + boolean p_is_via_keepout) throws java.io.IOException + { + Layer keepout_layer; + if (p_keepout.layer >= 0) + { + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[p_keepout.layer]; + keepout_layer = new Layer(board_layer.name, p_keepout.layer, board_layer.is_signal); + } + else + { + keepout_layer = Layer.SIGNAL; + } + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape; + eu.mihosoft.freerouting.geometry.planar.Shape [] holes; + if (p_keepout.area instanceof eu.mihosoft.freerouting.geometry.planar.Shape) + { + boundary_shape = (eu.mihosoft.freerouting.geometry.planar.Shape) p_keepout.area ; + holes = new eu.mihosoft.freerouting.geometry.planar.Shape [0]; + } + else + { + boundary_shape = p_keepout.area .get_border(); + holes = p_keepout.area .get_holes(); + } + p_par.file.start_scope(); + if (p_is_via_keepout) + { + p_par.file.write("via_keepout"); + } + else + { + p_par.file.write("keepout"); + } + Shape dsn_shape = p_par.coordinate_transform.board_to_dsn(boundary_shape, keepout_layer); + if (dsn_shape != null) + { + dsn_shape.write_scope(p_par.file, p_par.identifier_type); + } + for (int j = 0; j < holes.length; ++j) + { + Shape dsn_hole = p_par.coordinate_transform.board_to_dsn(holes[j], keepout_layer); + dsn_hole.write_hole_scope(p_par.file, p_par.identifier_type); + } + p_par.file.end_scope(); + } + + /** Reads the information of a single pin in a package. */ + private static PinInfo read_pin_info(Scanner p_scanner) + { + try + { + // Read the padstack name. + p_scanner.yybegin(SpecctraFileScanner.NAME); + String padstack_name = null; + Object next_token = p_scanner.next_token(); + if ( next_token instanceof String) + { + padstack_name = (String) next_token; + } + else if ( next_token instanceof Integer) + { + padstack_name = ((Integer) next_token).toString(); + } + else + { + System.out.println("Package.read_pin_info: String or Integer expected"); + return null; + } + double rotation = 0; + + p_scanner.yybegin(SpecctraFileScanner.NAME); // to be able to handle pin names starting with a digit. + next_token = p_scanner.next_token(); + if (next_token == Keyword.OPEN_BRACKET) + { + // read the padstack rotation + next_token = p_scanner.next_token(); + if (next_token == Keyword.ROTATE) + { + rotation = read_rotation(p_scanner); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + } + // Read the pin name. + String pin_name = null; + if ( next_token instanceof String) + { + pin_name = (String) next_token; + } + else if ( next_token instanceof Integer) + { + pin_name = ((Integer) next_token).toString(); + } + else + { + System.out.println("Package.read_pin_info: String or Integer expected"); + return null; + } + + double [] pin_coor = new double [2]; + for (int i = 0; i < 2; ++i) + { + next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + pin_coor[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + pin_coor[i] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Package.read_pin_info: number expected"); + return null; + } + } + // Handle scopes at the end of the pin scope. + for (;;) + { + Object prev_token = next_token; + next_token = p_scanner.next_token(); + + if (next_token == null) + { + System.out.println("Package.read_pin_info: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.ROTATE) + { + rotation = read_rotation(p_scanner); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + } + } + return new PinInfo(padstack_name, pin_name, pin_coor, rotation); + } + catch (java.io.IOException e) + { + System.out.println("Package.read_pin_info: IO error while scanning file"); + return null; + } + } + + private static double read_rotation(Scanner p_scanner) + { + double result = 0; + try + { + Object next_token = p_scanner.next_token(); + if (next_token instanceof Integer) + { + result = ((Integer)next_token).intValue(); + } + else if (next_token instanceof Double) + { + result = ((Double)next_token).doubleValue(); + } + else + { + System.out.println("Package.read_rotation: number expected"); + } + // Overread The closing bracket. + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Package.read_rotation: closing bracket expected"); + } + } + catch (java.io.IOException e) + { + System.out.println("Package.read_rotation: IO error while scanning file"); + } + return result; + } + + /** + * Writes the placements of p_package to a Specctra dsn-file. + */ + public static void write_placement_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.library.Package p_package) + throws java.io.IOException + { + Collection board_items = p_par.board.get_items(); + boolean component_found = false; + for (int i = 1; i <= p_par.board.components.count(); ++i) + { + eu.mihosoft.freerouting.board.Component curr_component = p_par.board.components.get(i); + if (curr_component.get_package() == p_package) + { + // check, if not all items of the component are deleted + boolean undeleted_item_found = false; + Iterator it = board_items.iterator(); + while (it.hasNext()) + { + Item curr_item = it.next(); + if (curr_item.get_component_no() == curr_component.no) + { + undeleted_item_found = true; + break; + } + } + if (undeleted_item_found || !curr_component.is_placed()) + { + if (!component_found) + { + // write the scope header + p_par.file.start_scope(); + p_par.file.write("component "); + p_par.identifier_type.write(p_package.name, p_par.file); + component_found = true; + } + Component.write_scope(p_par, curr_component); + } + } + } + if (component_found) + { + p_par.file.end_scope(); + } + } + + private static boolean read_placement_side(Scanner p_scanner) throws java.io.IOException + { + Object next_token = p_scanner.next_token(); + boolean result = (next_token != Keyword.BACK); + + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Package.read_placement_side: closing bracket expected"); + } + return result; + } + + + public final String name; + /** List of objects of type PinInfo. */ + public final PinInfo[] pin_info_arr; + /** The outline of the package. */ + public final Collection outline; + /** Collection of keepoouts belonging to this package */ + public final Collection keepouts; + /** Collection of via keepoouts belonging to this package */ + public final Collection via_keepouts; + /** Collection of place keepoouts belonging to this package */ + public final Collection place_keepouts; + /** If false, the package is placed on the back side of the eu.mihosoft.freerouting.board */ + public final boolean is_front; + + + /** Describes the Iinformation of a pin in a package. */ + static public class PinInfo + { + PinInfo(String p_padstack_name, String p_pin_name, double [] p_rel_coor, double p_rotation) + { + padstack_name = p_padstack_name; + pin_name = p_pin_name; + rel_coor = p_rel_coor; + rotation = p_rotation; + } + /** Phe name of the pastack of this pin. */ + public final String padstack_name; + /** Phe name of this pin. */ + public final String pin_name; + /** The x- and y-coordinates relative to the package location. */ + public final double [] rel_coor; + /** The rotation of the pin relative to the package. */ + public final double rotation; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Parser.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Parser.java new file mode 100644 index 0000000..5cba753 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Parser.java @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Parser.java + * + * Created on 24. Januar 2005, 08:29 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.board.Communication.SpecctraParserInfo; + +/** + * Class for reading and writing parser scopes from dsn-files. + * + * @author Alfons Wirtz + */ +public class Parser extends ScopeKeyword +{ + + /** Creates a new instance of Parser */ + public Parser() + { + super("parser"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Parser.read_scope: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("Parser.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + boolean read_ok = true; + if (prev_token == OPEN_BRACKET) + { + if (next_token == STRING_QUOTE) + { + String quote_char = read_quote_char(p_par.scanner); + if (quote_char == null) + { + return false; + } + p_par.string_quote = quote_char; + } + else if (next_token == HOST_CAD) + { + p_par.host_cad = DsnFile.read_string_scope(p_par.scanner); + } + else if (next_token == HOST_VERSION) + { + p_par.host_version = DsnFile.read_string_scope(p_par.scanner); + } + else if (next_token == CONSTANT) + { + String[] curr_constant = read_constant(p_par); + if (curr_constant != null) + { + p_par.constants.add(curr_constant); + } + } + else if (next_token == WRITE_RESOLUTION) + { + p_par.write_resolution = read_write_solution(p_par); + } + else if (next_token == GENERATED_BY_FREEROUTE) + { + p_par.dsn_file_generated_by_host = false; + // skip the closing bracket + skip_scope(p_par.scanner); + } + else + { + skip_scope(p_par.scanner); + } + } + if (!read_ok) + { + return false; + } + } + return true; + } + + private static SpecctraParserInfo.WriteResolution read_write_solution(ReadScopeParameter p_par) + { + try + { + Object next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Parser.read_write_solution: string expected"); + return null; + } + String resolution_string = (String) next_token; + next_token = p_par.scanner.next_token(); + if (!(next_token instanceof Integer)) + { + System.out.println("Parser.read_write_solution: integer expected expected"); + return null; + } + int resolution_value = (Integer) next_token; + next_token = p_par.scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Parser.read_write_solution: closing_bracket expected"); + return null; + } + return new SpecctraParserInfo.WriteResolution(resolution_string, resolution_value); + } + catch (java.io.IOException e) + { + System.out.println("Parser.read_write_solution: IO error scanning file"); + return null; + } + } + + private static String[] read_constant(ReadScopeParameter p_par) + { + try + { + String[] result = new String[2]; + p_par.scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Parser.read_constant: string expected"); + return null; + } + result[0] = (String) next_token; + p_par.scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Parser.read_constant: string expected"); + return null; + } + result[1] = (String) next_token; + next_token = p_par.scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Parser.read_constant: closing_bracket expected"); + return null; + } + return result; + } + catch (java.io.IOException e) + { + System.out.println("Parser.read_constant: IO error scanning file"); + return null; + } + } + + /** + * p_reduced is true if the scope is written to a session file. + */ + public static void write_scope(eu.mihosoft.freerouting.datastructures.IndentFileWriter p_file, SpecctraParserInfo p_parser_info, + eu.mihosoft.freerouting.datastructures.IdentifierType p_identifier_type, boolean p_reduced) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("parser"); + if (!p_reduced) + { + p_file.new_line(); + p_file.write("(string_quote "); + p_file.write(p_parser_info.string_quote); + p_file.write(")"); + p_file.new_line(); + p_file.write("(space_in_quoted_tokens on)"); + } + if (p_parser_info.host_cad != null) + { + p_file.new_line(); + p_file.write("(host_cad "); + p_identifier_type.write(p_parser_info.host_cad, p_file); + p_file.write(")"); + } + if (p_parser_info.host_version != null) + { + p_file.new_line(); + p_file.write("(host_version "); + p_identifier_type.write(p_parser_info.host_version, p_file); + p_file.write(")"); + } + if (p_parser_info.constants != null) + { + for (String[] curr_constant : p_parser_info.constants) + { + p_file.new_line(); + p_file.write("(constant "); + for (int i = 0; i < curr_constant.length; ++i) + { + p_identifier_type.write(curr_constant[i], p_file); + p_file.write(" "); + } + p_file.write(")"); + } + } + if (p_parser_info.write_resolution != null) + { + p_file.new_line(); + p_file.write("(write_resolution "); + p_file.write(p_parser_info.write_resolution.char_name.substring(0, 1)); + p_file.write(" "); + Integer positive_int = p_parser_info.write_resolution.positive_int; + p_file.write(positive_int.toString()); + p_file.write(")"); + } + if (!p_reduced) + { + p_file.new_line(); + p_file.write("(generated_by_freeroute)"); + } + p_file.end_scope(); + } + + private static String read_quote_char(Scanner p_scanner) + { + try + { + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Parser.read_quote_char: string expected"); + return null; + } + String result = (String) next_token; + next_token = p_scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Parser.read_quote_char: closing bracket expected"); + return null; + } + return result; + } + catch (java.io.IOException e) + { + System.out.println("Parser.read_quote_char: IO error scanning file"); + return null; + } + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PartLibrary.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PartLibrary.java new file mode 100644 index 0000000..31bd5f1 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PartLibrary.java @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * PartLibrary.java + * + * Created on 23. Maerz 2005, 08:36 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * + * @author Alfons Wirtz + */ +public class PartLibrary extends ScopeKeyword +{ + + /** Creates a new instance of PartLibrary */ + public PartLibrary() + { + super("part_library"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("PartLibrary.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (next_token == null) + { + System.out.println("PartLibrary.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == LOGICAL_PART_MAPPING) + { + LogicalPartMapping next_mapping = read_logical_part_mapping(p_par.scanner); + if (next_mapping == null) + { + return false; + } + p_par.logical_part_mappings.add(next_mapping); + } + else if (next_token == LOGICAL_PART) + { + LogicalPart next_part = read_logical_part(p_par.scanner); + if (next_part == null) + { + return false; + } + p_par.logical_parts.add(next_part); + } + else + { + skip_scope(p_par.scanner); + } + } + } + return true; + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + eu.mihosoft.freerouting.library.LogicalParts logical_parts = p_par.board.library.logical_parts; + if (logical_parts.count() <= 0) + { + return; + } + p_par.file.start_scope(); + p_par.file.write("part_library"); + + // write the logical part mappings + + for (int i = 1; i <= logical_parts.count(); ++i) + { + eu.mihosoft.freerouting.library.LogicalPart curr_part = logical_parts.get(i); + p_par.file.start_scope(); + p_par.file.write("logical_part_mapping "); + p_par.identifier_type.write(curr_part.name, p_par.file); + p_par.file.new_line(); + p_par.file.write("(comp"); + for (int j = 1; j <= p_par.board.components.count(); ++j) + { + eu.mihosoft.freerouting.board.Component curr_compomnent = p_par.board.components.get(j); + if (curr_compomnent.get_logical_part() == curr_part) + { + p_par.file.write(" "); + p_par.file.write(curr_compomnent.name); + } + } + p_par.file.write(")"); + p_par.file.end_scope(); + } + + // write the logical parts. + + for (int i = 1; i <= logical_parts.count(); ++i) + { + eu.mihosoft.freerouting.library.LogicalPart curr_part = logical_parts.get(i); + + p_par.file.start_scope(); + p_par.file.write("logical_part "); + p_par.identifier_type.write(curr_part.name, p_par.file); + p_par.file.new_line(); + for (int j = 0; j < curr_part.pin_count(); ++j) + { + p_par.file.new_line(); + eu.mihosoft.freerouting.library.LogicalPart.PartPin curr_pin = curr_part.get_pin(j); + p_par.file.write("(pin "); + p_par.identifier_type.write(curr_pin.pin_name, p_par.file); + p_par.file.write(" 0 "); + p_par.identifier_type.write(curr_pin.gate_name, p_par.file); + p_par.file.write(" "); + Integer gate_swap_code = curr_pin.gate_swap_code; + p_par.file.write(gate_swap_code.toString()); + p_par.file.write(" "); + p_par.identifier_type.write(curr_pin.gate_pin_name, p_par.file); + p_par.file.write(" "); + Integer gate_pin_swap_code = curr_pin.gate_pin_swap_code; + p_par.file.write(gate_pin_swap_code.toString()); + p_par.file.write(")"); + } + p_par.file.end_scope(); + } + p_par.file.end_scope(); + } + + /** + * Reads the component list of a logical part mapping. + * Returns null, if an error occured. + */ + private LogicalPartMapping read_logical_part_mapping(Scanner p_scanner) + { + try + { + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_logical_part_mapping: string expected"); + return null; + } + String name = (String) next_token; + next_token = p_scanner.next_token(); + if (next_token != OPEN_BRACKET) + { + System.out.println("PartLibrary.read_logical_part_mapping: open bracket expected"); + return null; + } + next_token = p_scanner.next_token(); + if (next_token != COMPONENT_SCOPE) + { + System.out.println("PartLibrary.read_logical_part_mapping: Keyword.COMPONENT_SCOPE expected"); + return null; + } + java.util.SortedSet result = new java.util.TreeSet(); + for(;;) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (next_token == CLOSED_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_logical_part_mapping: string expected"); + return null; + } + result.add((String) next_token); + } + next_token = p_scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("PartLibrary.read_logical_part_mapping: closing bracket expected"); + return null; + } + return new LogicalPartMapping(name, result); + } + catch (java.io.IOException e) + { + System.out.println("PartLibrary.read_logical_part_mapping: IO error scanning file"); + return null; + } + } + + private LogicalPart read_logical_part(Scanner p_scanner) + { + java.util.Collection part_pins = new java.util.LinkedList(); + Object next_token = null; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("PartLibrary.read_logical_part: IO error scanning file"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_logical_part: string expected"); + return null; + } + String part_name = (String) next_token; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("PartLibrary.read_logical_part: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("PartLibrary.read_logical_part: unexpected end of file"); + return null; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + boolean read_ok = true; + if (prev_token == OPEN_BRACKET) + { + if (next_token == PIN) + { + PartPin curr_part_pin = read_part_pin(p_scanner); + if (curr_part_pin == null) + { + return null; + } + part_pins.add(curr_part_pin); + } + else + { + skip_scope(p_scanner); + } + } + if (!read_ok) + { + return null; + } + } + return new LogicalPart(part_name, part_pins); + } + + private PartPin read_part_pin(Scanner p_scanner) + { + try + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_part_pin: string expected"); + return null; + } + String pin_name = (String) next_token; + next_token = p_scanner.next_token(); + if (!(next_token instanceof Integer)) + { + System.out.println("PartLibrary.read_part_pin: integer expected"); + return null; + } + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_part_pin: string expected"); + return null; + } + String gate_name = (String) next_token; + next_token = p_scanner.next_token(); + if (!(next_token instanceof Integer)) + { + System.out.println("PartLibrary.read_part_pin: integer expected"); + return null; + } + int gate_swap_code = (Integer) next_token; + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("PartLibrary.read_part_pin: string expected"); + return null; + } + String gate_pin_name = (String) next_token; + next_token = p_scanner.next_token(); + if (!(next_token instanceof Integer)) + { + System.out.println("PartLibrary.read_part_pin: integer expected"); + return null; + } + int gate_pin_swap_code = (Integer) next_token; + // overread subgates + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == CLOSED_BRACKET) + { + break; + } + } + return new PartPin(pin_name, gate_name, gate_swap_code, gate_pin_name, gate_pin_swap_code); + } + catch (java.io.IOException e) + { + System.out.println("PartLibrary.read_part_pin: IO error scanning file"); + return null; + } + } + + public static class LogicalPartMapping + { + private LogicalPartMapping(String p_name, java.util.SortedSet p_components) + { + name = p_name; + components = p_components; + } + /** The name of the maopping. */ + public final String name; + + /** The conponents belonging to the mapping. */ + public final java.util.SortedSet components; + } + + public static class PartPin + { + private PartPin(String p_pin_name, String p_gate_name, int p_gate_swap_code, + String p_gate_pin_name, int p_gate_pin_swap_code) + { + pin_name = p_pin_name; + gate_name = p_gate_name; + gate_swap_code = p_gate_swap_code; + gate_pin_name = p_gate_pin_name; + gate_pin_swap_code = p_gate_pin_swap_code; + } + + public final String pin_name; + public final String gate_name; + public final int gate_swap_code; + public final String gate_pin_name; + public final int gate_pin_swap_code; + } + + public static class LogicalPart + { + private LogicalPart(String p_name, java.util.Collection p_part_pins) + { + name = p_name; + part_pins = p_part_pins; + } + /** The name of the maopping. */ + public final String name; + + /** The pins of this logical part */ + public final java.util.Collection part_pins; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Path.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Path.java new file mode 100644 index 0000000..f484ba4 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Path.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Path.java + * + * Created on 30. Juni 2004, 09:28 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Class for writing path scopes from dsn-files. + * + * @author alfons + */ +public abstract class Path extends Shape +{ + + /** Creates a new instance of Path */ + Path(Layer p_layer, double p_width, double[] p_coordinate_arr) + { + super (p_layer); + width = p_width; + coordinate_arr = p_coordinate_arr; + } + + /** + * Writes this path as a scope to an output dsn-file. + */ + public abstract void write_scope(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException; + + public final double width; + public final double [] coordinate_arr; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PlaceControl.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PlaceControl.java new file mode 100644 index 0000000..735559f --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PlaceControl.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * PlaceControl.java + * + * Created on 25. November 2004, 13:21 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * Class for reading place_control scopes from dsn-files. + * + * @author Alfons Wirtz + */ +public class PlaceControl extends ScopeKeyword +{ + + /** Creates a new instance of PlaceControl */ + public PlaceControl() + { + super("place_control"); + } + + /** Reads the flip_style */ + public boolean read_scope(ReadScopeParameter p_par) + { + boolean flip_style_rotate_first = false; + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("PlaceControl.read_scope: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("PlaceControl.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == FLIP_STYLE) + { + flip_style_rotate_first = read_flip_style_rotate_first(p_par.scanner); + } + } + } + if (flip_style_rotate_first) + { + p_par.board_handling.get_routing_board().components.set_flip_style_rotate_first(true); + } + return true; + } + + /** + * Returns true, if rotate_first is read, else false. + */ + static boolean read_flip_style_rotate_first(Scanner p_scanner) + { + try + { + boolean result = false; + Object next_token = p_scanner.next_token(); + if (next_token == ROTATE_FIRST) + { + if (next_token == ROTATE_FIRST) + { + result = true; + } + } + next_token = p_scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Structure.read_flip_style: closing bracket expected"); + return false; + } + return result; + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_flip_style: IO error scanning file"); + return false; + } + } + +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Placement.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Placement.java new file mode 100644 index 0000000..538120a --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Placement.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Placement.java + * + * Created on 5. Juli 2004, 08:53 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * Class for writing placement scopes from dsn-files. + * + * @author Alfons Wirtz + */ +public class Placement extends ScopeKeyword +{ + + /** Creates a new instance of Placemet */ + public Placement() + { + super("placement"); + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("placement"); + if (p_par.board.components.get_flip_style_rotate_first()) + { + p_par.file.new_line(); + p_par.file.write("(place_control (flip_style rotate_first))"); + } + for (int i = 1; i <= p_par.board.library.packages.count(); ++i) + { + eu.mihosoft.freerouting.designforms.specctra.Package.write_placement_scope(p_par, p_par.board.library.packages.get(i)); + } + p_par.file.end_scope(); + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Plane.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Plane.java new file mode 100644 index 0000000..6e89d18 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Plane.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Plane.java + * + * Created on 19. Mai 2004, 08:39 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + + + +/** + * Class for reading and writing plane scopes from dsn-files. + * + * @author alfons + */ +public class Plane extends ScopeKeyword +{ + + /** Creates a new instance of Plane */ + public Plane() + { + super("plane"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + // read the net name + String net_name = null; + boolean skip_window_scopes = p_par.host_cad != null && p_par.host_cad.equalsIgnoreCase("allegro"); + // Cadence Allegro cutouts the pins on power planes, which leads to performance problems + // when dividing a conduction area into convex pieces. + Shape.ReadAreaScopeResult conduction_area = null; + try + { + Object next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Plane.read_scope: String expected"); + return false; + } + net_name = (String) next_token; + conduction_area = Shape.read_area_scope(p_par.scanner, p_par.layer_structure, skip_window_scopes); + } + catch (java.io.IOException e) + { + System.out.println("Plane.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + ReadScopeParameter.PlaneInfo plane_info = new ReadScopeParameter.PlaneInfo(conduction_area, net_name); + p_par.plane_list.add(plane_info); + return true; + } + + public static void write_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.ConductionArea p_conduction) throws java.io.IOException + { + int net_count = p_conduction.net_count(); + if (net_count <= 0 || net_count > 1) + { + System.out.println("Plane.write_scope: unexpected net count"); + return; + } + String net_name = p_par.board.rules.nets.get(p_conduction.get_net_no(0)).name; + eu.mihosoft.freerouting.geometry.planar.Area curr_area = p_conduction.get_area(); + int layer_no = p_conduction.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[ layer_no]; + Layer plane_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape; + eu.mihosoft.freerouting.geometry.planar.Shape [] holes; + if (curr_area instanceof eu.mihosoft.freerouting.geometry.planar.Shape) + { + boundary_shape = (eu.mihosoft.freerouting.geometry.planar.Shape) curr_area; + holes = new eu.mihosoft.freerouting.geometry.planar.Shape [0]; + } + else + { + boundary_shape = curr_area.get_border(); + holes = curr_area.get_holes(); + } + p_par.file.start_scope(); + p_par.file.write("plane "); + p_par.identifier_type.write(net_name, p_par.file); + Shape dsn_shape = p_par.coordinate_transform.board_to_dsn(boundary_shape, plane_layer); + if (dsn_shape != null) + { + dsn_shape.write_scope(p_par.file, p_par.identifier_type); + } + for (int i = 0; i < holes.length; ++i) + { + Shape dsn_hole = p_par.coordinate_transform.board_to_dsn(holes[i], plane_layer); + dsn_hole.write_hole_scope(p_par.file, p_par.identifier_type); + } + p_par.file.end_scope(); + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Polygon.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Polygon.java new file mode 100644 index 0000000..b195a53 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Polygon.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Polygon.java + * + * Created on 15. Mai 2004, 08:39 + */ + +package eu.mihosoft.freerouting.designforms.specctra; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Describes a polygon in a Specctra dsn file. + * + * @author alfons + */ +public class Polygon extends Shape +{ + /** + * Creates a new instance of Polygon + * p_coor is an array of dimension of dimension 2 * point_count and contains x0, y0, x1, y1, ... + * If the polygon is used as rectangle, + */ + public Polygon(Layer p_layer, double[] p_coor) + { + super(p_layer); + coor = p_coor; + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform) + { + IntPoint [] corner_arr = new IntPoint[coor.length / 2]; + double [] curr_point = new double [2]; + for (int i = 0; i < corner_arr.length; ++i) + { + curr_point[0] = coor[2 * i]; + curr_point[1] = coor[2 * i + 1]; + corner_arr[i] = p_coordinate_transform.dsn_to_board(curr_point).round(); + } + return new eu.mihosoft.freerouting.geometry.planar.PolygonShape(corner_arr); + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform) + { + if (coor.length < 2) + { + return eu.mihosoft.freerouting.geometry.planar.Simplex.EMPTY; + } + IntPoint [] corner_arr = new IntPoint[coor.length / 2]; + for (int i = 0; i < corner_arr.length; ++i) + { + int curr_x = (int) Math.round(p_coordinate_transform.dsn_to_board(coor[2 * i])); + int curr_y = (int) Math.round(p_coordinate_transform.dsn_to_board(coor[2 * i + 1])); + corner_arr[i] = new IntPoint(curr_x, curr_y); + } + return new eu.mihosoft.freerouting.geometry.planar.PolygonShape(corner_arr); + } + + public Rectangle bounding_box() + { + double[] bounds = new double[4]; + bounds[0] = Integer.MAX_VALUE; + bounds[1] = Integer.MAX_VALUE; + bounds[2] = Integer.MIN_VALUE; + bounds[3] = Integer.MIN_VALUE; + for (int i = 0; i < coor.length; ++i) + { + if (i % 2 == 0) + { + // x coordinate + bounds[0] = Math.min(bounds[0], coor[i]); + bounds[2] = Math.max(bounds[2], coor[i]); + } + else + { + // x coordinate + bounds[1] = Math.min(bounds[1], coor[i]); + bounds[3] = Math.max(bounds[3], coor[i]); + } + } + return new Rectangle(layer, bounds); + } + + /** + * Writes this polygon as a scope to an output dsn-file. + */ + public void write_scope(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("polygon "); + p_identifier_type.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Integer(0)).toString()); + int corner_count = coor.length/ 2; + for (int i = 0; i < corner_count; ++i) + { + p_file.new_line(); + p_file.write(new Double(coor[2 * i]).toString()); + p_file.write(" "); + p_file.write(new Double(coor[2 * i + 1]).toString()); + } + p_file.end_scope(); + } + + public void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("polygon "); + p_identifier_type.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Integer(0)).toString()); + int corner_count = coor.length/ 2; + for (int i = 0; i < corner_count; ++i) + { + p_file.new_line(); + Integer curr_coor = (int) Math.round(coor[2* i ]); + p_file.write(curr_coor.toString()); + p_file.write(" "); + curr_coor = (int) Math.round(coor[2* i + 1]); + p_file.write(curr_coor.toString()); + } + p_file.end_scope(); + } + + public final double [] coor; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolygonPath.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolygonPath.java new file mode 100644 index 0000000..47b31f9 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolygonPath.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Path.java + * + * Created on 24. Mai 2004, 08:10 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + + +/** + * Class for reading and writing path scopes consisting of a polygon from dsn-files. + * + * @author Alfons Wirtz + */ +public class PolygonPath extends Path +{ + + /** Creates a new instance of PolygonPath */ + public PolygonPath(Layer p_layer, double p_width, double[] p_coordinate_arr) + { + super(p_layer, p_width, p_coordinate_arr); + } + + + /** + * Writes this path as a scope to an output dsn-file. + */ + public void write_scope(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("path "); + p_identifier_type.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Double(this.width)).toString()); + int corner_count = coordinate_arr.length/ 2; + for (int i = 0; i < corner_count; ++i) + { + p_file.new_line(); + p_file.write(new Double(coordinate_arr[2 * i]).toString()); + p_file.write(" "); + p_file.write(new Double(coordinate_arr[2 * i + 1]).toString()); + } + p_file.end_scope(); + } + + public void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("path "); + p_identifier_type.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Double(this.width)).toString()); + int corner_count = coordinate_arr.length/ 2; + for (int i = 0; i < corner_count; ++i) + { + p_file.new_line(); + Integer curr_coor = (int) Math.round(coordinate_arr[2* i ]); + p_file.write(curr_coor.toString()); + p_file.write(" "); + curr_coor = (int) Math.round(coordinate_arr[2* i + 1]); + p_file.write(curr_coor.toString()); + } + p_file.end_scope(); + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform) + { + FloatPoint [] corner_arr = new FloatPoint[this.coordinate_arr.length / 2]; + double [] curr_point = new double [2]; + for (int i = 0; i < corner_arr.length; ++i) + { + curr_point[0] = this.coordinate_arr[2 * i]; + curr_point[1] = this.coordinate_arr[2 * i + 1]; + corner_arr[i] = p_coordinate_transform.dsn_to_board(curr_point); + } + double offset = p_coordinate_transform.dsn_to_board(this.width) / 2; + if (corner_arr.length <= 2) + { + IntOctagon bounding_oct = FloatPoint.bounding_octagon(corner_arr); + return bounding_oct.enlarge(offset); + } + IntPoint [] rounded_corner_arr = new IntPoint[corner_arr.length]; + for (int i = 0; i < corner_arr.length; ++i) + { + rounded_corner_arr[i] = corner_arr[i].round(); + } + eu.mihosoft.freerouting.geometry.planar.Shape result = new eu.mihosoft.freerouting.geometry.planar.PolygonShape(rounded_corner_arr); + if (offset > 0) + { + result = result.bounding_tile().enlarge(offset); + } + return result; + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform) + { + FloatPoint [] corner_arr = new FloatPoint[this.coordinate_arr.length / 2]; + double [] curr_point = new double [2]; + for (int i = 0; i < corner_arr.length; ++i) + { + curr_point[0] = this.coordinate_arr[2 * i]; + curr_point[1] = this.coordinate_arr[2 * i + 1]; + corner_arr[i] = p_coordinate_transform.dsn_to_board_rel(curr_point); + } + double offset = p_coordinate_transform.dsn_to_board(this.width) / 2; + if (corner_arr.length <= 2) + { + IntOctagon bounding_oct = FloatPoint.bounding_octagon(corner_arr); + return bounding_oct.enlarge(offset); + } + IntPoint [] rounded_corner_arr = new IntPoint[corner_arr.length]; + for (int i = 0; i < corner_arr.length; ++i) + { + rounded_corner_arr[i] = corner_arr[i].round(); + } + eu.mihosoft.freerouting.geometry.planar.Shape result = new eu.mihosoft.freerouting.geometry.planar.PolygonShape(rounded_corner_arr); + if (offset > 0) + { + result = result.bounding_tile().enlarge(offset); + } + return result; + } + + public Rectangle bounding_box() + { + double offset = this.width/2; + double[] bounds = new double[4]; + bounds[0] = Integer.MAX_VALUE; + bounds[1] = Integer.MAX_VALUE; + bounds[2] = Integer.MIN_VALUE; + bounds[3] = Integer.MIN_VALUE; + for (int i = 0; i < coordinate_arr.length; ++i) + { + if (i % 2 == 0) + { + // x coordinate + bounds[0] = Math.min(bounds[0], coordinate_arr[i] - offset); + bounds[2] = Math.max(bounds[2], coordinate_arr[i]) + offset; + } + else + { + // x coordinate + bounds[1] = Math.min(bounds[1], coordinate_arr[i] - offset); + bounds[3] = Math.max(bounds[3], coordinate_arr[i] + offset); + } + } + return new Rectangle(layer, bounds); + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolylinePath.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolylinePath.java new file mode 100644 index 0000000..68bc48e --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/PolylinePath.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * PolylinePath.java + * + * Created on 30. Juni 2004, 08:24 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + + +/** + * Describes a path defined by a sequence of lines (instead of a sequence of corners. + * + * @author alfons + */ +public class PolylinePath extends Path +{ + + /** Creates a new instance of PolylinePath */ + public PolylinePath(Layer p_layer, double p_width, double[] p_corner_arr) + { + super(p_layer, p_width, p_corner_arr); + } + + /** + * Writes this path as a scope to an output dsn-file. + */ + public void write_scope(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("polyline_path "); + p_identifier.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Double(this.width)).toString()); + int line_count = coordinate_arr.length/ 4; + for (int i = 0; i < line_count; ++i) + { + p_file.new_line(); + for (int j = 0; j < 4; ++j) + { + p_file.write(new Double(coordinate_arr[4 * i + j]).toString()); + p_file.write(" "); + } + } + p_file.end_scope(); + } + + public void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("polyline_path "); + p_identifier.write(this.layer.name, p_file); + p_file.write(" "); + p_file.write((new Double(this.width)).toString()); + int line_count = coordinate_arr.length/ 4; + for (int i = 0; i < line_count; ++i) + { + p_file.new_line(); + for (int j = 0; j < 4; ++j) + { + Integer curr_coor = (int) Math.round(coordinate_arr[4 * i + j]); + p_file.write(curr_coor.toString()); + p_file.write(" "); + } + } + p_file.end_scope(); + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform) + { + System.out.println("PolylinePath.transform_to_board_rel not implemented"); + return null; + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform) + { + System.out.println("PolylinePath.transform_to_board_rel not implemented"); + return null; + } + + + public Rectangle bounding_box() + { + System.out.println("PolylinePath.boundingbox not implemented"); + return null; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ReadScopeParameter.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ReadScopeParameter.java new file mode 100644 index 0000000..3fd8b56 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ReadScopeParameter.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * ReadScopeParameter.java + * + * Created on 21. Juni 2004, 08:28 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; + +/** + * Default parameter type used while reading a Specctra dsn-file. + * + * @author alfons + */ +public class ReadScopeParameter +{ + + /** Creates a new instance of ReadScopeParameter */ + ReadScopeParameter(Scanner p_scanner, eu.mihosoft.freerouting.interactive.IBoardHandling p_board_handling, + eu.mihosoft.freerouting.board.BoardObservers p_observers, + eu.mihosoft.freerouting.datastructures.IdNoGenerator p_item_id_no_generator, eu.mihosoft.freerouting.board.TestLevel p_test_level) + { + scanner = p_scanner; + board_handling = p_board_handling; + observers = p_observers; + item_id_no_generator = p_item_id_no_generator; + test_level = p_test_level; + } + + final Scanner scanner; + final eu.mihosoft.freerouting.interactive.IBoardHandling board_handling; + final NetList netlist = new NetList(); + + final eu.mihosoft.freerouting.board.BoardObservers observers; + final eu.mihosoft.freerouting.datastructures.IdNoGenerator item_id_no_generator; + final eu.mihosoft.freerouting.board.TestLevel test_level; + + /** Collection of elements of class PlaneInfo. + * The plane cannot be inserted directly into the boards, because the layers may not be read completely. + */ + final Collection plane_list = new LinkedList(); + + /** + * Component placement information. + * It is filled while reading the placement scope and can be + * evaluated after reading the eu.mihosoft.freerouting.library and network scope. + */ + final Collection placement_list = new LinkedList(); + + + /** + * The names of the via padstacks filled while reading the structure scope + * and evaluated after reading the eu.mihosoft.freerouting.library scope. + */ + Collection via_padstack_names = null; + + boolean via_at_smd_allowed = false; + eu.mihosoft.freerouting.board.AngleRestriction snap_angle = eu.mihosoft.freerouting.board.AngleRestriction.FORTYFIVE_DEGREE; + + /** The logical parts are used for pin and gate swaw */ + java.util.Collection logical_part_mappings + = new java.util.LinkedList(); + java.util.Collection logical_parts = new java.util.LinkedList(); + + /** The following objects are from the parser scope. */ + String string_quote = "\""; + String host_cad = null; + String host_version = null; + + boolean dsn_file_generated_by_host = true; + + boolean board_outline_ok = true; + + final Collection constants = new LinkedList(); + eu.mihosoft.freerouting.board.Communication.SpecctraParserInfo.WriteResolution write_resolution = null; + + + /** The following objects will be initialised when the structure scope is read. */ + CoordinateTransform coordinate_transform = null; + LayerStructure layer_structure = null; + eu.mihosoft.freerouting.interactive.AutorouteSettings autoroute_settings = null; + + eu.mihosoft.freerouting.board.Unit unit = eu.mihosoft.freerouting.board.Unit.MIL; + int resolution = 100; // default resulution + + /** Information for inserting a plane */ + static class PlaneInfo + { + PlaneInfo(Shape.ReadAreaScopeResult p_area, String p_net_name) + { + area = p_area; + net_name = p_net_name; + } + + final Shape.ReadAreaScopeResult area; + final String net_name; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rectangle.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rectangle.java new file mode 100644 index 0000000..b5ce490 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rectangle.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Rectangle.java + * + * Created on 15. Mai 2004, 08:39 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Describes a rectangle in a Specctra dsn file. + * + * @author alfons + */ +public class Rectangle extends Shape +{ + /** + * Creates a new instance of Rectangle + * p_coor is an array of dimension 4 and contains the rectangle coordinates + * in the following order: lower left x, lower left y, upper right x, uppper right y. + */ + public Rectangle(Layer p_layer, double[] p_coor) + { + super(p_layer); + coor = p_coor; + } + + public Rectangle bounding_box() + { + return this; + } + + /** + * Creates the smallest rectangle containing this rectangle and p_other + */ + public Rectangle union (Rectangle p_other) + { + double[] result_coor = new double[4]; + result_coor[0] = Math.min(this.coor[0], p_other.coor[0]); + result_coor[1] = Math.min(this.coor[1], p_other.coor[1]); + result_coor[2] = Math.max(this.coor[2], p_other.coor[2]); + result_coor[3] = Math.max(this.coor[3], p_other.coor[3]); + return new Rectangle(this.layer, result_coor); + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform) + { + int box_coor[] = new int[4]; + for (int i = 0; i < 4; ++i) + { + box_coor[i] = (int) Math.round(p_coordinate_transform.dsn_to_board(this.coor[i])); + } + + IntBox result; + if (box_coor[1] <= box_coor[3]) + { + // box_coor describe lower left and upper right corner + result = new IntBox(box_coor[0], box_coor[1], box_coor[2], box_coor[3]); + } + else + { + // box_coor describe upper left and lower right corner + result = new IntBox(box_coor[0], box_coor[3], box_coor[2], box_coor[1]); + } + return result; + } + + public eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform) + { + double [] curr_point = new double [2]; + curr_point[0] = Math.min(coor[0], coor[2]); + curr_point[1] = Math.min(coor[1], coor[3]); + FloatPoint lower_left = p_coordinate_transform.dsn_to_board(curr_point); + curr_point[0] = Math.max(coor[0], coor[2]); + curr_point[1] = Math.max(coor[1], coor[3]); + FloatPoint upper_right= p_coordinate_transform.dsn_to_board(curr_point); + return new IntBox(lower_left.round(), upper_right.round()); + } + + /** + * Writes this rectangle as a scope to an output dsn-file. + */ + public void write_scope(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(rect "); + p_identifier.write(this.layer.name, p_file); + for (int i = 0; i < coor.length; ++i) + { + p_file.write(" "); + p_file.write(new Double(coor[i]).toString()); + } + p_file.write(")"); + } + + public void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(rect "); + p_identifier.write(this.layer.name, p_file); + for (int i = 0; i < coor.length; ++i) + { + p_file.write(" "); + Integer curr_coor = (int) Math.round(coor[i]); + p_file.write(curr_coor.toString()); + } + p_file.write(")"); + } + + public final double [] coor; +} \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Resolution.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Resolution.java new file mode 100644 index 0000000..46db4fa --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Resolution.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Resolution.java + * + * Created on 30. Oktober 2004, 08:00 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * Class for reading resolution scopes from dsn-files. + * + * @author alfons + */ +public class Resolution extends ScopeKeyword +{ + + /** Creates a new instance of Resolution */ + public Resolution() + { + super("resolution"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + try + { + // read the unit + Object next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Resolution.read_scope: string expected"); + return false; + } + p_par.unit = eu.mihosoft.freerouting.board.Unit.from_string((String) next_token); + if (p_par.unit == null) + { + System.out.println("Resolution.read_scope: unit mil, inch or mm expected"); + return false; + } + // read the scale factor + next_token = p_par.scanner.next_token(); + if (!(next_token instanceof Integer)) + { + System.out.println("Resolution.read_scope: integer expected"); + return false; + } + p_par.resolution = ((Integer)next_token).intValue(); + // overread the closing bracket + next_token = p_par.scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Resolution.read_scope: closing bracket expected"); + return false; + } + return true; + } + catch (java.io.IOException e) + { + System.out.println("Resolution.read_scope: IO error scanning file"); + return false; + } + } + + public static void write_scope(eu.mihosoft.freerouting.datastructures.IndentFileWriter p_file, eu.mihosoft.freerouting.board.Communication p_board_communication) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(resolution "); + p_file.write(p_board_communication.unit.toString()); + p_file.write(" "); + p_file.write((new Integer(p_board_communication.resolution)).toString()); + p_file.write(")"); + } + +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rule.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rule.java new file mode 100644 index 0000000..71d574d --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Rule.java @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Rule.java + * + * Created on 1. Juni 2004, 09:27 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; + + +/** + * Class for reading and writing rule scopes from dsn-files. + * + * @author Alfons Wirtz + */ +public abstract class Rule +{ + /** + * Returns a collection of objects of class Rule. + */ + public static Collection read_scope( Scanner p_scanner) + { + Collection result = new LinkedList(); + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Rule.read_scope: IO error scanning file"); + System.out.println(e); + return null; + } + if (next_token == null) + { + System.out.println("Rule.read_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + Rule curr_rule = null; + if (next_token == Keyword.WIDTH) + { + curr_rule = read_width_rule(p_scanner); + } + else if (next_token == Keyword.CLEARANCE) + { + curr_rule = read_clearance_rule(p_scanner); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + if (curr_rule != null) + { + result.add(curr_rule); + } + + } + } + return result; + } + + /** + * Reads a LayerRule from dsn-file. + */ + public static LayerRule read_layer_rule_scope( Scanner p_scanner) + { + try + { + Collection layer_names = new LinkedList(); + Collection rule_list = new LinkedList(); + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.LAYER_NAME); + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.OPEN_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + + System.out.println("Rule.read_layer_rule_scope: string expected"); + return null; + } + layer_names.add((String) next_token); + } + for (;;) + { + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (next_token != Keyword.RULE) + { + + System.out.println("Rule.read_layer_rule_scope: rule expected"); + return null; + } + rule_list.addAll(read_scope(p_scanner)); + } + return new LayerRule(layer_names, rule_list); + } + catch (java.io.IOException e) + { + System.out.println("Rule.read_layer_rule_scope: IO error scanning file"); + return null; + } + } + + public static WidthRule read_width_rule(Scanner p_scanner) + { + try + { + double value; + Object next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + value = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + value = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Rule.read_width_rule: number expected"); + return null; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Rule.read_width_rule: closing bracket expected"); + return null; + } + return new WidthRule(value); + } + catch (java.io.IOException e) + { + System.out.println("Rule.read_width_rule: IO error scanning file"); + return null; + } + } + + public static void write_scope(eu.mihosoft.freerouting.rules.NetClass p_net_class, WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("rule"); + + // write the trace width + int default_trace_half_width = p_net_class.get_trace_half_width(0); + double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(default_trace_half_width); + p_par.file.new_line(); + p_par.file.write("(width "); + p_par.file.write((new Double(trace_width)).toString()); + p_par.file.write(")"); + p_par.file.end_scope(); + for (int i = 1; i < p_par.board.layer_structure.arr.length; ++i) + { + if (p_net_class.get_trace_half_width(i) != default_trace_half_width) + { + write_layer_rule(p_net_class, i, p_par); + } + } + } + + private static void write_layer_rule(eu.mihosoft.freerouting.rules.NetClass p_net_class, int p_layer_no, WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("layer_rule "); + + eu.mihosoft.freerouting.board.Layer curr_board_layer = p_par.board.layer_structure.arr[p_layer_no]; + + p_par.file.write(curr_board_layer.name); + p_par.file.start_scope(); + p_par.file.write("rule "); + + int curr_trace_half_width = p_net_class.get_trace_half_width(p_layer_no); + + // write the trace width + double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(curr_trace_half_width); + p_par.file.new_line(); + p_par.file.write("(width "); + p_par.file.write((new Double(trace_width)).toString()); + p_par.file.write(") "); + p_par.file.end_scope(); + p_par.file.end_scope(); + } + + /** + * Writes the default rule as a scope to an output dsn-file. + */ + public static void write_default_rule(WriteScopeParameter p_par, int p_layer) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("rule"); + // write the trace width + double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(p_par.board.rules.get_default_net_class().get_trace_half_width(0)); + p_par.file.new_line(); + p_par.file.write("(width "); + p_par.file.write((new Double(trace_width)).toString()); + p_par.file.write(")"); + // write the default clearance rule + int default_cl_no = eu.mihosoft.freerouting.rules.BoardRules.default_clearance_class(); + int default_board_clearance = p_par.board.rules.clearance_matrix.value(default_cl_no, default_cl_no, p_layer); + double default_clearance = p_par.coordinate_transform.board_to_dsn(default_board_clearance); + p_par.file.new_line(); + p_par.file.write("(clear "); + p_par.file.write((new Double(default_clearance)).toString()); + p_par.file.write(")"); + // write the Smd_to_turn_gap + Double smd_to_turn_dist = p_par.coordinate_transform.board_to_dsn(p_par.board.rules.get_pin_edge_to_turn_dist()); + p_par.file.new_line(); + p_par.file.write("(clear "); + p_par.file.write(smd_to_turn_dist.toString()); + p_par.file.write(" (type smd_to_turn_gap))"); + int cl_count = p_par.board.rules.clearance_matrix.get_class_count(); + for (int i = 1; i <= cl_count; ++i) + { + write_clearance_rules(p_par, p_layer, i, cl_count, default_board_clearance); + } + p_par.file.end_scope(); + } + + /** + * Write the clearance rules, which are different from the default clearance. + */ + private static void write_clearance_rules(WriteScopeParameter p_par, + int p_layer, int p_cl_class, int p_max_cl_class, int p_default_clearance) throws java.io.IOException + { + eu.mihosoft.freerouting.rules.ClearanceMatrix cl_matrix = p_par.board.rules.clearance_matrix; + for (int i = p_cl_class; i < p_max_cl_class; ++i) + { + int curr_board_clearance = cl_matrix.value(p_cl_class, i, p_layer); + if (curr_board_clearance == p_default_clearance) + { + continue; + } + double curr_clearance = p_par.coordinate_transform.board_to_dsn(curr_board_clearance); + p_par.file.new_line(); + p_par.file.write("(clear "); + p_par.file.write((new Double(curr_clearance)).toString()); + p_par.file.write(" (type "); + p_par.identifier_type.write(cl_matrix.get_name(p_cl_class), p_par.file); + p_par.file.write("_"); + p_par.identifier_type.write(cl_matrix.get_name(i), p_par.file); + p_par.file.write("))"); + } + } + + public static ClearanceRule read_clearance_rule(Scanner p_scanner) + { + try + { + double value; + Object next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + value = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + value = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Rule.read_clearance_rule: number expected"); + return null; + } + Collection class_pairs = new LinkedList (); + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + if (next_token != Keyword.OPEN_BRACKET) + { + System.out.println("Rule.read_clearance_rule: ( expected"); + return null; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.TYPE) + { + System.out.println("Rule.read_clearance_rule: type expected"); + return null; + } + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.IGNORE_QUOTE); + next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (!(next_token instanceof String)) + { + System.out.println("Rule.read_clearance_rule: string expected"); + return null; + } + class_pairs.add((String)next_token); + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Rule.read_clearance_rule: closing bracket expected"); + return null; + } + } + return new ClearanceRule(value, class_pairs); + } + catch (java.io.IOException e) + { + System.out.println("Rule.read_clearance_rule: IO error scanning file"); + return null; + } + + } + + static public void write_item_clearance_class( String p_name, eu.mihosoft.freerouting.datastructures.IndentFileWriter p_file, + eu.mihosoft.freerouting.datastructures.IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(clearance_class "); + p_identifier_type.write(p_name, p_file); + p_file.write(")"); + } + + public static class WidthRule extends Rule + { + public WidthRule(double p_value) + { + value = p_value; + } + final double value; + } + + public static class ClearanceRule extends Rule + { + public ClearanceRule(double p_value, Collection p_class_pairs) + { + value = p_value; + clearance_class_pairs = p_class_pairs; + } + final double value; + final Collection clearance_class_pairs; + } + + public static class LayerRule + { + LayerRule(Collection p_layer_names, Collection p_rules) + { + layer_names = p_layer_names; + rules = p_rules; + } + final Collection layer_names; + final Collection rules; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/RulesFile.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/RulesFile.java new file mode 100644 index 0000000..8730625 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/RulesFile.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * RulesFile.java + * + * Created on 18. Juli 2005, 07:07 + * + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; + +import eu.mihosoft.freerouting.board.BasicBoard; + +/** + * File for saving the eu.mihosoft.freerouting.board rules, so that they can be restored after the Board + * is creates anew from the host system. + * + * @author Alfons Wirtz + */ +public class RulesFile +{ + + public static void write(eu.mihosoft.freerouting.interactive.BoardHandling p_board_handling, java.io.OutputStream p_output_stream, String p_design_name) + { + IndentFileWriter output_file = new IndentFileWriter(p_output_stream); + BasicBoard routing_board = p_board_handling.get_routing_board(); + WriteScopeParameter write_scope_parameter = + new WriteScopeParameter(routing_board, p_board_handling.settings.autoroute_settings, + output_file, routing_board.communication.specctra_parser_info.string_quote, + routing_board.communication.coordinate_transform, false); + try + { + write_rules(write_scope_parameter, p_design_name); + } + catch (java.io.IOException e) + { + System.out.println("unable to write rules to file"); + } + try + { + output_file.close(); + } + catch (java.io.IOException e) + { + System.out.println("unable to close rules file"); + } + } + + public static boolean read(java.io.InputStream p_input_stream, String p_design_name, + eu.mihosoft.freerouting.interactive.BoardHandling p_board_handling) + { + BasicBoard routing_board = p_board_handling.get_routing_board(); + Scanner scanner = new SpecctraFileScanner(p_input_stream); + try + { + Object curr_token = scanner.next_token(); + if (curr_token != Keyword.OPEN_BRACKET) + { + System.out.println("RulesFile.read: open bracket expected"); + return false; + } + curr_token = scanner.next_token(); + if (curr_token != Keyword.RULES) + { + System.out.println("RulesFile.read: keyword rules expected"); + return false; + } + curr_token = scanner.next_token(); + if (curr_token != Keyword.PCB_SCOPE) + { + System.out.println("RulesFile.read: keyword pcb expected"); + return false; + } + scanner.yybegin(SpecctraFileScanner.NAME); + curr_token = scanner.next_token(); + if (!(curr_token instanceof String) || !((String) curr_token).equals(p_design_name)) + { + System.out.println("RulesFile.read: design_name not matching"); + return false; + } + } + catch (java.io.IOException e) + { + System.out.println("RulesFile.read: IO error scanning file"); + return false; + } + LayerStructure layer_structure = new LayerStructure(routing_board.layer_structure); + CoordinateTransform coordinate_transform = routing_board.communication.coordinate_transform; + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("RulesFile.read: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("Structure.read_scope: unexpected end of file"); + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + boolean read_ok = true; + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.RULE) + { + add_rules(Rule.read_scope(scanner), routing_board, null); + } + else if (next_token == Keyword.LAYER) + { + add_layer_rules(scanner, routing_board); + } + else if (next_token == Keyword.PADSTACK) + { + Library.read_padstack_scope(scanner, layer_structure, coordinate_transform, routing_board.library.padstacks); + } + else if (next_token == Keyword.VIA) + { + read_via_info(scanner, routing_board); + } + else if (next_token == Keyword.VIA_RULE) + { + read_via_rule(scanner, routing_board); + } + else if (next_token == Keyword.CLASS) + { + read_net_class(scanner, layer_structure, routing_board); + } + else if (next_token == Keyword.SNAP_ANGLE) + { + + eu.mihosoft.freerouting.board.AngleRestriction snap_angle = Structure.read_snap_angle(scanner); + if (snap_angle != null) + { + routing_board.rules.set_trace_angle_restriction(snap_angle); + } + } + else if (next_token == Keyword.AUTOROUTE_SETTINGS) + { + eu.mihosoft.freerouting.interactive.AutorouteSettings autoroute_settings + = AutorouteSettings.read_scope(scanner, layer_structure); + if (autoroute_settings != null) + { + p_board_handling.settings.autoroute_settings = autoroute_settings; + } + } + else + { + ScopeKeyword.skip_scope(scanner); + } + } + if (!read_ok) + { + return false; + } + } + return true; + } + + private static void write_rules( WriteScopeParameter p_par, String p_design_name) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("rules PCB "); + p_par.file.write(p_design_name); + Structure.write_snap_angle(p_par.file, p_par.board.rules.get_trace_angle_restriction()); + AutorouteSettings.write_scope(p_par.file, p_par.autoroute_settings, + p_par.board.layer_structure, p_par.identifier_type); + // write the default rule using 0 as default layer. + Rule.write_default_rule(p_par, 0); + // write the via padstacks + for (int i = 1; i <= p_par.board.library.padstacks.count(); ++i) + { + eu.mihosoft.freerouting.library.Padstack curr_padstack = p_par.board.library.padstacks.get(i); + if (p_par.board.library.get_via_padstack(curr_padstack.name )!= null) + { + Library.write_padstack_scope(p_par, curr_padstack); + } + } + Network.write_via_infos(p_par.board.rules, p_par.file, p_par.identifier_type); + Network.write_via_rules(p_par.board.rules, p_par.file, p_par.identifier_type); + Network.write_net_classes(p_par); + p_par.file.end_scope(); + } + + private static void add_rules(java.util.Collection p_rules, BasicBoard p_board, String p_layer_name) + { + int layer_no = -1; + if (p_layer_name != null) + { + layer_no = p_board.layer_structure.get_no(p_layer_name); + if (layer_no < 0) + { + System.out.println("RulesFile.add_rules: layer not found"); + } + } + CoordinateTransform coordinate_transform = p_board.communication.coordinate_transform; + String string_quote = p_board.communication.specctra_parser_info.string_quote; + for (Rule curr_rule : p_rules) + { + if (curr_rule instanceof Rule.WidthRule) + { + double wire_width = ((Rule.WidthRule)curr_rule).value; + int trace_halfwidth = (int) Math.round(coordinate_transform.dsn_to_board(wire_width) / 2); + if (layer_no < 0) + { + p_board.rules.set_default_trace_half_widths(trace_halfwidth); + } + else + { + p_board.rules.set_default_trace_half_width(layer_no, trace_halfwidth); + } + } + else if (curr_rule instanceof Rule.ClearanceRule) + { + Structure.set_clearance_rule(( Rule.ClearanceRule)curr_rule, layer_no, coordinate_transform, p_board.rules, string_quote); + } + } + } + + private static boolean add_layer_rules(Scanner p_scanner, BasicBoard p_board) + { + try + { + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("RulesFile.add_layer_rules: String expected"); + return false; + } + String layer_string = (String) next_token; + next_token = p_scanner.next_token(); + while (next_token != Keyword.CLOSED_BRACKET) + { + if (next_token != Keyword.OPEN_BRACKET) + { + System.out.println("RulesFile.add_layer_rules: ( expected"); + return false; + } + next_token = p_scanner.next_token(); + if (next_token == Keyword.RULE) + { + java.util.Collection curr_rules = Rule.read_scope(p_scanner); + add_rules(curr_rules, p_board, layer_string); + } + else + { + ScopeKeyword.skip_scope(p_scanner); + } + next_token = p_scanner.next_token(); + } + return true; + } + catch (java.io.IOException e) + { + System.out.println("RulesFile.add_layer_rules: IO error scanning file"); + return false; + } + } + private static boolean read_via_info(Scanner p_scanner, BasicBoard p_board) + { + eu.mihosoft.freerouting.rules.ViaInfo curr_via_info = Network.read_via_info(p_scanner, p_board); + if (curr_via_info == null) + { + return false; + } + eu.mihosoft.freerouting.rules.ViaInfo existing_via = p_board.rules.via_infos.get(curr_via_info.get_name()); + if (existing_via != null) + { + // replace existing via info + p_board.rules.via_infos.remove(existing_via); + } + p_board.rules.via_infos.add(curr_via_info); + return true; + } + + private static boolean read_via_rule(Scanner p_scanner, BasicBoard p_board) + { + java.util.Collection via_rule = Network.read_via_rule(p_scanner, p_board); + if (via_rule == null) + { + return false; + } + Network.add_via_rule(via_rule, p_board); + return true; + } + + private static boolean read_net_class(Scanner p_scanner, LayerStructure p_layer_structure, BasicBoard p_board) + { + NetClass curr_class = NetClass.read_scope(p_scanner); + if (curr_class == null) + { + return false; + } + Network.insert_net_class(curr_class, p_layer_structure, p_board, p_board.communication.coordinate_transform, false); + return true; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Scanner.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Scanner.java new file mode 100644 index 0000000..86320f3 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Scanner.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Scanner.java + * + * Created on 4. Juli 2004, 19:13 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * Interface for scanner generated by jflex. + * + * @author alfons + */ +public interface Scanner +{ + /** + * Reads the next token from the input file. + */ + Object next_token() throws java.io.IOException; + + /** + * Starts a new state. + */ + void yybegin(int p_new_state); +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ScopeKeyword.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ScopeKeyword.java new file mode 100644 index 0000000..62f352f --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/ScopeKeyword.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * ScopeKeyword.java + * + * Created on 12. Mai 2004, 08:47 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +/** + * + * @author alfons + */ + +/** Keywords defining a scope object*/ +public class ScopeKeyword extends Keyword +{ + public ScopeKeyword(String p_name) + { + super(p_name); + } + + /** + * Scips the current scope while reading a dsn file. + * Returns false, if no legal scope was found. + */ + public static boolean skip_scope(Scanner p_scanner) + { + int open_bracked_count = 1; + while (open_bracked_count > 0) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object curr_token = null; + try + { + curr_token = p_scanner.next_token(); + } + catch (Exception e) + { + System.out.println("ScopeKeyword.skip_scope: Error while scanning file"); + System.out.println(e); + return false; + } + if (curr_token == null) + { + return false; // end of file + } + if (curr_token == Keyword.OPEN_BRACKET) + { + ++open_bracked_count; + } + else if (curr_token == Keyword.CLOSED_BRACKET) + { + --open_bracked_count; + } + } + return true; + } + + /** + * Reads the next scope of this keyword from dsn file. + */ + public boolean read_scope(ReadScopeParameter p_par) + { + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("ScopeKeyword.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (next_token == null) + { + // end of file + return true; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == OPEN_BRACKET) + { + ScopeKeyword next_scope; + // a new scope is expected + if (next_token instanceof ScopeKeyword) + { + next_scope = (ScopeKeyword) next_token; + if (!next_scope.read_scope(p_par)) + { + return false; + } + + } + else + { + // skip unknown scope + skip_scope(p_par.scanner); + } + + } + } + return true; + } +} + diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionFile.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionFile.java new file mode 100644 index 0000000..79a55ee --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionFile.java @@ -0,0 +1,522 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * SessionFile.java + * + * Created on 29. Oktober 2004, 08:01 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Iterator; + +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; + +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.ConductionArea; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Methods to handle a Specctra session file. + * + * @author alfons + */ +public class SessionFile +{ + /** + * Creates a Specctra session file to update the host system from the RoutingBooard + */ + public static boolean write( BasicBoard p_board, java.io.OutputStream p_output_stream, String p_design_name) + { + if (p_output_stream == null) + { + return false; + } + IndentFileWriter output_file = null; + try + { + output_file = new IndentFileWriter(p_output_stream); + } + catch (Exception e) + { + System.out.println("unable to create session file"); + return false; + } + String session_name = p_design_name.replace(".dsn", ".ses"); + try + { + String [] reserved_chars = {"(", ")", " ", "-"}; + IdentifierType identifier_type = new IdentifierType(reserved_chars, p_board.communication.specctra_parser_info.string_quote); + write_session_scope(p_board, identifier_type, output_file, session_name, p_design_name); + } + catch (java.io.IOException e) + { + System.out.println("unable to write session file"); + return false; + } + try + { + output_file.close(); + } + catch (java.io.IOException e) + { + System.out.println("unable to close session file"); + return false; + } + return true; + } + + private static void write_session_scope(BasicBoard p_board, IdentifierType p_identifier_type, + IndentFileWriter p_file, String p_session_name, String p_design_name) throws java.io.IOException + { + double scale_factor = p_board.communication.coordinate_transform.dsn_to_board(1)/p_board.communication.resolution; + CoordinateTransform coordinate_transform = new CoordinateTransform(scale_factor, 0, 0); + p_file.start_scope(); + p_file.write("session "); + p_identifier_type.write(p_session_name, p_file); + p_file.new_line(); + p_file.write("(base_design "); + p_identifier_type.write(p_design_name, p_file); + p_file.write(")"); + write_placement(p_board, p_identifier_type, coordinate_transform, p_file); + write_was_is(p_board, p_identifier_type, p_file); + write_routes(p_board, p_identifier_type, coordinate_transform, p_file); + p_file.end_scope(); + } + + public static void write_placement(BasicBoard p_board, IdentifierType p_identifier_type, + CoordinateTransform p_coordinate_transform, IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("placement"); + Resolution.write_scope(p_file, p_board.communication); + + for (int i = 1; i <= p_board.library.packages.count(); ++i) + { + write_components(p_board, p_identifier_type, p_coordinate_transform, p_file, p_board.library.packages.get(i)); + } + p_file.end_scope(); + } + + /** + * Writes all components with the package p_package to the session file. + */ + public static void write_components(BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file, eu.mihosoft.freerouting.library.Package p_package) throws java.io.IOException + { + Collection board_items = p_board.get_items(); + boolean component_found = false; + for (int i = 1; i <= p_board.components.count(); ++i) + { + eu.mihosoft.freerouting.board.Component curr_component = p_board.components.get(i); + if (curr_component.get_package() == p_package) + { + // check, if not all items of the component are deleted + boolean undeleted_item_found = false; + Iterator it = board_items.iterator(); + while (it.hasNext()) + { + eu.mihosoft.freerouting.board.Item curr_item = it.next(); + if (curr_item.get_component_no() == curr_component.no) + { + undeleted_item_found = true; + break; + } + } + if (undeleted_item_found) + { + if (!component_found) + { + // write the scope header + p_file.start_scope(); + p_file.write("component "); + p_identifier_type.write(p_package.name, p_file); + component_found = true; + } + write_component(p_board, p_identifier_type, p_coordinate_transform, p_file, curr_component); + } + } + } + if (component_found) + { + p_file.end_scope(); + } + } + + public static void write_component(BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file, eu.mihosoft.freerouting.board.Component p_component) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(place "); + p_identifier_type.write(p_component.name, p_file); + double[] location = p_coordinate_transform.board_to_dsn(p_component.get_location().to_float()); + Integer x_coor = (int) Math.round(location[0]); + Integer y_coor = (int) Math.round(location[1]); + p_file.write(" "); + p_file.write(x_coor.toString()); + p_file.write(" "); + p_file.write(y_coor.toString()); + if (p_component.placed_on_front()) + { + p_file.write(" front "); + } + else + { + p_file.write(" back "); + } + int rotation = (int) Math.round(p_component.get_rotation_in_degree()); + p_file.write((new Integer(rotation).toString())); + if (p_component.position_fixed) + { + p_file.new_line(); + p_file.write(" (lock_type position)"); + } + p_file.write(")"); + } + + public static void write_was_is(BasicBoard p_board, IdentifierType p_identifier_type, + IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("was_is"); + Collection board_pins = p_board.get_pins(); + for (eu.mihosoft.freerouting.board.Pin curr_pin : board_pins) + { + eu.mihosoft.freerouting.board.Pin swapped_with = curr_pin.get_changed_to(); + if (curr_pin.get_changed_to() != curr_pin) + { + p_file.new_line(); + p_file.write("(pins "); + eu.mihosoft.freerouting.board.Component curr_cmp = p_board.components.get(curr_pin.get_component_no()); + if (curr_cmp != null) + { + p_identifier_type.write(curr_cmp.name, p_file); + p_file.write("-"); + eu.mihosoft.freerouting.library.Package.Pin package_pin = curr_cmp.get_package().get_pin(curr_pin.get_index_in_package()); + p_identifier_type.write(package_pin.name, p_file); + } + else + { + System.out.println("SessionFile.write_was_is: component not found"); + } + p_file.write(" "); + eu.mihosoft.freerouting.board.Component swap_cmp = p_board.components.get(swapped_with.get_component_no()); + if (swap_cmp != null) + { + p_identifier_type.write(swap_cmp.name, p_file); + p_file.write("-"); + eu.mihosoft.freerouting.library.Package.Pin package_pin = swap_cmp.get_package().get_pin(swapped_with.get_index_in_package()); + p_identifier_type.write(package_pin.name, p_file); + } + else + { + System.out.println("SessionFile.write_was_is: component not found"); + } + p_file.write(")"); + } + } + p_file.end_scope(); + } + + private static void write_routes(BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("routes "); + Resolution.write_scope(p_file, p_board.communication); + Parser.write_scope(p_file,p_board.communication.specctra_parser_info, p_identifier_type, true); + write_library(p_board, p_identifier_type, p_coordinate_transform, p_file); + write_network(p_board, p_identifier_type, p_coordinate_transform, p_file); + p_file.end_scope(); + } + + private static void write_library(BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("library_out "); + for (int i = 0; i < p_board.library.via_padstack_count(); ++i) + { + write_padstack(p_board.library.get_via_padstack(i), p_board, p_identifier_type, p_coordinate_transform, p_file); + } + p_file.end_scope(); + } + + private static void write_padstack(eu.mihosoft.freerouting.library.Padstack p_padstack, BasicBoard p_board, IdentifierType p_identifier_type, + CoordinateTransform p_coordinate_transform, IndentFileWriter p_file) + throws java.io.IOException + { + // search the layer range of the padstack + int first_layer_no = 0; + while (first_layer_no < p_board.get_layer_count()) + { + if (p_padstack.get_shape(first_layer_no) != null) + { + break; + } + ++first_layer_no; + } + int last_layer_no = p_board.get_layer_count() - 1; + while (last_layer_no >= 0 ) + { + if (p_padstack.get_shape(last_layer_no) != null) + { + break; + } + --last_layer_no; + } + if (first_layer_no >= p_board.get_layer_count() || last_layer_no < 0) + { + System.out.println("SessionFile.write_padstack: padstack shape not found"); + return; + } + + p_file.start_scope(); + p_file.write("padstack "); + p_identifier_type.write(p_padstack.name, p_file); + for (int i = first_layer_no; i <= last_layer_no; ++i) + { + eu.mihosoft.freerouting.geometry.planar.Shape curr_board_shape = p_padstack.get_shape(i); + if (curr_board_shape == null) + { + continue; + } + eu.mihosoft.freerouting.board.Layer board_layer = p_board.layer_structure.arr[i]; + Layer curr_layer = new Layer(board_layer.name, i, board_layer.is_signal); + Shape curr_shape = p_coordinate_transform.board_to_dsn_rel(curr_board_shape, curr_layer); + p_file.start_scope(); + p_file.write("shape"); + curr_shape.write_scope_int(p_file, p_identifier_type); + p_file.end_scope(); + } + if (!p_padstack.attach_allowed) + { + p_file.new_line(); + p_file.write("(attach off)"); + } + p_file.end_scope(); + } + + + + private static void write_network(BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("network_out "); + for (int i = 1; i <= p_board.rules.nets.max_net_no(); ++i) + { + write_net(i, p_board, p_identifier_type, p_coordinate_transform, p_file); + } + p_file.end_scope(); + } + + private static void write_net(int p_net_no, BasicBoard p_board, IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file) throws java.io.IOException + { + Collection net_items = p_board.get_connectable_items(p_net_no); + boolean header_written = false; + Iterator it = net_items.iterator(); + while (it.hasNext()) + { + eu.mihosoft.freerouting.board.Item curr_item = it.next(); + if (curr_item.get_fixed_state() == eu.mihosoft.freerouting.board.FixedState.SYSTEM_FIXED) + { + continue; + } + boolean is_wire = curr_item instanceof PolylineTrace; + boolean is_via = curr_item instanceof Via; + boolean is_conduction_area = curr_item instanceof ConductionArea + && p_board.layer_structure.arr [curr_item.first_layer()].is_signal; + if (!header_written && (is_wire || is_via || is_conduction_area)) + { + p_file.start_scope(); + p_file.write("net "); + eu.mihosoft.freerouting.rules.Net curr_net = p_board.rules.nets.get(p_net_no); + if (curr_net == null) + { + System.out.println("SessionFile.write_net: net not found"); + } + else + { + p_identifier_type.write(curr_net.name, p_file); + } + header_written = true; + } + if (is_wire) + { + write_wire((PolylineTrace)curr_item, p_board, p_identifier_type, p_coordinate_transform, p_file); + } + else if (is_via) + { + write_via((Via) curr_item, p_board, p_identifier_type, p_coordinate_transform, p_file); + } + else if (is_conduction_area) + { + write_conduction_area( (ConductionArea) curr_item, p_board, p_identifier_type, + p_coordinate_transform, p_file); + } + } + if (header_written) + { + p_file.end_scope(); + } + } + + private static void write_wire(PolylineTrace p_wire, BasicBoard p_board, IdentifierType p_identifier_type, + CoordinateTransform p_coordinate_transform, IndentFileWriter p_file) throws java.io.IOException + { + int layer_no = p_wire.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_board.layer_structure.arr[layer_no]; + int wire_width = (int) Math.round(p_coordinate_transform.board_to_dsn(2 * p_wire.get_half_width())); + p_file.start_scope(); + p_file.write("wire"); + Point[] corner_arr = p_wire.polyline().corner_arr(); + int [] coors = new int [2 * corner_arr.length]; + int corner_index = 0; + int [] prev_coors = null; + for (int i = 0; i < corner_arr.length; ++i) + { + double[] curr_float_coors = p_coordinate_transform.board_to_dsn(corner_arr[i].to_float()); + int [] curr_coors = new int[2]; + curr_coors[0] = (int) Math.round(curr_float_coors[0]); + curr_coors[1] = (int) Math.round(curr_float_coors[1]); + if (i == 0 || ( curr_coors[0] != prev_coors[0] || curr_coors[1] != prev_coors[1])) + { + coors[corner_index] = curr_coors[0]; + ++corner_index; + coors[corner_index] = curr_coors[1]; + ++corner_index; + prev_coors = curr_coors; + + } + } + if (corner_index < coors.length) + { + int [] adjusted_coors = new int[corner_index]; + for (int i = 0; i < adjusted_coors.length; ++i) + { + adjusted_coors[i] = coors[i]; + } + coors = adjusted_coors; + } + write_path(board_layer.name, wire_width, coors, p_identifier_type, p_file); + write_fixed_state(p_file, p_wire.get_fixed_state()); + p_file.end_scope(); + } + + private static void write_via(Via p_via, BasicBoard p_board, IdentifierType p_identifier_type, + CoordinateTransform p_coordinate_transform, IndentFileWriter p_file) throws java.io.IOException + { + eu.mihosoft.freerouting.library.Padstack via_padstack = p_via.get_padstack(); + FloatPoint via_location = p_via.get_center().to_float(); + p_file.start_scope(); + p_file.write("via "); + p_identifier_type.write(via_padstack.name, p_file); + p_file.write(" "); + double[] location = p_coordinate_transform.board_to_dsn(via_location); + Integer x_coor = (int) Math.round(location[0]); + p_file.write(x_coor.toString()); + p_file.write(" "); + Integer y_coor = (int) Math.round(location[1]); + p_file.write(y_coor.toString()); + write_fixed_state(p_file, p_via.get_fixed_state()); + p_file.end_scope(); + } + + static private void write_fixed_state(IndentFileWriter p_file, eu.mihosoft.freerouting.board.FixedState p_fixed_state) throws java.io.IOException + { + if (p_fixed_state.ordinal() <= eu.mihosoft.freerouting.board.FixedState.SHOVE_FIXED.ordinal()) + { + return; + } + p_file.new_line(); + p_file.write("(type "); + if (p_fixed_state == eu.mihosoft.freerouting.board.FixedState.SYSTEM_FIXED) + { + p_file.write("fix)"); + } + else + { + p_file.write("protect)"); + } + } + + private static void write_path(String p_layer_name, int p_width, int[] p_coors, IdentifierType p_identifier_type, + IndentFileWriter p_file) + throws java.io.IOException + { + p_file.start_scope(); + p_file.write("path "); + p_identifier_type.write(p_layer_name, p_file); + p_file.write(" "); + p_file.write((new Integer(p_width)).toString()); + int corner_count = p_coors.length/ 2; + for (int i = 0; i < corner_count; ++i) + { + p_file.new_line(); + p_file.write(new Integer(p_coors[2 * i]).toString()); + p_file.write(" "); + p_file.write(new Integer(p_coors[2 * i + 1]).toString()); + } + p_file.end_scope(); + } + + private static void write_conduction_area( ConductionArea p_conduction_area, BasicBoard p_board, + IdentifierType p_identifier_type, CoordinateTransform p_coordinate_transform, + IndentFileWriter p_file) throws java.io.IOException + { + int net_count = p_conduction_area.net_count(); + if (net_count <= 0 || net_count > 1) + { + System.out.println("SessionFile.write_conduction_area: unexpected net count"); + return; + } + eu.mihosoft.freerouting.geometry.planar.Area curr_area = p_conduction_area.get_area(); + int layer_no = p_conduction_area.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_board.layer_structure.arr[ layer_no]; + Layer conduction_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape; + eu.mihosoft.freerouting.geometry.planar.Shape [] holes; + if (curr_area instanceof eu.mihosoft.freerouting.geometry.planar.Shape) + { + boundary_shape = (eu.mihosoft.freerouting.geometry.planar.Shape) curr_area; + holes = new eu.mihosoft.freerouting.geometry.planar.Shape [0]; + } + else + { + boundary_shape = curr_area.get_border(); + holes = curr_area.get_holes(); + } + p_file.start_scope(); + p_file.write("wire "); + Shape dsn_shape = p_coordinate_transform.board_to_dsn(boundary_shape, conduction_layer); + if (dsn_shape != null) + { + dsn_shape.write_scope_int(p_file, p_identifier_type); + } + for (int i = 0; i < holes.length; ++i) + { + Shape dsn_hole = p_coordinate_transform.board_to_dsn(holes[i], conduction_layer); + dsn_hole.write_hole_scope(p_file, p_identifier_type); + } + p_file.end_scope(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionToEagle.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionToEagle.java new file mode 100644 index 0000000..07f8899 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SessionToEagle.java @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * SessionToEagle.java + * + * Created on 8. Dezember 2004, 07:42 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + + +/** + * Transformes a Specctra session file into an Eagle script file. + * + * @author Alfons Wirtz + */ +public class SessionToEagle extends javax.swing.JFrame +{ + + public static boolean get_instance(java.io.InputStream p_session, java.io.OutputStream p_output_stream, + eu.mihosoft.freerouting.board.BasicBoard p_board) + { + if (p_output_stream == null) + { + return false; + } + + // create a scanner for reading the session_file. + + Scanner scanner = new SpecctraFileScanner(p_session); + + // create a file_writer for the eagle script file. + java.io.OutputStreamWriter file_writer = new java.io.OutputStreamWriter(p_output_stream); + + boolean result = true; + + double board_scale_factor = p_board.communication.coordinate_transform.board_to_dsn(1); + SessionToEagle new_instance = new SessionToEagle(scanner, file_writer, p_board, + p_board.communication.unit, p_board.communication.resolution, board_scale_factor); + + try + { + result = new_instance.process_session_scope(); + } + catch (java.io.IOException e) + { + System.out.println("unable to process session scope"); + result = false; + } + + // close files + try + { + p_session.close(); + file_writer.close(); + } + catch (java.io.IOException e) + { + System.out.println("unable to close files"); + } + return result; + } + + SessionToEagle(Scanner p_scanner, java.io.OutputStreamWriter p_out_file, eu.mihosoft.freerouting.board.BasicBoard p_board, + eu.mihosoft.freerouting.board.Unit p_unit, double p_session_file_scale_dominator, double p_board_scale_factor) + { + scanner = p_scanner; + out_file = p_out_file; + board = p_board; + this.specctra_layer_structure = new LayerStructure(p_board.layer_structure); + unit = p_unit; + session_file_scale_denominator = p_session_file_scale_dominator; + board_scale_factor = p_board_scale_factor; + } + + /** + * Processes the outmost scope of the session file. + * Returns false, if an error occured. + */ + private boolean process_session_scope() throws java.io.IOException + { + + // read the first line of the session file + Object next_token = null; + for (int i = 0; i < 3; ++i) + { + next_token = this.scanner.next_token(); + boolean keyword_ok = true; + if (i == 0) + { + keyword_ok = (next_token == Keyword.OPEN_BRACKET); + } + else if (i == 1) + { + keyword_ok = (next_token == Keyword.SESSION); + this.scanner.yybegin(SpecctraFileScanner.NAME); // to overread the name of the pcb for i = 2 + } + if (!keyword_ok) + { + System.out.println("SessionToEagle.process_session_scope specctra session file format expected"); + return false; + } + } + + // Write the header of the eagle script file. + + this.out_file.write("GRID "); + this.out_file.write(this.unit.toString()); + this.out_file.write("\n"); + this.out_file.write("SET WIRE_BEND 2\n"); + this.out_file.write("SET OPTIMIZING OFF\n"); + + // Activate all layers in Eagle. + + for (int i = 0; i < this.board.layer_structure.arr.length; ++i) + { + this.out_file.write("LAYER " + this.get_eagle_layer_string(i) + ";\n"); + } + + this.out_file.write("LAYER 17;\n"); + this.out_file.write("LAYER 18;\n"); + this.out_file.write("LAYER 19;\n"); + this.out_file.write("LAYER 20;\n"); + this.out_file.write("LAYER 23;\n"); + this.out_file.write("LAYER 24;\n"); + + // Generate Code to remove the complete route. + // Write a bounding rectangle with GROUP (Min_X-1 Min_Y-1) (Max_X+1 Max_Y+1); + + eu.mihosoft.freerouting.geometry.planar.IntBox board_bounding_box = this.board.get_bounding_box(); + + Float min_x = (float) this.board_scale_factor * (board_bounding_box.ll.x - 1); + Float min_y = (float) this.board_scale_factor * (board_bounding_box.ll.y - 1); + Float max_x = (float) this.board_scale_factor * (board_bounding_box.ur.x + 1); + Float max_y = (float) this.board_scale_factor * (board_bounding_box.ur.y + 1); + + this.out_file.write("GROUP ("); + this.out_file.write(min_x.toString()); + this.out_file.write(" "); + this.out_file.write(min_y.toString()); + this.out_file.write(") ("); + this.out_file.write(max_x.toString()); + this.out_file.write(" "); + this.out_file.write(max_y.toString()); + this.out_file.write(");\n"); + this.out_file.write("RIPUP;\n"); + + // read the direct subscopes of the session scope + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + // end of file + return true; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.ROUTES) + { + if (!process_routes_scope()) + { + return false; + } + } + else if (next_token == Keyword.PLACEMENT_SCOPE) + { + if (!process_placement_scope()) + { + return false; + } + } + else + { + // overread all scopes except the routes scope for the time being + ScopeKeyword.skip_scope(this.scanner); + } + } + } + // Wird nur einmal am Ende benoetigt! + this.out_file.write("RATSNEST\n"); + return true; + } + + private boolean process_placement_scope() throws java.io.IOException + { + // read the component scopes + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + // unexpected end of file + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + + if (next_token == Keyword.COMPONENT_SCOPE) + { + if (!process_component_placement()) + { + return false; + } + } + else + { + // skip unknown scope + ScopeKeyword.skip_scope(this.scanner); + } + + } + } + process_swapped_pins(); + return true; + } + + private boolean process_component_placement() throws java.io.IOException + { + ComponentPlacement component_placement = Component.read_scope(this.scanner); + if (component_placement == null) + { + return false; + } + for (ComponentPlacement.ComponentLocation curr_location : component_placement.locations) + { + this.out_file.write("ROTATE ="); + Integer rotation = (int) Math.round(curr_location.rotation); + String rotation_string; + if (curr_location.is_front) + { + rotation_string = "R" + rotation.toString(); + } + else + { + rotation_string = "MR" + rotation.toString(); + } + this.out_file.write(rotation_string); + this.out_file.write(" '"); + this.out_file.write(curr_location.name); + this.out_file.write("';\n"); + this.out_file.write("move '"); + this.out_file.write(curr_location.name); + this.out_file.write("' ("); + Double x_coor = curr_location.coor[0] / this.session_file_scale_denominator; + this.out_file.write(x_coor.toString()); + this.out_file.write(" "); + Double y_coor = curr_location.coor[1] / this.session_file_scale_denominator; + this.out_file.write(y_coor.toString()); + this.out_file.write(");\n"); + } + return true; + } + + private boolean process_routes_scope() throws java.io.IOException + { + // read the direct subscopes of the routes scope + boolean result = true; + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + // unexpected end of file + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + + if (next_token == Keyword.NETWORK_OUT) + { + result = process_network_scope(); + } + else + { + // skip unknown scope + ScopeKeyword.skip_scope(this.scanner); + } + + } + } + return result; + } + + private boolean process_network_scope() throws java.io.IOException + { + boolean result = true; + Object next_token = null; + // read the net scopes + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + // unexpected end of file + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + + if (next_token == Keyword.NET) + { + result = process_net_scope(); + } + else + { + // skip unknown scope + ScopeKeyword.skip_scope(this.scanner); + } + + } + } + return result; + } + + private boolean process_net_scope() throws java.io.IOException + { + // read the net name + Object next_token = this.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("SessionToEagle.processnet_scope: String expected"); + return false; + } + String net_name = (String) next_token; + + // Hier alle nicht gefixten Traces und Vias des Netz mit Namen net_name + // in der Eagle Datenhaltung loeschen. + + // read the wires and vias of this net + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + // end of file + return true; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.WIRE) + { + if (!process_wire_scope(net_name)) + { + return false; + } + } + else if (next_token == Keyword.VIA) + { + if (!process_via_scope(net_name)) + { + return false; + } + } + else + { + ScopeKeyword.skip_scope(this.scanner); + } + } + } + return true; + } + + private boolean process_wire_scope(String p_net_name) throws java.io.IOException + { + PolygonPath wire_path = null; + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + next_token = this.scanner.next_token(); + if (next_token == null) + { + System.out.println("SessionToEagle.process_wire_scope: unexpected end of file"); + return false; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.POLYGON_PATH) + { + wire_path = Shape.read_polygon_path_scope(this.scanner, this.specctra_layer_structure); + } + else + { + ScopeKeyword.skip_scope(this.scanner); + } + } + } + if (wire_path == null) + { + // conduction areas are skipped + return true; + } + + this.out_file.write("CHANGE LAYER "); + + this.out_file.write(wire_path.layer.name); + this.out_file.write(";\n"); + + //WIRE ['signal_name'] [width] [ROUND | FLAT] [curve | @radius] + + this.out_file.write("WIRE '"); + + this.out_file.write(p_net_name); + this.out_file.write("' "); + Double wire_width = wire_path.width / this.session_file_scale_denominator; + this.out_file.write(wire_width.toString()); + this.out_file.write(" ("); + for (int i = 0; i < wire_path.coordinate_arr.length; ++i) + { + Double wire_coor = wire_path.coordinate_arr[i] / this.session_file_scale_denominator; + this.out_file.write(wire_coor.toString()); + if (i % 2 == 0) + { + this.out_file.write(" "); + } + else + { + if (i == wire_path.coordinate_arr.length - 1) + { + this.out_file.write(")"); + } + else + { + this.out_file.write(") ("); + } + } + } + this.out_file.write(";\n"); + + return true; + } + + private boolean process_via_scope(String p_net_name) throws java.io.IOException + { + // read the padstack name + Object next_token = this.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("SessionToEagle.process_via_scope: padstack name expected"); + return false; + } + String padstack_name = (String) next_token; + // read the location + double []location = new double [2]; + for (int i = 0; i < 2; ++i) + { + next_token = this.scanner.next_token(); + if (next_token instanceof Double) + { + location[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + location[i] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("SessionToEagle.process_via_scope: number expected"); + return false; + } + } + next_token = this.scanner.next_token(); + while (next_token == Keyword.OPEN_BRACKET) + { + // skip unknown scopes + ScopeKeyword.skip_scope(this.scanner); + next_token = this.scanner.next_token(); + } + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("SessionToEagle.process_via_scope: closing bracket expected"); + return false; + } + + if (padstack_name == null) + { + System.out.println("SessionToEagle.process_via_scope: padstack_name missing"); + return false; + } + + eu.mihosoft.freerouting.library.Padstack via_padstack = this.board.library.padstacks.get(padstack_name); + + if (via_padstack == null) + { + System.out.println("SessionToEagle.process_via_scope: via padstack not found"); + return false; + } + + eu.mihosoft.freerouting.geometry.planar.ConvexShape via_shape = via_padstack.get_shape(via_padstack.from_layer()); + + Double via_diameter = via_shape.max_width() * this.board_scale_factor; + + // The Padstack name is of the form Name$drill_diameter$from_layer-to_layer + + String [] name_parts = via_padstack.name.split("\\$", 3); + + // example CHANGE DRILL 0.2 + + this.out_file.write("CHANGE DRILL "); + if (name_parts.length > 1) + { + this.out_file.write(name_parts[1]); + } + else + { + // create a default drill, because it is needed in Eagle + this.out_file.write("0.1"); + } + this.out_file.write(";\n"); + + + //VIA ['signal_name'] [diameter] [shape] [layers] [flags] + // Via Net2 0.6 round 1-4 (20.0, 222.0); + this.out_file.write("VIA '"); + + this.out_file.write(p_net_name); + this.out_file.write("' "); + + //Durchmesser aus Padstack + this.out_file.write(via_diameter.toString()); + + //Shape lesen und einsetzen Square / Round / Octagon + if (via_shape instanceof eu.mihosoft.freerouting.geometry.planar.Circle) + { + this.out_file.write(" round "); + } + else if (via_shape instanceof eu.mihosoft.freerouting.geometry.planar.IntOctagon) + { + this.out_file.write(" octagon "); + } + else + { + this.out_file.write(" square "); + } + this.out_file.write(get_eagle_layer_string(via_padstack.from_layer())); + this.out_file.write("-"); + this.out_file.write(get_eagle_layer_string(via_padstack.to_layer())); + this.out_file.write(" ("); + Double x_coor = location[0] / this.session_file_scale_denominator; + this.out_file.write(x_coor.toString()); + this.out_file.write(" "); + Double y_coor = location[1] / this.session_file_scale_denominator; + this.out_file.write(y_coor.toString()); + this.out_file.write(");\n"); + + return true; + } + + private String get_eagle_layer_string(int p_layer_no) + { + if (p_layer_no < 0 || p_layer_no >= specctra_layer_structure.arr.length) + { + return "0"; + } + String [] name_pieces = this.specctra_layer_structure.arr[p_layer_no].name.split("#", 2); + return name_pieces[0]; + } + + private boolean process_swapped_pins() throws java.io.IOException + { + for (int i = 1; i <= this.board.components.count(); ++i) + { + if (!process_swapped_pins(i)) + { + return false; + } + } + return true; + } + + private boolean process_swapped_pins(int p_component_no) throws java.io.IOException + { + java.util.Collection component_pins = this.board.get_component_pins(p_component_no); + boolean component_has_swapped_pins = false; + for (eu.mihosoft.freerouting.board.Pin curr_pin : component_pins) + { + if (curr_pin.get_changed_to() != curr_pin) + { + component_has_swapped_pins = true; + break; + } + } + if (!component_has_swapped_pins) + { + return true; + } + PinInfo[] pin_info_arr = new PinInfo[component_pins.size()]; + int i = 0; + for (eu.mihosoft.freerouting.board.Pin curr_pin : component_pins) + { + pin_info_arr[i] = new PinInfo(curr_pin); + ++i; + } + for (i = 0; i < pin_info_arr.length; ++i) + { + PinInfo curr_pin_info = pin_info_arr[i]; + if (curr_pin_info.curr_changed_to != curr_pin_info.pin.get_changed_to()) + { + PinInfo other_pin_info = null; + for (int j = i + 1; j < pin_info_arr.length; ++j) + { + if (pin_info_arr[j].pin.get_changed_to() == curr_pin_info.pin) + { + other_pin_info = pin_info_arr[j]; + } + } + if (other_pin_info == null) + { + System.out.println("SessuinToEagle.process_swapped_pins: other_pin_info not found"); + return false; + } + write_pin_swap(curr_pin_info.pin, other_pin_info.pin); + curr_pin_info.curr_changed_to = other_pin_info.pin; + other_pin_info.curr_changed_to = curr_pin_info.pin; + } + } + return true; + } + + private void write_pin_swap(eu.mihosoft.freerouting.board.Pin p_pin_1, eu.mihosoft.freerouting.board.Pin p_pin_2) throws java.io.IOException + { + int layer_no = Math.max(p_pin_1.first_layer(), p_pin_2.first_layer()); + String layer_name = board.layer_structure.arr[layer_no].name; + + this.out_file.write("CHANGE LAYER "); + this.out_file.write(layer_name); + this.out_file.write(";\n"); + + double [] location_1 = + this.board.communication.coordinate_transform.board_to_dsn(p_pin_1.get_center().to_float()); + double [] location_2 = + this.board.communication.coordinate_transform.board_to_dsn(p_pin_2.get_center().to_float()); + + this.out_file.write("PINSWAP "); + this.out_file.write(" ("); + Double curr_coor = location_1[0]; + this.out_file.write(curr_coor.toString()); + this.out_file.write(" "); + curr_coor = location_1[1]; + this.out_file.write(curr_coor.toString()); + this.out_file.write(") ("); + curr_coor = location_2[0]; + this.out_file.write(curr_coor.toString()); + this.out_file.write(" "); + curr_coor = location_2[1]; + this.out_file.write(curr_coor.toString()); + this.out_file.write(");\n"); + } + + + + /** The function for scanning the session file */ + private final Scanner scanner; + + /** The generated Eagle script file. */ + private final java.io.OutputStreamWriter out_file; + + /** Some information is read from the eu.mihosoft.freerouting.board, because it is not contained in the speccctra session file. */ + private final eu.mihosoft.freerouting.board.BasicBoard board; + + /** The layer structure in specctra format */ + private final LayerStructure specctra_layer_structure; + + private final eu.mihosoft.freerouting.board.Unit unit; + + /** The scale factor for transforming coordinates from the session file to Eagle */ + private final double session_file_scale_denominator; + + /** The scale factor for transforming coordinates from the eu.mihosoft.freerouting.board to Eagle */ + private final double board_scale_factor; + + private static class PinInfo + { + PinInfo(eu.mihosoft.freerouting.board.Pin p_pin) + { + pin = p_pin; + curr_changed_to = p_pin; + } + final eu.mihosoft.freerouting.board.Pin pin; + eu.mihosoft.freerouting.board.Pin curr_changed_to; + } +} + diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Shape.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Shape.java new file mode 100644 index 0000000..e939462 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Shape.java @@ -0,0 +1,831 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Shape.java + * + * Created on 16. Mai 2004, 11:09 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Describes a shape in a Specctra dsn file. + * + * @author alfons + */ +public abstract class Shape +{ + + /** + * Writes a shape scope to a Specctra dsn file. + */ + public abstract void write_scope(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException; + + /** + * Writes a shape scope to a Specctra session file. + * In a session file all coordinates must be integer. + */ + public abstract void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException; + + /** + * Reads shape scope from a Specctra dsn file. + * If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers. + */ + public static final Shape read_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + Shape result = null; + try + { + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.OPEN_BRACKET) + { + // overread the open bracket + next_token = p_scanner.next_token(); + } + + if (next_token == Keyword.RECTANGLE) + { + + result = Shape.read_rectangle_scope(p_scanner, p_layer_structure); + } + else if (next_token == Keyword.POLYGON) + { + + result = Shape.read_polygon_scope(p_scanner, p_layer_structure); + } + else if (next_token == Keyword.CIRCLE) + { + + result = Shape.read_circle_scope(p_scanner, p_layer_structure); + } + else if (next_token == Keyword.POLYGON_PATH) + { + result = Shape.read_polygon_path_scope(p_scanner, p_layer_structure); + } + else + { + // not a shape scope, skip it. + ScopeKeyword.skip_scope(p_scanner); + } + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_scope: IO error scanning file"); + System.out.println(e); + return result; + } + return result; + } + + /** + * Reads an object of type PolylinePath from the dsn-file. + */ + public static PolylinePath read_polyline_path_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + Layer layer = null; + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.PCB_SCOPE) + { + layer = Layer.PCB; + } + else if (next_token == Keyword.SIGNAL) + { + layer = Layer.SIGNAL; + } + else + { + if (p_layer_structure == null) + { + System.out.println("PolylinePath.read_scope: only layer types pcb or signal expected"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("PolylinePath.read_scope: layer name string expected"); + return null; + } + int layer_no = p_layer_structure.get_no((String) next_token); + if (layer_no < 0 || layer_no >= p_layer_structure.arr.length) + { + System.out.print("Shape.read_polyline_path_scope: layer name "); + System.out.print((String) next_token); + System.out.println(" not found in layer structure "); + return null; + } + layer = p_layer_structure.arr[layer_no]; + } + Collection corner_list = new LinkedList(); + + // read the width and the corners of the path + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + corner_list.add(next_token); + } + if (corner_list.size() < 5) + { + System.out.println("PolylinePath.read_scope: to few numbers in scope"); + return null; + } + Iterator it = corner_list.iterator(); + double width = 0; + Object next_object = it.next(); + if (next_object instanceof Double) + { + width = ((Double) next_object).doubleValue(); + } + else if (next_object instanceof Integer) + { + width = ((Integer) next_object).intValue(); + } + else + { + System.out.println("PolylinePath.read_scope: number expected"); + return null; + } + double[] corner_arr = new double[corner_list.size() - 1]; + for (int i = 0; i < corner_arr.length; ++i) + { + next_object = it.next(); + if (next_object instanceof Double) + { + corner_arr[i] = ((Double) next_object).doubleValue(); + } + else if (next_object instanceof Integer) + { + corner_arr[i] = ((Integer) next_object).intValue(); + } + else + { + System.out.println("Shape.read_polygon_path_scope: number expected"); + return null; + } + + } + return new PolylinePath(layer, width, corner_arr); + } + catch (java.io.IOException e) + { + System.out.println("PolylinePath.read_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + /** + * Reads a shape , which may contain holes from a specctra dsn-file. + * The first shape in the shape_list of the result is the border of the area. + * The other shapes in the shape_list are holes (windows). + */ + public static final ReadAreaScopeResult read_area_scope(Scanner p_scanner, + LayerStructure p_layer_structure, boolean p_skip_window_scopes) + { + Collection shape_list = new LinkedList(); + String clearance_class_name = null; + String area_name = null; + boolean result_ok = true; + Object next_token = null; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_area_scope: IO error scanning file"); + return null; + } + if (next_token instanceof String) + { + String curr_name = (String) next_token; + if (!curr_name.isEmpty()) + { + area_name = curr_name; + } + } + Shape curr_shape = Shape.read_scope(p_scanner, p_layer_structure); + if (curr_shape == null) + { + result_ok = false; + } + shape_list.add(curr_shape); + next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_area_scope: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("Shape.read_area_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.CLOSED_BRACKET) + { + // end of scope + break; + } + + if (prev_token == Keyword.OPEN_BRACKET) + { + // a new scope is expected + if (next_token == Keyword.WINDOW && !p_skip_window_scopes) + { + Shape hole_shape = Shape.read_scope(p_scanner, p_layer_structure); + shape_list.add(hole_shape); + // overread closing bracket + try + { + next_token = p_scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_area_scope: IO error scanning file"); + return null; + } + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Shape.read_area_scope: closed bracket expected"); + return null; + } + + } + else if (next_token == Keyword.CLEARANCE_CLASS) + { + clearance_class_name = DsnFile.read_string_scope(p_scanner); + } + else + { + // skip unknown scope + ScopeKeyword.skip_scope(p_scanner); + } + } + } + if (!result_ok) + { + return null; + } + return new ReadAreaScopeResult(area_name, shape_list, clearance_class_name); + } + + /** + * Reads a rectangle scope from a Specctra dsn file. + * If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers. + */ + public static Rectangle read_rectangle_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + Layer rect_layer = null; + double rect_coor[] = new double[4]; + + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.PCB_SCOPE) + { + rect_layer = Layer.PCB; + } + else if (next_token == Keyword.SIGNAL) + { + rect_layer = Layer.SIGNAL; + } + else if (p_layer_structure != null) + { + if (!(next_token instanceof String)) + { + System.out.println("Shape.read_rectangle_scope: layer name string expected"); + return null; + } + String layer_name = (String) next_token; + int layer_no = p_layer_structure.get_no(layer_name); + if (layer_no < 0 || layer_no >= p_layer_structure.arr.length) + { + System.out.println("Shape.read_rectangle_scope: layer name " + layer_name + + " not found in layer structure "); + } + else + { + rect_layer = p_layer_structure.arr[layer_no]; + } + } + else + { + rect_layer = Layer.SIGNAL; + } + // fill the the rectangle + for (int i = 0; i < 4; ++i) + { + next_token = p_scanner.next_token(); + if (next_token instanceof Double) + { + rect_coor[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + rect_coor[i] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Shape.read_rectangle_scope: number expected"); + return null; + } + } + // overread the closing bracket + + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Shape.read_rectangle_scope ) expected"); + return null; + } + if (rect_layer == null) + { + return null; + } + return new Rectangle(rect_layer, rect_coor); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_rectangle_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + /** + * Reads a closed polygon scope from a Specctra dsn file. + * If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers. + */ + public static Polygon read_polygon_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + Layer polygon_layer = null; + boolean layer_ok = true; + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.PCB_SCOPE) + { + polygon_layer = Layer.PCB; + } + else if (next_token == Keyword.SIGNAL) + { + polygon_layer = Layer.SIGNAL; + } + else + { + if (p_layer_structure == null) + { + System.out.println("Shape.read_polygon_scope: only layer types pcb or signal expected"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("Shape.read_polygon_scope: layer name string expected"); + return null; + } + int layer_no = p_layer_structure.get_no((String) next_token); + if (layer_no < 0 || layer_no >= p_layer_structure.arr.length) + { + System.out.print("Shape.read_polygon_scope: layer name "); + System.out.print((String) next_token); + System.out.println(" not found in layer structure "); + layer_ok = false; + } + else + { + polygon_layer = p_layer_structure.arr[layer_no]; + } + } + + // overread the aperture width + next_token = p_scanner.next_token(); + + Collection coor_list = new LinkedList(); + + // read the coordinates of the polygon + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == null) + { + System.out.println("Shape.read_polygon_scope: unexpected end of file"); + return null; + } + if (next_token == Keyword.OPEN_BRACKET) + { + // unknown scope + ScopeKeyword.skip_scope(p_scanner); + next_token = p_scanner.next_token(); + } + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + coor_list.add(next_token); + } + if (!layer_ok) + { + return null; + } + double[] coor_arr = new double[coor_list.size()]; + Iterator it = coor_list.iterator(); + for (int i = 0; i < coor_arr.length; ++i) + { + Object next_object = it.next(); + if (next_object instanceof Double) + { + coor_arr[i] = ((Double) next_object).doubleValue(); + } + else if (next_object instanceof Integer) + { + coor_arr[i] = ((Integer) next_object).intValue(); + } + else + { + System.out.println("Shape.read_polygon_scope: number expected"); + return null; + } + + } + return new Polygon(polygon_layer, coor_arr); + } + catch (java.io.IOException e) + { + System.out.println("Rectangle.read_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + /** + * Reads a circle scope from a Specctra dsn file. + */ + public static Circle read_circle_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + Layer circle_layer = null; + boolean layer_ok = true; + double circle_coor[] = new double[3]; + + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.PCB_SCOPE) + { + circle_layer = Layer.PCB; + } + else if (next_token == Keyword.SIGNAL) + { + circle_layer = Layer.SIGNAL; + } + else + { + if (p_layer_structure == null) + { + System.out.println("Shape.read_circle_scope: p_layer_structure != null expected"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("Shape.read_circle_scope: string for layer_name expected"); + return null; + } + int layer_no = p_layer_structure.get_no((String) next_token); + if (layer_no < 0 || layer_no >= p_layer_structure.arr.length) + { + System.out.print("Shape.read_circle_scope: layer with name "); + System.out.print((String) next_token); + System.out.println(" not found in layer stracture "); + layer_ok = false; + } + else + { + circle_layer = p_layer_structure.arr[layer_no]; + } + } + // fill the the the coordinates + int curr_index = 0; + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (curr_index > 2) + { + System.out.println("Shape.read_circle_scope: closed bracket expected"); + return null; + } + if (next_token instanceof Double) + { + circle_coor[curr_index] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + circle_coor[curr_index] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Shape.read_circle_scope: number expected"); + return null; + } + ++curr_index; + } + if (!layer_ok) + { + return null; + } + return new Circle(circle_layer, circle_coor); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_rectangle_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + /** + * Reads an object of type Path from the dsn-file. + */ + public static PolygonPath read_polygon_path_scope(Scanner p_scanner, LayerStructure p_layer_structure) + { + try + { + Layer layer = null; + boolean layer_ok = true; + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.PCB_SCOPE) + { + layer = Layer.PCB; + } + else if (next_token == Keyword.SIGNAL) + { + layer = Layer.SIGNAL; + } + else + { + if (p_layer_structure == null) + { + System.out.println("Shape.read_polygon_path_scope: only layer types pcb or signal expected"); + return null; + } + if (!(next_token instanceof String)) + { + System.out.println("Path.read_scope: layer name string expected"); + return null; + } + int layer_no = p_layer_structure.get_no((String) next_token); + if (layer_no < 0 || layer_no >= p_layer_structure.arr.length) + { + System.out.print("Shape.read_polygon_path_scope: layer with name "); + System.out.print((String) next_token); + System.out.println(" not found in layer structure "); + layer_ok = false; + } + else + { + layer = p_layer_structure.arr[layer_no]; + } + } + Collection corner_list = new LinkedList(); + + // read the width and the corners of the path + for (;;) + { + next_token = p_scanner.next_token(); + if (next_token == Keyword.OPEN_BRACKET) + { + // unknown scope + ScopeKeyword.skip_scope(p_scanner); + next_token = p_scanner.next_token(); + } + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + corner_list.add(next_token); + } + if (corner_list.size() < 5) + { + System.out.println("Shape.read_polygon_path_scope: to few numbers in scope"); + return null; + } + if (!layer_ok) + { + return null; + } + Iterator it = corner_list.iterator(); + double width = 0; + Object next_object = it.next(); + if (next_object instanceof Double) + { + width = ((Double) next_object).doubleValue(); + } + else if (next_object instanceof Integer) + { + width = ((Integer) next_object).intValue(); + } + else + { + System.out.println("Shape.read_polygon_path_scope: number expected"); + return null; + } + double[] coordinate_arr = new double[corner_list.size() - 1]; + for (int i = 0; i < coordinate_arr.length; ++i) + { + next_object = it.next(); + if (next_object instanceof Double) + { + coordinate_arr[i] = ((Double) next_object).doubleValue(); + } + else if (next_object instanceof Integer) + { + coordinate_arr[i] = ((Integer) next_object).intValue(); + } + else + { + System.out.println("Shape.read_polygon_path_scope: number expected"); + return null; + } + + } + return new PolygonPath(layer, width, coordinate_arr); + } + catch (java.io.IOException e) + { + System.out.println("Shape.read_polygon_path_scope: IO error scanning file"); + System.out.println(e); + return null; + } + } + + /** + * Transforms a shape with holes to the eu.mihosoft.freerouting.board coordinate system. + * The first shape in the Collection p_area is the border, + * the other shapes are holes of the area. + */ + public static eu.mihosoft.freerouting.geometry.planar.Area transform_area_to_board(Collection p_area, CoordinateTransform p_coordinate_transform) + { + int hole_count = p_area.size() - 1; + if (hole_count <= -1) + { + System.out.println("Shape.transform_area_to_board: p_area.size() > 0 expected"); + return null; + } + Iterator it = p_area.iterator(); + Shape boundary = it.next(); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape = boundary.transform_to_board(p_coordinate_transform); + eu.mihosoft.freerouting.geometry.planar.Area result; + if (hole_count == 0) + { + result = boundary_shape; + } + else + { + // Area with holes + if (!(boundary_shape instanceof eu.mihosoft.freerouting.geometry.planar.PolylineShape)) + { + System.out.println("Shape.transform_area_to_board: PolylineShape expected"); + return null; + } + PolylineShape border = (PolylineShape) boundary_shape; + PolylineShape[] holes = new PolylineShape[hole_count]; + for (int i = 0; i < holes.length; ++i) + { + eu.mihosoft.freerouting.geometry.planar.Shape hole_shape = it.next().transform_to_board(p_coordinate_transform); + if (!(hole_shape instanceof PolylineShape)) + { + System.out.println("Shape.transform_area_to_board: PolylineShape expected"); + return null; + } + holes[i] = (PolylineShape) hole_shape; + } + result = new eu.mihosoft.freerouting.geometry.planar.PolylineArea(border, holes); + } + return result; + } + + /** + * Transforms the relative coordinates of a shape with holes to the eu.mihosoft.freerouting.board coordinate system. + * The first shape in the Collection p_area is the border, + * the other shapes are holes of the area. + */ + public static eu.mihosoft.freerouting.geometry.planar.Area transform_area_to_board_rel(Collection p_area, CoordinateTransform p_coordinate_transform) + { + int hole_count = p_area.size() - 1; + if (hole_count <= -1) + { + System.out.println("Shape.transform_area_to_board_rel: p_area.size() > 0 expected"); + return null; + } + Iterator it = p_area.iterator(); + Shape boundary = it.next(); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape = boundary.transform_to_board_rel(p_coordinate_transform); + eu.mihosoft.freerouting.geometry.planar.Area result; + if (hole_count == 0) + { + result = boundary_shape; + } + else + { + // Area with holes + if (!(boundary_shape instanceof eu.mihosoft.freerouting.geometry.planar.PolylineShape)) + { + System.out.println("Shape.transform_area_to_board_rel: PolylineShape expected"); + return null; + } + PolylineShape border = (PolylineShape) boundary_shape; + PolylineShape[] holes = new PolylineShape[hole_count]; + for (int i = 0; i < holes.length; ++i) + { + eu.mihosoft.freerouting.geometry.planar.Shape hole_shape = it.next().transform_to_board_rel(p_coordinate_transform); + if (!(hole_shape instanceof PolylineShape)) + { + System.out.println("Shape.transform_area_to_board: PolylineShape expected"); + return null; + } + holes[i] = (PolylineShape) hole_shape; + } + result = new eu.mihosoft.freerouting.geometry.planar.PolylineArea(border, holes); + } + return result; + } + + public void write_hole_scope(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("window"); + this.write_scope(p_file, p_identifier_type); + p_file.end_scope(); + } + + /** + * Transforms a specctra dsn shape to a eu.mihosoft.freerouting.geometry.planar.Shape. + */ + public abstract eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform); + + /** + * Returns the smallest axis parallel rectangle containing this shape. + */ + public abstract Rectangle bounding_box(); + + /** + * Transforms the relative (vector) coordinates of a specctra dsn shape to a eu.mihosoft.freerouting.geometry.planar.Shape. + */ + public abstract eu.mihosoft.freerouting.geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform); + + protected Shape(Layer p_layer) + { + layer = p_layer; + } + public final Layer layer; + + /** + * Contains the result of the function read_area_scope. + * area_name or clearance_class_name may be null, which means they are not provided. + */ + static class ReadAreaScopeResult + { + + private ReadAreaScopeResult(String p_area_name, Collection p_shape_list, String p_clearance_class_name) + { + area_name = p_area_name; + shape_list = p_shape_list; + clearance_class_name = p_clearance_class_name; + } + String area_name; // may be generated later on, if area_name is null. + final Collection shape_list; + final String clearance_class_name; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileDescription.flex b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileDescription.flex new file mode 100644 index 0000000..af7eedc --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileDescription.flex @@ -0,0 +1,311 @@ +package designformats.specctra; +@SuppressWarnings("all") +%% + +%class SpecctraFileScanner +%implements Scanner +%unicode +%ignorecase +%function next_token +%type Object +/* %debug */ + +%{ + StringBuffer string = new StringBuffer(); +%} + +LineTerminator = \r|\n|\r\n +InputCharacter = [^\r\n] +WhiteSpace = {LineTerminator} | [ \t\f] + +/* comments */ +Comment = {TraditionalComment} | {EndOfLineComment} + +TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" +EndOfLineComment = "#" {InputCharacter}* {LineTerminator} + +Letter=[A-Za-z] +Digit=[0-9] + +/* Character used for quoting string */ +QuoteChar1 = \" +QuoteChar2 = ' + +SpecCharASCII = _|\.|\/|\\|:|#|\$|&|>|<|,|;|=|@|\[|\]||\~|\*|\?|\!|\%|\^ + +SpecCharANSI1 = €|‚|ƒ|„|…|†|‡|ˆ|‰|Š|‹|Œ|Ž|‘|’|“|”|•|–|—|˜|™|š|›|œ|ž|Ÿ +SpecCharANSI2 = [¡-ÿ] +SpecCharANSI = {SpecCharANSI1}|{SpecCharANSI2} + + +SpecChar1 = {SpecCharASCII}|{SpecCharANSI} + +SpecChar2 = {SpecChar1}|-|\+ + +SpecChar3 = {SpecChar2}|{QuoteChar1}|{QuoteChar2} + +SpecChar4 = {SpecChar1}|\+ + +SpecChar5 = {SpecChar4}|{QuoteChar1}|{QuoteChar2} + + +DecIntegerLiteral = ([+-]? (0 | [1-9][0-9]*)) + +Mantissa = ([+-]? [0-9]+ ("." [0-9]+)?) + +Exponent = ([Ee] {DecIntegerLiteral}) + +DecFloatLiteral = {Mantissa} {Exponent}? + +Identifier = ({Letter}|{SpecChar1})({Letter}|{Digit}|{SpecChar3})* + +NameIdentifier = ({Letter}|{Digit}|{SpecChar2})({Letter}|{Digit}|{SpecChar3})* + +IdentifierIgnoringQuotes = ({Letter}|{Digit}|{SpecChar3})* + +/* to divide the component name from the pin name with the character "-" */ +ComponentIdentifier = ({Letter}|{Digit}|{SpecChar4})({Letter}|{Digit}|{SpecChar5})* + +/* States used for qouting strings */ +%state STRING1 +%state STRING2 + +/* The state NAME is used if the next token has to be interpreted as string, even if it is a number */ +%state NAME + +/* The state LAYER_NAME is used if the next token has to be interpreted as a layer name */ +%state LAYER_NAME + +/* To divide a component name from the pin name with the charracter "-" */ +%state COMPONENT_NAME + +/* Returns the next character */ +%state SPEC_CHAR + +/* Reads the next identifier while handling the quote characters as normal characters */ +%state IGNORE_QUOTE + +%% + + + { + /* keywords */ + "absolute" { return Keyword.ABSOLUTE; } + "active" { return Keyword.ACTIVE; } + "against_preferred_direction_trace_costs" { return Keyword.AGAINST_PREFERRED_DIRECTION_TRACE_COSTS; } + "against_prefered_direction_trace_costs" { return Keyword.AGAINST_PREFERRED_DIRECTION_TRACE_COSTS; } + "attach" { return Keyword.ATTACH; } + "autoroute" { return Keyword.AUTOROUTE; } + "autoroute_settings" { return Keyword.AUTOROUTE_SETTINGS; } + "back" { return Keyword.BACK; } + "boundary" { return Keyword.BOUNDARY; } + "circ" { yybegin(LAYER_NAME); return Keyword.CIRCLE; } + "circle" { yybegin(LAYER_NAME); return Keyword.CIRCLE; } + "circuit" { return Keyword.CIRCUIT; } + "class" { yybegin(NAME); return Keyword.CLASS; } + "class_class" { return Keyword.CLASS_CLASS; } + "classes" { return Keyword.CLASSES; } + "clear" { return Keyword.CLEARANCE; } + "clearance" { return Keyword.CLEARANCE; } + "clearance_class" { yybegin(NAME); return Keyword.CLEARANCE_CLASS; } + "comp" { yybegin(NAME); return Keyword.COMPONENT_SCOPE; } + "component" { yybegin(NAME); return Keyword.COMPONENT_SCOPE; } + "constant" { return Keyword.CONSTANT; } + "control" { return Keyword.CONTROL; } + "fanout" { return Keyword.FANOUT; } + "fix" { return Keyword.FIX; } + "fortyfive_degree" { return Keyword.FORTYFIVE_DEGREE; } + "flip_style" { return Keyword.FLIP_STYLE; } + "fromto" { return Keyword.FROMTO; } + "front" { return Keyword.FRONT; } + "generated_by_freeroute" {return Keyword.GENERATED_BY_FREEROUTE; } + "horizontal" { return Keyword.HORIZONTAL; } + "image" { yybegin(NAME); return Keyword.IMAGE; } + "host_cad" { yybegin(NAME); return Keyword.HOST_CAD; } + "host_version" { yybegin(NAME); return Keyword.HOST_VERSION; } + "keepout" { yybegin(NAME); return Keyword.KEEPOUT; } + "layer" { yybegin(NAME); return Keyword.LAYER; } + "layer_rule" { yybegin(NAME); return Keyword.LAYER_RULE; } + "length" { return Keyword.LENGTH; } + "library" { return Keyword.LIBRARY_SCOPE; } + "lock_type" { return Keyword.LOCK_TYPE; } + "logical_part" { yybegin(NAME); return Keyword.LOGICAL_PART; } + "logical_part_mapping" { yybegin(NAME); return Keyword.LOGICAL_PART_MAPPING; } + "net" { yybegin(NAME); return Keyword.NET; } + "network" { return Keyword.NETWORK_SCOPE; } + "network_out" { return Keyword.NETWORK_OUT; } + "ninety_degree" { return Keyword.NINETY_DEGREE; } + "none" { return Keyword.NONE; } + "normal" { return Keyword.NORMAL; } + "off" { return Keyword.OFF; } + "on" { return Keyword.ON; } + "order" { return Keyword.ORDER; } + "outline" { return Keyword.OUTLINE; } + "padstack" { yybegin(NAME); return Keyword.PADSTACK; } + "parser" { return Keyword.PARSER_SCOPE; } + "part_library" { return Keyword.PART_LIBRARY_SCOPE; } + "path" { yybegin(LAYER_NAME); return Keyword.POLYGON_PATH; } + "pcb" { return Keyword.PCB_SCOPE; } + "pin" { return Keyword.PIN; } + "pins" { return Keyword.PINS; } + "place" { yybegin(NAME); return Keyword.PLACE; } + "place_control" { return Keyword.PLACE_CONTROL; } + "place_keepout" { yybegin(NAME); return Keyword.PLACE_KEEPOUT; } + "placement" { return Keyword.PLACEMENT_SCOPE; } + "plane" { yybegin(NAME); return Keyword.PLANE_SCOPE; } + "plane_via_costs" { return Keyword.PLANE_VIA_COSTS; } + "poly" { yybegin(LAYER_NAME); return Keyword.POLYGON; } + "polygon" { yybegin(LAYER_NAME); return Keyword.POLYGON; } + "polyline_path" { yybegin(LAYER_NAME); return Keyword.POLYLINE_PATH; } + "position" { return Keyword.POSITION; } + "postroute" { return Keyword.POSTROUTE; } + "power" { return Keyword.POWER; } + "preferred_direction" { return Keyword.PREFERRED_DIRECTION; } + "prefered_direction" { return Keyword.PREFERRED_DIRECTION; } + "preferred_direction_trace_costs" { return Keyword.PREFERRED_DIRECTION_TRACE_COSTS; } + "prefered_direction_trace_costs" { return Keyword.PREFERRED_DIRECTION_TRACE_COSTS; } + "pull_tight" { return Keyword.PULL_TIGHT; } + "rect" { yybegin(LAYER_NAME); return Keyword.RECTANGLE; } + "rectangle" { yybegin(LAYER_NAME); return Keyword.RECTANGLE; } + "resolution" { return Keyword.RESOLUTION_SCOPE; } + "rotate" { return Keyword.ROTATE; } + "rotate_first" { return Keyword.ROTATE_FIRST; } + "routes" { return Keyword.ROUTES; } + "rule" { return Keyword.RULE; } + "rules" { return Keyword.RULES; } + "session" { return Keyword.SESSION; } + "shape" { return Keyword.SHAPE; } + "shove_fixed" { return Keyword.SHOVE_FIXED; } + "side" { return Keyword.SIDE; } + "signal" { return Keyword.SIGNAL; } + "snap_angle" { return Keyword.SNAP_ANGLE; } + "spare" { return Keyword.SPARE; } + "start_pass_no" { return Keyword.START_PASS_NO; } + "start_ripup_costs" { return Keyword.START_RIPUP_COSTS; } + "string_quote" { yybegin(IGNORE_QUOTE); return Keyword.STRING_QUOTE; } + "structure" { return Keyword.STRUCTURE_SCOPE; } + "type" { return Keyword.TYPE; } + "use_layer" { yybegin(NAME); return Keyword.USE_LAYER; } + "use_net" { yybegin(NAME); return Keyword.USE_NET; } + "use_via" { yybegin(NAME); return Keyword.USE_VIA; } + "vertical" { return Keyword.VERTICAL; } + "via" { yybegin(NAME); return Keyword.VIA; } + "vias" { return Keyword.VIAS; } + "via_at_smd" { return Keyword.VIA_AT_SMD; } + "via_costs" { return Keyword.VIA_COSTS; } + "via_keepout" { yybegin(NAME); return Keyword.VIA_KEEPOUT; } + "via_rule" { return Keyword.VIA_RULE; } + "width" { return Keyword.WIDTH; } + "window" { return Keyword.WINDOW; } + "wire" { yybegin(NAME); return Keyword.WIRE; } + "wire_keepout" { return Keyword.KEEPOUT; } + "wiring" { return Keyword.WIRING_SCOPE; } + "write_resolution" { return Keyword.WRITE_RESOLUTION; } + "(" { return Keyword.OPEN_BRACKET; } + ")" { return Keyword.CLOSED_BRACKET; } + + /* identifiers */ + {Identifier} { return yytext(); } + + /* Characters for quoting strings */ + {QuoteChar1} { string.setLength(0); yybegin(STRING1); } + {QuoteChar2} { string.setLength(0); yybegin(STRING2); } + + /* literals */ + {DecIntegerLiteral} { return new Integer(yytext()); } + {DecFloatLiteral} { return new Double(yytext()); } + + /* comments */ + {Comment} { /* ignore */ } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } +} + +/* Strings quoted with " */ + { + [^\"\\]+ { string.append( yytext() ); } + \\ { string.append('\\'); } + \" { yybegin(YYINITIAL); return string.toString(); } +} + +/* Strings quotet with ' */ + { + [^\'\\]+ { string.append( yytext() ); } + \\ { string.append('\\'); } + ' { yybegin(YYINITIAL); return string.toString(); } +} + + + { + /* keywords */ + "(" { yybegin(YYINITIAL); return Keyword.OPEN_BRACKET;} + ")" { yybegin(YYINITIAL); return Keyword.CLOSED_BRACKET;} + + /* identifiers */ + {NameIdentifier} { yybegin(YYINITIAL); return yytext(); } + + + /* Characters for quoting strings */ + {QuoteChar1} { string.setLength(0); yybegin(STRING1); } + {QuoteChar2} { string.setLength(0); yybegin(STRING2); } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } +} + +/* Reads the next identifier while handling the quote characters as normal characters */ + { + /* keywords */ + "(" { yybegin(YYINITIAL); return Keyword.OPEN_BRACKET;} + ")" { yybegin(YYINITIAL); return Keyword.CLOSED_BRACKET;} + + /* identifiers */ + {IdentifierIgnoringQuotes} { yybegin(YYINITIAL); return yytext(); } + {WhiteSpace} { /* ignore */ } +} + + + { + /* keywords */ + "pcb" { yybegin(YYINITIAL); return Keyword.PCB_SCOPE; } + "signal" { yybegin(YYINITIAL); return Keyword.SIGNAL; } + "(" { yybegin(YYINITIAL); return Keyword.OPEN_BRACKET;} + ")" { yybegin(YYINITIAL); return Keyword.CLOSED_BRACKET;} + + /* identifiers */ + {NameIdentifier} { yybegin(YYINITIAL); return yytext(); } + + /* Characters for quoting strings */ + {QuoteChar1} { string.setLength(0); yybegin(STRING1); } + {QuoteChar2} { string.setLength(0); yybegin(STRING2); } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } +} + +/* to divide a component name from the pin name with the charracter "-" */ + { + /* keywords */ + "(" { yybegin(YYINITIAL); return Keyword.OPEN_BRACKET;} + ")" { yybegin(YYINITIAL); return Keyword.CLOSED_BRACKET;} + + /* identifiers */ + {ComponentIdentifier} { yybegin(YYINITIAL); return yytext(); } + + + /* Characters for quoting strings */ + {QuoteChar1} { string.setLength(0); yybegin(STRING1); } + {QuoteChar2} { string.setLength(0); yybegin(STRING2); } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } +} + + { + {SpecChar2} {return yytext();} +} + +/* error fallback */ +.|\n { throw new Error("Illegal character <"+ + yytext()+">"); } diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileScanner.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileScanner.java new file mode 100644 index 0000000..55b00e2 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/SpecctraFileScanner.java @@ -0,0 +1,1459 @@ +/* The following code was generated by JFlex 1.4.1 on 16.10.08 09:27 */ + +package eu.mihosoft.freerouting.designforms.specctra; +@SuppressWarnings("all") + +/** + * This class is a scanner generated by + * JFlex 1.4.1 + * on 16.10.08 09:27 from the specification file + * C:/Users/Public/Documents/router/sources/designformats/specctra/SpecctraFileDescription.flex + */ +class SpecctraFileScanner implements Scanner { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int COMPONENT_NAME = 5; + public static final int IGNORE_QUOTE = 7; + public static final int YYINITIAL = 0; + public static final int SPEC_CHAR = 6; + public static final int LAYER_NAME = 4; + public static final int STRING2 = 2; + public static final int STRING1 = 1; + public static final int NAME = 3; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\3\1\2\1\0\1\3\1\1\21\0\1\16\1\3\1\16"+ + "\1\11\1\6\1\16\1\16\1\16\1\12\1\53\1\54\1\5\1\20"+ + "\1\16\1\17\1\14\1\4\1\21\11\10\1\16\1\16\1\16\1\16"+ + "\1\16\1\16\1\16\1\23\1\24\1\32\1\42\1\22\1\41\1\35"+ + "\1\43\1\33\1\7\1\44\1\27\1\46\1\36\1\26\1\37\1\52"+ + "\1\40\1\25\1\31\1\30\1\34\1\51\1\47\1\45\1\50\1\16"+ + "\1\15\1\16\1\16\1\13\1\0\1\23\1\24\1\32\1\42\1\22"+ + "\1\41\1\35\1\43\1\33\1\7\1\44\1\27\1\46\1\36\1\26"+ + "\1\37\1\52\1\40\1\25\1\31\1\30\1\34\1\51\1\47\1\45"+ + "\1\50\3\0\1\16\42\0\136\16\1\16\122\0\2\16\14\0\2\16"+ + "\26\0\1\16\4\0\2\16\22\0\2\16\u0133\0\1\16\25\0\1\16"+ + "\u1d36\0\1\16\1\16\3\0\1\16\1\16\1\16\1\0\1\16\1\16"+ + "\1\16\1\0\1\16\1\16\1\16\3\0\1\16\11\0\1\16\10\0"+ + "\1\16\1\16\161\0\1\16\165\0\1\16\udedd\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\7\0\1\1\1\2\2\3\3\4\1\5\1\6\1\7"+ + "\1\2\1\5\22\4\1\10\1\11\1\12\1\13\1\14"+ + "\1\12\1\1\1\15\1\16\3\1\2\4\3\0\1\17"+ + "\16\4\1\20\45\4\2\1\1\0\1\4\2\17\1\0"+ + "\1\17\22\4\1\21\16\4\1\22\1\4\1\23\13\4"+ + "\1\24\1\25\11\4\1\26\10\4\1\1\1\27\1\0"+ + "\6\4\1\30\6\4\1\31\14\4\1\32\2\4\1\33"+ + "\2\4\1\34\3\4\1\35\2\4\1\36\2\4\1\37"+ + "\5\4\1\40\4\4\1\41\2\4\1\42\2\4\1\43"+ + "\11\4\1\44\3\4\1\1\14\4\1\45\1\46\2\4"+ + "\1\47\1\4\1\50\11\4\1\51\1\52\2\4\1\53"+ + "\20\4\1\54\1\55\1\56\6\4\1\57\3\4\1\60"+ + "\7\4\1\61\1\4\1\1\2\4\1\62\1\63\6\4"+ + "\1\64\3\4\1\65\15\4\1\34\10\4\1\66\1\4"+ + "\1\67\15\4\1\70\1\71\1\72\2\4\1\73\4\4"+ + "\1\74\1\4\1\75\1\4\1\76\4\4\1\77\6\4"+ + "\1\100\3\4\1\101\1\4\1\102\1\103\1\4\1\104"+ + "\3\4\1\105\1\106\6\4\1\107\6\4\1\40\17\4"+ + "\1\110\2\4\1\111\2\4\1\112\12\4\1\113\3\4"+ + "\1\114\2\4\1\115\5\4\1\116\1\4\1\117\14\4"+ + "\1\120\4\4\1\121\3\4\1\122\4\4\1\123\1\4"+ + "\1\124\1\33\1\51\2\4\1\125\5\4\1\126\3\4"+ + "\1\127\4\4\1\42\14\4\1\130\1\4\1\131\3\4"+ + "\1\132\11\4\1\133\1\4\1\134\2\4\1\135\1\4"+ + "\1\136\7\4\1\137\2\4\1\140\1\141\1\4\1\142"+ + "\20\4\1\143\1\144\3\4\1\145\5\4\1\146\1\4"+ + "\1\147\1\150\3\4\1\151\4\4\1\152\1\153\1\154"+ + "\1\155\23\4\1\156\1\4\1\157\11\4\1\160\1\161"+ + "\2\4\1\162\3\4\1\163\3\4\1\164\5\4\1\165"+ + "\6\4\1\166\20\4\1\167\7\4\1\170"; + + private static int [] zzUnpackAction() { + int [] result = new int[712]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\55\0\132\0\207\0\264\0\341\0\u010e\0\u013b"+ + "\0\u0168\0\u0195\0\u0168\0\u01c2\0\u01ef\0\u021c\0\u0249\0\u0168"+ + "\0\u0168\0\u0276\0\u02a3\0\u02d0\0\u02fd\0\u032a\0\u0357\0\u0384"+ + "\0\u03b1\0\u03de\0\u040b\0\u0438\0\u0465\0\u0492\0\u04bf\0\u04ec"+ + "\0\u0519\0\u0546\0\u0573\0\u05a0\0\u05cd\0\u0168\0\u0168\0\u05fa"+ + "\0\u0168\0\u0168\0\u0627\0\u0654\0\u0168\0\u0168\0\u0681\0\u06ae"+ + "\0\u06db\0\u0168\0\u0708\0\u0735\0\u0762\0\u078f\0\u02a3\0\u07bc"+ + "\0\u07e9\0\u0816\0\u0843\0\u0870\0\u089d\0\u08ca\0\u08f7\0\u0924"+ + "\0\u0951\0\u097e\0\u09ab\0\u09d8\0\u0a05\0\u01ef\0\u0a32\0\u0a5f"+ + "\0\u0a8c\0\u0ab9\0\u0ae6\0\u0b13\0\u0b40\0\u0b6d\0\u0b9a\0\u0bc7"+ + "\0\u0bf4\0\u0c21\0\u0c4e\0\u0c7b\0\u0ca8\0\u0cd5\0\u0d02\0\u0d2f"+ + "\0\u0d5c\0\u0d89\0\u0db6\0\u0de3\0\u0e10\0\u0e3d\0\u0e6a\0\u0e97"+ + "\0\u0ec4\0\u0ef1\0\u0f1e\0\u0f4b\0\u0f78\0\u0fa5\0\u0fd2\0\u0fff"+ + "\0\u102c\0\u1059\0\u1086\0\u10b3\0\u10e0\0\u110d\0\u113a\0\u1167"+ + "\0\u1194\0\u11c1\0\u0168\0\u11ee\0\u121b\0\u1248\0\u1275\0\u12a2"+ + "\0\u12cf\0\u12fc\0\u1329\0\u1356\0\u1383\0\u13b0\0\u13dd\0\u140a"+ + "\0\u1437\0\u1464\0\u1491\0\u14be\0\u14eb\0\u01ef\0\u1518\0\u1545"+ + "\0\u1572\0\u159f\0\u15cc\0\u15f9\0\u1626\0\u1653\0\u1680\0\u16ad"+ + "\0\u16da\0\u1707\0\u1734\0\u1761\0\u178e\0\u17bb\0\u17e8\0\u1815"+ + "\0\u1842\0\u186f\0\u189c\0\u18c9\0\u18f6\0\u1923\0\u1950\0\u197d"+ + "\0\u19aa\0\u19d7\0\u01ef\0\u1a04\0\u1a31\0\u1a5e\0\u1a8b\0\u1ab8"+ + "\0\u1ae5\0\u1b12\0\u1b3f\0\u1b6c\0\u1b99\0\u01ef\0\u1bc6\0\u1bf3"+ + "\0\u1c20\0\u1c4d\0\u1c7a\0\u1ca7\0\u1cd4\0\u1d01\0\u1d2e\0\u0654"+ + "\0\u1d5b\0\u1d88\0\u1db5\0\u1de2\0\u1e0f\0\u1e3c\0\u1e69\0\u01ef"+ + "\0\u1e96\0\u1ec3\0\u1ef0\0\u1f1d\0\u1f4a\0\u1f77\0\u01ef\0\u1fa4"+ + "\0\u1fd1\0\u1ffe\0\u202b\0\u2058\0\u2085\0\u20b2\0\u20df\0\u210c"+ + "\0\u2139\0\u2166\0\u2193\0\u01ef\0\u21c0\0\u21ed\0\u221a\0\u2247"+ + "\0\u2274\0\u22a1\0\u22ce\0\u22fb\0\u2328\0\u01ef\0\u2355\0\u2382"+ + "\0\u01ef\0\u23af\0\u23dc\0\u01ef\0\u2409\0\u2436\0\u2463\0\u2490"+ + "\0\u24bd\0\u24ea\0\u2517\0\u2544\0\u2571\0\u259e\0\u01ef\0\u25cb"+ + "\0\u25f8\0\u2625\0\u2652\0\u267f\0\u26ac\0\u26d9\0\u2706\0\u2733"+ + "\0\u2760\0\u278d\0\u27ba\0\u27e7\0\u2814\0\u2841\0\u286e\0\u289b"+ + "\0\u28c8\0\u28f5\0\u2922\0\u294f\0\u297c\0\u29a9\0\u29d6\0\u2a03"+ + "\0\u2a30\0\u2a5d\0\u2a8a\0\u2ab7\0\u2ae4\0\u2b11\0\u2b3e\0\u01ef"+ + "\0\u01ef\0\u2b6b\0\u2b98\0\u01ef\0\u2bc5\0\u2bf2\0\u2c1f\0\u2c4c"+ + "\0\u2c79\0\u2ca6\0\u2cd3\0\u2d00\0\u2d2d\0\u2d5a\0\u2d87\0\u2db4"+ + "\0\u2de1\0\u2e0e\0\u2e3b\0\u01ef\0\u2e68\0\u2e95\0\u2ec2\0\u2eef"+ + "\0\u2f1c\0\u2f49\0\u2f76\0\u2fa3\0\u2fd0\0\u2ffd\0\u302a\0\u3057"+ + "\0\u3084\0\u30b1\0\u30de\0\u310b\0\u01ef\0\u3138\0\u3165\0\u3192"+ + "\0\u31bf\0\u31ec\0\u3219\0\u3246\0\u3273\0\u01ef\0\u32a0\0\u32cd"+ + "\0\u32fa\0\u01ef\0\u3327\0\u3354\0\u3381\0\u33ae\0\u33db\0\u3408"+ + "\0\u3435\0\u01ef\0\u3462\0\u348f\0\u34bc\0\u34e9\0\u01ef\0\u01ef"+ + "\0\u3516\0\u3543\0\u3570\0\u359d\0\u35ca\0\u35f7\0\u01ef\0\u3624"+ + "\0\u3651\0\u367e\0\u01ef\0\u36ab\0\u36d8\0\u3705\0\u3732\0\u375f"+ + "\0\u378c\0\u37b9\0\u37e6\0\u3813\0\u3840\0\u386d\0\u389a\0\u38c7"+ + "\0\u01ef\0\u38f4\0\u3921\0\u394e\0\u397b\0\u39a8\0\u39d5\0\u3a02"+ + "\0\u3a2f\0\u01ef\0\u3a5c\0\u01ef\0\u3a89\0\u3ab6\0\u3ae3\0\u3b10"+ + "\0\u3b3d\0\u3b6a\0\u3b97\0\u3bc4\0\u3bf1\0\u3c1e\0\u3c4b\0\u3c78"+ + "\0\u3ca5\0\u01ef\0\u3cd2\0\u01ef\0\u3cff\0\u3d2c\0\u01ef\0\u3d59"+ + "\0\u3d86\0\u3db3\0\u3de0\0\u01ef\0\u3e0d\0\u01ef\0\u3e3a\0\u0654"+ + "\0\u3e67\0\u3e94\0\u3ec1\0\u3eee\0\u01ef\0\u3f1b\0\u3f48\0\u3f75"+ + "\0\u3fa2\0\u3fcf\0\u3ffc\0\u01ef\0\u4029\0\u4056\0\u4083\0\u01ef"+ + "\0\u40b0\0\u01ef\0\u01ef\0\u40dd\0\u01ef\0\u410a\0\u4137\0\u4164"+ + "\0\u01ef\0\u01ef\0\u4191\0\u41be\0\u41eb\0\u4218\0\u4245\0\u4272"+ + "\0\u429f\0\u42cc\0\u42f9\0\u4326\0\u4353\0\u4380\0\u43ad\0\u01ef"+ + "\0\u43da\0\u4407\0\u4434\0\u4461\0\u448e\0\u44bb\0\u44e8\0\u4515"+ + "\0\u4542\0\u456f\0\u459c\0\u45c9\0\u45f6\0\u4623\0\u4650\0\u01ef"+ + "\0\u467d\0\u46aa\0\u01ef\0\u46d7\0\u4704\0\u01ef\0\u4731\0\u475e"+ + "\0\u478b\0\u47b8\0\u47e5\0\u4812\0\u483f\0\u486c\0\u4899\0\u48c6"+ + "\0\u01ef\0\u48f3\0\u4920\0\u494d\0\u01ef\0\u497a\0\u49a7\0\u01ef"+ + "\0\u49d4\0\u4a01\0\u4a2e\0\u4a5b\0\u4a88\0\u01ef\0\u4ab5\0\u01ef"+ + "\0\u4ae2\0\u4b0f\0\u4b3c\0\u4b69\0\u4b96\0\u4bc3\0\u4bf0\0\u4c1d"+ + "\0\u4c4a\0\u4c77\0\u4ca4\0\u4cd1\0\u01ef\0\u4cfe\0\u4d2b\0\u4d58"+ + "\0\u4d85\0\u4db2\0\u4ddf\0\u4e0c\0\u4e39\0\u01ef\0\u4e66\0\u4e93"+ + "\0\u4ec0\0\u4eed\0\u01ef\0\u4f1a\0\u01ef\0\u01ef\0\u4f47\0\u4f74"+ + "\0\u4fa1\0\u01ef\0\u4fce\0\u4ffb\0\u5028\0\u5055\0\u5082\0\u01ef"+ + "\0\u50af\0\u50dc\0\u5109\0\u01ef\0\u5136\0\u5163\0\u5190\0\u51bd"+ + "\0\u01ef\0\u51ea\0\u5217\0\u5244\0\u5271\0\u529e\0\u52cb\0\u52f8"+ + "\0\u5325\0\u5352\0\u537f\0\u53ac\0\u53d9\0\u01ef\0\u5406\0\u01ef"+ + "\0\u5433\0\u5460\0\u548d\0\u01ef\0\u54ba\0\u54e7\0\u5514\0\u5541"+ + "\0\u556e\0\u559b\0\u55c8\0\u55f5\0\u5622\0\u01ef\0\u564f\0\u01ef"+ + "\0\u567c\0\u56a9\0\u01ef\0\u56d6\0\u01ef\0\u5703\0\u5730\0\u575d"+ + "\0\u578a\0\u57b7\0\u57e4\0\u5811\0\u01ef\0\u583e\0\u586b\0\u01ef"+ + "\0\u01ef\0\u5898\0\u01ef\0\u58c5\0\u58f2\0\u591f\0\u594c\0\u5979"+ + "\0\u59a6\0\u59d3\0\u5a00\0\u5a2d\0\u5a5a\0\u5a87\0\u5ab4\0\u5ae1"+ + "\0\u5b0e\0\u5b3b\0\u5b68\0\u01ef\0\u5b95\0\u5bc2\0\u5bef\0\u5c1c"+ + "\0\u01ef\0\u5c49\0\u5c76\0\u5ca3\0\u5cd0\0\u5cfd\0\u01ef\0\u5d2a"+ + "\0\u01ef\0\u01ef\0\u5d57\0\u5d84\0\u5db1\0\u01ef\0\u5dde\0\u5e0b"+ + "\0\u5e38\0\u5e65\0\u01ef\0\u01ef\0\u01ef\0\u01ef\0\u5e92\0\u5ebf"+ + "\0\u5eec\0\u5f19\0\u5f46\0\u5f73\0\u5fa0\0\u5fcd\0\u5ffa\0\u6027"+ + "\0\u6054\0\u6081\0\u60ae\0\u60db\0\u6108\0\u6135\0\u6162\0\u618f"+ + "\0\u61bc\0\u01ef\0\u61e9\0\u01ef\0\u6216\0\u6243\0\u6270\0\u629d"+ + "\0\u62ca\0\u62f7\0\u6324\0\u6351\0\u637e\0\u01ef\0\u01ef\0\u63ab"+ + "\0\u63d8\0\u01ef\0\u6405\0\u6432\0\u645f\0\u01ef\0\u648c\0\u64b9"+ + "\0\u64e6\0\u6513\0\u6540\0\u656d\0\u659a\0\u65c7\0\u65f4\0\u01ef"+ + "\0\u6621\0\u664e\0\u667b\0\u66a8\0\u66d5\0\u6702\0\u01ef\0\u672f"+ + "\0\u675c\0\u6789\0\u67b6\0\u67e3\0\u6810\0\u683d\0\u686a\0\u6897"+ + "\0\u68c4\0\u68f1\0\u691e\0\u694b\0\u6978\0\u69a5\0\u69d2\0\u01ef"+ + "\0\u69ff\0\u6a2c\0\u6a59\0\u6a86\0\u6ab3\0\u6ae0\0\u6b0d\0\u01ef"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[712]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\11\1\12\2\13\1\14\1\15\1\16\1\15\1\17"+ + "\1\20\1\21\4\15\2\22\1\23\1\15\1\24\1\25"+ + "\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35"+ + "\1\36\1\37\1\40\1\41\1\42\1\15\1\43\1\44"+ + "\4\15\1\45\1\15\1\46\1\47\11\50\1\51\3\50"+ + "\1\52\37\50\12\53\1\51\2\53\1\52\37\53\1\11"+ + "\1\12\2\13\5\54\1\20\1\21\40\54\1\55\1\56"+ + "\1\11\1\12\2\13\5\54\1\20\1\21\12\54\1\57"+ + "\11\54\1\60\13\54\1\55\1\56\1\11\1\12\2\13"+ + "\5\61\1\20\1\21\4\61\1\11\33\61\1\55\1\56"+ + "\4\11\3\62\4\11\6\62\35\11\1\12\2\13\47\54"+ + "\1\55\1\56\57\0\1\13\56\0\1\15\1\63\45\15"+ + "\6\0\47\15\2\0\1\64\1\12\1\13\1\64\47\16"+ + "\2\64\10\0\1\17\3\0\1\65\4\0\1\17\1\66"+ + "\42\0\1\17\10\0\1\23\43\0\1\67\3\0\1\65"+ + "\4\0\1\67\1\66\36\0\20\15\1\70\3\15\1\71"+ + "\1\72\1\73\2\15\1\74\15\15\6\0\17\15\1\75"+ + "\2\15\1\76\24\15\6\0\16\15\1\77\6\15\1\100"+ + "\1\15\1\101\2\15\1\102\1\103\3\15\1\104\7\15"+ + "\6\0\24\15\1\105\5\15\1\106\1\15\1\107\1\110"+ + "\11\15\6\0\16\15\1\111\1\112\2\15\1\113\4\15"+ + "\1\114\17\15\6\0\21\15\1\115\25\15\6\0\41\15"+ + "\1\116\5\15\6\0\22\15\1\117\1\120\3\15\1\121"+ + "\17\15\6\0\42\15\1\122\4\15\6\0\16\15\1\123"+ + "\10\15\1\124\17\15\6\0\16\15\1\125\30\15\6\0"+ + "\16\15\1\126\3\15\1\127\4\15\1\130\17\15\6\0"+ + "\17\15\1\131\2\15\1\132\1\133\1\134\1\15\1\135"+ + "\1\136\4\15\1\137\12\15\6\0\16\15\1\140\3\15"+ + "\1\141\1\15\1\142\22\15\6\0\17\15\1\143\2\15"+ + "\1\144\1\145\3\15\1\146\4\15\1\147\12\15\6\0"+ + "\22\15\1\150\24\15\6\0\16\15\1\151\30\15\6\0"+ + "\27\15\1\152\4\15\1\153\12\15\2\0\11\50\1\0"+ + "\3\50\1\0\37\50\12\53\1\0\2\53\1\0\37\53"+ + "\4\0\47\54\6\0\27\54\1\154\17\54\6\0\26\54"+ + "\1\155\20\54\6\0\13\61\1\0\33\61\2\0\4\156"+ + "\1\157\1\15\45\157\2\156\1\64\1\12\1\13\52\64"+ + "\10\0\1\160\10\0\1\160\43\0\1\161\6\0\2\162"+ + "\1\163\37\0\21\15\1\164\25\15\6\0\25\15\1\165"+ + "\21\15\6\0\25\15\1\166\21\15\6\0\25\15\1\167"+ + "\21\15\6\0\17\15\1\170\27\15\6\0\26\15\1\171"+ + "\20\15\6\0\24\15\1\172\22\15\6\0\21\15\1\173"+ + "\25\15\6\0\17\15\1\174\14\15\1\175\12\15\6\0"+ + "\31\15\1\176\4\15\1\177\10\15\6\0\17\15\1\200"+ + "\27\15\6\0\17\15\1\201\27\15\6\0\17\15\1\202"+ + "\2\15\1\203\24\15\6\0\25\15\1\204\21\15\6\0"+ + "\36\15\1\205\10\15\6\0\35\15\1\206\11\15\6\0"+ + "\32\15\1\207\14\15\6\0\41\15\1\210\5\15\6\0"+ + "\26\15\1\211\2\15\1\212\15\15\6\0\20\15\1\213"+ + "\26\15\6\0\16\15\1\214\30\15\6\0\33\15\1\215"+ + "\13\15\6\0\32\15\1\216\7\15\1\217\4\15\6\0"+ + "\16\15\1\220\1\221\27\15\6\0\34\15\1\222\12\15"+ + "\6\0\17\15\1\223\27\15\6\0\34\15\1\224\12\15"+ + "\6\0\17\15\1\225\27\15\6\0\32\15\1\226\14\15"+ + "\6\0\25\15\1\227\21\15\6\0\32\15\1\230\1\15"+ + "\1\231\12\15\6\0\32\15\1\232\14\15\6\0\25\15"+ + "\1\233\6\15\1\234\1\15\1\235\10\15\6\0\21\15"+ + "\1\236\1\15\1\237\21\15\1\240\1\15\6\0\17\15"+ + "\1\241\27\15\6\0\23\15\1\242\23\15\6\0\20\15"+ + "\1\243\26\15\6\0\32\15\1\244\14\15\6\0\16\15"+ + "\1\245\30\15\6\0\21\15\1\246\4\15\1\247\20\15"+ + "\6\0\24\15\1\250\1\251\21\15\6\0\23\15\1\252"+ + "\23\15\6\0\32\15\1\253\14\15\6\0\34\15\1\254"+ + "\12\15\6\0\27\15\1\255\17\15\6\0\43\15\1\256"+ + "\3\15\6\0\22\15\1\257\24\15\6\0\21\15\1\260"+ + "\12\15\1\261\12\15\6\0\16\15\1\262\30\15\6\0"+ + "\32\15\1\263\1\15\1\264\1\15\1\265\10\15\6\0"+ + "\27\15\1\266\17\15\6\0\31\54\1\267\15\54\6\0"+ + "\20\54\1\270\26\54\2\0\5\156\1\271\53\156\1\157"+ + "\1\272\45\157\2\156\10\0\1\160\10\0\1\160\1\66"+ + "\42\0\1\161\10\0\1\161\43\0\1\161\10\0\1\163"+ + "\37\0\22\15\1\273\24\15\6\0\22\15\1\274\24\15"+ + "\6\0\17\15\1\275\27\15\6\0\27\15\1\276\17\15"+ + "\6\0\27\15\1\277\17\15\6\0\40\15\1\300\6\15"+ + "\6\0\32\15\1\301\14\15\6\0\21\15\1\302\25\15"+ + "\6\0\34\15\1\303\12\15\6\0\24\15\1\304\2\15"+ + "\1\305\17\15\6\0\32\15\1\306\14\15\6\0\16\15"+ + "\1\307\30\15\6\0\33\15\1\310\13\15\6\0\34\15"+ + "\1\311\12\15\6\0\33\15\1\312\13\15\6\0\30\15"+ + "\1\313\16\15\6\0\23\15\1\314\23\15\6\0\16\15"+ + "\1\315\30\15\6\0\31\15\1\316\15\15\6\0\16\15"+ + "\1\317\30\15\6\0\40\15\1\320\6\15\6\0\27\15"+ + "\1\321\17\15\6\0\34\15\1\322\12\15\6\0\7\15"+ + "\1\323\37\15\6\0\16\15\1\324\30\15\6\0\21\15"+ + "\1\325\3\15\1\326\21\15\6\0\33\15\1\327\13\15"+ + "\6\0\17\15\1\330\27\15\6\0\21\15\1\331\25\15"+ + "\6\0\26\15\1\332\20\15\6\0\31\15\1\333\15\15"+ + "\6\0\25\15\1\334\21\15\6\0\7\15\1\335\11\15"+ + "\1\336\25\15\6\0\16\15\1\337\30\15\6\0\45\15"+ + "\1\340\1\15\6\0\16\15\1\341\30\15\6\0\42\15"+ + "\1\342\4\15\6\0\16\15\1\343\30\15\6\0\37\15"+ + "\1\344\7\15\6\0\21\15\1\345\3\15\1\346\21\15"+ + "\6\0\21\15\1\347\25\15\6\0\25\15\1\350\1\15"+ + "\1\351\17\15\6\0\41\15\1\352\5\15\6\0\16\15"+ + "\1\353\30\15\6\0\26\15\1\354\3\15\1\355\14\15"+ + "\6\0\23\15\1\356\23\15\6\0\21\15\1\357\25\15"+ + "\6\0\35\15\1\360\11\15\6\0\22\15\1\361\24\15"+ + "\6\0\25\15\1\362\21\15\6\0\25\15\1\363\21\15"+ + "\6\0\17\15\1\364\27\15\6\0\16\15\1\365\30\15"+ + "\6\0\22\15\1\366\24\15\6\0\25\15\1\367\21\15"+ + "\6\0\33\15\1\370\13\15\6\0\32\15\1\371\7\15"+ + "\1\372\4\15\6\0\25\15\1\373\21\15\6\0\27\15"+ + "\1\374\17\15\6\0\33\15\1\375\13\15\6\0\36\15"+ + "\1\376\10\15\6\0\16\15\1\377\10\15\1\u0100\17\15"+ + "\6\0\25\15\1\u0101\21\15\6\0\25\15\1\u0102\21\15"+ + "\6\0\32\54\1\u0103\14\54\2\0\4\156\1\13\1\271"+ + "\53\156\1\15\1\272\45\157\2\156\4\0\23\15\1\u0104"+ + "\23\15\6\0\34\15\1\u0105\12\15\6\0\26\15\1\u0106"+ + "\20\15\6\0\30\15\1\u0107\16\15\6\0\32\15\1\u0108"+ + "\14\15\6\0\36\15\1\u0109\10\15\6\0\27\15\1\u010a"+ + "\17\15\6\0\25\15\1\u010b\21\15\6\0\26\15\1\u010c"+ + "\20\15\6\0\32\15\1\u010d\14\15\6\0\17\15\1\u010e"+ + "\27\15\6\0\7\15\1\u010f\37\15\6\0\16\15\1\u0110"+ + "\30\15\6\0\16\15\1\u0111\30\15\6\0\16\15\1\u0112"+ + "\30\15\6\0\27\15\1\u0113\17\15\6\0\34\15\1\u0114"+ + "\12\15\6\0\25\15\1\u0115\21\15\6\0\34\15\1\u0116"+ + "\12\15\6\0\7\15\1\u0117\37\15\6\0\26\15\1\u0118"+ + "\20\15\6\0\17\15\1\u0119\27\15\6\0\23\15\1\u011a"+ + "\4\15\1\u011b\1\15\1\u011c\14\15\6\0\25\15\1\u011d"+ + "\21\15\6\0\34\15\1\u011e\12\15\6\0\22\15\1\u011f"+ + "\24\15\6\0\34\15\1\u0120\12\15\6\0\21\15\1\u0121"+ + "\25\15\6\0\23\15\1\u0122\1\u0123\22\15\6\0\16\15"+ + "\1\u0124\30\15\6\0\27\15\1\u0125\17\15\6\0\17\15"+ + "\1\u0126\6\15\1\u0127\5\15\1\u0128\3\15\1\u0129\6\15"+ + "\6\0\34\15\1\u012a\12\15\6\0\22\15\1\u012b\24\15"+ + "\6\0\17\15\1\u012c\27\15\6\0\25\15\1\u012d\21\15"+ + "\6\0\16\15\1\u012e\30\15\6\0\7\15\1\u012f\37\15"+ + "\6\0\25\15\1\u0130\21\15\6\0\34\15\1\u0131\12\15"+ + "\6\0\25\15\1\u0132\21\15\6\0\23\15\1\u0133\5\15"+ + "\1\u0134\15\15\6\0\34\15\1\u0135\12\15\6\0\16\15"+ + "\1\u0136\30\15\6\0\16\15\1\u0137\30\15\6\0\7\15"+ + "\1\u0138\37\15\6\0\16\15\1\u0139\30\15\6\0\23\15"+ + "\1\u013a\23\15\6\0\17\15\1\u013b\27\15\6\0\16\15"+ + "\1\u013c\30\15\6\0\25\15\1\u013d\21\15\6\0\21\15"+ + "\1\u013e\25\15\6\0\24\15\1\u013f\22\15\6\0\41\15"+ + "\1\u0140\5\15\6\0\7\15\1\u0141\37\15\6\0\25\15"+ + "\1\u0142\21\15\6\0\25\15\1\u0143\21\15\6\0\7\15"+ + "\1\u0144\37\15\6\0\44\15\1\u0145\2\15\6\0\22\15"+ + "\1\u0146\24\15\6\0\22\15\1\u0147\24\15\6\0\7\15"+ + "\1\u0148\37\15\6\0\32\15\1\u0149\14\15\6\0\37\15"+ + "\1\u014a\7\15\6\0\16\15\1\u014b\30\15\6\0\17\54"+ + "\1\u014c\27\54\6\0\24\15\1\u014d\22\15\6\0\22\15"+ + "\1\u014e\24\15\6\0\37\15\1\u014f\7\15\6\0\16\15"+ + "\1\u0150\30\15\6\0\21\15\1\u0151\25\15\6\0\17\15"+ + "\1\u0152\27\15\6\0\22\15\1\u0153\24\15\6\0\7\15"+ + "\1\u0154\37\15\6\0\25\15\1\u0155\21\15\6\0\31\15"+ + "\1\u0156\15\15\6\0\23\15\1\u0157\23\15\6\0\17\15"+ + "\1\u0158\27\15\6\0\7\15\1\u0159\37\15\6\0\32\15"+ + "\1\u015a\14\15\6\0\37\15\1\u015b\7\15\6\0\7\15"+ + "\1\u015c\37\15\6\0\25\15\1\u015d\21\15\6\0\17\15"+ + "\1\u015e\27\15\6\0\34\15\1\u015f\12\15\6\0\17\15"+ + "\1\u0160\27\15\6\0\27\15\1\u0161\17\15\6\0\16\15"+ + "\1\u0162\30\15\6\0\17\15\1\u0163\27\15\6\0\22\15"+ + "\1\u0164\24\15\6\0\32\15\1\u0165\14\15\6\0\17\15"+ + "\1\u0166\27\15\6\0\7\15\1\u0167\6\15\1\u0168\30\15"+ + "\6\0\16\15\1\u0169\30\15\6\0\27\15\1\u016a\17\15"+ + "\6\0\26\15\1\u016b\20\15\6\0\25\15\1\u016c\21\15"+ + "\6\0\22\15\1\u016d\24\15\6\0\24\15\1\u016e\22\15"+ + "\6\0\16\15\1\u016f\30\15\6\0\17\15\1\u0170\27\15"+ + "\6\0\34\15\1\u0171\12\15\6\0\23\15\1\u0172\23\15"+ + "\6\0\41\15\1\u0173\5\15\6\0\34\15\1\u0174\12\15"+ + "\6\0\23\15\1\u0175\23\15\6\0\17\15\1\u0176\27\15"+ + "\6\0\22\15\1\u0177\24\15\6\0\27\15\1\u0178\17\15"+ + "\6\0\27\15\1\u0179\17\15\6\0\22\15\1\u017a\24\15"+ + "\6\0\7\15\1\u017b\32\15\1\u017c\4\15\6\0\7\15"+ + "\1\u017d\37\15\6\0\25\15\1\u017e\21\15\6\0\34\15"+ + "\1\u017f\12\15\6\0\24\15\1\u0180\22\15\6\0\32\15"+ + "\1\u0181\14\15\6\0\21\15\1\u0182\25\15\6\0\16\15"+ + "\1\u0183\30\15\6\0\25\15\1\u0184\21\15\6\0\35\15"+ + "\1\u0185\11\15\6\0\21\15\1\u0186\25\15\6\0\22\15"+ + "\1\u0187\24\15\6\0\26\15\1\u0188\1\15\1\u0189\16\15"+ + "\6\0\22\15\1\u018a\24\15\6\0\24\15\1\u018b\22\15"+ + "\6\0\45\15\1\u018c\1\15\6\0\40\15\1\u018d\6\15"+ + "\6\0\31\15\1\u018e\15\15\6\0\7\15\1\u018f\37\15"+ + "\6\0\23\54\1\u0190\23\54\6\0\25\15\1\u0191\21\15"+ + "\6\0\24\15\1\u0192\22\15\6\0\25\15\1\u0193\21\15"+ + "\6\0\34\15\1\u0194\12\15\6\0\32\15\1\u0195\14\15"+ + "\6\0\33\15\1\u0196\1\u0197\12\15\6\0\24\15\1\u0198"+ + "\22\15\6\0\7\15\1\u0199\37\15\6\0\32\15\1\u019a"+ + "\14\15\6\0\35\15\1\u019b\11\15\6\0\16\15\1\u019c"+ + "\30\15\6\0\34\15\1\u019d\12\15\6\0\41\15\1\u019e"+ + "\5\15\6\0\23\15\1\u019f\23\15\6\0\41\15\1\u01a0"+ + "\5\15\6\0\41\15\1\u01a1\5\15\6\0\17\15\1\u01a2"+ + "\27\15\6\0\25\15\1\u01a3\21\15\6\0\32\15\1\u01a4"+ + "\14\15\6\0\23\15\1\u01a5\23\15\6\0\16\15\1\u01a6"+ + "\30\15\6\0\32\15\1\u01a7\14\15\6\0\26\15\1\u01a8"+ + "\20\15\6\0\21\15\1\u01a9\25\15\6\0\25\15\1\u01aa"+ + "\21\15\6\0\17\15\1\u01ab\27\15\6\0\7\15\1\u01ac"+ + "\37\15\6\0\21\15\1\u01ad\25\15\6\0\23\15\1\u01ae"+ + "\23\15\6\0\16\15\1\u01af\30\15\6\0\25\15\1\u01b0"+ + "\21\15\6\0\40\15\1\u01b1\6\15\6\0\7\15\1\u01b2"+ + "\37\15\6\0\27\15\1\u01b3\17\15\6\0\26\15\1\u01b4"+ + "\20\15\6\0\24\15\1\u01b5\22\15\6\0\22\15\1\u01b6"+ + "\24\15\6\0\32\15\1\u01b7\14\15\6\0\32\15\1\u01b8"+ + "\14\15\6\0\26\15\1\u01b9\11\15\1\u01ba\6\15\6\0"+ + "\16\15\1\u01bb\30\15\6\0\30\15\1\u01bc\16\15\6\0"+ + "\27\15\1\u01bd\17\15\6\0\16\15\1\u01be\15\15\1\u01bf"+ + "\12\15\6\0\25\15\1\u01c0\21\15\6\0\31\15\1\u01c1"+ + "\15\15\6\0\7\15\1\u01c2\37\15\6\0\27\15\1\u01c3"+ + "\17\15\6\0\25\15\1\u01c4\21\15\6\0\17\15\1\u01c5"+ + "\27\15\6\0\16\15\1\u01c6\30\15\6\0\32\15\1\u01c7"+ + "\14\15\6\0\25\15\1\u01c8\21\15\6\0\16\15\1\u01c9"+ + "\30\15\6\0\34\15\1\u01ca\12\15\6\0\16\15\1\u01cb"+ + "\30\15\6\0\25\15\1\u01cc\21\15\6\0\7\15\1\u01cd"+ + "\37\15\6\0\41\15\1\u01ce\5\15\6\0\17\15\1\u01cf"+ + "\27\15\6\0\27\15\1\u01d0\17\15\6\0\34\15\1\u01d1"+ + "\12\15\6\0\46\15\1\u01d2\6\0\31\15\1\u01d3\15\15"+ + "\6\0\27\15\1\u01d4\17\15\6\0\24\15\1\u01d5\22\15"+ + "\6\0\33\15\1\u01d6\13\15\6\0\7\15\1\u01d7\37\15"+ + "\6\0\16\15\1\u01d8\30\15\6\0\25\15\1\u01d9\21\15"+ + "\6\0\32\15\1\u01da\14\15\6\0\26\15\1\u01db\20\15"+ + "\6\0\23\15\1\u01dc\23\15\6\0\23\15\1\u01dd\23\15"+ + "\6\0\21\15\1\u01de\25\15\6\0\25\15\1\u01df\21\15"+ + "\6\0\16\15\1\u01e0\30\15\6\0\33\15\1\u01e1\13\15"+ + "\6\0\16\15\1\u01e2\30\15\6\0\7\15\1\u01e3\37\15"+ + "\6\0\36\15\1\u01e4\10\15\6\0\20\15\1\u01e5\26\15"+ + "\6\0\40\15\1\u01e6\6\15\6\0\25\15\1\u01e7\21\15"+ + "\6\0\32\15\1\u01e8\14\15\6\0\16\15\1\u01e9\30\15"+ + "\6\0\22\15\1\u01ea\24\15\6\0\16\15\1\u01eb\30\15"+ + "\6\0\32\15\1\u01ec\14\15\6\0\27\15\1\u01ed\17\15"+ + "\6\0\31\15\1\u01ee\15\15\6\0\36\15\1\u01ef\10\15"+ + "\6\0\16\15\1\u01be\30\15\6\0\27\15\1\u01f0\17\15"+ + "\6\0\23\15\1\u01f1\23\15\6\0\35\15\1\u01f2\11\15"+ + "\6\0\30\15\1\u01f3\16\15\6\0\41\15\1\u01f4\5\15"+ + "\6\0\36\15\1\u01f5\10\15\6\0\34\15\1\u01f6\12\15"+ + "\6\0\25\15\1\u01f7\21\15\6\0\16\15\1\u01f8\30\15"+ + "\6\0\16\15\1\u01f9\30\15\6\0\16\15\1\u01fa\30\15"+ + "\6\0\33\15\1\u01fb\13\15\6\0\21\15\1\u01fc\25\15"+ + "\6\0\33\15\1\u01fd\13\15\6\0\16\15\1\u01fe\30\15"+ + "\6\0\24\15\1\u01ff\22\15\6\0\23\15\1\u0200\23\15"+ + "\6\0\43\15\1\u0201\3\15\6\0\23\15\1\u0202\23\15"+ + "\6\0\16\15\1\u0203\30\15\6\0\33\15\1\u0204\13\15"+ + "\6\0\34\15\1\u0205\12\15\6\0\25\15\1\u0206\21\15"+ + "\6\0\16\15\1\u0207\30\15\6\0\17\15\1\u0208\27\15"+ + "\6\0\42\15\1\u0209\4\15\6\0\21\15\1\u020a\25\15"+ + "\6\0\22\15\1\u020b\24\15\6\0\36\15\1\u020c\10\15"+ + "\6\0\22\15\1\u020d\24\15\6\0\16\15\1\u020e\30\15"+ + "\6\0\34\15\1\u020f\12\15\6\0\16\15\1\u0210\30\15"+ + "\6\0\7\15\1\u0211\37\15\6\0\32\15\1\u0212\14\15"+ + "\6\0\16\15\1\u0213\30\15\6\0\25\15\1\u0214\21\15"+ + "\6\0\17\15\1\u0215\27\15\6\0\37\15\1\u0216\7\15"+ + "\6\0\7\15\1\u0217\37\15\6\0\22\15\1\u0218\24\15"+ + "\6\0\16\15\1\u0219\30\15\6\0\27\15\1\u021a\17\15"+ + "\6\0\16\15\1\u021b\30\15\6\0\23\15\1\u021c\23\15"+ + "\6\0\21\15\1\u021d\25\15\6\0\17\15\1\u021e\27\15"+ + "\6\0\33\15\1\u021f\13\15\6\0\21\15\1\u0220\25\15"+ + "\6\0\7\15\1\u0221\37\15\6\0\34\15\1\u0222\12\15"+ + "\6\0\21\15\1\u0223\25\15\6\0\24\15\1\u0224\22\15"+ + "\6\0\22\15\1\u0225\24\15\6\0\16\15\1\u0226\30\15"+ + "\6\0\16\15\1\u0227\30\15\6\0\16\15\1\u0228\30\15"+ + "\6\0\17\15\1\u0229\27\15\6\0\7\15\1\u022a\37\15"+ + "\6\0\21\15\1\u022b\25\15\6\0\36\15\1\u022c\10\15"+ + "\6\0\24\15\1\u022d\22\15\6\0\7\15\1\u022e\37\15"+ + "\6\0\24\15\1\u022f\22\15\6\0\31\15\1\u0230\15\15"+ + "\6\0\17\15\1\u0231\27\15\6\0\33\15\1\u0232\13\15"+ + "\6\0\25\15\1\u0233\21\15\6\0\33\15\1\u0234\13\15"+ + "\6\0\7\15\1\u0235\37\15\6\0\25\15\1\u0236\21\15"+ + "\6\0\36\15\1\u0237\10\15\6\0\32\15\1\u0238\14\15"+ + "\6\0\34\15\1\u0239\12\15\6\0\7\15\1\u023a\37\15"+ + "\6\0\16\15\1\u023b\30\15\6\0\27\15\1\u023c\17\15"+ + "\6\0\23\15\1\u023d\23\15\6\0\22\15\1\u023e\24\15"+ + "\6\0\22\15\1\u023f\24\15\6\0\21\15\1\u0240\25\15"+ + "\6\0\16\15\1\u0241\30\15\6\0\7\15\1\u0242\37\15"+ + "\6\0\33\15\1\u0243\13\15\6\0\25\15\1\u0244\21\15"+ + "\6\0\36\15\1\u0245\10\15\6\0\34\15\1\u0246\12\15"+ + "\6\0\26\15\1\u0247\20\15\6\0\21\15\1\u0248\25\15"+ + "\6\0\25\15\1\u0249\21\15\6\0\20\15\1\u024a\26\15"+ + "\6\0\25\15\1\u024b\21\15\6\0\34\15\1\u024c\12\15"+ + "\6\0\34\15\1\u024d\12\15\6\0\17\15\1\u024e\27\15"+ + "\6\0\34\15\1\u024f\12\15\6\0\22\15\1\u0250\24\15"+ + "\6\0\26\15\1\u0251\20\15\6\0\27\15\1\u0252\17\15"+ + "\6\0\21\15\1\u0253\25\15\6\0\36\15\1\u0254\10\15"+ + "\6\0\22\15\1\u0255\24\15\6\0\24\15\1\u0256\22\15"+ + "\6\0\23\15\1\u0257\23\15\6\0\16\15\1\u0258\30\15"+ + "\6\0\35\15\1\u0259\11\15\6\0\32\15\1\u025a\14\15"+ + "\6\0\7\15\1\u025b\37\15\6\0\16\15\1\u025c\30\15"+ + "\6\0\25\15\1\u025d\21\15\6\0\23\15\1\u025e\23\15"+ + "\6\0\41\15\1\u025f\5\15\6\0\16\15\1\u0260\30\15"+ + "\6\0\41\15\1\u0261\5\15\6\0\25\15\1\u0262\21\15"+ + "\6\0\22\15\1\u0263\24\15\6\0\24\15\1\u0264\22\15"+ + "\6\0\22\15\1\u0265\24\15\6\0\34\15\1\u0266\12\15"+ + "\6\0\25\15\1\u0267\21\15\6\0\16\15\1\u0268\30\15"+ + "\6\0\32\15\1\u0269\14\15\6\0\25\15\1\u026a\21\15"+ + "\6\0\24\15\1\u026b\22\15\6\0\25\15\1\u026c\21\15"+ + "\6\0\16\15\1\u026d\30\15\6\0\22\15\1\u026e\24\15"+ + "\6\0\26\15\1\u026f\20\15\6\0\7\15\1\u0270\37\15"+ + "\6\0\17\15\1\u0271\27\15\6\0\7\15\1\u0272\37\15"+ + "\6\0\16\15\1\u0273\30\15\6\0\37\15\1\u0274\7\15"+ + "\6\0\23\15\1\u0275\23\15\6\0\25\15\1\u0276\21\15"+ + "\6\0\21\15\1\u0277\25\15\6\0\16\15\1\u0278\30\15"+ + "\6\0\31\15\1\u0279\15\15\6\0\25\15\1\u027a\21\15"+ + "\6\0\25\15\1\u027b\21\15\6\0\34\15\1\u027c\12\15"+ + "\6\0\22\15\1\u027d\24\15\6\0\42\15\1\u027e\4\15"+ + "\6\0\21\15\1\u027f\25\15\6\0\35\15\1\u0280\11\15"+ + "\6\0\25\15\1\u0281\21\15\6\0\26\15\1\u0282\20\15"+ + "\6\0\34\15\1\u0283\12\15\6\0\27\15\1\u0284\17\15"+ + "\6\0\27\15\1\u0285\17\15\6\0\16\15\1\u0286\15\15"+ + "\1\u0287\12\15\6\0\21\15\1\u0288\25\15\6\0\17\15"+ + "\1\u0289\27\15\6\0\21\15\1\u028a\25\15\6\0\34\15"+ + "\1\u028b\12\15\6\0\21\15\1\u028c\25\15\6\0\25\15"+ + "\1\u028d\21\15\6\0\16\15\1\u028e\30\15\6\0\22\15"+ + "\1\u028f\24\15\6\0\32\15\1\u0290\14\15\6\0\36\15"+ + "\1\u0291\10\15\6\0\16\15\1\u0286\30\15\6\0\25\15"+ + "\1\u0292\21\15\6\0\33\15\1\u0293\13\15\6\0\16\15"+ + "\1\u0294\30\15\6\0\27\15\1\u0295\17\15\6\0\16\15"+ + "\1\u0296\30\15\6\0\32\15\1\u0297\14\15\6\0\31\15"+ + "\1\u0298\15\15\6\0\7\15\1\u0299\37\15\6\0\21\15"+ + "\1\u029a\25\15\6\0\33\15\1\u029b\13\15\6\0\16\15"+ + "\1\u029c\30\15\6\0\22\15\1\u029d\24\15\6\0\21\15"+ + "\1\u029e\25\15\6\0\36\15\1\u029f\10\15\6\0\27\15"+ + "\1\u02a0\17\15\6\0\34\15\1\u02a1\12\15\6\0\32\15"+ + "\1\u02a2\14\15\6\0\27\15\1\u02a3\17\15\6\0\32\15"+ + "\1\u02a4\14\15\6\0\22\15\1\u02a5\24\15\6\0\7\15"+ + "\1\u02a6\37\15\6\0\34\15\1\u02a7\12\15\6\0\31\15"+ + "\1\u02a8\15\15\6\0\24\15\1\u02a9\22\15\6\0\25\15"+ + "\1\u02aa\21\15\6\0\16\15\1\u02ab\30\15\6\0\25\15"+ + "\1\u02ac\21\15\6\0\34\15\1\u02ad\12\15\6\0\26\15"+ + "\1\u02ae\20\15\6\0\16\15\1\u02af\30\15\6\0\17\15"+ + "\1\u02b0\27\15\6\0\25\15\1\u02b1\21\15\6\0\26\15"+ + "\1\u02b2\20\15\6\0\27\15\1\u02b3\17\15\6\0\16\15"+ + "\1\u02b4\30\15\6\0\22\15\1\u02b5\24\15\6\0\7\15"+ + "\1\u02b6\37\15\6\0\32\15\1\u02b7\14\15\6\0\26\15"+ + "\1\u02b8\20\15\6\0\7\15\1\u02b9\37\15\6\0\22\15"+ + "\1\u02ba\24\15\6\0\25\15\1\u02bb\21\15\6\0\21\15"+ + "\1\u02bc\25\15\6\0\34\15\1\u02bd\12\15\6\0\25\15"+ + "\1\u02be\21\15\6\0\17\15\1\u02bf\27\15\6\0\21\15"+ + "\1\u02c0\25\15\6\0\26\15\1\u02c1\20\15\6\0\16\15"+ + "\1\u02c2\30\15\6\0\7\15\1\u02c3\37\15\6\0\26\15"+ + "\1\u02c4\20\15\6\0\22\15\1\u02c5\24\15\6\0\21\15"+ + "\1\u02c6\25\15\6\0\25\15\1\u02c7\21\15\6\0\21\15"+ + "\1\u02c8\25\15\2\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[27450]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\7\0\1\1\1\11\1\1\1\11\4\1\2\11\24\1"+ + "\2\11\1\1\2\11\2\1\2\11\3\1\1\11\1\1"+ + "\3\0\67\1\1\0\3\1\1\0\1\11\105\1\1\0"+ + "\u020f\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[712]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ + StringBuffer string = new StringBuffer(); + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + SpecctraFileScanner(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + SpecctraFileScanner(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 274) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Object next_token() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 18: + { yybegin(NAME); return Keyword.VIA; + } + case 121: break; + case 24: + { return Keyword.BACK; + } + case 122: break; + case 31: + { yybegin(LAYER_NAME); return Keyword.POLYGON_PATH; + } + case 123: break; + case 71: + { return Keyword.NETWORK_SCOPE; + } + case 124: break; + case 56: + { return Keyword.ROUTES; + } + case 125: break; + case 93: + { return Keyword.FLIP_STYLE; + } + case 126: break; + case 108: + { return Keyword.PLACE_CONTROL; + } + case 127: break; + case 32: + { yybegin(LAYER_NAME); return Keyword.POLYGON; + } + case 128: break; + case 78: + { yybegin(NAME); return Keyword.PADSTACK; + } + case 129: break; + case 110: + { yybegin(NAME); return Keyword.CLEARANCE_CLASS; + } + case 130: break; + case 115: + { return Keyword.AUTOROUTE_SETTINGS; + } + case 131: break; + case 13: + { yybegin(YYINITIAL); return Keyword.OPEN_BRACKET; + } + case 132: break; + case 105: + { return Keyword.START_PASS_NO; + } + case 133: break; + case 23: + { yybegin(YYINITIAL); return Keyword.PCB_SCOPE; + } + case 134: break; + case 34: + { yybegin(LAYER_NAME); return Keyword.RECTANGLE; + } + case 135: break; + case 82: + { return Keyword.STRUCTURE_SCOPE; + } + case 136: break; + case 27: + { yybegin(NAME); return Keyword.COMPONENT_SCOPE; + } + case 137: break; + case 43: + { yybegin(NAME); return Keyword.IMAGE; + } + case 138: break; + case 112: + { return Keyword.FORTYFIVE_DEGREE; + } + case 139: break; + case 60: + { return Keyword.WINDOW; + } + case 140: break; + case 76: + { return Keyword.VERTICAL; + } + case 141: break; + case 20: + { return Keyword.PCB_SCOPE; + } + case 142: break; + case 37: + { return Keyword.SPARE; + } + case 143: break; + case 21: + { return Keyword.PIN; + } + case 144: break; + case 35: + { return Keyword.RULE; + } + case 145: break; + case 29: + { return Keyword.VIAS; + } + case 146: break; + case 16: + { return Keyword.ON; + } + case 147: break; + case 63: + { return Keyword.SESSION; + } + case 148: break; + case 74: + { return Keyword.BOUNDARY; + } + case 149: break; + case 88: + { return Keyword.SNAP_ANGLE; + } + case 150: break; + case 113: + { return Keyword.WRITE_RESOLUTION; + } + case 151: break; + case 54: + { return Keyword.NORMAL; + } + case 152: break; + case 8: + { return Keyword.OPEN_BRACKET; + } + case 153: break; + case 22: + { return Keyword.FIX; + } + case 154: break; + case 89: + { yybegin(NAME); return Keyword.LAYER_RULE; + } + case 155: break; + case 86: + { return Keyword.POSTROUTE; + } + case 156: break; + case 14: + { yybegin(YYINITIAL); return Keyword.CLOSED_BRACKET; + } + case 157: break; + case 9: + { return Keyword.CLOSED_BRACKET; + } + case 158: break; + case 90: + { return Keyword.VIA_AT_SMD; + } + case 159: break; + case 28: + { yybegin(LAYER_NAME); return Keyword.CIRCLE; + } + case 160: break; + case 50: + { return Keyword.ATTACH; + } + case 161: break; + case 92: + { return Keyword.RESOLUTION_SCOPE; + } + case 162: break; + case 77: + { return Keyword.VIA_RULE; + } + case 163: break; + case 70: + { return Keyword.CIRCUIT; + } + case 164: break; + case 87: + { return Keyword.PLACEMENT_SCOPE; + } + case 165: break; + case 36: + { yybegin(NAME); return Keyword.WIRE; + } + case 166: break; + case 116: + { return Keyword.PREFERRED_DIRECTION; + } + case 167: break; + case 40: + { yybegin(NAME); return Keyword.LAYER; + } + case 168: break; + case 69: + { return Keyword.CLASSES; + } + case 169: break; + case 61: + { return Keyword.WIRING_SCOPE; + } + case 170: break; + case 103: + { yybegin(NAME); return Keyword.HOST_VERSION; + } + case 171: break; + case 4: + { return yytext(); + } + case 172: break; + case 73: + { return Keyword.ABSOLUTE; + } + case 173: break; + case 58: + { return Keyword.FANOUT; + } + case 174: break; + case 79: + { return Keyword.POSITION; + } + case 175: break; + case 47: + { return Keyword.RULES; + } + case 176: break; + case 57: + { return Keyword.ROTATE; + } + case 177: break; + case 7: + { string.setLength(0); yybegin(STRING2); + } + case 178: break; + case 84: + { yybegin(NAME); return Keyword.USE_LAYER; + } + case 179: break; + case 80: + { yybegin(NAME); return Keyword.HOST_CAD; + } + case 180: break; + case 64: + { return Keyword.OUTLINE; + } + case 181: break; + case 45: + { yybegin(NAME); return Keyword.PLACE; + } + case 182: break; + case 6: + { string.setLength(0); yybegin(STRING1); + } + case 183: break; + case 99: + { yybegin(IGNORE_QUOTE); return Keyword.STRING_QUOTE; + } + case 184: break; + case 39: + { return Keyword.ORDER; + } + case 185: break; + case 17: + { return Keyword.OFF; + } + case 186: break; + case 81: + { return Keyword.AUTOROUTE; + } + case 187: break; + case 52: + { return Keyword.SIGNAL; + } + case 188: break; + case 107: + { yybegin(LAYER_NAME); return Keyword.POLYLINE_PATH; + } + case 189: break; + case 68: + { return Keyword.CONTROL; + } + case 190: break; + case 46: + { yybegin(NAME); return Keyword.PLANE_SCOPE; + } + case 191: break; + case 1: + { yybegin(YYINITIAL); return yytext(); + } + case 192: break; + case 100: + { yybegin(NAME); return Keyword.LOGICAL_PART; + } + case 193: break; + case 83: + { return Keyword.LOCK_TYPE; + } + case 194: break; + case 109: + { yybegin(NAME); return Keyword.PLACE_KEEPOUT; + } + case 195: break; + case 49: + { return Keyword.WIDTH; + } + case 196: break; + case 106: + { return Keyword.NINETY_DEGREE; + } + case 197: break; + case 67: + { yybegin(NAME); return Keyword.USE_NET; + } + case 198: break; + case 118: + { return Keyword.GENERATED_BY_FREEROUTE; + } + case 199: break; + case 101: + { return Keyword.PART_LIBRARY_SCOPE; + } + case 200: break; + case 85: + { return Keyword.VIA_COSTS; + } + case 201: break; + case 102: + { return Keyword.ROTATE_FIRST; + } + case 202: break; + case 75: + { return Keyword.CONSTANT; + } + case 203: break; + case 12: + { string.append('\\'); + } + case 204: break; + case 15: + { return new Double(yytext()); + } + case 205: break; + case 42: + { yybegin(NAME); return Keyword.CLASS; + } + case 206: break; + case 91: + { return Keyword.PULL_TIGHT; + } + case 207: break; + case 30: + { return Keyword.NONE; + } + case 208: break; + case 120: + { return Keyword.AGAINST_PREFERRED_DIRECTION_TRACE_COSTS; + } + case 209: break; + case 114: + { return Keyword.START_RIPUP_COSTS; + } + case 210: break; + case 53: + { return Keyword.LENGTH; + } + case 211: break; + case 38: + { return Keyword.SHAPE; + } + case 212: break; + case 59: + { return Keyword.FROMTO; + } + case 213: break; + case 44: + { return Keyword.POWER; + } + case 214: break; + case 94: + { return Keyword.HORIZONTAL; + } + case 215: break; + case 26: + { return Keyword.TYPE; + } + case 216: break; + case 51: + { return Keyword.ACTIVE; + } + case 217: break; + case 48: + { return Keyword.FRONT; + } + case 218: break; + case 11: + { yybegin(YYINITIAL); return string.toString(); + } + case 219: break; + case 19: + { yybegin(NAME); return Keyword.NET; + } + case 220: break; + case 96: + { return Keyword.CLASS_CLASS; + } + case 221: break; + case 66: + { yybegin(NAME); return Keyword.USE_VIA; + } + case 222: break; + case 65: + { return Keyword.LIBRARY_SCOPE; + } + case 223: break; + case 3: + { /* ignore */ + } + case 224: break; + case 117: + { yybegin(NAME); return Keyword.LOGICAL_PART_MAPPING; + } + case 225: break; + case 111: + { return Keyword.PLANE_VIA_COSTS; + } + case 226: break; + case 72: + { yybegin(NAME); return Keyword.KEEPOUT; + } + case 227: break; + case 98: + { return Keyword.NETWORK_OUT; + } + case 228: break; + case 55: + { return Keyword.PARSER_SCOPE; + } + case 229: break; + case 10: + { string.append( yytext() ); + } + case 230: break; + case 2: + { throw new Error("Illegal character <"+ + yytext()+">"); + } + case 231: break; + case 95: + { return Keyword.SHOVE_FIXED; + } + case 232: break; + case 104: + { return Keyword.KEEPOUT; + } + case 233: break; + case 33: + { return Keyword.PINS; + } + case 234: break; + case 119: + { return Keyword.PREFERRED_DIRECTION_TRACE_COSTS; + } + case 235: break; + case 5: + { return new Integer(yytext()); + } + case 236: break; + case 25: + { return Keyword.SIDE; + } + case 237: break; + case 41: + { return Keyword.CLEARANCE; + } + case 238: break; + case 97: + { yybegin(NAME); return Keyword.VIA_KEEPOUT; + } + case 239: break; + case 62: + { yybegin(YYINITIAL); return Keyword.SIGNAL; + } + case 240: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Structure.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Structure.java new file mode 100644 index 0000000..bc53d2f --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Structure.java @@ -0,0 +1,1419 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Structure.java + * + * Created on 13. Mai 2004, 09:57 + */ +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.Point; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import eu.mihosoft.freerouting.datastructures.UndoableObjects; + +import eu.mihosoft.freerouting.rules.BoardRules; +import eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; +import eu.mihosoft.freerouting.datastructures.UndoableObjects.Storable; + +import eu.mihosoft.freerouting.board.FixedState; +import eu.mihosoft.freerouting.board.TestLevel; + +/** + * Class for reading and writing structure scopes from dsn-files. + * + * @author Alfons Wirtz + */ +class Structure extends ScopeKeyword +{ + + /** Creates a new instance of Structure */ + public Structure() + { + super("structure"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + BoardConstructionInfo board_construction_info = new BoardConstructionInfo(); + + + // If true, components on the back side are rotated before mirroring + // The correct location is the scope PlaceControl, but Electra writes it here. + boolean flip_style_rotate_first = false; + + Collection keepout_list = new LinkedList(); + Collection via_keepout_list = new LinkedList(); + Collection place_keepout_list = new LinkedList(); + + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + if (next_token == null) + { + System.out.println("Structure.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + boolean read_ok = true; + if (prev_token == OPEN_BRACKET) + { + if (next_token == Keyword.BOUNDARY) + { + read_boundary_scope(p_par.scanner, board_construction_info); + } + else if (next_token == Keyword.LAYER) + { + read_ok = read_layer_scope(p_par.scanner, board_construction_info, p_par.string_quote); + if (p_par.layer_structure != null) + { + // correct the layer_structure because another layer isr read + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + } + } + else if (next_token == Keyword.VIA) + { + p_par.via_padstack_names = read_via_padstacks(p_par.scanner); + } + else if (next_token == Keyword.RULE) + { + board_construction_info.default_rules.addAll(Rule.read_scope(p_par.scanner)); + } + else if (next_token == Keyword.KEEPOUT) + { + if (p_par.layer_structure == null) + { + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + } + keepout_list.add(Shape.read_area_scope(p_par.scanner, p_par.layer_structure, false)); + } + else if (next_token == Keyword.VIA_KEEPOUT) + { + if (p_par.layer_structure == null) + { + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + } + via_keepout_list.add(Shape.read_area_scope(p_par.scanner, p_par.layer_structure, false)); + } + else if (next_token == Keyword.PLACE_KEEPOUT) + { + if (p_par.layer_structure == null) + { + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + } + place_keepout_list.add(Shape.read_area_scope(p_par.scanner, p_par.layer_structure, false)); + } + else if (next_token == Keyword.PLANE_SCOPE) + { + if (p_par.layer_structure == null) + { + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + } + Keyword.PLANE_SCOPE.read_scope(p_par); + } + else if (next_token == Keyword.AUTOROUTE_SETTINGS) + { + if (p_par.layer_structure == null) + { + p_par.layer_structure = new LayerStructure(board_construction_info.layer_info); + p_par.autoroute_settings = AutorouteSettings.read_scope(p_par.scanner, p_par.layer_structure); + } + } + else if (next_token == Keyword.CONTROL) + { + read_ok = read_control_scope(p_par); + } + else if (next_token == Keyword.FLIP_STYLE) + { + flip_style_rotate_first = PlaceControl.read_flip_style_rotate_first(p_par.scanner); + } + else if (next_token == Keyword.SNAP_ANGLE) + { + + eu.mihosoft.freerouting.board.AngleRestriction snap_angle = read_snap_angle(p_par.scanner); + if (snap_angle != null) + { + p_par.snap_angle = snap_angle; + } + } + else + { + skip_scope(p_par.scanner); + } + } + if (!read_ok) + { + return false; + } + } + + boolean result = true; + if (p_par.board_handling.get_routing_board() == null) + { + result = create_board(p_par, board_construction_info); + } + eu.mihosoft.freerouting.board.RoutingBoard board = p_par.board_handling.get_routing_board(); + if (board == null) + { + return false; + } + if (flip_style_rotate_first) + { + board.components.set_flip_style_rotate_first(true); + } + FixedState fixed_state; + if (board.get_test_level() == TestLevel.RELEASE_VERSION) + { + fixed_state = FixedState.SYSTEM_FIXED; + } + else + { + fixed_state = FixedState.USER_FIXED; + } + // insert the keepouts + for (Shape.ReadAreaScopeResult curr_area : keepout_list) + { + if (!insert_keepout(curr_area, p_par, KeepoutType.keepout, fixed_state)) + { + return false; + } + } + + for (Shape.ReadAreaScopeResult curr_area : via_keepout_list) + { + if (!insert_keepout(curr_area, p_par, KeepoutType.via_keepout, FixedState.SYSTEM_FIXED)) + { + return false; + } + } + + for (Shape.ReadAreaScopeResult curr_area : place_keepout_list) + { + if (!insert_keepout(curr_area, p_par, KeepoutType.place_keepout, FixedState.SYSTEM_FIXED)) + { + return false; + } + } + + // insert the planes. + Iterator it = p_par.plane_list.iterator(); + while (it.hasNext()) + { + ReadScopeParameter.PlaneInfo plane_info = it.next(); + Net.Id net_id = new Net.Id(plane_info.net_name, 1); + if (!p_par.netlist.contains(net_id)) + { + Net new_net = p_par.netlist.add_net(net_id); + if (new_net != null) + { + board.rules.nets.add(new_net.id.name, new_net.id.subnet_number, true); + } + } + eu.mihosoft.freerouting.rules.Net curr_net = board.rules.nets.get(plane_info.net_name, 1); + if (curr_net == null) + { + System.out.println("Plane.read_scope: net not found"); + continue; + } + eu.mihosoft.freerouting.geometry.planar.Area plane_area = + Shape.transform_area_to_board(plane_info.area.shape_list, p_par.coordinate_transform); + Layer curr_layer = (plane_info.area.shape_list.iterator().next()).layer; + if (curr_layer.no >= 0) + { + int clearance_class_no; + if (plane_info.area.clearance_class_name != null) + { + clearance_class_no = board.rules.clearance_matrix.get_no(plane_info.area.clearance_class_name); + if (clearance_class_no < 0) + { + System.out.println("Structure.read_scope: clearance class not found"); + clearance_class_no = BoardRules.clearance_class_none(); + } + } + else + { + clearance_class_no = curr_net.get_class().default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.AREA); + } + int[] net_numbers = new int[1]; + net_numbers[0] = curr_net.net_number; + board.insert_conduction_area(plane_area, curr_layer.no, net_numbers, clearance_class_no, + false, FixedState.SYSTEM_FIXED); + } + else + { + System.out.println("Plane.read_scope: unexpected layer name"); + return false; + } + } + insert_missing_power_planes(board_construction_info.layer_info, p_par.netlist, board); + + p_par.board_handling.initialize_manual_trace_half_widths(); + if (p_par.autoroute_settings != null) + { + p_par.board_handling.get_settings().autoroute_settings = p_par.autoroute_settings; + } + return result; + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("structure"); + // write the bounding box + p_par.file.start_scope(); + p_par.file.write("boundary"); + IntBox bounds = p_par.board.get_bounding_box(); + double[] rect_coor = p_par.coordinate_transform.board_to_dsn(bounds); + Rectangle bounding_rectangle = new Rectangle(Layer.PCB, rect_coor); + bounding_rectangle.write_scope(p_par.file, p_par.identifier_type); + p_par.file.end_scope(); + // lookup the outline in the eu.mihosoft.freerouting.board + Storable curr_ob = null; + Iterator it = p_par.board.item_list.start_read_object(); + for (;;) + { + curr_ob = p_par.board.item_list.read_object(it); + if (curr_ob == null) + { + break; + } + if (curr_ob instanceof eu.mihosoft.freerouting.board.BoardOutline) + { + break; + } + } + if (curr_ob == null) + { + System.out.println("Structure.write_scope; outline not found"); + return; + } + eu.mihosoft.freerouting.board.BoardOutline outline = (eu.mihosoft.freerouting.board.BoardOutline) curr_ob; + + // write the outline + for (int i = 0; i < outline.shape_count(); ++i) + { + Shape outline_shape = p_par.coordinate_transform.board_to_dsn(outline.get_shape(i), Layer.SIGNAL); + p_par.file.start_scope(); + p_par.file.write("boundary"); + outline_shape.write_scope(p_par.file, p_par.identifier_type); + p_par.file.end_scope(); + } + + write_snap_angle(p_par.file, p_par.board.rules.get_trace_angle_restriction()); + + // write the routing vias + write_via_padstacks(p_par.board.library, p_par.file, p_par.identifier_type); + + // write the control scope + write_control_scope(p_par.board.rules, p_par.file); + + write_default_rules(p_par); + + // write the eu.mihosoft.freerouting.autoroute settings + AutorouteSettings.write_scope(p_par.file, p_par.autoroute_settings, + p_par.board.layer_structure, p_par.identifier_type); + + // write the keepouts + it = p_par.board.item_list.start_read_object(); + for (;;) + { + curr_ob = p_par.board.item_list.read_object(it); + if (curr_ob == null) + { + break; + } + if (!(curr_ob instanceof eu.mihosoft.freerouting.board.ObstacleArea)) + { + continue; + } + eu.mihosoft.freerouting.board.ObstacleArea curr_keepout = (eu.mihosoft.freerouting.board.ObstacleArea) curr_ob; + if (curr_keepout.get_component_no() != 0) + { + // keepouts belonging to a component are not written individually. + continue; + } + if (curr_keepout instanceof eu.mihosoft.freerouting.board.ConductionArea) + { + // conduction area will be written later. + continue; + } + write_keepout_scope(p_par, curr_keepout); + } + + // write the conduction areas + it = p_par.board.item_list.start_read_object(); + for (;;) + { + curr_ob = p_par.board.item_list.read_object(it); + if (curr_ob == null) + { + break; + } + if (!(curr_ob instanceof eu.mihosoft.freerouting.board.ConductionArea)) + { + continue; + } + eu.mihosoft.freerouting.board.ConductionArea curr_area = (eu.mihosoft.freerouting.board.ConductionArea) curr_ob; + if (p_par.board.layer_structure.arr[curr_area.get_layer()].is_signal) + { + // These conduction areas are written in the wiring scope. + continue; + } + Plane.write_scope(p_par, (eu.mihosoft.freerouting.board.ConductionArea) curr_ob); + } + p_par.file.end_scope(); + } + + static void write_default_rules(WriteScopeParameter p_par) throws java.io.IOException + { + // write the default rule using 0 as default layer. + Rule.write_default_rule(p_par, 0); + + // write the layer structure + for (int i = 0; i < p_par.board.layer_structure.arr.length; ++i) + { + boolean write_layer_rule = + p_par.board.rules.get_default_net_class().get_trace_half_width(i) != p_par.board.rules.get_default_net_class().get_trace_half_width(0) || !clearance_equals(p_par.board.rules.clearance_matrix, i, 0); + Layer.write_scope(p_par, i, write_layer_rule); + } + } + + private static void write_via_padstacks(eu.mihosoft.freerouting.library.BoardLibrary p_library, IndentFileWriter p_file, + IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.new_line(); + p_file.write("(via"); + for (int i = 0; i < p_library.via_padstack_count(); ++i) + { + eu.mihosoft.freerouting.library.Padstack curr_padstack = p_library.get_via_padstack(i); + if (curr_padstack != null) + { + p_file.write(" "); + p_identifier_type.write(curr_padstack.name, p_file); + } + else + { + System.out.println("Structure.write_via_padstacks: padstack is null"); + } + } + p_file.write(")"); + } + + private static void write_control_scope(eu.mihosoft.freerouting.rules.BoardRules p_rules, IndentFileWriter p_file) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("control"); + p_file.new_line(); + p_file.write("(via_at_smd "); + boolean via_at_smd_allowed = false; + for (int i = 0; i < p_rules.via_infos.count(); ++i) + { + if (p_rules.via_infos.get(i).attach_smd_allowed()) + { + via_at_smd_allowed = true; + break; + } + } + if (via_at_smd_allowed) + { + p_file.write("on)"); + } + else + { + p_file.write("off)"); + } + p_file.end_scope(); + } + + private static void write_keepout_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.ObstacleArea p_keepout) throws java.io.IOException + { + eu.mihosoft.freerouting.geometry.planar.Area keepout_area = p_keepout.get_area(); + int layer_no = p_keepout.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[layer_no]; + Layer keepout_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape; + eu.mihosoft.freerouting.geometry.planar.Shape[] holes; + if (keepout_area instanceof eu.mihosoft.freerouting.geometry.planar.Shape) + { + boundary_shape = (eu.mihosoft.freerouting.geometry.planar.Shape) keepout_area; + holes = new eu.mihosoft.freerouting.geometry.planar.Shape[0]; + } + else + { + boundary_shape = keepout_area.get_border(); + holes = keepout_area.get_holes(); + } + p_par.file.start_scope(); + if (p_keepout instanceof eu.mihosoft.freerouting.board.ViaObstacleArea) + { + p_par.file.write("via_keepout"); + } + else + { + p_par.file.write("keepout"); + } + Shape dsn_shape = p_par.coordinate_transform.board_to_dsn(boundary_shape, keepout_layer); + if (dsn_shape != null) + { + dsn_shape.write_scope(p_par.file, p_par.identifier_type); + } + for (int i = 0; i < holes.length; ++i) + { + Shape dsn_hole = p_par.coordinate_transform.board_to_dsn(holes[i], keepout_layer); + dsn_hole.write_hole_scope(p_par.file, p_par.identifier_type); + } + if (p_keepout.clearance_class_no() > 0) + { + Rule.write_item_clearance_class(p_par.board.rules.clearance_matrix.get_name(p_keepout.clearance_class_no()), + p_par.file, p_par.identifier_type); + } + p_par.file.end_scope(); + } + + private static boolean read_boundary_scope(Scanner p_scanner, BoardConstructionInfo p_board_construction_info) + { + Shape curr_shape = Shape.read_scope(p_scanner, null); + // overread the closing bracket. + try + { + Object prev_token = null; + for (;;) + { + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (prev_token == Keyword.OPEN_BRACKET) + { + if (next_token == Keyword.CLEARANCE_CLASS) + { + p_board_construction_info.outline_clearance_class_name = DsnFile.read_string_scope(p_scanner); + } + } + prev_token = next_token; + } + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_boundary_scope: IO error scanning file"); + return false; + } + if (curr_shape == null) + { + System.out.println("Structure.read_boundary_scope: shape is null"); + return true; + } + if (curr_shape.layer == Layer.PCB) + { + if (p_board_construction_info.bounding_shape == null) + { + p_board_construction_info.bounding_shape = curr_shape; + } + else + { + System.out.println("Structure.read_boundary_scope: exact 1 bounding_shape expected"); + } + } + else if (curr_shape.layer == Layer.SIGNAL) + { + p_board_construction_info.outline_shapes.add(curr_shape); + } + else + { + System.out.println("Structure.read_boundary_scope: unexpected layer"); + } + return true; + } + + static boolean read_layer_scope(Scanner p_scanner, BoardConstructionInfo p_board_construction_info, String p_string_quote) + { + try + { + boolean layer_ok = true; + boolean is_signal = true; + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Structure.read_layer_scope: String expected"); + return false; + } + Collection net_names = new LinkedList(); + String layer_string = (String) next_token; + next_token = p_scanner.next_token(); + while (next_token != Keyword.CLOSED_BRACKET) + { + if (next_token != Keyword.OPEN_BRACKET) + { + System.out.println("Structure.read_layer_scope: ( expected"); + return false; + } + next_token = p_scanner.next_token(); + if (next_token == Keyword.TYPE) + { + next_token = p_scanner.next_token(); + if (next_token == Keyword.POWER) + { + is_signal = false; + } + else if (next_token != Keyword.SIGNAL) + { + System.out.print("Structure.read_layer_scope: unknown layer type "); + if (next_token instanceof String) + { + System.out.print((String) next_token); + } + System.out.println(); + layer_ok = false; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Structure.read_layer_scope: ) expected"); + return false; + } + } + else if (next_token == Keyword.RULE) + { + Collection curr_rules = Rule.read_scope(p_scanner); + p_board_construction_info.layer_dependent_rules.add(new LayerRule(layer_string, curr_rules)); + } + else if (next_token == Keyword.USE_NET) + { + for (;;) + { + p_scanner.yybegin(SpecctraFileScanner.NAME); + next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (next_token instanceof String) + { + net_names.add((String) next_token); + } + else + { + System.out.println("Structure.read_layer_scope: string expected"); + } + } + } + else + { + skip_scope(p_scanner); + } + next_token = p_scanner.next_token(); + } + if (layer_ok) + { + Layer curr_layer = new Layer(layer_string, p_board_construction_info.found_layer_count, is_signal, net_names); + p_board_construction_info.layer_info.add(curr_layer); + ++p_board_construction_info.found_layer_count; + } + } + catch (java.io.IOException e) + { + System.out.println("Layer.read_scope: IO error scanning file"); + System.out.println(e); + return false; + } + return true; + + } + + static Collection read_via_padstacks(Scanner p_scanner) + { + try + { + Collection normal_vias = new LinkedList(); + Collection spare_vias = new LinkedList(); + for (;;) + { + Object next_token = p_scanner.next_token(); + if (next_token == Keyword.CLOSED_BRACKET) + { + break; + } + if (next_token == Keyword.OPEN_BRACKET) + { + next_token = p_scanner.next_token(); + if (next_token == Keyword.SPARE) + { + spare_vias = read_via_padstacks(p_scanner); + } + else + { + skip_scope(p_scanner); + } + } + else if (next_token instanceof String) + { + normal_vias.add((String) next_token); + } + else + { + System.out.println("Structure.read_via_padstack: String expected"); + return null; + } + } + // add the spare vias to the end of the list + normal_vias.addAll(spare_vias); + return normal_vias; + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_via_padstack: IO error scanning file"); + return null; + } + } + + private static boolean read_control_scope(ReadScopeParameter p_par) + { + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_control_scope: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("Structure.read_control_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == Keyword.VIA_AT_SMD) + { + p_par.via_at_smd_allowed = DsnFile.read_on_off_scope(p_par.scanner); + } + else + { + skip_scope(p_par.scanner); + } + } + } + return true; + } + + static eu.mihosoft.freerouting.board.AngleRestriction read_snap_angle(Scanner p_scanner) + { + try + { + Object next_token = p_scanner.next_token(); + eu.mihosoft.freerouting.board.AngleRestriction snap_angle; + if (next_token == Keyword.NINETY_DEGREE) + { + snap_angle = eu.mihosoft.freerouting.board.AngleRestriction.NINETY_DEGREE; + } + else if (next_token == Keyword.FORTYFIVE_DEGREE) + { + snap_angle = eu.mihosoft.freerouting.board.AngleRestriction.FORTYFIVE_DEGREE; + } + else if (next_token == Keyword.NONE) + { + snap_angle = eu.mihosoft.freerouting.board.AngleRestriction.NONE; + } + else + { + System.out.println("Structure.read_snap_angle_scope: unexpected token"); + return null; + } + next_token = p_scanner.next_token(); + if (next_token != Keyword.CLOSED_BRACKET) + { + System.out.println("Structure.read_selection_layer_scop: closing bracket expected"); + return null; + } + return snap_angle; + } + catch (java.io.IOException e) + { + System.out.println("Structure.read_snap_angl: IO error scanning file"); + return null; + } + } + + static void write_snap_angle(IndentFileWriter p_file, eu.mihosoft.freerouting.board.AngleRestriction p_angle_restriction) throws java.io.IOException + { + p_file.start_scope(); + p_file.write("snap_angle "); + p_file.new_line(); + + if (p_angle_restriction == eu.mihosoft.freerouting.board.AngleRestriction.NINETY_DEGREE) + { + p_file.write("ninety_degree"); + } + else if (p_angle_restriction == eu.mihosoft.freerouting.board.AngleRestriction.FORTYFIVE_DEGREE) + { + p_file.write("fortyfive_degree"); + } + else + { + p_file.write("none"); + } + p_file.end_scope(); + } + + private boolean create_board(ReadScopeParameter p_par, BoardConstructionInfo p_board_construction_info) + { + int layer_count = p_board_construction_info.layer_info.size(); + if (layer_count == 0) + { + System.out.println("Structure.create_board: layers missing in structure scope"); + return false; + } + if (p_board_construction_info.bounding_shape == null) + { + // happens if the boundary shape with layer pcb is missing + if (p_board_construction_info.outline_shapes.isEmpty()) + { + System.out.println("Structure.create_board: outline missing"); + p_par.board_outline_ok = false; + return false; + } + Iterator it = p_board_construction_info.outline_shapes.iterator(); + + Rectangle bounding_box = it.next().bounding_box(); + while (it.hasNext()) + { + bounding_box = bounding_box.union(it.next().bounding_box()); + } + p_board_construction_info.bounding_shape = bounding_box; + } + Rectangle bounding_box = p_board_construction_info.bounding_shape.bounding_box(); + eu.mihosoft.freerouting.board.Layer[] board_layer_arr = new eu.mihosoft.freerouting.board.Layer[layer_count]; + Iterator it = p_board_construction_info.layer_info.iterator(); + for (int i = 0; i < layer_count; ++i) + { + Layer curr_layer = it.next(); + if (curr_layer.no < 0 || curr_layer.no >= layer_count) + { + System.out.println("Structure.create_board: illegal layer number"); + return false; + } + board_layer_arr[i] = new eu.mihosoft.freerouting.board.Layer(curr_layer.name, curr_layer.is_signal); + } + eu.mihosoft.freerouting.board.LayerStructure board_layer_structure = new eu.mihosoft.freerouting.board.LayerStructure(board_layer_arr); + p_par.layer_structure = new LayerStructure(p_board_construction_info.layer_info); + + // Calculate an appropritate scaling between dsn coordinates and eu.mihosoft.freerouting.board coordinates. + int scale_factor = Math.max(p_par.resolution, 1); + + double max_coor = 0; + for (int i = 0; i < 4; ++i) + { + max_coor = Math.max(max_coor, Math.abs(bounding_box.coor[i] * p_par.resolution)); + } + if (max_coor == 0) + { + p_par.board_outline_ok = false; + return false; + } + // make scalefactor smaller, if there is a danger of integer overflow. + while (5 * max_coor >= eu.mihosoft.freerouting.geometry.planar.Limits.CRIT_INT) + { + scale_factor /= 10; + max_coor /= 10; + } + + p_par.coordinate_transform = new CoordinateTransform(scale_factor, 0, 0); + + IntBox bounds = (IntBox) bounding_box.transform_to_board(p_par.coordinate_transform); + bounds = bounds.offset(1000); + + Collection board_outline_shapes = new LinkedList(); + for (Shape curr_shape : p_board_construction_info.outline_shapes) + { + if (curr_shape instanceof PolygonPath) + { + PolygonPath curr_path = (PolygonPath) curr_shape; + if (curr_path.width != 0) + { + // set the width to 0, because the offset function used in transform_to_board is not implemented + // for shapes, which are not convex. + curr_shape = new PolygonPath(curr_path.layer, 0, curr_path.coordinate_arr); + } + } + PolylineShape curr_board_shape = (PolylineShape) curr_shape.transform_to_board(p_par.coordinate_transform); + if (curr_board_shape.dimension() > 0) + { + board_outline_shapes.add(curr_board_shape); + } + } + if (board_outline_shapes.isEmpty()) + { + // construct an outline from the bounding_shape, if the outline is missing. + PolylineShape curr_board_shape = (PolylineShape) p_board_construction_info.bounding_shape.transform_to_board(p_par.coordinate_transform); + board_outline_shapes.add(curr_board_shape); + } + Collection hole_shapes = separate_holes(board_outline_shapes); + eu.mihosoft.freerouting.rules.ClearanceMatrix clearance_matrix = eu.mihosoft.freerouting.rules.ClearanceMatrix.get_default_instance(board_layer_structure, 0); + eu.mihosoft.freerouting.rules.BoardRules board_rules = new eu.mihosoft.freerouting.rules.BoardRules(board_layer_structure, clearance_matrix); + eu.mihosoft.freerouting.board.Communication.SpecctraParserInfo specctra_parser_info = + new eu.mihosoft.freerouting.board.Communication.SpecctraParserInfo(p_par.string_quote, p_par.host_cad, + p_par.host_version, p_par.constants, p_par.write_resolution, p_par.dsn_file_generated_by_host); + eu.mihosoft.freerouting.board.Communication board_communication = + new eu.mihosoft.freerouting.board.Communication(p_par.unit, p_par.resolution, specctra_parser_info, + p_par.coordinate_transform, p_par.item_id_no_generator, p_par.observers); + + PolylineShape[] outline_shape_arr = new PolylineShape[board_outline_shapes.size()]; + Iterator it2 = board_outline_shapes.iterator(); + for (int i = 0; i < outline_shape_arr.length; ++i) + { + outline_shape_arr[i] = it2.next(); + } + update_board_rules(p_par, p_board_construction_info, board_rules); + board_rules.set_trace_angle_restriction(p_par.snap_angle); + p_par.board_handling.create_board(bounds, board_layer_structure, outline_shape_arr, + p_board_construction_info.outline_clearance_class_name, board_rules, + board_communication, p_par.test_level); + + eu.mihosoft.freerouting.board.BasicBoard board = p_par.board_handling.get_routing_board(); + + // Insert the holes in the eu.mihosoft.freerouting.board outline as keepouts. + for (PolylineShape curr_outline_hole : hole_shapes) + { + for (int i = 0; i < board_layer_structure.arr.length; ++i) + { + board.insert_obstacle(curr_outline_hole, i, 0, FixedState.SYSTEM_FIXED); + } + } + + return true; + } + // Check, if a conduction area is inserted on each plane, + // and insert evtl. a conduction area + + private static void insert_missing_power_planes(Collection p_layer_info, + NetList p_netlist, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + Collection conduction_areas = p_board.get_conduction_areas(); + for (Layer curr_layer : p_layer_info) + { + if (curr_layer.is_signal) + { + continue; + } + boolean conduction_area_found = false; + for (eu.mihosoft.freerouting.board.ConductionArea curr_conduction_area : conduction_areas) + { + if (curr_conduction_area.get_layer() == curr_layer.no) + { + conduction_area_found = true; + break; + } + } + if (!conduction_area_found && !curr_layer.net_names.isEmpty()) + { + String curr_net_name = curr_layer.net_names.iterator().next(); + Net.Id curr_net_id = new Net.Id(curr_net_name, 1); + if (!p_netlist.contains(curr_net_id)) + { + Net new_net = p_netlist.add_net(curr_net_id); + if (new_net != null) + { + p_board.rules.nets.add(new_net.id.name, new_net.id.subnet_number, true); + } + } + eu.mihosoft.freerouting.rules.Net curr_net = p_board.rules.nets.get(curr_net_id.name, curr_net_id.subnet_number); + { + if (curr_net == null) + { + System.out.println("Structure.insert_missing_power_planes: net not found"); + continue; + } + } + int[] net_numbers = new int[1]; + net_numbers[0] = curr_net.net_number; + p_board.insert_conduction_area(p_board.bounding_box, curr_layer.no, net_numbers, BoardRules.clearance_class_none(), + false, FixedState.SYSTEM_FIXED); + } + } + } + + /** + * Calculates shapes in p_outline_shapes, which are holes in the outline and returns + * them in the result list. + */ + private static Collection separate_holes(Collection p_outline_shapes) + { + OutlineShape shape_arr[] = new OutlineShape[p_outline_shapes.size()]; + Iterator it = p_outline_shapes.iterator(); + for (int i = 0; i < shape_arr.length; ++i) + { + shape_arr[i] = new OutlineShape(it.next()); + } + for (int i = 0; i < shape_arr.length; ++i) + { + OutlineShape curr_shape = shape_arr[i]; + for (int j = 0; j < shape_arr.length; ++j) + { + // check if shape_arr[j] may be contained in shape_arr[i] + OutlineShape other_shape = shape_arr[j]; + if (i == j || other_shape.is_hole) + { + continue; + } + if (!other_shape.bounding_box.contains(curr_shape.bounding_box)) + { + continue; + } + curr_shape.is_hole = other_shape.contains_all_corners(curr_shape); + } + } + Collection hole_list = new LinkedList(); + for (int i = 0; i < shape_arr.length; ++i) + { + if (shape_arr[i].is_hole) + { + p_outline_shapes.remove(shape_arr[i].shape); + hole_list.add(shape_arr[i].shape); + } + } + return hole_list; + } + + /** + * Updates the board rules from the rules read from the dsn file. + */ + private static void update_board_rules(ReadScopeParameter p_par, + BoardConstructionInfo p_board_construction_info, BoardRules p_board_rules) + { + boolean smd_to_turn_gap_found = false; + // update the clearance matrix + Iterator it = p_board_construction_info.default_rules.iterator(); + while (it.hasNext()) + { + Rule curr_ob = it.next(); + if (curr_ob instanceof Rule.ClearanceRule) + { + Rule.ClearanceRule curr_rule = (Rule.ClearanceRule) curr_ob; + if (set_clearance_rule(curr_rule, -1, p_par.coordinate_transform, p_board_rules, p_par.string_quote)) + { + smd_to_turn_gap_found = true; + } + } + } + // update width rules + it = p_board_construction_info.default_rules.iterator(); + while (it.hasNext()) + { + Object curr_ob = it.next(); + if (curr_ob instanceof Rule.WidthRule) + { + double wire_width = ((Rule.WidthRule) curr_ob).value; + int trace_halfwidth = (int) Math.round(p_par.coordinate_transform.dsn_to_board(wire_width) / 2); + p_board_rules.set_default_trace_half_widths(trace_halfwidth); + } + } + Iterator it3 = p_board_construction_info.layer_dependent_rules.iterator(); + while (it3.hasNext()) + { + LayerRule layer_rule = it3.next(); + int layer_no = p_par.layer_structure.get_no(layer_rule.layer_name); + if (layer_no < 0) + { + continue; + } + Iterator it2 = layer_rule.rule.iterator(); + while (it2.hasNext()) + { + Rule curr_ob = it2.next(); + if (curr_ob instanceof Rule.WidthRule) + { + double wire_width = ((Rule.WidthRule) curr_ob).value; + int trace_halfwidth = (int) Math.round(p_par.coordinate_transform.dsn_to_board(wire_width) / 2); + p_board_rules.set_default_trace_half_width(layer_no, trace_halfwidth); + } + else if (curr_ob instanceof Rule.ClearanceRule) + { + Rule.ClearanceRule curr_rule = (Rule.ClearanceRule) curr_ob; + set_clearance_rule(curr_rule, layer_no, p_par.coordinate_transform, p_board_rules, p_par.string_quote); + } + } + } + if (!smd_to_turn_gap_found) + { + p_board_rules.set_pin_edge_to_turn_dist(p_board_rules.get_min_trace_half_width()); + } + } + + /** + * Converts a dsn clearance rule into a eu.mihosoft.freerouting.board clearance rule. + * If p_layer_no < 0, the rule is set on all layers. + * Returns true, if the string smd_to_turn_gap was found. + */ + static boolean set_clearance_rule(Rule.ClearanceRule p_rule, int p_layer_no, + CoordinateTransform p_coordinate_transform, BoardRules p_board_rules, String p_string_quote) + { + boolean result = false; + int curr_clearance = (int) Math.round(p_coordinate_transform.dsn_to_board(p_rule.value)); + if (p_rule.clearance_class_pairs.isEmpty()) + { + if (p_layer_no < 0) + { + p_board_rules.clearance_matrix.set_default_value(curr_clearance); + } + else + { + p_board_rules.clearance_matrix.set_default_value(p_layer_no, curr_clearance); + } + return result; + } + if (contains_wire_clearance_pair(p_rule.clearance_class_pairs)) + { + create_default_clearance_classes(p_board_rules); + } + Iterator it = p_rule.clearance_class_pairs.iterator(); + while (it.hasNext()) + { + String curr_string = it.next(); + if (curr_string.equalsIgnoreCase("smd_to_turn_gap")) + { + p_board_rules.set_pin_edge_to_turn_dist(curr_clearance); + result = true; + continue; + } + String[] curr_pair; + if (curr_string.startsWith(p_string_quote)) + { + // split at the second occurance of p_string_quote + curr_string = curr_string.substring(p_string_quote.length()); + curr_pair = curr_string.split(p_string_quote, 2); + if (curr_pair.length != 2 || !curr_pair[1].startsWith("_")) + { + System.out.println("Structure.set_clearance_rule: '_' exprcted"); + continue; + } + curr_pair[1] = curr_pair[1].substring(1); + } + else + { + curr_pair = curr_string.split("_", 2); + if (curr_pair.length != 2) + { + // pairs with more than 1 underline like smd_via_same_net are not implemented + continue; + } + } + + if (curr_pair[1].startsWith(p_string_quote) && curr_pair[1].endsWith(p_string_quote)) + { + // remove the quotes + curr_pair[1] = curr_pair[1].substring(1, curr_pair[1].length() - 1); + } + else + { + String[] tmp_pair = curr_pair[1].split("_", 2); + if (tmp_pair.length != 1) + { + // pairs with more than 1 underline like smd_via_same_net are not implemented + continue; + } + } + + int first_class_no; + if (curr_pair[0].equals("wire")) + { + first_class_no = 1; // default class + } + else + { + first_class_no = p_board_rules.clearance_matrix.get_no(curr_pair[0]); + } + if (first_class_no < 0) + { + first_class_no = append_clearance_class(p_board_rules, curr_pair[0]); + } + int second_class_no; + if (curr_pair[1].equals("wire")) + { + second_class_no = 1; // default class + } + else + { + second_class_no = p_board_rules.clearance_matrix.get_no(curr_pair[1]); + } + if (second_class_no < 0) + { + second_class_no = append_clearance_class(p_board_rules, curr_pair[1]); + } + if (p_layer_no < 0) + { + p_board_rules.clearance_matrix.set_value(first_class_no, second_class_no, curr_clearance); + p_board_rules.clearance_matrix.set_value(second_class_no, first_class_no, curr_clearance); + } + else + { + p_board_rules.clearance_matrix.set_value(first_class_no, second_class_no, p_layer_no, curr_clearance); + p_board_rules.clearance_matrix.set_value(second_class_no, first_class_no, p_layer_no, curr_clearance); + } + } + return result; + } + + static boolean contains_wire_clearance_pair(Collection p_clearance_pairs) + { + for (String curr_pair : p_clearance_pairs) + { + if (curr_pair.startsWith("wire_") || curr_pair.endsWith("_wire")) + { + return true; + } + } + return false; + } + + static private void create_default_clearance_classes(BoardRules p_board_rules) + { + append_clearance_class(p_board_rules, "via"); + append_clearance_class(p_board_rules, "smd"); + append_clearance_class(p_board_rules, "pin"); + append_clearance_class(p_board_rules, "area"); + } + + static private int append_clearance_class(BoardRules p_board_rules, String p_name) + { + p_board_rules.clearance_matrix.append_class(p_name); + int result = p_board_rules.clearance_matrix.get_no(p_name); + eu.mihosoft.freerouting.rules.NetClass default_net_class = p_board_rules.get_default_net_class(); + if (p_name.equals("via")) + { + default_net_class.default_item_clearance_classes.set(ItemClass.VIA, result); + } + else if (p_name.equals("pin")) + { + default_net_class.default_item_clearance_classes.set(ItemClass.PIN, result); + } + else if (p_name.equals("smd")) + { + default_net_class.default_item_clearance_classes.set(ItemClass.SMD, result); + } + else if (p_name.equals("area")) + { + default_net_class.default_item_clearance_classes.set(ItemClass.AREA, result); + } + return result; + } + + /** + * Returns true, if all clearance values on the 2 input layers are equal. + */ + private static boolean clearance_equals(eu.mihosoft.freerouting.rules.ClearanceMatrix p_cl_matrix, int p_layer_1, int p_layer_2) + { + if (p_layer_1 == p_layer_2) + { + return true; + } + for (int i = 1; i < p_cl_matrix.get_class_count(); ++i) + { + for (int j = i; j < p_cl_matrix.get_class_count(); ++j) + { + if (p_cl_matrix.value(i, j, p_layer_1) != p_cl_matrix.value(i, j, p_layer_2)) + { + return false; + } + } + } + return true; + } + + private static boolean insert_keepout(Shape.ReadAreaScopeResult p_area, ReadScopeParameter p_par, KeepoutType p_keepout_type, FixedState p_fixed_state) + { + eu.mihosoft.freerouting.geometry.planar.Area keepout_area = + Shape.transform_area_to_board(p_area.shape_list, p_par.coordinate_transform); + if (keepout_area.dimension() < 2) + { + System.out.println("Structure.insert_keepout: keepout is not an area"); + return true; + } + eu.mihosoft.freerouting.board.BasicBoard board = p_par.board_handling.get_routing_board(); + if (board == null) + { + System.out.println("Structure.insert_keepout: eu.mihosoft.freerouting.board not initialized"); + return false; + } + Layer curr_layer = (p_area.shape_list.iterator().next()).layer; + if (curr_layer == Layer.SIGNAL) + { + for (int i = 0; i < board.get_layer_count(); ++i) + { + if (p_par.layer_structure.arr[i].is_signal) + { + insert_keepout(board, keepout_area, i, p_area.clearance_class_name, p_keepout_type, p_fixed_state); + } + } + } + else if (curr_layer.no >= 0) + { + insert_keepout(board, keepout_area, curr_layer.no, p_area.clearance_class_name, p_keepout_type, p_fixed_state); + } + else + { + System.out.println("Structure.insert_keepout: unknown layer name"); + return false; + } + + return true; + } + + private static void insert_keepout(eu.mihosoft.freerouting.board.BasicBoard p_board, eu.mihosoft.freerouting.geometry.planar.Area p_area, int p_layer, + String p_clearance_class_name, KeepoutType p_keepout_type, FixedState p_fixed_state) + { + int clearance_class_no; + if (p_clearance_class_name == null) + { + clearance_class_no = + p_board.rules.get_default_net_class().default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.AREA); + } + else + { + clearance_class_no = p_board.rules.clearance_matrix.get_no(p_clearance_class_name); + if (clearance_class_no < 0) + { + System.out.println("Keepout.insert_leepout: clearance class not found"); + clearance_class_no = BoardRules.clearance_class_none(); + } + } + if (p_keepout_type == KeepoutType.via_keepout) + { + p_board.insert_via_obstacle(p_area, p_layer, clearance_class_no, p_fixed_state); + } + else if (p_keepout_type == KeepoutType.place_keepout) + { + p_board.insert_component_obstacle(p_area, p_layer, clearance_class_no, p_fixed_state); + } + else + { + p_board.insert_obstacle(p_area, p_layer, clearance_class_no, p_fixed_state); + } + } + + enum KeepoutType + { + + keepout, via_keepout, place_keepout + } + + private static class BoardConstructionInfo + { + + Collection layer_info = new LinkedList(); + Shape bounding_shape; + java.util.List outline_shapes = new LinkedList(); + String outline_clearance_class_name = null; + int found_layer_count = 0; + Collection default_rules = new LinkedList(); + Collection layer_dependent_rules = new LinkedList(); + } + + private static class LayerRule + { + + LayerRule(String p_layer_name, Collection p_rule) + { + layer_name = p_layer_name; + rule = p_rule; + } + final String layer_name; + final Collection rule; + } + + /** + * Used to seperate the holes in the outline. + */ + private static class OutlineShape + { + + public OutlineShape(PolylineShape p_shape) + { + shape = p_shape; + bounding_box = p_shape.bounding_box(); + convex_shapes = p_shape.split_to_convex(); + is_hole = false; + } + + /** + * Returns true, if this shape contains all corners of p_other_shape. + */ + private boolean contains_all_corners(OutlineShape p_other_shape) + { + if (this.convex_shapes == null) + { + // calculation of the convex shapes failed + return false; + } + int corner_count = p_other_shape.shape.border_line_count(); + for (int i = 0; i < corner_count; ++i) + { + Point curr_corner = p_other_shape.shape.corner(i); + boolean is_contained = false; + for (int j = 0; j < this.convex_shapes.length; ++j) + { + if (this.convex_shapes[j].contains(curr_corner)) + { + is_contained = true; + break; + } + } + if (!is_contained) + { + return false; + } + } + return true; + } + final PolylineShape shape; + final IntBox bounding_box; + final TileShape[] convex_shapes; + boolean is_hole; + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Wiring.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Wiring.java new file mode 100644 index 0000000..fafe713 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/Wiring.java @@ -0,0 +1,786 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * Wiring.java + * + * Created on 24. Mai 2004, 07:20 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.Iterator; + +import eu.mihosoft.freerouting.datastructures.UndoableObjects; + +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Polyline; + +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.FixedState; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; + +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Class for reading and writing wiring scopes from dsn-files. + * + * @author Alfons Wirtz + */ +class Wiring extends ScopeKeyword +{ + + /** Creates a new instance of Wiring */ + public Wiring() + { + super("wiring"); + } + + public boolean read_scope(ReadScopeParameter p_par) + { + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Wiring.read_scope: IO error scanning file"); + return false; + } + if (next_token == null) + { + System.out.println("Wiring.read_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + boolean read_ok = true; + if (prev_token == OPEN_BRACKET) + { + if (next_token == WIRE) + { + read_wire_scope(p_par); + } + else if (next_token == VIA) + { + read_ok = read_via_scope(p_par); + } + else + { + skip_scope(p_par.scanner); + } + } + if (!read_ok) + { + return false; + } + } + RoutingBoard board = p_par.board_handling.get_routing_board(); + for (int i = 1; i <= board.rules.nets.max_net_no(); ++i) + { + board.normalize_traces(i); + } + return true; + } + + public static void write_scope(WriteScopeParameter p_par) throws java.io.IOException + { + p_par.file.start_scope(); + p_par.file.write("wiring"); + // write the wires + Collection board_wires = p_par.board.get_traces(); + Iterator it = board_wires.iterator(); + while (it.hasNext()) + { + write_wire_scope(p_par, it.next()); + } + Collection board_vias = p_par.board.get_vias(); + for (Via curr_via : board_vias) + { + write_via_scope(p_par, curr_via); + } + // write the conduction areas + Iterator it2 = p_par.board.item_list.start_read_object(); + for(;;) + { + Object curr_ob = p_par.board.item_list.read_object(it2); + if (curr_ob == null) + { + break; + } + if (!(curr_ob instanceof eu.mihosoft.freerouting.board.ConductionArea)) + { + continue; + } + eu.mihosoft.freerouting.board.ConductionArea curr_area = (eu.mihosoft.freerouting.board.ConductionArea) curr_ob; + if (!(p_par.board.layer_structure.arr [curr_area.get_layer()].is_signal)) + { + // This conduction areas arw written in the structure scope. + continue; + } + write_conduction_area_scope(p_par, (eu.mihosoft.freerouting.board.ConductionArea) curr_ob); + } + p_par.file.end_scope(); + } + + private static void write_via_scope(WriteScopeParameter p_par, Via p_via) throws java.io.IOException + { + eu.mihosoft.freerouting.library.Padstack via_padstack = p_via.get_padstack(); + FloatPoint via_location = p_via.get_center().to_float(); + double [] via_coor = p_par.coordinate_transform.board_to_dsn(via_location); + int net_no; + eu.mihosoft.freerouting.rules.Net via_net; + if (p_via.net_count() > 0) + { + net_no = p_via.get_net_no(0); + via_net = p_par.board.rules.nets.get(net_no); + } + else + { + net_no = 0; + via_net = null; + } + p_par.file.start_scope(); + p_par.file.write("via "); + p_par.identifier_type.write(via_padstack.name, p_par.file); + for (int i = 0; i < via_coor.length; ++i) + { + p_par.file.write(" "); + p_par.file.write((new Double(via_coor[i])).toString()); + } + if (via_net != null) + { + write_net(via_net, p_par.file, p_par.identifier_type); + } + Rule.write_item_clearance_class(p_par.board.rules.clearance_matrix.get_name(p_via.clearance_class_no()), + p_par.file, p_par.identifier_type); + write_fixed_state(p_par.file, p_via.get_fixed_state()); + p_par.file.end_scope(); + } + + private static void write_wire_scope(WriteScopeParameter p_par, Trace p_wire) throws java.io.IOException + { + if (!(p_wire instanceof PolylineTrace)) + { + System.out.println("Wiring.write_wire_scope: trace type not yet implemented"); + return; + } + PolylineTrace curr_wire = (PolylineTrace) p_wire; + int layer_no = curr_wire.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[layer_no]; + Layer curr_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); + double wire_width = p_par.coordinate_transform.board_to_dsn(2 * curr_wire.get_half_width()); + eu.mihosoft.freerouting.rules.Net wire_net = null; + if (curr_wire.net_count() > 0) + { + wire_net = p_par.board.rules.nets.get(curr_wire.get_net_no(0)); + } + if (wire_net == null) + { + System.out.println("Wiring.write_wire_scope: net not found"); + return; + } + p_par.file.start_scope(); + p_par.file.write("wire"); + + if(p_par.compat_mode) + { + Point[] corner_arr = curr_wire.polyline().corner_arr(); + FloatPoint[] float_corner_arr = new FloatPoint [corner_arr.length]; + for (int i = 0; i < corner_arr.length; ++i) + { + float_corner_arr[i] = corner_arr[i].to_float(); + } + double [] coors = p_par.coordinate_transform.board_to_dsn(float_corner_arr); + PolygonPath curr_path = new PolygonPath(curr_layer, wire_width, coors); + curr_path.write_scope(p_par.file, p_par.identifier_type); + } + else + { + double [] coors = p_par.coordinate_transform.board_to_dsn(curr_wire.polyline().arr); + PolylinePath curr_path = new PolylinePath(curr_layer, wire_width, coors); + curr_path.write_scope(p_par.file, p_par.identifier_type); + } + write_net(wire_net, p_par.file, p_par.identifier_type); + Rule.write_item_clearance_class(p_par.board.rules.clearance_matrix.get_name(p_wire.clearance_class_no()), + p_par.file, p_par.identifier_type); + write_fixed_state(p_par.file, curr_wire.get_fixed_state()); + p_par.file.end_scope(); + } + + private static void write_conduction_area_scope(WriteScopeParameter p_par, eu.mihosoft.freerouting.board.ConductionArea p_conduction_area) throws java.io.IOException + { + int net_count = p_conduction_area.net_count(); + if (net_count <= 0 || net_count > 1) + { + System.out.println("Plane.write_scope: unexpected net count"); + return; + } + eu.mihosoft.freerouting.rules.Net curr_net = p_par.board.rules.nets.get(p_conduction_area.get_net_no(0)); + eu.mihosoft.freerouting.geometry.planar.Area curr_area = p_conduction_area.get_area(); + int layer_no = p_conduction_area.get_layer(); + eu.mihosoft.freerouting.board.Layer board_layer = p_par.board.layer_structure.arr[ layer_no]; + Layer conduction_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); + eu.mihosoft.freerouting.geometry.planar.Shape boundary_shape; + eu.mihosoft.freerouting.geometry.planar.Shape [] holes; + if (curr_area instanceof eu.mihosoft.freerouting.geometry.planar.Shape) + { + boundary_shape = (eu.mihosoft.freerouting.geometry.planar.Shape) curr_area; + holes = new eu.mihosoft.freerouting.geometry.planar.Shape [0]; + } + else + { + boundary_shape = curr_area.get_border(); + holes = curr_area.get_holes(); + } + p_par.file.start_scope(); + p_par.file.write("wire "); + Shape dsn_shape = p_par.coordinate_transform.board_to_dsn(boundary_shape, conduction_layer); + if (dsn_shape != null) + { + dsn_shape.write_scope(p_par.file, p_par.identifier_type); + } + for (int i = 0; i < holes.length; ++i) + { + Shape dsn_hole = p_par.coordinate_transform.board_to_dsn(holes[i], conduction_layer); + dsn_hole.write_hole_scope(p_par.file, p_par.identifier_type); + } + write_net(curr_net, p_par.file, p_par.identifier_type); + Rule.write_item_clearance_class(p_par.board.rules.clearance_matrix.get_name(p_conduction_area.clearance_class_no()), + p_par.file, p_par.identifier_type); + p_par.file.end_scope(); + } + + static private void write_net(eu.mihosoft.freerouting.rules.Net p_net, IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException + { + p_file.new_line(); + p_file.write("("); + Net.write_net_id(p_net, p_file, p_identifier_type); + p_file.write(")"); + } + + static private void write_fixed_state(IndentFileWriter p_file, FixedState p_fixed_state) throws java.io.IOException + { + if (p_fixed_state == FixedState.UNFIXED) + { + return; + } + p_file.new_line(); + p_file.write("(type "); + if (p_fixed_state == FixedState.SHOVE_FIXED) + { + p_file.write("shove_fixed)"); + } + else if (p_fixed_state == FixedState.SYSTEM_FIXED) + { + p_file.write("fix)"); + } + else + { + p_file.write("protect)"); + } + } + + private Item read_wire_scope(ReadScopeParameter p_par) + { + Net.Id net_id = null; + String clearance_class_name = null; + eu.mihosoft.freerouting.board.FixedState fixed = eu.mihosoft.freerouting.board.FixedState.UNFIXED; + Path path = null; // Used, if a trace is read. + Shape border_shape = null; // Used, if a conduction area is read. + Collection hole_list = new LinkedList(); + Object next_token = null; + for (;;) + { + Object prev_token = next_token; + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Wiring.read_wire_scope: IO error scanning file"); + return null; + } + if (next_token == null) + { + System.out.println("Wiring.read_wire_scope: unexpected end of file"); + return null; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == POLYGON_PATH) + { + path = Shape.read_polygon_path_scope(p_par.scanner, p_par.layer_structure); + } + else if (next_token == POLYLINE_PATH) + { + path = Shape.read_polyline_path_scope(p_par.scanner, p_par.layer_structure); + } + else if (next_token == RECTANGLE) + { + + border_shape = Shape.read_rectangle_scope(p_par.scanner, p_par.layer_structure); + } + else if (next_token == POLYGON) + { + + border_shape = Shape.read_polygon_scope(p_par.scanner, p_par.layer_structure); + } + else if (next_token == CIRCLE) + { + + border_shape = Shape.read_circle_scope(p_par.scanner, p_par.layer_structure); + } + else if (next_token == WINDOW) + { + Shape hole_shape = Shape.read_scope(p_par.scanner, p_par.layer_structure); + hole_list.add(hole_shape); + // overread the closing bracket + try + { + next_token = p_par.scanner.next_token(); + } + catch (java.io.IOException e) + { + System.out.println("Wiring.read_wire_scope: IO error scanning file"); + return null; + } + if (next_token != CLOSED_BRACKET) + { + System.out.println("Wiring.read_wire_scope: closing bracket expected"); + return null; + } + } + else if (next_token == NET) + { + net_id = read_net_id(p_par.scanner); + } + else if (next_token == CLEARANCE_CLASS) + { + clearance_class_name = DsnFile.read_string_scope(p_par.scanner); + } + else if (next_token == TYPE) + { + fixed = calc_fixed(p_par.scanner); + } + else + { + skip_scope(p_par.scanner); + } + } + } + if (path == null && border_shape == null) + { + System.out.println("Wiring.read_wire_scope: shape missing"); + return null; + } + RoutingBoard board = p_par.board_handling.get_routing_board(); + + eu.mihosoft.freerouting.rules.NetClass net_class = board.rules.get_default_net_class(); + Collection found_nets = get_subnets(net_id, board.rules); + int[] net_no_arr = new int[found_nets.size()]; + int curr_index = 0; + for (eu.mihosoft.freerouting.rules.Net curr_net : found_nets) + { + net_no_arr[curr_index] = curr_net.net_number; + net_class = curr_net.get_class(); + ++curr_index; + } + int clearance_class_no = -1; + if (clearance_class_name != null) + { + clearance_class_no = board.rules.clearance_matrix.get_no(clearance_class_name); + } + int layer_no; + int half_width; + if (path != null) + { + layer_no = path.layer.no; + half_width = (int) Math.round(p_par.coordinate_transform.dsn_to_board(path.width / 2)); + } + else + { + layer_no = border_shape.layer.no; + half_width = 0; + } + if (layer_no < 0 || layer_no >= board.get_layer_count()) + { + System.out.print("Wiring.read_wire_scope: unexpected layer "); + if (path != null) + { + System.out.println(path.layer.name); + } + else + { + System.out.println(border_shape.layer.name); + } + return null; + } + + IntBox bounding_box = board.get_bounding_box(); + + Item result = null; + if (border_shape != null) + { + if (clearance_class_no < 0) + { + clearance_class_no = + net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.AREA); + } + Collection area = new LinkedList(); + area.add(border_shape); + area.addAll(hole_list); + eu.mihosoft.freerouting.geometry.planar.Area conduction_area = + Shape.transform_area_to_board(area, p_par.coordinate_transform); + result = board.insert_conduction_area(conduction_area, layer_no, net_no_arr, clearance_class_no, + false, fixed); + } + else if (path instanceof PolygonPath) + { + if (clearance_class_no < 0) + { + clearance_class_no = + net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.TRACE); + } + IntPoint [] corner_arr = new IntPoint[path.coordinate_arr.length / 2]; + double [] curr_point = new double [2]; + for (int i = 0; i < corner_arr.length; ++i) + { + curr_point[0] = path.coordinate_arr[2 * i]; + curr_point[1] = path.coordinate_arr[2 * i + 1]; + FloatPoint curr_corner = p_par.coordinate_transform.dsn_to_board(curr_point); + if (!bounding_box.contains(curr_corner)) + { + System.out.println("Wiring.read_wire_scope: wire corner outside eu.mihosoft.freerouting.board"); + return null; + } + corner_arr[i] = curr_corner.round(); + } + Polyline trace_polyline = new Polyline(corner_arr); + // Traces are not yet normalized here because cycles may be removed premature. + result = board.insert_trace_without_cleaning(trace_polyline, layer_no, half_width, net_no_arr, clearance_class_no, fixed); + } + else if (path instanceof PolylinePath) + { + if (clearance_class_no < 0) + { + clearance_class_no = + net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.TRACE); + } + Line [] line_arr = new Line[path.coordinate_arr.length / 4]; + double [] curr_point = new double [2]; + for (int i = 0; i < line_arr.length; ++i) + { + curr_point[0] = path.coordinate_arr[4 * i]; + curr_point[1] = path.coordinate_arr[4 * i + 1]; + FloatPoint curr_a = p_par.coordinate_transform.dsn_to_board(curr_point); + curr_point[0] = path.coordinate_arr[4 * i + 2]; + curr_point[1] = path.coordinate_arr[4 * i + 3]; + FloatPoint curr_b = p_par.coordinate_transform.dsn_to_board(curr_point); + line_arr[i] = new Line(curr_a.round(), curr_b.round()); + } + Polyline trace_polyline = new Polyline(line_arr); + result = board.insert_trace_without_cleaning(trace_polyline, layer_no, half_width, net_no_arr, clearance_class_no, fixed); + } + else + { + System.out.println("Wiring.read_wire_scope: unexpected Path subclass"); + return null; + } + if (result != null && result.net_count() == 0) + { + try_correct_net(result); + } + return result; + } + + /** + * Maybe trace of type turret without net in Mentor design. + * Try to assig the net by calculating the overlaps. + */ + private void try_correct_net(Item p_item) + { + if (!(p_item instanceof Trace)) + { + return; + } + Trace curr_trace = (Trace) p_item; + java.util.Set contacts = curr_trace.get_normal_contacts(curr_trace.first_corner(), true); + contacts.addAll(curr_trace.get_normal_contacts(curr_trace.last_corner(), true)); + int corrected_net_no = 0; + for (Item curr_contact : contacts) + { + if (curr_contact.net_count() == 1) + { + corrected_net_no = curr_contact.get_net_no(0); + break; + } + } + if (corrected_net_no != 0) + { + p_item.assign_net_no(corrected_net_no); + } + } + + private static Collection get_subnets(Net.Id p_net_id, eu.mihosoft.freerouting.rules.BoardRules p_rules) + { + Collection found_nets = new LinkedList(); + if (p_net_id != null) + { + if (p_net_id.subnet_number > 0) + { + eu.mihosoft.freerouting.rules.Net found_net = p_rules.nets.get(p_net_id.name, p_net_id.subnet_number); + if (found_net != null) + { + found_nets.add(found_net); + } + } + else + { + found_nets = p_rules.nets.get(p_net_id.name); + } + } + return found_nets; + } + + private boolean read_via_scope(ReadScopeParameter p_par) + { + try + { + eu.mihosoft.freerouting.board.FixedState fixed = eu.mihosoft.freerouting.board.FixedState.UNFIXED; + // read the padstack name + Object next_token = p_par.scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Wiring.read_via_scope: padstack name expected"); + return false; + } + String padstack_name = (String) next_token; + // read the location + double []location = new double [2]; + for (int i = 0; i < 2; ++i) + { + next_token = p_par.scanner.next_token(); + if (next_token instanceof Double) + { + location[i] = ((Double) next_token).doubleValue(); + } + else if (next_token instanceof Integer) + { + location[i] = ((Integer) next_token).intValue(); + } + else + { + System.out.println("Wiring.read_via_scope: number expected"); + return false; + } + } + Net.Id net_id = null; + String clearance_class_name = null; + for (;;) + { + Object prev_token = next_token; + next_token = p_par.scanner.next_token(); + if (next_token == null) + { + System.out.println("Wiring.read_via_scope: unexpected end of file"); + return false; + } + if (next_token == CLOSED_BRACKET) + { + // end of scope + break; + } + if (prev_token == OPEN_BRACKET) + { + if (next_token == NET) + { + net_id = read_net_id(p_par.scanner); + } + else if (next_token == CLEARANCE_CLASS) + { + clearance_class_name = DsnFile.read_string_scope(p_par.scanner); + } + else if (next_token == TYPE) + { + fixed = calc_fixed(p_par.scanner); + } + else + { + skip_scope(p_par.scanner); + } + } + } + RoutingBoard board = p_par.board_handling.get_routing_board(); + eu.mihosoft.freerouting.library.Padstack curr_padstack = board.library.padstacks.get(padstack_name); + if (curr_padstack == null) + { + System.out.println("Wiring.read_via_scope: via padstack not found"); + return false; + } + eu.mihosoft.freerouting.rules.NetClass net_class = board.rules.get_default_net_class(); + Collection found_nets = get_subnets(net_id, board.rules); + if (net_id != null && found_nets.isEmpty()) + { + System.out.print("Wiring.read_via_scope: net with name "); + System.out.print(net_id.name); + System.out.println(" not found"); + } + int[] net_no_arr = new int[found_nets.size()]; + int curr_index = 0; + for (eu.mihosoft.freerouting.rules.Net curr_net : found_nets) + { + net_no_arr[curr_index] = curr_net.net_number; + net_class = curr_net.get_class(); + } + int clearance_class_no = -1; + if (clearance_class_name != null) + { + clearance_class_no = board.rules.clearance_matrix.get_no(clearance_class_name); + } + if (clearance_class_no < 0) + { + clearance_class_no = net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.VIA); + } + IntPoint board_location = p_par.coordinate_transform.dsn_to_board(location).round(); + if (via_exists(board_location, curr_padstack, net_no_arr, board)) + { + System.out.print("Multiple via skipped at ("); + System.out.println(board_location.x + ", " + board_location.y + ")"); + } + else + { + boolean attach_allowed = p_par.via_at_smd_allowed && curr_padstack.attach_allowed; + board.insert_via(curr_padstack, board_location, net_no_arr, clearance_class_no, fixed, attach_allowed); + } + return true; + } + catch (java.io.IOException e) + { + System.out.println("Wiring.read_via_scope: IO error scanning file"); + return false; + } + } + + private static boolean via_exists(IntPoint p_location, eu.mihosoft.freerouting.library.Padstack p_padstack, + int[] p_net_no_arr, eu.mihosoft.freerouting.board.BasicBoard p_board) + { + ItemSelectionFilter filter = new ItemSelectionFilter(ItemSelectionFilter.SelectableChoices.VIAS); + int from_layer = p_padstack.from_layer(); + int to_layer = p_padstack.to_layer(); + Collection picked_items = p_board.pick_items(p_location, p_padstack.from_layer(), filter); + for (Item curr_item : picked_items) + { + Via curr_via = (Via) curr_item; + if (curr_via.nets_equal(p_net_no_arr) && curr_via.get_center().equals(p_location) + && curr_via.first_layer() == from_layer && curr_via.last_layer() == to_layer) + { + return true; + } + } + return false; + } + + static eu.mihosoft.freerouting.board.FixedState calc_fixed(Scanner p_scanner) + { + try + { + eu.mihosoft.freerouting.board.FixedState result = eu.mihosoft.freerouting.board.FixedState.UNFIXED; + Object next_token = p_scanner.next_token(); + if (next_token == SHOVE_FIXED) + { + result = eu.mihosoft.freerouting.board.FixedState.SHOVE_FIXED; + } + else if (next_token == FIX) + { + result = eu.mihosoft.freerouting.board.FixedState.SYSTEM_FIXED; + } + else if (next_token != NORMAL) + { + result = eu.mihosoft.freerouting.board.FixedState.USER_FIXED; + } + next_token = p_scanner.next_token(); + if (next_token != CLOSED_BRACKET) + { + System.out.println("Wiring.is_fixed: ) expected"); + return eu.mihosoft.freerouting.board.FixedState.UNFIXED; + } + return result; + } + catch (java.io.IOException e) + { + System.out.println("Wiring.is_fixed: IO error scanning file"); + return eu.mihosoft.freerouting.board.FixedState.UNFIXED; + } + } + + /** + * Reads a net_id. The subnet_number of the net_id will be 0, if no subneet_number was found. + */ + private static Net.Id read_net_id(Scanner p_scanner) + { + try + { + int subnet_number = 0; + p_scanner.yybegin(SpecctraFileScanner.NAME); + Object next_token = p_scanner.next_token(); + if (!(next_token instanceof String)) + { + System.out.println("Wiring:read_net_id: String expected"); + return null; + } + String net_name = (String) next_token; + next_token = p_scanner.next_token(); + if (next_token instanceof Integer) + { + subnet_number = (Integer) next_token; + next_token = p_scanner.next_token(); + } + if (next_token != CLOSED_BRACKET) + { + System.out.println("Wiring.read_net_id: closing bracket expected"); + } + return new Net.Id(net_name, subnet_number); + } + catch (java.io.IOException e) + { + System.out.println("DsnFile.read_string_scope: IO error scanning file"); + return null; + } + } +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/WriteScopeParameter.java b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/WriteScopeParameter.java new file mode 100644 index 0000000..3d57015 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/WriteScopeParameter.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Alfons Wirtz + * website www.freerouting.net + * + * This program 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. + * + * This program 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 at + * for more details. + * + * WriteScopeParameter.java + * + * Created on 21. Juni 2004, 08:37 + */ + +package eu.mihosoft.freerouting.designforms.specctra; + +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.datastructures.IndentFileWriter; +import eu.mihosoft.freerouting.datastructures.IdentifierType; + +/** + * Default parameter type used while writing a Specctra dsn-file. + * + * @author alfons + */ +public class WriteScopeParameter +{ + + /** + * Creates a new instance of WriteScopeParameter. + * If p_compat_mode is true, only standard speecctra dsb scopes are written, so that any + * host system with an specctra interface can read them. + */ + WriteScopeParameter(BasicBoard p_board, eu.mihosoft.freerouting.interactive.AutorouteSettings p_autoroute_settings, + IndentFileWriter p_file, String p_string_quote, CoordinateTransform p_coordinate_transform, + boolean p_compat_mode) + { + board = p_board; + autoroute_settings = p_autoroute_settings; + file = p_file; + coordinate_transform = p_coordinate_transform; + compat_mode = p_compat_mode; + String[] reserved_chars = {"(", ")", " ", ";", "-", "_"}; + identifier_type = new IdentifierType(reserved_chars, p_string_quote); + } + + final BasicBoard board; + final eu.mihosoft.freerouting.interactive.AutorouteSettings autoroute_settings; + final IndentFileWriter file; + final CoordinateTransform coordinate_transform; + final boolean compat_mode; + final IdentifierType identifier_type; +} diff --git a/src/main/java/eu/mihosoft/freerouting/designforms/specctra/package.html b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/package.html new file mode 100644 index 0000000..ae7d1d5 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/designforms/specctra/package.html @@ -0,0 +1,21 @@ + +java.text package + + + Contains classes for reading and writing eu.mihosoft.freerouting.board designs in the Specctra dsn text format. + \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Area.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Area.java index 1f93618..e72401c 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Area.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Area.java @@ -18,7 +18,7 @@ * Created on 22. Juni 2003, 10:16 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * An Area is a not necessarily simply connected Shape, which means, diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/BigIntDirection.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/BigIntDirection.java index 57075a9..ba2c474 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/BigIntDirection.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/BigIntDirection.java @@ -18,7 +18,7 @@ * Created on 4. Februar 2003, 14:10 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; /** diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Circle.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Circle.java index ac2d115..f9b76b3 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Circle.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Circle.java @@ -18,7 +18,7 @@ * Created on 4. Juni 2003, 07:29 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * Discribes functionality of a circle shape in the plane. diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/ConvexShape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/ConvexShape.java index 5038438..c5d7109 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/ConvexShape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/ConvexShape.java @@ -18,7 +18,7 @@ * Created on 15. November 2002, 08:44 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * A shape is defined as convex, if for each line segment with both endpoints diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Direction.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Direction.java index d0f97c8..7421ae6 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Direction.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Direction.java @@ -18,8 +18,8 @@ * Created on 3. Februar 2003, 15:36 */ -package geometry.planar; -import datastructures.Signum; +package eu.mihosoft.freerouting.geometry.planar; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Ellipse.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Ellipse.java index c82f2a4..f8b72e0 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Ellipse.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Ellipse.java @@ -19,7 +19,7 @@ * */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * Describes functionality of an elllipse in the plane. diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatLine.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatLine.java index 5e4e249..767b2a2 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatLine.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatLine.java @@ -18,7 +18,7 @@ * Created on 19. Februar 2004, 07:22 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * Defines a line in the plane by to FloatPoints. diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatPoint.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatPoint.java index 9f47503..f5ea2f3 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatPoint.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FloatPoint.java @@ -18,7 +18,7 @@ * Created on 2. Februar 2003, 09:14 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeBoundingDirections.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeBoundingDirections.java index 596c7e6..447ec2f 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeBoundingDirections.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeBoundingDirections.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeDirection.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeDirection.java index 16356ae..2e932ec 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeDirection.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/FortyfiveDegreeDirection.java @@ -19,7 +19,7 @@ * */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; @SuppressWarnings("all") // Eclipse regards get_direction() as unused /** diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntBox.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntBox.java index cbbbe93..d783e83 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntBox.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntBox.java @@ -18,7 +18,7 @@ * Created on 2. Februar 2003, 14:09 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntDirection.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntDirection.java index 0e6b202..bcf3bc1 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntDirection.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntDirection.java @@ -18,8 +18,8 @@ * Created on 3. Februar 2003, 08:17 */ -package geometry.planar; -import datastructures.Signum; +package eu.mihosoft.freerouting.geometry.planar; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntOctagon.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntOctagon.java index 1b82c1e..a1d8930 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntOctagon.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntOctagon.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntPoint.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntPoint.java index dd8fead..a0a7e1b 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntPoint.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntPoint.java @@ -18,7 +18,7 @@ * Created on 1. Februar 2003, 10:31 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntVector.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntVector.java index d736990..921082d 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntVector.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/IntVector.java @@ -18,9 +18,9 @@ * Created on 1. Februar 2003, 14:47 */ -package geometry.planar; -import datastructures.BigIntAux; -import datastructures.Signum; +package eu.mihosoft.freerouting.geometry.planar; +import eu.mihosoft.freerouting.datastructures.BigIntAux; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Limits.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Limits.java index f735b4e..96bbc8a 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Limits.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Limits.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; /** diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Line.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Line.java index 4967ec1..8569864 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Line.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Line.java @@ -14,11 +14,11 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/LineSegment.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/LineSegment.java index 8ccad33..fe28c82 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/LineSegment.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/LineSegment.java @@ -13,9 +13,9 @@ * GNU General Public License at * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; /** * Implements functionality for line segments. diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/OrthogonalBoundingDirections.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/OrthogonalBoundingDirections.java index 70c7cb6..ad909a3 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/OrthogonalBoundingDirections.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/OrthogonalBoundingDirections.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Point.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Point.java index bc8a961..a0da84b 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Point.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Point.java @@ -18,7 +18,7 @@ * Created on 1. Februar 2003, 11:38 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polygon.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polygon.java index 817e342..be785e4 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polygon.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polygon.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolygonShape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolygonShape.java index 9330a15..7c7c27f 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolygonShape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolygonShape.java @@ -18,7 +18,7 @@ * Created on 13. Juni 2003, 12:12 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polyline.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polyline.java index a91a9af..85dfabc 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polyline.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Polyline.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineArea.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineArea.java index a0c21cf..071f598 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineArea.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineArea.java @@ -17,7 +17,7 @@ * * Created on 19. Juni 2003, 07:58 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; @@ -182,7 +182,7 @@ public class PolylineArea implements Area, java.io.Serializable * instead of Polygons, so that no intersection points are needed in the result. * If p_stoppable_thread != null, this function can be interrupted. */ - public TileShape[] split_to_convex(datastructures.Stoppable p_stoppable_thread) + public TileShape[] split_to_convex(eu.mihosoft.freerouting.datastructures.Stoppable p_stoppable_thread) { if (precalculated_convex_pieces == null) { diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineShape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineShape.java index 9d2e740..e9934e6 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineShape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/PolylineShape.java @@ -18,7 +18,7 @@ * Created on 16. November 2002, 09:34 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalPoint.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalPoint.java index 8122c56..1c64baa 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalPoint.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalPoint.java @@ -18,10 +18,10 @@ * Created on 1. Februar 2003, 13:12 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; -import datastructures.BigIntAux; +import eu.mihosoft.freerouting.datastructures.BigIntAux; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalVector.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalVector.java index 08868ed..96b438e 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalVector.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RationalVector.java @@ -18,11 +18,11 @@ * Created on 1. Februar 2003, 09:16 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; -import datastructures.BigIntAux; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.BigIntAux; +import eu.mihosoft.freerouting.datastructures.Signum; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RegularTileShape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RegularTileShape.java index 26bba49..bfe362d 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/RegularTileShape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/RegularTileShape.java @@ -18,7 +18,7 @@ * Created on 16. November 2002, 17:11 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * TileShapes whose border lines may have only directions out of diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Shape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Shape.java index 98d680b..7dd90bd 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Shape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Shape.java @@ -18,7 +18,7 @@ * Created on 14. November 2002, 12:35 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * Interface describing functionality for connected 2-dimensional shapes in the plane. diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/ShapeBoundingDirections.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/ShapeBoundingDirections.java index ce1b584..a77d20b 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/ShapeBoundingDirections.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/ShapeBoundingDirections.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Side.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Side.java index d062267..ccb47e6 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Side.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Side.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Simplex.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Simplex.java index 1a79f2b..9408521 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Simplex.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Simplex.java @@ -14,7 +14,7 @@ * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/TileShape.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/TileShape.java index f13a34b..26c5997 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/TileShape.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/TileShape.java @@ -13,7 +13,7 @@ * GNU General Public License at * for more details. */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.util.Collection; import java.util.Iterator; diff --git a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Vector.java b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Vector.java index 3b079f3..fb482a4 100644 --- a/src/main/java/eu/mihosoft/freerouting/geometry/planar/Vector.java +++ b/src/main/java/eu/mihosoft/freerouting/geometry/planar/Vector.java @@ -18,11 +18,11 @@ * Created on 1. Februar 2003, 14:28 */ -package geometry.planar; +package eu.mihosoft.freerouting.geometry.planar; import java.math.BigInteger; -import datastructures.Signum; +import eu.mihosoft.freerouting.datastructures.Signum; /** * Abstract class describing functionality of Vectors. diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardFrame.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardFrame.java index f355626..7cc46fe 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardFrame.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardFrame.java @@ -14,7 +14,7 @@ * for more details. */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.interactive.ScreenMessages; @@ -111,7 +111,7 @@ public class BoardFrame extends javax.swing.JFrame this.board_observers = p_observers; this.item_id_no_generator = p_item_id_no_generator; this.locale = p_locale; - this.resources = java.util.ResourceBundle.getBundle("resources.BoardFrame", p_locale); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardFrame", p_locale); BoardMenuBar curr_menubar; boolean session_file_option = (p_option == Option.SESSION_FILE); boolean curr_help_system_used = true; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuBar.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuBar.java index 8a6d504..6c1b4e4 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuBar.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuBar.java @@ -18,7 +18,7 @@ * Created on 11. Februar 2005, 10:17 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Creates the menu bar of a eu.mihosoft.freerouting.board frame together with its menu items. diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuDisplay.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuDisplay.java index 5dfc8e0..36a5ad9 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuDisplay.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuDisplay.java @@ -18,7 +18,7 @@ * Created on 12. Februar 2005, 05:42 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Creates the display menu of a eu.mihosoft.freerouting.board frame. @@ -91,7 +91,7 @@ public class BoardMenuDisplay extends javax.swing.JMenu private BoardMenuDisplay(BoardFrame p_board_frame) { board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuDisplay", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuDisplay", p_board_frame.get_locale()); } private final BoardFrame board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuFile.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuFile.java index 47a34b7..64a59e9 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuFile.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuFile.java @@ -17,7 +17,7 @@ * * Created on 11. Februar 2005, 11:26 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Creates the file menu of a eu.mihosoft.freerouting.board frame. @@ -313,7 +313,7 @@ public class BoardMenuFile extends javax.swing.JMenu { session_file_option = p_session_file_option; board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); } private final BoardFrame board_frame; private final boolean session_file_option; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelp.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelp.java index d807a63..5ec74c8 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelp.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelp.java @@ -36,7 +36,7 @@ public class BoardMenuHelp extends BoardMenuHelpReduced { /** * Creates a new instance of BoardMenuHelp - * Separated from BoardMenuHelpReduced to avoid ClassNotFound exception when the eu.mihosoft.freerouting.library + * Separated from BoardMenuHelpReduced to avoid ClassNotFound exception when the library * jh.jar is not found, which is only used in this extended class. */ public BoardMenuHelp(BoardFrame p_board_frame) diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelpReduced.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelpReduced.java index 8f7b814..ba0f94d 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelpReduced.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuHelpReduced.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -29,23 +29,19 @@ public class BoardMenuHelpReduced extends javax.swing.JMenu { /** * Creates a new instance of BoardMenuHelpReduced - * Separated from BoardMenuHelp to avoid ClassNotFound exception when the eu.mihosoft.freerouting.library + * Separated from BoardMenuHelp to avoid ClassNotFound exception when the library * jh.jar is not found, which is only used in the extended help menu. */ public BoardMenuHelpReduced(BoardFrame p_board_frame) { this.board_frame = p_board_frame; - this.resources = java.util.ResourceBundle.getBundle("resources.BoardMenuHelp", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuHelp", p_board_frame.get_locale()); this.setText(this.resources.getString("help")); javax.swing.JMenuItem about_window = new javax.swing.JMenuItem(); about_window.setText(this.resources.getString("about")); - about_window.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - board_frame.about_window.setVisible(true); - } + about_window.addActionListener((java.awt.event.ActionEvent evt) -> { + board_frame.about_window.setVisible(true); }); this.add(about_window); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuInfo.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuInfo.java index 540afe2..a839376 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuInfo.java @@ -18,7 +18,7 @@ * Created on 6. Maerz 2005, 05:37 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -129,7 +129,7 @@ public class BoardMenuInfo extends javax.swing.JMenu private BoardMenuInfo(BoardFrame p_board_frame) { board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuInfo", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuInfo", p_board_frame.get_locale()); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuOther.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuOther.java index 5dbceb9..9836106 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuOther.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuOther.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -55,7 +55,7 @@ public class BoardMenuOther extends javax.swing.JMenu private BoardMenuOther(BoardFrame p_board_frame) { board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuOther", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuOther", p_board_frame.get_locale()); } private final BoardFrame board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuParameter.java index 0f45352..957fe43 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuParameter.java @@ -18,7 +18,7 @@ * Created on 12. Februar 2005, 06:08 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Creates the parameter menu of a eu.mihosoft.freerouting.board frame. @@ -59,7 +59,7 @@ public class BoardMenuParameter extends javax.swing.JMenu parameter_menu.add(routewindow); javax.swing.JMenuItem autoroutewindow = new javax.swing.JMenuItem(); - autoroutewindow.setText(parameter_menu.resources.getString("eu/mihosoft/freerouting/autoroute")); + autoroutewindow.setText(parameter_menu.resources.getString("autoroute")); autoroutewindow.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) @@ -89,7 +89,7 @@ public class BoardMenuParameter extends javax.swing.JMenu private BoardMenuParameter(BoardFrame p_board_frame) { board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuParameter", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuParameter", p_board_frame.get_locale()); } private final BoardFrame board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuRules.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuRules.java index f00e522..4c868c3 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuRules.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardMenuRules.java @@ -18,22 +18,22 @@ * Created on 20. Februar 2005, 06:00 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** - * Creates the eu.mihosoft.freerouting.rules menu of a eu.mihosoft.freerouting.board frame. + * Creates the rules menu of a board frame. * * @author Alfons Wirtz */ public class BoardMenuRules extends javax.swing.JMenu { - /** Returns a new windows menu for the eu.mihosoft.freerouting.board frame. */ + /** Returns a new windows menu for the board frame. */ public static BoardMenuRules get_instance(BoardFrame p_board_frame) { final BoardMenuRules rules_menu = new BoardMenuRules(p_board_frame); - rules_menu.setText(rules_menu.resources.getString("eu/mihosoft/freerouting/rules")); + rules_menu.setText(rules_menu.resources.getString("rules")); javax.swing.JMenuItem clearance_window = new javax.swing.JMenuItem(); clearance_window.setText(rules_menu.resources.getString("clearance_matrix")); @@ -87,7 +87,7 @@ public class BoardMenuRules extends javax.swing.JMenu private BoardMenuRules(BoardFrame p_board_frame) { board_frame = p_board_frame; - resources = java.util.ResourceBundle.getBundle("resources.BoardMenuRules", p_board_frame.get_locale()); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuRules", p_board_frame.get_locale()); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardPanel.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardPanel.java index d5ebab6..9959694 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardPanel.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardPanel.java @@ -18,7 +18,7 @@ * Created on 3. Oktober 2002, 18:47 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.interactive.BoardHandling; import eu.mihosoft.freerouting.interactive.ScreenMessages; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardPanelStatus.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardPanelStatus.java index 776f6b6..f31c1ab 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardPanelStatus.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardPanelStatus.java @@ -18,7 +18,7 @@ * Created on 16. Februar 2005, 08:11 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Panel at the lower border of the eu.mihosoft.freerouting.board frame containing amongst others the message line @@ -33,7 +33,7 @@ class BoardPanelStatus extends javax.swing.JPanel BoardPanelStatus(java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.BoardPanelStatus", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardPanelStatus", p_locale); this.setLayout(new java.awt.BorderLayout()); this.setPreferredSize(new java.awt.Dimension(300, 20)); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardSavableSubWindow.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardSavableSubWindow.java index 82fc11d..fdfc930 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardSavableSubWindow.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardSavableSubWindow.java @@ -18,7 +18,7 @@ * Created on 20. Dezember 2004, 09:03 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Subwindow of the eu.mihosoft.freerouting.board frame, whose location and visibility can be saved and read from disc. diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardSubWindow.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardSubWindow.java index a68b78a..0a78474 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardSubWindow.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardSubWindow.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Subwindows of the eu.mihosoft.freerouting.board frame. diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardTemporarySubWindow.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardTemporarySubWindow.java index a108914..a04f1d7 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardTemporarySubWindow.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardTemporarySubWindow.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Class for temporary subwindows of the boarrd frame diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbar.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbar.java index 1440049..47c0af5 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbar.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbar.java @@ -18,7 +18,7 @@ * Created on 15. Februar 2005, 09:44 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Implements the toolbar panel of the eu.mihosoft.freerouting.board frame. @@ -34,7 +34,7 @@ class BoardToolbar extends javax.swing.JPanel this.board_frame = p_board_frame; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.BoardToolbar", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardToolbar", p_board_frame.get_locale()); this.setLayout(new java.awt.BorderLayout()); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbarSelectedItem.java b/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbarSelectedItem.java index f3d5342..4a20aea 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbarSelectedItem.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/BoardToolbarSelectedItem.java @@ -18,7 +18,7 @@ * Created on 16. Februar 2005, 05:59 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Describes the toolbar of the eu.mihosoft.freerouting.board frame, when it is in the selected item state. @@ -37,7 +37,7 @@ class BoardToolbarSelectedItem extends javax.swing.JToolBar this.board_frame = p_board_frame; this.resources = - java.util.ResourceBundle.getBundle("resources.BoardToolbarSelectedItem", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardToolbarSelectedItem", p_board_frame.get_locale()); javax.swing.JButton cancel_button = new javax.swing.JButton(); cancel_button.setText(resources.getString("cancel")); @@ -119,7 +119,7 @@ class BoardToolbarSelectedItem extends javax.swing.JToolBar this.add(unfix_button); javax.swing.JButton autoroute_button = new javax.swing.JButton(); - autoroute_button.setText(resources.getString("eu/mihosoft/freerouting/autoroute")); + autoroute_button.setText(resources.getString("autoroute")); autoroute_button.setToolTipText(resources.getString("autoroute_tooltip")); autoroute_button.addActionListener(new java.awt.event.ActionListener() { diff --git a/src/main/java/eu/mihosoft/freerouting/gui/ColorManager.java b/src/main/java/eu/mihosoft/freerouting/gui/ColorManager.java index af0118c..514166e 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/ColorManager.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/ColorManager.java @@ -18,7 +18,7 @@ * Created on 3. August 2003, 11:16 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.awt.BorderLayout; import java.awt.Color; @@ -57,7 +57,7 @@ public class ColorManager extends BoardSavableSubWindow { GraphicsContext graphics_context = p_board_frame.board_panel.board_handling.graphics_context; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setTitle(resources.getString("color_manager")); final JPanel panel = new JPanel(); final int textfield_height = 17; @@ -135,7 +135,7 @@ public class ColorManager extends BoardSavableSubWindow } }; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_locale); final JDialog dialog = JColorChooser.createDialog(button, resources.getString("pick_a_color"), true, colorChooser, okListener, null); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxClearance.java b/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxClearance.java index db83ed5..7f4716f 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxClearance.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxClearance.java @@ -18,7 +18,7 @@ * Created on 1. Maerz 2005, 09:27 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.ClearanceMatrix; /** diff --git a/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxLayer.java b/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxLayer.java index 9c37fde..cd47092 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxLayer.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/ComboBoxLayer.java @@ -18,7 +18,7 @@ * Created on 20. Februar 2005, 08:14 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.board.LayerStructure; /** @@ -33,7 +33,7 @@ public class ComboBoxLayer extends javax.swing.JComboBox public ComboBoxLayer(LayerStructure p_layer_structure, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_locale); int signal_layer_count = p_layer_structure.signal_layer_count(); int item_count = signal_layer_count + 1; boolean add_inner_layer_item = signal_layer_count > 2; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/Cursor.java b/src/main/java/eu/mihosoft/freerouting/gui/Cursor.java index 0c5051b..fcc9882 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/Cursor.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/Cursor.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.awt.AlphaComposite; import java.awt.BasicStroke; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/DefaultExceptionHandler.java b/src/main/java/eu/mihosoft/freerouting/gui/DefaultExceptionHandler.java index 3e01d9f..98fb617 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/DefaultExceptionHandler.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/DefaultExceptionHandler.java @@ -1,4 +1,4 @@ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.logger.FRLogger; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/DesignFile.java b/src/main/java/eu/mihosoft/freerouting/gui/DesignFile.java index 6b7ddfa..b299ee2 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/DesignFile.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/DesignFile.java @@ -18,7 +18,7 @@ * Created on 25. Oktober 2006, 07:48 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.datastructures.FileFilter; import eu.mihosoft.freerouting.designforms.specctra.RulesFile; @@ -135,7 +135,7 @@ public class DesignFile public void save_as_dialog(java.awt.Component p_parent, BoardFrame p_board_frame) { final java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); String[] file_name_parts = this.get_name().split("\\.", 2); String design_name = file_name_parts[0]; @@ -204,7 +204,7 @@ public class DesignFile public boolean write_specctra_session_file(BoardFrame p_board_frame) { final java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); String design_file_name = this.get_name(); String[] file_name_parts = design_file_name.split("\\.", 2); String design_name = file_name_parts[0]; @@ -255,7 +255,7 @@ public class DesignFile output_stream = new java.io.FileOutputStream(rules_file); } catch (java.io.IOException e) { - System.out.println("unable to create eu.mihosoft.freerouting.rules file"); + System.out.println("unable to create rules file"); return false; } @@ -268,7 +268,7 @@ public class DesignFile { boolean result = true; - String rule_file_name = p_design_name + ".eu.mihosoft.freerouting.rules"; + String rule_file_name = p_design_name + ".rules"; boolean dsn_file_generated_by_host = p_board_handling.get_routing_board().communication.specctra_parser_info.dsn_file_generated_by_host; { @@ -306,7 +306,7 @@ public class DesignFile public void update_eagle(BoardFrame p_board_frame) { final java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); String design_file_name = get_name(); java.io.ByteArrayOutputStream session_output_stream = new java.io.ByteArrayOutputStream(); if (!p_board_frame.board_panel.board_handling.export_specctra_session_file(design_file_name, session_output_stream)) @@ -401,7 +401,7 @@ public class DesignFile // if (!new_session_file_name.equalsIgnoreCase(session_file_name)) // { // final java.util.ResourceBundle resources = -// java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); +// java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); // String curr_message = resources.getString("message_20") + " " + session_file_name + "\n" + resources.getString("message_21"); // WindowMessage.ok(curr_message); // } @@ -442,7 +442,7 @@ public class DesignFile // if (!new_script_file_name.endsWith(".scr")) // { // final java.util.ResourceBundle resources = -// java.util.ResourceBundle.getBundle("resources.BoardMenuFile", p_board_frame.get_locale()); +// java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.BoardMenuFile", p_board_frame.get_locale()); // String curr_message = resources.getString("message_22") + "\n" + resources.getString("message_21"); // WindowMessage.ok(curr_message); // } @@ -493,5 +493,5 @@ public class DesignFile private java.io.File output_file; private final java.io.File input_file; private javax.swing.JFileChooser file_chooser; - private static final String RULES_FILE_EXTENSION = ".eu.mihosoft.freerouting.rules"; + private static final String RULES_FILE_EXTENSION = ".rules"; } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsFile.java b/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsFile.java index 353da57..bf98fea 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsFile.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsFile.java @@ -18,7 +18,7 @@ * Created on 26. Dezember 2004, 08:29 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.datastructures.IndentFileWriter; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsScanner.java b/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsScanner.java index 9fea6cb..8c7777e 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsScanner.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/GUIDefaultsScanner.java @@ -1,6 +1,6 @@ /* The following code was generated by JFlex 1.4 on 16.03.07 09:07 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; @SuppressWarnings("all") /** @@ -1220,7 +1220,7 @@ class GUIDefaultsScanner { * (e.g. a JFlex bug producing a faulty scanner etc.). * * Usual syntax/scanner level error handling should be done - * in error fallback eu.mihosoft.freerouting.rules. + * in error fallback rules. * * @param errorCode the code of the errormessage to display */ diff --git a/src/main/java/eu/mihosoft/freerouting/gui/MainApplication.java b/src/main/java/eu/mihosoft/freerouting/gui/MainApplication.java index 18e157d..33584e0 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/MainApplication.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/MainApplication.java @@ -18,9 +18,13 @@ * Created on 19. Oktober 2002, 17:58 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.board.TestLevel; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; /** * @@ -33,21 +37,30 @@ public class MainApplication extends javax.swing.JFrame /** * Main function of the Application + * @param args */ - public static void main(String p_args[]) + public static void main(String args[]) { - Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler()); - StartupOptions startupOptions = StartupOptions.parse(p_args); - - if (!(OFFLINE_ALLOWED || startupOptions.webstart_option)) - { - Runtime.getRuntime().exit(1); + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException ex) { + Logger.getLogger(MainApplication.class.getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + Logger.getLogger(MainApplication.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(MainApplication.class.getName()).log(Level.SEVERE, null, ex); + } catch (UnsupportedLookAndFeelException ex) { + Logger.getLogger(MainApplication.class.getName()).log(Level.SEVERE, null, ex); } + + Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler()); + StartupOptions startupOptions = StartupOptions.parse(args); if (startupOptions.single_design_option) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.MainApplication", startupOptions.current_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.MainApplication", startupOptions.current_locale); BoardFrame.Option board_option; if (startupOptions.session_file_option) { @@ -65,10 +78,13 @@ public class MainApplication extends javax.swing.JFrame System.out.println(" " + resources.getString("message_7")); return; } - String message = resources.getString("loading_design") + " " + startupOptions.design_file_name; + String message = resources.getString("loading_design") + " " + + startupOptions.design_file_name; WindowMessage welcome_window = WindowMessage.show(message); final BoardFrame new_frame = - create_board_frame(design_file, null, board_option, startupOptions.test_version_option, startupOptions.current_locale); + create_board_frame(design_file, null, board_option, + startupOptions.test_version_option, + startupOptions.current_locale); welcome_window.dispose(); if (new_frame == null) { @@ -78,6 +94,7 @@ public class MainApplication extends javax.swing.JFrame new_frame.addWindowListener(new java.awt.event.WindowAdapter() { + @Override public void windowClosed(java.awt.event.WindowEvent evt) { Runtime.getRuntime().exit(0); @@ -92,7 +109,8 @@ public class MainApplication extends javax.swing.JFrame /** * Creates new form MainApplication - * It takes the directory of the eu.mihosoft.freerouting.board designs as optional argument. + * It takes the directory of the board designs as optional argument. + * @param startupOptions */ public MainApplication(StartupOptions startupOptions) { @@ -101,7 +119,7 @@ public class MainApplication extends javax.swing.JFrame this.is_webstart = startupOptions.getWebstartOption(); this.locale = startupOptions.getCurrentLocale(); this.resources = - java.util.ResourceBundle.getBundle("resources.MainApplication", locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.MainApplication", locale); main_panel = new javax.swing.JPanel(); getContentPane().add(main_panel); java.awt.GridBagLayout gridbag = new java.awt.GridBagLayout(); @@ -133,13 +151,8 @@ public class MainApplication extends javax.swing.JFrame { demonstration_button.setText(resources.getString("router_demonstrations")); demonstration_button.setToolTipText(resources.getString("router_demonstrations_tooltip")); - demonstration_button.addActionListener(new java.awt.event.ActionListener() - { - - public void actionPerformed(java.awt.event.ActionEvent evt) - { - window_net_demonstrations.setVisible(true); - } + demonstration_button.addActionListener((java.awt.event.ActionEvent evt) -> { + window_net_demonstrations.setVisible(true); }); gridbag.setConstraints(demonstration_button, gridbag_constraints); @@ -147,13 +160,8 @@ public class MainApplication extends javax.swing.JFrame sample_board_button.setText(resources.getString("sample_designs")); sample_board_button.setToolTipText(resources.getString("sample_designs_tooltip")); - sample_board_button.addActionListener(new java.awt.event.ActionListener() - { - - public void actionPerformed(java.awt.event.ActionEvent evt) - { - window_net_sample_designs.setVisible(true); - } + sample_board_button.addActionListener((java.awt.event.ActionEvent evt) -> { + window_net_sample_designs.setVisible(true); }); gridbag.setConstraints(sample_board_button, gridbag_constraints); @@ -163,13 +171,8 @@ public class MainApplication extends javax.swing.JFrame open_board_button.setText(resources.getString("open_own_design")); open_board_button.setToolTipText(resources.getString("open_own_design_tooltip")); - open_board_button.addActionListener(new java.awt.event.ActionListener() - { - - public void actionPerformed(java.awt.event.ActionEvent evt) - { - open_board_design_action(evt); - } + open_board_button.addActionListener((java.awt.event.ActionEvent evt) -> { + open_board_design_action(evt); }); gridbag.setConstraints(open_board_button, gridbag_constraints); @@ -182,15 +185,10 @@ public class MainApplication extends javax.swing.JFrame { restore_defaults_button.setText(resources.getString("restore_defaults")); restore_defaults_button.setToolTipText(resources.getString("restore_defaults_tooltip")); - restore_defaults_button.addActionListener(new java.awt.event.ActionListener() - { - - public void actionPerformed(java.awt.event.ActionEvent evt) + restore_defaults_button.addActionListener((java.awt.event.ActionEvent evt) -> { + if (is_webstart) { - if (is_webstart) - { - restore_defaults_action(evt); - } + restore_defaults_action(evt); } }); @@ -205,6 +203,8 @@ public class MainApplication extends javax.swing.JFrame this.addWindowListener(new WindowStateListener()); pack(); + setSize(450,250); + } /** opens a eu.mihosoft.freerouting.board design from a binary file or a specctra dsn file. */ @@ -265,7 +265,7 @@ public class MainApplication extends javax.swing.JFrame BoardFrame.Option p_option, boolean p_is_test_version, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.MainApplication", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.MainApplication", p_locale); java.io.InputStream input_stream = p_design_file.get_input_stream(); if (input_stream == null) @@ -295,7 +295,7 @@ public class MainApplication extends javax.swing.JFrame new_frame.menubar.add_design_dependent_items(); if (p_design_file.is_created_from_text_file()) { - // Read the file with the saved eu.mihosoft.freerouting.rules, if it is existing. + // Read the file with the saved rules, if it is existing. String file_name = p_design_file.get_name(); String[] name_parts = file_name.split("\\."); @@ -312,8 +312,8 @@ public class MainApplication extends javax.swing.JFrame private final javax.swing.JButton sample_board_button; private final javax.swing.JButton open_board_button; private final javax.swing.JButton restore_defaults_button; - private javax.swing.JTextField message_field; - private javax.swing.JPanel main_panel; + private final javax.swing.JTextField message_field; + private final javax.swing.JPanel main_panel; /** * A Frame with routing demonstrations in the net. */ @@ -323,7 +323,8 @@ public class MainApplication extends javax.swing.JFrame */ private final WindowNetSamples window_net_sample_designs; /** The list of open eu.mihosoft.freerouting.board frames */ - private java.util.Collection board_frames = new java.util.LinkedList(); + private final java.util.Collection board_frames + = new java.util.LinkedList<>(); private String design_dir_name = null; private final boolean is_test_version; private final boolean is_webstart; @@ -338,6 +339,7 @@ public class MainApplication extends javax.swing.JFrame this.board_frame = p_board_frame; } + @Override public void windowClosed(java.awt.event.WindowEvent evt) { if (board_frame != null) @@ -354,13 +356,15 @@ public class MainApplication extends javax.swing.JFrame private class WindowStateListener extends java.awt.event.WindowAdapter { + @Override public void windowClosing(java.awt.event.WindowEvent evt) { setDefaultCloseOperation(DISPOSE_ON_CLOSE); boolean exit_program = true; if (!is_test_version && board_frames.size() > 0) { - int option = javax.swing.JOptionPane.showConfirmDialog(null, resources.getString("confirm_cancel"), + int option = javax.swing.JOptionPane.showConfirmDialog(null, + resources.getString("confirm_cancel"), null, javax.swing.JOptionPane.YES_NO_OPTION); if (option == javax.swing.JOptionPane.NO_OPTION) { @@ -374,20 +378,21 @@ public class MainApplication extends javax.swing.JFrame } } + @Override public void windowIconified(java.awt.event.WindowEvent evt) { window_net_sample_designs.parent_iconified(); } + @Override public void windowDeiconified(java.awt.event.WindowEvent evt) { window_net_sample_designs.parent_deiconified(); } } - static final String WEB_FILE_BASE_NAME = "http://www.freerouting.net/java/"; - private static final boolean OFFLINE_ALLOWED = true; + static final String WEB_FILE_BASE_NAME = "http://www.freerouting.mihosoft.eu"; /** * Change this string when creating a new version */ - static final String VERSION_NUMBER_STRING = "1.2.43 Extra"; + static final String VERSION_NUMBER_STRING = "v1.3.0 (JDK9 version by mihosoft.eu)"; } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuChangeLayer.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuChangeLayer.java index 473b074..b611603 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuChangeLayer.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuChangeLayer.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 08:58 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Used as submenu in a popup menu for change layer actions. @@ -36,7 +36,7 @@ class PopupMenuChangeLayer extends javax.swing.JMenu eu.mihosoft.freerouting.board.LayerStructure layer_structure = board_frame.board_panel.board_handling.get_routing_board().layer_structure; this.item_arr = new LayermenuItem[layer_structure.signal_layer_count()]; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setText(resources.getString("change_layer")); this.setToolTipText(resources.getString("change_layer_tooltip")); @@ -80,7 +80,7 @@ class PopupMenuChangeLayer extends javax.swing.JMenu LayermenuItem(int p_layer_no) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", board_frame.get_locale()); message1 = resources.getString("layer_changed_to") + " "; layer_no = p_layer_no; addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuCopy.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuCopy.java index 75bb5b5..a9e8dfa 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuCopy.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuCopy.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 08:20 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup menu used in the eu.mihosoft.freerouting.interactive copy item state. @@ -44,7 +44,7 @@ public class PopupMenuCopy extends PopupMenuDisplay change_layer_menu = null; } java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem insert_item = new javax.swing.JMenuItem(); insert_item.setText(resources.getString("insert")); insert_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDisplay.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDisplay.java index a2171a6..e8f6bc9 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDisplay.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDisplay.java @@ -22,7 +22,7 @@ * Open. You can then make changes to the template in the Source Editor. */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -36,7 +36,7 @@ public class PopupMenuDisplay extends javax.swing.JPopupMenu { this.board_panel = p_board_frame.board_panel; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem center_display_item = new javax.swing.JMenuItem(); center_display_item.setText(resources.getString("center_display")); center_display_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDynamicRoute.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDynamicRoute.java index b1d1441..5ca1c07 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDynamicRoute.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuDynamicRoute.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 07:08 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup menu used in the eu.mihosoft.freerouting.interactive route state. @@ -34,7 +34,7 @@ public class PopupMenuDynamicRoute extends PopupMenuDisplay super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); eu.mihosoft.freerouting.board.LayerStructure layer_structure = board_panel.board_handling.get_routing_board().layer_structure; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuInsertCancel.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuInsertCancel.java index 5d520ae..903a59e 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuInsertCancel.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuInsertCancel.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 08:05 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup menu containing the 2 items complete and cancel. @@ -33,7 +33,7 @@ class PopupMenuInsertCancel extends javax.swing.JPopupMenu { this.board_panel = p_board_frame.board_panel; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem insert_item = new javax.swing.JMenuItem(); insert_item.setText(resources.getString("insert")); insert_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMain.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMain.java index 609200b..6e32e18 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMain.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMain.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 05:42 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup Menu used in the eu.mihosoft.freerouting.interactive select state. @@ -33,7 +33,7 @@ class PopupMenuMain extends PopupMenuDisplay { super(p_board_frame) ; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.PopupMenuMain", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.PopupMenuMain", p_board_frame.get_locale()); // add the item for selecting items diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMove.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMove.java index 9e153c0..5a91bd2 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMove.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuMove.java @@ -22,7 +22,7 @@ * Open. You can then make changes to the template in the Source Editor. */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -36,7 +36,7 @@ public class PopupMenuMove extends PopupMenuDisplay { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.PopupMenuMove", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.PopupMenuMove", p_board_frame.get_locale()); // Add menu for turning the items by a multiple of 90 degree diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuSelectedItems.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuSelectedItems.java index 1c48547..ec9bd7d 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuSelectedItems.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuSelectedItems.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 07:47 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup menu used in the eu.mihosoft.freerouting.interactive selected item state.. @@ -33,7 +33,7 @@ class PopupMenuSelectedItems extends PopupMenuDisplay { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem copy_item = new javax.swing.JMenuItem(); copy_item.setText(resources.getString("copy")); copy_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuStitchRoute.java b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuStitchRoute.java index c3a8712..9586b0b 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuStitchRoute.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PopupMenuStitchRoute.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -44,7 +44,7 @@ public class PopupMenuStitchRoute extends PopupMenuDisplay change_layer_menu = null; } java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem insert_item = new javax.swing.JMenuItem(); insert_item.setText(resources.getString("insert")); insert_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/PupupMenuCornerItemConstruction.java b/src/main/java/eu/mihosoft/freerouting/gui/PupupMenuCornerItemConstruction.java index 62e7ca2..68072c8 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/PupupMenuCornerItemConstruction.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/PupupMenuCornerItemConstruction.java @@ -18,7 +18,7 @@ * Created on 17. Februar 2005, 07:31 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Popup menu used while constructing a cornered shape.. @@ -33,7 +33,7 @@ class PupupMenuCornerItemConstruction extends javax.swing.JPopupMenu { this.board_panel = p_board_frame.board_panel; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JMenuItem add_corner_item = new javax.swing.JMenuItem(); add_corner_item.setText(resources.getString("add_corner")); add_corner_item.addActionListener(new java.awt.event.ActionListener() diff --git a/src/main/java/eu/mihosoft/freerouting/gui/StartupOptions.java b/src/main/java/eu/mihosoft/freerouting/gui/StartupOptions.java index 1081339..3fd29fd 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/StartupOptions.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/StartupOptions.java @@ -1,4 +1,4 @@ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.Locale; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowAbout.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowAbout.java index 8426909..8ae82aa 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowAbout.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowAbout.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** @@ -32,7 +32,7 @@ public class WindowAbout extends BoardSavableSubWindow public WindowAbout(java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowAbout", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowAbout", p_locale); this.setTitle(resources.getString("title")); final javax.swing.JPanel window_panel = new javax.swing.JPanel(); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowAssignNetClass.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowAssignNetClass.java index 71ac209..9aebb31 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowAssignNetClass.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowAssignNetClass.java @@ -19,7 +19,7 @@ * Created on 12. April 2005, 06:09 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.Net; import eu.mihosoft.freerouting.rules.NetClass; @@ -34,7 +34,7 @@ public class WindowAssignNetClass extends BoardSavableSubWindow /** Creates a new instance of AssignNetRulesWindow */ public WindowAssignNetClass(BoardFrame p_board_frame) { - this.resources = java.util.ResourceBundle.getBundle("resources.WindowAssignNetClass", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowAssignNetClass", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.board_frame = p_board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteDetailParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteDetailParameter.java index a74dd24..f59882a 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteDetailParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteDetailParameter.java @@ -18,7 +18,7 @@ * Created on 25. Juli 2006, 08:17 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * @@ -32,7 +32,7 @@ public class WindowAutorouteDetailParameter extends BoardSavableSubWindow { this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowAutorouteParameter", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowAutorouteParameter", p_board_frame.get_locale()); this.setTitle(resources.getString("detail_autoroute_parameter")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteParameter.java index 304b4d5..48d96f1 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowAutorouteParameter.java @@ -18,7 +18,7 @@ * Created on 24. Juli 2006, 07:20 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Window handling parameters of the automatic routing. @@ -33,7 +33,7 @@ public class WindowAutorouteParameter extends BoardSavableSubWindow { this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowAutorouteParameter", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowAutorouteParameter", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -118,7 +118,7 @@ public class WindowAutorouteParameter extends BoardSavableSubWindow main_panel.add(passes_label); this.fanout_pass_button = new javax.swing.JRadioButton(resources.getString("fanout")); - this.autoroute_pass_button = new javax.swing.JRadioButton(resources.getString("eu/mihosoft/freerouting/autoroute")); + this.autoroute_pass_button = new javax.swing.JRadioButton(resources.getString("autoroute")); this.postroute_pass_button = new javax.swing.JRadioButton(resources.getString("postroute")); fanout_pass_button.addActionListener(new FanoutListener()); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceMatrix.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceMatrix.java index 734cd9c..b25f3f1 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceMatrix.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceMatrix.java @@ -18,7 +18,7 @@ * Created on 20. Februar 2005, 06:09 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.ClearanceMatrix; @@ -36,7 +36,7 @@ public class WindowClearanceMatrix extends BoardSavableSubWindow public WindowClearanceMatrix(BoardFrame p_board_frame) { this.board_frame = p_board_frame; - this.resources = java.util.ResourceBundle.getBundle("resources.WindowClearanceMatrix", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowClearanceMatrix", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceViolations.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceViolations.java index ef8ff4a..bc25c6a 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceViolations.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowClearanceViolations.java @@ -18,7 +18,7 @@ * Created on 22. Maerz 2005, 05:40 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import eu.mihosoft.freerouting.board.ClearanceViolation; @@ -36,7 +36,7 @@ public class WindowClearanceViolations extends WindowObjectListWithFilter public WindowClearanceViolations(BoardFrame p_board_frame) { super(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.WindowClearanceViolations", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowClearanceViolations", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.list_empty_message.setText(resources.getString("list_empty_message")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_ClearanceViolations"); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowComponents.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowComponents.java index 774d2d6..4a1b2ff 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowComponents.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowComponents.java @@ -18,7 +18,7 @@ * Created on 8. Maerz 2005, 05:56 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.board.Component; import eu.mihosoft.freerouting.board.Components; @@ -35,7 +35,7 @@ public class WindowComponents extends WindowObjectListWithFilter { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setTitle(resources.getString("components")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_BoardComponents"); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowDisplayMisc.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowDisplayMisc.java index 976d46a..b27a725 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowDisplayMisc.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowDisplayMisc.java @@ -18,7 +18,7 @@ * Created on 20. Dezember 2004, 08:23 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Window for eu.mihosoft.freerouting.interactive changing of miscellanious display properties. @@ -33,7 +33,7 @@ public class WindowDisplayMisc extends BoardSavableSubWindow { this.panel = p_board_frame.board_panel; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.DisplayMisc", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.DisplayMisc", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // Create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowEditVias.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowEditVias.java index 57d6998..69cf69c 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowEditVias.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowEditVias.java @@ -18,7 +18,7 @@ * Created on 4. April 2005, 07:05 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.ViaInfo; import eu.mihosoft.freerouting.rules.ViaInfos; @@ -35,7 +35,7 @@ public class WindowEditVias extends BoardSavableSubWindow /** Creates a new instance of ViaTablePanel */ public WindowEditVias(BoardFrame p_board_frame) { - this.resources = java.util.ResourceBundle.getBundle("resources.WindowEditVias", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowEditVias", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.board_frame = p_board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowIncompletes.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowIncompletes.java index adc3373..1f148f4 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowIncompletes.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowIncompletes.java @@ -18,7 +18,7 @@ * Created on 21. Maerz 2005, 05:30 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.interactive.RatsNest; @@ -34,7 +34,7 @@ public class WindowIncompletes extends WindowObjectListWithFilter { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setTitle(resources.getString("incompletes")); this.list_empty_message.setText(resources.getString("route_completed")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_Incompletes"); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowLayerVisibility.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowLayerVisibility.java index 69155cb..14d3be3 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowLayerVisibility.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowLayerVisibility.java @@ -18,7 +18,7 @@ * Created on 5. November 2004, 11:29 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Interactive Frame to adjust the visibility of the individual eu.mihosoft.freerouting.board layers @@ -32,7 +32,7 @@ public class WindowLayerVisibility extends WindowVisibility { BoardPanel board_panel = p_board_frame.board_panel; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); String title = resources.getString("layer_visibility"); String header_message = resources.getString("layer_visibility_header"); eu.mihosoft.freerouting.board.LayerStructure layer_structure = board_panel.board_handling.get_routing_board().layer_structure; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowLengthViolations.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowLengthViolations.java index da4d0e4..3242c2c 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowLengthViolations.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowLengthViolations.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.Net; import eu.mihosoft.freerouting.rules.Nets; @@ -38,7 +38,7 @@ public class WindowLengthViolations extends WindowObjectListWithFilter public WindowLengthViolations(BoardFrame p_board_frame) { super(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.WindowLengthViolations", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowLengthViolations", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.list_empty_message.setText(resources.getString("list_empty")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_LengthViolations"); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowManualRules.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowManualRules.java index f64e7e4..d566c58 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowManualRules.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowManualRules.java @@ -17,7 +17,7 @@ * * Created on 18. November 2004, 09:08 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Used for manual choice of trace widths in eu.mihosoft.freerouting.interactive routing. @@ -32,7 +32,7 @@ public class WindowManualRules extends BoardSavableSubWindow { this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowManualRule", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowManualRule", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowMessage.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowMessage.java index b0291b0..836ad79 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowMessage.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowMessage.java @@ -18,7 +18,7 @@ * Created on 8. Dezember 2005, 06:20 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Startup window visible when the program is loading. diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowMoveParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowMoveParameter.java index dceb1ee..9369111 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowMoveParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowMoveParameter.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Window with the parameters for moving components. @@ -34,7 +34,7 @@ public class WindowMoveParameter extends BoardSavableSubWindow { this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowMoveParameter", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowMoveParameter", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetClasses.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetClasses.java index 0d25ebd..827c5bb 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetClasses.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetClasses.java @@ -17,7 +17,7 @@ * * Created on 10. April 2005, 07:49 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.NetClass; import eu.mihosoft.freerouting.rules.ViaRule; @@ -26,7 +26,7 @@ import eu.mihosoft.freerouting.rules.BoardRules; import eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable; /** - * Edit window for the table of net eu.mihosoft.freerouting.rules. + * Edit window for the table of net rules. * * @author Alfons Wirtz */ @@ -36,7 +36,7 @@ public class WindowNetClasses extends BoardSavableSubWindow /** Creates a new instance of NetClassesWindow */ public WindowNetClasses(BoardFrame p_board_frame) { - this.resources = java.util.ResourceBundle.getBundle("resources.WindowNetClasses", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowNetClasses", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.board_frame = p_board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetDemonstrations.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetDemonstrations.java index b4e45b1..84fdf0a 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetDemonstrations.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetDemonstrations.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.zip.ZipInputStream; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSampleDesigns.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSampleDesigns.java index b6cf166..2beda43 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSampleDesigns.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSampleDesigns.java @@ -18,7 +18,7 @@ * Created on 14. November 2006, 10:13 * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSamples.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSamples.java index b462f4d..f3ffe83 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSamples.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowNetSamples.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.zip.ZipInputStream; @@ -38,7 +38,7 @@ public abstract class WindowNetSamples extends BoardSubWindow public WindowNetSamples(java.util.Locale p_locale, String p_title, String p_button_name, int p_row_count) { this.locale = p_locale; - this.resources = java.util.ResourceBundle.getBundle("resources.WindowNetSamples", p_locale); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowNetSamples", p_locale); this.setTitle(resources.getString(p_title)); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE ); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowNets.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowNets.java index 6978ae9..82a23a5 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowNets.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowNets.java @@ -18,7 +18,7 @@ * Created on 24. Maerz 2005, 07:41 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.Net; import eu.mihosoft.freerouting.rules.Nets; @@ -37,7 +37,7 @@ public class WindowNets extends WindowObjectListWithFilter public WindowNets(BoardFrame p_board_frame) { super(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.WindowNets", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowNets", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); javax.swing.JPanel curr_button_panel = new javax.swing.JPanel(); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectInfo.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectInfo.java index 2a17c77..595e03f 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectInfo.java @@ -18,7 +18,7 @@ * Created on 1. Januar 2005, 07:28 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.Collection; @@ -157,7 +157,7 @@ public class WindowObjectInfo extends BoardTemporarySubWindow implements eu.miho { super(p_board_frame); this.resources = - java.util.ResourceBundle.getBundle("resources.WindowObjectInfo", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowObjectInfo", p_board_frame.get_locale()); this.coordinate_transform = p_coordinate_transform; // create the text pane diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectList.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectList.java index 41df48d..e32a983 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectList.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectList.java @@ -18,7 +18,7 @@ * Created on 7. Maerz 2005, 09:26 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Abstract class for windows displaying a list of objects @@ -32,7 +32,7 @@ public abstract class WindowObjectList extends BoardSavableSubWindow public WindowObjectList(BoardFrame p_board_frame) { this.board_frame = p_board_frame; - this.resources = java.util.ResourceBundle.getBundle("resources.WindowObjectList", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowObjectList", p_board_frame.get_locale()); // create main panel this.main_panel = new javax.swing.JPanel(); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectListWithFilter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectListWithFilter.java index 0037290..bced0bb 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectListWithFilter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectListWithFilter.java @@ -18,7 +18,7 @@ * Created on 24. Maerz 2005, 10:10 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Abstract class for windows displaying a list of objects @@ -32,7 +32,7 @@ public abstract class WindowObjectListWithFilter extends WindowObjectList { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowObjectList", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowObjectList", p_board_frame.get_locale()); javax.swing.JPanel input_panel = new javax.swing.JPanel(); this.south_panel.add(input_panel, java.awt.BorderLayout.SOUTH); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectVisibility.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectVisibility.java index 6ace964..30174be 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectVisibility.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowObjectVisibility.java @@ -18,7 +18,7 @@ * Created on 7. November 2004, 07:38 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.boardgraphics.ColorIntensityTable.ObjectNames; @@ -33,7 +33,7 @@ public class WindowObjectVisibility extends WindowVisibility public static WindowObjectVisibility get_instance(BoardFrame p_board_frame) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowObjectVisibility", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowObjectVisibility", p_board_frame.get_locale()); String title = resources.getString("title"); String header_message = resources.getString("header_message"); String [] message_arr = new String [ObjectNames.values().length]; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowPackages.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowPackages.java index 785d778..aca542a 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowPackages.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowPackages.java @@ -18,7 +18,7 @@ * Created on 7. Maerz 2005, 09:14 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.library.Packages; import eu.mihosoft.freerouting.library.Package; @@ -36,7 +36,7 @@ public class WindowPackages extends WindowObjectListWithFilter { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setTitle(resources.getString("packages")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_LibraryPackages"); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowPadstacks.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowPadstacks.java index 3ae83cd..a3e0016 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowPadstacks.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowPadstacks.java @@ -18,7 +18,7 @@ * Created on 6. Maerz 2005, 06:47 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.datastructures.UndoableObjects; @@ -38,7 +38,7 @@ public class WindowPadstacks extends WindowObjectListWithFilter { super(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); this.setTitle(resources.getString("padstacks")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_LibraryPadstacks"); } diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteDetail.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteDetail.java index 23be9f5..5f09030 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteDetail.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteDetail.java @@ -17,7 +17,7 @@ * * Created on 18. November 2004, 07:31 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.board.BoardOutline; @@ -34,7 +34,7 @@ public class WindowRouteDetail extends BoardSavableSubWindow { this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowRouteDetail", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowRouteDetail", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteParameter.java index 46c41ab..edd4a81 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteParameter.java @@ -18,7 +18,7 @@ * Created on 17. November 2004, 07:11 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.Collection; @@ -39,7 +39,7 @@ public class WindowRouteParameter extends BoardSavableSubWindow this.manual_rule_window = new WindowManualRules(p_board_frame); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowRouteParameter", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowRouteParameter", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE ); @@ -479,7 +479,7 @@ public class WindowRouteParameter extends BoardSavableSubWindow if (free_angle_traces_found) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowRouteParameter", current_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowRouteParameter", current_locale); String curr_message = resources.getString("change_snap_angle_90"); if (!WindowMessage.confirm(curr_message)) { @@ -515,7 +515,7 @@ public class WindowRouteParameter extends BoardSavableSubWindow if (free_angle_traces_found) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowRouteParameter", current_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowRouteParameter", current_locale); String curr_message = resources.getString("change_snap_angle_45"); if (!WindowMessage.confirm(curr_message)) { diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteStubs.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteStubs.java index 8a07b1d..2b9c08c 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteStubs.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowRouteStubs.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.Collection; import java.util.Set; @@ -42,7 +42,7 @@ public class WindowRouteStubs extends WindowObjectListWithFilter public WindowRouteStubs(BoardFrame p_board_frame) { super(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.CleanupWindows", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.CleanupWindows", p_board_frame.get_locale()); this.setTitle(resources.getString("route_stubs")); this.list_empty_message.setText(resources.getString("no_route_stubs_found")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_RouteStubs"); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowSelectParameter.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowSelectParameter.java index 2d4db47..713757b 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowSelectParameter.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowSelectParameter.java @@ -18,7 +18,7 @@ * Created on 19. November 2004, 11:12 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.board.ItemSelectionFilter; @@ -36,7 +36,7 @@ public class WindowSelectParameter extends BoardSavableSubWindow this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowSelectParameter", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowSelectParameter", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshot.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshot.java index de186ca..90d5b95 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshot.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshot.java @@ -18,7 +18,7 @@ * Created on 9. November 2004, 09:42 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Window handling snapshots of the eu.mihosoft.freerouting.interactive situation. @@ -33,7 +33,7 @@ public class WindowSnapshot extends BoardSavableSubWindow { this.board_frame = p_board_frame; this.settings_window = new WindowSnapshotSettings(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.WindowSnapshot", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowSnapshot", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE ); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshotSettings.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshotSettings.java index 49f9215..3ff099f 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshotSettings.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowSnapshotSettings.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Window for the settinngs of eu.mihosoft.freerouting.interactive snapshots. @@ -35,7 +35,7 @@ public class WindowSnapshotSettings extends BoardSavableSubWindow this.board_handling = p_board_frame.board_panel.board_handling; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.WindowSnapshotSettings", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowSnapshotSettings", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); // create main panel diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowUnconnectedRoute.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowUnconnectedRoute.java index 6e3f376..d62767c 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowUnconnectedRoute.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowUnconnectedRoute.java @@ -19,7 +19,7 @@ * */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import java.util.Collection; import java.util.Set; @@ -38,7 +38,7 @@ public class WindowUnconnectedRoute extends WindowObjectListWithFilter public WindowUnconnectedRoute(BoardFrame p_board_frame) { super(p_board_frame); - this.resources = java.util.ResourceBundle.getBundle("resources.CleanupWindows", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.CleanupWindows", p_board_frame.get_locale()); this.setTitle(resources.getString("unconnected_route")); this.list_empty_message.setText(resources.getString("no_unconnected_route_found")); p_board_frame.set_context_sensitive_help(this, "WindowObjectList_UnconnectedRoute"); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowVia.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowVia.java index 93d4f5d..a942772 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowVia.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowVia.java @@ -18,7 +18,7 @@ * Created on 31. Maerz 2005, 08:36 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.ViaRule; import eu.mihosoft.freerouting.rules.BoardRules; @@ -26,7 +26,7 @@ import eu.mihosoft.freerouting.rules.BoardRules; import eu.mihosoft.freerouting.board.Layer; /** - * Window for eu.mihosoft.freerouting.interactive editing of via eu.mihosoft.freerouting.rules. + * Window for eu.mihosoft.freerouting.interactive editing of via rules. * * @author Alfons Wirtz */ @@ -36,7 +36,7 @@ public class WindowVia extends BoardSavableSubWindow /** Creates a new instance of ViaWindow */ public WindowVia(BoardFrame p_board_frame) { - this.resources = java.util.ResourceBundle.getBundle("resources.WindowVia", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowVia", p_board_frame.get_locale()); this.setTitle(resources.getString("title")); this.board_frame = p_board_frame; diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowViaRule.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowViaRule.java index dbfa128..7b3aabf 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowViaRule.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowViaRule.java @@ -18,7 +18,7 @@ * Created on 5. April 2005, 06:29 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; import eu.mihosoft.freerouting.rules.ViaRule; import eu.mihosoft.freerouting.rules.ViaInfo; @@ -38,7 +38,7 @@ public class WindowViaRule extends javax.swing.JFrame this.via_rule = p_via_rule; this.via_list = p_via_list; - this.resources = java.util.ResourceBundle.getBundle("resources.WindowViaRule", p_board_frame.get_locale()); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.WindowViaRule", p_board_frame.get_locale()); this.setTitle(resources.getString("title") + " " + p_via_rule.name); this.main_panel = new javax.swing.JPanel(); diff --git a/src/main/java/eu/mihosoft/freerouting/gui/WindowVisibility.java b/src/main/java/eu/mihosoft/freerouting/gui/WindowVisibility.java index 70dfa49..d272ddf 100644 --- a/src/main/java/eu/mihosoft/freerouting/gui/WindowVisibility.java +++ b/src/main/java/eu/mihosoft/freerouting/gui/WindowVisibility.java @@ -18,7 +18,7 @@ * Created on 7. November 2004, 11:29 */ -package eu.mihosoft.freerouting.gui.resources; +package eu.mihosoft.freerouting.gui; /** * Interactive Frame to adjust the visibility of a set of objects @@ -69,7 +69,7 @@ public abstract class WindowVisibility extends BoardSavableSubWindow main_panel.add(empty_label); gridbag_constraints.gridwidth = 2; java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("resources.Default", p_board_frame.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.gui.resources.Default", p_board_frame.get_locale()); javax.swing.JButton min_all_button = new javax.swing.JButton(resources.getString("minimum_all")); min_all_button.setToolTipText(resources.getString("minimum_all_tooltip")); min_all_button.addActionListener(new MinAllButtonListener()); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/AutorouteSettings.java b/src/main/java/eu/mihosoft/freerouting/interactive/AutorouteSettings.java index 8cbdf81..5451cd1 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/AutorouteSettings.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/AutorouteSettings.java @@ -18,13 +18,13 @@ * Created on 27. Juli 2006, 09:16 * */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import board.RoutingBoard; -import autoroute.AutorouteControl.ExpansionCostFactor; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.autoroute.AutorouteControl.ExpansionCostFactor; /** - * Contains the interactive settings for the autorouter. + * Contains the eu.mihosoft.freerouting.interactive settings for the autorouter. * * @author Alfons Wirtz */ @@ -66,7 +66,7 @@ public class AutorouteSettings implements java.io.Serializable double vertical_add_costs_against_preferred_dir = 0.1 * Math.round(10 * vertical_width / horizontal_width); - // make more horizontal pefered direction, if the board is horizontal. + // make more horizontal pefered direction, if the eu.mihosoft.freerouting.board is horizontal. boolean curr_preferred_direction_is_horizontal = horizontal_width < vertical_width; for (int i = 0; i < layer_count; ++i) diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/BatchAutorouterThread.java b/src/main/java/eu/mihosoft/freerouting/interactive/BatchAutorouterThread.java index a5ce46d..3dac1c7 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/BatchAutorouterThread.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/BatchAutorouterThread.java @@ -18,16 +18,16 @@ * Created on 25. April 2006, 07:58 * */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.FloatLine; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatLine; -import board.Unit; +import eu.mihosoft.freerouting.board.Unit; -import autoroute.BatchAutorouter; -import autoroute.BatchFanout; -import autoroute.BatchOptRoute; +import eu.mihosoft.freerouting.autoroute.BatchAutorouter; +import eu.mihosoft.freerouting.autoroute.BatchFanout; +import eu.mihosoft.freerouting.autoroute.BatchOptRoute; /** * Thread for the batch autorouter. @@ -52,7 +52,7 @@ public class BatchAutorouterThread extends InteractiveActionThread try { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", hdlg.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", hdlg.get_locale()); boolean saved_board_read_only = hdlg.is_board_read_only(); hdlg.set_board_read_only(true); boolean ratsnest_hidden_before = hdlg.get_ratsnest().is_hidden(); @@ -117,9 +117,9 @@ public class BatchAutorouterThread extends InteractiveActionThread } hdlg.get_panel().board_frame.refresh_windows(); - if (hdlg.get_routing_board().rules.get_trace_angle_restriction() == board.AngleRestriction.FORTYFIVE_DEGREE && hdlg.get_routing_board().get_test_level() != board.TestLevel.RELEASE_VERSION) + if (hdlg.get_routing_board().rules.get_trace_angle_restriction() == eu.mihosoft.freerouting.board.AngleRestriction.FORTYFIVE_DEGREE && hdlg.get_routing_board().get_test_level() != eu.mihosoft.freerouting.board.TestLevel.RELEASE_VERSION) { - tests.Validate.multiple_of_45_degree("after autoroute: ", hdlg.get_routing_board()); + eu.mihosoft.freerouting.tests.Validate.multiple_of_45_degree("after eu.mihosoft.freerouting.autoroute: ", hdlg.get_routing_board()); } } catch (Exception e) { diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandling.java b/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandling.java index b5798cb..bbdfdf6 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandling.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandling.java @@ -18,7 +18,7 @@ * Created on 5. November 2003, 13:02 * */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.awt.Dimension; import java.awt.Graphics; @@ -31,30 +31,34 @@ import java.io.OutputStream; import java.util.Collection; import java.util.Set; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.IntPoint; -import geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.designforms.specctra.SessionFile; +import eu.mihosoft.freerouting.designforms.specctra.SessionToEagle; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; -import rules.BoardRules; -import board.LayerStructure; -import board.RoutingBoard; -import board.Item; -import board.PolylineTrace; -import board.FixedState; -import board.ItemSelectionFilter; +import eu.mihosoft.freerouting.gui.BoardPanel; +import eu.mihosoft.freerouting.gui.ComboBoxLayer; +import eu.mihosoft.freerouting.rules.BoardRules; +import eu.mihosoft.freerouting.board.LayerStructure; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.FixedState; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; -import boardgraphics.GraphicsContext; -import board.CoordinateTransform; -import board.Unit; -import board.TestLevel; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.board.CoordinateTransform; +import eu.mihosoft.freerouting.board.Unit; +import eu.mihosoft.freerouting.board.TestLevel; -import designformats.specctra.DsnFile; +import eu.mihosoft.freerouting.designforms.specctra.DsnFile; /** * * Central connection class between the graphical user interface and - * the board database. + * the eu.mihosoft.freerouting.board database. * * @author Alfons Wirtz */ @@ -64,18 +68,18 @@ public class BoardHandling extends BoardHandlingImpl /** * Creates a new BoardHandling */ - public BoardHandling(gui.BoardPanel p_panel, java.util.Locale p_locale) + public BoardHandling(BoardPanel p_panel, java.util.Locale p_locale) { this.locale = p_locale; this.panel = p_panel; this.screen_messages = p_panel.screen_messages; this.set_interactive_state(SelectMenuState.get_instance(this, logfile)); - this.resources = java.util.ResourceBundle.getBundle("interactive.resources.BoardHandling", p_locale); + this.resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.BoardHandling", p_locale); } /** - * Sets the board to read only for example when running a seperate action thread - * to avoid unsynchronized change of the board. + * Sets the eu.mihosoft.freerouting.board to read only for example when running a seperate action thread + * to avoid unsynchronized change of the eu.mihosoft.freerouting.board. */ public void set_board_read_only(boolean p_value) { @@ -84,7 +88,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Return true, if the board is set to read only. + * Return true, if the eu.mihosoft.freerouting.board is set to read only. */ public boolean is_board_read_only() { @@ -101,7 +105,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * returns the number of layers of the board design. + * returns the number of layers of the eu.mihosoft.freerouting.board design. */ public int get_layer_count() { @@ -153,8 +157,8 @@ public class BoardHandling extends BoardHandlingImpl if (edge_to_turn_dist != board.rules.get_pin_edge_to_turn_dist()) { // unfix the pin exit stubs - Collection pin_list = board.get_pins(); - for (board.Pin curr_pin : pin_list) + Collection pin_list = board.get_pins(); + for (eu.mihosoft.freerouting.board.Pin curr_pin : pin_list) { if (curr_pin.has_trace_exit_restrictions()) { @@ -203,7 +207,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Gets the trace half width used in interactive routing for the input net on the input layer. + * Gets the trace half width used in eu.mihosoft.freerouting.interactive routing for the input net on the input layer. */ public int get_trace_halfwidth(int p_net_no, int p_layer) { @@ -220,7 +224,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Returns if p_layer is active for interactive routing of traces. + * Returns if p_layer is active for eu.mihosoft.freerouting.interactive routing of traces. */ public boolean is_active_routing_layer(int p_net_no, int p_layer) { @@ -228,12 +232,12 @@ public class BoardHandling extends BoardHandlingImpl { return true; } - rules.Net curr_net = this.board.rules.nets.get(p_net_no); + eu.mihosoft.freerouting.rules.Net curr_net = this.board.rules.nets.get(p_net_no); if (curr_net == null) { return true; } - rules.NetClass curr_net_class = curr_net.get_class(); + eu.mihosoft.freerouting.rules.NetClass curr_net_class = curr_net.get_class(); if (curr_net_class == null) { return true; @@ -241,7 +245,7 @@ public class BoardHandling extends BoardHandlingImpl return curr_net_class.is_active_routing_layer(p_layer); } - /** Gets the trace clearance class used in interactive routing. */ + /** Gets the trace clearance class used in eu.mihosoft.freerouting.interactive routing. */ public int get_trace_clearance_class(int p_net_no) { int result; @@ -256,10 +260,10 @@ public class BoardHandling extends BoardHandlingImpl return result; } - /** Gets the via rule used in interactive routing. */ - public rules.ViaRule get_via_rule(int p_net_no) + /** Gets the via rule used in eu.mihosoft.freerouting.interactive routing. */ + public eu.mihosoft.freerouting.rules.ViaRule get_via_rule(int p_net_no) { - rules.ViaRule result = null; + eu.mihosoft.freerouting.rules.ViaRule result = null; if (settings.manual_rule_selection) { result = board.rules.via_rules.get(this.settings.manual_via_rule_index); @@ -272,7 +276,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Changes the default trace halfwidth currently used in interactive routing on the input layer. + * Changes the default trace halfwidth currently used in eu.mihosoft.freerouting.interactive routing on the input layer. */ public void set_default_trace_halfwidth(int p_layer, int p_value) { @@ -302,9 +306,9 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Changes the current snap angle in the interactive board handling. + * Changes the current snap angle in the eu.mihosoft.freerouting.interactive eu.mihosoft.freerouting.board handling. */ - public void set_current_snap_angle(board.AngleRestriction p_snap_angle) + public void set_current_snap_angle(eu.mihosoft.freerouting.board.AngleRestriction p_snap_angle) { if (board_is_read_only) { @@ -315,7 +319,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Changes the current layer in the interactive board handling. + * Changes the current layer in the eu.mihosoft.freerouting.interactive eu.mihosoft.freerouting.board handling. */ public void set_current_layer(int p_layer) { @@ -335,7 +339,7 @@ public class BoardHandling extends BoardHandlingImpl */ void set_layer(int p_layer_no) { - board.Layer curr_layer = board.layer_structure.arr[p_layer_no]; + eu.mihosoft.freerouting.board.Layer curr_layer = board.layer_structure.arr[p_layer_no]; screen_messages.set_layer(curr_layer.name); settings.layer = p_layer_no; @@ -363,24 +367,24 @@ public class BoardHandling extends BoardHandlingImpl public void display_layer_messsage() { screen_messages.clear_add_field(); - board.Layer curr_layer = board.layer_structure.arr[this.settings.layer]; + eu.mihosoft.freerouting.board.Layer curr_layer = board.layer_structure.arr[this.settings.layer]; screen_messages.set_layer(curr_layer.name); } /** - * Sets the manual trace half width used in interactive routing. + * Sets the manual trace half width used in eu.mihosoft.freerouting.interactive routing. * If p_layer_no < 0, the manual trace half width is changed on all layers. */ public void set_manual_trace_half_width(int p_layer_no, int p_value) { - if (p_layer_no == gui.ComboBoxLayer.ALL_LAYER_INDEX) + if (p_layer_no == ComboBoxLayer.ALL_LAYER_INDEX) { for (int i = 0; i < settings.manual_trace_half_width_arr.length; ++i) { this.settings.set_manual_trace_half_width(i, p_value); } } - else if (p_layer_no == gui.ComboBoxLayer.INNER_LAYER_INDEX) + else if (p_layer_no == ComboBoxLayer.INNER_LAYER_INDEX) { for (int i = 1; i < settings.manual_trace_half_width_arr.length - 1; ++i) { @@ -394,7 +398,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Changes the interactive selectability of p_item_type. + * Changes the eu.mihosoft.freerouting.interactive selectability of p_item_type. */ public void set_selectable(ItemSelectionFilter.SelectableChoices p_item_type, boolean p_value) { @@ -562,21 +566,21 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Creates the Routingboard, the graphic context and the interactive settings. + * Creates the Routingboard, the graphic context and the eu.mihosoft.freerouting.interactive settings. */ @Override public void create_board(IntBox p_bounding_box, LayerStructure p_layer_structure, PolylineShape[] p_outline_shapes, String p_outline_clearance_class_name, - BoardRules p_rules, board.Communication p_board_communication, TestLevel p_test_level) + BoardRules p_rules, eu.mihosoft.freerouting.board.Communication p_board_communication, TestLevel p_test_level) { super.create_board(p_bounding_box, p_layer_structure, p_outline_shapes, p_outline_clearance_class_name, p_rules, p_board_communication, p_test_level); - // create the interactive settings with default + // create the eu.mihosoft.freerouting.interactive settings with default double unit_factor = p_board_communication.coordinate_transform.board_to_dsn(1); this.coordinate_transform = new CoordinateTransform(1, p_board_communication.unit, unit_factor, p_board_communication.unit); - // create a graphics context for the board + // create a graphics context for the eu.mihosoft.freerouting.board Dimension panel_size = panel.getPreferredSize(); graphics_context = new GraphicsContext(p_bounding_box, panel_size, p_layer_structure, this.locale); } @@ -604,7 +608,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * From here on the interactive actions are written to a logfile. + * From here on the eu.mihosoft.freerouting.interactive actions are written to a logfile. */ public void start_logfile(File p_filename) { @@ -616,7 +620,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Repaints the board panel on the screen. + * Repaints the eu.mihosoft.freerouting.board panel on the screen. */ public void repaint() { @@ -632,7 +636,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Repaints a rectangle of board panel on the screen. + * Repaints a rectangle of eu.mihosoft.freerouting.board panel on the screen. */ public void repaint(Rectangle p_rect) { @@ -647,15 +651,15 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Gets the panel for graphical display of the board. + * Gets the panel for graphical display of the eu.mihosoft.freerouting.board. */ - gui.BoardPanel get_panel() + BoardPanel get_panel() { return this.panel; } /** - * Gets the popup menu used in the current interactive state. + * Gets the popup menu used in the current eu.mihosoft.freerouting.interactive state. * Returns null, if the current state uses no popup menu. */ public javax.swing.JPopupMenu get_current_popup_menu() @@ -673,8 +677,8 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Draws the board and all temporary construction graphics in the - * current interactive state. + * Draws the eu.mihosoft.freerouting.board and all temporary construction graphics in the + * current eu.mihosoft.freerouting.interactive state. */ public void draw(Graphics p_graphics) { @@ -771,7 +775,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state * when the left mouse butten is clicked. */ public void left_button_clicked(Point2D p_point) @@ -780,7 +784,7 @@ public class BoardHandling extends BoardHandlingImpl { if (this.interactive_action_thread != null) { - // The left button is used to stop the interactive action thread. + // The left button is used to stop the eu.mihosoft.freerouting.interactive action thread. this.interactive_action_thread.request_stop(); } return; @@ -800,14 +804,14 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state * when the mouse pointer has moved. */ public void mouse_moved(Point2D p_point) { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } if (interactive_state != null && graphics_context != null) @@ -816,7 +820,7 @@ public class BoardHandling extends BoardHandlingImpl graphics_context.coordinate_transform.screen_to_board(p_point); InteractiveState return_state = interactive_state.mouse_moved(); // An automatic repaint here would slow down the display - // performance in interactive route. + // performance in eu.mihosoft.freerouting.interactive route. // If a repaint is necessary, it should be done in the individual mouse_moved // method of the class derived from InteractiveState if (return_state != this.interactive_state) @@ -841,7 +845,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state * when the mouse is dragged. */ public void mouse_dragged(Point2D p_point) @@ -861,7 +865,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state * when a mouse button is released. */ public void button_released() @@ -878,7 +882,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state * when the mouse wheel is moved */ public void mouse_wheel_moved(int p_rotation) @@ -895,14 +899,14 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Action to be taken in the current interactive state + * Action to be taken in the current eu.mihosoft.freerouting.interactive state * when a key on the keyboard is typed. */ public void key_typed_action(char p_key_char) { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } InteractiveState return_state = interactive_state.key_typed(p_key_char); @@ -916,14 +920,14 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Completes the curreent interactive state and returns to + * Completes the curreent eu.mihosoft.freerouting.interactive state and returns to * its return state. */ public void return_from_state() { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } @@ -938,13 +942,13 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Cancels the current interactive state. + * Cancels the current eu.mihosoft.freerouting.interactive state. */ public void cancel_state() { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } @@ -959,8 +963,8 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Actions to be taken in the current interactive state when - * the current board layer is changed. + * Actions to be taken in the current eu.mihosoft.freerouting.interactive state when + * the current eu.mihosoft.freerouting.board layer is changed. * Returns false, if the layer change failed. */ public boolean change_layer_action(int p_new_layer) @@ -974,7 +978,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Sets the interactive state to SelectMenuState + * Sets the eu.mihosoft.freerouting.interactive state to SelectMenuState */ public void set_select_menu_state() { @@ -983,7 +987,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Sets the interactive state to RouteMenuState + * Sets the eu.mihosoft.freerouting.interactive state to RouteMenuState */ public void set_route_menu_state() { @@ -992,7 +996,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Sets the interactive state to DragMenuState + * Sets the eu.mihosoft.freerouting.interactive state to DragMenuState */ public void set_drag_menu_state() { @@ -1001,8 +1005,8 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Reads an existing board design from the input stream. - * Returns false, if the input stream does not contains a legal board design. + * Reads an existing eu.mihosoft.freerouting.board design from the input stream. + * Returns false, if the input stream does not contains a legal eu.mihosoft.freerouting.board design. */ public boolean read_design(java.io.ObjectInputStream p_design, TestLevel p_test_level) { @@ -1024,14 +1028,14 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Imports a board design from a Specctra dsn-file. + * Imports a eu.mihosoft.freerouting.board design from a Specctra dsn-file. * The parameters p_item_observers and p_item_id_no_generator are used, - * in case the board is embedded into a host system. + * in case the eu.mihosoft.freerouting.board is embedded into a host system. * Returns false, if the dsn-file is currupted. */ public DsnFile.ReadResult import_design(java.io.InputStream p_design, - board.BoardObservers p_observers, - datastructures.IdNoGenerator p_item_id_no_generator, TestLevel p_test_level) + eu.mihosoft.freerouting.board.BoardObservers p_observers, + eu.mihosoft.freerouting.datastructures.IdNoGenerator p_item_id_no_generator, TestLevel p_test_level) { if (p_design == null) { @@ -1073,7 +1077,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Writes the currently edited board design to a text file in the Specctra dsn format. + * Writes the currently edited eu.mihosoft.freerouting.board design to a text file in the Specctra dsn format. * If p_compat_mode is true, only standard speecctra dsn scopes are written, so that any * host system with an specctra interface can read them. */ @@ -1083,7 +1087,7 @@ public class BoardHandling extends BoardHandlingImpl { return false; } - return designformats.specctra.DsnFile.write(this, p_output_stream, p_design_name, p_compat_mode); + return DsnFile.write(this, p_output_stream, p_design_name, p_compat_mode); } /** @@ -1095,7 +1099,7 @@ public class BoardHandling extends BoardHandlingImpl { return false; } - return designformats.specctra.SessionToEagle.get_instance(p_input_stream, p_output_stream, this.board); + return SessionToEagle.get_instance(p_input_stream, p_output_stream, this.board); } /** @@ -1107,11 +1111,11 @@ public class BoardHandling extends BoardHandlingImpl { return false; } - return designformats.specctra.SessionFile.write(this.get_routing_board(), p_output_stream, p_design_name); + return SessionFile.write(this.get_routing_board(), p_output_stream, p_design_name); } /** - * Saves the currently edited board design to p_design_file. + * Saves the currently edited eu.mihosoft.freerouting.board design to p_design_file. */ public boolean save_design_file(java.io.ObjectOutputStream p_object_stream) { @@ -1156,13 +1160,13 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Starts interactive routing at the input location. + * Starts eu.mihosoft.freerouting.interactive routing at the input location. */ public void start_route(Point2D p_point) { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } FloatPoint location = @@ -1172,7 +1176,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Selects board items at the input location. + * Selects eu.mihosoft.freerouting.board items at the input location. */ public void select_items(Point2D p_point) { @@ -1188,7 +1192,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Selects all items in an interactive defined rectangle. + * Selects all items in an eu.mihosoft.freerouting.interactive defined rectangle. */ public void select_items_in_region() { @@ -1206,7 +1210,7 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } this.display_layer_messsage(); @@ -1534,7 +1538,7 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only || !(interactive_state instanceof MoveItemState)) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } ((MoveItemState) interactive_state).turn_45_degree(p_factor); @@ -1544,14 +1548,14 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only || !(interactive_state instanceof MoveItemState)) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } ((MoveItemState) interactive_state).change_placement_side(); } /** - * Zooms display to an interactive defined rectangle. + * Zooms display to an eu.mihosoft.freerouting.interactive defined rectangle. */ public void zoom_region() { @@ -1565,7 +1569,7 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } FloatPoint location = graphics_context.coordinate_transform.screen_to_board(p_point); @@ -1579,7 +1583,7 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } FloatPoint location = graphics_context.coordinate_transform.screen_to_board(p_point); @@ -1593,7 +1597,7 @@ public class BoardHandling extends BoardHandlingImpl { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } FloatPoint location = graphics_context.coordinate_transform.screen_to_board(p_point); @@ -1603,13 +1607,13 @@ public class BoardHandling extends BoardHandlingImpl /** * Actions to be taken, when adding a hole to an existing obstacle shape - * on the board is started. + * on the eu.mihosoft.freerouting.board is started. */ public void start_adding_hole(Point2D p_point) { if (board_is_read_only) { - // no interactive action when logfile is running + // no eu.mihosoft.freerouting.interactive action when logfile is running return; } FloatPoint location = graphics_context.coordinate_transform.screen_to_board(p_point); @@ -1620,7 +1624,7 @@ public class BoardHandling extends BoardHandlingImpl /** * Gets a surrounding rectangle of the area, where an update of the - * graphics is needed caused by the previous interactive actions. + * graphics is needed caused by the previous eu.mihosoft.freerouting.interactive actions. */ Rectangle get_graphics_update_rectangle() { @@ -1639,7 +1643,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Gets all items at p_location on the active board layer. + * Gets all items at p_location on the active eu.mihosoft.freerouting.board layer. * If nothing is found on the active layer and settings.select_on_all_layers * is true, all layers are selected. */ @@ -1649,7 +1653,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Gets all items at p_location on the active board layer with the inputt item filter. + * Gets all items at p_location on the active eu.mihosoft.freerouting.board layer with the inputt item filter. * If nothing is found on the active layer and settings.select_on_all_layers * is true, all layers are selected. */ @@ -1683,7 +1687,7 @@ public class BoardHandling extends BoardHandlingImpl } /** - * Gets the current interactive state. + * Gets the current eu.mihosoft.freerouting.interactive state. */ public InteractiveState get_interactive_state() { @@ -1705,7 +1709,7 @@ public class BoardHandling extends BoardHandlingImpl /** * Adjust the design bounds, so that also all items being still placed outside the - * board outline are contained in the new bounds. + * eu.mihosoft.freerouting.board outline are contained in the new bounds. */ public void adjust_design_bounds() { @@ -1737,34 +1741,34 @@ public class BoardHandling extends BoardHandlingImpl clearance_violations = null; board = null; } - /** The graphical context for drawing the board. */ + /** The graphical context for drawing the eu.mihosoft.freerouting.board. */ public GraphicsContext graphics_context = null; - /** For ransforming coordinates between the user and the board coordinate space */ + /** For ransforming coordinates between the user and the eu.mihosoft.freerouting.board coordinate space */ public CoordinateTransform coordinate_transform = null; /** The text message fields displayed on the screen */ public final ScreenMessages screen_messages; - /** The currently active interactive state. */ + /** The currently active eu.mihosoft.freerouting.interactive state. */ InteractiveState interactive_state = null; /** - * Used for running an interactive action in a seperate thread. + * Used for running an eu.mihosoft.freerouting.interactive action in a seperate thread. */ private InteractiveActionThread interactive_action_thread = null; /** To display all incomplete connections on the screen. */ private RatsNest ratsnest = null; /** To display all clearance violations between items on the screen. */ private ClearanceViolations clearance_violations = null; - /** The graphical panel used for displaying the board. */ - private final gui.BoardPanel panel; + /** The graphical panel used for displaying the eu.mihosoft.freerouting.board. */ + private final BoardPanel panel; /** * True if currently a logfile is being processed. - * Used to prevent interactive changes of the board database + * Used to prevent eu.mihosoft.freerouting.interactive changes of the eu.mihosoft.freerouting.board database * in this case. */ private boolean board_is_read_only = false; /** The current position of the mouse pointer. */ private FloatPoint current_mouse_position = null; /** - * To repaint the board immediately for example when reading a logfile. + * To repaint the eu.mihosoft.freerouting.board immediately for example when reading a logfile. */ boolean paint_immediately = false; private final java.util.ResourceBundle resources; diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandlingImpl.java b/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandlingImpl.java index 58b4a73..3ffca66 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandlingImpl.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/BoardHandlingImpl.java @@ -1,12 +1,12 @@ -package interactive; +package eu.mihosoft.freerouting.interactive; -import board.Communication; -import board.LayerStructure; -import board.RoutingBoard; -import board.TestLevel; -import geometry.planar.IntBox; -import geometry.planar.PolylineShape; -import rules.BoardRules; +import eu.mihosoft.freerouting.board.Communication; +import eu.mihosoft.freerouting.board.LayerStructure; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.TestLevel; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.rules.BoardRules; import java.util.Locale; @@ -18,20 +18,20 @@ import java.util.Locale; */ public class BoardHandlingImpl implements IBoardHandling { /** - * The file used for logging interactive action, + * The file used for logging eu.mihosoft.freerouting.interactive action, * so that they can be replayed later */ public final Logfile logfile = new Logfile(); - /** The current settings for interactive actions on the board*/ + /** The current settings for eu.mihosoft.freerouting.interactive actions on the eu.mihosoft.freerouting.board*/ public Settings settings = null; - /** The board database used in this interactive handling. */ + /** The eu.mihosoft.freerouting.board database used in this eu.mihosoft.freerouting.interactive handling. */ protected RoutingBoard board = null; public BoardHandlingImpl() { } /** - * Gets the routing board of this board handling. + * Gets the routing eu.mihosoft.freerouting.board of this eu.mihosoft.freerouting.board handling. */ @Override public RoutingBoard get_routing_board() @@ -45,7 +45,7 @@ public class BoardHandlingImpl implements IBoardHandling { } /** - * Initializes the manual trace widths from the default trace widths in the board rules. + * Initializes the manual trace widths from the default trace widths in the eu.mihosoft.freerouting.board rules. */ @Override public void initialize_manual_trace_half_widths() @@ -60,7 +60,7 @@ public class BoardHandlingImpl implements IBoardHandling { public void create_board(IntBox p_bounding_box, LayerStructure p_layer_structure, PolylineShape[] p_outline_shapes, String p_outline_clearance_class_name, BoardRules p_rules, Communication p_board_communication, TestLevel p_test_level) { if (this.board != null) { - System.out.println(" BoardHandling.create_board: board already created"); + System.out.println(" BoardHandling.create_board: eu.mihosoft.freerouting.board already created"); } int outline_cl_class_no = 0; @@ -74,7 +74,7 @@ public class BoardHandlingImpl implements IBoardHandling { else { outline_cl_class_no = - p_rules.get_default_net_class().default_item_clearance_classes.get(rules.DefaultItemClearanceClasses.ItemClass.AREA); + p_rules.get_default_net_class().default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.AREA); } } this.board = diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/CircleConstructionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/CircleConstructionState.java index 9603921..f9cbee9 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/CircleConstructionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/CircleConstructionState.java @@ -18,18 +18,18 @@ * Created on 6. November 2003, 09:37 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.Circle; -import geometry.planar.ConvexShape; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Circle; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; -import rules.BoardRules; +import eu.mihosoft.freerouting.rules.BoardRules; -import board.AngleRestriction; -import board.RoutingBoard; -import board.FixedState; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.FixedState; /** * Interactive creation of a circle obstacle diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/ClearanceViolations.java b/src/main/java/eu/mihosoft/freerouting/interactive/ClearanceViolations.java index 8fe90d6..2a91328 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/ClearanceViolations.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/ClearanceViolations.java @@ -18,7 +18,7 @@ * Created on 3. Oktober 2004, 09:13 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Collection; import java.util.LinkedList; @@ -27,10 +27,10 @@ import java.util.Iterator; import java.awt.Graphics; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; -import board.Item; -import board.ClearanceViolation; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ClearanceViolation; /** * To display the clearance violations between items on the screen. diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/CopyItemState.java b/src/main/java/eu/mihosoft/freerouting/interactive/CopyItemState.java index dd844a2..3789702 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/CopyItemState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/CopyItemState.java @@ -18,12 +18,12 @@ * Created on 11. November 2003, 08:23 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.Point; -import geometry.planar.Vector; -import geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; import java.util.Collection; import java.util.Iterator; @@ -31,15 +31,15 @@ import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; -import library.Padstack; -import library.Package; +import eu.mihosoft.freerouting.library.Padstack; +import eu.mihosoft.freerouting.library.Package; -import board.Item; -import board.DrillItem; -import board.ObstacleArea; -import board.Via; -import board.Component; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.ObstacleArea; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.Component; +import eu.mihosoft.freerouting.board.RoutingBoard; /** * Interactive copying of items. @@ -106,10 +106,10 @@ public class CopyItemState extends InteractiveState if (!current_position.equals(previous_position)) { Vector translate_vector = current_position.difference_by(previous_position); - Iterator it = item_list.iterator(); + Iterator it = item_list.iterator(); while (it.hasNext()) { - board.Item curr_item = it.next(); + eu.mihosoft.freerouting.board.Item curr_item = it.next(); curr_item.translate_by(translate_vector); } previous_position = current_position; @@ -133,7 +133,7 @@ public class CopyItemState extends InteractiveState } /** - * Inserts the items in the copy list into the board. + * Inserts the items in the copy list into the eu.mihosoft.freerouting.board. * Items, which would produce a clearance violation, are not inserted. */ public void insert() diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/CornerItemConstructionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/CornerItemConstructionState.java index 613de87..aba2db2 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/CornerItemConstructionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/CornerItemConstructionState.java @@ -18,11 +18,11 @@ * Created on 7. November 2003, 09:26 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import board.AngleRestriction; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.board.AngleRestriction; /** * Common class for constructing an obstacle with a polygonal shape. diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/CutoutRouteState.java b/src/main/java/eu/mihosoft/freerouting/interactive/CutoutRouteState.java index 1936185..05ae6ed 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/CutoutRouteState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/CutoutRouteState.java @@ -19,19 +19,19 @@ * */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Collection; import java.util.LinkedList; import java.util.Set; import java.util.TreeSet; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; -import board.Item; -import board.PolylineTrace; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.PolylineTrace; /** * @@ -121,7 +121,7 @@ public class CutoutRouteState extends SelectRegionState for (PolylineTrace curr_trace : this.trace_list) { - board.ShapeTraceEntries.cutout_trace(curr_trace, cut_box, 0); + eu.mihosoft.freerouting.board.ShapeTraceEntries.cutout_trace(curr_trace, cut_box, 0); for (int i = 0; i < curr_trace.net_count(); ++i) { changed_nets.add(curr_trace.get_net_no(i)); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/DragItemState.java b/src/main/java/eu/mihosoft/freerouting/interactive/DragItemState.java index 66b914a..07b9143 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/DragItemState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/DragItemState.java @@ -18,22 +18,22 @@ * Created on 9. November 2003, 08:13 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Collection; import java.util.Set; import java.util.TreeSet; import java.util.Iterator; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Vector; -import board.AngleRestriction; -import board.Item; -import board.MoveComponent; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.MoveComponent; /** - * Class for interactive dragging items with the mouse on a routing board + * Class for eu.mihosoft.freerouting.interactive dragging items with the mouse on a routing eu.mihosoft.freerouting.board * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/DragMenuState.java b/src/main/java/eu/mihosoft/freerouting/interactive/DragMenuState.java index 3aefd97..591a350 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/DragMenuState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/DragMenuState.java @@ -18,9 +18,9 @@ * Created on 4. November 2004, 11:14 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** * Class implementing the different functionality in the drag menu diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/DragState.java b/src/main/java/eu/mihosoft/freerouting/interactive/DragState.java index c584925..7860ae0 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/DragState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/DragState.java @@ -18,18 +18,18 @@ * Created on 10. Dezember 2003, 09:08 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.util.Iterator; -import board.Trace; -import board.DrillItem; -import board.Item; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.Item; /** - * Class implementing functionality when the mouse is dragged on a routing board + * Class implementing functionality when the mouse is dragged on a routing eu.mihosoft.freerouting.board * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/DynamicRouteState.java b/src/main/java/eu/mihosoft/freerouting/interactive/DynamicRouteState.java index aebbdc7..9e45fb2 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/DynamicRouteState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/DynamicRouteState.java @@ -18,12 +18,12 @@ * Created on 8. Dezember 2003, 10:00 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** - * State for dynamic interactive routing, which is routing while moving the mouse pointer. + * State for dynamic eu.mihosoft.freerouting.interactive routing, which is routing while moving the mouse pointer. * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/ExpandTestState.java b/src/main/java/eu/mihosoft/freerouting/interactive/ExpandTestState.java index 6dacb24..203b807 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/ExpandTestState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/ExpandTestState.java @@ -17,10 +17,10 @@ * * Created on 23. Dezember 2003, 07:56 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Set; @@ -28,16 +28,16 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.Iterator; -import autoroute.AutorouteControl; -import autoroute.CompleteFreeSpaceExpansionRoom; -import autoroute.IncompleteFreeSpaceExpansionRoom; -import autoroute.InsertFoundConnectionAlgo; -import autoroute.LocateFoundConnectionAlgo; -import autoroute.MazeSearchAlgo; -import autoroute.AutorouteEngine; +import eu.mihosoft.freerouting.autoroute.AutorouteControl; +import eu.mihosoft.freerouting.autoroute.CompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.IncompleteFreeSpaceExpansionRoom; +import eu.mihosoft.freerouting.autoroute.InsertFoundConnectionAlgo; +import eu.mihosoft.freerouting.autoroute.LocateFoundConnectionAlgo; +import eu.mihosoft.freerouting.autoroute.MazeSearchAlgo; +import eu.mihosoft.freerouting.autoroute.AutorouteEngine; -import board.Item; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.RoutingBoard; /** * State for testing the expanding algorithm of the autorouter. @@ -178,7 +178,7 @@ public class ExpandTestState extends InteractiveState private void init(FloatPoint p_location) { - // look if an autoroute can be started at the input location + // look if an eu.mihosoft.freerouting.autoroute can be started at the input location RoutingBoard board = hdlg.get_routing_board(); int layer = hdlg.settings.layer; Collection found_items = board.pick_items(p_location.round(), layer, null); @@ -188,7 +188,7 @@ public class ExpandTestState extends InteractiveState while (it.hasNext()) { Item curr_ob = it.next(); - if (curr_ob instanceof board.Connectable) + if (curr_ob instanceof eu.mihosoft.freerouting.board.Connectable) { Item curr_item = curr_ob; if (curr_item.net_count() == 1 && curr_item.get_net_no(0) > 0) @@ -221,7 +221,7 @@ public class ExpandTestState extends InteractiveState Set route_dest_set = route_item.get_unconnected_set(route_net_no); if (route_dest_set.size() > 0) { - hdlg.screen_messages.set_status_message("autoroute test started"); + hdlg.screen_messages.set_status_message("eu.mihosoft.freerouting.autoroute test started"); this.maze_search_algo = MazeSearchAlgo.get_instance(route_start_set, route_dest_set, autoroute_engine, control_settings); this.in_autoroute = (this.maze_search_algo != null); @@ -238,7 +238,7 @@ public class ExpandTestState extends InteractiveState LocateFoundConnectionAlgo.get_instance(search_result, control_settings, this.autoroute_engine.autoroute_search_tree, hdlg.get_routing_board().rules.get_trace_angle_restriction(), - ripped_item_list, board.TestLevel.ALL_DEBUGGING_OUTPUT); + ripped_item_list, eu.mihosoft.freerouting.board.TestLevel.ALL_DEBUGGING_OUTPUT); hdlg.get_routing_board().generate_snapshot(); SortedSet ripped_connections = new TreeSet(); for (Item curr_ripped_item : ripped_item_list) diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/HoleConstructionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/HoleConstructionState.java index 20b01f3..f33b875 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/HoleConstructionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/HoleConstructionState.java @@ -18,21 +18,21 @@ * Created on 7. November 2003, 18:40 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.Area; -import geometry.planar.Circle; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.PolygonShape; -import geometry.planar.PolylineArea; -import geometry.planar.PolylineShape; -import geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Circle; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.PolygonShape; +import eu.mihosoft.freerouting.geometry.planar.PolylineArea; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.geometry.planar.Shape; import java.util.Iterator; -import board.ObstacleArea; -import board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.ObstacleArea; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; /** * Interactive cutting a hole into an obstacle shape @@ -75,14 +75,14 @@ public class HoleConstructionState extends CornerItemConstructionState ItemSelectionFilter.SelectableChoices.CONDUCTION }; ItemSelectionFilter selection_filter = new ItemSelectionFilter(selectable_choices); - java.util.Collection found_items = hdlg.get_routing_board().pick_items(pick_location, + java.util.Collection found_items = hdlg.get_routing_board().pick_items(pick_location, hdlg.settings.layer, selection_filter); if (found_items.size() != 1) { hdlg.screen_messages.set_status_message(resources.getString("no_item_found_for_adding_hole")); return false; } - board.Item found_item = found_items.iterator().next(); + eu.mihosoft.freerouting.board.Item found_item = found_items.iterator().next(); if (!(found_item instanceof ObstacleArea)) { hdlg.screen_messages.set_status_message(resources.getString("no_obstacle_area_found_for_adding_hole")); @@ -183,7 +183,7 @@ public class HoleConstructionState extends CornerItemConstructionState hdlg.get_routing_board().generate_snapshot(); hdlg.get_routing_board().remove_item( item_to_modify); hdlg.get_routing_board().insert_obstacle(new_obs_area, item_to_modify.get_layer(), - item_to_modify.clearance_class_no(), board.FixedState.UNFIXED); + item_to_modify.clearance_class_no(), eu.mihosoft.freerouting.board.FixedState.UNFIXED); if (this.observers_activated) { hdlg.get_routing_board().end_notify_observers(); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/IBoardHandling.java b/src/main/java/eu/mihosoft/freerouting/interactive/IBoardHandling.java index eee280c..615325b 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/IBoardHandling.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/IBoardHandling.java @@ -1,11 +1,11 @@ -package interactive; +package eu.mihosoft.freerouting.interactive; -import board.LayerStructure; -import board.RoutingBoard; -import board.TestLevel; -import geometry.planar.IntBox; -import geometry.planar.PolylineShape; -import rules.BoardRules; +import eu.mihosoft.freerouting.board.LayerStructure; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.TestLevel; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.PolylineShape; +import eu.mihosoft.freerouting.rules.BoardRules; /** * Andrey Belomutskiy @@ -20,7 +20,7 @@ public interface IBoardHandling { void create_board(IntBox p_bounding_box, LayerStructure p_layer_structure, PolylineShape[] p_outline_shapes, String p_outline_clearance_class_name, - BoardRules p_rules, board.Communication p_board_communication, TestLevel p_test_level); + BoardRules p_rules, eu.mihosoft.freerouting.board.Communication p_board_communication, TestLevel p_test_level); Settings get_settings(); } diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveActionThread.java b/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveActionThread.java index 2637768..362f479 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveActionThread.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveActionThread.java @@ -18,15 +18,15 @@ * Created on 2. Maerz 2006, 07:23 * */ -package interactive; +package eu.mihosoft.freerouting.interactive; /** - * Used for running an interactive action in a seperate Thread, + * Used for running an eu.mihosoft.freerouting.interactive action in a seperate Thread, * that can be stopped by the user. * * @author Alfons Wirtz */ -public abstract class InteractiveActionThread extends Thread implements datastructures.Stoppable +public abstract class InteractiveActionThread extends Thread implements eu.mihosoft.freerouting.datastructures.Stoppable { public static InteractiveActionThread get_autoroute_instance(BoardHandling p_board_handling) @@ -155,7 +155,7 @@ public abstract class InteractiveActionThread extends Thread implements datastru { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", hdlg.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", hdlg.get_locale()); boolean saved_board_read_only = hdlg.is_board_read_only(); hdlg.set_board_read_only(true); String start_message = resources.getString("logfile") + " " + resources.getString("stop_message"); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveState.java b/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveState.java index 5cab9b7..72dd80c 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/InteractiveState.java @@ -18,9 +18,9 @@ * Created on 5. November 2003, 12:55 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.awt.Graphics; @@ -39,7 +39,7 @@ public class InteractiveState this.hdlg = p_board_handling; this.logfile = p_logfile; this.resources = - java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", p_board_handling.get_locale()); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", p_board_handling.get_locale()); } /** @@ -174,7 +174,7 @@ public class InteractiveState else if (Character.isDigit(p_key_char)) { // change the current layer to the p_key_char-ths signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int d = Character.digit(p_key_char, 10); d = Math.min(d, layer_structure.signal_layer_count()); // Board layers start at 0, keyboard input for layers starts at 1. @@ -250,7 +250,7 @@ public class InteractiveState /** - * Returns the popup menu from board_panel, which is used in this interactive state. + * Returns the popup menu from board_panel, which is used in this eu.mihosoft.freerouting.interactive state. * Default function to be overwritten in derived classes. */ public javax.swing.JPopupMenu get_popup_menu() @@ -264,13 +264,13 @@ public class InteractiveState { } - /** board setting access handler for the derived classes */ + /** eu.mihosoft.freerouting.board setting access handler for the derived classes */ protected final BoardHandling hdlg; /** The intended state after this state is finished */ protected InteractiveState return_state; - /** if logfile != null, the interactive actions are stored in a logfile */ + /** if logfile != null, the eu.mihosoft.freerouting.interactive actions are stored in a logfile */ protected final Logfile logfile; /** Contains the files with the language dependent messages */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/Logfile.java b/src/main/java/eu/mihosoft/freerouting/interactive/Logfile.java index 289955e..5679ea7 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/Logfile.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/Logfile.java @@ -14,9 +14,9 @@ * for more details. */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.io.File; import java.io.FileWriter; @@ -24,7 +24,7 @@ import java.io.IOException; import java.io.InputStream; /** - * Logfile to track the actions in the interactive board handling + * Logfile to track the actions in the eu.mihosoft.freerouting.interactive eu.mihosoft.freerouting.board handling * for automatic replay. * * @author Alfons Wirtz diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileDescription.flex b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileDescription.flex index 7edd119..52b4ef7 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileDescription.flex +++ b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileDescription.flex @@ -1,4 +1,4 @@ -package interactive; +package eu.mihosoft.freerouting.interactive; @SuppressWarnings("all") %% diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScanner.java b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScanner.java index 9b9d901..b24d086 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScanner.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScanner.java @@ -1,13 +1,13 @@ /* The following code was generated by JFlex 1.4 on 06.07.05 18:12 */ -package interactive; +package eu.mihosoft.freerouting.interactive; @SuppressWarnings("all") /** * This class is a scanner generated by * JFlex 1.4 * on 06.07.05 18:12 from the specification file - * C:/Dokumente und Einstellungen/alfons/Eigene Dateien/freeroute/interactive/LogfileDescription.flex + * C:/Dokumente und Einstellungen/alfons/Eigene Dateien/freeroute/eu.mihosoft.freerouting.interactive/LogfileDescription.flex */ class LogfileScanner { diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScope.java b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScope.java index d2bdb26..3f4d21f 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScope.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/LogfileScope.java @@ -18,9 +18,9 @@ * Created on 12. November 2003, 11:10 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** @@ -40,7 +40,7 @@ public abstract class LogfileScope public static final LogfileScope REDO = new RedoScope("redo"); public static final LogfileScope GENERATE_SNAPSHOT = new GenerateSnapshotScope("generate_snapshot"); - // Scopes for logging changes in the interactive setting: + // Scopes for logging changes in the eu.mihosoft.freerouting.interactive setting: public static final LogfileScope SET_CLEARANCE_COMPENSATION = new SetClearanceCompensationScope("set_clearance_compensation"); public static final LogfileScope SET_DRAG_COMPONENTS_ENABLED = new SetDragComponentsEnabledScope("set_drag_componente_enabled"); public static final LogfileScope SET_LAYER = new SetLayerScope("set_layer"); @@ -78,7 +78,7 @@ public abstract class LogfileScope public static final LogfileScope AUTOROUTE_SELECTED = new AutorouteSelectedScope("autoroute_selected"); public static final LogfileScope FANOUT_SELECTED = new FanoutSelectedScope("fanout_selected"); - // scopes for logging interactive creating or moving items. + // scopes for logging eu.mihosoft.freerouting.interactive creating or moving items. public static final LogfileScope COMPLETE_SCOPE = new CompleteScope("complete_scope"); public static final LogfileScope CANCEL_SCOPE = new CancelScope("cancel_scope"); public static final LogfileScope CREATING_TILE = new CreateTileScope("creating_tile"); @@ -126,7 +126,7 @@ public abstract class LogfileScope /** * Reads the scope from the input logfile. - * Returns the active interactive state after reading the scope. + * Returns the active eu.mihosoft.freerouting.interactive state after reading the scope. */ public abstract InteractiveState read_scope(Logfile p_logfile, InteractiveState p_return_state, BoardHandling p_board_handling); @@ -175,7 +175,7 @@ public abstract class LogfileScope /** * Reads the next corner list scope togethet with its * interiour scopes (layer change for example) from the input logfile. - * Returns the active interactive state after reading the scope. + * Returns the active eu.mihosoft.freerouting.interactive state after reading the scope. */ public InteractiveState read_scope(Logfile p_logfile, InteractiveState p_return_state, BoardHandling p_board_handling) @@ -345,7 +345,7 @@ public abstract class LogfileScope InteractiveState result; if (p_return_state instanceof SelectedItemState) { - java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); + java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); result = CopyItemState.get_instance(p_location, item_list, p_return_state.return_state, p_board_handling, null); } else @@ -371,7 +371,7 @@ public abstract class LogfileScope InteractiveState result; if (p_return_state instanceof SelectedItemState) { - java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); + java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); result = MoveItemState.get_instance(p_location, item_list, p_return_state.return_state, p_board_handling, null); } else @@ -602,7 +602,7 @@ public abstract class LogfileScope { System.out.println("CutoutRouteScope.read_scope: electedItemState expected"); } - java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); + java.util.Collection item_list = ((SelectedItemState) p_return_state).get_item_list(); FloatPoint lower_left = p_logfile.read_corner(); if (lower_left == null) { @@ -1162,7 +1162,7 @@ public abstract class LogfileScope public InteractiveState read_scope(Logfile p_logfile, InteractiveState p_return_state, BoardHandling p_board_handling) { int new_snap_angle_no = p_logfile.read_int(); - p_board_handling.get_routing_board().rules.set_trace_angle_restriction(board.AngleRestriction.arr[new_snap_angle_no]); + p_board_handling.get_routing_board().rules.set_trace_angle_restriction(eu.mihosoft.freerouting.board.AngleRestriction.arr[new_snap_angle_no]); return p_return_state; } } @@ -1209,7 +1209,7 @@ public abstract class LogfileScope { int item_type_no = p_logfile.read_int(); int selection = p_logfile.read_int(); - board.ItemSelectionFilter.SelectableChoices item_type = board.ItemSelectionFilter.SelectableChoices.values()[item_type_no]; + eu.mihosoft.freerouting.board.ItemSelectionFilter.SelectableChoices item_type = eu.mihosoft.freerouting.board.ItemSelectionFilter.SelectableChoices.values()[item_type_no]; if (selection == 0) { p_board_handling.settings.item_selection_filter.set_selected(item_type, false); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/MakeSpaceState.java b/src/main/java/eu/mihosoft/freerouting/interactive/MakeSpaceState.java index edade1e..ccf8a04 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/MakeSpaceState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/MakeSpaceState.java @@ -18,12 +18,12 @@ * Created on 10. Dezember 2003, 10:53 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.Point; -import board.AngleRestriction; -import board.BasicBoard; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.BasicBoard; /** * Class for shoving items out of a region to make space to insert something else. @@ -48,9 +48,9 @@ public class MakeSpaceState extends DragState layer_active_arr[i] = true; } int [] route_net_no_arr = new int[1]; - route_net_no_arr[0] = rules.Nets.hidden_net_no; + route_net_no_arr[0] = eu.mihosoft.freerouting.rules.Nets.hidden_net_no; route = new Route(p_location.round(), hdlg.settings.layer, shove_trace_width_arr, layer_active_arr, - route_net_no_arr, 0, rules.ViaRule.EMPTY, true, hdlg.settings.trace_pull_tight_region_width, + route_net_no_arr, 0, eu.mihosoft.freerouting.rules.ViaRule.EMPTY, true, hdlg.settings.trace_pull_tight_region_width, hdlg.settings.trace_pull_tight_accuracy, null, null, hdlg.get_routing_board(), false, false, false, hdlg.settings.hilight_routing_obstacle); } @@ -91,7 +91,7 @@ public class MakeSpaceState extends DragState public InteractiveState button_released() { - int delete_net_no = rules.Nets.hidden_net_no; + int delete_net_no = eu.mihosoft.freerouting.rules.Nets.hidden_net_no; BasicBoard board = hdlg.get_routing_board(); board.remove_items(board.get_connectable_items(delete_net_no), false); if (this.observers_activated) diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/MenuState.java b/src/main/java/eu/mihosoft/freerouting/interactive/MenuState.java index 4824ed1..eaf030e 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/MenuState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/MenuState.java @@ -18,15 +18,15 @@ * Created on 28. November 2003, 10:04 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.util.Collection; -import board.Item; -import board.ItemSelectionFilter; -import board.TestLevel; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.TestLevel; /** * Common base class for the main menus, which can be selected in the tool bar. @@ -84,12 +84,12 @@ public class MenuState extends InteractiveState if (picked_items.size() > 0) { Item first_item = picked_items.iterator().next(); - if (!(first_item instanceof board.Pin)) + if (!(first_item instanceof eu.mihosoft.freerouting.board.Pin)) { System.out.println("MenuState.swap_pin: Pin expected"); return this; } - board.Pin selected_pin = (board.Pin) first_item; + eu.mihosoft.freerouting.board.Pin selected_pin = (eu.mihosoft.freerouting.board.Pin) first_item; result = PinSwapState.get_instance(selected_pin, this, hdlg, this.logfile); } else @@ -161,7 +161,7 @@ public class MenuState extends InteractiveState else if (p_key_char == '+') { // increase the current layer to the next signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int current_layer_no = hdlg.settings.layer; for(;;) { @@ -179,7 +179,7 @@ public class MenuState extends InteractiveState else if (p_key_char == '-') { // decrease the current layer to the previous signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int current_layer_no = hdlg.settings.layer; for(;;) { diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/MoveItemState.java b/src/main/java/eu/mihosoft/freerouting/interactive/MoveItemState.java index a6e3af2..0fd170b 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/MoveItemState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/MoveItemState.java @@ -18,25 +18,25 @@ * Created on 11. Mai 2005, 06:34 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Collection; import java.util.LinkedList; import java.util.Set; import java.util.TreeSet; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Vector; -import geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Point; -import library.BoardLibrary; +import eu.mihosoft.freerouting.library.BoardLibrary; -import board.Component; -import board.Item; -import board.Via; -import board.ClearanceViolation; -import board.LayerStructure; +import eu.mihosoft.freerouting.board.Component; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.ClearanceViolation; +import eu.mihosoft.freerouting.board.LayerStructure; /** * @@ -51,7 +51,7 @@ public class MoveItemState extends InteractiveState public static MoveItemState get_instance(FloatPoint p_location, Collection p_item_list, InteractiveState p_parent_state, BoardHandling p_board_handling, Logfile p_logfile) { - java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", p_board_handling.get_locale()); + java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.InteractiveState", p_board_handling.get_locale()); if (p_item_list.isEmpty()) { p_board_handling.screen_messages.set_status_message(resources.getString("move_component_failed_because_no_item_selected")); @@ -60,7 +60,7 @@ public class MoveItemState extends InteractiveState // extend p_item_list to full components Set item_list = new TreeSet(); Set component_list = new TreeSet(); - board.BasicBoard routing_board = p_board_handling.get_routing_board(); + eu.mihosoft.freerouting.board.BasicBoard routing_board = p_board_handling.get_routing_board(); Component grid_snap_component = null; for (Item curr_item : p_item_list) { @@ -117,7 +117,7 @@ public class MoveItemState extends InteractiveState { for (Item curr_contact : contacts) { - if (curr_contact instanceof board.ConductionArea) + if (curr_contact instanceof eu.mihosoft.freerouting.board.ConductionArea) { continue; @@ -187,7 +187,7 @@ public class MoveItemState extends InteractiveState { logfile.start_scope(LogfileScope.MOVE_ITEMS, p_location); } - board.BasicBoard routing_board = hdlg.get_routing_board(); + eu.mihosoft.freerouting.board.BasicBoard routing_board = hdlg.get_routing_board(); this.observers_activated = !hdlg.get_routing_board().observers_active(); if (this.observers_activated) { @@ -264,7 +264,7 @@ public class MoveItemState extends InteractiveState return this; } } - board.BasicBoard routing_board = hdlg.get_routing_board(); + eu.mihosoft.freerouting.board.BasicBoard routing_board = hdlg.get_routing_board(); for (Item curr_item : this.item_list) { routing_board.insert_item(curr_item); @@ -330,7 +330,7 @@ public class MoveItemState extends InteractiveState { translate_vector = adjust_to_placement_grid(translate_vector); } - board.Components components = hdlg.get_routing_board().components; + eu.mihosoft.freerouting.board.Components components = hdlg.get_routing_board().components; for (Component curr_component : this.component_list) { components.move(curr_component.no, translate_vector); @@ -372,7 +372,7 @@ public class MoveItemState extends InteractiveState { return; } - board.Components components = hdlg.get_routing_board().components; + eu.mihosoft.freerouting.board.Components components = hdlg.get_routing_board().components; for (Component curr_component : this.component_list) { components.turn_90_degree(curr_component.no, p_factor, current_position); @@ -401,7 +401,7 @@ public class MoveItemState extends InteractiveState { return; } - board.Components components = hdlg.get_routing_board().components; + eu.mihosoft.freerouting.board.Components components = hdlg.get_routing_board().components; for (Component curr_component : this.component_list) { components.rotate(curr_component.no, p_angle_in_degree, this.current_position); @@ -478,7 +478,7 @@ public class MoveItemState extends InteractiveState return; } - board.Components components = hdlg.get_routing_board().components; + eu.mihosoft.freerouting.board.Components components = hdlg.get_routing_board().components; for (Component curr_component : this.component_list) { components.change_side(curr_component.no, current_position); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/NetIncompletes.java b/src/main/java/eu/mihosoft/freerouting/interactive/NetIncompletes.java index 0681468..3c2faad 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/NetIncompletes.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/NetIncompletes.java @@ -18,7 +18,7 @@ * Created on 16. Maerz 2004, 06:47 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.awt.Graphics; import java.util.Collection; @@ -27,16 +27,16 @@ import java.util.LinkedList; import java.util.SortedSet; import java.util.TreeSet; -import datastructures.PlanarDelaunayTriangulation; +import eu.mihosoft.freerouting.datastructures.PlanarDelaunayTriangulation; -import geometry.planar.FloatPoint; -import geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; -import rules.Net; +import eu.mihosoft.freerouting.rules.Net; -import board.Item; -import board.BasicBoard; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * Creates the Incompletes (Ratsnest) of one net to display them on the screen. @@ -178,8 +178,8 @@ public class NetIncompletes return; } // draw the length violation around every Pin of the net. - Collection net_pins = this.net.get_pins(); - for (board.Pin curr_pin : net_pins) + Collection net_pins = this.net.get_pins(); + for (eu.mihosoft.freerouting.board.Pin curr_pin : net_pins) { draw_length_violation_marker(curr_pin.get_center().to_float(), this.length_violation, p_graphics, p_graphics_context); } @@ -321,7 +321,7 @@ public class NetIncompletes result = this.to_corner.y - p_other.to_corner.y; } } - return datastructures.Signum.as_int(result); + return eu.mihosoft.freerouting.datastructures.Signum.as_int(result); } } diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/PinSwapState.java b/src/main/java/eu/mihosoft/freerouting/interactive/PinSwapState.java index 73673b3..db19076 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/PinSwapState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/PinSwapState.java @@ -18,13 +18,13 @@ * Created on 28. Maerz 2005, 09:25 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import board.Pin; -import board.Item; -import board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.Pin; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/PolygonShapeConstructionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/PolygonShapeConstructionState.java index cffcd89..2bcae94 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/PolygonShapeConstructionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/PolygonShapeConstructionState.java @@ -18,15 +18,15 @@ * Created on 7. November 2003, 17:19 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.PolygonShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.PolygonShape; import java.util.Iterator; -import rules.BoardRules; +import eu.mihosoft.freerouting.rules.BoardRules; /** * Interactive state for constructing an obstacle with a polygon shape. @@ -56,7 +56,7 @@ public class PolygonShapeConstructionState extends CornerItemConstructionState } /** - * Inserts the polygon shape item into the board, if possible + * Inserts the polygon shape item into the eu.mihosoft.freerouting.board, if possible * and returns to the main state */ public InteractiveState complete() @@ -92,7 +92,7 @@ public class PolygonShapeConstructionState extends CornerItemConstructionState hdlg.get_routing_board().start_notify_observers(); } hdlg.get_routing_board().generate_snapshot(); - hdlg.get_routing_board().insert_obstacle(obstacle_shape, hdlg.settings.layer, cl_class, board.FixedState.UNFIXED); + hdlg.get_routing_board().insert_obstacle(obstacle_shape, hdlg.settings.layer, cl_class, eu.mihosoft.freerouting.board.FixedState.UNFIXED); hdlg.get_routing_board().end_notify_observers(); if (this.observers_activated) { diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/RatsNest.java b/src/main/java/eu/mihosoft/freerouting/interactive/RatsNest.java index cd18122..10f8b36 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/RatsNest.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/RatsNest.java @@ -18,7 +18,7 @@ * Created on 18. Maerz 2004, 07:30 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Collection; import java.util.LinkedList; @@ -27,16 +27,16 @@ import java.util.Vector; import java.awt.Graphics; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; -import rules.Net; +import eu.mihosoft.freerouting.rules.Net; -import board.BasicBoard; -import board.Item; -import board.Connectable; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * Creates all Incompletes (Ratsnest) to display them on the screen @@ -201,7 +201,7 @@ public class RatsNest } /** - * Used for example to hide the incompletes during interactive routiing. + * Used for example to hide the incompletes during eu.mihosoft.freerouting.interactive routiing. */ public boolean is_hidden() { @@ -242,7 +242,7 @@ public class RatsNest /** * Describes a single incomplete connection of the ratsnest. */ - public static class AirLine implements Comparable, board.ObjectInfoPanel.Printable + public static class AirLine implements Comparable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable { AirLine(Net p_net, Item p_from_item, FloatPoint p_from_corner, Item p_to_item, FloatPoint p_to_corner, java.util.Locale p_locale) @@ -270,22 +270,22 @@ public class RatsNest private String item_info(Item p_item) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.RatsNest", this.locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.RatsNest", this.locale); String result; - if (p_item instanceof board.Pin) + if (p_item instanceof eu.mihosoft.freerouting.board.Pin) { - board.Pin curr_pin = (board.Pin) p_item; + eu.mihosoft.freerouting.board.Pin curr_pin = (eu.mihosoft.freerouting.board.Pin) p_item; result = curr_pin.component_name() + ", " + curr_pin.name(); } - else if (p_item instanceof board.Via) + else if (p_item instanceof eu.mihosoft.freerouting.board.Via) { result = resources.getString("via"); } - else if (p_item instanceof board.Trace) + else if (p_item instanceof eu.mihosoft.freerouting.board.Trace) { result = resources.getString("trace"); } - else if (p_item instanceof board.ConductionArea) + else if (p_item instanceof eu.mihosoft.freerouting.board.ConductionArea) { result = resources.getString("conduction_area"); } @@ -296,10 +296,10 @@ public class RatsNest return result; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("interactive.resources.RatsNest", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.RatsNest", p_locale); p_window.append_bold(resources.getString("incomplete")); p_window.append(" " + resources.getString("net") + " "); p_window.append(net.name); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/Route.java b/src/main/java/eu/mihosoft/freerouting/interactive/Route.java index dced98d..aaef2d6 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/Route.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/Route.java @@ -13,19 +13,19 @@ * GNU General Public License at * for more details. */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import datastructures.TimeLimit; +import eu.mihosoft.freerouting.datastructures.TimeLimit; -import geometry.planar.Area; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; -import geometry.planar.IntPoint; -import geometry.planar.Vector; -import geometry.planar.Point; -import geometry.planar.Polyline; -import geometry.planar.Ellipse; +import eu.mihosoft.freerouting.geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.Ellipse; import java.awt.Graphics; import java.util.Collection; @@ -33,28 +33,28 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Set; -import library.Padstack; +import eu.mihosoft.freerouting.library.Padstack; -import rules.ViaRule; -import rules.ViaInfo; -import rules.Net; +import eu.mihosoft.freerouting.rules.ViaRule; +import eu.mihosoft.freerouting.rules.ViaInfo; +import eu.mihosoft.freerouting.rules.Net; -import board.AngleRestriction; -import board.Trace; -import board.ConductionArea; -import board.DrillItem; -import board.Item; -import board.PolylineTrace; -import board.RoutingBoard; -import board.ItemSelectionFilter; -import board.TestLevel; -import board.Unit; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.ConductionArea; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.TestLevel; +import eu.mihosoft.freerouting.board.Unit; -import boardgraphics.GraphicsContext; +import eu.mihosoft.freerouting.boardgraphics.GraphicsContext; /** * - * Functionality for interactive routing. + * Functionality for eu.mihosoft.freerouting.interactive routing. * * @author Alfons Wirtz */ @@ -64,7 +64,7 @@ public class Route /** * Starts routing a connection. * p_pen_half_width_arr is provided because it may be different from - * the half width array in p_board.rules. + * the half width array in p_board.eu.mihosoft.freerouting.rules. */ public Route(Point p_start_corner, int p_layer, int[] p_pen_half_width_arr, boolean[] p_layer_active_arr, int[] p_net_no_arr, int p_clearance_class, ViaRule p_via_rule, boolean p_push_enabled, @@ -170,12 +170,12 @@ public class Route } - // tests.Validate.check("before insert", board); + // eu.mihosoft.freerouting.tests.Validate.check("before insert", eu.mihosoft.freerouting.board); Point ok_point = board.insert_forced_trace_segment(prev_corner, curr_corner, pen_half_width_arr[layer], layer, net_no_arr, clearance_class, max_shove_trace_recursion_depth, max_shove_via_recursion_depth, max_spring_over_recursion_depth, trace_tidy_width, pull_tight_accuracy, !is_stitch_mode, check_forced_trace_time_limit); - // tests.Validate.check("after insert", board); + // eu.mihosoft.freerouting.tests.Validate.check("after insert", eu.mihosoft.freerouting.board); if (ok_point == prev_corner && this.with_neckdown) { ok_point = try_neckdown_at_start(curr_corner); @@ -245,7 +245,7 @@ public class Route } /** - * Changing the layer in interactive route and inserting a via. + * Changing the layer in eu.mihosoft.freerouting.interactive route and inserting a via. * Returns false, if changing the layer was not possible. */ public boolean change_layer(int p_to_layer) @@ -315,12 +315,12 @@ public class Route { ItemSelectionFilter selection_filter = new ItemSelectionFilter(ItemSelectionFilter.SelectableChoices.PINS); java.util.Collection picked_items = board.pick_items(this.prev_corner, p_layer, selection_filter); - board.Pin found_smd_pin = null; + eu.mihosoft.freerouting.board.Pin found_smd_pin = null; for (Item curr_item : picked_items) { - if (curr_item instanceof board.Pin && curr_item.shares_net_no(this.net_no_arr)) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin && curr_item.shares_net_no(this.net_no_arr)) { - board.Pin curr_pin = (board.Pin) curr_item; + eu.mihosoft.freerouting.board.Pin curr_pin = (eu.mihosoft.freerouting.board.Pin) curr_item; if (curr_pin.first_layer() == p_layer && curr_pin.last_layer() == p_layer) { found_smd_pin = curr_pin; @@ -463,10 +463,10 @@ public class Route } for (Item curr_item : this.target_set) { - if (curr_item instanceof board.Pin) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin) { - Collection curr_swapppable_pins = ((board.Pin) curr_item).get_swappable_pins(); - for (board.Pin curr_swappable_pin : curr_swapppable_pins) + Collection curr_swapppable_pins = ((eu.mihosoft.freerouting.board.Pin) curr_item).get_swappable_pins(); + for (eu.mihosoft.freerouting.board.Pin curr_swappable_pin : curr_swapppable_pins) { result.add(new SwapPinInfo(curr_swappable_pin)); } @@ -477,10 +477,10 @@ public class Route java.util.Collection picked_items = board.pick_items(this.prev_corner, this.layer, selection_filter); for (Item curr_item : picked_items) { - if (curr_item instanceof board.Pin) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin) { - Collection curr_swapppable_pins = ((board.Pin) curr_item).get_swappable_pins(); - for (board.Pin curr_swappable_pin : curr_swapppable_pins) + Collection curr_swapppable_pins = ((eu.mihosoft.freerouting.board.Pin) curr_item).get_swappable_pins(); + for (eu.mihosoft.freerouting.board.Pin curr_swappable_pin : curr_swapppable_pins) { result.add(new SwapPinInfo(curr_swappable_pin)); } @@ -549,8 +549,8 @@ public class Route // trace_length_add is != 0 only in stitching mode. if (max_trace_length <= 0) { - // max_trace_length not provided. Create an ellipse containing the whole board. - max_trace_length = 0.3 * geometry.planar.Limits.CRIT_INT; + // max_trace_length not provided. Create an ellipse containing the whole eu.mihosoft.freerouting.board. + max_trace_length = 0.3 * eu.mihosoft.freerouting.geometry.planar.Limits.CRIT_INT; } double curr_max_trace_length = max_trace_length - (curr_net.get_trace_length() + trace_length_add); double curr_min_trace_length = min_trace_length - (curr_net.get_trace_length() + trace_length_add); @@ -772,11 +772,11 @@ public class Route */ private Point try_neckdown_at_start(IntPoint p_to_corner) { - if (!(this.start_item instanceof board.Pin)) + if (!(this.start_item instanceof eu.mihosoft.freerouting.board.Pin)) { return this.prev_corner; } - board.Pin start_pin = (board.Pin) this.start_item; + eu.mihosoft.freerouting.board.Pin start_pin = (eu.mihosoft.freerouting.board.Pin) this.start_item; if (!start_pin.is_on_layer(this.layer)) { return this.prev_corner; @@ -824,11 +824,11 @@ public class Route */ private Point try_neckdown_at_end(Point p_from_corner, Point p_to_corner) { - if (!(this.nearest_target_item instanceof board.Pin)) + if (!(this.nearest_target_item instanceof eu.mihosoft.freerouting.board.Pin)) { return p_from_corner; } - board.Pin target_pin = (board.Pin) this.nearest_target_item; + eu.mihosoft.freerouting.board.Pin target_pin = (eu.mihosoft.freerouting.board.Pin) this.nearest_target_item; if (!target_pin.is_on_layer(this.layer)) { return p_from_corner; @@ -903,7 +903,7 @@ public class Route private class SwapPinInfo implements Comparable { - SwapPinInfo(board.Pin p_pin) + SwapPinInfo(eu.mihosoft.freerouting.board.Pin p_pin) { pin = p_pin; incomplete = null; @@ -932,7 +932,7 @@ public class Route } if (nearest_point != null) { - incomplete = new geometry.planar.FloatLine(pin_center, nearest_point); + incomplete = new eu.mihosoft.freerouting.geometry.planar.FloatLine(pin_center, nearest_point); } } @@ -940,7 +940,7 @@ public class Route { return this.pin.compareTo(p_other.pin); } - final board.Pin pin; - geometry.planar.FloatLine incomplete; + final eu.mihosoft.freerouting.board.Pin pin; + eu.mihosoft.freerouting.geometry.planar.FloatLine incomplete; } } \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/RouteMenuState.java b/src/main/java/eu/mihosoft/freerouting/interactive/RouteMenuState.java index 565be01..6cf7621 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/RouteMenuState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/RouteMenuState.java @@ -18,9 +18,9 @@ * Created on 29. November 2003, 07:50 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** * Class implementing the different functionality in the route menu, diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/RouteState.java b/src/main/java/eu/mihosoft/freerouting/interactive/RouteState.java index 7bbff13..8e00795 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/RouteState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/RouteState.java @@ -17,23 +17,22 @@ * * Created on 8. November 2003, 08:22 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; import java.util.Collection; import java.util.Set; -import board.Trace; -import board.Via; -import board.PolylineTrace; -import board.ConductionArea; -import board.DrillItem; -import board.Item; -import board.RoutingBoard; -import board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.Trace; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.ConductionArea; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; /** * Interactive routing state. @@ -68,10 +67,10 @@ public class RouteState extends InteractiveState return null; } int[] route_net_no_arr; - if (picked_item instanceof board.Pin && net_count > 1) + if (picked_item instanceof eu.mihosoft.freerouting.board.Pin && net_count > 1) { // tie pin, remove nets, which are already conneccted to this pin on the current layer. - route_net_no_arr = get_route_net_numbers_at_tie_pin((board.Pin) picked_item, p_board_handling.settings.layer); + route_net_no_arr = get_route_net_numbers_at_tie_pin((eu.mihosoft.freerouting.board.Pin) picked_item, p_board_handling.settings.layer); } else { @@ -85,7 +84,7 @@ public class RouteState extends InteractiveState { return null; } - board.RoutingBoard routing_board = p_board_handling.get_routing_board(); + eu.mihosoft.freerouting.board.RoutingBoard routing_board = p_board_handling.get_routing_board(); int[] trace_half_widths = new int[routing_board.get_layer_count()]; boolean[] layer_active_arr = new boolean[trace_half_widths.length]; for (int i = 0; i < trace_half_widths.length; ++i) @@ -151,7 +150,7 @@ public class RouteState extends InteractiveState } - rules.Net curr_net = routing_board.rules.nets.get(route_net_no_arr[0]); + eu.mihosoft.freerouting.rules.Net curr_net = routing_board.rules.nets.get(route_net_no_arr[0]); if (curr_net == null) { return null; @@ -205,13 +204,13 @@ public class RouteState extends InteractiveState } /** - * Checks starting an interactive route at p_location. + * Checks starting an eu.mihosoft.freerouting.interactive route at p_location. * Returns the picked start item of the routing at p_location, * or null, if no such item was found. */ static protected Item start_ok(IntPoint p_location, BoardHandling p_hdlg) { - board.RoutingBoard routing_board = p_hdlg.get_routing_board(); + eu.mihosoft.freerouting.board.RoutingBoard routing_board = p_hdlg.get_routing_board(); /** * look if an already exististing trace ends at p_start_corner @@ -290,12 +289,12 @@ public class RouteState extends InteractiveState if (Character.isDigit(p_key_char)) { // change to the p_key_char-ths signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int d = Character.digit(p_key_char, 10); d = Math.min(d, layer_structure.signal_layer_count()); // Board layers start at 0, keyboard input for layers starts at 1. d = Math.max(d - 1, 0); - board.Layer new_layer = layer_structure.get_signal_layer(d); + eu.mihosoft.freerouting.board.Layer new_layer = layer_structure.get_signal_layer(d); d = layer_structure.get_no(new_layer); if (d >= 0) @@ -306,7 +305,7 @@ public class RouteState extends InteractiveState else if (p_key_char == '+') { // change to the next signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int current_layer_no = hdlg.settings.layer; for (;;) { @@ -324,7 +323,7 @@ public class RouteState extends InteractiveState else if (p_key_char == '-') { // change to the to the previous signal layer - board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; + eu.mihosoft.freerouting.board.LayerStructure layer_structure = hdlg.get_routing_board().layer_structure; int current_layer_no = hdlg.settings.layer; for (;;) { @@ -521,7 +520,7 @@ public class RouteState extends InteractiveState /** * get nets of p_tie_pin except nets of traces, which are already conneccted to this pin on p_layer. */ - static int[] get_route_net_numbers_at_tie_pin(board.Pin p_pin, int p_layer) + static int[] get_route_net_numbers_at_tie_pin(eu.mihosoft.freerouting.board.Pin p_pin, int p_layer) { Set net_number_list = new java.util.TreeSet(); for (int i = 0; i < p_pin.net_count(); ++i) @@ -561,7 +560,7 @@ public class RouteState extends InteractiveState { if (route != null) { - rules.Net curr_net = hdlg.get_routing_board().rules.nets.get(route.net_no_arr[0]); + eu.mihosoft.freerouting.rules.Net curr_net = hdlg.get_routing_board().rules.nets.get(route.net_no_arr[0]); hdlg.screen_messages.set_status_message(resources.getString("routing_net") + " " + curr_net.name); } } diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/ScreenMessages.java b/src/main/java/eu/mihosoft/freerouting/interactive/ScreenMessages.java index d3ef389..bc3c304 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/ScreenMessages.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/ScreenMessages.java @@ -18,7 +18,7 @@ * Created on 8. August 2003, 19:10 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import javax.swing.JLabel; @@ -34,7 +34,7 @@ public class ScreenMessages public ScreenMessages(JLabel p_status_field, JLabel p_add_field, JLabel p_layer_field, JLabel p_mouse_position, java.util.Locale p_locale) { - resources = java.util.ResourceBundle.getBundle("interactive.resources.ScreenMessages", p_locale); + resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.interactive.resources.ScreenMessages", p_locale); locale = p_locale; active_layer_string = resources.getString("current_layer") + " "; target_layer_string = resources.getString("target_layer") + " "; @@ -110,7 +110,7 @@ public class ScreenMessages /** * Sets the displayed layer of the nearest target item - * in interactive routing. + * in eu.mihosoft.freerouting.interactive routing. */ public void set_target_layer(String p_layer_name) { @@ -121,7 +121,7 @@ public class ScreenMessages } } - public void set_mouse_position(geometry.planar.FloatPoint p_pos) + public void set_mouse_position(eu.mihosoft.freerouting.geometry.planar.FloatPoint p_pos) { if (p_pos == null || this.mouse_position == null || this.write_protected) { diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/SelectItemsInRegionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/SelectItemsInRegionState.java index 4461109..49635cc 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/SelectItemsInRegionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/SelectItemsInRegionState.java @@ -17,17 +17,17 @@ * * Created on 9. November 2003, 12:02 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.IntBox; -import geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; -import board.Item; +import eu.mihosoft.freerouting.board.Item; /** * Interactive state for selecting all items in a rectangle. diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/SelectMenuState.java b/src/main/java/eu/mihosoft/freerouting/interactive/SelectMenuState.java index 49d3de0..dfa3007 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/SelectMenuState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/SelectMenuState.java @@ -18,9 +18,9 @@ * Created on 28. November 2003, 10:13 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** * Class implementing the different functionality in the select menu, diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/SelectRegionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/SelectRegionState.java index 45c9f55..af6c157 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/SelectRegionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/SelectRegionState.java @@ -18,12 +18,12 @@ * Created on 9. November 2003, 11:34 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** - * Common base class for interactive selection of a rectangle. + * Common base class for eu.mihosoft.freerouting.interactive selection of a rectangle. * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/SelectedItemState.java b/src/main/java/eu/mihosoft/freerouting/interactive/SelectedItemState.java index 0bddcff..ae9bc03 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/SelectedItemState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/SelectedItemState.java @@ -17,38 +17,39 @@ * * Created on 10. November 2003, 08:02 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Point; -import geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Point; +import eu.mihosoft.freerouting.geometry.planar.Vector; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; -import datastructures.Stoppable; +import eu.mihosoft.freerouting.datastructures.Stoppable; -import library.Package; +import eu.mihosoft.freerouting.gui.WindowObjectInfo; +import eu.mihosoft.freerouting.library.Package; -import rules.Net; +import eu.mihosoft.freerouting.rules.Net; -import autoroute.AutorouteEngine; +import eu.mihosoft.freerouting.autoroute.AutorouteEngine; -import board.Component; -import board.Connectable; -import board.DrillItem; -import board.Via; -import board.Pin; -import board.Item; -import board.ObstacleArea; -import board.PolylineTrace; -import board.RoutingBoard; -import board.FixedState; -import board.OptViaAlgo; -import board.TestLevel; +import eu.mihosoft.freerouting.board.Component; +import eu.mihosoft.freerouting.board.Connectable; +import eu.mihosoft.freerouting.board.DrillItem; +import eu.mihosoft.freerouting.board.Via; +import eu.mihosoft.freerouting.board.Pin; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ObstacleArea; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.FixedState; +import eu.mihosoft.freerouting.board.OptViaAlgo; +import eu.mihosoft.freerouting.board.TestLevel; /** * Class implementing actions on the currently selected items. @@ -434,7 +435,7 @@ public class SelectedItemState extends InteractiveState continue; } boolean contains_plane = false; - rules.Net route_net = hdlg.get_routing_board().rules.nets.get(curr_item.get_net_no(0)); + eu.mihosoft.freerouting.rules.Net route_net = hdlg.get_routing_board().rules.nets.get(curr_item.get_net_no(0)); if (route_net != null) { contains_plane = route_net.contains_plane(); @@ -658,7 +659,7 @@ public class SelectedItemState extends InteractiveState */ public InteractiveState assign_clearance_class(int p_cl_class_index) { - board.BasicBoard routing_board = this.hdlg.get_routing_board(); + eu.mihosoft.freerouting.board.BasicBoard routing_board = this.hdlg.get_routing_board(); if (p_cl_class_index < 0 || p_cl_class_index >= routing_board.rules.clearance_matrix.get_class_count()) { return this.return_state; @@ -882,7 +883,7 @@ public class SelectedItemState extends InteractiveState } /** - * Removes items not selected by the current interactive filter from the selected item list. + * Removes items not selected by the current eu.mihosoft.freerouting.interactive filter from the selected item list. */ public InteractiveState filter() { @@ -901,7 +902,7 @@ public class SelectedItemState extends InteractiveState */ public SelectedItemState info() { - gui.WindowObjectInfo.display(this.item_list, hdlg.get_panel().board_frame, hdlg.coordinate_transform, new java.awt.Point(100, 100)); + WindowObjectInfo.display(this.item_list, hdlg.get_panel().board_frame, hdlg.coordinate_transform, new java.awt.Point(100, 100)); return this; } @@ -917,7 +918,7 @@ public class SelectedItemState extends InteractiveState return; } - for (board.Item curr_item : item_list) + for (eu.mihosoft.freerouting.board.Item curr_item : item_list) { curr_item.draw(p_graphics, hdlg.graphics_context, hdlg.graphics_context.get_hilight_color(), hdlg.graphics_context.get_hilight_color_intensity()); diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/Settings.java b/src/main/java/eu/mihosoft/freerouting/interactive/Settings.java index bdbda15..50e921a 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/Settings.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/Settings.java @@ -18,19 +18,19 @@ * Created on 29. August 2003, 11:33 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import board.ItemSelectionFilter; -import board.RoutingBoard; +import eu.mihosoft.freerouting.board.ItemSelectionFilter; +import eu.mihosoft.freerouting.board.RoutingBoard; /** - * Contains the values of the interactive settings of the board handling. + * Contains the values of the eu.mihosoft.freerouting.interactive settings of the eu.mihosoft.freerouting.board handling. * * @author Alfons Wirtz */ public class Settings implements java.io.Serializable { - /** Creates a new interactive settings variable. */ + /** Creates a new eu.mihosoft.freerouting.interactive settings variable. */ public Settings(RoutingBoard p_board, Logfile p_logfile) { this.logfile = p_logfile; @@ -39,7 +39,7 @@ public class Settings implements java.io.Serializable push_enabled = true; drag_components_enabled = true; select_on_all_visible_layers = true; // else selection is only on the current layer - is_stitch_route = false; // else interactive routing is dynamic + is_stitch_route = false; // else eu.mihosoft.freerouting.interactive routing is dynamic trace_pull_tight_region_width = Integer.MAX_VALUE; trace_pull_tight_accuracy = 500; via_snap_to_smd_center = true; @@ -113,7 +113,7 @@ public class Settings implements java.io.Serializable return this.drag_components_enabled; } - /** indicates if interactive selections are made on all visible layers or only on the current layer.*/ + /** indicates if eu.mihosoft.freerouting.interactive selections are made on all visible layers or only on the current layer.*/ public boolean get_select_on_all_visible_layers() { return this.select_on_all_visible_layers; @@ -154,7 +154,7 @@ public class Settings implements java.io.Serializable return this.zoom_with_wheel; } - /** The filter used in interactive selection of board items. */ + /** The filter used in eu.mihosoft.freerouting.interactive selection of eu.mihosoft.freerouting.board items. */ public ItemSelectionFilter get_item_selection_filter() { return this.item_selection_filter; @@ -183,7 +183,7 @@ public class Settings implements java.io.Serializable } /** - * The index of the clearance class used for traces in interactive routing in the clearance matrix, + * The index of the clearance class used for traces in eu.mihosoft.freerouting.interactive routing in the clearance matrix, * if manual_route_selection is on. */ public int get_manual_trace_clearance_class() @@ -192,7 +192,7 @@ public class Settings implements java.io.Serializable } /** - * The index of the via rule used in routing in the board via rules if manual_route_selection is on. + * The index of the via rule used in routing in the eu.mihosoft.freerouting.board via rules if manual_route_selection is on. */ public int get_manual_via_rule_index() { @@ -223,7 +223,7 @@ public class Settings implements java.io.Serializable } /** - * The index of the via rule used in routing in the board via rules if manual_route_selection is on. + * The index of the via rule used in routing in the eu.mihosoft.freerouting.board via rules if manual_route_selection is on. */ public void set_manual_via_rule_index(int p_value) { @@ -281,7 +281,7 @@ public class Settings implements java.io.Serializable this.automatic_neckdown = p_value; } - /** The filter used in interactive selection of board items. */ + /** The filter used in eu.mihosoft.freerouting.interactive selection of eu.mihosoft.freerouting.board items. */ public void set_item_selection_filter(ItemSelectionFilter p_value) { if (read_only) @@ -292,7 +292,7 @@ public class Settings implements java.io.Serializable } /** - * Enables or disables pushing obstacles in interactive routing + * Enables or disables pushing obstacles in eu.mihosoft.freerouting.interactive routing */ public void set_push_enabled(boolean p_value) { @@ -319,7 +319,7 @@ public class Settings implements java.io.Serializable /** - * Sets, if item selection is on all board layers or only + * Sets, if item selection is on all eu.mihosoft.freerouting.board layers or only * on the current layer. */ public void set_select_on_all_visible_layers(boolean p_value) @@ -397,7 +397,7 @@ public class Settings implements java.io.Serializable } /** - * Sets the manual trace half width used in interactive routing. + * Sets the manual trace half width used in eu.mihosoft.freerouting.interactive routing. */ public void set_manual_trace_half_width( int p_layer_no, int p_value) { @@ -412,7 +412,7 @@ public class Settings implements java.io.Serializable /** - * The index of the clearance class used for traces in interactive routing in the clearance matrix, + * The index of the clearance class used for traces in eu.mihosoft.freerouting.interactive routing in the clearance matrix, * if manual_route_selection is on. */ public void set_manual_trace_clearance_class(int p_index) @@ -445,7 +445,7 @@ public class Settings implements java.io.Serializable } /** - * Changes the interactive selectability of p_item_type. + * Changes the eu.mihosoft.freerouting.interactive selectability of p_item_type. */ public void set_selectable(ItemSelectionFilter.SelectableChoices p_item_type, boolean p_value) { @@ -509,7 +509,7 @@ public class Settings implements java.io.Serializable /** allows dragging components with the route */ boolean drag_components_enabled; - /** indicates if interactive selections are made on all visible layers or only on the current layer.*/ + /** indicates if eu.mihosoft.freerouting.interactive selections are made on all visible layers or only on the current layer.*/ boolean select_on_all_visible_layers ; /** Route mode: stitching or dynamic */ @@ -549,13 +549,13 @@ public class Settings implements java.io.Serializable boolean hilight_routing_obstacle; /** - * The index of the clearance class used for traces in interactive routing in the clearance matrix, + * The index of the clearance class used for traces in eu.mihosoft.freerouting.interactive routing in the clearance matrix, * if manual_route_selection is on. */ int manual_trace_clearance_class; /** - * The index of the via rule used in routing in the board via rules if manual_route_selection is on. + * The index of the via rule used in routing in the eu.mihosoft.freerouting.board via rules if manual_route_selection is on. */ int manual_via_rule_index; @@ -567,17 +567,17 @@ public class Settings implements java.io.Serializable public AutorouteSettings autoroute_settings; - /** The filter used in interactive selection of board items. */ + /** The filter used in eu.mihosoft.freerouting.interactive selection of eu.mihosoft.freerouting.board items. */ ItemSelectionFilter item_selection_filter; /** Defines the data of the snapshot selected for restoring. */ SnapShot.Attributes snapshot_attributes; - /** Indicates, if the data of this class are not allowed to be changed in ineractive board editing. */ + /** Indicates, if the data of this class are not allowed to be changed in ineractive eu.mihosoft.freerouting.board editing. */ private transient boolean read_only = false; /** - * The file used for logging interactive action, + * The file used for logging eu.mihosoft.freerouting.interactive action, * so that they can be replayed later */ private transient Logfile logfile; diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/SnapShot.java b/src/main/java/eu/mihosoft/freerouting/interactive/SnapShot.java index 926eee4..89f4c42 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/SnapShot.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/SnapShot.java @@ -18,17 +18,19 @@ * Created on 8. November 2004, 08:01 */ -package interactive; +package eu.mihosoft.freerouting.interactive; + +import eu.mihosoft.freerouting.gui.BoardFrame; /** - * Snapshot of the client situation in an interactive session. + * Snapshot of the client situation in an eu.mihosoft.freerouting.interactive session. * * @author Alfons Wirtz */ public class SnapShot implements java.io.Serializable { /** - * Returns a new snapshot or null, if the current interactive state + * Returns a new snapshot or null, if the current eu.mihosoft.freerouting.interactive state * is not suitable to generate a snapshot. */ public static SnapShot get_instance(String p_name, BoardHandling p_board_handling) @@ -41,13 +43,13 @@ public class SnapShot implements java.io.Serializable return new SnapShot(p_name, p_board_handling); } - /** Creates a SnapShot of the display region and the interactive settings */ + /** Creates a SnapShot of the display region and the eu.mihosoft.freerouting.interactive settings */ private SnapShot(String p_name, BoardHandling p_board_handling) { this.name = p_name; this.settings = new Settings(p_board_handling.settings); this.interactive_state_no = get_no(p_board_handling.interactive_state); - this.graphics_context = new boardgraphics.GraphicsContext(p_board_handling.graphics_context); + this.graphics_context = new eu.mihosoft.freerouting.boardgraphics.GraphicsContext(p_board_handling.graphics_context); this.viewport_position = new java.awt.Point(p_board_handling.get_panel().get_viewport_position()); this.subwindow_filters = p_board_handling.get_panel().board_frame.get_snapshot_subwindow_selections(); } @@ -68,16 +70,16 @@ public class SnapShot implements java.io.Serializable } /** - * Goes to this shnapshot in interactive board etiting. + * Goes to this shnapshot in eu.mihosoft.freerouting.interactive eu.mihosoft.freerouting.board etiting. */ - public void go_to(interactive.BoardHandling p_board_handling) + public void go_to(eu.mihosoft.freerouting.interactive.BoardHandling p_board_handling) { - interactive.SnapShot.Attributes snapshot_attributes = this.settings.snapshot_attributes; + eu.mihosoft.freerouting.interactive.SnapShot.Attributes snapshot_attributes = this.settings.snapshot_attributes; if (snapshot_attributes.object_visibility) { p_board_handling.graphics_context.color_intensity_table = - new boardgraphics.ColorIntensityTable(this.graphics_context.color_intensity_table); + new eu.mihosoft.freerouting.boardgraphics.ColorIntensityTable(this.graphics_context.color_intensity_table); } if (snapshot_attributes.layer_visibility) { @@ -94,7 +96,7 @@ public class SnapShot implements java.io.Serializable } if (snapshot_attributes.selectable_items) { - p_board_handling.settings.item_selection_filter = new board.ItemSelectionFilter(this.settings.item_selection_filter); + p_board_handling.settings.item_selection_filter = new eu.mihosoft.freerouting.board.ItemSelectionFilter(this.settings.item_selection_filter); } if (snapshot_attributes.current_layer) { @@ -157,7 +159,7 @@ public class SnapShot implements java.io.Serializable } /** - * Create a number for writing an interactive state to disk. + * Create a number for writing an eu.mihosoft.freerouting.interactive state to disk. * Only MenuStates are saved. The default is SelectState. */ private static int get_no(InteractiveState p_interactive_state) @@ -181,9 +183,9 @@ public class SnapShot implements java.io.Serializable private final String name; public final Settings settings; private final int interactive_state_no; - public final boardgraphics.GraphicsContext graphics_context; + public final eu.mihosoft.freerouting.boardgraphics.GraphicsContext graphics_context; private final java.awt.Point viewport_position; - public final gui.BoardFrame.SubwindowSelections subwindow_filters; + public final BoardFrame.SubwindowSelections subwindow_filters; /** * Defines the data of the snapshot selected for restoring. diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/StitchRouteState.java b/src/main/java/eu/mihosoft/freerouting/interactive/StitchRouteState.java index 2d49eb2..6123749 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/StitchRouteState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/StitchRouteState.java @@ -18,13 +18,13 @@ * Created on 8. Dezember 2003, 08:05 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; /** - * State for interactive routing by adding corners with the left mouse button. + * State for eu.mihosoft.freerouting.interactive routing by adding corners with the left mouse button. * * @author Alfons Wirtz */ @@ -82,8 +82,8 @@ public class StitchRouteState extends RouteState double display_width = hdlg.get_trace_halfwidth(route.net_no_arr[0], hdlg.settings.layer); int clearance_draw_width = 50; double radius_with_clearance = display_width; - rules.NetClass default_net_class = hdlg.get_routing_board().rules.get_default_net_class(); - int cl_class = default_net_class.default_item_clearance_classes.get(rules.DefaultItemClearanceClasses.ItemClass.TRACE); + eu.mihosoft.freerouting.rules.NetClass default_net_class = hdlg.get_routing_board().rules.get_default_net_class(); + int cl_class = default_net_class.default_item_clearance_classes.get(eu.mihosoft.freerouting.rules.DefaultItemClearanceClasses.ItemClass.TRACE); radius_with_clearance += hdlg.get_routing_board().clearance_value(cl_class, cl_class, hdlg.settings.layer); hdlg.graphics_context.draw(draw_points, display_width, draw_color, p_graphics, 0.5); // draw the clearance boundary around the end point diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/TileConstructionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/TileConstructionState.java index 3466a38..3f8a3c6 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/TileConstructionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/TileConstructionState.java @@ -18,25 +18,25 @@ * Created on 6. November 2003, 14:46 */ -package interactive; +package eu.mihosoft.freerouting.interactive; import java.util.Iterator; -import geometry.planar.FloatPoint; -import geometry.planar.IntPoint; -import geometry.planar.Line; -import geometry.planar.Side; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Line; +import eu.mihosoft.freerouting.geometry.planar.Side; +import eu.mihosoft.freerouting.geometry.planar.TileShape; -import rules.BoardRules; +import eu.mihosoft.freerouting.rules.BoardRules; -import board.AngleRestriction; -import board.RoutingBoard; -import board.FixedState; +import eu.mihosoft.freerouting.board.AngleRestriction; +import eu.mihosoft.freerouting.board.RoutingBoard; +import eu.mihosoft.freerouting.board.FixedState; /** - * Class for interactive construction of a tile shaped obstacle + * Class for eu.mihosoft.freerouting.interactive construction of a tile shaped obstacle * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/ZoomRegionState.java b/src/main/java/eu/mihosoft/freerouting/interactive/ZoomRegionState.java index a541be3..03eba18 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/ZoomRegionState.java +++ b/src/main/java/eu/mihosoft/freerouting/interactive/ZoomRegionState.java @@ -18,14 +18,14 @@ * Created on 9. November 2003, 13:05 */ -package interactive; +package eu.mihosoft.freerouting.interactive; -import geometry.planar.FloatPoint; +import eu.mihosoft.freerouting.geometry.planar.FloatPoint; import java.awt.geom.Point2D; /** - * Class for interactive zooming to a rectangle. + * Class for eu.mihosoft.freerouting.interactive zooming to a rectangle. * * @author Alfons Wirtz */ @@ -56,7 +56,7 @@ public class ZoomRegionState extends SelectRegionState super(p_parent_state, p_board_handling, p_logfile); if (this.logfile != null) { - logfile.start_scope(interactive.LogfileScope.ZOOM_FRAME); + logfile.start_scope(eu.mihosoft.freerouting.interactive.LogfileScope.ZOOM_FRAME); } } diff --git a/src/main/java/eu/mihosoft/freerouting/interactive/package.html b/src/main/java/eu/mihosoft/freerouting/interactive/package.html index e5076e0..7f7f28b 100644 --- a/src/main/java/eu/mihosoft/freerouting/interactive/package.html +++ b/src/main/java/eu/mihosoft/freerouting/interactive/package.html @@ -17,5 +17,5 @@ --> - Contains functionality for interactive board handling, which is independent of the graphical user interface. + Contains functionality for eu.mihosoft.freerouting.interactive eu.mihosoft.freerouting.board handling, which is independent of the graphical user interface. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/library/BoardLibrary.java b/src/main/java/eu/mihosoft/freerouting/library/BoardLibrary.java index 2a2b248..9e470fd 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/BoardLibrary.java +++ b/src/main/java/eu/mihosoft/freerouting/library/BoardLibrary.java @@ -18,13 +18,13 @@ * Created on 4. Juni 2004, 06:37 */ -package library; +package eu.mihosoft.freerouting.library; import java.util.List; import java.util.Vector; /** - * Describes a board library of packages and padstacks. + * Describes a eu.mihosoft.freerouting.board eu.mihosoft.freerouting.library of packages and padstacks. * * @author alfons */ @@ -127,9 +127,9 @@ public class BoardLibrary implements java.io.Serializable /** * Removes p_padstack from the via padstack list. * Returns false, if p_padstack was not found in the list. - * If the padstack is no more used on the board, it will also be removed from the board padstacks. + * If the padstack is no more used on the eu.mihosoft.freerouting.board, it will also be removed from the eu.mihosoft.freerouting.board padstacks. */ - public boolean remove_via_padstack(Padstack p_padstack, board.BasicBoard p_board) + public boolean remove_via_padstack(Padstack p_padstack, eu.mihosoft.freerouting.board.BasicBoard p_board) { boolean result = via_padstacks.remove(p_padstack); return result; @@ -137,7 +137,7 @@ public class BoardLibrary implements java.io.Serializable /** - * Gets the via padstack mirrored to the back side of the board. + * Gets the via padstack mirrored to the back side of the eu.mihosoft.freerouting.board. * Returns null, if no such via padstack exists. */ public Padstack get_mirrored_via_padstack(Padstack p_via_padstack) @@ -162,19 +162,19 @@ public class BoardLibrary implements java.io.Serializable /** * Looks, if the input padstack is used on p_board in a Package or in drill. */ - public boolean is_used (Padstack p_padstack, board.BasicBoard p_board) + public boolean is_used (Padstack p_padstack, eu.mihosoft.freerouting.board.BasicBoard p_board) { - java.util.Iterator it = p_board.item_list.start_read_object(); + java.util.Iterator it = p_board.item_list.start_read_object(); for(;;) { - datastructures.UndoableObjects.Storable curr_item = p_board.item_list.read_object(it); + eu.mihosoft.freerouting.datastructures.UndoableObjects.Storable curr_item = p_board.item_list.read_object(it); if (curr_item == null) { break; } - if (curr_item instanceof board.DrillItem) + if (curr_item instanceof eu.mihosoft.freerouting.board.DrillItem) { - if (((board.DrillItem) curr_item).get_padstack() == p_padstack) + if (((eu.mihosoft.freerouting.board.DrillItem) curr_item).get_padstack() == p_padstack) { return true; } @@ -199,6 +199,6 @@ public class BoardLibrary implements java.io.Serializable /** Containes information for gate swap and pin swap in the Specctra-dsn format. */ public LogicalParts logical_parts = new LogicalParts(); - /** The subset of padstacks in the board library, which can be used in routing for inserting vias. */ + /** The subset of padstacks in the eu.mihosoft.freerouting.board eu.mihosoft.freerouting.library, which can be used in routing for inserting vias. */ private List via_padstacks = null; } diff --git a/src/main/java/eu/mihosoft/freerouting/library/LogicalPart.java b/src/main/java/eu/mihosoft/freerouting/library/LogicalPart.java index 3023a68..fdff762 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/LogicalPart.java +++ b/src/main/java/eu/mihosoft/freerouting/library/LogicalPart.java @@ -18,20 +18,20 @@ * Created on 26. Maerz 2005, 06:14 */ -package library; +package eu.mihosoft.freerouting.library; /** * Contains contain information for gate swap and pin swap for a single component. * * @author Alfons Wirtz */ -public class LogicalPart implements board.ObjectInfoPanel.Printable, java.io.Serializable +public class LogicalPart implements eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { /** * Creates a new instance of LogicalPart. * The part pins are sorted by pin_no. - * The pin_no's of the part pins must be the same number as in the componnents library package. + * The pin_no's of the part pins must be the same number as in the componnents eu.mihosoft.freerouting.library package. */ public LogicalPart(String p_name, int p_no, PartPin[] p_part_pin_arr) { @@ -56,10 +56,10 @@ public class LogicalPart implements board.ObjectInfoPanel.Printable, java.io.Ser return part_pin_arr[p_no]; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("logical_part_2") + " "); p_window.append_bold(this.name); for (int i = 0; i < this.part_pin_arr.length; ++i) @@ -106,10 +106,10 @@ public class LogicalPart implements board.ObjectInfoPanel.Printable, java.io.Ser return this.pin_no - p_other.pin_no; } - /** The number of the part pin. Must be the same number as in the componnents library package. */ + /** The number of the part pin. Must be the same number as in the componnents eu.mihosoft.freerouting.library package. */ public final int pin_no; - /** The name of the part pin. Must be the same name as in the componnents library package. */ + /** The name of the part pin. Must be the same name as in the componnents eu.mihosoft.freerouting.library package. */ public final String pin_name; /** The name of the gate this pin belongs to. */ diff --git a/src/main/java/eu/mihosoft/freerouting/library/LogicalParts.java b/src/main/java/eu/mihosoft/freerouting/library/LogicalParts.java index 32301a8..75dd5f4 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/LogicalParts.java +++ b/src/main/java/eu/mihosoft/freerouting/library/LogicalParts.java @@ -18,7 +18,7 @@ * Created on 26. Maerz 2005, 06:08 */ -package library; +package eu.mihosoft.freerouting.library; import java.util.Vector; diff --git a/src/main/java/eu/mihosoft/freerouting/library/Package.java b/src/main/java/eu/mihosoft/freerouting/library/Package.java index fba5274..2a04022 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/Package.java +++ b/src/main/java/eu/mihosoft/freerouting/library/Package.java @@ -18,11 +18,11 @@ * Created on 27. Mai 2004, 06:53 */ -package library; +package eu.mihosoft.freerouting.library; -import geometry.planar.Vector; -import geometry.planar.Shape; -import geometry.planar.Area; +import eu.mihosoft.freerouting.geometry.planar.Vector; +import eu.mihosoft.freerouting.geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.Area; /** * Component package templates describing the padstacks and @@ -31,7 +31,7 @@ import geometry.planar.Area; * * @author alfons */ -public class Package implements Comparable, board.ObjectInfoPanel.Printable, java.io.Serializable +public class Package implements Comparable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { /** @@ -103,10 +103,10 @@ public class Package implements Comparable, board.ObjectInfoPanel.Print return this.name; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("package") + " "); p_window.append_bold(this.name); for (int i = 0; i < this.pin_arr.length; ++i) @@ -145,7 +145,7 @@ public class Package implements Comparable, board.ObjectInfoPanel.Print public final Keepout[] place_keepout_arr; - /** If false, the package is placed on the back side of the board */ + /** If false, the package is placed on the back side of the eu.mihosoft.freerouting.board */ public final boolean is_front; private final Packages package_list; diff --git a/src/main/java/eu/mihosoft/freerouting/library/Packages.java b/src/main/java/eu/mihosoft/freerouting/library/Packages.java index 1fa2ef7..8312d1c 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/Packages.java +++ b/src/main/java/eu/mihosoft/freerouting/library/Packages.java @@ -18,15 +18,15 @@ * Created on 3. Juni 2004, 09:29 */ -package library; +package eu.mihosoft.freerouting.library; import java.util.Iterator; import java.util.Vector; -import geometry.planar.Shape; +import eu.mihosoft.freerouting.geometry.planar.Shape; /** - * Describes a library of component packages. + * Describes a eu.mihosoft.freerouting.library of component packages. * * @author Alfons Wirtz */ diff --git a/src/main/java/eu/mihosoft/freerouting/library/Padstack.java b/src/main/java/eu/mihosoft/freerouting/library/Padstack.java index 11aea3e..5172958 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/Padstack.java +++ b/src/main/java/eu/mihosoft/freerouting/library/Padstack.java @@ -18,19 +18,19 @@ * Created on 27. Mai 2004, 06:35 */ -package library; +package eu.mihosoft.freerouting.library; -import geometry.planar.ConvexShape; -import geometry.planar.Direction; -import geometry.planar.IntBox; -import geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.Direction; +import eu.mihosoft.freerouting.geometry.planar.IntBox; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; /** * Describes padstack masks for pins or vias located at the origin. * * @author alfons */ -public class Padstack implements Comparable, board.ObjectInfoPanel.Printable, java.io.Serializable +public class Padstack implements Comparable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { /** @@ -98,7 +98,7 @@ public class Padstack implements Comparable, board.ObjectInfoPanel.Pri return result; } - /** Returns the layer ciount of the board of this padstack. */ + /** Returns the layer ciount of the eu.mihosoft.freerouting.board of this padstack. */ public int board_layer_count() { return shapes.length; @@ -152,10 +152,10 @@ public class Padstack implements Comparable, board.ObjectInfoPanel.Pri return result; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("padstack") + " "); p_window.append_bold(this.name); for (int i = 0; i < shapes.length; ++i) diff --git a/src/main/java/eu/mihosoft/freerouting/library/Padstacks.java b/src/main/java/eu/mihosoft/freerouting/library/Padstacks.java index 532fd79..aaea301 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/Padstacks.java +++ b/src/main/java/eu/mihosoft/freerouting/library/Padstacks.java @@ -18,22 +18,22 @@ * Created on 3. Juni 2004, 09:42 */ -package library; +package eu.mihosoft.freerouting.library; import java.util.Iterator; import java.util.Vector; -import geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; /** - * Describes a library of padstacks for pins or vias. + * Describes a eu.mihosoft.freerouting.library of padstacks for pins or vias. * * @author alfons */ public class Padstacks implements java.io.Serializable { /** Creates a new instance of Padstacks */ - public Padstacks(board.LayerStructure p_layer_structure) + public Padstacks(eu.mihosoft.freerouting.board.LayerStructure p_layer_structure) { board_layer_structure = p_layer_structure; padstack_arr = new Vector(); @@ -86,7 +86,7 @@ public class Padstacks implements java.io.Serializable /** * Appends a new padstack with the input shapes to this padstacks. - * p_shapes is an array of dimension board layer_count. + * p_shapes is an array of dimension eu.mihosoft.freerouting.board layer_count. * p_drill_allowed indicates, if vias of the own net are allowed to overlap with this padstack * If p_placed_absolute is false, the layers of the padstack are mirrored, if it is placed on the back side. */ @@ -100,7 +100,7 @@ public class Padstacks implements java.io.Serializable /** * Appends a new padstack with the input shapes to this padstacks. - * p_shapes is an array of dimension board layer_count. + * p_shapes is an array of dimension eu.mihosoft.freerouting.board layer_count. * The padatack name is generated internally. */ public Padstack add(ConvexShape [] p_shapes) @@ -130,5 +130,5 @@ public class Padstacks implements java.io.Serializable private Vector padstack_arr; /** The layer structure of each padstack. */ - public final board.LayerStructure board_layer_structure; + public final eu.mihosoft.freerouting.board.LayerStructure board_layer_structure; } diff --git a/src/main/java/eu/mihosoft/freerouting/library/package.html b/src/main/java/eu/mihosoft/freerouting/library/package.html index 5a207af..3ae2bb4 100644 --- a/src/main/java/eu/mihosoft/freerouting/library/package.html +++ b/src/main/java/eu/mihosoft/freerouting/library/package.html @@ -16,4 +16,4 @@ --> -Describes library objects of a printed circuit board such as padstacks and component packages. \ No newline at end of file +Describes eu.mihosoft.freerouting.library objects of a printed circuit eu.mihosoft.freerouting.board such as padstacks and component packages. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/logger/FRLogger.java b/src/main/java/eu/mihosoft/freerouting/logger/FRLogger.java index 206fddd..05ec885 100644 --- a/src/main/java/eu/mihosoft/freerouting/logger/FRLogger.java +++ b/src/main/java/eu/mihosoft/freerouting/logger/FRLogger.java @@ -1,4 +1,4 @@ -package logger; +package eu.mihosoft.freerouting.logger; /** * Andrey Belomutskiy diff --git a/src/main/java/eu/mihosoft/freerouting/module-info.java b/src/main/java/eu/mihosoft/freerouting/module-info.java new file mode 100644 index 0000000..e8bf153 --- /dev/null +++ b/src/main/java/eu/mihosoft/freerouting/module-info.java @@ -0,0 +1,6 @@ + +module eu.mihosoft.freerouting { + requires java.desktop; + requires java.logging; + requires eu.mihosoft.freerouting.deps.jh; +} diff --git a/src/main/java/eu/mihosoft/freerouting/rules/BoardRules.java b/src/main/java/eu/mihosoft/freerouting/rules/BoardRules.java index 98250b4..089ab12 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/BoardRules.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/BoardRules.java @@ -18,13 +18,13 @@ * Created on 1. Juni 2004, 07:16 */ -package rules; +package eu.mihosoft.freerouting.rules; -import geometry.planar.ConvexShape; +import eu.mihosoft.freerouting.geometry.planar.ConvexShape; /** * Contains the rules and constraints required for items - * to be inserted into a routing board + * to be inserted into a routing eu.mihosoft.freerouting.board * * @author Alfons Wirtz */ @@ -33,12 +33,12 @@ public class BoardRules implements java.io.Serializable /** * Creates a new instance of this class. */ - public BoardRules(board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) + public BoardRules(eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) { layer_structure = p_layer_structure; clearance_matrix = p_clearance_matrix; nets = new Nets(); - this.trace_angle_restriction = board.AngleRestriction.FORTYFIVE_DEGREE; + this.trace_angle_restriction = eu.mihosoft.freerouting.board.AngleRestriction.FORTYFIVE_DEGREE; this.min_trace_half_width = 100000; this.max_trace_half_width = 100; @@ -181,7 +181,7 @@ public class BoardRules implements java.io.Serializable ViaInfo curr_via_info = this.via_infos.get(i); if (curr_via_info.get_clearance_class() == default_via_cl_class) { - library.Padstack curr_padstack = curr_via_info.get_padstack(); + eu.mihosoft.freerouting.library.Padstack curr_padstack = curr_via_info.get_padstack(); int curr_from_layer = curr_padstack.from_layer(); int curr_to_layer = curr_padstack.to_layer(); ViaInfo existing_via = default_rule.get_layer_range(curr_from_layer, curr_to_layer); @@ -276,12 +276,12 @@ public class BoardRules implements java.io.Serializable } /** - * Changes the clearance class index of all objects on the board with index p_from_no + * Changes the clearance class index of all objects on the eu.mihosoft.freerouting.board with index p_from_no * to p_to_no. */ - public void change_clearance_class_no(int p_from_no, int p_to_no, java.util.Collection p_board_items) + public void change_clearance_class_no(int p_from_no, int p_to_no, java.util.Collection p_board_items) { - for(board.Item curr_item : p_board_items) + for(eu.mihosoft.freerouting.board.Item curr_item : p_board_items) { if (curr_item.clearance_class_no() == p_from_no) { @@ -291,7 +291,7 @@ public class BoardRules implements java.io.Serializable for (int i = 0; i < this.net_classes.count(); ++i) { - rules.NetClass curr_net_class = this.net_classes.get(i); + eu.mihosoft.freerouting.rules.NetClass curr_net_class = this.net_classes.get(i); if (curr_net_class.get_trace_clearance_class() == p_from_no) { curr_net_class.set_trace_clearance_class(p_to_no); @@ -307,7 +307,7 @@ public class BoardRules implements java.io.Serializable for (int i = 0; i < this.via_infos.count(); ++i) { - rules.ViaInfo curr_via = this.via_infos.get(i); + eu.mihosoft.freerouting.rules.ViaInfo curr_via = this.via_infos.get(i); if (curr_via.get_clearance_class() == p_from_no) { curr_via.set_clearance_class(p_to_no); @@ -320,9 +320,9 @@ public class BoardRules implements java.io.Serializable * Removes the clearance class with number p_index. * Returns false, if that was not possible, because there were still items assigned to this class. */ - public boolean remove_clearance_class(int p_index, java.util.Collection p_board_items) + public boolean remove_clearance_class(int p_index, java.util.Collection p_board_items) { - for(board.Item curr_item : p_board_items) + for(eu.mihosoft.freerouting.board.Item curr_item : p_board_items) { if (curr_item.clearance_class_no() == p_index) { @@ -331,7 +331,7 @@ public class BoardRules implements java.io.Serializable } for (int i = 0; i < this.net_classes.count(); ++i) { - rules.NetClass curr_net_class = this.net_classes.get(i); + eu.mihosoft.freerouting.rules.NetClass curr_net_class = this.net_classes.get(i); if (curr_net_class.get_trace_clearance_class() == p_index) { return false; @@ -347,14 +347,14 @@ public class BoardRules implements java.io.Serializable for (int i = 0; i < this.via_infos.count(); ++i) { - rules.ViaInfo curr_via = this.via_infos.get(i); + eu.mihosoft.freerouting.rules.ViaInfo curr_via = this.via_infos.get(i); if (curr_via.get_clearance_class() == p_index) { return false; } } - for(board.Item curr_item : p_board_items) + for(eu.mihosoft.freerouting.board.Item curr_item : p_board_items) { if (curr_item.clearance_class_no() > p_index) { @@ -364,7 +364,7 @@ public class BoardRules implements java.io.Serializable for (int i = 0; i < this.net_classes.count(); ++i) { - rules.NetClass curr_net_class = this.net_classes.get(i); + eu.mihosoft.freerouting.rules.NetClass curr_net_class = this.net_classes.get(i); if (curr_net_class.get_trace_clearance_class() > p_index) { curr_net_class.set_trace_clearance_class(curr_net_class.get_trace_clearance_class() - 1); @@ -381,7 +381,7 @@ public class BoardRules implements java.io.Serializable for (int i = 0; i < this.via_infos.count(); ++i) { - rules.ViaInfo curr_via = this.via_infos.get(i); + eu.mihosoft.freerouting.rules.ViaInfo curr_via = this.via_infos.get(i); if (curr_via.get_clearance_class() > p_index) { curr_via.set_clearance_class(curr_via.get_clearance_class() - 1); @@ -429,13 +429,13 @@ public class BoardRules implements java.io.Serializable } /** The angle restriction for tracese: 90 degree, 45 degree or none. */ - public board.AngleRestriction get_trace_angle_restriction() + public eu.mihosoft.freerouting.board.AngleRestriction get_trace_angle_restriction() { return this.trace_angle_restriction; } /** Sets the angle restriction for tracese: 90 degree, 45 degree or none. */ - public void set_trace_angle_restriction(board.AngleRestriction p_angle_restriction) + public void set_trace_angle_restriction(eu.mihosoft.freerouting.board.AngleRestriction p_angle_restriction) { this.trace_angle_restriction = p_angle_restriction; } @@ -475,7 +475,7 @@ public class BoardRules implements java.io.Serializable { return 0; } - library.Padstack via_padstack = default_via_rule.get_via(0).get_padstack(); + eu.mihosoft.freerouting.library.Padstack via_padstack = default_via_rule.get_via(0).get_padstack(); ConvexShape curr_shape = via_padstack.get_shape(via_padstack.from_layer()); double result = curr_shape.max_width(); curr_shape = via_padstack.get_shape(via_padstack.to_layer()); @@ -498,7 +498,7 @@ public class BoardRules implements java.io.Serializable { p_stream.defaultReadObject(); int snap_angle_no = p_stream.readInt(); - this.trace_angle_restriction = board.AngleRestriction.arr[snap_angle_no]; + this.trace_angle_restriction = eu.mihosoft.freerouting.board.AngleRestriction.arr[snap_angle_no]; } /** @@ -509,20 +509,20 @@ public class BoardRules implements java.io.Serializable /** - * Describes the electrical nets on the board. + * Describes the electrical nets on the eu.mihosoft.freerouting.board. */ public final Nets nets; /** The angle restriction for traces: 90 degree, 45 degree or none. */ - private transient board.AngleRestriction trace_angle_restriction; + private transient eu.mihosoft.freerouting.board.AngleRestriction trace_angle_restriction; /** * If true, the router ignores conduction areas. */ private boolean ignore_conduction = true; - private final board.LayerStructure layer_structure; + private final eu.mihosoft.freerouting.board.LayerStructure layer_structure; public final ViaInfos via_infos = new ViaInfos(); diff --git a/src/main/java/eu/mihosoft/freerouting/rules/ClearanceMatrix.java b/src/main/java/eu/mihosoft/freerouting/rules/ClearanceMatrix.java index b755557..d37f08f 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/ClearanceMatrix.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/ClearanceMatrix.java @@ -14,7 +14,7 @@ * for more details. */ -package rules; +package eu.mihosoft.freerouting.rules; /** * @@ -31,7 +31,7 @@ public class ClearanceMatrix implements java.io.Serializable * Creates a new instance with the 2 clearance classes "none"and "default" * ans initializes it with p_default_value. */ - public static ClearanceMatrix get_default_instance(board.LayerStructure p_layer_structure, int p_default_value) + public static ClearanceMatrix get_default_instance(eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, int p_default_value) { String [] name_arr = new String [2]; name_arr[0] = "null"; @@ -46,7 +46,7 @@ public class ClearanceMatrix implements java.io.Serializable * p_layer_count layers. * p_names is an array of dimension p_class_count; */ - public ClearanceMatrix(int p_class_count, board.LayerStructure p_layer_structure, String [] p_name_arr) + public ClearanceMatrix(int p_class_count, eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, String [] p_name_arr) { class_count = Math.max(p_class_count, 1); layer_structure = p_layer_structure; @@ -385,7 +385,7 @@ public class ClearanceMatrix implements java.io.Serializable */ private int class_count; - private final board.LayerStructure layer_structure; + private final eu.mihosoft.freerouting.board.LayerStructure layer_structure; private Row [] row; // vector of class_count rows of the clearance matrix private int [] max_value_on_layer; // maximum clearance value for each layer @@ -393,7 +393,7 @@ public class ClearanceMatrix implements java.io.Serializable /** * contains a row of entries of the clearance matrix */ - private class Row implements board.ObjectInfoPanel.Printable, java.io.Serializable + private class Row implements eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { private Row(String p_name) { @@ -406,10 +406,10 @@ public class ClearanceMatrix implements java.io.Serializable max_value = new int[layer_structure.arr.length]; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("spacing_from_clearance_class") + " "); p_window.append_bold(this.name); for (int i = 1; i < this.column.length; ++i) diff --git a/src/main/java/eu/mihosoft/freerouting/rules/DefaultItemClearanceClasses.java b/src/main/java/eu/mihosoft/freerouting/rules/DefaultItemClearanceClasses.java index 36b87bb..4c58195 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/DefaultItemClearanceClasses.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/DefaultItemClearanceClasses.java @@ -19,7 +19,7 @@ * */ -package rules; +package eu.mihosoft.freerouting.rules; /** * diff --git a/src/main/java/eu/mihosoft/freerouting/rules/Net.java b/src/main/java/eu/mihosoft/freerouting/rules/Net.java index 110c3c8..bb8e6d1 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/Net.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/Net.java @@ -17,19 +17,19 @@ * * Created on 11. Juni 2004, 08:17 */ -package rules; +package eu.mihosoft.freerouting.rules; -import board.Item; -import board.ObjectInfoPanel.Printable; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable; -import datastructures.UndoableObjects; +import eu.mihosoft.freerouting.datastructures.UndoableObjects; /** * Describes properties for an individual electrical net. * * @author Alfons Wirtz */ -public class Net implements Comparable, board.ObjectInfoPanel.Printable, java.io.Serializable +public class Net implements Comparable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { /** @@ -78,7 +78,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja public java.util.Collection get_terminal_items() { java.util.Collection result = new java.util.LinkedList(); - board.BasicBoard board = this.net_list.get_board(); + eu.mihosoft.freerouting.board.BasicBoard board = this.net_list.get_board(); java.util.Iterator it = board.item_list.start_read_object(); for (;;) { @@ -87,7 +87,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja { break; } - if (curr_item instanceof board.Connectable) + if (curr_item instanceof eu.mihosoft.freerouting.board.Connectable) { if (curr_item.contains_net(this.net_number) && !curr_item.is_route()) { @@ -101,10 +101,10 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja /** * Returns the pins of this net. */ - public java.util.Collection get_pins() + public java.util.Collection get_pins() { - java.util.Collection result = new java.util.LinkedList(); - board.BasicBoard board = this.net_list.get_board(); + java.util.Collection result = new java.util.LinkedList(); + eu.mihosoft.freerouting.board.BasicBoard board = this.net_list.get_board(); java.util.Iterator it = board.item_list.start_read_object(); for (;;) { @@ -113,11 +113,11 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja { break; } - if (curr_item instanceof board.Pin) + if (curr_item instanceof eu.mihosoft.freerouting.board.Pin) { if (curr_item.contains_net(this.net_number)) { - result.add((board.Pin) curr_item); + result.add((eu.mihosoft.freerouting.board.Pin) curr_item); } } } @@ -127,10 +127,10 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja /** * Returns all items of this net. */ - public java.util.Collection get_items() + public java.util.Collection get_items() { - java.util.Collection result = new java.util.LinkedList(); - board.BasicBoard board = this.net_list.get_board(); + java.util.Collection result = new java.util.LinkedList(); + eu.mihosoft.freerouting.board.BasicBoard board = this.net_list.get_board(); java.util.Iterator it = board.item_list.start_read_object(); for (;;) { @@ -148,7 +148,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja } /** - * Returns the cumulative trace length of all traces on the board belonging to this net. + * Returns the cumulative trace length of all traces on the eu.mihosoft.freerouting.board belonging to this net. */ public double get_trace_length() { @@ -157,16 +157,16 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja for (Item curr_item : net_items) { - if (curr_item instanceof board.Trace) + if (curr_item instanceof eu.mihosoft.freerouting.board.Trace) { - cumulative_trace_length += ((board.Trace) curr_item).get_length(); + cumulative_trace_length += ((eu.mihosoft.freerouting.board.Trace) curr_item).get_length(); } } return cumulative_trace_length; } /** - * Returns the count of vias on the board belonging to this net. + * Returns the count of vias on the eu.mihosoft.freerouting.board belonging to this net. */ public int get_via_count() { @@ -174,7 +174,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja java.util.Collection net_items = net_list.get_board().get_connectable_items(this.net_number); for (Item curr_item : net_items) { - if (curr_item instanceof board.Via) + if (curr_item instanceof eu.mihosoft.freerouting.board.Via) { ++result; } @@ -198,7 +198,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja return contains_plane; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { Integer via_count = this.get_via_count(); double cumulative_trace_length = this.get_trace_length(); @@ -208,7 +208,7 @@ public class Net implements Comparable, board.ObjectInfoPanel.Printable, ja Integer terminal_item_count = terminals.size(); java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("net") + " "); p_window.append_bold(this.name); p_window.append_bold(": "); diff --git a/src/main/java/eu/mihosoft/freerouting/rules/NetClass.java b/src/main/java/eu/mihosoft/freerouting/rules/NetClass.java index fbf17af..6b1cae2 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/NetClass.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/NetClass.java @@ -17,18 +17,18 @@ * * Created on 7. April 2005, 06:08 */ -package rules; +package eu.mihosoft.freerouting.rules; /** * Describes routing rules for individual nets. * * @author Alfons Wirtz */ -public class NetClass implements java.io.Serializable, board.ObjectInfoPanel.Printable +public class NetClass implements java.io.Serializable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable { /** Creates a new instance of NetClass */ - public NetClass(String p_name, board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) + public NetClass(String p_name, eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) { this.name = p_name; this.board_layer_structure = p_layer_structure; @@ -267,10 +267,10 @@ public class NetClass implements java.io.Serializable, board.ObjectInfoPanel.Pri } } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("net_class_2") + " "); p_window.append_bold(this.name); p_window.append_bold(":"); @@ -365,10 +365,10 @@ public class NetClass implements java.io.Serializable, board.ObjectInfoPanel.Pri private double minimum_trace_length = 0; private double maximum_trace_length = 0; private final ClearanceMatrix clearance_matrix; - private final board.LayerStructure board_layer_structure; + private final eu.mihosoft.freerouting.board.LayerStructure board_layer_structure; /** * The clearance classes of the item types, if this net class comes from a class in a Speccctra dsn-file - * Should evtl be moved to designformats.specctra.NetClass and used only when reading a dsn-file. + * Should evtl be moved to NetClass and used only when reading a dsn-file. */ public DefaultItemClearanceClasses default_item_clearance_classes = new DefaultItemClearanceClasses(); } diff --git a/src/main/java/eu/mihosoft/freerouting/rules/NetClasses.java b/src/main/java/eu/mihosoft/freerouting/rules/NetClasses.java index f962d17..e7a9bea 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/NetClasses.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/NetClasses.java @@ -18,11 +18,11 @@ * Created on 7. April 2005, 07:52 */ -package rules; +package eu.mihosoft.freerouting.rules; /** - * Contains the array of net classes for interactive routing. + * Contains the array of net classes for eu.mihosoft.freerouting.interactive routing. * * @author Alfons Wirtz */ @@ -63,7 +63,7 @@ public class NetClasses implements java.io.Serializable /** * Appends a new empty class with name p_name to the class array */ - NetClass append(String p_name, board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) + NetClass append(String p_name, eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix) { NetClass new_class = new NetClass(p_name, p_layer_structure, p_clearance_matrix); class_arr.add(new_class); @@ -73,10 +73,10 @@ public class NetClasses implements java.io.Serializable /** * Appends a new empty class to the class array. A name for the class is created internally */ - NetClass append(board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix, java.util.Locale p_locale) + NetClass append(eu.mihosoft.freerouting.board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("rules.resources.Default", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.rules.resources.Default", p_locale); String name_front = resources.getString("class"); String new_name = null; Integer index = 0; diff --git a/src/main/java/eu/mihosoft/freerouting/rules/Nets.java b/src/main/java/eu/mihosoft/freerouting/rules/Nets.java index 7e6432b..97e90ba 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/Nets.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/Nets.java @@ -17,13 +17,13 @@ * * Created on 9. Juni 2004, 10:24 */ -package rules; +package eu.mihosoft.freerouting.rules; import java.util.Vector; import java.util.Collection; /** - * Describes the electrical Nets on a board. + * Describes the electrical Nets on a eu.mihosoft.freerouting.board. * * @author alfons */ @@ -37,7 +37,7 @@ public class Nets implements java.io.Serializable } /** - * Returns the biggest net number on the board. + * Returns the biggest net number on the eu.mihosoft.freerouting.board. */ public int max_net_no() { @@ -98,7 +98,7 @@ public class Nets implements java.io.Serializable */ public Net new_net(java.util.Locale p_locale) { - java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("rules.resources.Default", p_locale); + java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.rules.resources.Default", p_locale); String net_name = resources.getString("net#") + (new Integer(net_arr.size() + 1)).toString(); return add(net_name, 1, false); } @@ -133,7 +133,7 @@ public class Nets implements java.io.Serializable * Sets the Board of this net list. * Used for example to get access to the Items of the net. */ - public void set_board(board.BasicBoard p_board) + public void set_board(eu.mihosoft.freerouting.board.BasicBoard p_board) { this.board = p_board; } @@ -142,7 +142,7 @@ public class Nets implements java.io.Serializable * Gets the Board of this net list. * Used for example to get access to the Items of the net. */ - public board.BasicBoard get_board() + public eu.mihosoft.freerouting.board.BasicBoard get_board() { return this.board; } @@ -153,7 +153,7 @@ public class Nets implements java.io.Serializable public static final int max_legal_net_no = 9999999; /** auxiliary net number for internal use */ public static final int hidden_net_no = 10000001; - /** The list of electrical nets on the board */ + /** The list of electrical nets on the eu.mihosoft.freerouting.board */ private Vector net_arr; - private board.BasicBoard board; + private eu.mihosoft.freerouting.board.BasicBoard board; } diff --git a/src/main/java/eu/mihosoft/freerouting/rules/ViaInfo.java b/src/main/java/eu/mihosoft/freerouting/rules/ViaInfo.java index d6176c4..2e62c2e 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/ViaInfo.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/ViaInfo.java @@ -18,16 +18,16 @@ * Created on 31. Maerz 2005, 05:34 */ -package rules; -import library.Padstack; +package eu.mihosoft.freerouting.rules; +import eu.mihosoft.freerouting.library.Padstack; /** * Information about a combination of via_padstack, via clearance class and drill_to_smd_allowed - * used in interactive and automatic routing. + * used in eu.mihosoft.freerouting.interactive and automatic routing. * * @author Alfons Wirtz */ -public class ViaInfo implements Comparable, board.ObjectInfoPanel.Printable, java.io.Serializable +public class ViaInfo implements Comparable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable, java.io.Serializable { /** Creates a new instance of ViaRule */ @@ -91,10 +91,10 @@ public class ViaInfo implements Comparable, board.ObjectInfoPanel.Print return this.name.compareTo(p_other.name); } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("via") + " "); p_window.append_bold(this.name); p_window.append_bold(": "); diff --git a/src/main/java/eu/mihosoft/freerouting/rules/ViaInfos.java b/src/main/java/eu/mihosoft/freerouting/rules/ViaInfos.java index a9aa4f2..f52afe2 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/ViaInfos.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/ViaInfos.java @@ -18,17 +18,17 @@ * Created on 2. April 2005, 06:49 */ -package rules; +package eu.mihosoft.freerouting.rules; import java.util.List; import java.util.LinkedList; /** - * Contains the lists of different ViaInfo's, which can be used in interactive and automatic routing. + * Contains the lists of different ViaInfo's, which can be used in eu.mihosoft.freerouting.interactive and automatic routing. * * @author Alfons Wirtz */ -public class ViaInfos implements java.io.Serializable, board.ObjectInfoPanel.Printable +public class ViaInfos implements java.io.Serializable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable { /** * Adds a via info consisting of padstack, clearance class and drill_to_smd_allowed. @@ -100,10 +100,10 @@ public class ViaInfos implements java.io.Serializable, board.ObjectInfoPanel.Pri return this.list.remove(p_via_info); } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("vias") + ": "); int counter = 0; boolean first_time = true; diff --git a/src/main/java/eu/mihosoft/freerouting/rules/ViaRule.java b/src/main/java/eu/mihosoft/freerouting/rules/ViaRule.java index 6145e4b..f2788fa 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/ViaRule.java +++ b/src/main/java/eu/mihosoft/freerouting/rules/ViaRule.java @@ -18,7 +18,7 @@ * Created on 31. Maerz 2005, 06:44 */ -package rules; +package eu.mihosoft.freerouting.rules; import java.util.List; import java.util.LinkedList; @@ -29,7 +29,7 @@ import java.util.LinkedList; * * @author Alfons Wirtz */ -public class ViaRule implements java.io.Serializable, board.ObjectInfoPanel.Printable +public class ViaRule implements java.io.Serializable, eu.mihosoft.freerouting.board.ObjectInfoPanel.Printable { /** Empty via rule. Must nott be changed. */ @@ -88,7 +88,7 @@ public class ViaRule implements java.io.Serializable, board.ObjectInfoPanel.Prin /** * Returns true, if this rule contains a via with padstack p_padstack */ - public boolean contains_padstack(library.Padstack p_padstack) + public boolean contains_padstack(eu.mihosoft.freerouting.library.Padstack p_padstack) { for (ViaInfo curr_info : this.list) { @@ -137,10 +137,10 @@ public class ViaRule implements java.io.Serializable, board.ObjectInfoPanel.Prin return true; } - public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale) + public void print_info(eu.mihosoft.freerouting.board.ObjectInfoPanel p_window, java.util.Locale p_locale) { java.util.ResourceBundle resources = - java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale); + java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale); p_window.append_bold(resources.getString("via_rule_2") + " "); p_window.append_bold(this.name); p_window.append_bold(":"); diff --git a/src/main/java/eu/mihosoft/freerouting/rules/package.html b/src/main/java/eu/mihosoft/freerouting/rules/package.html index 9ecf25d..bbd27ac 100644 --- a/src/main/java/eu/mihosoft/freerouting/rules/package.html +++ b/src/main/java/eu/mihosoft/freerouting/rules/package.html @@ -16,4 +16,4 @@ --> -Contains rules and restrictions for the items on a printed circuit board. \ No newline at end of file +Contains eu.mihosoft.freerouting.rules and restrictions for the items on a printed circuit eu.mihosoft.freerouting.board. \ No newline at end of file diff --git a/src/main/java/eu/mihosoft/freerouting/tests/Validate.java b/src/main/java/eu/mihosoft/freerouting/tests/Validate.java index 5dac01a..bda4fa6 100644 --- a/src/main/java/eu/mihosoft/freerouting/tests/Validate.java +++ b/src/main/java/eu/mihosoft/freerouting/tests/Validate.java @@ -18,37 +18,37 @@ * Created on 7. Dezember 2002, 18:26 */ -package tests; +package eu.mihosoft.freerouting.tests; -import geometry.planar.IntOctagon; -import geometry.planar.IntPoint; -import geometry.planar.Polyline; -import geometry.planar.TileShape; +import eu.mihosoft.freerouting.geometry.planar.IntOctagon; +import eu.mihosoft.freerouting.geometry.planar.IntPoint; +import eu.mihosoft.freerouting.geometry.planar.Polyline; +import eu.mihosoft.freerouting.geometry.planar.TileShape; import java.util.Collection; import java.util.Iterator; -import board.Item; -import board.BasicBoard; -import board.PolylineTrace; -import board.SearchTreeObject; +import eu.mihosoft.freerouting.board.Item; +import eu.mihosoft.freerouting.board.BasicBoard; +import eu.mihosoft.freerouting.board.PolylineTrace; +import eu.mihosoft.freerouting.board.SearchTreeObject; /** - * Some consistancy checking on a routing board. + * Some consistancy checking on a routing eu.mihosoft.freerouting.board. * * @author Alfons Wirtz */ public class Validate { /** - * Does some consistancy checking on the routing board and may be some + * Does some consistancy checking on the routing eu.mihosoft.freerouting.board and may be some * other actions. * Returns false, if problems were detected. */ public static boolean check(String p_s, BasicBoard p_board) { - if (p_board.get_test_level() == board.TestLevel.RELEASE_VERSION) + if (p_board.get_test_level() == eu.mihosoft.freerouting.board.TestLevel.RELEASE_VERSION) { return true; } @@ -64,7 +64,7 @@ public class Validate { if (first_time) { - System.out.println(" validate board is on "); + System.out.println(" validate eu.mihosoft.freerouting.board is on "); first_time = false; } Collection l = p_board.overlapping_objects(surr_oct, layer) ; @@ -271,11 +271,11 @@ public class Validate while (it.hasNext()) { Item curr_item = it.next(); - if (!(curr_item instanceof board.Trace)) + if (!(curr_item instanceof eu.mihosoft.freerouting.board.Trace)) { continue; } - if(((board.Trace)curr_item).is_cycle()) + if(((eu.mihosoft.freerouting.board.Trace)curr_item).is_cycle()) { System.out.print(p_s); System.out.println(": cycle found"); @@ -295,9 +295,9 @@ public class Validate while (it.hasNext()) { Item curr_ob = it.next(); - if(curr_ob instanceof board.Trace) + if(curr_ob instanceof eu.mihosoft.freerouting.board.Trace) { - if (((board.Trace)curr_ob).contains_net(p_net_no)) + if (((eu.mihosoft.freerouting.board.Trace)curr_ob).contains_net(p_net_no)) { ++found_traces; } @@ -315,7 +315,7 @@ public class Validate } /** - * checks, if there are unconnectedtraces ore vias on the board + * checks, if there are unconnectedtraces ore vias on the eu.mihosoft.freerouting.board */ static public boolean unconnnected_routing_items(String p_s, BasicBoard p_board) { diff --git a/src/main/java/eu/mihosoft/freerouting/tests/package.html b/src/main/java/eu/mihosoft/freerouting/tests/package.html index a54dc13..841f34b 100644 --- a/src/main/java/eu/mihosoft/freerouting/tests/package.html +++ b/src/main/java/eu/mihosoft/freerouting/tests/package.html @@ -16,4 +16,4 @@ --> -Contains functions for testing and checking the consistancy of the board database. \ No newline at end of file +Contains functions for testing and checking the consistancy of the eu.mihosoft.freerouting.board database. \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_de.properties new file mode 100644 index 0000000..251bf7f --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_de.properties @@ -0,0 +1,10 @@ +# German version of language dependent text of the class BoardMenuInfo +title = Platinen-Layout +confirm_cancel = Bitte Abbrechen best\u00E4tigen +error_1 = Lesen der Gui-Defaults-Datei ist fehlgeschlagen +error_2 = Speichern des Platinendesigns ist fehhlgeschlagen +error_3 = Schreiberlaubnis verweigert +error_4 = Speichern des Board-Frames ist fehlgeschlagen +error_5 = Sclie\u00DFen der Output-Datei ist fehlgeschlagen +error_6 = Lesen der .dsn-Datei fehlgeschlagen +error_7 = Outline fehlt in der .dsn-Datei \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_en.properties new file mode 100644 index 0000000..5bccd2b --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardFrame_en.properties @@ -0,0 +1,10 @@ +# English version of language dependent text of the class BoardMenuInfo +title = Board Layout +confirm_cancel = Please confirm cancel +error_1 = unable to read file gui defaults file +error_2 = unable to save board to file +error_3 = sorry, no write permission +error_4 = unable to write board frame to file +error_5 = unable to close output file +error_6 = unable to read .dsn-file +error_7 = outline missing in .dsn-file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_de.properties new file mode 100644 index 0000000..ba40021 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_de.properties @@ -0,0 +1,9 @@ +# German version of language dependent text of the class BoardMenuDisplay +display = Display +object_visibility = Objekt-Sichtbarkeit +object_visibility_tooltip = die Abbildungsintensität eines Objekts ändern +layer_visibility = Lagen-Sichtbarkeit +layer_visibility_tooltip = die Sichtbarkeit einzelner Lagen ändern +colors = Farben +colors_tooltip = Die Farben der Objekte auf der Platine ändern +miscellaneous = sonstiges diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_en.properties new file mode 100644 index 0000000..64211ab --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuDisplay_en.properties @@ -0,0 +1,9 @@ +# English version of language dependent text of the class BoardMenuDisplay +display = Display +object_visibility = Object Visibility +object_visibility_tooltip = to change the drawing intensity of an object +layer_visibility = Layer Visibility +layer_visibility_tooltip = to change the visibility of individual layers +colors = Colors +colors_tooltip = to change the colors of the board objects on the screen +miscellaneous = Miscellaneous \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_de.properties new file mode 100644 index 0000000..8354d36 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_de.properties @@ -0,0 +1,45 @@ +# German version of language dependent text of the class BoardMenuFile + +file = Datei +save = speichern +save_tooltip = speichert das Design auf Platte im internen .bin Dateiformat +save_message = Design-Datei gespeichert +save_and_exit = speichern und beenden +save_and_exit_tooltip = beendet das Programm nach Speichern des Designs auf Platte +cancel_and_exit = abbrechen und beenden +cancel_and_exit_tooltip = beendet das Programm ohne das Design zu speichern +save_as = speichern unter +save_as_tooltip = Erweiterungen .bin für binär oder .dsn für Specctra-Text-Format können verwendet werden +generate_logfile = Log-Datei erzeugen +generate_logfile_tooltip = schreibt ab jetzt die interaktiven Aktionen in eine Log-Datei +replay_logfile = Log-Datei abspielen +replay_logfile_tooltip = wiederholt die in einer Log_Datei gespeicherten interactiven Aktionen +session_file = Specctra-Session-Datei exportieren +session_file_tooltip = Schreibt eine Session-Datei im .ses-Format von Specctra +eagle_script = Eagle-Session-Script exportieren +eagle_script_tooltip = Schreibt die Änderungen im Routing in ein Eagle-Script zum Update der entsprechenden .brd-Datei in Eagle +settings = GUI-Einstellungen als Default speichern +settings_tooltip = Speichert die aktuellen Einstellungen im graphischen User-Interface als default +confirm = Möchten Sie auch die in diesem Programm erzeugten Regeln zur späteren Wiederverwendung speichern? +message_1 = Speichern der Design-Datei ist fehlgeschlagen +message_2 = die Design-Datei wird von jetzt ab gespeichert unter dem Namen +message_3 = legale Dateierweiterungen sind .bin and .dsn +message_4 = Textdatei +message_5 = im Specctra-Textformat geschrieben +message_6 = Schreiben auf Textdatei +message_7 = ist fehlgeschlagen +message_8 = Erzeugen der Log-Datei ist fehlgeschlagen. +message_9 = Schreibe Log-Datei +message_10 = Lesen der Log_datei ist fehlgeschlagen +message_11 = Session-Datei +message_12 = im Specctra-Format geschrieben +message_13 = schreibe Session-Datei +message_14 = Eagle-Script-Datei +message_15 = geschrieben +message_16 = erzeuge Eagle-Script-Datei +message_17 = GUI-Default-Einstellungen gespeichert +message_18 = Speichern der GUI-Default-Einstellungen ist fehlgeschlagen +message_19 = Speichern fehlgeschlagen da Datei nicht mit .dsn endet +message_20 = Das Host-Cad-System erwartet evtl. den Session-Dateinamen +message_21 = Bitte Datei gegebenenfalls umbenennen +message_22 = Eagle erwartet evtl. die Dateierweiterung .scr für das Script-File. \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_en.properties new file mode 100644 index 0000000..e7dfe37 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuFile_en.properties @@ -0,0 +1,44 @@ +# English version of language dependent text of the class BoardMenuFile +file = File +save = Save +save_tooltip = saves the design to disk in the internal .bin file format +save_message = design file saved +save_and_exit = Save and Exit +save_and_exit_tooltip = exits the program after saving the design to disk +cancel_and_exit = Cancel and Exit +cancel_and_exit_tooltip = exits the program without saving the design +save_as = Save as +save_as_tooltip = use extensions .bin for binary and .dsn for Specctra text format +generate_logfile = Generate Logfile +generate_logfile_tooltip = starts writing the interactive actions to a logfile +replay_logfile = Replay Logfile +replay_logfile_tooltip = repeats the interactive actions stored in a logfile +session_file = Export Specctra Session File +session_file_tooltip = writes a session file in the Specctra .ses format +eagle_script = Export Eagle Session Script +eagle_script_tooltip = creates an eagle script to export the changes in routing +settings = Save GUI Settings as Default +settings_tooltip = saves the current settings of the graphical user interface as default +confirm = Save also the rules created in this program for later reuse? +message_1 = unable to save design file +message_2 = saving design file from now on as +message_3 = legal file extensions are .bin and .dsn +message_4 = textfile +message_5 = in Specctra text format written +message_6 = writing to textfile +message_7 = failed +message_8 = unable to create logfile +message_9 = writing logfile +message_10 = unable to read logfile +message_11 = session file +message_12 = in Specctra format written +message_13 = writing session file +message_14 = Eagle script file +message_15 = written +message_16 = creating Eagle script file +message_17 = GUI default settings saved +message_18 = saving GUI default settings failed +message_19 = File not saved because file extension .dsn expected +message_20 = Host cad system might expect the session file name +message_21 = Please rename the file if necessary +message_22 = Eagle might expect the script file extension .scr \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_de.properties new file mode 100644 index 0000000..2eb800a --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_de.properties @@ -0,0 +1,5 @@ +# German version of language dependent text of the class BoardMenuHelp +help = Hilfe +contents = allgemeine Hilfe +direct_help = kontextsensitive Hilfe +about = über diese Software diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_en.properties new file mode 100644 index 0000000..0d8c2c2 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuHelp_en.properties @@ -0,0 +1,5 @@ +# English version of language dependent text of the class BoardMenuHelp +help = Help +contents = Help Contents +direct_help = Help Context +about = About this Software diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_de.properties new file mode 100644 index 0000000..cf05faf --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_de.properties @@ -0,0 +1,10 @@ +# German version of language dependent text of the class BoardMenuInfo +info = Info +incompletes = offene Verbindungen +length_violations = Längenverletzungen +clearance_violations = Clearance-Verletzungen +library_packages = Bibliotheks-Packages +library_padstacks = Bibliotheks-Padstacks +board_components = platzierte Bauteile +unconnected_route = nicht verbundener Route +route_stubs = Route-Stummel \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_en.properties new file mode 100644 index 0000000..de3f11a --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuInfo_en.properties @@ -0,0 +1,10 @@ +# English version of language dependent text of the class BoardMenuInfo +info = Info +incompletes = Incompletes +length_violations = Length Violations +clearance_violations = Clearance Violations +library_packages = Library Packages +library_padstacks = Library Padstacks +board_components = Placed Components +unconnected_route = Unconnected Route +route_stubs = Route Stubs \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_de.properties new file mode 100644 index 0000000..adc23eb --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_de.properties @@ -0,0 +1,4 @@ +# German version of language dependent text of the class BoardMenuOther +other = Sonstiges +snapshots = Snapshots +snapshots_tooltip = öffnet Fenster für interactive Snapshots diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_en.properties new file mode 100644 index 0000000..9a1e24c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuOther_en.properties @@ -0,0 +1,4 @@ +# English version of language dependent text of the class BoardMenuOther +other = Other +snapshots = Snapshots +snapshots_tooltip = opens window for interactive snapshots diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_de.properties new file mode 100644 index 0000000..e4dc9e3 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_de.properties @@ -0,0 +1,6 @@ +# German version of language dependent text of the class BoardMenuParameter +parameter = Parameter +select = selektieren +route = routen +autoroute = autorouten +move = platzieren diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_en.properties new file mode 100644 index 0000000..45276a6 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuParameter_en.properties @@ -0,0 +1,6 @@ +# English version of language dependent text of the class BoardMenuParameter +parameter = Parameter +select = Select +route = Route +autoroute = Autoroute +move = Move diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_de.properties new file mode 100644 index 0000000..8a652ef --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_de.properties @@ -0,0 +1,6 @@ +# German version of language dependent text of the class BoardMenuRules +rules = Regeln +clearance_matrix = Clearance-Matrix +vias = Vias +nets = Netze +net_classes = Netzklassen diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_en.properties new file mode 100644 index 0000000..22692d2 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardMenuRules_en.properties @@ -0,0 +1,6 @@ +# English version of language dependent text of the class BoardMenuRules +rules = Rules +clearance_matrix = Clearance Matrix +vias = Vias +nets = Nets +net_classes = Net Classes \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_de.properties new file mode 100644 index 0000000..0adafc7 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_de.properties @@ -0,0 +1,5 @@ +# German version of language dependent text of the class BoardPanelStatus +status_line = Statuszeile +additional_text_field = zusätzliches Textfeld +current_layer = aktuelle Lage: Bauteil-Seite +cursor = Cursor: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_en.properties new file mode 100644 index 0000000..d17b7c4 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardPanelStatus_en.properties @@ -0,0 +1,5 @@ +# English version of language dependent text of the class BoardPanelStatus +status_line = status line +additional_text_field = additional text field +current_layer = current layer: Component Side +cursor = cursor: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_de.properties new file mode 100644 index 0000000..721164c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_de.properties @@ -0,0 +1,43 @@ +# German version of language dependent text of the class BoardToolbarSelectedItem +info = Info +info_tooltip = zeigt Informationen \u00FCber die ausgew\u00E4hlten Objekte (i) +cancel = Abbrechen +cancel_tooltip = das Auswahlmen\u00FC verlassen (Esc) +delete = L\u00F6schen +delete_tooltip = die unfixierten ausgew\u00E4hlten Objekte l\u00F6schen (Entf) +cutout = Ausschneiden +cutout_tooltip = den ausgew\u00E4hlten Route innerhalb eines Rechtecks l\u00F6schen (d) +fix = Fix +fix_tooltip = die ausgew\u00E4hlten Objekte fixieren (f) +unfix = Unfix +unfix_tooltip = die Fixierung der ausgew\u00E4hlten Objekte aufheben (u) +spacing = Clearance +spacing_tooltip = den ausgew\u00E4hlten Objekten eine neue Clearance-Klasse zuweisen +pull_tight = Gl\u00E4tten +pull_tight_tooltip = Die ausgew\u00E4hlten Bahnen und Vias glattt ziehen (p) +autoroute = Autoroute +autoroute_tooltip = die ausgew\u00E4hlten Objekte autorouten (a) +fanout = Fanout +fanout_tooltip = die ausgew\u00E4hlten SMD-Pins bis zum ersten Via autorouten +nets = Netze +nets_tooltip = die Auswahl auf ganze Netze erweitern (n) +conn_sets = Zush. +conn_sets_tooltip = die Auswahl auf ganze zusammenh\u00E4ngende Teilmengen erweitern (s) +connections = Verb. +connections_tooltip = die Auswahl auf ganze Verbindungen erweitern (e) +components = Bauteile +components_tooltip = die Auswahl auf ganze Bauteile erweitern (b) +new_net = Neues Netz +new_net_tooltip = die ausgew\u00E4hlten Objekte einem neuen Netz zuweisen +new_component = Neues Bauteil +new_component_tooltip = die ausgew\u00E4hlten Objekte einem neuen Bauteil zuweisen +violations = Verletzungen +violations_tooltip = Das Zeigen der Clearance-Verletzungen der ausgew\u00E4hlten Objekte an- oder abschalten (v) +zoom_selection = Auswahl abbilden +zoom_selection_tooltip = ein umgebendes Rechteck der ausgew\u00E4hlten Objekte abbilden(w) +zoom_all = Alles abb. +zoom_all_tooltip = die gesamte Platine abbilden (a) +zoom_region = Ausschnitt abb. +zoom_region_tooltip = ein Rechteck der Platine zum Abbilden ausw\u00E4hlen (r) +select_clearance_class = W\u00E4hle Clearance-Klasse +assign_clearance_class = Clearance-Klasse zuweisen diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_en.properties new file mode 100644 index 0000000..8a02d0c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbarSelectedItem_en.properties @@ -0,0 +1,43 @@ +# English version of language dependent text of the class BoardToolbarSelectedItem +info = Info +info_tooltip = displays information about the selected items (i) +cancel = Cancel +cancel_tooltip = to cancel the current selection (esc) +delete = Delete +delete_tooltip = to delete the selected items which are not fixed (del) +cutout = Cutout +cutout_tooltip = to delete the selected route inside a rectangle (d) +fix = Fix +fix_tooltip = to fix the selected items (f) +unfix = Unfix +unfix_tooltip = to unfix the selected items (u) +spacing = Clearance +spacing_tooltip = to assign a new clearance class to the selected items +pull_tight = Pull Tight +pull_tight_tooltip = to optimize the selected traces and vias (p) +autoroute = Autoroute +autoroute_tooltip = to autoroute the selected items (a) +fanout = Fanout +fanout_tooltip = to autoroute the selected SMD pins until the first via +nets = Nets +nets_tooltip = to extend the selection to whole nets (n) +conn_sets = Conn. Sets +conn_sets_tooltip = to extend the selection to whole connected sets (s) +connections = Connections +connections_tooltip = to extend the selection until the next fork or terminal item (e) +components = Components +components_tooltip = to extend the selection to whole components (b) +new_net = New Net +new_net_tooltip = to assign the selected items to a new net +new_component = New Component +new_component_tooltip = to assign the selected items to a new component +violations = Violations +violations_tooltip = to show or hide the clearance violations of the selected items (v) +zoom_selection = Zoom Selection +zoom_selection_tooltip = to display a window containing the selected items (w) +zoom_all = Zoom All +zoom_all_tooltip = to display the whole board (a) +zoom_region = Zoom Region +zoom_region_tooltip = to display a region of the board (r) +select_clearance_class = Select clearance class +assign_clearance_class = Assign Clearance Class \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_de.properties new file mode 100644 index 0000000..a9cbc74 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_de.properties @@ -0,0 +1,22 @@ +# German Version of language dependent text of the board toolbar +select_button = Selektieren +select_button_tooltip = linke Maustaste selektiert Objekte (s) +route_button = Routen +route_button_tooltip = linke Maustaste beginnt eine neue Bahn (r) +drag_button = Ziehen +drag_button_tooltip = Objekte mit gedr\u00fcckter linker Maustaste ziehen oder Bahnen vom leeren Raum aus schieben(d) +undo_button = Undo +undo_button_tooltip = die letzte \u00c4nderung r\u00fcckg\u00e4ngig machen (u) +redo_button = Redo +redo_button_tooltip = die letzte \u00c4nderung wiederherstellen (b) +incompletes_button = Incompletes +incompletes_button_tooltip = das Zeigen der offenen Verbindungen an- oder abschalten (g) +violations_button = Verletzungen +violations_button_tooltip = das Zeigen der Clearance-Verletzungen an- oder abschalten (v) +autoroute_button = Autorouter +autoroute_button_tooltip = den Batch-Autorouter starten +display_all_button = Alles abbilden +display_all_button_tooltip = die gesamte Platine abbilden (a) +display_region_button = Ausschnitt abbilden +display_region_button_tooltip = ein Rechteck der Platine zum Abbilden ausw\u00e4hlen (f) +unit_button = Unit: \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_en.properties new file mode 100644 index 0000000..b47ba07 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/BoardToolbar_en.properties @@ -0,0 +1,23 @@ +# English version of language dependent text of the board toolbar + +select_button = Select +select_button_tooltip = left button selects items (s) +route_button = Route +route_button_tooltip = left button starts a new trace (r) +drag_button = Drag +drag_button_tooltip = to drag items with the left button or to push traces out of empty space (d) +undo_button = Undo +undo_button_tooltip = to undo the last change (u) +redo_button = Redo +redo_button_tooltip = to redo the last change (b) +incompletes_button = Incompletes +incompletes_button_tooltip = to display or hide the incomplete connections (g) +violations_button = Violations +violations_button_tooltip = to display or hide the clearance violations (v) +autoroute_button = Autorouter +autoroute_button_tooltip = to start the batch autorouter +display_all_button = Zoom All +display_all_button_tooltip = to display the whole board (a) +display_region_button = Zoom Region +display_region_button_tooltip = to select a region of the board for display(f) +unit_button = Unit: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_de.properties new file mode 100644 index 0000000..d78a58e --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_de.properties @@ -0,0 +1,13 @@ +# German version of language dependent text of the cleanup windows in the info menu +at = bei +net = Netz +no_route_stubs_found = keine Route-Stummel gefunden +no_unconnected_route_found = keine nicht verbundenen Traces oder Vias gefunden +on_layer = auf Lage +route_stubs = Route-Stummel +stub_net = Stummel Netz +trace = Trace +trace_count = Trace-Anzahl +unconnected_route = Nicht verbundener Route +via = Via +via_count = Via-Anzahl diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_en.properties new file mode 100644 index 0000000..a138280 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/CleanupWindows_en.properties @@ -0,0 +1,13 @@ +# English version of language dependent text of the cleanup windows in the info menu +at = at +net = Net +no_route_stubs_found = no route stubs found +no_unconnected_route_found = no unconnected traces or vias found +on_layer = on layer +route_stubs = Route Stubs +stub_net = stub net +trace = Trace +trace_count = trace count +unconnected_route = Unconnected Route +via = Via +via_count = via count \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_de.properties new file mode 100644 index 0000000..9528c42 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_de.properties @@ -0,0 +1,40 @@ +# German version of the default file with language dependent text +add_corner = Ecke hinzufügen (linke Maustaste) +all = alle +cancel = abbrechen (Esc) +cancel_route = Route abbrechen(Esc) +center_display = Bild zentrieren (c) +change_layer = Lage wechseln +change_layer_tooltip = geht auch mit Zifferntaste oder '+' '-' +close = schließen +color_manager = Farbverwaltung +components = Bauteile +copy = kopieren +done = beenden (Leertaste) +end_route = Route beenden (linke Maustaste) +generate_snapshot = Snapshot erzeugen (s) +incompletes = Offene Verbindungen +inner = innere +insert = einfügen (linke Maustaste) +layer_changed_to = Lage gewechselt nach +layer_visibility = Lagen-Sichtbarkeit +layer_visibility_header = Regler zum Ändern der Sichtbarkeit von Lage +maximum_all = Alle Maximum +maximum_all_tooltip = schiebt alle Regler nach rechts +minimum_all = Alle Minimum +minimum_all_tooltip = schiebt alle Regler nach links +move = verschieben (m) +packages = Packages +padstacks = Padstacks +pick_a_color = Wählen Sie eine Farbe +route_completed = Platine vollständig entflochten +zoom = zoomen +zoom_in = größer (z) +zoom_out = kleiner (o) + + + + + + + diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_en.properties new file mode 100644 index 0000000..8c40873 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/Default_en.properties @@ -0,0 +1,41 @@ +# English version of the default file with language dependent text +add_corner = add corner (left button) +all = all +cancel = cancel (Esc) +cancel_route = cancel route (Esc) +center_display = center display (c) +change_layer = change layer +change_layer_tooltip = also possible with number key or '+' '-' +close = close +color_manager = Color Manager +components = Components +copy = copy +done = done (Space) +end_route = end route (left button) +generate_snapshot = generate snapshot (s) +incompletes = Incompletes +inner = inner +insert = insert (left button) +layer_changed_to = layer changed to +layer_visibility = Layer Visibility +layer_visibility_header = Use slider to modify the visibility on layer +maximum_all = Maximum All +maximum_all_tooltip = pushs all sliders to the right +minimum_all = Minimum All +minimum_all_tooltip = pushs all sliders to the left +move = move (m) +packages = Packages +padstacks = Padstacks +pick_a_color = Pick a Color +route_completed = route completed +zoom = zoom +zoom_in = in (z) +zoom_out = out (o) + + + + + + + + diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_de.properties new file mode 100644 index 0000000..80c8e46 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_de.properties @@ -0,0 +1,16 @@ +# German version of language dependent text of the class DisplayMisc +title = Abbildung sonstiges +cross_hair_cursor = Crosshair-Cursor +small = klein +big = groß +cursor_checkbox_tooltip = Shortcut ist die Komma-Taste +rotation = Platinenrotation: +none = keine +90_degree = 90 Grad +180_degree = 180 Grad +-90_degree = -90 Grad +board_mirroring = Platinenspiegelung: +left_right = links rechts +top_bottom = oben unten +layer_dimming = automatisches Lagen-Dimmen: +layer_dimming_tooltip = Mit dem Regler können Sie die Intensität des automatischen Lagen-Dimmens verändern diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_en.properties new file mode 100644 index 0000000..5dd6f85 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/DisplayMisc_en.properties @@ -0,0 +1,16 @@ +# English version of language dependent text of the class DisplayMisc +title = Display Miscellaneous +cross_hair_cursor = crosshair cursor +small = small +big = big +cursor_checkbox_tooltip = Shortcut is the comma-key +rotation = board rotation: +none = none +90_degree = 90 degree +180_degree = 180 degree +-90_degree = -90 degree +board_mirroring = board mirroring: +left_right = left right +top_bottom = top bottom +layer_dimming = automatic layer dimming: +layer_dimming_tooltip = Use slider to change intensity of automatic layer dimming diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_de.properties new file mode 100644 index 0000000..8f6a083 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_de.properties @@ -0,0 +1,25 @@ +# German version of language dependent text of the class MainApplication + +title = Freerouter +confirm_cancel = Bitte Verlassen des Programms best\u00E4tigen +loading_design = Lade Design +router_demonstrations = Demonstrations-Beispiele +router_demonstrations_tooltip = spiele Demonstrations-Beispiele f\u00FCr den Router ab +sample_designs = Beispiel-Designs +sample_designs_tooltip = Beispiel-Platinen-Designs im Netz \u00F6ffnen +open_own_design = Eigenes Design \u00F6ffnen +open_own_design_tooltip = ein Platinen-Design im Specctra .dsn Format auf der eigenen Festplatte \u00F6ffnen +restore_defaults = System-Defaults wiederherstellen +restore_defaults_tooltip = l\u00F6scht die vom User gespeicherten Einstellungen und stellt die System-Defaults wieder her. +defaults_restored = System-Voreinstellungen wiederhergestellt. +nothing_to_restore = nichts wiederherzustellen +confirm_delete = Bitte das L\u00F6schen der von Ihnen gespeicherten Einstellungen best\u00E4tigen +confirm_import_rules = Bitte das Importieren der gespeicherten Regeln best\u00E4tigen\nBeachten Sie dass dabei aus dem Host-System importierte Regeln \u00FCberschrieben werden k\u00F6nnen +message_3 = kann Platinendesign nicht \u00F6ffnen +message_4 = Design-Datei +message_5 = ge\u00F6ffnet +message_6 = Datei mit Namen +message_7 = nicht gefunden +message_8 = kann Designfile nicht lesen! +user_online_message_1 = Internet Verbindung zum Starten der Freerouter Anwendung erforderlich! +user_online_message_2 = Danach k\u00F6nnen Sie die Verbindung wieder abschalten! \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_en.properties new file mode 100644 index 0000000..407b563 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/MainApplication_en.properties @@ -0,0 +1,25 @@ +# English version of language dependent text of the class MainApplication + +title = Freerouter +confirm_cancel = Please confirm exit +loading_design = Loading design +router_demonstrations = Router Demonstrations +router_demonstrations_tooltip = replay demonstration examples of the router +sample_designs = Sample Designs +sample_designs_tooltip = open example board designs in the net +open_own_design = Open Your Own Design +open_own_design_tooltip = open a board design in the Specctra .dsn format on your own local disc +restore_defaults = Restore System Defaults +restore_defaults_tooltip = deletes the settings stored by the user and restores the system defaults +defaults_restored = system default settings restored +nothing_to_restore = nothing to restore +confirm_delete = Please confirm deleting your stored settings +confirm_import_rules = Please confirm importing stored rules\nBeware that rules imported from the the host system may be overwritten +message_3 = unable to open board design +message_4 = design file +message_5 = opened +message_6 = File with name +message_7 = not found +message_8 = unable to read design file! +user_online_message_1 = Internet connection required to start the Freerouter application! +user_online_message_2 = After that you can switch the connection off again! \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_de.properties new file mode 100644 index 0000000..d47b163 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_de.properties @@ -0,0 +1,9 @@ +# German version of language dependent text of the class PopupMenuMain +select_item = Objekt selektieren (i) +start_route = Route starten (t) +swap_pin = Pin tauschen (w) +create_keepout = Sperrfläche konstruieren +tile = convexes Polygon +circle = Kreis +polygon = Polygon +hole = Loch diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_en.properties new file mode 100644 index 0000000..682f33b --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMain_en.properties @@ -0,0 +1,9 @@ +# English version of language dependent text of the class PopupMenuMain +select_item = select item (i) +start_route = start route (t) +swap_pin = swap pin (w) +create_keepout = create keepout +tile = tile +circle = circle +polygon = polygon +hole = hole diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_de.properties new file mode 100644 index 0000000..e99d03c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_de.properties @@ -0,0 +1,13 @@ +# German version of language dependent text of the class PopupMenuMove +turn = drehen +90_degree = 90 Grad (+) +180_degree = 180 Grad (*) +-90_degree = -90 Grad (-) +45_degree = 45 Grad +135_degree = 135 Grad +-135_degree = -135 Grad +-45_degree = -45 Grad +change_side = Seite wechseln(/) +reset_rotation = Rotation zurücksetzen +insert = einfügen (linke Maustaste) +cancel = abbrechen (Esc) diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_en.properties new file mode 100644 index 0000000..022168d --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/PopupMenuMove_en.properties @@ -0,0 +1,13 @@ +# English version of language dependent text of the class PopupMenuMain +turn = turn +90_degree = 90 degree (+) +180_degree = 180 degree (*) +-90_degree = -90 degree (-) +45_degree = 45 degree +135_degree = 135 degree +-135_degree = -135 degree +-45_degree = -45 degree +change_side = change side (/) +reset_rotation = reset rotation +insert = insert (left button) +cancel = cancel (Esc) \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_de.properties new file mode 100644 index 0000000..9870af8 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_de.properties @@ -0,0 +1,7 @@ +# German version of language dependent text of the class WindowAbout +title = \u00dcber diese Software +description = Freie Software zum Entflechten von Leiterplatten +warranty = Wir \u00fcbernehmen keinerlei Garantie oder Gew\u00e4hrleistung! +version = Version: +homepage = Homepage: http://freerouting.mihosoft.eu (fr\u00fcher http://www.freerouting.net) +support = Kontakt: info@michaelhoffer.de (fr\u00fcher support@freerouting.net) diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_en.properties new file mode 100644 index 0000000..7bbc230 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAbout_en.properties @@ -0,0 +1,7 @@ +# English version of language dependent text of the class WindowAbout +title = About this software +description = Free software for Printed Circuit Board Routing +version = Version: +warranty = This program comes with absolutely no warranty! +homepage = Homepage: http://freerouting.mihosoft.eu (was http://www.freerouting.net) +support = Contact: info@michaelhoffer.de (was support@freerouting.net) diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_de.properties new file mode 100644 index 0000000..2c79dbb --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_de.properties @@ -0,0 +1,6 @@ +# German version of language dependent text of the class WindowAssignNetClass +title = Netzklasse zuweisen +net_name = Netzname +class_name = Klassenname +net_name_tooltip = Der Name des Netzes +class_name_tooltip = Die zugewiesene Netzklasse diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_en.properties new file mode 100644 index 0000000..19cbc06 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAssignNetClass_en.properties @@ -0,0 +1,6 @@ +# English version of language dependent text of the class WindowAssignNetClass +title = Assign Net Class +net_name = net name +class_name = class name +net_name_tooltip = The net name +class_name_tooltip = The assigned net class \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_de.properties new file mode 100644 index 0000000..9308de1 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_de.properties @@ -0,0 +1,25 @@ +# German version of language dependent text of the class WindowAutorouteParameter +title = Autoroute-Einstellungen +layer = Lage: +active = aktiv: +preferred_direction = Vorzugsrichtung: +horizontal = horizontal +vertical = vertikal +detail_parameter = Detail-Einstellungen +detail_autoroute_parameter = Detailierte Autoroute-Einstellungen +trace_costs_on_layer = Trace-Kosten auf Lage: +in_preferred_direction in Vorzugsrichtung: +against_preferred_direction gegen die Vorzugsrichtung: +with_fanout = Fanout vorrouten: +vias_allowed = Vias erlaubt: +via_costs Via-Kosten: +plane_via_costs Stromlagen-Via-Kosten: +start_ripup_costs = Ripup-Anfangskosten: +start_pass = Start-Pass: +speed = Tempo: +fast = schnell +slow = langsam +passes = Passes: +fanout = Fanout +autoroute = Autoroute +postroute = Postroute diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_en.properties new file mode 100644 index 0000000..958abf6 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowAutorouteParameter_en.properties @@ -0,0 +1,25 @@ +# English version of language dependent text of the class WindowRouteParameter +title = Autoroute Parameter +layer = Layer: +active = Active: +preferred_direction = Preferred Direction: +horizontal = horizontal +vertical = vertical +detail_parameter = Detail parameter +detail_autoroute_parameter = Detail Autoroute Parameter +trace_costs_on_layer = Trace costs on layer: +in_preferred_direction In preferred direction: +against_preferred_direction Against preferred direction: +with_fanout = Preroute fanout: +vias_allowed = Vias allowed: +via_costs Via costs: +plane_via_costs Powerplane via costs: +start_ripup_costs = Ripup start costs: +start_pass = Start pass: +speed = Speed: +fast = fast +slow = slow +passes = Passes: +fanout = Fanout +autoroute = Autoroute +postroute = Postroute diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_de.properties new file mode 100644 index 0000000..b51540f --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_de.properties @@ -0,0 +1,16 @@ +# English version of language dependent text of the class WindowClearanceClass +title = Clearance-Matrix +layer = Lage: +layer_tooltip = Lage einstellen, wo die die Werte der Clearance-Matrix geändert werden können +add_class = Klasse hinzufügen +add_class_tooltip = Eine neue Clearance-Klasse Klasse hinzufügen +prune = Trimmen +prune_tooltip = Redundante Klassen löschen +new_name = Bitte geben Sie den Namen der neuen Klasse ein +confirm_remove = Bitte bestätigen Sie das Löschen der Klasse +class = Klasse +the_class = der Klasse +the_classes = den Klassen +and = und +already_assigned = Objekte sind schon zugewiesen zu +change_anyway = !\nClearance-Regel trotzdem ändern? diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_en.properties new file mode 100644 index 0000000..d5dc4d6 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceMatrix_en.properties @@ -0,0 +1,16 @@ +# English version of language dependent text of the class WindowClearanceClass +title = Clearance Matrix +layer = Layer: +layer_tooltip = Set the layer, where the clearance matrix can be changed +add_class = Add Class +add_class_tooltip = Append a new clearance class +prune = Trim +prune_tooltip = Remove redundant classes +new_name = Please enter the name of the new class +confirm_remove = Please confirm removing class +class = class +the_class = the class +the_classes = the classes +and = and +already_assigned = Items already assigned to +change_anyway = !\nChange clearance anyway? \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_de.properties new file mode 100644 index 0000000..66bfe69 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_de.properties @@ -0,0 +1,14 @@ +# German version of language dependent text of the class WindowClearanceViolations +title = Clearance-Verletzungen +list_empty_message = keine Verletzungen gefunden +at = bei +on_layer = auf Lage +pin = Pin +via = Via +trace = Bahn +conduction_area = Leitungsfläche +keepout = Sperrfläche +via_keepout = Via-Sperrfläche +component_keepout = Bauteil-Sperrfläche +board_outline = Platinen-Rand +unknown = unbekannt diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_en.properties new file mode 100644 index 0000000..9774394 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowClearanceViolations_en.properties @@ -0,0 +1,14 @@ +# English version of language dependent text of the class WindowClearanceViolations +title = Clearance Violations +list_empty_message = no violations found +at = at +on_layer = on layer +pin = pin +via = via +trace = trace +conduction_area = conduction area +keepout = keepout +via_keepout = via keepout +component_keepout = component keepout +board_outline = board outline +unknown = unknown \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_de.properties new file mode 100644 index 0000000..9ead8f6 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_de.properties @@ -0,0 +1,15 @@ +# English version of language dependent text of the class WindowEditVias +title = Vias editieren +add = Hinzufügen +add_tooltip = Ein neues Via hinzufügen +remove = Löschen +remove_tooltip = Das augewählte Via löschen +new_via = neues_via_ +via = Via +removed = gelöscht +NAME = Name +PADSTACK = Padstack +CLEARANCE_CLASS = Clearance-Klasse +ATTACH_SMD = SMD-Überlappung +message_1 = letztes Via niccht gelöscht +message_2 = Via nicht gelöscht weil es noch verwendet wird in der Via-Regel diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_en.properties new file mode 100644 index 0000000..ca661de --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowEditVias_en.properties @@ -0,0 +1,15 @@ +# English version of language dependent text of the class WindowEditVias +title = Edit Vias +add = Add +add_tooltip = Append a new via +remove = Remove +remove_tooltip = Remove the selected via +new_via = new_via_ +via = via +removed = removed +NAME = name +PADSTACK = padstack +CLEARANCE_CLASS = clearance class +ATTACH_SMD = attach smd +message_1 = last via not removed +message_2 = via not removed because it is still used in via rule diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_de.properties new file mode 100644 index 0000000..f013933 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_de.properties @@ -0,0 +1,7 @@ +# German version of language dependent text of the class WindowAbout +title = Längenverletzungen +list_empty = keine Längenverletzungen gefunden +maximum_allowed = maximal erlaubt +minimum_allowed = minimal erlaubt +net = Netz +trace_length = : Bahnlänge diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_en.properties new file mode 100644 index 0000000..cbb2db9 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowLengthViolations_en.properties @@ -0,0 +1,7 @@ +# English version of language dependent text of the class WindowAbout +title = Length Violations +list_empty = no length violations found +maximum_allowed = maximum allowed +minimum_allowed = minimum allowed +net = Net +trace_length = : trace length diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_de.properties new file mode 100644 index 0000000..7cf21bc --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_de.properties @@ -0,0 +1,6 @@ +# German version of language dependent text of the class WindowManualRule +title = Manuelle Regeln +via_rule = Via-Regel: +trace_clearance_class = Clearance-Klasse für Bahnen: +trace_width = Bahnbreite: +on_layer = auf Lage: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_en.properties new file mode 100644 index 0000000..dbe4a0e --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowManualRule_en.properties @@ -0,0 +1,6 @@ +# English version of language dependent text of the class WindowManualRule +title = Manual Rules +via_rule = via rule: +trace_clearance_class = trace clearance class: +trace_width = trace width: +on_layer = on layer: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_de.properties new file mode 100644 index 0000000..dfa89d0 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_de.properties @@ -0,0 +1,8 @@ +# German version of language dependent text of the class WindowMoveParameter +title = Platzierungs-Parameter +horizontal_component_grid = horizontales Bauteilraster: +vertical_component_grid = vertikales Bauteilraste: +wheel_function = Mausrad-Funktion: +wheel_function_tooltip = Definiert die Funktion des Mausrads beim Platzieren von Bauteilen +zoom = zoomen +rotate = drehen diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_en.properties new file mode 100644 index 0000000..0e714c8 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowMoveParameter_en.properties @@ -0,0 +1,8 @@ +# English version of language dependent text of the class WindowMoveParameter +title = Move Parameter +horizontal_component_grid = horizontal component grid: +vertical_component_grid = vertical component grid: +wheel_function = wheel function: +wheel_function_tooltip = Defines the function of the mouse wheel while moving components +zoom = zoom +rotate = rotate \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_de.properties new file mode 100644 index 0000000..85a7e95 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_de.properties @@ -0,0 +1,37 @@ +# German version of language dependent text of the class WindowNetClasses +title = Netzklassen +add = Hinzufügen +add_tooltip = eine neue Netzklasse hinzufügen +remove = Löschen +remove_tooltip = die ausgewählte Netzklasse löschen +assign = Zuweisen +assign_tooltip = Netzklassen zuweisen +select = Selektieren +select_tooltip = Die Objekte der ausgewählten Netzklassen auf der Platine selektieren +filter_incompletes = Incompletes filtern +filter_incompletes_tooltip = Nur die offenen Verbindungen der ausgewählten Netzklassen anzeigen +show_nets = Netze anzeigen +show_nets_tooltip = Öffnet eine Liste mit allen in den ausgewählten Klassen enthaltenen Netzen +contained_nets = Enthaltene Netze +message_1 = Default-Netzklasse nicht gelöscht +message_2 = Netzklasse nicht gelöscht, weil sie noch benutzt wird für Netz +net_class = Netzklasse +removed = gelöscht +column_tool_tip_1 = Der geordnete Satz von Vias +column_tool_tip_2 = Die Clearance-Klasse für Bahnen +column_tool_tip_3 = Die Bahnbreite +column_tool_tip_4 = Die Lagen für die Bahnbreite +column_tool_tip_5 = Gibt an, ob Bahnen aus dieser Netzklasse verschoben oder glattgezogen werden dürfen +column_tool_tip_6 = Wenn nicht selektiert, werden Mehrfachverbindungen zu Leitungsflächen entfernt +If true, multiple connections to conduction areas are not removed +column_tool_tip_7 = Wenn > 0 muss die kumulative Bahnlänge mindestens diesen Wert haben +column_tool_tip_8 = Wenn > 0 darf die kumulative Bahnlänge höchstens diesen Wert haben +NAME = Name +VIA_RULE = Via-Regel +CLEARANCE_CLASS = Clearance-Klasse +TRACE_WIDTH = Bahnbreite +ON_LAYER = auf Lage +SHOVE_FIXED = schiebe-fixiert +CYCLES_WITH_AREAS = Zykeln mit Flächen +MIN_TRACE_LENGTH = min. Länge +MAX_TRACE_LENGTH = max. Länge diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_en.properties new file mode 100644 index 0000000..0c9485c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetClasses_en.properties @@ -0,0 +1,36 @@ +# English version of language dependent text of the class WindowNetClasses +title = Net Classes +add = Add +add_tooltip = Append a new class +remove = Remove +remove_tooltip = Remove the selected class +assign = Assign +assign_tooltip = Assign net classes +select = Select +select_tooltip = Select the items of the chosen net classes on the board +filter_incompletes = Filter Incompletes +filter_incompletes_tooltip = Display only the open connections of the selected net classes +show_nets = Show Nets +show_nets_tooltip = Displays a list with all nets contained in the selected classes +contained_nets = Contained Nets +message_1 = default net class not removed +message_2 = net class not removed because it is still used in net +net_class = net class +removed = removed +column_tool_tip_1 = The orded set of vias +column_tool_tip_2 = The trace clearance class +column_tool_tip_3 = The trace width +column_tool_tip_4 = The layers of the trace width +column_tool_tip_5 = Indicates, if items of this net can be pushed aside or pulled tight +column_tool_tip_6 = If not selected, multiple connections to conduction areas are removed +column_tool_tip_7 = If > 0, the cumulative trace length must be at least this value +column_tool_tip_8 = If > 0, the cumulative trace length must be less than this value +NAME = name +VIA_RULE = via rule +CLEARANCE_CLASS = clearance class +TRACE_WIDTH = trace width +ON_LAYER = on layer +SHOVE_FIXED = shove fixed +CYCLES_WITH_AREAS = cycles with areas +MIN_TRACE_LENGTH = min. length +MAX_TRACE_LENGTH = max. length diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_de.properties new file mode 100644 index 0000000..5864c93 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_de.properties @@ -0,0 +1,12 @@ +# German version of language dependent text of the subclasses of WindowNetSamples + +router_demonstrations = Demonstrations-Beispiele +open_sample_design = Beispiel-Design öffnen +sample_designs = Beispiel-Designs +replay_example = Beispiel abspielen +45_degree_logfile = Router-Beispiel für 45 Grad +drag_component_logfile = Beispiel für das Ziehen von Bauteilen +any_angle_logfile = Router-Beispiel für beliebige Winkel +autorouter_example_1 = erstes Autorouter-Beispiel +autorouter_example_2 = zweites Autorouter-Beispiel +autorouter_example_3 = drittes Autorouter-Beispiel diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_en.properties new file mode 100644 index 0000000..d2ad0bd --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNetSamples_en.properties @@ -0,0 +1,12 @@ +# English version of language dependent text of the subclasses of WindowNetSamples + +router_demonstrations = Router Demonstrations +open_sample_design = Open Sample Design +sample_designs = Sample Designs +replay_example = Replay Example +45_degree_logfile = 45 degree routing example +drag_component_logfile = Example for dragging components +any_angle_logfile = Free angle routing example +autorouter_example_1 = first autorouter example +autorouter_example_2 = second autorouter example +autorouter_example_3 = third autorouter example diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_de.properties new file mode 100644 index 0000000..5f1b3e9 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_de.properties @@ -0,0 +1,8 @@ +# English version of language dependent text of the class WindowNet +title = Netze +assign_class = Klasse zuweisen +assign_class_tooltip = den ausgewählten Netzen eine Klasse zuweisen +filter_incompletes = Incompletes filtern +filter_incompletes_tooltip = Nur die Luftlinien der ausgewählten Netze abbilden +message_1 = Wähle Netzklasse +message_2 = Netzklasse zuweisen diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_en.properties new file mode 100644 index 0000000..cc0d6a1 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowNets_en.properties @@ -0,0 +1,8 @@ +# English version of language dependent text of the class WindowNets +title = Nets +assign_class = Assign Class +assign_class_tooltip = Assign class to selected nets +filter_incompletes = Filter Incompletes +filter_incompletes_tooltip = Display only the incompletes of the selected nets +message_1 = Select net class +message_2 = Net Class Selection \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_de.properties new file mode 100644 index 0000000..3b32099 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_de.properties @@ -0,0 +1,10 @@ +# German version of language dependent text of the class WindowObjectInfo +title = Ausgewählte Objekte +summary = Zusammenfassung: +pin = Pin +pins = Pins +via = Via +vias = Vias +trace = Bahn, kumulative Bahnlänge +traces = Bahnen, kumulative Bahnlänge +list_empty = Liste ist leer diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_en.properties new file mode 100644 index 0000000..0bed452 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectInfo_en.properties @@ -0,0 +1,10 @@ +# English version of language dependent text of the class WindowObjectInfo +title = Selected Items +summary = Summary: +pin = pin +pins = pins +via = via +vias = vias +trace = trace, cumulative trace length +traces = traces, cumulative trace length +list_empty = list is empty diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_de.properties new file mode 100644 index 0000000..d7208bc --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_de.properties @@ -0,0 +1,12 @@ +# German version of language dependent text of the class WindowObjectList +info = Info +info_tooltip = zeigt Informationen über die ausgewählten Objekte +select = Anzeigen +select_tooltip = selektiert die ausgewählten Objekte auf der Platine +invert = Invertieren +invert_tooltip = invertiert die Auswahl +recalculate = Neu berechnen +recalculate_tooltip = berechnet den Inhalt dieses Fensters neu +list_empty = keine Objekte gefunden +window_title = Selektierte Objekte +filter = Filter: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_en.properties new file mode 100644 index 0000000..35f8192 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectList_en.properties @@ -0,0 +1,12 @@ +# English version of language dependent text of the class WindowObjectList +info = Info +info_tooltip = Displays information about the selected objects +select = Show +select_tooltip = Selects the chosen objects on the board +invert = Inverse +invert_tooltip = inverts the selection +recalculate = Recalculate +recalculate_tooltip = Recalculates the content of this window +list_empty = no items found +window_title = Selected Objects +filter = Filter: diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_de.properties new file mode 100644 index 0000000..2d24ccd --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_de.properties @@ -0,0 +1,14 @@ +# German version of language dependent text of the class WindowObjectVisibility +title = Objekt-Sichbarkeit +header_message = Regler zum Ändern der Sichtbarkeit von +TRACES = Bahnen +VIAS = Vias +PINS = Pins +CONDUCTION_AREAS = Leitungsflächen +KEEPOUTS = Sperrflächen +VIA_KEEPOUTS = Via-Sperrflächen +PLACE_KEEPOUTS = Platzierungs-Sperrflächen +COMPONENT_OUTLINES = Bauteil-Umrandungen +HILIGHT = markierten Objekten +INCOMPLETES = Incompletes +LENGTH_MATCHING_AREAS = Längenbeschränkungs-Flächen \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_en.properties new file mode 100644 index 0000000..229fe92 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowObjectVisibility_en.properties @@ -0,0 +1,14 @@ +# English version of language dependent text of the class WindowObjectVisibility +title = Object Visibility +header_message = Use slider to modify the visibility of +TRACES = traces +VIAS = vias +PINS = pins +CONDUCTION_AREAS = conduction areas +KEEPOUTS = keepouts +VIA_KEEPOUTS = via keepouts +PLACE_KEEPOUTS = place keepouts +COMPONENT_OUTLINES = component outlines +HILIGHT = hilight +INCOMPLETES = incompletes +LENGTH_MATCHING_AREAS = length matching areas \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_de.properties new file mode 100644 index 0000000..1080fc3 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_de.properties @@ -0,0 +1,10 @@ +# German version of language dependent text of the class WindowRouteDetail +title = Detailierte Route-Parameter +clearance_compensation = Clearance-Kompensation: +clearance_compensation_tooltip = Clearance-Kompensation ist sinnvoll, wenn es nur eine Clearance-Klasse f\u00FCr Bahnen gibt +on = ein +off = aus +pull_tight_accuracy = Glattzieh-Genauigkeit f\u00FCr Bahnen: +pull_tight_accuracy_tooltip = Regler zum \u00C4ndern der Glattzieh-Genauigkeit f\u00FCr Bahnen +keepout_outside_outline = Keepout au\u00DFerhalb der Board-Outline +keepout_outside_outline_tooltip = Falls gesetzt, wird die gesamte Fl\u00E4che au\u00DFerhalb der Board-Outline zu Keepout. \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_en.properties new file mode 100644 index 0000000..5158e56 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteDetail_en.properties @@ -0,0 +1,10 @@ +# English version of language dependent text of the class WindowRouteDetail +title = Detail Route Parameter +clearance_compensation = clearance compensation: +clearance_compensation_tooltip = Clearance compensation on may be useful if you have only one trace clearance type +on = on +off = off +pull_tight_accuracy = pull tight accuracy: +pull_tight_accuracy_tooltip = Use slider to change the accuracy for pulling tight traces +keepout_outside_outline = keepout outside board outline +keepout_outside_outline_tooltip = If enabled, the complete area outside the board outline gets keepout \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_de.properties new file mode 100644 index 0000000..5c4056f --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_de.properties @@ -0,0 +1,34 @@ +# German version of language dependent text of the class WindowRouteParameter +title = Route-Einstellungen +snap_angle = Winkel-Einschr\u00E4nkung: +snap_angle_tooltip = Winkeleinschr\u00E4nkung f\u00FCr Bahnen +90_degree = 90 Grad +45_degree = 45 Grad +none = keine +route_mode = Route-Modus: +dynamic = dynamisch +stitching = stitching +rule_selection = Regel-Auswahl: +automatic = automatisch +manual = manuell +push&shove_enabled = schieben erlaubt +push&shove_enabled_tooltip = erm\u00F6glicht das Wegschieben von Hindernissen +drag_components_enabled = Bauteil-ziehen erlaubt +drag_components_enabled_tooltip = erm\u00F6glicht das Wegziehen von Bauteilen mit gedr\u00FCckter linker Maustaste +via_snap_to_smd_center = Vias schnappen zum SMD-Zentrum +via_snap_to_smd_center_tooltip = wenn gesetzt schnappen Vias, die SMD-Pins ber\u00FChren, zum Pin-Zentrum +hilight_routing_obstacle = Route-Hindernis highlighten +hilight_routing_obstacle_tooltip = markiert das aktuelle Route-Hindernis im dynamischen Route-Modus +ignore_conduction_areas = Leitungsfl\u00E4chen ignorieren +ignore_conduction_areas_tooltip = wenn gesetzt werden Leitungsfl\u00E4chen nicht als Route-Hindernis angesehen +automatic_neckdown = automatisches Neckdown +automatic_neckdown_tooltip = wenn gesetzt wird bei Pins, die schmaler als die aktuelle Bahnbreite sind, die aktuelle Bahnbreite automatisch reduziert +restrict_pin_exit_directions = Exit-Richtungen bei Pins einschr\u00E4nken +restrict_pin_exit_directions_tooltip = wenn gesetzt werden die Exit-Richtungen von Bahnen bei rechteckigen Pins auf die Schmalseiten begrenzt +pin_pad_to_turn_gap = Pad-Abbiege-Abstand: +pin_pad_to_turn_gap_tooltip = definiert die Mindestl\u00E4nge der Exit-Beschr\u00E4nkungen f\u00FCr Bahnen bei rechteckigen Pins +pull_tight_region = Glattzieh-Bereich: +pull_tight_region_tooltip = Textfeld oder Regler k\u00F6nnen zum \u00C4ndern der Glattzieh-Region um den Cursor verwendet werden +detail_parameter = Detail-Parameter +change_snap_angle_45 = Winkelfreie Bahnen im 45-Grad-Modus noch nicht vollst\u00E4ndig unterst\u00FCtzt. Winkel-Einschr\u00E4nkung trotzdem \u00E4ndern? +change_snap_angle_90 = Nur achsenparallele Bahnen im 90-Grad-Modus bisher vollst\u00E4ndig unterst\u00FCtzt. Winkel-Einschr\u00E4nkung trotzdem \u00E4ndern? diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_en.properties new file mode 100644 index 0000000..e06c9f5 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowRouteParameter_en.properties @@ -0,0 +1,34 @@ +# English version of language dependent text of the class WindowRouteParameter +title = Route Parameter +snap_angle = snap angle: +snap_angle_tooltip = Angle Restriction for Traces +90_degree = 90 degree +45_degree = 45 degree +none = none +route_mode = route mode: +dynamic = dynamic +stitching = stitching +rule_selection = rule selection: +automatic = automatic +manual = manual +push&shove_enabled = push & shove enabled +push&shove_enabled_tooltip = Enables pushing obstacles +drag_components_enabled = drag components enabled +drag_components_enabled_tooltip = Enables dragging components with the pressed left mouse button +via_snap_to_smd_center = vias snap to smd center +via_snap_to_smd_center_tooltip = If set, vias attaching smd pins snap to the pin center +hilight_routing_obstacle = highlight routing obstacle +hilight_routing_obstacle_tooltip = to highlight the current routing obstacle in dynamic routing +ignore_conduction_areas = ignore conduction areas +ignore_conduction_areas_tooltip = If set, conduction areas are not regarded as routing obstacles +automatic_neckdown = automatic neckdown +automatic_neckdown_tooltip = If set, at pins smaller than the current trace width the trace width will be automatically lowered +restrict_pin_exit_directions = restrict pin exit directions +restrict_pin_exit_directions_tooltip = If set, the trace exit directions of rectangular pins are restricted to the small sides +pin_pad_to_turn_gap = pad to turn gap: +pin_pad_to_turn_gap_tooltip = Defines the length of the trace exit restrictions for rectangular pins +pull_tight_region = pull tight region: +pull_tight_region_tooltip = Use text field or slider to change the pull tight region around the cursor +detail_parameter = detail parameter +change_snap_angle_45 = Free angle traces with snap angle 45 degree not yet fully supported. Change snap angle anyway? +change_snap_angle_90 = Only orthoganal traces with snap angle 90 degree fully supported yet. Change snap angle anyway? \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_de.properties new file mode 100644 index 0000000..1cce29c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_de.properties @@ -0,0 +1,20 @@ +# German version of language dependent text of the class WindowSelectParameter +title = Select-Einstellungen +selection_layers = Selektions-Lagen: +all_visible = alle sichtbaren +all_visible_tooltip = Selektion auf allen sichtbaren Lagen, die aktuelle Lage wird bevorzugt +current_only = nur aktuelle +current_only_tooltip = Selektion nur auf der aktuellen Lage +selectable_items = Selektierbare Objekte: +TRACES = Bahnen +VIAS = Vias +PINS = Pins +CONDUCTION = Leitungsflächen +KEEPOUT = Sperrflächen +VIA_KEEPOUT = Via-Sperrflächen +COMPONENT_KEEPOUT = Platzierungs-Sperrflächen +BOARD_OUTLINE = Platinenrand +FIXED = fixiert +UNFIXED = unfixiert +current_layer = Aktuelle Lage: +current_layer_tooltip = kann auch mit Ziffertasten oder '+' '-' geändert werden diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_en.properties new file mode 100644 index 0000000..2213c6b --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSelectParameter_en.properties @@ -0,0 +1,20 @@ +# English version of language dependent text of the class WindowSelectParameter +title = Select Parameter +selection_layers = Selection Layers: +all_visible = all visible +all_visible_tooltip = selection on all visible layer, the current layer is preferred +current_only = current only +current_only_tooltip = selection only on the current layer +selectable_items = Selectable Items: +TRACES = traces +VIAS = vias +PINS = pins +CONDUCTION = conduction areas +KEEPOUT = keepout +VIA_KEEPOUT = via keepout +COMPONENT_KEEPOUT = place keepout +BOARD_OUTLINE = board outline +FIXED = fixed +UNFIXED = unfixed +current_layer = Current Layer: +current_layer_tooltip = can be changed also with number key or '+' '-' \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_de.properties new file mode 100644 index 0000000..f3ade65 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_de.properties @@ -0,0 +1,17 @@ +# German version of language dependent text of the class WindowSnapshotSettings +title = Snapshot-Einstellungen +object_colors = Objekt-Farben +object_visibility = Objekt-Sichtbarkeit +layer_visibility = Lagen-Sichtbarkeit +display_region = Abbildungs-Ausschnitt +interactive_state = interaktiver Zustand +selection_layers = Selektions-Lagen +selectable_items = selektierbare Objekte +current_layer = aktuelle Lage +rule_selection = Regel-Auswahl +manual_rule_settings = manuelle Regel-Einstellungen +push&shove_enabled = schieben erlaubt +drag_components_enabled = Bauteil-Ziehen erlaubt +pull_tight_region = Glattzieh-Bereich +component_grid = Bauteil-Raster +info_list_selections = Info-Listen-Selektion \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_en.properties new file mode 100644 index 0000000..fca609a --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshotSettings_en.properties @@ -0,0 +1,17 @@ +# English version of language dependent text of the class WindowSnapshotSettings +title = Snapshot Settings +object_colors = object colors +object_visibility = object visibility +layer_visibility = layer visibility +display_region = display region +interactive_state = interactive state +selection_layers = selection layers +selectable_items = selectable items +current_layer = current layer +rule_selection = rule selection +manual_rule_settings = manual rule settings +push&shove_enabled = push&shove enabled +drag_components_enabled = drag components enabled +pull_tight_region = pull tight region +component_grid = component grid +info_list_selections = info list selections diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_de.properties new file mode 100644 index 0000000..1420a28 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_de.properties @@ -0,0 +1,10 @@ +# German version of language dependent text of the class WindowSnapshot +title = Snapshots +goto_snapshot = Gehe zu ausgewähltem Snapshot +goto_tooltip = Shortcut ist j +create = Neuer Snapshot +snapshot = Snapshot +remove = Ausgewählten Snapshot löschen +remove_all = Alle Snapshots löschen +settings = Snapshot-Einstellungen +settings_tooltip = zum Feslegen der Eigenschaften eines neuen Snapshots diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_en.properties new file mode 100644 index 0000000..7ac01c5 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowSnapshot_en.properties @@ -0,0 +1,10 @@ +# English version of language dependent text of the class WindowSnapshot +title = Snapshots +goto_snapshot = Goto Selected Snapshot +goto_tooltip = shortcut is j +create = Create +snapshot = snapshot +remove = Remove Selected Snapshot +remove_all = Remove All Snapshots +settings = Snapshot Settings +settings_tooltip = to define the settings of a new snapshot diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_de.properties new file mode 100644 index 0000000..67653f2 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_de.properties @@ -0,0 +1,14 @@ +# German version of language dependent text of the class WindowViaRule +title = Via Regel +append = Hinzufügen +append_tooltip = ein Via zu der Regel hinzufügen +remove = Löschen +remove_tooltip = das ausgewählte Via aus der Regel entfernen +move_up = Aufwärts +move_up_tooltip = die Priorität des ausgewählten Vias erhöhen +move_down = Abwärts +move_down_tooltip = die Priorität des ausgewählten Vias verringern +choose_via_to_append = bitte wählen Sie das hinzuzufügende Via +append_via_to_rule = Via zur Regel hinzufügen +remove_2 = lösche +from_the_rule = aus der Regel diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_en.properties new file mode 100644 index 0000000..a188e2c --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowViaRule_en.properties @@ -0,0 +1,14 @@ +# English version of language dependent text of the class WindowViaRule +title = Via Rule +append = Append +append_tooltip = appends a via to the rule +remove = Remove +remove_tooltip = removes the selected via from the rule +move_up = Move Up +move_up_tooltip = increases the priority of the selected via in the rule +move_down = Move Down +move_down_tooltip = decreases the priority of the selected via in the rule +choose_via_to_append = Choose via to append +append_via_to_rule = Append Via to Rule +remove_2 = remove +from_the_rule = from the rule \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_de.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_de.properties new file mode 100644 index 0000000..fb5d86b --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_de.properties @@ -0,0 +1,34 @@ +# German version of language dependent text of the class WindowVia +title = Via-Regeln +available_via_padstacks = Verfügbare Via-Padstacks +info = Info +info_tooltip = zeigt die zur Verfügung stehenden Via-Padstacks +info_tooltip_2 = zeigt die Vias, die in eiiner Via-Regel verwendet werden können +info_tooltip_3 = zeigt Informationen über die ausgewählte Via-Regel +create = Neu +create_tooltip = einen neuen Via-Padstack definieren +create_tooltip_2 = eine neue leere Via-Regel erzeugen +remove = Löschen +remove_tooltip = einen vorhandenen Via-Padstack löschen +remove_tooltip_2 = die ausgewählte Via-Regel löschen +available_vias = Verfügbare Vias +edit = Editieren +edit_tooltip = die Vias editieren, die in einer Via-Regel verwendet werden können +edit_tooltip_2 = die ausgewählte Via-Regel editieren +via_rules = Via-Regeln +select_start_layer = bitte die erste Lage wählen +start_layer_selection = Auswahl der ersten Lage +select_end_layer = bitte die letzte Lage wählen +end_layer_selection = Auswahl der letzten Lage +adjust_circles = Kreise anpassen +radius_on_layer = Radius auf Lage +choose_padstack_to_remove = bitte zu löschenden Padstach auswählen +remove_via_padstack = Via-Padstack löschen +selected_rule = ausgewählte Regel +remove_via_rule = Via-Regel löschen +message_1 = Bitte den Namen des neuen Via-Padstacks eingeben +message_2 = Name existiert bereits, bitte anpassen +message_3 = Bitte den Default-Radius eingeben +message_4 = Via-Padstack nicht gelöscht, weil er noch verwendet wird in Via +message_5 = Bitte den Namen der neuen Via-Regel eingeben + diff --git a/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_en.properties b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_en.properties new file mode 100644 index 0000000..6ba8680 --- /dev/null +++ b/src/main/resources/eu/mihosoft/freerouting/gui/resources/WindowVia_en.properties @@ -0,0 +1,33 @@ +# English version of language dependent text of the class WindowVia +title = Via Rules +available_via_padstacks = Available Via Padstacks +info = Info +info_tooltip = shows the available via padstacks +info_tooltip_2 = shows the vias, which can be used in a via rule +info_tooltip_3 = shows information about the selected via rule +create = Create +create_tooltip = to create a new via padstack +create_tooltip_2 = to create a new empty via rule +remove = Remove +remove_tooltip = to remove an existing via padstack +remove_tooltip_2 = to remove the selected via rule +available_vias = Available Vias +edit = Edit +edit_tooltip = to edits the vias, which can be used in a via rule +edit_tooltip_2 = to edit the selected via rule +via_rules = Via Rules +select_start_layer = Select start layer +start_layer_selection = Start Layer Selection +select_end_layer = Select end layer +end_layer_selection = End Layer Selection +adjust_circles = Adjust Circles +radius_on_layer = radius on layer +choose_padstack_to_remove = Choose padstack to remove +remove_via_padstack = Remove Via Padstack +selected_rule = Selected Rule +remove_via_rule = Remove via rule +message_1 = Please enter the name of the new padstack +message_2 = Name exists already, please adjust +message_3 = Please enter the default radius +message_4 = Via padstack not removed because it is used in via +message_5 = Please enter the name of the new via rule \ No newline at end of file diff --git a/src/main/resources/eu/mihosoft/freerouting/helpset/en/html_files/WindowVia.html b/src/main/resources/eu/mihosoft/freerouting/helpset/en/html_files/WindowVia.html index bff2922..ef3ccfc 100644 --- a/src/main/resources/eu/mihosoft/freerouting/helpset/en/html_files/WindowVia.html +++ b/src/main/resources/eu/mihosoft/freerouting/helpset/en/html_files/WindowVia.html @@ -15,7 +15,7 @@

    A via consists of a name, a via padstack, a clearance class and a switch, if attaching smd-pins of the same net is allowed or not.

    Via Padstacks

    A via padstack consists of a begin layer and an end layer and of a circle shape on each layer between the begin and the end layer.

    -

    The following is a description of the window with the via rules.

    +

    The following is a description of the window with the via rules.

    Available Via Padstacks

    Here you see the three buttons Info, Create and Remove.

    After pushing the Info button a list with all available via padstacks will be displayed.

    With the Create Button you can create a new via padstack. You you will be asked to provide the name of the new via padstack, the start and the end layer, and the default radius of the circle shape. In the following input window you can adjust this radius on each single layer, if you want the shapes of the new via padstack to be layer dependent

    diff --git a/src/main/resources/eu/mihosoft/freerouting/interactive/resources/InteractiveState_de.properties b/src/main/resources/eu/mihosoft/freerouting/interactive/resources/InteractiveState_de.properties index 5cc7d12..d2db6bf 100644 --- a/src/main/resources/eu/mihosoft/freerouting/interactive/resources/InteractiveState_de.properties +++ b/src/main/resources/eu/mihosoft/freerouting/interactive/resources/InteractiveState_de.properties @@ -1,10 +1,10 @@ # German version of language dependent text of the derived classes of InteractiveState -adding_hole_completed = Loch erfolgreich eingef\u00FCgt -adding_hole_failed = Loch Einf\u00FCgen gescheitert -adding_hole_to_circle_not_yet_implemented = Loch in Kreis einf\u00FCgen noch nicht implementiert -adding_hole_to_obstacle_area = f\u00FCge Loch in Keepout ein +adding_hole_completed = Loch erfolgreich eingef\u00fcgt +adding_hole_failed = Loch Einf\u00fcgen gescheitert +adding_hole_to_circle_not_yet_implemented = Loch in Kreis einf\u00fcgen noch nicht implementiert +adding_hole_to_obstacle_area = f\u00fcge Loch in Keepout ein all_connections_routed = alle Verbindungen gerouted -all_items_inserted = alle Objekte eingef\u00FCgt +all_items_inserted = alle Objekte eingef\u00fcgt autoroute = Autoroute batch_autorouter = Batch Autorouter batch_optimizer = Batch Optimierer @@ -14,31 +14,31 @@ completed beendet connections_could_not_be_routed = Verbindungen konnten nicht gerouted werden connections_found = Verbindungen gefunden connections_not_found = Verbindungen nicht gefunden -creating_circle = bilde kreisf\u00F6rmige Sperrrfl\u00E4che -creating_polygonshape = bilde polygonale Sperrfl\u00E4che -creatig_tile = bilde konvexe polygonale Sperrfl\u00E4che +creating_circle = bilde kreisf\u00f6rmige Sperrrfl\u00e4che +creating_polygonshape = bilde polygonale Sperrfl\u00e4che +creatig_tile = bilde konvexe polygonale Sperrfl\u00e4che drag_left_mouse_button_to_create_region_to_display = zur Definition des Abbildungs-Rechtecks linke Maustaste ziehen drag_left_mouse_button_to_select_cutout_rectangle = zur Definition des Ausschneide-Rechtecks linke Maustaste ziehen drag_left_mouse_button_to_selects_items_in_region = zur Definition des Auswahl-Rechtecks linke Maustaste ziehen dragging_item = ziehe Objekt fanout = Fanout -in_select_menu = im Auswahl-Men\u00FC +in_select_menu = im Auswahl-Men\u00fc in_select_mode = im Auswahl-Modus in_select_item_mode = im Objektauswahl-Modus -is_not_active_for_the_current_net = f\u00FCr das zu routende Netz nicht aktiv ist -insertion_failed_because_of_obstacles = Einf\u00FCgen auf Grund von Hindernissen fehlgeschlagen +is_not_active_for_the_current_net = f\u00fcr das zu routende Netz nicht aktiv ist +insertion_failed_because_of_obstacles = Einf\u00fcgen auf Grund von Hindernissen fehlgeschlagen interrupted abgebrochen -keepout_cancelled_because_of_overlaps = Sperrfl\u00E4che wegen \u00DCberlappungen verworfen -keepout_successful_completed = Sperrfl\u00E4che erfolgreich eingef\u00FCgt +keepout_cancelled_because_of_overlaps = Sperrfl\u00e4che wegen \u00dcberlappungen verworfen +keepout_successful_completed = Sperrfl\u00e4che erfolgreich eingef\u00fcgt layer_changed_to = Lage gewechselt nach layer_not_changed_because_layer = Lage nicht gewechselt weil Lage layer_not_changed_because_of_obstacle_on_layer = Lage nicht gewechselt wegen Hindernis auf Lage logfile = Logdatei move_completed = Verschieben abgeschlossen move_component_failed_because_no_item_selected = Bauteil-Verschieben fehlgeschlagen weil kein Bauteil-Objekt selektiert ist -new_net_created_from_selected_items = neues Netz aus den ausgew\u00E4hlten Objekten erzeugt -no_item_found_for_adding_hole = kein Objekt zum Loch-Einf\u00FCgen gefunden -no_obstacle_area_found_for_adding_hole = keine Sperrfl\u00E4che zum Loch-Einf\u00FCgen gefunden +new_net_created_from_selected_items = neues Netz aus den ausgew\u00e4hlten Objekten erzeugt +no_item_found_for_adding_hole = kein Objekt zum Loch-Einf\u00fcgen gefunden +no_obstacle_area_found_for_adding_hole = keine Sperrfl\u00e4che zum Loch-Einf\u00fcgen gefunden no_pin_selected = kein Pin selektiert no_swappable_pin_found = kein tauschbarer Pin gefunden nothing_selected = nichts selektiert @@ -46,18 +46,18 @@ pass = Pass picked_pin_expected = selektierten Pin erwartet pin_not_swapped_because_it_is_already_connected = Pin nicht getauscht, weil er schon angeschlossen ist pin_not_swapped_because_second_pin_is_already_connected = Pin nicht getauscht, weil der andere Pin schon angeschlossen ist -pin_swap_completed = Pintausch vollst\u00E4ndig +pin_swap_completed = Pintausch vollst\u00e4ndig pin_to_swap_missing = zu tauschender Pin fehlt -please_click_second_pin_with_the_left_mouse_button = bitte zweiten Pin mit der linken Maustaste w\u00E4hlen -please_unfix_selected_items_before_moving = bitte die Fixierung der ausgew\u00E4hlten Objekte vor dem Verschieben aufheben +please_click_second_pin_with_the_left_mouse_button = bitte zweiten Pin mit der linken Maustaste w\u00e4hlen +please_unfix_selected_items_before_moving = bitte die Fixierung der ausgew\u00e4hlten Objekte vor dem Verschieben aufheben postroute = Postroute routing_net = route Netz please_unroute_or_extend_selection_before_moving = bitte vor dem Verschieben unrouten oder die Auswahl erweitern pull_tight = Glatt ziehen -some_items_are_fixed_and_could_therefore_not_be_removed = einige Objekte sind fixiert und konnten deshalb nicht gel\u00F6scht werden -some_items_are_not_changed_because_they_are_already_connected = einige Objekte k\u00F6nnen nicht ge\u00E4ndert werden weil sie schon verbunden sind -some_items_cannot_be_moved_because_they_are_fixed = einige Objekte sind fixiert und k\u00F6nnen nicht verschoben werden -some_items_not_inserted_because_of_obstacles = einige Objekte wegen Abstandsverletzungen nicht eingef\u00FCgt -stop_message = l\u00E4uft, stoppen mit linker Maustaste -unable_to_reset_components_with_different_rotations = kann Bauteile mit ungleichen Drehungen nicht zur\u00FCcksetzen +some_items_are_fixed_and_could_therefore_not_be_removed = einige Objekte sind fixiert und konnten deshalb nicht gel\u00f6scht werden +some_items_are_not_changed_because_they_are_already_connected = einige Objekte k\u00f6nnen nicht ge\u00e4ndert werden weil sie schon verbunden sind +some_items_cannot_be_moved_because_they_are_fixed = einige Objekte sind fixiert und k\u00f6nnen nicht verschoben werden +some_items_not_inserted_because_of_obstacles = einige Objekte wegen Abstandsverletzungen nicht eingef\u00fcgt +stop_message = l\u00e4uft, stoppen mit linker Maustaste +unable_to_reset_components_with_different_rotations = kann Bauteile mit ungleichen Drehungen nicht zur\u00fccksetzen