2022-11-06 03:37:52 +00:00
/ *
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 .
* /
2024-03-02 01:40:02 +00:00
mxConnectionHandler . prototype . movePreviewAway = false ;
mxConnectionHandler . prototype . waypointsEnabled = true ;
mxGraph . prototype . resetEdgesOnConnect = false ;
mxConstants . SHADOWCOLOR = '#C0C0C0' ;
var joinNodeSize = 7 ;
var strokeWidth = 2 ;
2022-11-06 03:37:52 +00:00
class AltiumSchematicRenderer
{
constructor ( canvas , document )
{
this . canvas = canvas ;
this . document = document ;
2024-03-02 01:40:02 +00:00
this . graph = null
2022-11-06 03:37:52 +00:00
}
# 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 ;
}
2024-03-02 01:40:02 +00:00
render ( ) {
2024-03-05 05:44:11 +00:00
let oldMove = mxGraphHandler . prototype . mouseMove
2024-03-04 12:51:04 +00:00
mxGraphHandler . prototype . mouseMove = function ( sender , me ) {
2024-03-06 15:40:58 +00:00
console . log ( "mouse move" , sender , me )
2024-03-04 12:51:04 +00:00
// 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 ) ;
2024-03-06 15:40:58 +00:00
} else if ( this . shape != null ) {
console . log ( "mouseMove" , this )
2024-03-04 12:51:04 +00:00
}
2024-03-05 05:44:11 +00:00
oldMove . call ( this , sender , me ) ;
}
let oldClick = mxGraphHandler . prototype . mouseDown
mxGraphHandler . prototype . mouseDown = function ( sender , me ) {
console . log ( "mouse down" , 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 ) {
oldClick . call ( this , sender , me ) ;
} else {
// oldClick.call(this, sender, me);
}
}
2024-03-04 12:51:04 +00:00
}
2024-03-05 05:44:11 +00:00
2024-03-04 12:51:04 +00:00
// 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 ( ) ;
}
} ;
2024-03-05 05:44:11 +00:00
2024-03-02 01:40:02 +00:00
this . graph = new mxGraph ( document . getElementById ( 'graphContainer' ) ) ;
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
2024-03-06 15:40:58 +00:00
this . graph . maximumGraphBounds = new mxRectangle ( 0 , 0 , 1920 , 1024 )
2024-03-03 05:14:38 +00:00
this . graph . border = 0 ;
2024-03-02 01:40:02 +00:00
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 ) ;
2024-03-04 12:51:04 +00:00
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
console . log ( "sss" )
return ;
}
}
connectionHandlerMouseUp . apply ( this , arguments ) ;
} ;
2024-03-06 15:40:58 +00:00
mxVertexHandler . prototype . rotationEnabled = false ;
2024-03-02 01:40:02 +00:00
// 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 ;
console . log ( "getAllConnectionConstraints " )
if ( ( geo != null ? ! geo . relative : false ) &&
this . getModel ( ) . isVertex ( terminal . cell ) &&
this . getModel ( ) . getChildCount ( terminal . cell ) == 0 )
{
2024-03-05 05:44:11 +00:00
return [ new mxConnectionConstraint ( new mxPoint ( 0 , 0.5 ) , false ) ,
new mxConnectionConstraint ( new mxPoint ( 1 , 0.5 ) , false ) ] ;
}
return null ;
} ;
2024-03-02 01:40:02 +00:00
// Makes sure non-relative cells can only be connected via constraints
2024-03-05 05:44:11 +00:00
this . graph . connectionHandler . isConnectableCell = function ( cell ) {
2024-03-02 01:40:02 +00:00
if ( this . graph . getModel ( ) . isEdge ( cell ) )
{
return true ;
2024-02-25 16:34:35 +00:00
}
2024-03-02 01:40:02 +00:00
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' ;
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
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' ;
// 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' ] = '12' ;
style [ 'resizable' ] = '0' ;
style [ 'strokeWidth' ] = strokeWidth ;
2024-02-25 16:34:35 +00:00
// let canvas = this.canvas;
2022-11-06 03:37:52 +00:00
let doc = this . document ;
let sheetObject = doc . objects . find ( o => o instanceof AltiumSheet ) ;
2024-02-25 16:34:35 +00:00
// canvas.style.width = sheetObject.width + "px";
// canvas.style.height = sheetObject.height + "px";
// canvas.width = sheetObject.width * window.devicePixelRatio;
// canvas.height = sheetObject.height * window.devicePixelRatio;
2022-11-06 03:37:52 +00:00
let areaColourInt = Number . parseInt ( sheetObject . attributes . areacolor , 10 ) ;
let areaColour = this . # altiumColourToHex ( areaColourInt ) ;
2024-02-25 16:34:35 +00:00
// 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);
2022-11-06 03:37:52 +00:00
let results = document . getElementById ( "results" ) ;
let sheet = doc . objects . find ( ( o ) => o instanceof AltiumSheet ) ;
let gridLight = "#eeeeee" ;
let gridDark = "#cccccc" ;
2024-02-25 16:34:35 +00:00
// ctx.lineWidth = 1;
// ctx.globalAlpha = 0.5;
2022-11-06 03:37:52 +00:00
if ( sheet . show _grid )
{
2024-02-25 16:34:35 +00:00
2022-11-06 03:37:52 +00:00
let n = 0 ;
2024-02-25 16:34:35 +00:00
// 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++;
// }
2022-11-06 03:37:52 +00:00
}
2024-02-25 16:34:35 +00:00
// ctx.globalAlpha = 1;
2022-11-06 03:37:52 +00:00
/ *
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" ;
* /
2024-03-02 01:40:02 +00:00
this . graph . getModel ( ) . beginUpdate ( ) ;
try {
let bom = [ ] ;
bom . push ( "\"designator\", \"part\", \"description\"" ) ;
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumDesignator ) )
2022-11-06 03:37:52 +00:00
{
2024-03-02 01:40:02 +00:00
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;
2022-11-06 03:37:52 +00:00
}
2024-03-02 01:40:02 +00:00
results . innerText = bom . join ( "\n" ) ;
2022-11-06 03:37:52 +00:00
2024-03-04 12:51:04 +00:00
// 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)
// console.log(obj1,obj2)
// // if (!this.#shouldShow(obj)) continue;
2024-03-02 01:40:02 +00:00
2024-03-04 12:51:04 +00:00
// // 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();
// }
2024-03-02 01:40:02 +00:00
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();
}
2024-03-03 05:14:38 +00:00
let chips = { }
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumRectangle ) )
{
obj . top = 840 - obj . top
obj . bottom = 840 - obj . bottom
console . log ( 'verticalLabelPosition=top;verticalAlign=bottom;fillColor='
+ this . # altiumColourToHex ( obj . attributes . areacolor ) )
2024-03-04 12:51:04 +00:00
let v1 = this . graph . insertVertex ( parent , null , '' ,
2024-03-02 01:40:02 +00:00
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 ) ;
2024-03-03 05:14:38 +00:00
if ( chips [ obj . owner _record _index ] == undefined ) {
chips [ obj . owner _record _index ] = [ ]
}
2024-03-04 12:51:04 +00:00
v1 . geometry . relative = false
2024-03-03 05:14:38 +00:00
chips [ obj . owner _record _index ] . push ( v1 )
2024-03-02 01:40:02 +00:00
2024-03-04 12:51:04 +00:00
// if (!this.#shouldShow(obj))
2024-03-02 01:40:02 +00:00
// continue;
2024-02-25 16:34:35 +00:00
// ctx.fillStyle = this.#altiumColourToHex(obj.attributes.areacolor);
// ctx.fillRect(obj.attributes.location_x,
2024-03-02 01:40:02 +00:00
// obj.attributes.location_y,
// obj.attributes.corner_x - obj.attributes.location_x, obj.attributes.corner_y - obj.attributes.location_y);
2024-02-25 16:34:35 +00:00
// ctx.stroke();
// ctx.strokeStyle = this.#altiumColourToHex(obj.attributes.color);
// ctx.strokeRect(obj.attributes.location_x,
2024-03-02 01:40:02 +00:00
// obj.attributes.location_y,
// obj.attributes.corner_x - obj.attributes.location_x, obj.attributes.corner_y - obj.attributes.location_y);
}
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
// 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();
}
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumTextFrame ) )
{
// 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);
// }
}
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumEllipse ) )
{
// 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 AltiumPin ) )
{
var style = 'shape=line;fontColor=#000000;strokeColor=#000000;'
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 ) {
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
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// console.log(style)
var v11 = this . graph . insertVertex ( parent , null , '' , obj . x , obj . y ,
obj . length , 1 ,
style ) ;
v11 . geometry . relative = false ;
v11 . setConnectable ( true ) ;
2024-03-03 05:14:38 +00:00
if ( chips [ obj . owner _record _index ] == undefined ) {
chips [ obj . owner _record _index ] = [ ]
}
chips [ obj . owner _record _index ] . push ( v11 )
2024-03-04 12:51:04 +00:00
2024-03-02 01:40:02 +00:00
// 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();
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
// 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();
}
2022-11-06 03:37:52 +00:00
2024-03-05 05:44:11 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumLine ) ) {
2024-03-06 15:40:58 +00:00
mxCellRenderer . registerShape ( 'polyline' , mxPolyline ) ;
2024-03-05 05:44:11 +00:00
obj . x2 = 840 - obj . x2
obj . y2 = 840 - obj . y2
2024-03-06 15:40:58 +00:00
style = 'shape=polyline;strokeColor=#0000ff;'
// console.log(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 )
2024-03-05 05:44:11 +00:00
// 将cell设定为线段
// cell.edge = true;
// 设置起始点
2024-03-06 15:40:58 +00:00
// cell.geometry.setTerminalPoint(new mxPoint(obj.x1, obj.x2), true);
2024-03-05 05:44:11 +00:00
// 设置终结点
2024-03-06 15:40:58 +00:00
// cell.geometry.setTerminalPoint(new mxPoint(obj.y1, obj.y2), false);
2024-03-05 05:44:11 +00:00
// 使用 points 定义多个中间节点
2024-03-06 15:40:58 +00:00
// this.graph.model.root.insert(cell);
2024-03-05 05:44:11 +00:00
// this.graph.model.root.insert(cell);
// chips[obj.owner_record_index].push(cell)
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// 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();
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumArc ) )
{
// 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;
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumPolygon ) )
{
2024-03-06 15:40:58 +00:00
2024-03-02 01:40:02 +00:00
// 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;
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumJunction ) )
{
2024-03-06 15:40:58 +00:00
2024-03-02 01:40:02 +00:00
// if (!this.#shouldShow(obj)) continue;
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
// ctx.beginPath();
// ctx.ellipse(obj.x, obj.y, 5, 4, 0, 0, 2*Math.PI);
// ctx.fill();
}
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumPowerPort ) )
{
2024-03-06 15:40:58 +00:00
2024-03-02 01:40:02 +00:00
// if (!this.#shouldShow(obj)) continue;
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// 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);
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// store the transform for recovery later
// let savedTransform = ctx.getTransform();
// ctx.resetTransform();
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumLabel ) )
{
2024-03-06 15:40:58 +00:00
obj . y = 840 - obj . y
var v11 = this . graph . insertVertex ( parent , null , obj . text , obj . x , obj . y ,
0 , 0 ,
"shape=label" ) ;
v11 . geometry . relative = false ;
v11 . setConnectable ( false ) ;
if ( obj . owner _record _index != 1 )
chips [ obj . owner _record _index ] . push ( v11 )
2024-03-02 01:40:02 +00:00
// 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";
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumDesignator ) )
{
// if (!this.#shouldShow(obj)) continue;
// if (obj.hidden)
// continue;
// ctx.textAlign = ["left", "left", "right", "right"][obj.orientation];
// ctx.textBaseline = ["bottom", "bottom", "top", "top"][obj.orientation];
// ctx.fillStyle = this.#altiumColourToHex(obj.colour);
// ctx.fillText(obj.full_designator, obj.x, canvas.height - obj.y);
}
// ctx.textAlign = "left";
// ctx.textBaseline = "bottom";
2022-11-06 03:37:52 +00:00
2024-03-06 15:40:58 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumParameter ) ) {
2024-03-02 01:40:02 +00:00
// 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";
2022-11-06 03:37:52 +00:00
2024-03-06 15:40:58 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumNetLabel ) ) {
obj = obj
2024-03-02 01:40:02 +00:00
// 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";
2022-11-06 03:37:52 +00:00
2024-03-05 05:44:11 +00:00
2024-03-02 01:40:02 +00:00
// ctx.textAlign = "left";
// ctx.textBaseline = "bottom";
2024-03-06 15:40:58 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumPowerPort ) ) {
obj = obj
2024-03-02 01:40:02 +00:00
// 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));
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
// ctx.textAlign = "left";
2024-02-25 16:34:35 +00:00
// ctx.textBaseline = "middle";
2024-03-02 01:40:02 +00:00
// let savedFont = ctx.font;
2024-03-06 15:40:58 +00:00
for ( let obj of doc . objects . filter ( ( o ) => o instanceof AltiumTextFrame ) ) {
2024-03-02 01:40:02 +00:00
// 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;
// }
// }
// }
// }
// }
// }
}
2022-11-06 03:37:52 +00:00
2024-03-02 01:40:02 +00:00
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 , '' )
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 )
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 )
for ( let i in this . graph . model . cells ) {
if ( this . graph . model . cells [ i ] . geometry != undefined ) {
//
if ( ( this . graph . model . cells [ i ] . geometry [ 'x' ] == obj . points [ 0 ] . x )
&& ( this . graph . model . cells [ i ] . geometry [ 'y' ] == obj . points [ 0 ] . y ) ) {
console . log ( "find first" )
console . log ( this . graph . model . cells [ i ] . geometry )
}
}
}
// 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();
}
2024-03-03 05:14:38 +00:00
for ( let i in chips ) {
let chip = this . graph . groupCells ( null , 0 , chips [ i ] )
2024-03-04 12:51:04 +00:00
chip . setStyle ( "border=0;strokeColor=none" )
2024-03-03 05:14:38 +00:00
}
2022-11-06 03:37:52 +00:00
}
2024-03-02 01:40:02 +00:00
finally {
this . graph . getModel ( ) . endUpdate ( ) ;
2022-11-06 03:37:52 +00:00
}
2024-03-02 01:40:02 +00:00
// ctx.font = savedFont;
// ctx.textAlign = "left";
// ctx.textBaseline = "bottom";
2024-02-25 16:34:35 +00:00
2024-03-02 01:40:02 +00:00
// 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;
2022-11-06 03:37:52 +00:00
}
}