@llc3233149/core 0.9.0

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 (457) hide show
  1. package/dist/canvaskit.d.ts +9 -0
  2. package/dist/canvaskit.d.ts.map +1 -0
  3. package/dist/canvaskit.js +55 -0
  4. package/dist/canvaskit.js.map +1 -0
  5. package/dist/clipboard.d.ts +32 -0
  6. package/dist/clipboard.d.ts.map +1 -0
  7. package/dist/clipboard.js +345 -0
  8. package/dist/clipboard.js.map +1 -0
  9. package/dist/color.d.ts +28 -0
  10. package/dist/color.d.ts.map +1 -0
  11. package/dist/color.js +67 -0
  12. package/dist/color.js.map +1 -0
  13. package/dist/constants.d.ts +159 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +224 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/copy.d.ts +20 -0
  18. package/dist/copy.d.ts.map +1 -0
  19. package/dist/copy.js +64 -0
  20. package/dist/copy.js.map +1 -0
  21. package/dist/fig-export-worker.d.ts +2 -0
  22. package/dist/fig-export-worker.d.ts.map +1 -0
  23. package/dist/fig-export-worker.js +17 -0
  24. package/dist/fig-export-worker.js.map +1 -0
  25. package/dist/fig-export.d.ts +13 -0
  26. package/dist/fig-export.d.ts.map +1 -0
  27. package/dist/fig-export.js +243 -0
  28. package/dist/fig-export.js.map +1 -0
  29. package/dist/figma-api.d.ts +268 -0
  30. package/dist/figma-api.d.ts.map +1 -0
  31. package/dist/figma-api.js +1074 -0
  32. package/dist/figma-api.js.map +1 -0
  33. package/dist/figma-rest-import.d.ts +122 -0
  34. package/dist/figma-rest-import.d.ts.map +1 -0
  35. package/dist/figma-rest-import.js +319 -0
  36. package/dist/figma-rest-import.js.map +1 -0
  37. package/dist/fonts.d.ts +24 -0
  38. package/dist/fonts.d.ts.map +1 -0
  39. package/dist/fonts.js +356 -0
  40. package/dist/fonts.js.map +1 -0
  41. package/dist/geometry.d.ts +14 -0
  42. package/dist/geometry.d.ts.map +1 -0
  43. package/dist/geometry.js +47 -0
  44. package/dist/geometry.js.map +1 -0
  45. package/dist/index.d.ts +38 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +32 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/kiwi/codec.d.ts +292 -0
  50. package/dist/kiwi/codec.d.ts.map +1 -0
  51. package/dist/kiwi/codec.js +340 -0
  52. package/dist/kiwi/codec.js.map +1 -0
  53. package/dist/kiwi/fig-file.d.ts +4 -0
  54. package/dist/kiwi/fig-file.d.ts.map +1 -0
  55. package/dist/kiwi/fig-file.js +236 -0
  56. package/dist/kiwi/fig-file.js.map +1 -0
  57. package/dist/kiwi/fig-import.d.ts +4 -0
  58. package/dist/kiwi/fig-import.d.ts.map +1 -0
  59. package/dist/kiwi/fig-import.js +248 -0
  60. package/dist/kiwi/fig-import.js.map +1 -0
  61. package/dist/kiwi/fig-parse-worker.d.ts +7 -0
  62. package/dist/kiwi/fig-parse-worker.d.ts.map +1 -0
  63. package/dist/kiwi/fig-parse-worker.js +184 -0
  64. package/dist/kiwi/fig-parse-worker.js.map +1 -0
  65. package/dist/kiwi/instance-overrides.d.ts +66 -0
  66. package/dist/kiwi/instance-overrides.d.ts.map +1 -0
  67. package/dist/kiwi/instance-overrides.js +644 -0
  68. package/dist/kiwi/instance-overrides.js.map +1 -0
  69. package/dist/kiwi/kiwi-convert.d.ts +19 -0
  70. package/dist/kiwi/kiwi-convert.d.ts.map +1 -0
  71. package/dist/kiwi/kiwi-convert.js +678 -0
  72. package/dist/kiwi/kiwi-convert.js.map +1 -0
  73. package/dist/kiwi/kiwi-schema/bb.d.ts +25 -0
  74. package/dist/kiwi/kiwi-schema/bb.d.ts.map +1 -0
  75. package/dist/kiwi/kiwi-schema/bb.js +225 -0
  76. package/dist/kiwi/kiwi-schema/bb.js.map +1 -0
  77. package/dist/kiwi/kiwi-schema/binary.d.ts +5 -0
  78. package/dist/kiwi/kiwi-schema/binary.d.ts.map +1 -0
  79. package/dist/kiwi/kiwi-schema/binary.js +86 -0
  80. package/dist/kiwi/kiwi-schema/binary.js.map +1 -0
  81. package/dist/kiwi/kiwi-schema/index.d.ts +6 -0
  82. package/dist/kiwi/kiwi-schema/index.d.ts.map +1 -0
  83. package/dist/kiwi/kiwi-schema/index.js +5 -0
  84. package/dist/kiwi/kiwi-schema/index.js.map +1 -0
  85. package/dist/kiwi/kiwi-schema/js.d.ts +4 -0
  86. package/dist/kiwi/kiwi-schema/js.d.ts.map +1 -0
  87. package/dist/kiwi/kiwi-schema/js.js +282 -0
  88. package/dist/kiwi/kiwi-schema/js.js.map +1 -0
  89. package/dist/kiwi/kiwi-schema/parser.d.ts +5 -0
  90. package/dist/kiwi/kiwi-schema/parser.d.ts.map +1 -0
  91. package/dist/kiwi/kiwi-schema/parser.js +228 -0
  92. package/dist/kiwi/kiwi-schema/parser.js.map +1 -0
  93. package/dist/kiwi/kiwi-schema/schema.d.ts +22 -0
  94. package/dist/kiwi/kiwi-schema/schema.d.ts.map +1 -0
  95. package/dist/kiwi/kiwi-schema/schema.js +2 -0
  96. package/dist/kiwi/kiwi-schema/schema.js.map +1 -0
  97. package/dist/kiwi/kiwi-schema/util.d.ts +3 -0
  98. package/dist/kiwi/kiwi-schema/util.d.ts.map +1 -0
  99. package/dist/kiwi/kiwi-schema/util.js +10 -0
  100. package/dist/kiwi/kiwi-schema/util.js.map +1 -0
  101. package/dist/kiwi/protocol.d.ts +172 -0
  102. package/dist/kiwi/protocol.d.ts.map +1 -0
  103. package/dist/kiwi/protocol.js +214 -0
  104. package/dist/kiwi/protocol.js.map +1 -0
  105. package/dist/kiwi/schema.d.ts +3 -0
  106. package/dist/kiwi/schema.d.ts.map +1 -0
  107. package/dist/kiwi/schema.js +2285 -0
  108. package/dist/kiwi/schema.js.map +1 -0
  109. package/dist/kiwi-serialize.d.ts +17 -0
  110. package/dist/kiwi-serialize.d.ts.map +1 -0
  111. package/dist/kiwi-serialize.js +419 -0
  112. package/dist/kiwi-serialize.js.map +1 -0
  113. package/dist/layout.d.ts +9 -0
  114. package/dist/layout.d.ts.map +1 -0
  115. package/dist/layout.js +533 -0
  116. package/dist/layout.js.map +1 -0
  117. package/dist/profiler/draw-call-counter.d.ts +9 -0
  118. package/dist/profiler/draw-call-counter.d.ts.map +1 -0
  119. package/dist/profiler/draw-call-counter.js +37 -0
  120. package/dist/profiler/draw-call-counter.js.map +1 -0
  121. package/dist/profiler/frame-capture.d.ts +34 -0
  122. package/dist/profiler/frame-capture.d.ts.map +1 -0
  123. package/dist/profiler/frame-capture.js +90 -0
  124. package/dist/profiler/frame-capture.js.map +1 -0
  125. package/dist/profiler/frame-stats.d.ts +33 -0
  126. package/dist/profiler/frame-stats.d.ts.map +1 -0
  127. package/dist/profiler/frame-stats.js +103 -0
  128. package/dist/profiler/frame-stats.js.map +1 -0
  129. package/dist/profiler/gpu-timer.d.ts +15 -0
  130. package/dist/profiler/gpu-timer.d.ts.map +1 -0
  131. package/dist/profiler/gpu-timer.js +77 -0
  132. package/dist/profiler/gpu-timer.js.map +1 -0
  133. package/dist/profiler/hud-renderer.d.ts +22 -0
  134. package/dist/profiler/hud-renderer.d.ts.map +1 -0
  135. package/dist/profiler/hud-renderer.js +200 -0
  136. package/dist/profiler/hud-renderer.js.map +1 -0
  137. package/dist/profiler/index.d.ts +9 -0
  138. package/dist/profiler/index.d.ts.map +1 -0
  139. package/dist/profiler/index.js +8 -0
  140. package/dist/profiler/index.js.map +1 -0
  141. package/dist/profiler/phase-timer.d.ts +9 -0
  142. package/dist/profiler/phase-timer.d.ts.map +1 -0
  143. package/dist/profiler/phase-timer.js +51 -0
  144. package/dist/profiler/phase-timer.js.map +1 -0
  145. package/dist/profiler/render-profiler.d.ts +41 -0
  146. package/dist/profiler/render-profiler.d.ts.map +1 -0
  147. package/dist/profiler/render-profiler.js +142 -0
  148. package/dist/profiler/render-profiler.js.map +1 -0
  149. package/dist/render/components.d.ts +25 -0
  150. package/dist/render/components.d.ts.map +1 -0
  151. package/dist/render/components.js +55 -0
  152. package/dist/render/components.js.map +1 -0
  153. package/dist/render/emoji-icons.d.ts +5 -0
  154. package/dist/render/emoji-icons.d.ts.map +1 -0
  155. package/dist/render/emoji-icons.js +55 -0
  156. package/dist/render/emoji-icons.js.map +1 -0
  157. package/dist/render/export-code.d.ts +9 -0
  158. package/dist/render/export-code.d.ts.map +1 -0
  159. package/dist/render/export-code.js +335 -0
  160. package/dist/render/export-code.js.map +1 -0
  161. package/dist/render/export-jsx.d.ts +5 -0
  162. package/dist/render/export-jsx.d.ts.map +1 -0
  163. package/dist/render/export-jsx.js +621 -0
  164. package/dist/render/export-jsx.js.map +1 -0
  165. package/dist/render/index.d.ts +8 -0
  166. package/dist/render/index.d.ts.map +1 -0
  167. package/dist/render/index.js +8 -0
  168. package/dist/render/index.js.map +1 -0
  169. package/dist/render/jsx-runtime.d.ts +31 -0
  170. package/dist/render/jsx-runtime.d.ts.map +1 -0
  171. package/dist/render/jsx-runtime.js +13 -0
  172. package/dist/render/jsx-runtime.js.map +1 -0
  173. package/dist/render/mini-react.d.ts +14 -0
  174. package/dist/render/mini-react.d.ts.map +1 -0
  175. package/dist/render/mini-react.js +16 -0
  176. package/dist/render/mini-react.js.map +1 -0
  177. package/dist/render/render-jsx.d.ts +24 -0
  178. package/dist/render/render-jsx.d.ts.map +1 -0
  179. package/dist/render/render-jsx.js +51 -0
  180. package/dist/render/render-jsx.js.map +1 -0
  181. package/dist/render/renderer.d.ts +16 -0
  182. package/dist/render/renderer.d.ts.map +1 -0
  183. package/dist/render/renderer.js +437 -0
  184. package/dist/render/renderer.js.map +1 -0
  185. package/dist/render/tailwind.d.ts +20 -0
  186. package/dist/render/tailwind.d.ts.map +1 -0
  187. package/dist/render/tailwind.js +115 -0
  188. package/dist/render/tailwind.js.map +1 -0
  189. package/dist/render/tree.d.ts +72 -0
  190. package/dist/render/tree.d.ts.map +1 -0
  191. package/dist/render/tree.js +63 -0
  192. package/dist/render/tree.js.map +1 -0
  193. package/dist/render-image.d.ts +19 -0
  194. package/dist/render-image.d.ts.map +1 -0
  195. package/dist/render-image.js +84 -0
  196. package/dist/render-image.js.map +1 -0
  197. package/dist/renderer/effects.d.ts +9 -0
  198. package/dist/renderer/effects.d.ts.map +1 -0
  199. package/dist/renderer/effects.js +44 -0
  200. package/dist/renderer/effects.js.map +1 -0
  201. package/dist/renderer/fills.d.ts +9 -0
  202. package/dist/renderer/fills.d.ts.map +1 -0
  203. package/dist/renderer/fills.js +189 -0
  204. package/dist/renderer/fills.js.map +1 -0
  205. package/dist/renderer/index.d.ts +2 -0
  206. package/dist/renderer/index.d.ts.map +1 -0
  207. package/dist/renderer/index.js +2 -0
  208. package/dist/renderer/index.js.map +1 -0
  209. package/dist/renderer/label-cache.d.ts +43 -0
  210. package/dist/renderer/label-cache.d.ts.map +1 -0
  211. package/dist/renderer/label-cache.js +85 -0
  212. package/dist/renderer/label-cache.js.map +1 -0
  213. package/dist/renderer/labels.d.ts +6 -0
  214. package/dist/renderer/labels.d.ts.map +1 -0
  215. package/dist/renderer/labels.js +126 -0
  216. package/dist/renderer/labels.js.map +1 -0
  217. package/dist/renderer/lru-cache.d.ts +20 -0
  218. package/dist/renderer/lru-cache.d.ts.map +1 -0
  219. package/dist/renderer/lru-cache.js +65 -0
  220. package/dist/renderer/lru-cache.js.map +1 -0
  221. package/dist/renderer/overlays.d.ts +25 -0
  222. package/dist/renderer/overlays.d.ts.map +1 -0
  223. package/dist/renderer/overlays.js +783 -0
  224. package/dist/renderer/overlays.js.map +1 -0
  225. package/dist/renderer/renderer.d.ts +229 -0
  226. package/dist/renderer/renderer.d.ts.map +1 -0
  227. package/dist/renderer/renderer.js +909 -0
  228. package/dist/renderer/renderer.js.map +1 -0
  229. package/dist/renderer/rulers.d.ts +8 -0
  230. package/dist/renderer/rulers.d.ts.map +1 -0
  231. package/dist/renderer/rulers.js +147 -0
  232. package/dist/renderer/rulers.js.map +1 -0
  233. package/dist/renderer/scene.d.ts +11 -0
  234. package/dist/renderer/scene.d.ts.map +1 -0
  235. package/dist/renderer/scene.js +392 -0
  236. package/dist/renderer/scene.js.map +1 -0
  237. package/dist/renderer/shapes.d.ts +13 -0
  238. package/dist/renderer/shapes.d.ts.map +1 -0
  239. package/dist/renderer/shapes.js +160 -0
  240. package/dist/renderer/shapes.js.map +1 -0
  241. package/dist/renderer/strokes.d.ts +9 -0
  242. package/dist/renderer/strokes.d.ts.map +1 -0
  243. package/dist/renderer/strokes.js +180 -0
  244. package/dist/renderer/strokes.js.map +1 -0
  245. package/dist/rpc/commands.d.ts +202 -0
  246. package/dist/rpc/commands.d.ts.map +1 -0
  247. package/dist/rpc/commands.js +429 -0
  248. package/dist/rpc/commands.js.map +1 -0
  249. package/dist/rpc/index.d.ts +3 -0
  250. package/dist/rpc/index.d.ts.map +1 -0
  251. package/dist/rpc/index.js +2 -0
  252. package/dist/rpc/index.js.map +1 -0
  253. package/dist/scene-graph.d.ts +318 -0
  254. package/dist/scene-graph.d.ts.map +1 -0
  255. package/dist/scene-graph.js +803 -0
  256. package/dist/scene-graph.js.map +1 -0
  257. package/dist/snap.d.ts +16 -0
  258. package/dist/snap.d.ts.map +1 -0
  259. package/dist/snap.js +97 -0
  260. package/dist/snap.js.map +1 -0
  261. package/dist/style-runs.d.ts +20 -0
  262. package/dist/style-runs.d.ts.map +1 -0
  263. package/dist/style-runs.js +168 -0
  264. package/dist/style-runs.js.map +1 -0
  265. package/dist/svg-export/defs.d.ts +19 -0
  266. package/dist/svg-export/defs.d.ts.map +1 -0
  267. package/dist/svg-export/defs.js +191 -0
  268. package/dist/svg-export/defs.js.map +1 -0
  269. package/dist/svg-export/index.d.ts +8 -0
  270. package/dist/svg-export/index.d.ts.map +1 -0
  271. package/dist/svg-export/index.js +318 -0
  272. package/dist/svg-export/index.js.map +1 -0
  273. package/dist/svg-export/paths.d.ts +9 -0
  274. package/dist/svg-export/paths.d.ts.map +1 -0
  275. package/dist/svg-export/paths.js +189 -0
  276. package/dist/svg-export/paths.js.map +1 -0
  277. package/dist/svg-node.d.ts +8 -0
  278. package/dist/svg-node.d.ts.map +1 -0
  279. package/dist/svg-node.js +48 -0
  280. package/dist/svg-node.js.map +1 -0
  281. package/dist/text-editor.d.ts +57 -0
  282. package/dist/text-editor.d.ts.map +1 -0
  283. package/dist/text-editor.js +337 -0
  284. package/dist/text-editor.js.map +1 -0
  285. package/dist/tools/ai-adapter.d.ts +22 -0
  286. package/dist/tools/ai-adapter.d.ts.map +1 -0
  287. package/dist/tools/ai-adapter.js +121 -0
  288. package/dist/tools/ai-adapter.js.map +1 -0
  289. package/dist/tools/analyze.d.ts +22 -0
  290. package/dist/tools/analyze.d.ts.map +1 -0
  291. package/dist/tools/analyze.js +677 -0
  292. package/dist/tools/analyze.js.map +1 -0
  293. package/dist/tools/create.d.ts +8 -0
  294. package/dist/tools/create.d.ts.map +1 -0
  295. package/dist/tools/create.js +204 -0
  296. package/dist/tools/create.js.map +1 -0
  297. package/dist/tools/describe.d.ts +9 -0
  298. package/dist/tools/describe.d.ts.map +1 -0
  299. package/dist/tools/describe.js +295 -0
  300. package/dist/tools/describe.js.map +1 -0
  301. package/dist/tools/export-code.d.ts +2 -0
  302. package/dist/tools/export-code.d.ts.map +1 -0
  303. package/dist/tools/export-code.js +34 -0
  304. package/dist/tools/export-code.js.map +1 -0
  305. package/dist/tools/export-tailwind-config.d.ts +27 -0
  306. package/dist/tools/export-tailwind-config.d.ts.map +1 -0
  307. package/dist/tools/export-tailwind-config.js +215 -0
  308. package/dist/tools/export-tailwind-config.js.map +1 -0
  309. package/dist/tools/icons.d.ts +5 -0
  310. package/dist/tools/icons.d.ts.map +1 -0
  311. package/dist/tools/icons.js +192 -0
  312. package/dist/tools/icons.js.map +1 -0
  313. package/dist/tools/index.d.ts +7 -0
  314. package/dist/tools/index.d.ts.map +1 -0
  315. package/dist/tools/index.js +6 -0
  316. package/dist/tools/index.js.map +1 -0
  317. package/dist/tools/modify.d.ts +22 -0
  318. package/dist/tools/modify.d.ts.map +1 -0
  319. package/dist/tools/modify.js +653 -0
  320. package/dist/tools/modify.js.map +1 -0
  321. package/dist/tools/patterns.d.ts +2 -0
  322. package/dist/tools/patterns.d.ts.map +1 -0
  323. package/dist/tools/patterns.js +173 -0
  324. package/dist/tools/patterns.js.map +1 -0
  325. package/dist/tools/read.d.ts +17 -0
  326. package/dist/tools/read.d.ts.map +1 -0
  327. package/dist/tools/read.js +379 -0
  328. package/dist/tools/read.js.map +1 -0
  329. package/dist/tools/registry.d.ts +3 -0
  330. package/dist/tools/registry.d.ts.map +1 -0
  331. package/dist/tools/registry.js +124 -0
  332. package/dist/tools/registry.js.map +1 -0
  333. package/dist/tools/schema.d.ts +46 -0
  334. package/dist/tools/schema.d.ts.map +1 -0
  335. package/dist/tools/schema.js +17 -0
  336. package/dist/tools/schema.js.map +1 -0
  337. package/dist/tools/structure.d.ts +18 -0
  338. package/dist/tools/structure.d.ts.map +1 -0
  339. package/dist/tools/structure.js +345 -0
  340. package/dist/tools/structure.js.map +1 -0
  341. package/dist/tools/variables.d.ts +12 -0
  342. package/dist/tools/variables.d.ts.map +1 -0
  343. package/dist/tools/variables.js +190 -0
  344. package/dist/tools/variables.js.map +1 -0
  345. package/dist/tools/vector.d.ts +15 -0
  346. package/dist/tools/vector.d.ts.map +1 -0
  347. package/dist/tools/vector.js +312 -0
  348. package/dist/tools/vector.js.map +1 -0
  349. package/dist/types.d.ts +29 -0
  350. package/dist/types.d.ts.map +1 -0
  351. package/dist/types.js +2 -0
  352. package/dist/types.js.map +1 -0
  353. package/dist/undo.d.ts +33 -0
  354. package/dist/undo.d.ts.map +1 -0
  355. package/dist/undo.js +98 -0
  356. package/dist/undo.js.map +1 -0
  357. package/dist/vector.d.ts +14 -0
  358. package/dist/vector.d.ts.map +1 -0
  359. package/dist/vector.js +334 -0
  360. package/dist/vector.js.map +1 -0
  361. package/dist/xpath.d.ts +8 -0
  362. package/dist/xpath.d.ts.map +1 -0
  363. package/dist/xpath.js +199 -0
  364. package/dist/xpath.js.map +1 -0
  365. package/package.json +54 -0
  366. package/src/canvaskit.ts +66 -0
  367. package/src/clipboard.ts +444 -0
  368. package/src/color.ts +83 -0
  369. package/src/constants.ts +277 -0
  370. package/src/copy.ts +75 -0
  371. package/src/fig-export-worker.ts +28 -0
  372. package/src/fig-export.ts +321 -0
  373. package/src/figma-api.ts +1297 -0
  374. package/src/figma-rest-import.ts +443 -0
  375. package/src/fonts.ts +369 -0
  376. package/src/geometry.ts +73 -0
  377. package/src/global.d.ts +20 -0
  378. package/src/index.ts +247 -0
  379. package/src/kiwi/codec.ts +614 -0
  380. package/src/kiwi/fig-file.ts +248 -0
  381. package/src/kiwi/fig-import.ts +300 -0
  382. package/src/kiwi/fig-parse-worker.ts +213 -0
  383. package/src/kiwi/instance-overrides.ts +682 -0
  384. package/src/kiwi/kiwi-convert.ts +771 -0
  385. package/src/kiwi/kiwi-schema/bb.ts +244 -0
  386. package/src/kiwi/kiwi-schema/binary.ts +102 -0
  387. package/src/kiwi/kiwi-schema/index.ts +5 -0
  388. package/src/kiwi/kiwi-schema/js.ts +339 -0
  389. package/src/kiwi/kiwi-schema/parser.ts +287 -0
  390. package/src/kiwi/kiwi-schema/schema.ts +24 -0
  391. package/src/kiwi/kiwi-schema/util.ts +10 -0
  392. package/src/kiwi/protocol.ts +237 -0
  393. package/src/kiwi/schema.ts +2286 -0
  394. package/src/kiwi-serialize.ts +467 -0
  395. package/src/layout.ts +608 -0
  396. package/src/profiler/draw-call-counter.ts +43 -0
  397. package/src/profiler/frame-capture.ts +139 -0
  398. package/src/profiler/frame-stats.ts +122 -0
  399. package/src/profiler/gpu-timer.ts +93 -0
  400. package/src/profiler/hud-renderer.ts +242 -0
  401. package/src/profiler/index.ts +8 -0
  402. package/src/profiler/phase-timer.ts +62 -0
  403. package/src/profiler/render-profiler.ts +163 -0
  404. package/src/render/components.ts +69 -0
  405. package/src/render/emoji-icons.ts +60 -0
  406. package/src/render/export-code.ts +366 -0
  407. package/src/render/export-jsx.ts +633 -0
  408. package/src/render/index.ts +38 -0
  409. package/src/render/jsx-runtime.ts +36 -0
  410. package/src/render/mini-react.ts +30 -0
  411. package/src/render/render-jsx.ts +74 -0
  412. package/src/render/renderer.ts +508 -0
  413. package/src/render/tailwind.ts +114 -0
  414. package/src/render/tree.ts +137 -0
  415. package/src/render-image.ts +139 -0
  416. package/src/renderer/effects.ts +64 -0
  417. package/src/renderer/fills.ts +248 -0
  418. package/src/renderer/index.ts +1 -0
  419. package/src/renderer/label-cache.ts +114 -0
  420. package/src/renderer/labels.ts +168 -0
  421. package/src/renderer/lru-cache.ts +71 -0
  422. package/src/renderer/overlays.ts +1089 -0
  423. package/src/renderer/renderer.ts +1226 -0
  424. package/src/renderer/rulers.ts +230 -0
  425. package/src/renderer/scene.ts +554 -0
  426. package/src/renderer/shapes.ts +193 -0
  427. package/src/renderer/strokes.ts +221 -0
  428. package/src/rpc/commands.ts +667 -0
  429. package/src/rpc/index.ts +25 -0
  430. package/src/scene-graph.ts +1254 -0
  431. package/src/snap.ts +122 -0
  432. package/src/style-runs.ts +234 -0
  433. package/src/svg-export/defs.ts +255 -0
  434. package/src/svg-export/index.ts +427 -0
  435. package/src/svg-export/paths.ts +212 -0
  436. package/src/svg-node.ts +62 -0
  437. package/src/text-editor.ts +349 -0
  438. package/src/tools/ai-adapter.ts +144 -0
  439. package/src/tools/analyze.ts +786 -0
  440. package/src/tools/create.ts +206 -0
  441. package/src/tools/describe.ts +280 -0
  442. package/src/tools/export-code.ts +41 -0
  443. package/src/tools/export-tailwind-config.ts +266 -0
  444. package/src/tools/icons.ts +213 -0
  445. package/src/tools/index.ts +6 -0
  446. package/src/tools/modify.ts +651 -0
  447. package/src/tools/patterns.ts +189 -0
  448. package/src/tools/read.ts +401 -0
  449. package/src/tools/registry.ts +155 -0
  450. package/src/tools/schema.ts +65 -0
  451. package/src/tools/structure.ts +348 -0
  452. package/src/tools/variables.ts +193 -0
  453. package/src/tools/vector.ts +311 -0
  454. package/src/types.ts +32 -0
  455. package/src/undo.ts +126 -0
  456. package/src/vector.ts +413 -0
  457. package/src/xpath.ts +259 -0
@@ -0,0 +1,1226 @@
1
+ import {
2
+ SELECTION_COLOR,
3
+ COMPONENT_COLOR,
4
+ SNAP_COLOR,
5
+ CANVAS_BG_COLOR,
6
+ PEN_PATH_STROKE_WIDTH,
7
+ PARENT_OUTLINE_ALPHA,
8
+ PARENT_OUTLINE_DASH,
9
+ DEFAULT_FONT_SIZE,
10
+ LABEL_FONT_SIZE,
11
+ LABEL_OFFSET_Y,
12
+ SIZE_FONT_SIZE,
13
+ SECTION_TITLE_FONT_SIZE,
14
+ SECTION_TITLE_HEIGHT,
15
+ SECTION_TITLE_PADDING_X,
16
+ SECTION_TITLE_GAP,
17
+ COMPONENT_SET_DASH,
18
+ COMPONENT_SET_DASH_GAP,
19
+ COMPONENT_SET_BORDER_WIDTH,
20
+ COMPONENT_LABEL_FONT_SIZE,
21
+ COMPONENT_LABEL_GAP,
22
+ COMPONENT_LABEL_ICON_SIZE,
23
+ COMPONENT_LABEL_ICON_GAP,
24
+ RULER_BG_COLOR,
25
+ RULER_TICK_COLOR,
26
+ RULER_TEXT_COLOR,
27
+ DEFAULT_FONT_FAMILY
28
+ } from '../constants'
29
+ import { isFontLoaded, getCJKFallbackFamily } from '../fonts'
30
+ import { RenderProfiler } from '../profiler'
31
+
32
+ import type { SceneNode, SceneGraph, Fill, Stroke } from '../scene-graph'
33
+ import type { SnapGuide } from '../snap'
34
+ import type { TextEditor } from '../text-editor'
35
+ import type { Color, Rect, Vector } from '../types'
36
+ import type {
37
+ Image as CKImage,
38
+ Path,
39
+ CanvasKit,
40
+ Surface,
41
+ Canvas,
42
+ Paint,
43
+ Font,
44
+ FontMgr,
45
+ FontWeight,
46
+ TypefaceFontProvider,
47
+ SkPicture,
48
+ ImageFilter,
49
+ MaskFilter,
50
+ Paragraph
51
+ } from 'canvaskit-wasm'
52
+
53
+ import {
54
+ drawHoverHighlight as drawHoverHighlightFn,
55
+ drawSelection as drawSelectionFn,
56
+ drawNodeSelection as drawNodeSelectionFn,
57
+ drawSelectionLabels as drawSelectionLabelsFn,
58
+ drawParentFrameOutlines as drawParentFrameOutlinesFn,
59
+ drawNodeOutline as drawNodeOutlineFn,
60
+ drawGroupBounds as drawGroupBoundsFn,
61
+ getRotatedCorners as getRotatedCornersFn,
62
+ drawHandle as drawHandleFn,
63
+ drawSnapGuides as drawSnapGuidesFn,
64
+ drawMarquee as drawMarqueeFn,
65
+ drawFlashes as drawFlashesFn,
66
+ drawLayoutInsertIndicator as drawLayoutInsertIndicatorFn,
67
+ drawTextEditOverlay as drawTextEditOverlayFn,
68
+ drawPenOverlay as drawPenOverlayFn,
69
+ drawRemoteCursors as drawRemoteCursorsFn,
70
+ drawMeasurements as drawMeasurementsFn,
71
+ drawPaddingOverlay as drawPaddingOverlayFn
72
+ } from './overlays'
73
+ import { drawRulers as drawRulersFn } from './rulers'
74
+ import {
75
+ drawSectionTitles as drawSectionTitlesFn,
76
+ drawComponentLabels as drawComponentLabelsFn
77
+ } from './labels'
78
+ import { LabelCache } from './label-cache'
79
+ import { LRUCache } from './lru-cache'
80
+ import {
81
+ renderNode as renderNodeFn,
82
+ renderSection as renderSectionFn,
83
+ renderComponentSet as renderComponentSetFn,
84
+ renderShape as renderShapeFn,
85
+ renderShapeUncached as renderShapeUncachedFn,
86
+ renderEffects as renderEffectsFn,
87
+ renderText as renderTextFn
88
+ } from './scene'
89
+ import {
90
+ drawNodeFill as drawNodeFillFn,
91
+ applyFill as applyFillFn,
92
+ applyGradientFill as applyGradientFillFn,
93
+ applyImageFill as applyImageFillFn,
94
+ drawArc as drawArcFn
95
+ } from './fills'
96
+ import {
97
+ drawNodeStroke as drawNodeStrokeFn,
98
+ drawStrokeWithAlign as drawStrokeWithAlignFn,
99
+ drawRRectStrokeWithAlign as drawRRectStrokeWithAlignFn,
100
+ drawIndividualSideStrokes as drawIndividualSideStrokesFn,
101
+ strokeNodeShape as strokeNodeShapeFn
102
+ } from './strokes'
103
+ import {
104
+ makeNodeShapePath as makeNodeShapePathFn,
105
+ makePolygonPath as makePolygonPathFn,
106
+ makeRRect as makeRRectFn,
107
+ makeRRectWithSpread as makeRRectWithSpreadFn,
108
+ makeRRectWithOffset as makeRRectWithOffsetFn,
109
+ clipNodeShape as clipNodeShapeFn,
110
+ getVectorPaths as getVectorPathsFn,
111
+ getFillGeometry as getFillGeometryFn,
112
+ getStrokeGeometry as getStrokeGeometryFn
113
+ } from './shapes'
114
+ import {
115
+ getCachedDropShadow as getCachedDropShadowFn,
116
+ getCachedBlur as getCachedBlurFn,
117
+ getCachedDecalBlur as getCachedDecalBlurFn,
118
+ getCachedMaskBlur as getCachedMaskBlurFn,
119
+ applyClippedBlur as applyClippedBlurFn
120
+ } from './effects'
121
+
122
+ export interface RenderOverlays {
123
+ hoveredNodeId?: string | null
124
+ editingTextId?: string | null
125
+ textEditor?: TextEditor | null
126
+ marquee?: Rect | null
127
+ snapGuides?: SnapGuide[]
128
+ rotationPreview?: { nodeId: string; angle: number } | null
129
+ dropTargetId?: string | null
130
+ layoutInsertIndicator?: {
131
+ x: number
132
+ y: number
133
+ length: number
134
+ direction: 'HORIZONTAL' | 'VERTICAL'
135
+ } | null
136
+ penState?: {
137
+ vertices: Vector[]
138
+ segments: Array<{
139
+ start: number
140
+ end: number
141
+ tangentStart: Vector
142
+ tangentEnd: Vector
143
+ }>
144
+ dragTangent: Vector | null
145
+ closingToFirst: boolean
146
+ cursorX?: number
147
+ cursorY?: number
148
+ } | null
149
+ remoteCursors?: Array<{
150
+ name: string
151
+ color: Color
152
+ x: number
153
+ y: number
154
+ selection?: string[]
155
+ }>
156
+ measurementMode?: boolean
157
+ }
158
+
159
+ export class SkiaRenderer {
160
+ ck: CanvasKit
161
+ surface: Surface
162
+ fillPaint: Paint
163
+ strokePaint: Paint
164
+ selectionPaint: Paint
165
+ parentOutlinePaint: Paint
166
+ snapPaint: Paint
167
+ auxFill: Paint
168
+ auxStroke: Paint
169
+ opacityPaint: Paint
170
+ effectLayerPaint: Paint
171
+ imageFilterCache = new Map<string, ImageFilter>()
172
+ maskFilterCache = new Map<number, MaskFilter>()
173
+ _tmpColor = new Float32Array(4)
174
+ _tmpRect = new Float32Array(4)
175
+ textFont: Font | null = null
176
+ labelFont: Font | null = null
177
+ sizeFont: Font | null = null
178
+ sectionTitleFont: Font | null = null
179
+ componentLabelFont: Font | null = null
180
+ fontMgr: FontMgr | null = null
181
+ fontProvider: TypefaceFontProvider | null = null
182
+ fontsLoaded = false
183
+ imageCache = new LRUCache<string, CKImage>(512, (img) => img.delete())
184
+ vectorPathCache = new LRUCache<string, Path[]>(512, (paths) => { for (const p of paths) p.delete() })
185
+ fillGeometryCache = new LRUCache<string, Path[]>(512, (paths) => { for (const p of paths) p.delete() })
186
+ strokeGeometryCache = new LRUCache<string, Path[]>(512, (paths) => { for (const p of paths) p.delete() })
187
+ scenePicture: SkPicture | null = null
188
+ scenePictureVersion = -1
189
+ scenePicturePageId: string | null = null
190
+ nodePictureCache = new LRUCache<string, SkPicture>(512, (pic) => pic.delete())
191
+ readonly labelCache = new LabelCache()
192
+ readonly profiler: RenderProfiler
193
+
194
+ rulerBgPaint: Paint
195
+ rulerTickPaint: Paint
196
+ rulerTextPaint: Paint
197
+ rulerHlPaint: Paint
198
+ rulerBadgePaint: Paint
199
+ rulerLabelPaint: Paint
200
+ penPathPaint: Paint
201
+ penHandlePaint: Paint
202
+ penVertexFill: Paint
203
+ penVertexStroke: Paint
204
+
205
+ panX = 0
206
+ panY = 0
207
+ zoom = 1
208
+ dpr = 1
209
+ viewportWidth = 0
210
+ viewportHeight = 0
211
+ showRulers = true
212
+ pageColor = CANVAS_BG_COLOR
213
+ pageId: string | null = null
214
+
215
+ worldViewport = { x: 0, y: 0, w: 0, h: 0 }
216
+ _nodeCount = 0
217
+ _culledCount = 0
218
+ _flashes: Array<{ nodeId: string; startTime: number }> = []
219
+ _flashPaint: Paint | null = null
220
+
221
+ readonly DEFAULT_FONT_SIZE = DEFAULT_FONT_SIZE
222
+ readonly COMPONENT_SET_BORDER_WIDTH = COMPONENT_SET_BORDER_WIDTH
223
+ readonly COMPONENT_SET_DASH = COMPONENT_SET_DASH
224
+ readonly COMPONENT_SET_DASH_GAP = COMPONENT_SET_DASH_GAP
225
+
226
+ /**
227
+ * Returns a shared Float32Array [r, g, b, a] for passing colors to CanvasKit.
228
+ * WARNING: The returned buffer is reused on every call. Callers must consume
229
+ * the value immediately (pass it to a CanvasKit API) before the next call to
230
+ * color4f(), as the underlying data will be overwritten.
231
+ */
232
+ color4f(r: number, g: number, b: number, a: number): Float32Array {
233
+ const c = this._tmpColor
234
+ c[0] = r
235
+ c[1] = g
236
+ c[2] = b
237
+ c[3] = a
238
+ return c
239
+ }
240
+
241
+ /**
242
+ * Returns a shared Float32Array [left, top, right, bottom] for passing rects to CanvasKit.
243
+ * WARNING: The returned buffer is reused on every call. Callers must consume
244
+ * the value immediately (pass it to a CanvasKit API) before the next call to
245
+ * ltrb(), as the underlying data will be overwritten.
246
+ */
247
+ ltrb(l: number, t: number, r: number, b: number): Float32Array {
248
+ const rc = this._tmpRect
249
+ rc[0] = l
250
+ rc[1] = t
251
+ rc[2] = r
252
+ rc[3] = b
253
+ return rc
254
+ }
255
+
256
+ selColor(alpha = 1) {
257
+ return this.ck.Color4f(SELECTION_COLOR.r, SELECTION_COLOR.g, SELECTION_COLOR.b, alpha)
258
+ }
259
+
260
+ compColor(alpha = 1) {
261
+ return this.ck.Color4f(COMPONENT_COLOR.r, COMPONENT_COLOR.g, COMPONENT_COLOR.b, alpha)
262
+ }
263
+
264
+ isComponentType(type: string): boolean {
265
+ return type === 'COMPONENT' || type === 'COMPONENT_SET' || type === 'INSTANCE'
266
+ }
267
+
268
+ isRectangularType(type: string): boolean {
269
+ return (
270
+ type === 'FRAME' ||
271
+ type === 'RECTANGLE' ||
272
+ type === 'ROUNDED_RECTANGLE' ||
273
+ type === 'COMPONENT' ||
274
+ type === 'INSTANCE' ||
275
+ type === 'SECTION' ||
276
+ type === 'GROUP'
277
+ )
278
+ }
279
+
280
+ effectOverflow(node: SceneNode): number {
281
+ let expand = 0
282
+ for (const e of node.effects) {
283
+ if (!e.visible) continue
284
+ const blur = e.radius
285
+ const spread = e.spread
286
+ const ox = Math.abs(e.offset.x)
287
+ const oy = Math.abs(e.offset.y)
288
+ expand = Math.max(expand, blur + spread + ox, blur + spread + oy)
289
+ }
290
+ return expand
291
+ }
292
+
293
+ constructor(ck: CanvasKit, surface: Surface, gl?: WebGL2RenderingContext | null) {
294
+ this.ck = ck
295
+ this.surface = surface
296
+ this.profiler = new RenderProfiler(ck, gl ?? null)
297
+
298
+ this.fillPaint = new ck.Paint()
299
+ this.fillPaint.setStyle(ck.PaintStyle.Fill)
300
+ this.fillPaint.setAntiAlias(true)
301
+
302
+ this.strokePaint = new ck.Paint()
303
+ this.strokePaint.setStyle(ck.PaintStyle.Stroke)
304
+ this.strokePaint.setAntiAlias(true)
305
+
306
+ this.selectionPaint = new ck.Paint()
307
+ this.selectionPaint.setStyle(ck.PaintStyle.Stroke)
308
+ this.selectionPaint.setStrokeWidth(1)
309
+ this.selectionPaint.setColor(this.selColor())
310
+ this.selectionPaint.setAntiAlias(true)
311
+
312
+ this.parentOutlinePaint = new ck.Paint()
313
+ this.parentOutlinePaint.setStyle(ck.PaintStyle.Stroke)
314
+ this.parentOutlinePaint.setStrokeWidth(1)
315
+ this.parentOutlinePaint.setColor(this.selColor(PARENT_OUTLINE_ALPHA))
316
+ this.parentOutlinePaint.setAntiAlias(true)
317
+ this.parentOutlinePaint.setPathEffect(
318
+ ck.PathEffect.MakeDash([PARENT_OUTLINE_DASH, PARENT_OUTLINE_DASH], 0)
319
+ )
320
+
321
+ this.snapPaint = new ck.Paint()
322
+ this.snapPaint.setStyle(ck.PaintStyle.Stroke)
323
+ this.snapPaint.setStrokeWidth(1)
324
+ this.snapPaint.setColor(this.ck.Color4f(SNAP_COLOR.r, SNAP_COLOR.g, SNAP_COLOR.b, 1))
325
+ this.snapPaint.setAntiAlias(true)
326
+
327
+ this.auxFill = new ck.Paint()
328
+ this.auxFill.setStyle(ck.PaintStyle.Fill)
329
+ this.auxFill.setAntiAlias(true)
330
+
331
+ this.auxStroke = new ck.Paint()
332
+ this.auxStroke.setStyle(ck.PaintStyle.Stroke)
333
+ this.auxStroke.setAntiAlias(true)
334
+
335
+ this.opacityPaint = new ck.Paint()
336
+ this.effectLayerPaint = new ck.Paint()
337
+
338
+ this.textFont = new ck.Font(null, DEFAULT_FONT_SIZE)
339
+
340
+ const bg = RULER_BG_COLOR
341
+ this.rulerBgPaint = new ck.Paint()
342
+ this.rulerBgPaint.setColor(ck.Color4f(bg.r, bg.g, bg.b, 1))
343
+
344
+ this.rulerTickPaint = new ck.Paint()
345
+ this.rulerTickPaint.setColor(
346
+ ck.Color4f(RULER_TICK_COLOR.r, RULER_TICK_COLOR.g, RULER_TICK_COLOR.b, 1)
347
+ )
348
+ this.rulerTickPaint.setStrokeWidth(1)
349
+ this.rulerTickPaint.setAntiAlias(true)
350
+
351
+ const tc = RULER_TEXT_COLOR
352
+ this.rulerTextPaint = new ck.Paint()
353
+ this.rulerTextPaint.setColor(ck.Color4f(tc.r, tc.g, tc.b, 1))
354
+ this.rulerTextPaint.setAntiAlias(true)
355
+
356
+ this.rulerHlPaint = new ck.Paint()
357
+ this.rulerHlPaint.setAntiAlias(true)
358
+
359
+ this.rulerBadgePaint = new ck.Paint()
360
+ this.rulerBadgePaint.setAntiAlias(true)
361
+
362
+ this.rulerLabelPaint = new ck.Paint()
363
+ this.rulerLabelPaint.setColor(ck.Color4f(1, 1, 1, 1))
364
+ this.rulerLabelPaint.setAntiAlias(true)
365
+
366
+ this.penPathPaint = new ck.Paint()
367
+ this.penPathPaint.setStyle(ck.PaintStyle.Stroke)
368
+ this.penPathPaint.setStrokeWidth(PEN_PATH_STROKE_WIDTH)
369
+ this.penPathPaint.setColor(this.selColor())
370
+ this.penPathPaint.setAntiAlias(true)
371
+
372
+ this.penHandlePaint = new ck.Paint()
373
+ this.penHandlePaint.setStyle(ck.PaintStyle.Stroke)
374
+ this.penHandlePaint.setStrokeWidth(1)
375
+ this.penHandlePaint.setColor(this.selColor(PARENT_OUTLINE_ALPHA))
376
+ this.penHandlePaint.setAntiAlias(true)
377
+
378
+ this.penVertexFill = new ck.Paint()
379
+ this.penVertexFill.setStyle(ck.PaintStyle.Fill)
380
+ this.penVertexFill.setColor(ck.WHITE)
381
+ this.penVertexFill.setAntiAlias(true)
382
+
383
+ this.penVertexStroke = new ck.Paint()
384
+ this.penVertexStroke.setStyle(ck.PaintStyle.Stroke)
385
+ this.penVertexStroke.setStrokeWidth(PEN_PATH_STROKE_WIDTH)
386
+ this.penVertexStroke.setColor(this.selColor())
387
+ this.penVertexStroke.setAntiAlias(true)
388
+ }
389
+
390
+ getFontProvider(): TypefaceFontProvider | null {
391
+ return this.fontProvider
392
+ }
393
+
394
+ async loadFonts(): Promise<void> {
395
+ this.fontProvider = this.ck.TypefaceFontProvider.Make()
396
+
397
+ const { initFontService, loadFont, ensureCJKFallback } = await import('../fonts')
398
+ initFontService(this.ck, this.fontProvider)
399
+
400
+ const fontData = await loadFont(DEFAULT_FONT_FAMILY, 'Regular')
401
+ if (fontData) {
402
+ const typeface = this.ck.Typeface.MakeFreeTypeFaceFromData(fontData)
403
+ if (typeface) {
404
+ this.textFont?.delete()
405
+ this.labelFont?.delete()
406
+ this.sizeFont?.delete()
407
+ this.sectionTitleFont?.delete()
408
+ this.componentLabelFont?.delete()
409
+ this.textFont = new this.ck.Font(typeface, DEFAULT_FONT_SIZE)
410
+ this.labelFont = new this.ck.Font(typeface, LABEL_FONT_SIZE)
411
+ this.sizeFont = new this.ck.Font(typeface, SIZE_FONT_SIZE)
412
+ this.sectionTitleFont = new this.ck.Font(typeface, SECTION_TITLE_FONT_SIZE)
413
+ this.componentLabelFont = new this.ck.Font(typeface, COMPONENT_LABEL_FONT_SIZE)
414
+ this.profiler.setTypeface(typeface)
415
+ }
416
+ this.fontMgr = this.ck.FontMgr.FromData(fontData) ?? null
417
+ }
418
+
419
+ this.fontsLoaded = true
420
+ this.invalidateAllPictures()
421
+
422
+ void ensureCJKFallback().then((family) => {
423
+ if (family) this.invalidateAllPictures()
424
+ })
425
+ }
426
+
427
+ replaceSurface(surface: Surface): void {
428
+ this.surface.delete()
429
+ this.surface = surface
430
+ this.invalidateScenePicture()
431
+ }
432
+
433
+ invalidateScenePicture(): void {
434
+ this.scenePicture?.delete()
435
+ this.scenePicture = null
436
+ this.scenePictureVersion = -1
437
+ }
438
+
439
+ invalidateAllPictures(): void {
440
+ this.invalidateScenePicture()
441
+ this.nodePictureCache.clear()
442
+ }
443
+
444
+ invalidateNodePicture(nodeId: string): void {
445
+ this.nodePictureCache.delete(nodeId)
446
+ }
447
+
448
+ flashNode(nodeId: string): void {
449
+ this._flashes.push({ nodeId, startTime: performance.now() })
450
+ }
451
+
452
+ get hasActiveFlashes(): boolean {
453
+ return this._flashes.length > 0
454
+ }
455
+
456
+ hitTestSectionTitle(graph: SceneGraph, canvasX: number, canvasY: number): SceneNode | null {
457
+ if (!this.sectionTitleFont) return null
458
+
459
+ const pageNode = graph.getNode(this.pageId ?? graph.rootId)
460
+ if (!pageNode) return null
461
+
462
+ const font = this.sectionTitleFont
463
+ let result: SceneNode | null = null
464
+
465
+ const check = (parentId: string, ox: number, oy: number, insideSection: boolean) => {
466
+ const parent = graph.getNode(parentId)
467
+ if (!parent) return
468
+ for (let i = parent.childIds.length - 1; i >= 0; i--) {
469
+ if (result) return
470
+ const childId = parent.childIds[i]
471
+ const child = graph.getNode(childId)
472
+ if (!child || !child.visible) continue
473
+ const ax = ox + child.x
474
+ const ay = oy + child.y
475
+ if (child.type === 'SECTION') {
476
+ const glyphIds = font.getGlyphIDs(child.name)
477
+ const widths = font.getGlyphWidths(glyphIds)
478
+ let textW = 0
479
+ for (const w of widths) textW += w
480
+ const pillW =
481
+ Math.min(textW + SECTION_TITLE_PADDING_X * 2, child.width * this.zoom) / this.zoom
482
+ const pillH = SECTION_TITLE_HEIGHT / this.zoom
483
+ const gap = SECTION_TITLE_GAP / this.zoom
484
+
485
+ let pillX = ax
486
+ let pillY: number
487
+ if (insideSection) {
488
+ pillY = ay + gap
489
+ } else {
490
+ pillY = ay - pillH - gap
491
+ }
492
+
493
+ if (
494
+ canvasX >= pillX &&
495
+ canvasX <= pillX + pillW &&
496
+ canvasY >= pillY &&
497
+ canvasY <= pillY + pillH
498
+ ) {
499
+ result = child
500
+ return
501
+ }
502
+
503
+ check(childId, ax, ay, true)
504
+ } else if (child.childIds.length > 0) {
505
+ check(childId, ax, ay, insideSection)
506
+ }
507
+ }
508
+ }
509
+
510
+ check(pageNode.id, 0, 0, false)
511
+ return result
512
+ }
513
+
514
+ hitTestComponentLabel(graph: SceneGraph, canvasX: number, canvasY: number): SceneNode | null {
515
+ if (!this.componentLabelFont) return null
516
+
517
+ const pageNode = graph.getNode(this.pageId ?? graph.rootId)
518
+ if (!pageNode) return null
519
+
520
+ const font = this.componentLabelFont
521
+ const LABEL_TYPES = new Set(['COMPONENT', 'COMPONENT_SET'])
522
+ let result: SceneNode | null = null
523
+
524
+ const check = (parentId: string, ox: number, oy: number) => {
525
+ const parent = graph.getNode(parentId)
526
+ if (!parent) return
527
+ for (let i = parent.childIds.length - 1; i >= 0; i--) {
528
+ if (result) return
529
+ const childId = parent.childIds[i]
530
+ const child = graph.getNode(childId)
531
+ if (!child || !child.visible) continue
532
+ const ax = ox + child.x
533
+ const ay = oy + child.y
534
+ if (LABEL_TYPES.has(child.type)) {
535
+ const glyphIds = font.getGlyphIDs(child.name)
536
+ const widths = font.getGlyphWidths(glyphIds)
537
+ let textW = 0
538
+ for (const w of widths) textW += w
539
+ const labelW = (COMPONENT_LABEL_ICON_SIZE + COMPONENT_LABEL_ICON_GAP + textW) / this.zoom
540
+ const labelH = COMPONENT_LABEL_FONT_SIZE / this.zoom
541
+ const gap = COMPONENT_LABEL_GAP / this.zoom
542
+
543
+ const isInsideSet = parent.type === 'COMPONENT_SET'
544
+ const labelX = ax
545
+ let labelY: number
546
+ if (isInsideSet) {
547
+ labelY = ay + gap
548
+ } else {
549
+ labelY = ay - labelH - gap
550
+ }
551
+
552
+ if (
553
+ canvasX >= labelX &&
554
+ canvasX <= labelX + labelW &&
555
+ canvasY >= labelY &&
556
+ canvasY <= labelY + labelH
557
+ ) {
558
+ result = child
559
+ return
560
+ }
561
+ }
562
+ if (child.childIds.length > 0) {
563
+ check(childId, ax, ay)
564
+ }
565
+ }
566
+ }
567
+
568
+ check(pageNode.id, 0, 0)
569
+ return result
570
+ }
571
+
572
+ hitTestFrameTitle(
573
+ graph: SceneGraph,
574
+ canvasX: number,
575
+ canvasY: number,
576
+ selectedIds: Set<string>
577
+ ): SceneNode | null {
578
+ if (!this.labelFont || selectedIds.size !== 1) return null
579
+
580
+ const id = [...selectedIds][0]
581
+ const node = graph.getNode(id)
582
+ if (node?.type !== 'FRAME') return null
583
+
584
+ const parent = node.parentId ? graph.getNode(node.parentId) : null
585
+ const isTopLevel = !parent || parent.type === 'CANVAS' || parent.type === 'SECTION'
586
+ if (!isTopLevel) return null
587
+
588
+ const abs = graph.getAbsolutePosition(id)
589
+ const font = this.labelFont
590
+ const glyphIds = font.getGlyphIDs(node.name)
591
+ const widths = font.getGlyphWidths(glyphIds)
592
+ let textW = 0
593
+ for (const w of widths) textW += w
594
+
595
+ const labelW = textW / this.zoom
596
+ const labelH = LABEL_FONT_SIZE / this.zoom
597
+ const gap = LABEL_OFFSET_Y / this.zoom
598
+ const labelX = abs.x
599
+ const labelY = abs.y - gap - labelH
600
+
601
+ if (
602
+ canvasX >= labelX &&
603
+ canvasX <= labelX + labelW &&
604
+ canvasY >= labelY &&
605
+ canvasY <= labelY + labelH
606
+ ) {
607
+ return node
608
+ }
609
+
610
+ return null
611
+ }
612
+
613
+ renderSceneToCanvas(canvas: Canvas, graph: SceneGraph, pageId: string): void {
614
+ const prevViewport = this.worldViewport
615
+ this.worldViewport = { x: -1e9, y: -1e9, w: 2e9, h: 2e9 }
616
+ const pageNode = graph.getNode(pageId)
617
+ if (pageNode) {
618
+ for (const childId of pageNode.childIds) {
619
+ this.renderNode(canvas, graph, childId, {})
620
+ }
621
+ }
622
+ this.worldViewport = prevViewport
623
+ }
624
+
625
+ render(
626
+ graph: SceneGraph,
627
+ selectedIds: Set<string>,
628
+ overlays: RenderOverlays = {},
629
+ sceneVersion = -1
630
+ ): void {
631
+ const p = this.profiler
632
+ p.beginFrame()
633
+
634
+ graph.clearAbsPosCache()
635
+
636
+ const canvas = this.surface.getCanvas()
637
+ canvas.clear(this.ck.Color4f(this.pageColor.r, this.pageColor.g, this.pageColor.b, 1))
638
+
639
+ this.worldViewport = {
640
+ x: -this.panX / this.zoom,
641
+ y: -this.panY / this.zoom,
642
+ w: this.viewportWidth / this.zoom,
643
+ h: this.viewportHeight / this.zoom
644
+ }
645
+
646
+ const hasVolatileOverlays =
647
+ overlays.dropTargetId != null ||
648
+ overlays.rotationPreview != null ||
649
+ overlays.editingTextId != null
650
+
651
+ const canUsePicture =
652
+ !hasVolatileOverlays &&
653
+ this.scenePicture &&
654
+ sceneVersion === this.scenePictureVersion &&
655
+ this.pageId === this.scenePicturePageId
656
+
657
+ p.setCacheHit(!!canUsePicture)
658
+
659
+ canvas.save()
660
+ canvas.scale(this.dpr, this.dpr)
661
+ canvas.translate(this.panX, this.panY)
662
+ canvas.scale(this.zoom, this.zoom)
663
+
664
+ p.beginPhase('render:scene')
665
+ if (canUsePicture) {
666
+ p.beginPhase('render:drawPicture')
667
+ if (this.scenePicture) canvas.drawPicture(this.scenePicture)
668
+ p.endPhase('render:drawPicture')
669
+ } else if (hasVolatileOverlays) {
670
+ this._nodeCount = 0
671
+ this._culledCount = 0
672
+ p.beginPhase('render:volatile')
673
+ const pageNode = graph.getNode(this.pageId ?? graph.rootId)
674
+ if (pageNode) {
675
+ for (const childId of pageNode.childIds) {
676
+ this.renderNode(canvas, graph, childId, overlays, 0, 0)
677
+ }
678
+ }
679
+ p.endPhase('render:volatile')
680
+ } else {
681
+ this._nodeCount = 0
682
+ this._culledCount = 0
683
+ p.beginPhase('render:recordPicture')
684
+ this.recordScenePicture(canvas, graph, sceneVersion)
685
+ p.endPhase('render:recordPicture')
686
+ }
687
+ p.endPhase('render:scene')
688
+
689
+ canvas.restore()
690
+
691
+ canvas.save()
692
+ canvas.scale(this.dpr, this.dpr)
693
+ this.labelCache.update(graph, this.pageId, sceneVersion)
694
+ p.beginPhase('render:sectionTitles')
695
+ this.drawSectionTitles(canvas, graph)
696
+ p.endPhase('render:sectionTitles')
697
+ p.beginPhase('render:componentLabels')
698
+ this.drawComponentLabels(canvas, graph)
699
+ p.endPhase('render:componentLabels')
700
+ canvas.restore()
701
+
702
+ canvas.save()
703
+ canvas.scale(this.dpr, this.dpr)
704
+
705
+ this.drawHoverHighlight(canvas, graph, overlays.hoveredNodeId)
706
+ p.beginPhase('render:selection')
707
+ this.drawSelection(canvas, graph, selectedIds, overlays)
708
+ p.endPhase('render:selection')
709
+ this.drawFlashes(canvas, graph)
710
+ this.drawSnapGuides(canvas, overlays.snapGuides)
711
+ if (overlays.measurementMode) {
712
+ this.drawMeasurements(canvas, graph, selectedIds, overlays.hoveredNodeId)
713
+ this.drawPaddingOverlay(canvas, graph, selectedIds)
714
+ }
715
+ this.drawMarquee(canvas, overlays.marquee)
716
+ this.drawLayoutInsertIndicator(canvas, overlays.layoutInsertIndicator)
717
+ this.drawPenOverlay(canvas, overlays.penState)
718
+ this.drawRemoteCursors(canvas, graph, overlays.remoteCursors)
719
+ p.beginPhase('render:rulers')
720
+ if (this.showRulers) this.drawRulers(canvas, graph, selectedIds)
721
+ p.endPhase('render:rulers')
722
+
723
+ p.drawHUD(canvas, this.showRulers)
724
+
725
+ canvas.restore()
726
+
727
+ p.beginPhase('render:flush')
728
+ this.surface.flush()
729
+ p.endPhase('render:flush')
730
+
731
+ p.setNodeCounts(this._nodeCount, this._culledCount)
732
+ p.endFrame()
733
+ }
734
+
735
+ private recordScenePicture(canvas: Canvas, graph: SceneGraph, sceneVersion: number): void {
736
+ this.scenePicture?.delete()
737
+ const prevViewport = this.worldViewport
738
+ this.worldViewport = { x: -1e6, y: -1e6, w: 2e6, h: 2e6 }
739
+ const recorder = new this.ck.PictureRecorder()
740
+ const bounds = this.ck.LTRBRect(-1e6, -1e6, 1e6, 1e6)
741
+ const recCanvas = recorder.beginRecording(bounds)
742
+ const pageNode = graph.getNode(this.pageId ?? graph.rootId)
743
+ if (pageNode) {
744
+ for (const childId of pageNode.childIds) {
745
+ this.renderNode(recCanvas, graph, childId, {}, 0, 0)
746
+ }
747
+ }
748
+ this.scenePicture = recorder.finishRecordingAsPicture()
749
+ recorder.delete()
750
+ this.worldViewport = prevViewport
751
+ this.scenePictureVersion = sceneVersion
752
+ this.scenePicturePageId = this.pageId
753
+ canvas.drawPicture(this.scenePicture)
754
+ }
755
+
756
+ invalidateVectorPath(nodeId: string): void {
757
+ this.vectorPathCache.delete(nodeId)
758
+ this.fillGeometryCache.delete(nodeId)
759
+ this.strokeGeometryCache.delete(nodeId)
760
+ }
761
+
762
+ measureTextNode(node: SceneNode, maxWidth?: number): { width: number; height: number } | null {
763
+ if (!this.fontsLoaded || !this.fontProvider || !this.isNodeFontLoaded(node)) return null
764
+ if (node.type !== 'TEXT' || !node.text) return null
765
+
766
+ const paragraph = this.buildParagraph(node)
767
+ const layoutWidth =
768
+ maxWidth !== undefined
769
+ ? maxWidth
770
+ : (node.textAutoResize === 'WIDTH_AND_HEIGHT'
771
+ ? 1e6
772
+ : node.width || 1e6)
773
+ paragraph.layout(layoutWidth)
774
+ const width = paragraph.getLongestLine()
775
+ const height = paragraph.getHeight()
776
+ paragraph.delete()
777
+ return { width: Math.ceil(width), height: Math.ceil(height) }
778
+ }
779
+
780
+ isNodeFontLoaded(node: SceneNode): boolean {
781
+ const families = new Set<string>()
782
+ families.add(node.fontFamily || DEFAULT_FONT_FAMILY)
783
+ for (const run of node.styleRuns) {
784
+ if (run.style.fontFamily) families.add(run.style.fontFamily)
785
+ }
786
+ return [...families].every((f) => isFontLoaded(f))
787
+ }
788
+
789
+ buildTextPicture(node: SceneNode): Uint8Array | null {
790
+ if (!this.fontsLoaded || !this.fontProvider || !this.isNodeFontLoaded(node)) return null
791
+ if (node.type !== 'TEXT' || !node.text) return null
792
+
793
+ const ck = this.ck
794
+ const recorder = new ck.PictureRecorder()
795
+ const bounds = ck.LTRBRect(0, 0, node.width || 1e6, node.height || 1e6)
796
+ const recCanvas = recorder.beginRecording(bounds)
797
+
798
+ const paragraph = this.buildParagraph(node, undefined, { halfLeading: true })
799
+ recCanvas.drawParagraph(paragraph, 0, 0)
800
+ paragraph.delete()
801
+
802
+ const picture = recorder.finishRecordingAsPicture()
803
+ recorder.delete()
804
+
805
+ const bytes = picture.serialize()
806
+ picture.delete()
807
+ return bytes ?? null
808
+ }
809
+
810
+ buildParagraph(
811
+ node: SceneNode,
812
+ color?: Float32Array,
813
+ { halfLeading = false }: { halfLeading?: boolean } = {}
814
+ ): Paragraph {
815
+ const ck = this.ck
816
+ const baseColor = color ?? ck.BLACK
817
+ const baseFontSize = node.fontSize || DEFAULT_FONT_SIZE
818
+ const cjkFallback = getCJKFallbackFamily()
819
+
820
+ const truncateOpts = this.buildTruncateOpts(node, baseFontSize)
821
+
822
+ const fontFamilies = (primary: string) =>
823
+ cjkFallback ? [primary, cjkFallback] : [primary]
824
+
825
+ const paraStyle = new ck.ParagraphStyle({
826
+ textAlign: this.getTextAlign(node.textAlignHorizontal),
827
+ ...truncateOpts,
828
+ textStyle: {
829
+ color: baseColor,
830
+ fontFamilies: fontFamilies(node.fontFamily || DEFAULT_FONT_FAMILY),
831
+ fontSize: baseFontSize,
832
+ fontStyle: {
833
+ weight: { value: node.fontWeight || 400 } as FontWeight,
834
+ slant: node.italic ? ck.FontSlant.Italic : ck.FontSlant.Upright
835
+ },
836
+ letterSpacing: node.letterSpacing || 0,
837
+ decoration: this.textDecorationValue(node.textDecoration),
838
+ heightMultiplier: node.lineHeight ? node.lineHeight / baseFontSize : undefined,
839
+ halfLeading
840
+ }
841
+ })
842
+
843
+ if (!this.fontProvider) throw new Error('Font provider not initialized')
844
+ const builder = ck.ParagraphBuilder.MakeFromFontProvider(paraStyle, this.fontProvider)
845
+
846
+ if (node.styleRuns.length === 0) {
847
+ builder.addText(node.text)
848
+ } else {
849
+ this.addStyledRuns(builder, node, baseColor, baseFontSize, fontFamilies, halfLeading)
850
+ }
851
+
852
+ const paragraph = builder.build()
853
+ paragraph.layout(node.width || 1e6)
854
+ builder.delete()
855
+ return paragraph
856
+ }
857
+
858
+ private buildTruncateOpts(
859
+ node: SceneNode,
860
+ baseFontSize: number
861
+ ): { maxLines?: number; ellipsis?: string } {
862
+ if (node.textTruncation !== 'ENDING') return {}
863
+
864
+ const opts: { maxLines?: number; ellipsis: string } = { ellipsis: '…' }
865
+ if (node.maxLines != null && node.maxLines > 0) {
866
+ opts.maxLines = node.maxLines
867
+ } else if (node.height > 0) {
868
+ const lineH = node.lineHeight || baseFontSize * 1.2
869
+ opts.maxLines = Math.max(1, Math.floor(node.height / lineH))
870
+ }
871
+ return opts
872
+ }
873
+
874
+ private addStyledRuns(
875
+ builder: ReturnType<CanvasKit['ParagraphBuilder']['MakeFromFontProvider']>,
876
+ node: SceneNode,
877
+ baseColor: Float32Array,
878
+ baseFontSize: number,
879
+ fontFamilies: (primary: string) => string[],
880
+ halfLeading: boolean
881
+ ): void {
882
+ const ck = this.ck
883
+ const text = node.text
884
+ let pos = 0
885
+
886
+ for (const run of node.styleRuns) {
887
+ if (pos < run.start) {
888
+ builder.addText(text.slice(pos, run.start))
889
+ }
890
+ const s = run.style
891
+ const runLineHeight = s.lineHeight !== undefined ? s.lineHeight : node.lineHeight
892
+ const runFontSize = s.fontSize ?? baseFontSize
893
+
894
+ builder.pushStyle(
895
+ new ck.TextStyle({
896
+ color: baseColor,
897
+ fontFamilies: fontFamilies(s.fontFamily ?? (node.fontFamily || DEFAULT_FONT_FAMILY)),
898
+ fontSize: runFontSize,
899
+ fontStyle: {
900
+ weight: { value: (s.fontWeight ?? node.fontWeight) || 400 } as FontWeight,
901
+ slant: (s.italic ?? node.italic) ? ck.FontSlant.Italic : ck.FontSlant.Upright
902
+ },
903
+ letterSpacing: s.letterSpacing ?? (node.letterSpacing || 0),
904
+ decoration: this.textDecorationValue(s.textDecoration ?? node.textDecoration),
905
+ heightMultiplier: runLineHeight ? runLineHeight / runFontSize : undefined,
906
+ halfLeading
907
+ })
908
+ )
909
+ builder.addText(text.slice(run.start, run.start + run.length))
910
+ builder.pop()
911
+ pos = run.start + run.length
912
+ }
913
+
914
+ if (pos < text.length) {
915
+ builder.addText(text.slice(pos))
916
+ }
917
+ }
918
+
919
+ private textDecorationValue(decoration: string): number {
920
+ switch (decoration) {
921
+ case 'UNDERLINE':
922
+ return this.ck.UnderlineDecoration
923
+ case 'STRIKETHROUGH':
924
+ return this.ck.LineThroughDecoration
925
+ default:
926
+ return this.ck.NoDecoration
927
+ }
928
+ }
929
+
930
+ private getTextAlign(align: string) {
931
+ switch (align) {
932
+ case 'CENTER':
933
+ return this.ck.TextAlign.Center
934
+ case 'RIGHT':
935
+ return this.ck.TextAlign.Right
936
+ case 'JUSTIFIED':
937
+ return this.ck.TextAlign.Justify
938
+ default:
939
+ return this.ck.TextAlign.Left
940
+ }
941
+ }
942
+
943
+ resolveFillColor(fill: Fill, fillIndex: number, node: SceneNode, graph: SceneGraph): Color {
944
+ const varId = node.boundVariables[`fills/${fillIndex}/color`]
945
+ if (varId) {
946
+ const resolved = graph.resolveColorVariable(varId)
947
+ if (resolved) return resolved
948
+ }
949
+ return fill.color
950
+ }
951
+
952
+ resolveStrokeColor(
953
+ stroke: Stroke,
954
+ strokeIndex: number,
955
+ node: SceneNode,
956
+ graph: SceneGraph
957
+ ): Color {
958
+ const varId = node.boundVariables[`strokes/${strokeIndex}/color`]
959
+ if (varId) {
960
+ const resolved = graph.resolveColorVariable(varId)
961
+ if (resolved) return resolved
962
+ }
963
+ return stroke.color
964
+ }
965
+
966
+ screenToCanvas(sx: number, sy: number): Vector {
967
+ return {
968
+ x: (sx - this.panX) / this.zoom,
969
+ y: (sy - this.panY) / this.zoom
970
+ }
971
+ }
972
+
973
+ destroyed = false
974
+
975
+ destroy(): void {
976
+ if (this.destroyed) return
977
+ this.destroyed = true
978
+
979
+ this.imageCache.clear()
980
+ this.vectorPathCache.clear()
981
+ this.fillGeometryCache.clear()
982
+ this.strokeGeometryCache.clear()
983
+ this.fillPaint.delete()
984
+ this.strokePaint.delete()
985
+ this.selectionPaint.delete()
986
+ this.snapPaint.delete()
987
+ this.auxFill.delete()
988
+ this.auxStroke.delete()
989
+ this.opacityPaint.delete()
990
+ this.textFont?.delete()
991
+ this.labelFont?.delete()
992
+ this.sizeFont?.delete()
993
+ this.fontMgr?.delete()
994
+ this.fontProvider?.delete()
995
+ this.rulerBgPaint.delete()
996
+ this.rulerTickPaint.delete()
997
+ this.rulerTextPaint.delete()
998
+ this.rulerHlPaint.delete()
999
+ this.rulerBadgePaint.delete()
1000
+ this.rulerLabelPaint.delete()
1001
+ this.penPathPaint.delete()
1002
+ this.penHandlePaint.delete()
1003
+ this.penVertexFill.delete()
1004
+ this.penVertexStroke.delete()
1005
+ this.effectLayerPaint.delete()
1006
+ for (const filter of this.imageFilterCache.values()) filter.delete()
1007
+ this.imageFilterCache.clear()
1008
+ for (const filter of this.maskFilterCache.values()) filter.delete()
1009
+ this.maskFilterCache.clear()
1010
+ this.nodePictureCache.clear()
1011
+ this.scenePicture?.delete()
1012
+ this._flashPaint?.delete()
1013
+ this.profiler.destroy()
1014
+ this.surface.delete()
1015
+ }
1016
+
1017
+ // --- Delegation methods ---
1018
+
1019
+ private drawHoverHighlight(canvas: Canvas, graph: SceneGraph, hoveredNodeId?: string | null): void {
1020
+ drawHoverHighlightFn(this, canvas, graph, hoveredNodeId)
1021
+ }
1022
+
1023
+ private drawSelection(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>, overlays: RenderOverlays): void {
1024
+ drawSelectionFn(this, canvas, graph, selectedIds, overlays)
1025
+ }
1026
+
1027
+ drawNodeSelection(canvas: Canvas, node: SceneNode, rotation: number, graph: SceneGraph): void {
1028
+ drawNodeSelectionFn(this, canvas, node, rotation, graph)
1029
+ }
1030
+
1031
+ drawSelectionLabels(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>): void {
1032
+ drawSelectionLabelsFn(this, canvas, graph, selectedIds)
1033
+ }
1034
+
1035
+ drawParentFrameOutlines(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>): void {
1036
+ drawParentFrameOutlinesFn(this, canvas, graph, selectedIds)
1037
+ }
1038
+
1039
+ drawNodeOutline(canvas: Canvas, node: SceneNode, rotation: number, graph: SceneGraph): void {
1040
+ drawNodeOutlineFn(this, canvas, node, rotation, graph)
1041
+ }
1042
+
1043
+ drawGroupBounds(canvas: Canvas, nodes: SceneNode[], graph: SceneGraph): void {
1044
+ drawGroupBoundsFn(this, canvas, nodes, graph)
1045
+ }
1046
+
1047
+ getRotatedCorners(n: SceneNode, abs: Vector): Vector[] {
1048
+ return getRotatedCornersFn(this, n, abs)
1049
+ }
1050
+
1051
+ drawHandle(canvas: Canvas, x: number, y: number): void {
1052
+ drawHandleFn(this, canvas, x, y)
1053
+ }
1054
+
1055
+ private drawSnapGuides(canvas: Canvas, guides?: SnapGuide[]): void {
1056
+ drawSnapGuidesFn(this, canvas, guides)
1057
+ }
1058
+
1059
+ private drawMeasurements(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>, hoveredNodeId?: string | null): void {
1060
+ drawMeasurementsFn(this, canvas, graph, selectedIds, hoveredNodeId)
1061
+ }
1062
+
1063
+ private drawPaddingOverlay(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>): void {
1064
+ drawPaddingOverlayFn(this, canvas, graph, selectedIds)
1065
+ }
1066
+
1067
+ private drawMarquee(canvas: Canvas, marquee?: Rect | null): void {
1068
+ drawMarqueeFn(this, canvas, marquee)
1069
+ }
1070
+
1071
+ private drawFlashes(canvas: Canvas, graph: SceneGraph): void {
1072
+ drawFlashesFn(this, canvas, graph)
1073
+ }
1074
+
1075
+ private drawLayoutInsertIndicator(canvas: Canvas, indicator?: RenderOverlays['layoutInsertIndicator']): void {
1076
+ drawLayoutInsertIndicatorFn(this, canvas, indicator)
1077
+ }
1078
+
1079
+ drawTextEditOverlay(canvas: Canvas, node: SceneNode, editor: TextEditor): void {
1080
+ drawTextEditOverlayFn(this, canvas, node, editor)
1081
+ }
1082
+
1083
+ private drawPenOverlay(canvas: Canvas, penState: RenderOverlays['penState']): void {
1084
+ drawPenOverlayFn(this, canvas, penState)
1085
+ }
1086
+
1087
+ private drawRemoteCursors(canvas: Canvas, graph: SceneGraph, cursors?: RenderOverlays['remoteCursors']): void {
1088
+ drawRemoteCursorsFn(this, canvas, graph, cursors)
1089
+ }
1090
+
1091
+ private drawRulers(canvas: Canvas, graph: SceneGraph, selectedIds: Set<string>): void {
1092
+ drawRulersFn(this, canvas, graph, selectedIds)
1093
+ }
1094
+
1095
+ private drawSectionTitles(canvas: Canvas, graph: SceneGraph): void {
1096
+ drawSectionTitlesFn(this, canvas, graph)
1097
+ }
1098
+
1099
+ private drawComponentLabels(canvas: Canvas, graph: SceneGraph): void {
1100
+ drawComponentLabelsFn(this, canvas, graph)
1101
+ }
1102
+
1103
+ renderNode(canvas: Canvas, graph: SceneGraph, nodeId: string, overlays: RenderOverlays, parentAbsX = 0, parentAbsY = 0): void {
1104
+ renderNodeFn(this, canvas, graph, nodeId, overlays, parentAbsX, parentAbsY)
1105
+ }
1106
+
1107
+ renderSection(canvas: Canvas, node: SceneNode, graph: SceneGraph): void {
1108
+ renderSectionFn(this, canvas, node, graph)
1109
+ }
1110
+
1111
+ renderComponentSet(canvas: Canvas, node: SceneNode, graph: SceneGraph): void {
1112
+ renderComponentSetFn(this, canvas, node, graph)
1113
+ }
1114
+
1115
+ renderShape(canvas: Canvas, node: SceneNode, graph: SceneGraph): void {
1116
+ renderShapeFn(this, canvas, node, graph)
1117
+ }
1118
+
1119
+ renderShapeUncached(canvas: Canvas, node: SceneNode, graph: SceneGraph): void {
1120
+ renderShapeUncachedFn(this, canvas, node, graph)
1121
+ }
1122
+
1123
+ renderEffects(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean, pass: 'behind' | 'front'): void {
1124
+ renderEffectsFn(this, canvas, node, rect, hasRadius, pass)
1125
+ }
1126
+
1127
+ renderText(canvas: Canvas, node: SceneNode): void {
1128
+ renderTextFn(this, canvas, node)
1129
+ }
1130
+
1131
+ drawNodeFill(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean): void {
1132
+ drawNodeFillFn(this, canvas, node, rect, hasRadius)
1133
+ }
1134
+
1135
+ applyFill(fill: Fill, node: SceneNode, graph: SceneGraph, fillIndex = 0): boolean {
1136
+ return applyFillFn(this, fill, node, graph, fillIndex)
1137
+ }
1138
+
1139
+ applyGradientFill(fill: Fill, node: SceneNode): void {
1140
+ applyGradientFillFn(this, fill, node)
1141
+ }
1142
+
1143
+ applyImageFill(fill: Fill, node: SceneNode, graph: SceneGraph): boolean {
1144
+ return applyImageFillFn(this, fill, node, graph)
1145
+ }
1146
+
1147
+ drawArc(canvas: Canvas, node: SceneNode, paint: Paint): void {
1148
+ drawArcFn(this, canvas, node, paint)
1149
+ }
1150
+
1151
+ drawNodeStroke(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean): void {
1152
+ drawNodeStrokeFn(this, canvas, node, rect, hasRadius)
1153
+ }
1154
+
1155
+ drawStrokeWithAlign(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean, align: 'INSIDE' | 'CENTER' | 'OUTSIDE'): void {
1156
+ drawStrokeWithAlignFn(this, canvas, node, rect, hasRadius, align)
1157
+ }
1158
+
1159
+ drawRRectStrokeWithAlign(canvas: Canvas, rrect: Float32Array, node: SceneNode, stroke: Stroke): void {
1160
+ drawRRectStrokeWithAlignFn(this, canvas, rrect, node, stroke)
1161
+ }
1162
+
1163
+ drawIndividualSideStrokes(canvas: Canvas, node: SceneNode, align: 'INSIDE' | 'CENTER' | 'OUTSIDE'): void {
1164
+ drawIndividualSideStrokesFn(this, canvas, node, align)
1165
+ }
1166
+
1167
+ strokeNodeShape(canvas: Canvas, node: SceneNode, paint: Paint): void {
1168
+ strokeNodeShapeFn(this, canvas, node, paint)
1169
+ }
1170
+
1171
+ makeNodeShapePath(node: SceneNode, rect: Float32Array, hasRadius: boolean): Path {
1172
+ return makeNodeShapePathFn(this, node, rect, hasRadius)
1173
+ }
1174
+
1175
+ makePolygonPath(node: SceneNode): Path {
1176
+ return makePolygonPathFn(this, node)
1177
+ }
1178
+
1179
+ makeRRect(node: SceneNode): Float32Array {
1180
+ return makeRRectFn(this, node)
1181
+ }
1182
+
1183
+ makeRRectWithSpread(node: SceneNode, spread: number): Float32Array {
1184
+ return makeRRectWithSpreadFn(this, node, spread)
1185
+ }
1186
+
1187
+ makeRRectWithOffset(node: SceneNode, ox: number, oy: number, spread: number): Float32Array {
1188
+ return makeRRectWithOffsetFn(this, node, ox, oy, spread)
1189
+ }
1190
+
1191
+ clipNodeShape(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean): void {
1192
+ clipNodeShapeFn(this, canvas, node, rect, hasRadius)
1193
+ }
1194
+
1195
+ getVectorPaths(node: SceneNode): Path[] | null {
1196
+ return getVectorPathsFn(this, node)
1197
+ }
1198
+
1199
+ getFillGeometry(node: SceneNode): Path[] | null {
1200
+ return getFillGeometryFn(this, node)
1201
+ }
1202
+
1203
+ getStrokeGeometry(node: SceneNode): Path[] | null {
1204
+ return getStrokeGeometryFn(this, node)
1205
+ }
1206
+
1207
+ getCachedDropShadow(dx: number, dy: number, sigma: number, color: Float32Array): ImageFilter {
1208
+ return getCachedDropShadowFn(this, dx, dy, sigma, color)
1209
+ }
1210
+
1211
+ getCachedBlur(sigma: number): ImageFilter {
1212
+ return getCachedBlurFn(this, sigma)
1213
+ }
1214
+
1215
+ getCachedDecalBlur(sigma: number): ImageFilter {
1216
+ return getCachedDecalBlurFn(this, sigma)
1217
+ }
1218
+
1219
+ getCachedMaskBlur(sigma: number): MaskFilter {
1220
+ return getCachedMaskBlurFn(this, sigma)
1221
+ }
1222
+
1223
+ applyClippedBlur(canvas: Canvas, node: SceneNode, rect: Float32Array, hasRadius: boolean, sigma: number): void {
1224
+ applyClippedBlurFn(this, canvas, node, rect, hasRadius, sigma)
1225
+ }
1226
+ }