circuit-to-canvas 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +407 -182
- package/lib/drawer/CircuitToCanvasDrawer.ts +1 -5
- package/lib/drawer/elements/pcb-copper-text.ts +23 -37
- package/lib/drawer/elements/pcb-hole.ts +248 -61
- package/lib/drawer/elements/pcb-plated-hole.ts +194 -102
- package/lib/drawer/elements/pcb-smtpad.ts +14 -17
- package/package.json +1 -1
- package/tests/board-snapshot/__snapshots__/usb-c-flashlight-board.snap.png +0 -0
- package/tests/elements/__snapshots__/board-with-elements.snap.png +0 -0
- package/tests/elements/__snapshots__/custom-outline-board.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-board.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-comprehensive-soldermask-margin.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-copper-text-knockout.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-fabrication-note-dimension.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-hole-soldermask-margin.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-keepout-layer-filter.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-keepout-multiple-layers.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-keepout-rect-and-circle.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-keepout-with-group-id.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-note-dimension-with-offset.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-plated-hole-soldermask-margin.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-silkscreen-oval.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-smtpad-soldermask-margin.snap.png +0 -0
- package/tests/elements/pcb-comprehensive-soldermask-margin.test.ts +330 -0
- package/tests/elements/pcb-hole-soldermask-margin.test.ts +5 -5
- package/tests/elements/pcb-plated-hole-soldermask-margin.test.ts +8 -8
- package/tests/elements/pcb-smtpad-soldermask-margin.test.ts +0 -6
- package/tests/shapes/__snapshots__/dimension-line.snap.png +0 -0
package/dist/index.js
CHANGED
|
@@ -464,8 +464,9 @@ function getSoldermaskColor(layers, colorMap) {
|
|
|
464
464
|
}
|
|
465
465
|
function drawPcbPlatedHole(params) {
|
|
466
466
|
const { ctx, hole, realToCanvasMat, colorMap } = params;
|
|
467
|
-
const
|
|
468
|
-
const margin =
|
|
467
|
+
const isCoveredWithSoldermask = hole.is_covered_with_solder_mask === true;
|
|
468
|
+
const margin = isCoveredWithSoldermask ? 0 : hole.soldermask_margin ?? 0;
|
|
469
|
+
const hasSoldermask = !isCoveredWithSoldermask && hole.soldermask_margin !== void 0 && hole.soldermask_margin !== 0;
|
|
469
470
|
const soldermaskRingColor = getSoldermaskColor(hole.layers, colorMap);
|
|
470
471
|
const positiveMarginColor = colorMap.substrate;
|
|
471
472
|
const copperColor = colorMap.copper.top;
|
|
@@ -497,13 +498,24 @@ function drawPcbPlatedHole(params) {
|
|
|
497
498
|
copperColor
|
|
498
499
|
);
|
|
499
500
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
501
|
+
if (isCoveredWithSoldermask) {
|
|
502
|
+
drawCircle({
|
|
503
|
+
ctx,
|
|
504
|
+
center: { x: hole.x, y: hole.y },
|
|
505
|
+
radius: hole.outer_diameter / 2,
|
|
506
|
+
fill: soldermaskRingColor,
|
|
507
|
+
realToCanvasMat
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
if (!isCoveredWithSoldermask) {
|
|
511
|
+
drawCircle({
|
|
512
|
+
ctx,
|
|
513
|
+
center: { x: hole.x, y: hole.y },
|
|
514
|
+
radius: hole.hole_diameter / 2,
|
|
515
|
+
fill: colorMap.drill,
|
|
516
|
+
realToCanvasMat
|
|
517
|
+
});
|
|
518
|
+
}
|
|
507
519
|
return;
|
|
508
520
|
}
|
|
509
521
|
if (hole.shape === "oval") {
|
|
@@ -540,15 +552,28 @@ function drawPcbPlatedHole(params) {
|
|
|
540
552
|
copperColor
|
|
541
553
|
);
|
|
542
554
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
555
|
+
if (isCoveredWithSoldermask) {
|
|
556
|
+
drawOval({
|
|
557
|
+
ctx,
|
|
558
|
+
center: { x: hole.x, y: hole.y },
|
|
559
|
+
radius_x: hole.outer_width / 2,
|
|
560
|
+
radius_y: hole.outer_height / 2,
|
|
561
|
+
fill: soldermaskRingColor,
|
|
562
|
+
realToCanvasMat,
|
|
563
|
+
rotation: hole.ccw_rotation
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
if (!isCoveredWithSoldermask) {
|
|
567
|
+
drawOval({
|
|
568
|
+
ctx,
|
|
569
|
+
center: { x: hole.x, y: hole.y },
|
|
570
|
+
radius_x: hole.hole_width / 2,
|
|
571
|
+
radius_y: hole.hole_height / 2,
|
|
572
|
+
fill: colorMap.drill,
|
|
573
|
+
realToCanvasMat,
|
|
574
|
+
rotation: hole.ccw_rotation
|
|
575
|
+
});
|
|
576
|
+
}
|
|
552
577
|
return;
|
|
553
578
|
}
|
|
554
579
|
if (hole.shape === "pill") {
|
|
@@ -585,15 +610,28 @@ function drawPcbPlatedHole(params) {
|
|
|
585
610
|
copperColor
|
|
586
611
|
);
|
|
587
612
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
613
|
+
if (isCoveredWithSoldermask) {
|
|
614
|
+
drawPill({
|
|
615
|
+
ctx,
|
|
616
|
+
center: { x: hole.x, y: hole.y },
|
|
617
|
+
width: hole.outer_width,
|
|
618
|
+
height: hole.outer_height,
|
|
619
|
+
fill: soldermaskRingColor,
|
|
620
|
+
realToCanvasMat,
|
|
621
|
+
rotation: hole.ccw_rotation
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
if (!isCoveredWithSoldermask) {
|
|
625
|
+
drawPill({
|
|
626
|
+
ctx,
|
|
627
|
+
center: { x: hole.x, y: hole.y },
|
|
628
|
+
width: hole.hole_width,
|
|
629
|
+
height: hole.hole_height,
|
|
630
|
+
fill: colorMap.drill,
|
|
631
|
+
realToCanvasMat,
|
|
632
|
+
rotation: hole.ccw_rotation
|
|
633
|
+
});
|
|
634
|
+
}
|
|
597
635
|
return;
|
|
598
636
|
}
|
|
599
637
|
if (hole.shape === "circular_hole_with_rect_pad") {
|
|
@@ -631,15 +669,28 @@ function drawPcbPlatedHole(params) {
|
|
|
631
669
|
copperColor
|
|
632
670
|
);
|
|
633
671
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
672
|
+
if (isCoveredWithSoldermask) {
|
|
673
|
+
drawRect({
|
|
674
|
+
ctx,
|
|
675
|
+
center: { x: hole.x, y: hole.y },
|
|
676
|
+
width: hole.rect_pad_width,
|
|
677
|
+
height: hole.rect_pad_height,
|
|
678
|
+
fill: soldermaskRingColor,
|
|
679
|
+
realToCanvasMat,
|
|
680
|
+
borderRadius: hole.rect_border_radius ?? 0
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
if (!isCoveredWithSoldermask) {
|
|
684
|
+
const holeX = hole.x + (hole.hole_offset_x ?? 0);
|
|
685
|
+
const holeY = hole.y + (hole.hole_offset_y ?? 0);
|
|
686
|
+
drawCircle({
|
|
687
|
+
ctx,
|
|
688
|
+
center: { x: holeX, y: holeY },
|
|
689
|
+
radius: hole.hole_diameter / 2,
|
|
690
|
+
fill: colorMap.drill,
|
|
691
|
+
realToCanvasMat
|
|
692
|
+
});
|
|
693
|
+
}
|
|
643
694
|
return;
|
|
644
695
|
}
|
|
645
696
|
if (hole.shape === "pill_hole_with_rect_pad") {
|
|
@@ -677,16 +728,29 @@ function drawPcbPlatedHole(params) {
|
|
|
677
728
|
copperColor
|
|
678
729
|
);
|
|
679
730
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
731
|
+
if (isCoveredWithSoldermask) {
|
|
732
|
+
drawRect({
|
|
733
|
+
ctx,
|
|
734
|
+
center: { x: hole.x, y: hole.y },
|
|
735
|
+
width: hole.rect_pad_width,
|
|
736
|
+
height: hole.rect_pad_height,
|
|
737
|
+
fill: soldermaskRingColor,
|
|
738
|
+
realToCanvasMat,
|
|
739
|
+
borderRadius: hole.rect_border_radius ?? 0
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
if (!isCoveredWithSoldermask) {
|
|
743
|
+
const holeX = hole.x + (hole.hole_offset_x ?? 0);
|
|
744
|
+
const holeY = hole.y + (hole.hole_offset_y ?? 0);
|
|
745
|
+
drawPill({
|
|
746
|
+
ctx,
|
|
747
|
+
center: { x: holeX, y: holeY },
|
|
748
|
+
width: hole.hole_width,
|
|
749
|
+
height: hole.hole_height,
|
|
750
|
+
fill: colorMap.drill,
|
|
751
|
+
realToCanvasMat
|
|
752
|
+
});
|
|
753
|
+
}
|
|
690
754
|
return;
|
|
691
755
|
}
|
|
692
756
|
if (hole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
@@ -726,17 +790,31 @@ function drawPcbPlatedHole(params) {
|
|
|
726
790
|
copperColor
|
|
727
791
|
);
|
|
728
792
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
793
|
+
if (isCoveredWithSoldermask) {
|
|
794
|
+
drawRect({
|
|
795
|
+
ctx,
|
|
796
|
+
center: { x: hole.x, y: hole.y },
|
|
797
|
+
width: hole.rect_pad_width,
|
|
798
|
+
height: hole.rect_pad_height,
|
|
799
|
+
fill: soldermaskRingColor,
|
|
800
|
+
realToCanvasMat,
|
|
801
|
+
borderRadius: hole.rect_border_radius ?? 0,
|
|
802
|
+
rotation: hole.rect_ccw_rotation
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
if (!isCoveredWithSoldermask) {
|
|
806
|
+
const holeX = hole.x + (hole.hole_offset_x ?? 0);
|
|
807
|
+
const holeY = hole.y + (hole.hole_offset_y ?? 0);
|
|
808
|
+
drawPill({
|
|
809
|
+
ctx,
|
|
810
|
+
center: { x: holeX, y: holeY },
|
|
811
|
+
width: hole.hole_width,
|
|
812
|
+
height: hole.hole_height,
|
|
813
|
+
fill: colorMap.drill,
|
|
814
|
+
realToCanvasMat,
|
|
815
|
+
rotation: hole.hole_ccw_rotation
|
|
816
|
+
});
|
|
817
|
+
}
|
|
740
818
|
return;
|
|
741
819
|
}
|
|
742
820
|
if (hole.shape === "hole_with_polygon_pad") {
|
|
@@ -753,44 +831,46 @@ function drawPcbPlatedHole(params) {
|
|
|
753
831
|
realToCanvasMat
|
|
754
832
|
});
|
|
755
833
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
834
|
+
if (!isCoveredWithSoldermask) {
|
|
835
|
+
const holeX = hole.x + (hole.hole_offset_x ?? 0);
|
|
836
|
+
const holeY = hole.y + (hole.hole_offset_y ?? 0);
|
|
837
|
+
const holeShape = hole.hole_shape;
|
|
838
|
+
if (holeShape === "circle") {
|
|
839
|
+
drawCircle({
|
|
840
|
+
ctx,
|
|
841
|
+
center: { x: holeX, y: holeY },
|
|
842
|
+
radius: (hole.hole_diameter ?? 0) / 2,
|
|
843
|
+
fill: colorMap.drill,
|
|
844
|
+
realToCanvasMat
|
|
845
|
+
});
|
|
846
|
+
} else if (holeShape === "oval") {
|
|
847
|
+
drawOval({
|
|
848
|
+
ctx,
|
|
849
|
+
center: { x: holeX, y: holeY },
|
|
850
|
+
radius_x: (hole.hole_width ?? 0) / 2,
|
|
851
|
+
radius_y: (hole.hole_height ?? 0) / 2,
|
|
852
|
+
fill: colorMap.drill,
|
|
853
|
+
realToCanvasMat
|
|
854
|
+
});
|
|
855
|
+
} else if (holeShape === "pill") {
|
|
856
|
+
drawPill({
|
|
857
|
+
ctx,
|
|
858
|
+
center: { x: holeX, y: holeY },
|
|
859
|
+
width: hole.hole_width ?? 0,
|
|
860
|
+
height: hole.hole_height ?? 0,
|
|
861
|
+
fill: colorMap.drill,
|
|
862
|
+
realToCanvasMat
|
|
863
|
+
});
|
|
864
|
+
} else if (holeShape === "rotated_pill") {
|
|
865
|
+
drawPill({
|
|
866
|
+
ctx,
|
|
867
|
+
center: { x: holeX, y: holeY },
|
|
868
|
+
width: hole.hole_width ?? 0,
|
|
869
|
+
height: hole.hole_height ?? 0,
|
|
870
|
+
fill: colorMap.drill,
|
|
871
|
+
realToCanvasMat
|
|
872
|
+
});
|
|
873
|
+
}
|
|
794
874
|
}
|
|
795
875
|
return;
|
|
796
876
|
}
|
|
@@ -824,9 +904,12 @@ function getRotation(hole) {
|
|
|
824
904
|
}
|
|
825
905
|
function drawPcbHole(params) {
|
|
826
906
|
const { ctx, hole, realToCanvasMat, colorMap } = params;
|
|
827
|
-
const
|
|
828
|
-
const margin =
|
|
907
|
+
const isCoveredWithSoldermask = hole.is_covered_with_solder_mask === true;
|
|
908
|
+
const margin = isCoveredWithSoldermask ? 0 : hole.soldermask_margin ?? 0;
|
|
909
|
+
const hasSoldermask = !isCoveredWithSoldermask && hole.soldermask_margin !== void 0 && hole.soldermask_margin !== 0;
|
|
829
910
|
const positiveMarginColor = colorMap.substrate;
|
|
911
|
+
const soldermaskOverlayColor = colorMap.soldermask.top;
|
|
912
|
+
const soldermaskRingColor = colorMap.soldermask.top;
|
|
830
913
|
if (hole.hole_shape === "circle") {
|
|
831
914
|
if (hasSoldermask && margin > 0) {
|
|
832
915
|
drawCircle({
|
|
@@ -837,13 +920,35 @@ function drawPcbHole(params) {
|
|
|
837
920
|
realToCanvasMat
|
|
838
921
|
});
|
|
839
922
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
923
|
+
if (!isCoveredWithSoldermask) {
|
|
924
|
+
drawCircle({
|
|
925
|
+
ctx,
|
|
926
|
+
center: { x: hole.x, y: hole.y },
|
|
927
|
+
radius: hole.hole_diameter / 2,
|
|
928
|
+
fill: colorMap.drill,
|
|
929
|
+
realToCanvasMat
|
|
930
|
+
});
|
|
931
|
+
if (hasSoldermask && margin < 0) {
|
|
932
|
+
drawSoldermaskRingForCircle(
|
|
933
|
+
ctx,
|
|
934
|
+
{ x: hole.x, y: hole.y },
|
|
935
|
+
hole.hole_diameter / 2,
|
|
936
|
+
margin,
|
|
937
|
+
realToCanvasMat,
|
|
938
|
+
soldermaskRingColor,
|
|
939
|
+
colorMap.drill
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (isCoveredWithSoldermask) {
|
|
944
|
+
drawCircle({
|
|
945
|
+
ctx,
|
|
946
|
+
center: { x: hole.x, y: hole.y },
|
|
947
|
+
radius: hole.hole_diameter / 2,
|
|
948
|
+
fill: soldermaskOverlayColor,
|
|
949
|
+
realToCanvasMat
|
|
950
|
+
});
|
|
951
|
+
}
|
|
847
952
|
return;
|
|
848
953
|
}
|
|
849
954
|
if (hole.hole_shape === "square") {
|
|
@@ -859,15 +964,42 @@ function drawPcbHole(params) {
|
|
|
859
964
|
rotation
|
|
860
965
|
});
|
|
861
966
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
967
|
+
if (!isCoveredWithSoldermask) {
|
|
968
|
+
drawRect({
|
|
969
|
+
ctx,
|
|
970
|
+
center: { x: hole.x, y: hole.y },
|
|
971
|
+
width: hole.hole_diameter,
|
|
972
|
+
height: hole.hole_diameter,
|
|
973
|
+
fill: colorMap.drill,
|
|
974
|
+
realToCanvasMat,
|
|
975
|
+
rotation
|
|
976
|
+
});
|
|
977
|
+
if (hasSoldermask && margin < 0) {
|
|
978
|
+
drawSoldermaskRingForRect(
|
|
979
|
+
ctx,
|
|
980
|
+
{ x: hole.x, y: hole.y },
|
|
981
|
+
hole.hole_diameter,
|
|
982
|
+
hole.hole_diameter,
|
|
983
|
+
margin,
|
|
984
|
+
0,
|
|
985
|
+
rotation,
|
|
986
|
+
realToCanvasMat,
|
|
987
|
+
soldermaskRingColor,
|
|
988
|
+
colorMap.drill
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
if (isCoveredWithSoldermask) {
|
|
993
|
+
drawRect({
|
|
994
|
+
ctx,
|
|
995
|
+
center: { x: hole.x, y: hole.y },
|
|
996
|
+
width: hole.hole_diameter,
|
|
997
|
+
height: hole.hole_diameter,
|
|
998
|
+
fill: soldermaskOverlayColor,
|
|
999
|
+
realToCanvasMat,
|
|
1000
|
+
rotation
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
871
1003
|
return;
|
|
872
1004
|
}
|
|
873
1005
|
if (hole.hole_shape === "oval") {
|
|
@@ -883,15 +1015,41 @@ function drawPcbHole(params) {
|
|
|
883
1015
|
rotation
|
|
884
1016
|
});
|
|
885
1017
|
}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1018
|
+
if (!isCoveredWithSoldermask) {
|
|
1019
|
+
drawOval({
|
|
1020
|
+
ctx,
|
|
1021
|
+
center: { x: hole.x, y: hole.y },
|
|
1022
|
+
radius_x: hole.hole_width / 2,
|
|
1023
|
+
radius_y: hole.hole_height / 2,
|
|
1024
|
+
fill: colorMap.drill,
|
|
1025
|
+
realToCanvasMat,
|
|
1026
|
+
rotation
|
|
1027
|
+
});
|
|
1028
|
+
if (hasSoldermask && margin < 0) {
|
|
1029
|
+
drawSoldermaskRingForOval(
|
|
1030
|
+
ctx,
|
|
1031
|
+
{ x: hole.x, y: hole.y },
|
|
1032
|
+
hole.hole_width / 2,
|
|
1033
|
+
hole.hole_height / 2,
|
|
1034
|
+
margin,
|
|
1035
|
+
rotation,
|
|
1036
|
+
realToCanvasMat,
|
|
1037
|
+
soldermaskRingColor,
|
|
1038
|
+
colorMap.drill
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
if (isCoveredWithSoldermask) {
|
|
1043
|
+
drawOval({
|
|
1044
|
+
ctx,
|
|
1045
|
+
center: { x: hole.x, y: hole.y },
|
|
1046
|
+
radius_x: hole.hole_width / 2,
|
|
1047
|
+
radius_y: hole.hole_height / 2,
|
|
1048
|
+
fill: soldermaskOverlayColor,
|
|
1049
|
+
realToCanvasMat,
|
|
1050
|
+
rotation
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
895
1053
|
return;
|
|
896
1054
|
}
|
|
897
1055
|
if (hole.hole_shape === "rect") {
|
|
@@ -907,15 +1065,42 @@ function drawPcbHole(params) {
|
|
|
907
1065
|
rotation
|
|
908
1066
|
});
|
|
909
1067
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1068
|
+
if (!isCoveredWithSoldermask) {
|
|
1069
|
+
drawRect({
|
|
1070
|
+
ctx,
|
|
1071
|
+
center: { x: hole.x, y: hole.y },
|
|
1072
|
+
width: hole.hole_width,
|
|
1073
|
+
height: hole.hole_height,
|
|
1074
|
+
fill: colorMap.drill,
|
|
1075
|
+
realToCanvasMat,
|
|
1076
|
+
rotation
|
|
1077
|
+
});
|
|
1078
|
+
if (hasSoldermask && margin < 0) {
|
|
1079
|
+
drawSoldermaskRingForRect(
|
|
1080
|
+
ctx,
|
|
1081
|
+
{ x: hole.x, y: hole.y },
|
|
1082
|
+
hole.hole_width,
|
|
1083
|
+
hole.hole_height,
|
|
1084
|
+
margin,
|
|
1085
|
+
0,
|
|
1086
|
+
rotation,
|
|
1087
|
+
realToCanvasMat,
|
|
1088
|
+
soldermaskRingColor,
|
|
1089
|
+
colorMap.drill
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (isCoveredWithSoldermask) {
|
|
1094
|
+
drawRect({
|
|
1095
|
+
ctx,
|
|
1096
|
+
center: { x: hole.x, y: hole.y },
|
|
1097
|
+
width: hole.hole_width,
|
|
1098
|
+
height: hole.hole_height,
|
|
1099
|
+
fill: soldermaskOverlayColor,
|
|
1100
|
+
realToCanvasMat,
|
|
1101
|
+
rotation
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
919
1104
|
return;
|
|
920
1105
|
}
|
|
921
1106
|
if (hole.hole_shape === "pill") {
|
|
@@ -931,15 +1116,41 @@ function drawPcbHole(params) {
|
|
|
931
1116
|
rotation
|
|
932
1117
|
});
|
|
933
1118
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1119
|
+
if (!isCoveredWithSoldermask) {
|
|
1120
|
+
drawPill({
|
|
1121
|
+
ctx,
|
|
1122
|
+
center: { x: hole.x, y: hole.y },
|
|
1123
|
+
width: hole.hole_width,
|
|
1124
|
+
height: hole.hole_height,
|
|
1125
|
+
fill: colorMap.drill,
|
|
1126
|
+
realToCanvasMat,
|
|
1127
|
+
rotation
|
|
1128
|
+
});
|
|
1129
|
+
if (hasSoldermask && margin < 0) {
|
|
1130
|
+
drawSoldermaskRingForPill(
|
|
1131
|
+
ctx,
|
|
1132
|
+
{ x: hole.x, y: hole.y },
|
|
1133
|
+
hole.hole_width,
|
|
1134
|
+
hole.hole_height,
|
|
1135
|
+
margin,
|
|
1136
|
+
rotation,
|
|
1137
|
+
realToCanvasMat,
|
|
1138
|
+
soldermaskRingColor,
|
|
1139
|
+
colorMap.drill
|
|
1140
|
+
);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
if (isCoveredWithSoldermask) {
|
|
1144
|
+
drawPill({
|
|
1145
|
+
ctx,
|
|
1146
|
+
center: { x: hole.x, y: hole.y },
|
|
1147
|
+
width: hole.hole_width,
|
|
1148
|
+
height: hole.hole_height,
|
|
1149
|
+
fill: soldermaskOverlayColor,
|
|
1150
|
+
realToCanvasMat,
|
|
1151
|
+
rotation
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
943
1154
|
return;
|
|
944
1155
|
}
|
|
945
1156
|
if (hole.hole_shape === "rotated_pill") {
|
|
@@ -955,15 +1166,41 @@ function drawPcbHole(params) {
|
|
|
955
1166
|
rotation
|
|
956
1167
|
});
|
|
957
1168
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1169
|
+
if (!isCoveredWithSoldermask) {
|
|
1170
|
+
drawPill({
|
|
1171
|
+
ctx,
|
|
1172
|
+
center: { x: hole.x, y: hole.y },
|
|
1173
|
+
width: hole.hole_width,
|
|
1174
|
+
height: hole.hole_height,
|
|
1175
|
+
fill: colorMap.drill,
|
|
1176
|
+
realToCanvasMat,
|
|
1177
|
+
rotation
|
|
1178
|
+
});
|
|
1179
|
+
if (hasSoldermask && margin < 0) {
|
|
1180
|
+
drawSoldermaskRingForPill(
|
|
1181
|
+
ctx,
|
|
1182
|
+
{ x: hole.x, y: hole.y },
|
|
1183
|
+
hole.hole_width,
|
|
1184
|
+
hole.hole_height,
|
|
1185
|
+
margin,
|
|
1186
|
+
rotation,
|
|
1187
|
+
realToCanvasMat,
|
|
1188
|
+
soldermaskRingColor,
|
|
1189
|
+
colorMap.drill
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (isCoveredWithSoldermask) {
|
|
1194
|
+
drawPill({
|
|
1195
|
+
ctx,
|
|
1196
|
+
center: { x: hole.x, y: hole.y },
|
|
1197
|
+
width: hole.hole_width,
|
|
1198
|
+
height: hole.hole_height,
|
|
1199
|
+
fill: soldermaskOverlayColor,
|
|
1200
|
+
realToCanvasMat,
|
|
1201
|
+
rotation
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
967
1204
|
return;
|
|
968
1205
|
}
|
|
969
1206
|
}
|
|
@@ -982,13 +1219,13 @@ function drawPcbSmtPad(params) {
|
|
|
982
1219
|
const { ctx, pad, realToCanvasMat, colorMap } = params;
|
|
983
1220
|
const color = layerToColor(pad.layer, colorMap);
|
|
984
1221
|
const isCoveredWithSoldermask = pad.is_covered_with_solder_mask === true;
|
|
985
|
-
const margin = isCoveredWithSoldermask
|
|
986
|
-
const hasSoldermask = isCoveredWithSoldermask && pad.soldermask_margin !== void 0 && pad.soldermask_margin !== 0;
|
|
1222
|
+
const margin = isCoveredWithSoldermask ? 0 : pad.soldermask_margin ?? 0;
|
|
1223
|
+
const hasSoldermask = !isCoveredWithSoldermask && pad.soldermask_margin !== void 0 && pad.soldermask_margin !== 0;
|
|
987
1224
|
const soldermaskRingColor = getSoldermaskColor2(pad.layer, colorMap);
|
|
988
1225
|
const positiveMarginColor = colorMap.substrate;
|
|
989
1226
|
const soldermaskOverlayColor = getSoldermaskColor2(pad.layer, colorMap);
|
|
990
1227
|
if (pad.shape === "rect") {
|
|
991
|
-
if (
|
|
1228
|
+
if (hasSoldermask && margin > 0) {
|
|
992
1229
|
drawRect({
|
|
993
1230
|
ctx,
|
|
994
1231
|
center: { x: pad.x, y: pad.y },
|
|
@@ -1036,7 +1273,7 @@ function drawPcbSmtPad(params) {
|
|
|
1036
1273
|
return;
|
|
1037
1274
|
}
|
|
1038
1275
|
if (pad.shape === "rotated_rect") {
|
|
1039
|
-
if (
|
|
1276
|
+
if (hasSoldermask && margin > 0) {
|
|
1040
1277
|
drawRect({
|
|
1041
1278
|
ctx,
|
|
1042
1279
|
center: { x: pad.x, y: pad.y },
|
|
@@ -1087,7 +1324,7 @@ function drawPcbSmtPad(params) {
|
|
|
1087
1324
|
return;
|
|
1088
1325
|
}
|
|
1089
1326
|
if (pad.shape === "circle") {
|
|
1090
|
-
if (
|
|
1327
|
+
if (hasSoldermask && margin > 0) {
|
|
1091
1328
|
drawCircle({
|
|
1092
1329
|
ctx,
|
|
1093
1330
|
center: { x: pad.x, y: pad.y },
|
|
@@ -1126,7 +1363,7 @@ function drawPcbSmtPad(params) {
|
|
|
1126
1363
|
return;
|
|
1127
1364
|
}
|
|
1128
1365
|
if (pad.shape === "pill") {
|
|
1129
|
-
if (
|
|
1366
|
+
if (hasSoldermask && margin > 0) {
|
|
1130
1367
|
drawPill({
|
|
1131
1368
|
ctx,
|
|
1132
1369
|
center: { x: pad.x, y: pad.y },
|
|
@@ -1170,7 +1407,7 @@ function drawPcbSmtPad(params) {
|
|
|
1170
1407
|
return;
|
|
1171
1408
|
}
|
|
1172
1409
|
if (pad.shape === "rotated_pill") {
|
|
1173
|
-
if (
|
|
1410
|
+
if (hasSoldermask && margin > 0) {
|
|
1174
1411
|
drawPill({
|
|
1175
1412
|
ctx,
|
|
1176
1413
|
center: { x: pad.x, y: pad.y },
|
|
@@ -1843,9 +2080,6 @@ function drawPcbCopperPour(params) {
|
|
|
1843
2080
|
// lib/drawer/elements/pcb-copper-text.ts
|
|
1844
2081
|
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
1845
2082
|
var DEFAULT_PADDING = { left: 0.2, right: 0.2, top: 0.2, bottom: 0.2 };
|
|
1846
|
-
function layerToCopperColor(layer, colorMap) {
|
|
1847
|
-
return colorMap.copper[layer] ?? colorMap.copper.top;
|
|
1848
|
-
}
|
|
1849
2083
|
function mapAnchorAlignment2(alignment) {
|
|
1850
2084
|
if (!alignment) return "center";
|
|
1851
2085
|
if (alignment.includes("left")) return "center_left";
|
|
@@ -1867,13 +2101,11 @@ function drawPcbCopperText(params) {
|
|
|
1867
2101
|
...DEFAULT_PADDING,
|
|
1868
2102
|
...text.knockout_padding
|
|
1869
2103
|
};
|
|
1870
|
-
const textColor =
|
|
2104
|
+
const textColor = colorMap.copper[text.layer] ?? colorMap.copper.top;
|
|
1871
2105
|
const layout = getAlphabetLayout(content, fontSize);
|
|
1872
2106
|
const totalWidth = layout.width + layout.strokeWidth;
|
|
1873
2107
|
const alignment = mapAnchorAlignment2(text.anchor_alignment);
|
|
1874
2108
|
const startPos = getTextStartPosition(alignment, layout);
|
|
1875
|
-
const startX = startPos.x;
|
|
1876
|
-
const startY = startPos.y;
|
|
1877
2109
|
ctx.save();
|
|
1878
2110
|
ctx.translate(x, y);
|
|
1879
2111
|
if (text.is_mirrored) ctx.scale(-1, 1);
|
|
@@ -1886,29 +2118,22 @@ function drawPcbCopperText(params) {
|
|
|
1886
2118
|
const paddingRight = padding.right * scale2;
|
|
1887
2119
|
const paddingTop = padding.top * scale2;
|
|
1888
2120
|
const paddingBottom = padding.bottom * scale2;
|
|
1889
|
-
const
|
|
1890
|
-
const
|
|
1891
|
-
const
|
|
1892
|
-
const
|
|
1893
|
-
const yOffset = textBoxTop - paddingTop;
|
|
1894
|
-
const knockoutWidth = totalWidth + paddingLeft + paddingRight;
|
|
1895
|
-
const knockoutHeight = textBoxHeight + paddingTop + paddingBottom;
|
|
2121
|
+
const rectX = startPos.x - paddingLeft * 4;
|
|
2122
|
+
const rectY = startPos.y - paddingTop * 4;
|
|
2123
|
+
const rectWidth = totalWidth + paddingLeft * 2 + paddingRight * 2;
|
|
2124
|
+
const rectHeight = layout.height + layout.strokeWidth + paddingTop * 2 + paddingBottom * 2;
|
|
1896
2125
|
ctx.fillStyle = textColor;
|
|
1897
|
-
ctx.fillRect(
|
|
1898
|
-
const previousCompositeOperation = ctx.globalCompositeOperation;
|
|
1899
|
-
ctx.globalCompositeOperation = "destination-out";
|
|
1900
|
-
ctx.fillStyle = "rgba(0,0,0,1)";
|
|
1901
|
-
ctx.strokeStyle = "rgba(0,0,0,1)";
|
|
1902
|
-
strokeAlphabetText({ ctx, text: content, fontSize, startX, startY });
|
|
1903
|
-
if (previousCompositeOperation) {
|
|
1904
|
-
ctx.globalCompositeOperation = previousCompositeOperation;
|
|
1905
|
-
} else {
|
|
1906
|
-
ctx.globalCompositeOperation = "source-over";
|
|
1907
|
-
}
|
|
2126
|
+
ctx.fillRect(rectX, rectY, rectWidth, rectHeight);
|
|
1908
2127
|
} else {
|
|
1909
2128
|
ctx.strokeStyle = textColor;
|
|
1910
|
-
strokeAlphabetText({ ctx, text: content, fontSize, startX, startY });
|
|
1911
2129
|
}
|
|
2130
|
+
strokeAlphabetText({
|
|
2131
|
+
ctx,
|
|
2132
|
+
text: content,
|
|
2133
|
+
fontSize,
|
|
2134
|
+
startX: startPos.x,
|
|
2135
|
+
startY: startPos.y
|
|
2136
|
+
});
|
|
1912
2137
|
ctx.restore();
|
|
1913
2138
|
}
|
|
1914
2139
|
|
|
@@ -2367,7 +2592,7 @@ var CircuitToCanvasDrawer = class {
|
|
|
2367
2592
|
(el) => el.type === "pcb_plated_hole" && el.is_covered_with_solder_mask === true
|
|
2368
2593
|
);
|
|
2369
2594
|
for (const element of elements) {
|
|
2370
|
-
if (element.type === "pcb_board"
|
|
2595
|
+
if (element.type === "pcb_board") {
|
|
2371
2596
|
this.drawBoardWithSoldermask(element);
|
|
2372
2597
|
} else {
|
|
2373
2598
|
this.drawElement(element, options);
|