@bilalba/fig-mcp 1.0.1 → 1.1.3

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +110 -55
  3. package/dist/index.js +55 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/inspect-fig.d.ts +1 -1
  6. package/dist/inspect-fig.d.ts.map +1 -1
  7. package/dist/inspect-fig.js +7 -3
  8. package/dist/inspect-fig.js.map +1 -1
  9. package/dist/web-viewer/build-client.d.ts +1 -0
  10. package/dist/web-viewer/build-client.d.ts.map +1 -1
  11. package/dist/web-viewer/build-client.js +32 -5
  12. package/dist/web-viewer/build-client.js.map +1 -1
  13. package/dist/web-viewer/client/dist/viewer.js +10 -0
  14. package/dist/web-viewer/client/index.html +138 -0
  15. package/dist/web-viewer/client/styles.css +561 -0
  16. package/package.json +6 -3
  17. package/dist/debug/debug-stroke-geom.d.ts +0 -2
  18. package/dist/debug/debug-stroke-geom.d.ts.map +0 -1
  19. package/dist/debug/debug-stroke-geom.js +0 -67
  20. package/dist/debug/debug-stroke-geom.js.map +0 -1
  21. package/dist/debug/debug-transforms.d.ts +0 -2
  22. package/dist/debug/debug-transforms.d.ts.map +0 -1
  23. package/dist/debug/debug-transforms.js +0 -97
  24. package/dist/debug/debug-transforms.js.map +0 -1
  25. package/dist/debug/debug-vertex.d.ts +0 -2
  26. package/dist/debug/debug-vertex.d.ts.map +0 -1
  27. package/dist/debug/debug-vertex.js +0 -72
  28. package/dist/debug/debug-vertex.js.map +0 -1
  29. package/dist/debug-group.d.ts +0 -5
  30. package/dist/debug-group.d.ts.map +0 -1
  31. package/dist/debug-group.js +0 -44
  32. package/dist/debug-group.js.map +0 -1
  33. package/dist/debug-stroke-geom.d.ts +0 -2
  34. package/dist/debug-stroke-geom.d.ts.map +0 -1
  35. package/dist/debug-stroke-geom.js +0 -67
  36. package/dist/debug-stroke-geom.js.map +0 -1
  37. package/dist/debug-transforms.d.ts +0 -2
  38. package/dist/debug-transforms.d.ts.map +0 -1
  39. package/dist/debug-transforms.js +0 -97
  40. package/dist/debug-transforms.js.map +0 -1
  41. package/dist/debug-vertex.d.ts +0 -2
  42. package/dist/debug-vertex.d.ts.map +0 -1
  43. package/dist/debug-vertex.js +0 -72
  44. package/dist/debug-vertex.js.map +0 -1
  45. package/dist/experimental/paint-utils.d.ts +0 -35
  46. package/dist/experimental/paint-utils.d.ts.map +0 -1
  47. package/dist/experimental/paint-utils.js +0 -105
  48. package/dist/experimental/paint-utils.js.map +0 -1
  49. package/dist/experimental/render-screen-v2.d.ts +0 -32
  50. package/dist/experimental/render-screen-v2.d.ts.map +0 -1
  51. package/dist/experimental/render-screen-v2.js +0 -366
  52. package/dist/experimental/render-screen-v2.js.map +0 -1
  53. package/dist/experimental/render-screen.d.ts +0 -26
  54. package/dist/experimental/render-screen.d.ts.map +0 -1
  55. package/dist/experimental/render-screen.js +0 -547
  56. package/dist/experimental/render-screen.js.map +0 -1
  57. package/dist/experimental/render-types.d.ts +0 -43
  58. package/dist/experimental/render-types.d.ts.map +0 -1
  59. package/dist/experimental/render-types.js +0 -22
  60. package/dist/experimental/render-types.js.map +0 -1
  61. package/dist/experimental/render-utils.d.ts +0 -38
  62. package/dist/experimental/render-utils.d.ts.map +0 -1
  63. package/dist/experimental/render-utils.js +0 -126
  64. package/dist/experimental/render-utils.js.map +0 -1
  65. package/dist/experimental/screenshot.d.ts +0 -11
  66. package/dist/experimental/screenshot.d.ts.map +0 -1
  67. package/dist/experimental/screenshot.js +0 -26
  68. package/dist/experimental/screenshot.js.map +0 -1
  69. package/dist/experimental/vector-renderer.d.ts +0 -31
  70. package/dist/experimental/vector-renderer.d.ts.map +0 -1
  71. package/dist/experimental/vector-renderer.js +0 -427
  72. package/dist/experimental/vector-renderer.js.map +0 -1
  73. package/dist/test-render-v2.d.ts +0 -5
  74. package/dist/test-render-v2.d.ts.map +0 -1
  75. package/dist/test-render-v2.js +0 -76
  76. package/dist/test-render-v2.js.map +0 -1
@@ -1,427 +0,0 @@
1
- /**
2
- * Vector Renderer - Handles rendering of vector nodes to SVG
3
- *
4
- * This module contains all vector-related rendering logic including:
5
- * - Vector network decoding (blob and structured formats)
6
- * - Path command parsing and building
7
- * - Stroked and filled vector rendering
8
- */
9
- import { multiplyTransforms, buildSvgPath, computeCommandBounds } from "./render-utils.js";
10
- import { getPaints, getVisiblePaint, paintToColor } from "./paint-utils.js";
11
- // ============================================================================
12
- // Vector Network Decoding
13
- // ============================================================================
14
- /**
15
- * Decode vectorNetworkBlob to extract vertices and segments.
16
- *
17
- * Format: [vertexCount(4), segmentCount(4), regionCount(4), ...vertexData, ...segmentData]
18
- * Each vertex is 12 bytes: styleID(uint32), x(float32), y(float32)
19
- * Each segment is 28 bytes: styleID(4), startVertex(4), startDx(4), startDy(4), endVertex(4), endDx(4), endDy(4)
20
- */
21
- function decodeVectorNetworkBlob(blobIndex, blobs, ctx) {
22
- if (blobIndex === undefined || !blobs?.[blobIndex]?.bytes)
23
- return null;
24
- const bytes = blobs[blobIndex].bytes;
25
- if (bytes.length < 12)
26
- return null;
27
- try {
28
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.length);
29
- const vertexCount = view.getUint32(0, true);
30
- const segmentCount = view.getUint32(4, true);
31
- // regionCount at offset 8, not needed for centerline
32
- if (vertexCount > 1000 || segmentCount > 1000)
33
- return null;
34
- const vertices = [];
35
- const segments = [];
36
- const VERTEX_STRIDE = 12;
37
- let offset = 12;
38
- for (let i = 0; i < vertexCount && offset + VERTEX_STRIDE <= bytes.length; i++) {
39
- const x = view.getFloat32(offset + 4, true);
40
- const y = view.getFloat32(offset + 8, true);
41
- vertices.push({ x, y });
42
- offset += VERTEX_STRIDE;
43
- }
44
- const SEGMENT_STRIDE = 28;
45
- for (let i = 0; i < segmentCount && offset + SEGMENT_STRIDE <= bytes.length; i++) {
46
- const startVertex = view.getUint32(offset + 4, true);
47
- const startDx = view.getFloat32(offset + 8, true);
48
- const startDy = view.getFloat32(offset + 12, true);
49
- const endVertex = view.getUint32(offset + 16, true);
50
- const endDx = view.getFloat32(offset + 20, true);
51
- const endDy = view.getFloat32(offset + 24, true);
52
- if (startVertex < vertices.length && endVertex < vertices.length) {
53
- segments.push({
54
- start: {
55
- vertex: startVertex,
56
- dx: Number.isFinite(startDx) ? startDx : 0,
57
- dy: Number.isFinite(startDy) ? startDy : 0,
58
- },
59
- end: {
60
- vertex: endVertex,
61
- dx: Number.isFinite(endDx) ? endDx : 0,
62
- dy: Number.isFinite(endDy) ? endDy : 0,
63
- },
64
- });
65
- }
66
- offset += SEGMENT_STRIDE;
67
- }
68
- return { vertices, segments };
69
- }
70
- catch (e) {
71
- ctx.warnings.push(`Failed to decode vector network: ${e}`);
72
- return null;
73
- }
74
- }
75
- /**
76
- * Parse the structured vectorNetwork object from vectorData.
77
- * This is the preferred source for vector network data (not the blob).
78
- */
79
- function parseStructuredVectorNetwork(vectorData) {
80
- if (!vectorData?.vectorNetwork)
81
- return null;
82
- const vn = vectorData.vectorNetwork;
83
- if (!vn.vertices?.length || !vn.segments?.length)
84
- return null;
85
- const vertices = vn.vertices.map((v) => ({ x: v.x, y: v.y }));
86
- const segments = vn.segments.map((s) => ({
87
- start: {
88
- vertex: s.start.vertex,
89
- dx: s.start.dx ?? 0,
90
- dy: s.start.dy ?? 0,
91
- },
92
- end: {
93
- vertex: s.end.vertex,
94
- dx: s.end.dx ?? 0,
95
- dy: s.end.dy ?? 0,
96
- },
97
- }));
98
- return { vertices, segments };
99
- }
100
- // ============================================================================
101
- // Path Command Decoding
102
- // ============================================================================
103
- /**
104
- * Decode path commands from a binary blob.
105
- */
106
- export function decodePathCommands(blobIndex, blobs, ctx) {
107
- if (blobIndex === undefined || !blobs?.[blobIndex]?.bytes)
108
- return null;
109
- const bytes = blobs[blobIndex].bytes;
110
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.length);
111
- const cmdArgCounts = { 0: 0, 1: 2, 2: 2, 3: 4, 4: 6, 5: 4 };
112
- const commands = [];
113
- let offset = 0;
114
- while (offset < bytes.length) {
115
- const cmd = bytes[offset++];
116
- const argCount = cmdArgCounts[cmd];
117
- if (argCount === undefined)
118
- break;
119
- const values = [];
120
- for (let i = 0; i < argCount && offset + 4 <= bytes.length; i++) {
121
- values.push(view.getFloat32(offset, true));
122
- offset += 4;
123
- }
124
- commands.push({ cmd, values });
125
- }
126
- return commands.length > 0 ? commands : null;
127
- }
128
- /**
129
- * Decode path commands from an array format (alternative to blob).
130
- */
131
- export function decodePathCommandsFromArray(commands) {
132
- if (!commands?.length)
133
- return null;
134
- const cmdMap = { M: 1, L: 2, Q: 3, C: 4, Z: 0 };
135
- const argCounts = { 0: 0, 1: 2, 2: 2, 3: 4, 4: 6 };
136
- const result = [];
137
- let currentCmd = null;
138
- let buffer = [];
139
- for (const entry of commands) {
140
- if (typeof entry === "string") {
141
- const cmd = cmdMap[entry.toUpperCase()];
142
- if (cmd === undefined)
143
- continue;
144
- if (cmd === 0) {
145
- result.push({ cmd, values: [] });
146
- continue;
147
- }
148
- currentCmd = cmd;
149
- buffer = [];
150
- }
151
- else if (typeof entry === "number" && currentCmd !== null) {
152
- buffer.push(entry);
153
- const expected = argCounts[currentCmd] ?? 0;
154
- if (buffer.length === expected) {
155
- result.push({ cmd: currentCmd, values: buffer });
156
- buffer = [];
157
- }
158
- }
159
- }
160
- return result.length > 0 ? result : null;
161
- }
162
- // ============================================================================
163
- // Centerline Generation
164
- // ============================================================================
165
- /**
166
- * Create simple centerline path for a stroked vector from normalizedSize.
167
- * This is a straight line from (0,0) to (width, height).
168
- */
169
- function createCenterlineFromNormalizedSize(normalizedSize) {
170
- return [
171
- { cmd: 1, values: [0, 0] },
172
- { cmd: 2, values: [normalizedSize.x, normalizedSize.y] },
173
- ];
174
- }
175
- /**
176
- * Create centerline from decoded vector network.
177
- * Handles bezier curves using dx/dy control points.
178
- */
179
- function createCenterlineFromNetwork(network, normalizedSize) {
180
- if (network.vertices.length === 0)
181
- return null;
182
- // Filter out degenerate segments (where start vertex == end vertex)
183
- const validSegments = network.segments.filter((seg) => seg.start.vertex !== seg.end.vertex);
184
- if (validSegments.length === 0)
185
- return null;
186
- // Validate vertex coordinates against normalizedSize (with tolerance for stroke width)
187
- if (normalizedSize) {
188
- const tolerance = 2;
189
- for (const v of network.vertices) {
190
- if (v.x < -tolerance ||
191
- v.y < -tolerance ||
192
- v.x > normalizedSize.x + tolerance ||
193
- v.y > normalizedSize.y + tolerance) {
194
- return null;
195
- }
196
- }
197
- }
198
- const commands = [];
199
- const usedSegments = new Set();
200
- let currentVertex = validSegments[0].start.vertex;
201
- // Move to the starting vertex
202
- const startV = network.vertices[currentVertex];
203
- if (!startV)
204
- return null;
205
- commands.push({ cmd: 1, values: [startV.x, startV.y] });
206
- // Walk through segments to build the path
207
- while (usedSegments.size < validSegments.length) {
208
- let foundSegment = null;
209
- let foundIdx = -1;
210
- for (let i = 0; i < validSegments.length; i++) {
211
- if (usedSegments.has(i))
212
- continue;
213
- const seg = validSegments[i];
214
- if (seg.start.vertex === currentVertex) {
215
- foundSegment = seg;
216
- foundIdx = i;
217
- break;
218
- }
219
- }
220
- if (!foundSegment) {
221
- // No connected segment found, try to find any unused segment to continue
222
- for (let i = 0; i < validSegments.length; i++) {
223
- if (!usedSegments.has(i)) {
224
- foundSegment = validSegments[i];
225
- foundIdx = i;
226
- const v = network.vertices[foundSegment.start.vertex];
227
- if (v) {
228
- commands.push({ cmd: 1, values: [v.x, v.y] });
229
- }
230
- break;
231
- }
232
- }
233
- }
234
- if (!foundSegment || foundIdx === -1)
235
- break;
236
- usedSegments.add(foundIdx);
237
- const v0 = network.vertices[foundSegment.start.vertex];
238
- const v1 = network.vertices[foundSegment.end.vertex];
239
- if (!v0 || !v1)
240
- continue;
241
- const hasCurve = Math.abs(foundSegment.start.dx) > 0.001 ||
242
- Math.abs(foundSegment.start.dy) > 0.001 ||
243
- Math.abs(foundSegment.end.dx) > 0.001 ||
244
- Math.abs(foundSegment.end.dy) > 0.001;
245
- if (hasCurve) {
246
- const cp1x = v0.x + foundSegment.start.dx;
247
- const cp1y = v0.y + foundSegment.start.dy;
248
- const cp2x = v1.x + foundSegment.end.dx;
249
- const cp2y = v1.y + foundSegment.end.dy;
250
- commands.push({ cmd: 4, values: [cp1x, cp1y, cp2x, cp2y, v1.x, v1.y] });
251
- }
252
- else {
253
- commands.push({ cmd: 2, values: [v1.x, v1.y] });
254
- }
255
- currentVertex = foundSegment.end.vertex;
256
- }
257
- // Close the path if it ends where it started
258
- if (commands.length > 1) {
259
- const firstCmd = commands[0];
260
- const lastCmd = commands[commands.length - 1];
261
- if (firstCmd && lastCmd) {
262
- const startX = firstCmd.values[0];
263
- const startY = firstCmd.values[1];
264
- const lastVals = lastCmd.values;
265
- const endX = lastVals[lastVals.length - 2];
266
- const endY = lastVals[lastVals.length - 1];
267
- if (Math.abs((startX ?? 0) - (endX ?? 0)) < 0.01 &&
268
- Math.abs((startY ?? 0) - (endY ?? 0)) < 0.01) {
269
- commands.push({ cmd: 0, values: [] });
270
- }
271
- }
272
- }
273
- return commands.length > 0 ? commands : null;
274
- }
275
- // ============================================================================
276
- // Vector Type Detection
277
- // ============================================================================
278
- /**
279
- * Check if a vector node is stroked (has stroke paint, no fill paint).
280
- */
281
- export function isStrokedVector(node) {
282
- const fills = getPaints(node, "fills");
283
- const strokes = getPaints(node, "strokes");
284
- const hasVisibleFill = fills?.some((p) => p.visible !== false && p.type === "SOLID");
285
- const hasVisibleStroke = strokes?.some((p) => p.visible !== false && p.type === "SOLID");
286
- return !hasVisibleFill && hasVisibleStroke === true;
287
- }
288
- // ============================================================================
289
- // Stroked Vector Rendering
290
- // ============================================================================
291
- /**
292
- * Render a stroked vector using its centerline.
293
- */
294
- export function renderStrokedVector(node, transform, blobs, ctx, output) {
295
- const strokes = getPaints(node, "strokes");
296
- const strokeColor = paintToColor(getVisiblePaint(strokes));
297
- if (!strokeColor)
298
- return false;
299
- const vectorData = node.vectorData;
300
- const normalizedSize = vectorData?.normalizedSize;
301
- // Get centerline commands using priority-based approach
302
- let centerline = null;
303
- // PRIORITY 1: Use structured vectorNetwork data (most reliable)
304
- const structuredNetwork = parseStructuredVectorNetwork(vectorData);
305
- if (structuredNetwork && structuredNetwork.vertices.length >= 2) {
306
- centerline = createCenterlineFromNetwork(structuredNetwork, normalizedSize);
307
- }
308
- // PRIORITY 2: Try blob-encoded vector network
309
- if (!centerline && vectorData?.vectorNetworkBlob !== undefined) {
310
- const blobNetwork = decodeVectorNetworkBlob(vectorData.vectorNetworkBlob, blobs, ctx);
311
- if (blobNetwork && blobNetwork.vertices.length >= 2) {
312
- centerline = createCenterlineFromNetwork(blobNetwork, normalizedSize);
313
- }
314
- }
315
- // PRIORITY 3: Fallback to simple line from normalizedSize
316
- if (!centerline && normalizedSize && (normalizedSize.x > 0 || normalizedSize.y > 0)) {
317
- centerline = createCenterlineFromNormalizedSize(normalizedSize);
318
- }
319
- if (!centerline || centerline.length === 0)
320
- return false;
321
- // Get target size from node
322
- const targetWidth = node.size?.x ?? node.width ?? normalizedSize?.x ?? 1;
323
- const targetHeight = node.size?.y ?? node.height ?? normalizedSize?.y ?? 1;
324
- // Compute actual bounds and calculate scale
325
- const commandBounds = computeCommandBounds(centerline);
326
- const baseScaleX = normalizedSize?.x ? targetWidth / normalizedSize.x : 1;
327
- const baseScaleY = normalizedSize?.y ? targetHeight / normalizedSize.y : 1;
328
- const cmdWidth = commandBounds ? commandBounds.maxX - commandBounds.minX : 0;
329
- const cmdHeight = commandBounds ? commandBounds.maxY - commandBounds.minY : 0;
330
- const scaleX = cmdWidth > 0.001 ? targetWidth / cmdWidth : baseScaleX;
331
- const scaleY = cmdHeight > 0.001 ? targetHeight / cmdHeight : baseScaleY;
332
- const offsetX = commandBounds ? -commandBounds.minX : 0;
333
- const offsetY = commandBounds ? -commandBounds.minY : 0;
334
- // Build transform: offset -> scale -> parent transform
335
- const localTransform = {
336
- a: scaleX,
337
- b: 0,
338
- c: 0,
339
- d: scaleY,
340
- e: offsetX * scaleX,
341
- f: offsetY * scaleY,
342
- };
343
- const finalTransform = multiplyTransforms(transform, localTransform);
344
- const pathD = buildSvgPath(centerline, finalTransform);
345
- if (!pathD)
346
- return false;
347
- // Build stroke attributes
348
- const strokeWeight = node.strokeWeight ?? 1;
349
- const attrs = [
350
- `d="${pathD}"`,
351
- `fill="none"`,
352
- `stroke="${strokeColor}"`,
353
- `stroke-width="${strokeWeight}"`,
354
- ];
355
- if (node.strokeCap)
356
- attrs.push(`stroke-linecap="${node.strokeCap.toLowerCase()}"`);
357
- if (node.strokeJoin)
358
- attrs.push(`stroke-linejoin="${node.strokeJoin.toLowerCase()}"`);
359
- if (node.strokeDashes?.length)
360
- attrs.push(`stroke-dasharray="${node.strokeDashes.join(" ")}"`);
361
- if (node.opacity !== undefined && node.opacity < 1)
362
- attrs.push(`opacity="${node.opacity}"`);
363
- output.push(`<path ${attrs.join(" ")} />`);
364
- return true;
365
- }
366
- // ============================================================================
367
- // Filled Vector Rendering
368
- // ============================================================================
369
- /**
370
- * Render a filled vector using its fillGeometry.
371
- */
372
- export function renderFilledVector(node, transform, blobs, ctx, output) {
373
- const fills = getPaints(node, "fills");
374
- const fillColor = paintToColor(getVisiblePaint(fills));
375
- if (!fillColor)
376
- return false;
377
- const fillGeometry = node.fillGeometry;
378
- if (!fillGeometry?.length)
379
- return false;
380
- const vectorData = node.vectorData;
381
- const normalizedSize = vectorData?.normalizedSize;
382
- const targetWidth = node.size?.x ?? node.width ?? normalizedSize?.x ?? 1;
383
- const targetHeight = node.size?.y ?? node.height ?? normalizedSize?.y ?? 1;
384
- const baseScaleX = normalizedSize?.x ? targetWidth / normalizedSize.x : 1;
385
- const baseScaleY = normalizedSize?.y ? targetHeight / normalizedSize.y : 1;
386
- for (const path of fillGeometry) {
387
- let commands = null;
388
- if (typeof path.commandsBlob === "number") {
389
- commands = decodePathCommands(path.commandsBlob, blobs, ctx);
390
- }
391
- else if (path.commands) {
392
- commands = decodePathCommandsFromArray(path.commands);
393
- }
394
- if (!commands)
395
- continue;
396
- const commandBounds = computeCommandBounds(commands);
397
- const cmdWidth = commandBounds ? commandBounds.maxX - commandBounds.minX : 0;
398
- const cmdHeight = commandBounds ? commandBounds.maxY - commandBounds.minY : 0;
399
- const scaleX = cmdWidth > 0.001 ? targetWidth / cmdWidth : baseScaleX;
400
- const scaleY = cmdHeight > 0.001 ? targetHeight / cmdHeight : baseScaleY;
401
- const offsetX = commandBounds ? -commandBounds.minX : 0;
402
- const offsetY = commandBounds ? -commandBounds.minY : 0;
403
- const localTransform = {
404
- a: scaleX,
405
- b: 0,
406
- c: 0,
407
- d: scaleY,
408
- e: offsetX * scaleX,
409
- f: offsetY * scaleY,
410
- };
411
- const finalTransform = multiplyTransforms(transform, localTransform);
412
- const pathD = buildSvgPath(commands, finalTransform);
413
- if (!pathD)
414
- continue;
415
- const windingRule = path.windingRule?.toLowerCase() === "evenodd" ? "evenodd" : "nonzero";
416
- const attrs = [
417
- `d="${pathD}"`,
418
- `fill="${fillColor}"`,
419
- `fill-rule="${windingRule}"`,
420
- ];
421
- if (node.opacity !== undefined && node.opacity < 1)
422
- attrs.push(`opacity="${node.opacity}"`);
423
- output.push(`<path ${attrs.join(" ")} />`);
424
- }
425
- return true;
426
- }
427
- //# sourceMappingURL=vector-renderer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vector-renderer.js","sourceRoot":"","sources":["../../src/experimental/vector-renderer.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Test the v2 renderer on specific nodes
3
- */
4
- export {};
5
- //# sourceMappingURL=test-render-v2.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-render-v2.d.ts","sourceRoot":"","sources":["../src/test-render-v2.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,76 +0,0 @@
1
- /**
2
- * Test the v2 renderer on specific nodes
3
- */
4
- import { readFigFile } from "./parser/index.js";
5
- import { parseCanvasFig, formatGUID, extractDocumentTree } from "./parser/kiwi-parser.js";
6
- import { renderScreenV2 } from "./experimental/render-screen-v2.js";
7
- import { writeFileSync, mkdirSync } from "fs";
8
- const FILE_PATH = "/Users/billy/Downloads/AutoDevice (Copy).fig";
9
- const TEST_NODES = [
10
- "457:1694", // Frame with 3 vector lines
11
- "457:1681", // Logo with rotated vectors
12
- "457:1695", // Simple horizontal line
13
- ];
14
- async function testRenderer() {
15
- console.log("Reading .fig file...");
16
- const archive = await readFigFile(FILE_PATH);
17
- console.log("Parsing canvas.fig...");
18
- const parsed = parseCanvasFig(archive.canvasFig);
19
- const nodeChanges = parsed.message["nodeChanges"];
20
- const blobs = parsed.message["blobs"];
21
- console.log("Building document tree...");
22
- const doc = extractDocumentTree(parsed.message);
23
- if (!doc) {
24
- console.log("Failed to extract document tree!");
25
- return;
26
- }
27
- // Build node index
28
- const nodeIndex = new Map();
29
- function indexNode(node) {
30
- const key = formatGUID(node.guid);
31
- nodeIndex.set(key, node);
32
- if (node.children) {
33
- for (const child of node.children) {
34
- indexNode(child);
35
- }
36
- }
37
- }
38
- indexNode(doc);
39
- console.log(`Indexed ${nodeIndex.size} nodes\n`);
40
- // Create output directory
41
- mkdirSync("output", { recursive: true });
42
- // Test each node
43
- for (const nodeId of TEST_NODES) {
44
- console.log("=".repeat(60));
45
- console.log(`Testing node: ${nodeId}`);
46
- console.log("=".repeat(60));
47
- const node = nodeIndex.get(nodeId);
48
- if (!node) {
49
- console.log("Node not found in tree!\n");
50
- continue;
51
- }
52
- console.log(`Type: ${node.type}, Name: ${node.name}`);
53
- const result = renderScreenV2(node, undefined, blobs, {
54
- includeFills: true,
55
- includeStrokes: true,
56
- includeText: true,
57
- background: "#1a1a1a",
58
- });
59
- console.log(`Result: ${result.width}x${result.height}`);
60
- if (result.warnings.length > 0) {
61
- console.log(`Warnings: ${result.warnings.join(", ")}`);
62
- }
63
- // Save SVG
64
- const filename = `output/v2-${nodeId.replace(":", "-")}.svg`;
65
- writeFileSync(filename, result.svg);
66
- console.log(`Saved: ${filename}`);
67
- // Show first 500 chars of SVG for inspection
68
- console.log(`\nSVG preview (first 1000 chars):`);
69
- console.log(result.svg.slice(0, 1000));
70
- if (result.svg.length > 1000)
71
- console.log("...");
72
- console.log("\n");
73
- }
74
- }
75
- testRenderer().catch(console.error);
76
- //# sourceMappingURL=test-render-v2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-render-v2.js","sourceRoot":"","sources":["../src/test-render-v2.ts"],"names":[],"mappings":"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"}