1419 lines
45 KiB
JavaScript
1419 lines
45 KiB
JavaScript
/*
|
|
|
|
altium.js schematic renderer
|
|
|
|
Copyright (c) 2022 Graham Sutherland
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
a copy of this software and associated documentation files (the
|
|
"Software"), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class AltiumSchematicRenderer
|
|
{
|
|
constructor(canvas, document)
|
|
{
|
|
this.canvas = canvas;
|
|
this.document = document;
|
|
this.graph = null
|
|
}
|
|
|
|
#altiumColourToHex(colourInt)
|
|
{
|
|
return "#" + (colourInt & 0xFF).toString(16).padStart(2, '0') + ((colourInt >> 8) & 0xFF).toString(16).padStart(2, '0') + ((colourInt >> 16) & 0xFF).toString(16).padStart(2, '0');
|
|
}
|
|
|
|
#shouldShow(object)
|
|
{
|
|
if (object.owner_part_id == null || object.owner_part_id < 1)
|
|
return true;
|
|
|
|
const parent = object.find_parent(AltiumComponent);
|
|
if (parent == null)
|
|
return true;
|
|
|
|
if (parent.current_part_id == null || parent.current_part_id < 1)
|
|
return true;
|
|
|
|
return parent.current_part_id == object.owner_part_id;
|
|
}
|
|
delete_select_cop(){ // 删除选中器件
|
|
this.graph.removeCells();
|
|
}
|
|
render() {
|
|
|
|
|
|
this.graph = new mxGraph(document.getElementById('graphContainer'));
|
|
|
|
mxConnectionHandler.prototype.movePreviewAway = false;
|
|
mxConnectionHandler.prototype.waypointsEnabled = true;
|
|
mxGraph.prototype.resetEdgesOnConnect = true;
|
|
mxConstants.SHADOWCOLOR = '#C0C0C0';
|
|
var joinNodeSize = 4;
|
|
var strokeWidth = 2;
|
|
|
|
|
|
// Enables guides
|
|
mxGraphHandler.prototype.guidesEnabled = false;
|
|
|
|
// Alt disables guides
|
|
mxGuide.prototype.isEnabledForEvent = function(evt)
|
|
{
|
|
return !mxEvent.isAltDown(evt);
|
|
};
|
|
|
|
// Enables snapping waypoints to terminals
|
|
mxEdgeHandler.prototype.snapToTerminals = true;
|
|
|
|
|
|
mxEdgeStyle.WireConnector = function(state, source, target, hints, result)
|
|
{
|
|
mxLog.debug('add waypoint');
|
|
mxLog.debug("WireConnector",state,source,target,hint)
|
|
// Creates array of all way- and terminalpoints
|
|
var pts = state.absolutePoints;
|
|
var horizontal = true;
|
|
var hint = null;
|
|
|
|
// Gets the initial connection from the source terminal or edge
|
|
if (source != null && state.view.graph.model.isEdge(source.cell))
|
|
{
|
|
horizontal = state.style['sourceConstraint'] == 'horizontal';
|
|
}
|
|
else if (source != null)
|
|
{
|
|
horizontal = source.style['portConstraint'] != 'vertical';
|
|
|
|
// Checks the direction of the shape and rotates
|
|
var direction = source.style[mxConstants.STYLE_DIRECTION];
|
|
|
|
if (direction == 'north' || direction == 'south')
|
|
{
|
|
horizontal = !horizontal;
|
|
}
|
|
}
|
|
|
|
// Adds the first point
|
|
// TODO: Should move along connected segment
|
|
var pt = pts[0];
|
|
|
|
if (pt == null && source != null)
|
|
{
|
|
pt = new mxPoint(state.view.getRoutingCenterX(source), state.view.getRoutingCenterY(source));
|
|
}
|
|
else if (pt != null)
|
|
{
|
|
pt = pt.clone();
|
|
}
|
|
|
|
var first = pt;
|
|
|
|
// Adds the waypoints
|
|
if (hints != null && hints.length > 0)
|
|
{
|
|
// FIXME: First segment not movable
|
|
hint = state.view.transformControlPoint(state, hints[0]);
|
|
mxLog.show();
|
|
mxLog.debug(hints.length,'hints0.y='+hint.y, pt.y)
|
|
|
|
if (horizontal && Math.floor(hint.y) != Math.floor(pt.y))
|
|
{
|
|
mxLog.show();
|
|
mxLog.debug('add waypoint');
|
|
|
|
pt = new mxPoint(pt.x, hint.y);
|
|
result.push(pt);
|
|
pt = pt.clone();
|
|
//horizontal = !horizontal;
|
|
}
|
|
|
|
for (var i = 0; i < hints.length; i++)
|
|
{
|
|
horizontal = !horizontal;
|
|
hint = state.view.transformControlPoint(state, hints[i]);
|
|
|
|
if (horizontal)
|
|
{
|
|
if (pt.y != hint.y)
|
|
{
|
|
pt.y = hint.y;
|
|
result.push(pt.clone());
|
|
}
|
|
}
|
|
else if (pt.x != hint.x)
|
|
{
|
|
pt.x = hint.x;
|
|
result.push(pt.clone());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hint = pt;
|
|
}
|
|
|
|
// Adds the last point
|
|
pt = pts[pts.length - 1];
|
|
|
|
// TODO: Should move along connected segment
|
|
if (pt == null && target != null)
|
|
{
|
|
pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target));
|
|
}
|
|
|
|
if (horizontal)
|
|
{
|
|
if (pt.y != hint.y && first.x != pt.x)
|
|
{
|
|
// result.push(new mxPoint(pt.x, hint.y));
|
|
}
|
|
}
|
|
else if (pt.x != hint.x && first.y != pt.y)
|
|
{
|
|
// result.push(new mxPoint(hint.x, pt.y));
|
|
}
|
|
};
|
|
|
|
mxStyleRegistry.putValue('wireEdgeStyle', mxEdgeStyle.WireConnector);
|
|
|
|
|
|
|
|
let mxGraphGetCellStyle = mxGraph.prototype.getCellStyle;
|
|
mxGraph.prototype.getCellStyle = function(cell)
|
|
{
|
|
var style = mxGraphGetCellStyle.apply(this, arguments);
|
|
|
|
if (style != null && this.model.isEdge(cell))
|
|
{
|
|
style = mxUtils.clone(style);
|
|
|
|
if (this.model.isEdge(this.model.getTerminal(cell, true)))
|
|
{
|
|
style['startArrow'] = 'oval';
|
|
}
|
|
|
|
if (this.model.isEdge(this.model.getTerminal(cell, false)))
|
|
{
|
|
style['endArrow'] = 'oval';
|
|
}
|
|
}
|
|
|
|
return style;
|
|
};
|
|
|
|
let mxConnectionHandlerCreateMarker = mxConnectionHandler.prototype.createMarker;
|
|
mxConnectionHandler.prototype.createMarker = function() {
|
|
var marker = mxConnectionHandlerCreateMarker.apply(this, arguments);
|
|
|
|
// Uses complete area of cell for new connections (no hotspot)
|
|
marker.intersects = function(state, evt)
|
|
{
|
|
return true;
|
|
};
|
|
|
|
// Adds in-place highlighting
|
|
mxCellHighlightHighlight = mxCellHighlight.prototype.highlight;
|
|
marker.highlight.highlight = function(state)
|
|
{
|
|
if (this.state != state)
|
|
{
|
|
if (this.state != null)
|
|
{
|
|
this.state.style = this.lastStyle;
|
|
|
|
// Workaround for shape using current stroke width if no strokewidth defined
|
|
this.state.style['strokeWidth'] = this.state.style['strokeWidth'] || '1';
|
|
this.state.style['strokeColor'] = this.state.style['strokeColor'] || 'none';
|
|
|
|
if (this.state.shape != null)
|
|
{
|
|
this.state.view.graph.cellRenderer.configureShape(this.state);
|
|
this.state.shape.redraw();
|
|
}
|
|
}
|
|
|
|
if (state != null)
|
|
{
|
|
this.lastStyle = state.style;
|
|
state.style = mxUtils.clone(state.style);
|
|
state.style['strokeColor'] = '#00ff00';
|
|
state.style['strokeWidth'] = '3';
|
|
|
|
if (state.shape != null)
|
|
{
|
|
state.view.graph.cellRenderer.configureShape(state);
|
|
state.shape.redraw();
|
|
}
|
|
}
|
|
|
|
this.state = state;
|
|
}
|
|
};
|
|
|
|
return marker;
|
|
};
|
|
|
|
let mxEdgeHandlerCreateMarker = mxEdgeHandler.prototype.createMarker;
|
|
mxEdgeHandler.prototype.createMarker = function()
|
|
{
|
|
var marker = mxEdgeHandlerCreateMarker.apply(this, arguments);
|
|
marker.highlight.highlight = this.graph.connectionHandler.marker.highlight.highlight;
|
|
return marker;
|
|
}
|
|
// Sets source terminal point for edge-to-edge connections.
|
|
mxConnectionHandler.prototype.createEdgeState = function(me)
|
|
{
|
|
var edge = this.graph.createEdge();
|
|
|
|
if (this.sourceConstraint != null && this.previous != null)
|
|
{
|
|
edge.style = mxConstants.STYLE_EXIT_X+'='+this.sourceConstraint.point.x+';'+
|
|
mxConstants.STYLE_EXIT_Y+'='+this.sourceConstraint.point.y+';';
|
|
}
|
|
else if (this.graph.model.isEdge(me.getCell()))
|
|
{
|
|
var scale = this.graph.view.scale;
|
|
var tr = this.graph.view.translate;
|
|
var pt = new mxPoint(this.graph.snap(me.getGraphX() / scale) - tr.x,
|
|
this.graph.snap(me.getGraphY() / scale) - tr.y);
|
|
edge.geometry.setTerminalPoint(pt, true);
|
|
}
|
|
|
|
return this.graph.view.createState(edge);
|
|
};
|
|
|
|
// Uses right mouse button to create edges on background (see also: lines 67 ff)
|
|
mxConnectionHandler.prototype.isStopEvent = function(me)
|
|
{
|
|
return me.getState() != null || mxEvent.isRightMouseButton(me.getEvent());
|
|
};
|
|
|
|
// Updates target terminal point for edge-to-edge connections.
|
|
let mxConnectionHandlerUpdateCurrentState = mxConnectionHandler.prototype.updateCurrentState;
|
|
mxConnectionHandler.prototype.updateCurrentState = function(me)
|
|
{
|
|
mxConnectionHandlerUpdateCurrentState.apply(this, arguments);
|
|
|
|
if (this.edgeState != null)
|
|
{
|
|
this.edgeState.cell.geometry.setTerminalPoint(null, false);
|
|
|
|
if (this.shape != null && this.currentState != null &&
|
|
this.currentState.view.graph.model.isEdge(this.currentState.cell))
|
|
{
|
|
var scale = this.graph.view.scale;
|
|
var tr = this.graph.view.translate;
|
|
var pt = new mxPoint(this.graph.snap(me.getGraphX() / scale) - tr.x,
|
|
this.graph.snap(me.getGraphY() / scale) - tr.y);
|
|
this.edgeState.cell.geometry.setTerminalPoint(pt, false);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Updates the terminal and control points in the cloned preview.
|
|
mxEdgeSegmentHandler.prototype.clonePreviewState = function(point, terminal) {
|
|
var clone = mxEdgeHandler.prototype.clonePreviewState.apply(this, arguments);
|
|
clone.cell = clone.cell.clone();
|
|
|
|
if (this.isSource || this.isTarget)
|
|
{
|
|
clone.cell.geometry = clone.cell.geometry.clone();
|
|
|
|
// Sets the terminal point of an edge if we're moving one of the endpoints
|
|
if (this.graph.getModel().isEdge(clone.cell))
|
|
{
|
|
// TODO: Only set this if the target or source terminal is an edge
|
|
clone.cell.geometry.setTerminalPoint(point, this.isSource);
|
|
}
|
|
else
|
|
{
|
|
clone.cell.geometry.setTerminalPoint(null, this.isSource);
|
|
}
|
|
}
|
|
|
|
return clone;
|
|
};
|
|
|
|
var mxEdgeHandlerConnect = mxEdgeHandler.prototype.connect;
|
|
mxEdgeHandler.prototype.connect = function(edge, terminal, isSource, isClone, me)
|
|
{
|
|
var result = null;
|
|
var model = this.graph.getModel();
|
|
var parent = model.getParent(edge);
|
|
|
|
model.beginUpdate();
|
|
try
|
|
{
|
|
result = mxEdgeHandlerConnect.apply(this, arguments);
|
|
var geo = model.getGeometry(result);
|
|
|
|
if (geo != null)
|
|
{
|
|
geo = geo.clone();
|
|
var pt = null;
|
|
|
|
if (model.isEdge(terminal))
|
|
{
|
|
pt = this.abspoints[(this.isSource) ? 0 : this.abspoints.length - 1];
|
|
pt.x = pt.x / this.graph.view.scale - this.graph.view.translate.x;
|
|
pt.y = pt.y / this.graph.view.scale - this.graph.view.translate.y;
|
|
|
|
var pstate = this.graph.getView().getState(
|
|
this.graph.getModel().getParent(edge));
|
|
|
|
if (pstate != null)
|
|
{
|
|
pt.x -= pstate.origin.x;
|
|
pt.y -= pstate.origin.y;
|
|
}
|
|
|
|
pt.x -= this.graph.panDx / this.graph.view.scale;
|
|
pt.y -= this.graph.panDy / this.graph.view.scale;
|
|
}
|
|
|
|
geo.setTerminalPoint(pt, isSource);
|
|
model.setGeometry(edge, geo);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
model.endUpdate();
|
|
}
|
|
|
|
return result;
|
|
};
|
|
// https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L1036
|
|
mxGraphHandler.prototype.updatePreview = function(remote) {
|
|
if (this.livePreviewUsed && !remote) {
|
|
if (this.cells != null)
|
|
{
|
|
this.setHandlesVisibleForCells(this.graph.getSelectionCells(), false);
|
|
this.updateLivePreview(this.currentDx, this.currentDy);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.updatePreviewShape();
|
|
}
|
|
};
|
|
let oldMove = mxGraphHandler.prototype.mouseMove
|
|
mxGraphHandler.prototype.mouseMove = function(sender, me){
|
|
// mxLog.debug("mouse move",sender,me)
|
|
// https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901
|
|
if (!this.livePreviewUsed && this.shape == null) {
|
|
this.shape = this.createPreviewShape(this.bounds);
|
|
}else if(this.shape != null){
|
|
// mxLog.debug("mouseMove",this)
|
|
}
|
|
oldMove.call(this, sender, me);
|
|
}
|
|
|
|
|
|
let oldClick = mxGraphHandler.prototype.mouseDown
|
|
mxGraphHandler.prototype.mouseDown = function(sender, me){
|
|
mxLog.debug("mouse down",sender,me,this.graph.getSelectionCells())
|
|
if(this.graph.getSelectionCells().length > 0)
|
|
this.graph.clearSelection()
|
|
// https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901
|
|
if(me.state != undefined){
|
|
if(me.state.cell.children != undefined){
|
|
oldClick.call(this, sender, me);
|
|
}else{
|
|
mxLog.debug(me.state.cell)
|
|
if(me.state.cell.parent != undefined){
|
|
this.graph.addSelectionCell(me.state.cell.parent)
|
|
oldClick.call(this, sender, me);
|
|
}
|
|
// oldClick.call(this, sender, me);
|
|
}
|
|
}
|
|
}
|
|
|
|
let oldMouseUp = mxGraphHandler.prototype.mouseUp
|
|
mxGraphHandler.prototype.mouseUp = function(sender, me) {
|
|
mxLog.debug("mouse up",sender,me)
|
|
// https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901
|
|
if(me.state != undefined){
|
|
if(me.state.cell.children != undefined){
|
|
oldMouseUp.call(this, sender, me);
|
|
}else{
|
|
if(me.state.cell.parent != undefined){
|
|
this.graph.addSelectionCell(me.state.cell.parent)
|
|
// oldMouseUp.call(this, sender, me);
|
|
}
|
|
// oldClick.call(this, sender, me);
|
|
}
|
|
}
|
|
oldMouseUp.call(this, sender, me);
|
|
}
|
|
|
|
|
|
this.graph.setPanning(true);
|
|
this.graph.setConnectable(true);
|
|
this.graph.setConnectableEdges(true);
|
|
this.graph.setDisconnectOnMove(false);
|
|
this.graph.foldingEnabled = false;
|
|
this.graph.gridSize = 1
|
|
//Maximum size
|
|
this.graph.maximumGraphBounds = new mxRectangle(0, 0, 1920, 1024)
|
|
this.graph.border = 0;
|
|
var fontColor = '#FFFFFF' ;
|
|
var strokeColor = '#C0C0C0' ;
|
|
var fillColor = '#C0C0C0';
|
|
// Panning handler consumed right click so this must be
|
|
// disabled if right click should stop connection handler.
|
|
this.graph.panningHandler.isPopupTrigger = function() { return false; };
|
|
|
|
// Enables return key to stop editing (use shift-enter for newlines)
|
|
this.graph.setEnterStopsCellEditing(true);
|
|
|
|
// Adds rubberband selection
|
|
new mxRubberband(this.graph);
|
|
|
|
this.graph.addListener(mxEvent.CLICK, function(sender, evt) {
|
|
var e = evt.getProperty('event'); // mouse event
|
|
var cell = evt.getProperty('cell'); // cell may be null
|
|
|
|
if (cell != null)
|
|
{
|
|
// Do something useful with cell and consume the event
|
|
// evt.consume();
|
|
}
|
|
});
|
|
|
|
var connectionHandlerMouseUp = this.graph.connectionHandler.mouseUp;
|
|
this.graph.connectionHandler.mouseUp = function(sender, me) {
|
|
if (this.first != null && this.previous != null)
|
|
{
|
|
var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
|
|
var dx = Math.abs(point.x - this.first.x);
|
|
var dy = Math.abs(point.y - this.first.y);
|
|
|
|
if (dx < this.graph.tolerance && dy < this.graph.tolerance)
|
|
{
|
|
// Selects edges in non-wire mode for single clicks, but starts
|
|
// connecting for non-edges regardless of wire-mode
|
|
mxLog.debug("sss")
|
|
|
|
return;
|
|
}
|
|
}
|
|
connectionHandlerMouseUp.apply(this, arguments);
|
|
};
|
|
|
|
mxVertexHandler.prototype.rotationEnabled = false;
|
|
|
|
// Alternative solution for implementing connection points without child cells.
|
|
// This can be extended as shown in portrefs.html example to allow for per-port
|
|
// incoming/outgoing direction.
|
|
this.graph.getAllConnectionConstraints = function(terminal) {
|
|
var geo = (terminal != null) ? this.getCellGeometry(terminal.cell) : null;
|
|
if ((geo != null ? !geo.relative : false) &&
|
|
this.getModel().isVertex(terminal.cell) &&
|
|
this.getModel().getChildCount(terminal.cell) == 0)
|
|
{
|
|
if(terminal.cell.Pin == true){ // a pin
|
|
mxLog.debug("getAllConnectionConstraints ",terminal.cell.angle)
|
|
if(terminal.cell.angle == 90){
|
|
return [new mxConnectionConstraint(new mxPoint(0,0), false)];
|
|
}else if(terminal.cell.angle == 180){
|
|
return [new mxConnectionConstraint(new mxPoint(0,0), false)];
|
|
}else if(terminal.cell.angle == 270){
|
|
return [new mxConnectionConstraint(new mxPoint(1, 0), false)];
|
|
}else{
|
|
return [new mxConnectionConstraint(new mxPoint(1, 0), false)];
|
|
}
|
|
|
|
}
|
|
}
|
|
if((geo != null) && (this.getModel.isEdge(terminal.cell))){
|
|
console.log(terminal.cell)
|
|
}
|
|
return null;
|
|
};
|
|
// Makes sure non-relative cells can only be connected via constraints
|
|
this.graph.connectionHandler.isConnectableCell = function(cell) {
|
|
if (this.graph.getModel().isEdge(cell))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
var geo = (cell != null) ? this.graph.getCellGeometry(cell) : null;
|
|
|
|
return (geo != null) ? geo.relative : false;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
var parent = this.graph.getDefaultParent();
|
|
mxVertexHandler.prototype.livePreview = true;
|
|
|
|
var labelBackground = (false) ? '#000000' : '#FFFFFF';
|
|
var fontColor = (false) ? '#FFFFFF' : '#000000';
|
|
var strokeColor = (false) ? '#C0C0C0' : '#000000';
|
|
var fillColor = (false) ? 'none' : '#FFFFFF';
|
|
|
|
|
|
var style = this.graph.getStylesheet().getDefaultEdgeStyle();
|
|
delete style['endArrow'];
|
|
style['strokeColor'] = strokeColor;
|
|
style['labelBackgroundColor'] = labelBackground;
|
|
style['edgeStyle'] = 'wireEdgeStyle';
|
|
style['fontColor'] = fontColor;
|
|
style['fontSize'] = '9';
|
|
style['movable'] = '0';
|
|
style['strokeWidth'] = strokeWidth;
|
|
style['rounded'] = '0';
|
|
style[mxConstants.STYLE_FONTSIZE] = '11';
|
|
|
|
|
|
// Sets join node size
|
|
style['startSize'] = joinNodeSize;
|
|
style['endSize'] = joinNodeSize;
|
|
|
|
style = this.graph.getStylesheet().getDefaultVertexStyle();
|
|
//style['gradientColor'] = '#909090';
|
|
style['strokeColor'] = strokeColor;
|
|
//style['fillColor'] = '#e0e0e0';
|
|
style['fillColor'] = 'none';
|
|
style['fontColor'] = fontColor;
|
|
style['fontStyle'] = '1';
|
|
style['fontSize'] = '6';
|
|
style['resizable'] = '0';
|
|
style['strokeWidth'] = strokeWidth;
|
|
// let canvas = this.canvas;
|
|
let doc = this.document;
|
|
|
|
let sheetObject = doc.objects.find(o => o instanceof AltiumSheet);
|
|
|
|
// canvas.style.width = sheetObject.width + "px";
|
|
// canvas.style.height = sheetObject.height + "px";
|
|
// canvas.width = sheetObject.width * window.devicePixelRatio;
|
|
// canvas.height = sheetObject.height * window.devicePixelRatio;
|
|
let areaColourInt = Number.parseInt(sheetObject.attributes.areacolor, 10);
|
|
let areaColour = this.#altiumColourToHex(areaColourInt);
|
|
// canvas.style.backgroundColor = areaColour;
|
|
// let ctx = canvas.getContext('2d');
|
|
// ctx.scale(1, -1);
|
|
// ctx.translate(0.5, 0.5);
|
|
// ctx.translate(0, -canvas.height);
|
|
// ctx.font = "7pt sans-serif";
|
|
// ctx.textRendering = "optimizeLegibility";
|
|
// ctx.imageSmoothingQuality = "high";
|
|
// ctx.textBaseline = "bottom";
|
|
// ctx.fillStyle = areaColour;
|
|
// ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
let results = document.getElementById("results");
|
|
|
|
let sheet = doc.objects.find((o) => o instanceof AltiumSheet);
|
|
let gridLight = "#eeeeee";
|
|
let gridDark = "#cccccc";
|
|
// ctx.lineWidth = 1;
|
|
// ctx.globalAlpha = 0.5;
|
|
if (sheet.show_grid)
|
|
{
|
|
|
|
let n = 0;
|
|
// for (let x = 0; x < canvas.width; x += sheet.grid_size)
|
|
// {
|
|
// ctx.strokeStyle = ((n % 10) == 0) ? gridDark : gridLight;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(x, 0);
|
|
// ctx.lineTo(x, canvas.height);
|
|
// ctx.stroke();
|
|
// n++;
|
|
// }
|
|
// n = 0;
|
|
// for (let y = 0; y < canvas.height; y += sheet.grid_size)
|
|
// {
|
|
// ctx.strokeStyle = ((n % 10) == 0) ? gridDark : gridLight;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(0, y);
|
|
// ctx.lineTo(canvas.width, y);
|
|
// ctx.stroke();
|
|
// n++;
|
|
// }
|
|
}
|
|
// ctx.globalAlpha = 1;
|
|
|
|
/*
|
|
|
|
ctx.textAlign = "center";
|
|
ctx.font = "bold 100px serif";
|
|
ctx.fillStyle = "#333300";
|
|
ctx.globalAlpha = 0.03;
|
|
ctx.save();
|
|
|
|
ctx.rotate(Math.PI/4);
|
|
ctx.scale(1,-1);
|
|
for (let y = 0; y < canvas.height * 2; y += 400)
|
|
{
|
|
ctx.fillText("PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA", canvas.width / 2, canvas.height - (y + 200));
|
|
ctx.fillText("BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW - BETA - PREVIEW", canvas.width / 2, canvas.height - y);
|
|
}
|
|
|
|
ctx.textAlign = "left";
|
|
*/
|
|
|
|
this.graph.getModel().beginUpdate();
|
|
try{
|
|
let bom = [];
|
|
bom.push("\"designator\", \"part\", \"description\"");
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumDesignator))
|
|
{
|
|
if (!this.#shouldShow(obj)) continue;
|
|
|
|
let bomLine = "";
|
|
//let designator = doc.objects.find((des) => des instanceof AltiumDesignator && des.owner_part_id == obj.current_part_id);
|
|
let component = doc.object_from_record_index(obj.owner_record_index);
|
|
if (component != null && component instanceof AltiumComponent)
|
|
{
|
|
bomLine += "\"" + obj.text + "\", \"" + component.design_item_id + "\", \"" + component.description.replaceAll("\"", "'") + "\"";
|
|
bom.push(bomLine);
|
|
}
|
|
//bomLine += obj.description;
|
|
|
|
}
|
|
results.innerText = bom.join("\n");
|
|
|
|
// for (let obj of doc.objects.filter((o) => o instanceof AltiumWire))
|
|
// {
|
|
// // for (let i = 1; i < obj.points.length; i++)
|
|
// // {
|
|
// // obj.points[i].y = 840 - obj.points[i].y
|
|
// // }
|
|
// var obj1 = this.graph.getCellAt(obj.points[0].x,obj.points[0].y,parent)
|
|
// var obj2 = this.graph.getCellAt(obj.points[obj.points.length - 1].x,
|
|
// obj.points[obj.points.length - 1].y,parent)
|
|
|
|
// mxLog.debug(obj1,obj2)
|
|
// // if (!this.#shouldShow(obj)) continue;
|
|
|
|
// // ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// // ctx.lineWidth = obj.width;
|
|
// // ctx.beginPath();
|
|
// // ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// // for (let i = 1; i < obj.points.length; i++)
|
|
// // {
|
|
// // ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// // }
|
|
// // ctx.stroke();
|
|
// }
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumBus))
|
|
{
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// for (let i = 1; i < obj.points.length; i++)
|
|
// {
|
|
// ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// }
|
|
// ctx.stroke();
|
|
}
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumSheetSymbol))
|
|
{
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.attributes.areacolor);
|
|
|
|
// ctx.fillRect(obj.attributes.location_x,
|
|
// obj.attributes.location_y- obj.attributes.ysize,
|
|
// obj.attributes.xsize, obj.attributes.ysize);
|
|
// ctx.stroke();
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.attributes.color);
|
|
// ctx.strokeRect(obj.attributes.location_x,
|
|
// obj.attributes.location_y- obj.attributes.ysize,
|
|
// obj.attributes.xsize, obj.attributes.ysize);
|
|
|
|
|
|
// ctx.strokeStyle = "#000080";
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.attributes.location_x, obj.attributes.location_y);
|
|
// ctx.lineTo(obj.attributes.location_x + obj.attributes.xsize,
|
|
// obj.attributes.location_y + obj.attributes.ysize);
|
|
// ctx.stroke();
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// for (let i = 1; i < obj.points.length; i++)
|
|
// {
|
|
// ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// }
|
|
// ctx.stroke();
|
|
}
|
|
let chips = {}
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumRectangle))
|
|
{
|
|
obj.top = 840 - obj.top
|
|
obj.bottom = 840 - obj.bottom
|
|
if(!obj.transparent){
|
|
mxLog.debug('verticalLabelPosition=top;verticalAlign=bottom;fillColor='
|
|
+ this.#altiumColourToHex(obj.attributes.areacolor))
|
|
let v1 = this.graph.insertVertex(parent, null, '',
|
|
obj.left, obj.top,
|
|
(obj.right - obj.left),
|
|
(obj.bottom - obj.top),
|
|
'verticalLabelPosition=top;verticalAlign=bottom;fillColor='
|
|
+ this.#altiumColourToHex(obj.attributes.areacolor));
|
|
v1.setConnectable(false);
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
v1.geometry.relative = false
|
|
chips[obj.owner_record_index].push(v1)
|
|
}
|
|
// if (!this.#shouldShow(obj))
|
|
// continue;
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.attributes.areacolor);
|
|
|
|
// ctx.fillRect(obj.attributes.location_x,
|
|
// obj.attributes.location_y,
|
|
// obj.attributes.corner_x - obj.attributes.location_x, obj.attributes.corner_y - obj.attributes.location_y);
|
|
// ctx.stroke();
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.attributes.color);
|
|
// ctx.strokeRect(obj.attributes.location_x,
|
|
// obj.attributes.location_y,
|
|
// obj.attributes.corner_x - obj.attributes.location_x, obj.attributes.corner_y - obj.attributes.location_y);
|
|
|
|
}
|
|
|
|
// todo undo
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumSheetEntry))
|
|
{
|
|
if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// for (let i = 1; i < obj.points.length; i++)
|
|
// {
|
|
// ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// }
|
|
// ctx.stroke();
|
|
}
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumTextFrame))
|
|
{
|
|
obj = obj
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (!obj.transparent)
|
|
// {
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.fill_colour);
|
|
// ctx.fillRect(obj.left, obj.top, obj.right - obj.left,
|
|
// obj.bottom - obj.top);
|
|
// }
|
|
// if (obj.show_border)
|
|
// {
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.border_colour);
|
|
// ctx.strokeRect(obj.left, obj.top, obj.right - obj.left,
|
|
// obj.bottom - obj.top);
|
|
// }
|
|
}
|
|
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumPin))
|
|
{
|
|
var style = 'shape=line;fontColor=#000000;strokeColor=#000000;'
|
|
let name = ''
|
|
if(obj.show_name){
|
|
name = obj.name
|
|
}
|
|
if(obj.angle == 0){
|
|
style = style + 'labelPosition=left;'
|
|
}
|
|
if(obj.angle == 90){
|
|
style += 'rotation=90'
|
|
obj.y = obj.y + obj.length/2
|
|
obj.x = obj.x - obj.length/2
|
|
}
|
|
if(obj.angle == 180){
|
|
style = style + 'labelPosition=right;'
|
|
obj.x = obj.x - obj.length
|
|
}
|
|
if(obj.angle == 270){
|
|
style += 'rotation=90'
|
|
obj.y = obj.y - obj.length/2
|
|
obj.x = obj.x - obj.length/2
|
|
}
|
|
obj.y = 840 - obj.y
|
|
|
|
// mxLog.debug(style)
|
|
var v11 = this.graph.insertVertex(parent, null, name, obj.x, obj.y,
|
|
obj.length, 1,
|
|
style);
|
|
v11.geometry.relative = false;
|
|
v11.setConnectable(true);
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
v11.Pin = true
|
|
v11.angle = obj.angle
|
|
v11.length = obj.length
|
|
mxLog.debug(v11.geometry.getTerminalPoint (true))
|
|
chips[obj.owner_record_index].push(v11)
|
|
|
|
// v11.geometry.offset = new mxPoint(-v11.geometry.width, 2); // ctx.strokeStyle = "#000000";
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x, obj.y);
|
|
// ctx.lineTo(obj.x + obj.angle_vec[0] * obj.length, obj.y + obj.angle_vec[1] * obj.length);
|
|
// ctx.stroke();
|
|
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.beginPath();
|
|
// ctx.ellipse(obj.x + obj.angle_vec[0] * obj.length, obj.y + obj.angle_vec[1] * obj.length, 5, 4, 0, 0, 2*Math.PI);
|
|
// ctx.fill();
|
|
}
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumEllipse))
|
|
{
|
|
obj = obj
|
|
obj.y = 840-obj.y
|
|
let v1 = this.graph.insertVertex(parent, null, '',
|
|
obj.x - obj.radius_x, obj.y - obj.radius_x,
|
|
obj.radius_x*2, obj.radius_y*2,'shape=ellipse;fillColor='
|
|
+ this.#altiumColourToHex(obj.fill_colour));
|
|
v1.setConnectable(false)
|
|
chips[obj.owner_record_index].push(v1)
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (!obj.transparent)
|
|
// {
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.fill_colour);
|
|
// }
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.line_colour);
|
|
// ctx.beginPath();
|
|
// ctx.ellipse(obj.x, obj.y, obj.radius_x, obj.radius_y, 0, 0, Math.PI*2);
|
|
// ctx.stroke();
|
|
// if (!obj.transparent)
|
|
// ctx.fill();
|
|
}
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumLine)) {
|
|
mxCellRenderer.registerShape('polyline', mxPolyline);
|
|
obj.x2 = 840 - obj.x2
|
|
obj.y2 = 840 - obj.y2
|
|
style = 'shape=polyline;strokeColor=#0000ff;'
|
|
// mxLog.debug(style)
|
|
var v11 = this.graph.insertVertex(parent, null, '', obj.x1, obj.x2,
|
|
1,1,style);
|
|
v11.points = [new mxPoint(obj.y1 - obj.x1,obj.y2 - obj.x2)]
|
|
v11.geometry.relative = false;
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
v11.setConnectable(false);
|
|
|
|
chips[obj.owner_record_index].push(v11)
|
|
|
|
// 将cell设定为线段
|
|
// cell.edge = true;
|
|
|
|
|
|
// 设置起始点
|
|
// cell.geometry.setTerminalPoint(new mxPoint(obj.x1, obj.x2), true);
|
|
// 设置终结点
|
|
// cell.geometry.setTerminalPoint(new mxPoint(obj.y1, obj.y2), false);
|
|
// 使用 points 定义多个中间节点
|
|
// this.graph.model.root.insert(cell);
|
|
|
|
// this.graph.model.root.insert(cell);
|
|
// chips[obj.owner_record_index].push(cell)
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x1, obj.y1);
|
|
// ctx.lineTo(obj.x2, obj.y2);
|
|
// ctx.stroke();
|
|
}
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumArc))
|
|
{
|
|
obj = obj
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.arc(obj.x, obj.y, obj.radius, obj.start_angle * Math.PI/180, obj.end_angle * Math.PI/180);
|
|
// ctx.stroke();
|
|
// ctx.lineWidth = 1;
|
|
}
|
|
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumPolygon))
|
|
{
|
|
obj = obj
|
|
mxCellRenderer.registerShape('polygon', mxPolygon);
|
|
obj.x2 = 840 - obj.x2
|
|
obj.y2 = 840 - obj.y2
|
|
style = 'shape=polygon;strokeColor=#0000ff;'
|
|
// mxLog.debug(style)
|
|
var v11 = this.graph.insertVertex(parent, null, '', obj.points[0], obj.points[0],
|
|
1,1,style);
|
|
|
|
v11.points = obj.obj.points
|
|
v11.geometry.relative = false;
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
if(chips[obj.owner_record_index] == undefined){
|
|
chips[obj.owner_record_index] = []
|
|
}
|
|
v11.setConnectable(false);
|
|
|
|
chips[obj.owner_record_index].push(v11)
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.line_colour);
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.fill_colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// for (let i = 1; i < obj.points.length; i++)
|
|
// {
|
|
// ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// }
|
|
// ctx.closePath();
|
|
// ctx.stroke();
|
|
// ctx.fill();
|
|
// ctx.lineWidth = 1;
|
|
}
|
|
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumPowerPort))
|
|
{
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = 1;
|
|
// if (!obj.is_off_sheet_connector)
|
|
// {
|
|
// switch (obj.style)
|
|
// {
|
|
// case 2:
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x, obj.y);
|
|
// ctx.lineTo(obj.x, obj.y + 10);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 5, obj.y + 10);
|
|
// ctx.lineTo(obj.x + 5, obj.y + 10);
|
|
// ctx.stroke();
|
|
// break;
|
|
// case 4:
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 10, obj.y);
|
|
// ctx.lineTo(obj.x + 10, obj.y);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 7.5, obj.y - 2);
|
|
// ctx.lineTo(obj.x + 7.5, obj.y - 2);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 5, obj.y - 4);
|
|
// ctx.lineTo(obj.x + 5, obj.y - 4);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 2.5, obj.y - 6);
|
|
// ctx.lineTo(obj.x + 2.5, obj.y - 6);
|
|
// ctx.stroke();
|
|
// break;
|
|
// case 6:
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x, obj.y);
|
|
// ctx.lineTo(obj.x, obj.y - 5);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x - 5, obj.y - 5);
|
|
// ctx.lineTo(obj.x + 5, obj.y - 5);
|
|
// ctx.stroke();
|
|
// for (let g = -1; g < 2; g++)
|
|
// {
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.x + (g * 5), obj.y - 5);
|
|
// ctx.lineTo(obj.x + (g * 5) - 3, obj.y - 10);
|
|
// ctx.stroke();
|
|
// }
|
|
// break;
|
|
// default:
|
|
// ctx.fillRect(obj.x - 10, obj.y, 20, (obj.orientation == 1) ? 10 : -10);
|
|
// break;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, obj.y);
|
|
// ctx.rotate((obj.orientation - 1) * Math.PI/2);
|
|
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(0, 0);
|
|
// ctx.lineTo(-5, 5);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(0, 0);
|
|
// ctx.lineTo(5, 5);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(0, 5);
|
|
// ctx.lineTo(-5, 10);
|
|
// ctx.stroke();
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(0, 5);
|
|
// ctx.lineTo(5, 10);
|
|
// ctx.stroke();
|
|
|
|
// ctx.restore();
|
|
// }
|
|
//ctx.fillText(obj.style.toString(), obj.x, obj.y);
|
|
}
|
|
|
|
// store the transform for recovery later
|
|
// let savedTransform = ctx.getTransform();
|
|
// ctx.resetTransform();
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumLabel))
|
|
{
|
|
obj.y = 840 - obj.y
|
|
if(obj.text != undefined){
|
|
mxLog.debug(obj.text.length)
|
|
var v11 = this.graph.insertVertex(parent, null, obj.text, obj.x, obj.y - 4,
|
|
obj.text.length*9/2, 0,
|
|
"shape=label;fontSize=6;");
|
|
v11.geometry.relative = false;
|
|
v11.setConnectable(false);
|
|
if(obj.owner_record_index != 1)
|
|
chips[obj.owner_record_index].push(v11)
|
|
}
|
|
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (obj.hidden)
|
|
// continue;
|
|
// ctx.textAlign = ["left", "center", "right"][obj.justification];
|
|
// ctx.textBaseline = ["bottom", "bottom", "top", "top"][obj.orientation];
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, canvas.height - obj.y);
|
|
// ctx.rotate(obj.orientation * -Math.PI/2);
|
|
// ctx.fillText(obj.text, 0, 0);
|
|
// ctx.restore();
|
|
}
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumDesignator))
|
|
{
|
|
obj = obj
|
|
obj.y = 840 - obj.y
|
|
if(obj.text != undefined){
|
|
mxLog.debug(obj.text.length)
|
|
var v11 = this.graph.insertVertex(parent, null, obj.text, obj.x, obj.y - 5,
|
|
obj.text.length*9/2, 0,
|
|
"shape=label;fontSize=9;");
|
|
v11.geometry.relative = false;
|
|
v11.setConnectable(false);
|
|
if(obj.owner_record_index != 1)
|
|
chips[obj.owner_record_index].push(v11)
|
|
}
|
|
|
|
}
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumParameter)) {
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (obj.hidden || obj.is_implementation_parameter)
|
|
// continue;
|
|
|
|
// ctx.textAlign = ["left", "left", "right", "right"][obj.orientation];
|
|
// ctx.textBaseline = ["bottom", "bottom", "top", "top"][obj.orientation];
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// if (obj.orientation == 1)
|
|
// {
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, canvas.height - obj.y);
|
|
// ctx.rotate(-Math.PI/2);
|
|
// ctx.fillText(obj.text, 0, 0);
|
|
// ctx.restore();
|
|
// }
|
|
// else if (obj.orientation == 3)
|
|
// {
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, canvas.height - obj.y);
|
|
// ctx.rotate(Math.PI/2);
|
|
// ctx.fillText(obj.text, 0, 0);
|
|
// ctx.restore();
|
|
// }
|
|
// else
|
|
// {
|
|
// ctx.fillText(obj.text, obj.x, canvas.height - obj.y);
|
|
// }
|
|
}
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumNetLabel)) {
|
|
obj = obj
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (obj.hidden)
|
|
// continue;
|
|
// ctx.textAlign = ["left", "center", "right"][obj.justification];
|
|
// ctx.textBaseline = ["bottom", "bottom", "top", "top"][obj.orientation];
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// if (obj.orientation == 1)
|
|
// {
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, canvas.height - obj.y);
|
|
// ctx.rotate(-Math.PI/2);
|
|
// ctx.fillText(obj.text, 0, 0);
|
|
// ctx.restore();
|
|
// }
|
|
// else if (obj.orientation == 3)
|
|
// {
|
|
// ctx.save();
|
|
// ctx.translate(obj.x, canvas.height - obj.y);
|
|
// ctx.rotate(Math.PI/2);
|
|
// ctx.fillText(obj.text, 0, 0);
|
|
// ctx.restore();
|
|
// }
|
|
// else
|
|
// {
|
|
// ctx.fillText(obj.text, obj.x, canvas.height - obj.y);
|
|
// }
|
|
}
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumPowerPort)) {
|
|
obj = obj
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (!obj.show_text)
|
|
// continue;
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.textBaseline = ["middle", "top", "middle", "bottom"][obj.orientation];
|
|
// ctx.textAlign = ["left", "center", "right", "center"][obj.orientation];
|
|
// let offset_x = [12, 0, -12, 0][obj.orientation];
|
|
// let offset_y = [0, 20, 0, -20][obj.orientation];
|
|
// ctx.fillText(obj.text, obj.x + offset_x, canvas.height - (obj.y + offset_y));
|
|
}
|
|
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "middle";
|
|
// let savedFont = ctx.font;
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumTextFrame)) {
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// if (obj.font_id > 0 && doc.sheet.fonts[obj.font_id] != null)
|
|
// {
|
|
// const frameFont = doc.sheet.fonts[obj.font_id];
|
|
// const fontStr = (frameFont.size - 1).toString() + "px " + frameFont.name;
|
|
// if (fontStr.includes(":") || fontStr.includes("/") || !document.fonts.check(fontStr))
|
|
// {
|
|
// ctx.font = savedFont;
|
|
// }
|
|
// else
|
|
// {
|
|
// ctx.font = fontStr;
|
|
// }
|
|
// }
|
|
|
|
// ctx.fillStyle = this.#altiumColourToHex(obj.text_colour);
|
|
// ctx.textAlign = ["center", "left", "right"][obj.alignment];
|
|
// let offset_x = [(obj.right-obj.left)/2, obj.text_margin, (obj.right-obj.left) - obj.text_margin][obj.alignment];
|
|
// if (!obj.word_wrap)
|
|
// {
|
|
// ctx.fillText(obj.text.replaceAll("~1", "\n"), obj.left + offset_x, canvas.height - (obj.top + (obj.bottom-obj.top)/2));
|
|
// }
|
|
// else
|
|
// {
|
|
// // todo: refactor this so that an initial pass figures out all the line splits, then a second pass writes the text, so that vertical alignment can be supported.
|
|
// const text = obj.text.replaceAll("~1", "\n");
|
|
// const lines = text.split("\n");
|
|
// let ypos = 0;
|
|
// if (lines.length > 1)
|
|
// {
|
|
// // this is a total hack, but if there are multiple lines in the text then we can make a rough guess at how far up we need to shift the text to center it vertically
|
|
// // this doesn't correct for line wraps (see todo above for refactoring approach) but it's at least something I guess!
|
|
// const roughMeasure = ctx.measureText(text);
|
|
// ypos = ((roughMeasure.fontBoundingBoxDescent + roughMeasure.fontBoundingBoxAscent) * -lines.length) / 2;
|
|
// }
|
|
// const maxWidth = (obj.right - obj.left) + (obj.text_margin * 2);
|
|
// for (let line of lines)
|
|
// {
|
|
// const lineMeasure = ctx.measureText(line);
|
|
// if (lineMeasure.width <= maxWidth)
|
|
// {
|
|
// ctx.fillText(line, obj.left + offset_x, (canvas.height - (obj.top + (obj.bottom-obj.top)/2)) + ypos);
|
|
// ypos += lineMeasure.fontBoundingBoxDescent + lineMeasure.fontBoundingBoxAscent;
|
|
// }
|
|
// else
|
|
// {
|
|
// let words = line.split(" ");
|
|
// while (words.length > 0)
|
|
// {
|
|
// if (words.length == 1)
|
|
// {
|
|
// // we only have one word, either because that's just how many we had or because the final word is super long
|
|
// const lastWord = words[0];
|
|
// const lastWordMeasure = ctx.measureText(lastWord);
|
|
// ctx.fillText(lastWord, obj.left + offset_x, (canvas.height - (obj.top + (obj.bottom-obj.top)/2)) + ypos);
|
|
// ypos += lastWordMeasure.fontBoundingBoxDescent + lineMeasure.fontBoundingBoxAscent;
|
|
// words = [];
|
|
// break;
|
|
// }
|
|
// for (let wc = words.length; wc > 0; wc--)
|
|
// {
|
|
// const partialLine = words.slice(0, wc - 1).join(" ");
|
|
// const partialMeasure = ctx.measureText(partialLine);
|
|
// if (partialMeasure.width <= maxWidth || wc == 1)
|
|
// {
|
|
// ctx.fillText(partialLine, obj.left + offset_x, (canvas.height - (obj.top + (obj.bottom-obj.top)/2)) + ypos);
|
|
// ypos += partialMeasure.fontBoundingBoxDescent + lineMeasure.fontBoundingBoxAscent;
|
|
// words = words.slice(wc - 1);
|
|
// break;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumWire))
|
|
{
|
|
let poi = []
|
|
for (let i = 0; i < obj.points.length; i++) {
|
|
obj.points[i].y = 840 - obj.points[i].y
|
|
if((i != 0) &&(i != obj.points.length)){
|
|
poi.push(new mxPoint(obj.points[i].x , obj.points[i].y))
|
|
}
|
|
}
|
|
|
|
var e6 = this.graph.insertEdge(parent, null, '',null,null,'fillColor=fff2ff,startArrow=oval')
|
|
e6.geometry.points = poi
|
|
|
|
e6.geometry.setTerminalPoint(new mxPoint(obj.points[0].x, obj.points[0].y), true)
|
|
e6.geometry.setTerminalPoint(new mxPoint(obj.points[obj.points.length - 1].x,
|
|
obj.points[obj.points.length - 1].y), false)
|
|
|
|
|
|
if(this.wires == undefined){
|
|
this.wires = []
|
|
this.wires.push(e6)
|
|
}else{
|
|
this.wires.push(e6)
|
|
}
|
|
|
|
|
|
// if (!this.#shouldShow(obj)) continue;
|
|
|
|
// ctx.strokeStyle = this.#altiumColourToHex(obj.colour);
|
|
// ctx.lineWidth = obj.width;
|
|
// ctx.beginPath();
|
|
// ctx.moveTo(obj.points[0].x, obj.points[0].y);
|
|
// for (let i = 1; i < obj.points.length; i++)
|
|
// {
|
|
// ctx.lineTo(obj.points[i].x, obj.points[i].y);
|
|
// }
|
|
// ctx.stroke();
|
|
}
|
|
|
|
// find the junction on the wire
|
|
for (let obj of doc.objects.filter((o) => o instanceof AltiumJunction))
|
|
{
|
|
obj.y = 840 - obj.y
|
|
let found = false
|
|
for(let i = 0;i < this.wires.length;i++){
|
|
for(let j = 0;j < this.wires[i].geometry.points.length;j++){
|
|
if((this.wires[i].geometry.points[j].x == obj.x)
|
|
&&(this.wires[i].geometry.points[j].y == obj.y)){
|
|
found = true
|
|
// this.wires[i].geometry.points.push(new mxPoint(obj.x,obj.y))
|
|
// this.wires[i].geometry.points.push(obj.x,obj.y)
|
|
}
|
|
}
|
|
}
|
|
// obj = obj
|
|
// obj.y = 840 - obj.y
|
|
// let edge = this.graph.getCellsBeyond(obj.x,obj.y)
|
|
// mxLog.debug(edge)
|
|
|
|
var v11 = this.graph.insertVertex(parent, null, '', obj.x - 1, obj.y - 1,
|
|
1,1,'');
|
|
|
|
for (let i in chips){
|
|
let chip = this.graph.groupCells(null,0,chips[i])
|
|
chip.setStyle("border=0;strokeColor=none")
|
|
}
|
|
}
|
|
}
|
|
finally{
|
|
this.graph.getModel().endUpdate();
|
|
}
|
|
// ctx.font = savedFont;
|
|
|
|
// ctx.textAlign = "left";
|
|
// ctx.textBaseline = "bottom";
|
|
|
|
// ctx.setTransform(savedTransform);
|
|
|
|
// savedFont = ctx.font;
|
|
// ctx.textAlign = "left";
|
|
// ctx.font = "bold 33px sans-serif";
|
|
// ctx.fillStyle = "#000000";
|
|
// ctx.globalAlpha = 0.2;
|
|
// ctx.save();
|
|
// ctx.scale(1,-1);
|
|
// ctx.fillText("Preview generated by altium.js", 10, -(canvas.height - 50));
|
|
// ctx.font = "bold 15px sans-serif";
|
|
// ctx.fillText("for reference purposes only. schematic accuracy not guaranteed.", 12, -(canvas.height - 75));
|
|
// ctx.restore();
|
|
// ctx.globalAlpha = 1;
|
|
// ctx.font = savedFont;
|
|
}
|
|
} |