circuit-to-canvas 0.0.8 → 0.0.10

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyCircuitElement, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNoteText } from 'circuit-json';
1
+ import { AnyCircuitElement, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText } from 'circuit-json';
2
2
  import { Matrix } from 'transformation-matrix';
3
3
 
4
4
  /**
@@ -370,6 +370,14 @@ interface DrawPcbFabricationNotePathParams {
370
370
  }
371
371
  declare function drawPcbFabricationNotePath(params: DrawPcbFabricationNotePathParams): void;
372
372
 
373
+ interface DrawPcbNotePathParams {
374
+ ctx: CanvasContext;
375
+ path: PcbNotePath;
376
+ transform: Matrix;
377
+ colorMap: PcbColorMap;
378
+ }
379
+ declare function drawPcbNotePath(params: DrawPcbNotePathParams): void;
380
+
373
381
  interface DrawPcbNoteTextParams {
374
382
  ctx: CanvasContext;
375
383
  text: PcbNoteText;
@@ -378,4 +386,4 @@ interface DrawPcbNoteTextParams {
378
386
  }
379
387
  declare function drawPcbNoteText(params: DrawPcbNoteTextParams): void;
380
388
 
381
- export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawCircleParams, type DrawContext, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawCircle, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenPath, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
389
+ export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawCircleParams, type DrawContext, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawCircle, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenPath, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
package/dist/index.js CHANGED
@@ -819,7 +819,6 @@ var GLYPH_WIDTH_RATIO = 0.62;
819
819
  var LETTER_SPACING_RATIO = 0.3;
820
820
  var SPACE_WIDTH_RATIO = 1;
821
821
  var STROKE_WIDTH_RATIO = 0.13;
822
- var CURVED_GLYPHS = /* @__PURE__ */ new Set(["O", "o", "0"]);
823
822
  function getAlphabetLayout(text, fontSize) {
824
823
  const glyphWidth = fontSize * GLYPH_WIDTH_RATIO;
825
824
  const letterSpacing = glyphWidth * LETTER_SPACING_RATIO;
@@ -873,23 +872,7 @@ function strokeAlphabetText(ctx, text, layout, startX, startY) {
873
872
  characters.forEach((char, index) => {
874
873
  const lines = getGlyphLines(char);
875
874
  const advance = char === " " ? spaceWidth : glyphWidth;
876
- if (CURVED_GLYPHS.has(char)) {
877
- const normalizedCenterY = 0.5;
878
- const centerY = topY + normalizedCenterY * height;
879
- const radiusX = Math.max(glyphWidth / 2 - strokeWidth / 2, strokeWidth);
880
- const radiusY = Math.max(height / 2 - strokeWidth / 2, strokeWidth);
881
- ctx.beginPath();
882
- ctx.ellipse(
883
- cursor + glyphWidth / 2,
884
- centerY,
885
- radiusX,
886
- radiusY,
887
- 0,
888
- 0,
889
- Math.PI * 2
890
- );
891
- ctx.stroke();
892
- } else if (lines?.length) {
875
+ if (lines?.length) {
893
876
  ctx.beginPath();
894
877
  for (const line of lines) {
895
878
  const x1 = cursor + line.x1 * glyphWidth;
@@ -1096,6 +1079,27 @@ function drawPcbFabricationNotePath(params) {
1096
1079
  }
1097
1080
  }
1098
1081
 
1082
+ // lib/drawer/elements/pcb-note-path.ts
1083
+ function drawPcbNotePath(params) {
1084
+ const { ctx, path, transform, colorMap } = params;
1085
+ const defaultColor = "rgb(89, 148, 220)";
1086
+ const color = path.color ?? defaultColor;
1087
+ if (!path.route || path.route.length < 2) return;
1088
+ for (let i = 0; i < path.route.length - 1; i++) {
1089
+ const start = path.route[i];
1090
+ const end = path.route[i + 1];
1091
+ if (!start || !end) continue;
1092
+ drawLine({
1093
+ ctx,
1094
+ start: { x: start.x, y: start.y },
1095
+ end: { x: end.x, y: end.y },
1096
+ strokeWidth: path.stroke_width ?? 0.1,
1097
+ stroke: color,
1098
+ transform
1099
+ });
1100
+ }
1101
+ }
1102
+
1099
1103
  // lib/drawer/elements/pcb-note-text.ts
1100
1104
  var DEFAULT_NOTE_TEXT_COLOR = "rgb(89, 148, 220)";
1101
1105
  function drawPcbNoteText(params) {
@@ -1328,6 +1332,14 @@ var CircuitToCanvasDrawer = class {
1328
1332
  colorMap: this.colorMap
1329
1333
  });
1330
1334
  }
1335
+ if (element.type === "pcb_note_path") {
1336
+ drawPcbNotePath({
1337
+ ctx: this.ctx,
1338
+ path: element,
1339
+ transform: this.realToCanvasMat,
1340
+ colorMap: this.colorMap
1341
+ });
1342
+ }
1331
1343
  if (element.type === "pcb_note_text") {
1332
1344
  drawPcbNoteText({
1333
1345
  ctx: this.ctx,
@@ -1353,6 +1365,7 @@ export {
1353
1365
  drawPcbFabricationNoteRect,
1354
1366
  drawPcbFabricationNoteText,
1355
1367
  drawPcbHole,
1368
+ drawPcbNotePath,
1356
1369
  drawPcbNoteRect,
1357
1370
  drawPcbNoteText,
1358
1371
  drawPcbPlatedHole,
@@ -18,6 +18,7 @@ import type {
18
18
  PcbFabricationNoteRect,
19
19
  PcbNoteRect,
20
20
  PcbFabricationNotePath,
21
+ PcbNotePath,
21
22
  PcbNoteText,
22
23
  } from "circuit-json"
23
24
  import { identity, compose, translate, scale } from "transformation-matrix"
@@ -49,6 +50,7 @@ import { drawPcbFabricationNoteText } from "./elements/pcb-fabrication-note-text
49
50
  import { drawPcbFabricationNoteRect } from "./elements/pcb-fabrication-note-rect"
50
51
  import { drawPcbNoteRect } from "./elements/pcb-note-rect"
51
52
  import { drawPcbFabricationNotePath } from "./elements/pcb-fabrication-note-path"
53
+ import { drawPcbNotePath } from "./elements/pcb-note-path"
52
54
  import { drawPcbNoteText } from "./elements/pcb-note-text"
53
55
 
54
56
  export interface DrawElementsOptions {
@@ -310,6 +312,15 @@ export class CircuitToCanvasDrawer {
310
312
  })
311
313
  }
312
314
 
315
+ if (element.type === "pcb_note_path") {
316
+ drawPcbNotePath({
317
+ ctx: this.ctx,
318
+ path: element as PcbNotePath,
319
+ transform: this.realToCanvasMat,
320
+ colorMap: this.colorMap,
321
+ })
322
+ }
323
+
313
324
  if (element.type === "pcb_note_text") {
314
325
  drawPcbNoteText({
315
326
  ctx: this.ctx,
@@ -58,6 +58,11 @@ export {
58
58
  type DrawPcbFabricationNotePathParams,
59
59
  } from "./pcb-fabrication-note-path"
60
60
 
61
+ export {
62
+ drawPcbNotePath,
63
+ type DrawPcbNotePathParams,
64
+ } from "./pcb-note-path"
65
+
61
66
  export {
62
67
  drawPcbNoteText,
63
68
  type DrawPcbNoteTextParams,
@@ -0,0 +1,39 @@
1
+ import type { PcbNotePath } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawLine } from "../shapes/line"
5
+
6
+ export interface DrawPcbNotePathParams {
7
+ ctx: CanvasContext
8
+ path: PcbNotePath
9
+ transform: Matrix
10
+ colorMap: PcbColorMap
11
+ }
12
+
13
+ export function drawPcbNotePath(params: DrawPcbNotePathParams): void {
14
+ const { ctx, path, transform, colorMap } = params
15
+
16
+ // Use the color from the path if provided, otherwise use a default color
17
+ // Notes are typically shown in a distinct color
18
+ const defaultColor = "rgb(89, 148, 220)" // Blue color for notes
19
+ const color = path.color ?? defaultColor
20
+
21
+ if (!path.route || path.route.length < 2) return
22
+
23
+ // Draw each segment of the path
24
+ for (let i = 0; i < path.route.length - 1; i++) {
25
+ const start = path.route[i]
26
+ const end = path.route[i + 1]
27
+
28
+ if (!start || !end) continue
29
+
30
+ drawLine({
31
+ ctx,
32
+ start: { x: start.x, y: start.y },
33
+ end: { x: end.x, y: end.y },
34
+ strokeWidth: path.stroke_width ?? 0.1,
35
+ stroke: color,
36
+ transform,
37
+ })
38
+ }
39
+ }
@@ -7,7 +7,6 @@ const GLYPH_WIDTH_RATIO = 0.62
7
7
  const LETTER_SPACING_RATIO = 0.3 // Letter spacing between characters (25% of glyph width)
8
8
  const SPACE_WIDTH_RATIO = 1
9
9
  const STROKE_WIDTH_RATIO = 0.13
10
- const CURVED_GLYPHS = new Set(["O", "o", "0"])
11
10
 
12
11
  export type AlphabetLayout = {
13
12
  width: number
@@ -125,23 +124,7 @@ export function strokeAlphabetText(
125
124
  const lines = getGlyphLines(char)
126
125
  const advance = char === " " ? spaceWidth : glyphWidth
127
126
 
128
- if (CURVED_GLYPHS.has(char)) {
129
- const normalizedCenterY = 0.5
130
- const centerY = topY + normalizedCenterY * height
131
- const radiusX = Math.max(glyphWidth / 2 - strokeWidth / 2, strokeWidth)
132
- const radiusY = Math.max(height / 2 - strokeWidth / 2, strokeWidth)
133
- ctx.beginPath()
134
- ctx.ellipse(
135
- cursor + glyphWidth / 2,
136
- centerY,
137
- radiusX,
138
- radiusY,
139
- 0,
140
- 0,
141
- Math.PI * 2,
142
- )
143
- ctx.stroke()
144
- } else if (lines?.length) {
127
+ if (lines?.length) {
145
128
  ctx.beginPath()
146
129
  for (const line of lines) {
147
130
  // Convert normalized y coordinates to canvas coordinates (inverted for canvas)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-to-canvas",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.8",
4
+ "version": "0.0.10",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup-node ./lib/index.ts --format esm --dts",
@@ -0,0 +1,34 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "canvas"
3
+ import type { PcbNotePath } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw pcb note path", async () => {
7
+ const canvas = createCanvas(100, 100)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 100, 100)
13
+
14
+ const path: PcbNotePath = {
15
+ type: "pcb_note_path",
16
+ pcb_note_path_id: "note_path1",
17
+ route: [
18
+ { x: 10, y: 50 },
19
+ { x: 30, y: 20 },
20
+ { x: 70, y: 20 },
21
+ { x: 90, y: 50 },
22
+ { x: 70, y: 80 },
23
+ { x: 30, y: 80 },
24
+ { x: 10, y: 50 },
25
+ ],
26
+ stroke_width: 2,
27
+ }
28
+
29
+ drawer.drawElements([path])
30
+
31
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
32
+ import.meta.path,
33
+ )
34
+ })