@meonode/canvas 2.0.2 → 2.0.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 (68) hide show
  1. package/dist/cjs/canvas/canvas.helper.js +0 -230
  2. package/dist/cjs/canvas/canvas.helper.js.map +1 -1
  3. package/dist/cjs/canvas/chart.canvas.js +70 -144
  4. package/dist/cjs/canvas/chart.canvas.js.map +1 -1
  5. package/dist/cjs/canvas/image.canvas.js +2 -2
  6. package/dist/cjs/canvas/image.canvas.js.map +1 -1
  7. package/dist/cjs/canvas/layout.canvas.js +6 -6
  8. package/dist/cjs/canvas/layout.canvas.js.map +1 -1
  9. package/dist/cjs/canvas/root.canvas.js +23 -117
  10. package/dist/cjs/canvas/root.canvas.js.map +1 -1
  11. package/dist/cjs/canvas/text.canvas.js +2 -2
  12. package/dist/cjs/canvas/text.canvas.js.map +1 -1
  13. package/dist/cjs/src/canvas/canvas.helper.d.ts +1 -20
  14. package/dist/cjs/src/canvas/canvas.helper.d.ts.map +1 -1
  15. package/dist/cjs/src/canvas/canvas.type.d.ts +1 -12
  16. package/dist/cjs/src/canvas/canvas.type.d.ts.map +1 -1
  17. package/dist/cjs/src/canvas/chart.canvas.d.ts +1 -1
  18. package/dist/cjs/src/canvas/chart.canvas.d.ts.map +1 -1
  19. package/dist/cjs/src/canvas/image.canvas.d.ts +1 -1
  20. package/dist/cjs/src/canvas/image.canvas.d.ts.map +1 -1
  21. package/dist/cjs/src/canvas/layout.canvas.d.ts +2 -2
  22. package/dist/cjs/src/canvas/layout.canvas.d.ts.map +1 -1
  23. package/dist/cjs/src/canvas/root.canvas.d.ts +3 -2
  24. package/dist/cjs/src/canvas/root.canvas.d.ts.map +1 -1
  25. package/dist/cjs/src/canvas/text.canvas.d.ts +1 -1
  26. package/dist/cjs/src/canvas/text.canvas.d.ts.map +1 -1
  27. package/dist/cjs/src/worker/comlink.pool.d.ts +30 -0
  28. package/dist/cjs/src/worker/comlink.pool.d.ts.map +1 -0
  29. package/dist/cjs/src/worker/comlink.setup.d.ts +4 -0
  30. package/dist/cjs/src/worker/comlink.setup.d.ts.map +1 -0
  31. package/dist/cjs/src/worker/worker.types.d.ts +5 -68
  32. package/dist/cjs/src/worker/worker.types.d.ts.map +1 -1
  33. package/dist/cjs/worker/comlink.pool.js +164 -0
  34. package/dist/cjs/worker/comlink.pool.js.map +1 -0
  35. package/dist/cjs/worker/comlink.setup.js +53 -0
  36. package/dist/cjs/worker/comlink.setup.js.map +1 -0
  37. package/dist/cjs/worker/render.worker.js +58 -61
  38. package/dist/cjs/worker/render.worker.js.map +1 -1
  39. package/dist/esm/canvas/canvas.helper.js +1 -230
  40. package/dist/esm/canvas/chart.canvas.js +71 -145
  41. package/dist/esm/canvas/image.canvas.js +2 -2
  42. package/dist/esm/canvas/layout.canvas.js +6 -6
  43. package/dist/esm/canvas/root.canvas.js +23 -116
  44. package/dist/esm/canvas/text.canvas.js +2 -2
  45. package/dist/esm/src/canvas/canvas.helper.d.ts +1 -20
  46. package/dist/esm/src/canvas/canvas.helper.d.ts.map +1 -1
  47. package/dist/esm/src/canvas/canvas.type.d.ts +1 -12
  48. package/dist/esm/src/canvas/canvas.type.d.ts.map +1 -1
  49. package/dist/esm/src/canvas/chart.canvas.d.ts +1 -1
  50. package/dist/esm/src/canvas/chart.canvas.d.ts.map +1 -1
  51. package/dist/esm/src/canvas/image.canvas.d.ts +1 -1
  52. package/dist/esm/src/canvas/image.canvas.d.ts.map +1 -1
  53. package/dist/esm/src/canvas/layout.canvas.d.ts +2 -2
  54. package/dist/esm/src/canvas/layout.canvas.d.ts.map +1 -1
  55. package/dist/esm/src/canvas/root.canvas.d.ts +3 -2
  56. package/dist/esm/src/canvas/root.canvas.d.ts.map +1 -1
  57. package/dist/esm/src/canvas/text.canvas.d.ts +1 -1
  58. package/dist/esm/src/canvas/text.canvas.d.ts.map +1 -1
  59. package/dist/esm/src/worker/comlink.pool.d.ts +30 -0
  60. package/dist/esm/src/worker/comlink.pool.d.ts.map +1 -0
  61. package/dist/esm/src/worker/comlink.setup.d.ts +4 -0
  62. package/dist/esm/src/worker/comlink.setup.d.ts.map +1 -0
  63. package/dist/esm/src/worker/worker.types.d.ts +5 -68
  64. package/dist/esm/src/worker/worker.types.d.ts.map +1 -1
  65. package/dist/esm/worker/comlink.pool.js +139 -0
  66. package/dist/esm/worker/comlink.setup.js +30 -0
  67. package/dist/esm/worker/render.worker.js +38 -60
  68. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"root.canvas.js","sources":["../../../../../src/canvas/root.canvas.ts"],"sourcesContent":["import { Canvas, FontLibrary, type CanvasRenderingContext2D } from 'skia-canvas'\nimport type { ExportFormat, ExportOptions, SaveOptions, RenderOptions } from 'skia-canvas'\nimport { ColumnNode, BoxNode, RowNode } from '@/canvas/layout.canvas.js'\nimport type { BaseProps, RootProps, CanvasElement, RootPropsWithWorker, RootPropsWithoutWorker } from '@/canvas/canvas.type.js'\nimport type { CanvasCallMethod, CallArgs, CallResult, WorkerCallRequest, WorkerResponse, WorkerRequest } from '@/worker/worker.types.js'\nimport { ImageNode, type RenderImageCache } from '@/canvas/image.canvas.js'\nimport { deleteDiskCache } from '@/util/disk.cache.js'\nimport { TextNode } from '@/canvas/text.canvas.js'\nimport { ChartNode } from '@/canvas/chart.canvas.js'\nimport { GridNode, GridItemNode } from '@/canvas/grid.canvas.js'\nimport { Style } from '@/constant/common.const.js'\nimport { WorkerPreProcessor } from '@/canvas/canvas.helper.js'\nimport * as path from 'node:path'\nimport * as fs from 'node:fs'\nimport { cpus } from 'node:os'\nimport { Worker } from 'node:worker_threads'\nimport { fileURLToPath } from 'node:url'\n\n/** Registry to track fonts that have already been loaded */\nconst registeredFonts = new Map<string, Set<string>>()\n\n// Exported for testing purposes only\nexport const _clearRegisteredFonts = () => {\n registeredFonts.clear()\n}\n\n/**\n * FinalizationRegistry to clean up WorkerCanvas instances that were not explicitly released.\n * This is a safety net — users should still call .release() explicitly.\n */\nconst canvasRegistry = new FinalizationRegistry<{ workerIdx: number; canvasId: number }>(heldValue => {\n // Best-effort cleanup — worker may already be terminated\n try {\n // Access workers via a public method or make it accessible\n // For now, just try to send the message and let errors be caught\n if (_workerPool) {\n ;(_workerPool as any).workers?.[heldValue.workerIdx]?.postMessage({ type: 'release', canvasId: heldValue.canvasId })\n }\n } catch {\n // Worker already gone — nothing to clean up\n }\n})\n\n/** Engine configuration — legacy support for configure() */\nlet _defaultWorkerMode = true\nlet _defaultWorkerPoolSize = Math.max(1, cpus().length - 1)\nlet _workerPool: WorkerPool | null = null\n\nexport interface CanvasEngineConfig {\n /** Run rendering in worker threads to avoid blocking the event loop (default: true) */\n workerMode?: boolean\n /** Number of worker threads in the pool (default: os.cpus().length - 1) */\n workers?: number\n}\n\n/**\n * Configure the canvas rendering engine.\n * Call this once at application startup before rendering.\n * @deprecated Pass workerMode and workers directly to Root() props instead.\n */\nexport function configure(options: CanvasEngineConfig) {\n if (options.workerMode !== undefined) _defaultWorkerMode = options.workerMode\n if (options.workers !== undefined) _defaultWorkerPoolSize = options.workers\n}\n\n/**\n * Terminate all worker pools and free worker thread resources.\n * Call this when shutting down a long-running server to clean up immediately.\n * After calling, you must call configure() again before rendering.\n */\nexport function terminate() {\n if (_workerPool) {\n _workerPool.terminate()\n _workerPool = null\n }\n}\n\ninterface PendingTask {\n resolve: (value: unknown) => void\n reject: (err: Error) => void\n}\n\ninterface PoolRenderResult {\n buffer: Buffer\n canvasId: number\n workerIdx: number\n width: number\n height: number\n}\n\n/**\n * Proxies all skia-canvas Canvas APIs to a Canvas instance living inside a worker thread.\n * Sync methods (toBufferSync, toURLSync) return from a pre-encoded PNG buffer.\n * Async methods (toBuffer, toURL, toFile, getters) delegate to the worker.\n */\nclass WorkerCanvas {\n readonly width: number\n readonly height: number\n private readonly _buffer: Buffer // pre-encoded PNG for sync use\n private readonly _pool: WorkerPool\n private readonly _workerIdx: number\n private readonly _canvasId: number\n\n constructor(opts: PoolRenderResult & { pool: WorkerPool }) {\n this._buffer = opts.buffer\n this.width = opts.width\n this.height = opts.height\n this._pool = opts.pool\n this._workerIdx = opts.workerIdx\n this._canvasId = opts.canvasId\n // Register for finalizer-based cleanup if user forgets to call .release()\n canvasRegistry.register(this, { workerIdx: opts.workerIdx, canvasId: opts.canvasId }, this)\n }\n\n private _call<M extends CanvasCallMethod>(method: M, ...args: CallArgs<M>): Promise<CallResult<M>> {\n return this._pool.callOnCanvas(this._workerIdx, this._canvasId, method, args)\n }\n\n // --- Sync methods: return from pre-encoded PNG buffer ---\n\n toBufferSync(_format?: ExportFormat, _options?: ExportOptions): Buffer {\n return this._buffer\n }\n\n toURLSync(_format?: ExportFormat, _options?: ExportOptions): string {\n return `data:image/png;base64,${this._buffer.toString('base64')}`\n }\n\n // --- Async methods: delegate to worker ---\n\n toBuffer(format: ExportFormat, options?: ExportOptions): Promise<Buffer> {\n return this._call('toBuffer', format, options)\n }\n\n toURL(format: ExportFormat, options?: ExportOptions): Promise<string> {\n return this._call('toURL', format, options)\n }\n\n toFile(filename: string, options?: SaveOptions): Promise<void> {\n return this._call('toFile', filename, options)\n }\n\n /** Returns a Buffer (Sharp instance cannot be transferred across threads) */\n toSharp(options?: RenderOptions): Promise<Buffer> {\n return this._call('toSharp', options)\n }\n\n toSharpSync(_options?: RenderOptions): never {\n throw new Error('[canvas] toSharpSync() is not available in worker mode — use toSharp() instead')\n }\n\n // --- Async convenience getters ---\n\n get png(): Promise<Buffer> {\n return this._call('toBuffer', 'png')\n }\n get webp(): Promise<Buffer> {\n return this._call('toBuffer', 'webp')\n }\n get jpg(): Promise<Buffer> {\n return this._call('toBuffer', 'jpg')\n }\n get svg(): Promise<Buffer> {\n return this._call('toBuffer', 'svg')\n }\n get pdf(): Promise<Buffer> {\n return this._call('toBuffer', 'pdf')\n }\n get raw(): Promise<Buffer> {\n return this._call('toBuffer', 'raw')\n }\n\n /** Release the Canvas from worker memory. Call when done with this object. */\n release(): void {\n this._pool.releaseCanvas(this._workerIdx, this._canvasId)\n // Unregister from finalizer since we're explicitly cleaning up\n canvasRegistry.unregister(this)\n }\n}\n\n/** Worker thread pool — routes render and canvas-call messages */\nclass WorkerPool {\n private workers: Worker[] = []\n private idle: Worker[] = []\n private queue: Array<{ id: number; props: RootProps }> = []\n private pending = new Map<number, PendingTask>()\n private nextId = 0\n\n constructor(size: number) {\n this.init(size)\n }\n\n private init(size: number) {\n const workerFile = path.join(path.dirname(fileURLToPath(import.meta.url)), '../worker/render.worker.js')\n\n for (let i = 0; i < size; i++) {\n const workerIdx = i\n const worker = new Worker(workerFile)\n worker.on('message', (msg: WorkerResponse) => {\n const task = this.pending.get(msg.taskId)\n if (!task) return\n this.pending.delete(msg.taskId)\n\n if ('error' in msg) {\n task.reject(new Error(msg.error))\n return\n }\n\n if ('canvasId' in msg) {\n // Render complete — put worker back to idle\n this.idle.push(worker)\n this.drain()\n const result: PoolRenderResult = { buffer: msg.buffer, canvasId: msg.canvasId, workerIdx, width: msg.width, height: msg.height }\n task.resolve(result)\n } else {\n // Canvas method call complete\n task.resolve(msg.result)\n }\n })\n this.workers.push(worker)\n this.idle.push(worker)\n }\n }\n\n private drain() {\n while (this.queue.length > 0 && this.idle.length > 0) {\n const task = this.queue.shift()!\n const worker = this.idle.pop()!\n const request: WorkerRequest = { type: 'render', taskId: task.id, props: task.props }\n worker.postMessage(request)\n }\n }\n\n render(props: RootProps): Promise<PoolRenderResult> {\n const sanitizedProps = WorkerPreProcessor.process(props)\n return new Promise<PoolRenderResult>((resolve, reject) => {\n const id = this.nextId++\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject })\n if (this.idle.length > 0) {\n const worker = this.idle.pop()!\n const request: WorkerRequest = { type: 'render', taskId: id, props: sanitizedProps }\n worker.postMessage(request)\n } else {\n this.queue.push({ id, props: sanitizedProps })\n }\n })\n }\n\n callOnCanvas<M extends CanvasCallMethod>(workerIdx: number, canvasId: number, method: M, args: CallArgs<M>): Promise<CallResult<M>> {\n return new Promise<CallResult<M>>((resolve, reject) => {\n const id = this.nextId++\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject })\n const request = { type: 'call' as const, taskId: id, canvasId, method, args } as WorkerCallRequest\n this.workers[workerIdx].postMessage(request)\n })\n }\n\n releaseCanvas(workerIdx: number, canvasId: number): void {\n const request: WorkerRequest = { type: 'release', canvasId }\n this.workers[workerIdx]?.postMessage(request)\n }\n\n terminate() {\n this.workers.forEach(w => w.terminate())\n }\n}\n\n/**\n * Converts a CanvasElement tree into actual BoxNode instances.\n * Used both for non-worker rendering (inline tree building) and inside\n * the render worker (reconstructing the tree from serialized descriptors).\n */\nexport function buildTree(descriptor: CanvasElement): BoxNode {\n switch (descriptor.__type) {\n case 'Box':\n return new BoxNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Column':\n return new ColumnNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Row':\n return new RowNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Grid':\n return new GridNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) as any })\n case 'GridItem':\n return new GridItemNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) as any })\n case 'Image':\n return new ImageNode(descriptor.props as any)\n case 'Text':\n return new TextNode(descriptor.text, descriptor.props)\n case 'Chart':\n return new ChartNode(descriptor.props as any)\n }\n}\n\n/**\n * Root node that manages the canvas rendering context and coordinates overall layout and drawing.\n * Inherits from ColumnNode to provide vertical layout capabilities.\n */\nexport class RootNode extends ColumnNode {\n declare props: RootProps & BaseProps\n /** The canvas instance used for rendering */\n private canvas: Canvas | undefined\n /** The 2D rendering context for the canvas */\n private ctx: CanvasRenderingContext2D | null = null\n /** Target width for the canvas in pixels */\n private readonly targetWidth: number\n /** Target height for the canvas in pixels */\n private readonly targetHeight: number | undefined\n /** Scale factor for rendering (e.g. 2 for 2x resolution) */\n private readonly scale: number\n\n /**\n * Creates a new root node for canvas rendering\n * @param props Configuration properties for the root node\n * @throws Error if width property is not provided\n */\n constructor(props: RootProps & BaseProps) {\n // Call the parent constructor with root name and props\n super({ name: 'Root', ...props })\n\n this.props = props\n\n // Validate the required width property\n if (!props.width) {\n throw new Error('Width and height are required for Root')\n }\n\n // Register provided fonts with caching\n if (props.fonts?.length) {\n for (const font of props.fonts) {\n const family = font.family\n const paths = font.paths.map(p => path.resolve(p))\n\n if (!registeredFonts.has(family)) {\n registeredFonts.set(family, new Set())\n }\n\n const cachedPaths = registeredFonts.get(family)!\n const newPaths = paths.filter(p => !cachedPaths.has(p) && fs.existsSync(p))\n\n if (newPaths.length > 0) {\n FontLibrary.use({ [family]: newPaths })\n newPaths.forEach(p => cachedPaths.add(p))\n }\n }\n }\n\n // Set up scale and width\n this.scale = props.scale || 1\n this.targetWidth = props.width\n this.targetHeight = props.height\n this.node.setWidth(this.targetWidth)\n\n // Convert any CanvasElement children to actual BoxNode instances\n if (this.props.children) {\n const childArray = Array.isArray(this.props.children) ? this.props.children : [this.props.children]\n this.props.children = childArray.map(child => {\n if (child && typeof child === 'object' && '__type' in child) {\n return buildTree(child as CanvasElement)\n }\n return child\n }) as any\n }\n\n // Initialize children nodes\n this.processInitialChildren()\n }\n\n /**\n * Traverses the node tree to find all ImageNode instances using breadth-first search\n * @returns Array of all ImageNode instances found in the tree\n */\n private findAllImageNodes(): ImageNode[] {\n const imageNodes: ImageNode[] = []\n const queue: BoxNode[] = [this]\n while (queue.length > 0) {\n const node = queue.shift()!\n if (node instanceof ImageNode) {\n imageNodes.push(node)\n }\n queue.push(...node.children)\n }\n return imageNodes\n }\n\n /**\n * Renders the entire node tree to a canvas, handling image loading, layout calculation,\n * and final drawing\n * @returns Promise resolving to the rendered Canvas instance\n */\n async render(): Promise<Canvas> {\n const diskCacheKeys = this.props.useDiskCache ? new Set<string>() : undefined\n\n try {\n // Step 1: Load all images with a concurrency limit to avoid overwhelming remote sources.\n // A per-render cache deduplicates identical src+color combinations within this render pass.\n const imageNodes = this.findAllImageNodes()\n if (imageNodes.length > 0) {\n const imageCache: RenderImageCache = new Map()\n const CONCURRENCY = 5\n const queue = [...imageNodes]\n const workers = Array.from({ length: Math.min(CONCURRENCY, queue.length) }, async () => {\n while (queue.length > 0) {\n const node = queue.shift()!\n await node.load(imageCache, diskCacheKeys)\n }\n })\n await Promise.allSettled(workers)\n }\n\n // Step 2: Calculate initial layout\n this.node.calculateLayout(this.targetWidth, undefined, Style.Direction.LTR)\n\n // Step 3: Allow nodes to finalize their layout\n const needRecalculate = this.finalizeLayout()\n if (needRecalculate) {\n this.node.calculateLayout(this.targetWidth, undefined, Style.Direction.LTR)\n }\n\n // Step 4: Create a canvas with calculated dimensions\n const calculatedContentHeight = this.node.getComputedHeight()\n const finalCanvasWidth = Math.ceil(this.targetWidth * this.scale)\n const finalCanvasHeight = this.targetHeight ? Math.ceil(this.targetHeight * this.scale) : Math.max(1, Math.ceil(calculatedContentHeight * this.scale))\n\n // Step 5: Set up canvas context\n this.canvas = new Canvas(finalCanvasWidth, finalCanvasHeight)\n this.ctx = this.canvas.getContext('2d')\n this.ctx.scale(this.scale, this.scale)\n\n // Step 6: Render content\n super.render(this.ctx, 0, 0)\n\n if (!this.canvas) {\n throw new Error('Canvas not initialized')\n }\n\n return this.canvas\n } finally {\n if (diskCacheKeys?.size) {\n await Promise.allSettled([...diskCacheKeys].map(key => deleteDiskCache(key)))\n }\n }\n }\n}\n\n/**\n * Creates and renders a new root node with the given properties.\n * Rendering runs in worker threads by default for non-blocking operation.\n * @example\n * // Worker mode (default) - .release() available\n * const canvas = await Root({ width: 400, children: [...] })\n * canvas.release() // ✓ OK\n * @example\n * // Worker mode explicit - .release() available\n * const canvas = await Root({ width: 400, workerMode: true, workers: 2 })\n * canvas.release() // ✓ OK\n * @example\n * // Non-worker mode - .release() NOT available, workers not allowed\n * const canvas = await Root({ width: 400, workerMode: false })\n * canvas.release() // ✗ TypeScript error\n * @param props Configuration properties for the root node\n * @returns Canvas with .release() in worker mode, plain Canvas otherwise\n */\nexport function Root(props: RootPropsWithWorker): Promise<Canvas & { release(): void }>\nexport function Root(props: RootPropsWithoutWorker): Promise<Canvas>\nexport async function Root(props: RootProps): Promise<Canvas | (Canvas & { release(): void })> {\n // Determine worker mode: props override legacy configure()\n const workerMode = props.workerMode ?? _defaultWorkerMode\n const workerPoolSize = props.workers ?? _defaultWorkerPoolSize\n\n if (workerMode) {\n // Lazy initialize worker pool\n if (!_workerPool) {\n _workerPool = new WorkerPool(workerPoolSize)\n }\n const result = await _workerPool.render(props)\n return new WorkerCanvas({ ...result, pool: _workerPool }) as unknown as Canvas & { release(): void }\n }\n\n // Non-worker mode — render directly and return Canvas\n return new RootNode(props).render()\n}\n"],"names":["cpus","path","fileURLToPath","Worker","WorkerPreProcessor","BoxNode","ColumnNode","RowNode","GridNode","GridItemNode","ImageNode","TextNode","ChartNode","fs","FontLibrary","Style","Canvas","deleteDiskCache"],"mappings":"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"}
1
+ {"version":3,"file":"root.canvas.js","sources":["../../../../../src/canvas/root.canvas.ts"],"sourcesContent":["import { Canvas, FontLibrary, type CanvasRenderingContext2D } from 'skia-canvas'\nimport type { ExportFormat, ExportOptions, SaveOptions, RenderOptions } from 'skia-canvas'\nimport { ColumnNode, BoxNode, RowNode } from '@/canvas/layout.canvas.js'\nimport type { BaseProps, RootProps, CanvasElement, RootPropsWithWorker, RootPropsWithoutWorker } from '@/canvas/canvas.type.js'\nimport type { ComlinkPool as ComlinkPoolType, PoolRenderResult } from '@/worker/comlink.pool.js'\nimport { ImageNode, type RenderImageCache } from '@/canvas/image.canvas.js'\nimport { deleteDiskCache } from '@/util/disk.cache.js'\nimport { TextNode } from '@/canvas/text.canvas.js'\nimport { ChartNode } from '@/canvas/chart.canvas.js'\nimport { GridNode, GridItemNode } from '@/canvas/grid.canvas.js'\nimport { Style } from '@/constant/common.const.js'\nimport * as path from 'node:path'\nimport * as fs from 'node:fs'\nimport { cpus } from 'node:os'\n\n/** Registry to track fonts that have already been loaded */\nconst registeredFonts = new Map<string, Set<string>>()\n\n// Exported for testing purposes only\nexport const _clearRegisteredFonts = () => {\n registeredFonts.clear()\n}\n\n/**\n * FinalizationRegistry to clean up WorkerCanvas instances that were not explicitly released.\n * This is a safety net — users should still call .release() explicitly.\n */\nconst canvasRegistry = new FinalizationRegistry<{ workerIdx: number; canvasId: number }>(heldValue => {\n try {\n _workerPool?.releaseCanvas(heldValue.workerIdx, heldValue.canvasId)\n } catch {\n // Worker already gone — nothing to clean up\n }\n})\n\n/** Engine configuration — legacy support for configure() */\nlet _defaultWorkerMode = true\nlet _defaultWorkerPoolSize = Math.max(1, cpus().length - 1)\nlet _workerPool: ComlinkPoolType | null = null\n\nexport interface CanvasEngineConfig {\n /** Run rendering in worker threads to avoid blocking the event loop (default: true) */\n workerMode?: boolean\n /** Number of worker threads in the pool (default: os.cpus().length - 1) */\n workers?: number\n}\n\n/**\n * Configure the canvas rendering engine.\n * Call this once at application startup before rendering.\n * @deprecated Pass workerMode and workers directly to Root() props instead.\n */\nexport function configure(options: CanvasEngineConfig) {\n if (options.workerMode !== undefined) _defaultWorkerMode = options.workerMode\n if (options.workers !== undefined) _defaultWorkerPoolSize = options.workers\n}\n\n/**\n * Terminate all worker pools and free worker thread resources.\n * Call this when shutting down a long-running server to clean up immediately.\n * After calling, you must call configure() again before rendering.\n */\nexport function terminate() {\n if (_workerPool) {\n _workerPool.terminate()\n _workerPool = null\n }\n}\n\n/**\n * Proxies all skia-canvas Canvas APIs to a Canvas instance living inside a worker thread.\n * Sync methods (toBufferSync, toURLSync) return from a pre-encoded PNG buffer.\n * Async methods (toBuffer, toURL, toFile, getters) delegate to the worker.\n */\nclass WorkerCanvas {\n readonly width: number\n readonly height: number\n private readonly _buffer: Buffer\n private readonly _pool: ComlinkPoolType\n private readonly _workerIdx: number\n private readonly _canvasId: number\n\n constructor(opts: PoolRenderResult & { pool: ComlinkPoolType }) {\n this._buffer = opts.buffer\n this.width = opts.width\n this.height = opts.height\n this._pool = opts.pool\n this._workerIdx = opts.workerIdx\n this._canvasId = opts.canvasId\n canvasRegistry.register(this, { workerIdx: opts.workerIdx, canvasId: opts.canvasId }, this)\n }\n\n // --- Sync methods: return from pre-encoded PNG buffer ---\n\n toBufferSync(_format?: ExportFormat, _options?: ExportOptions): Buffer {\n return this._buffer\n }\n\n toURLSync(_format?: ExportFormat, _options?: ExportOptions): string {\n return `data:image/png;base64,${this._buffer.toString('base64')}`\n }\n\n // --- Async methods: delegate to worker via Comlink ---\n\n toBuffer(format: ExportFormat, options?: ExportOptions): Promise<Buffer> {\n return this._pool.callOnCanvas(this._workerIdx, this._canvasId, 'toBuffer', [format, options]) as Promise<Buffer>\n }\n\n toURL(format: ExportFormat, options?: ExportOptions): Promise<string> {\n return this._pool.callOnCanvas(this._workerIdx, this._canvasId, 'toURL', [format, options]) as Promise<string>\n }\n\n toFile(filename: string, options?: SaveOptions): Promise<void> {\n return this._pool.callOnCanvas(this._workerIdx, this._canvasId, 'toFile', [filename, options]) as Promise<void>\n }\n\n toSharp(options?: RenderOptions): Promise<Buffer> {\n return this._pool.callOnCanvas(this._workerIdx, this._canvasId, 'toSharp', [options]) as Promise<Buffer>\n }\n\n toSharpSync(_options?: RenderOptions): never {\n throw new Error('[canvas] toSharpSync() is not available in worker mode — use toSharp() instead')\n }\n\n // --- Async convenience getters ---\n\n get png(): Promise<Buffer> {\n return this.toBuffer('png')\n }\n get webp(): Promise<Buffer> {\n return this.toBuffer('webp')\n }\n get jpg(): Promise<Buffer> {\n return this.toBuffer('jpg')\n }\n get svg(): Promise<Buffer> {\n return this.toBuffer('svg')\n }\n get pdf(): Promise<Buffer> {\n return this.toBuffer('pdf')\n }\n get raw(): Promise<Buffer> {\n return this.toBuffer('raw')\n }\n\n /** Release the Canvas from worker memory. Call when done with this object. */\n release(): void {\n this._pool.releaseCanvas(this._workerIdx, this._canvasId)\n canvasRegistry.unregister(this)\n }\n}\n\n/**\n * Converts a CanvasElement tree into actual BoxNode instances.\n * Used both for non-worker rendering (inline tree building) and inside\n * the render worker (reconstructing the tree from serialized descriptors).\n */\nexport function buildTree(descriptor: CanvasElement): BoxNode {\n switch (descriptor.__type) {\n case 'Box':\n return new BoxNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Column':\n return new ColumnNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Row':\n return new RowNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) })\n case 'Grid':\n return new GridNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) as any })\n case 'GridItem':\n return new GridItemNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) as any })\n case 'Image':\n return new ImageNode(descriptor.props as any)\n case 'Text':\n return new TextNode(descriptor.text, descriptor.props)\n case 'Chart':\n return new ChartNode(descriptor.props as any)\n }\n}\n\n/**\n * Root node that manages the canvas rendering context and coordinates overall layout and drawing.\n * Inherits from ColumnNode to provide vertical layout capabilities.\n */\nexport class RootNode extends ColumnNode {\n declare props: RootProps & BaseProps\n /** The canvas instance used for rendering */\n private canvas: Canvas | undefined\n /** The 2D rendering context for the canvas */\n private ctx: CanvasRenderingContext2D | null = null\n /** Target width for the canvas in pixels */\n private readonly targetWidth: number\n /** Target height for the canvas in pixels */\n private readonly targetHeight: number | undefined\n /** Scale factor for rendering (e.g. 2 for 2x resolution) */\n private readonly scale: number\n\n /**\n * Creates a new root node for canvas rendering\n * @param props Configuration properties for the root node\n * @throws Error if width property is not provided\n */\n constructor(props: RootProps & BaseProps) {\n // Call the parent constructor with root name and props\n super({ name: 'Root', ...props })\n\n this.props = props\n\n // Validate the required width property\n if (!props.width) {\n throw new Error('Width and height are required for Root')\n }\n\n // Register provided fonts with caching\n if (props.fonts?.length) {\n for (const font of props.fonts) {\n const family = font.family\n const paths = font.paths.map(p => path.resolve(p))\n\n if (!registeredFonts.has(family)) {\n registeredFonts.set(family, new Set())\n }\n\n const cachedPaths = registeredFonts.get(family)!\n const newPaths = paths.filter(p => !cachedPaths.has(p) && fs.existsSync(p))\n\n if (newPaths.length > 0) {\n FontLibrary.use({ [family]: newPaths })\n newPaths.forEach(p => cachedPaths.add(p))\n }\n }\n }\n\n // Set up scale and width\n this.scale = props.scale || 1\n this.targetWidth = props.width\n this.targetHeight = props.height\n this.node.setWidth(this.targetWidth)\n\n // Convert any CanvasElement children to actual BoxNode instances\n if (this.props.children) {\n const childArray = Array.isArray(this.props.children) ? this.props.children : [this.props.children]\n this.props.children = childArray.map(child => {\n if (child && typeof child === 'object' && '__type' in child) {\n return buildTree(child as CanvasElement)\n }\n return child\n }) as any\n }\n\n // Initialize children nodes\n this.processInitialChildren()\n }\n\n /**\n * Traverses the node tree to find all ImageNode instances using breadth-first search\n * @returns Array of all ImageNode instances found in the tree\n */\n private findAllImageNodes(): ImageNode[] {\n const imageNodes: ImageNode[] = []\n const queue: BoxNode[] = [this]\n while (queue.length > 0) {\n const node = queue.shift()!\n if (node instanceof ImageNode) {\n imageNodes.push(node)\n }\n queue.push(...node.children)\n }\n return imageNodes\n }\n\n /**\n * Renders the entire node tree to a canvas, handling image loading, layout calculation,\n * and final drawing\n * @returns Promise resolving to the rendered Canvas instance\n */\n override async render(ctx: CanvasRenderingContext2D, offsetX?: number, offsetY?: number): Promise<void>\n async render(ctx?: CanvasRenderingContext2D, offsetX?: number, offsetY?: number): Promise<Canvas>\n async render(ctx?: CanvasRenderingContext2D, offsetX = 0, offsetY = 0): Promise<Canvas | void> {\n // If ctx is provided, delegate to parent render (used when called as a child node)\n if (ctx) {\n await super.render(ctx, offsetX, offsetY)\n return\n }\n\n const diskCacheKeys = this.props.useDiskCache ? new Set<string>() : undefined\n\n try {\n // Step 1: Load all images with a concurrency limit to avoid overwhelming remote sources.\n // A per-render cache deduplicates identical src+color combinations within this render pass.\n const imageNodes = this.findAllImageNodes()\n if (imageNodes.length > 0) {\n const imageCache: RenderImageCache = new Map()\n const CONCURRENCY = 5\n const queue = [...imageNodes]\n const workers = Array.from({ length: Math.min(CONCURRENCY, queue.length) }, async () => {\n while (queue.length > 0) {\n const node = queue.shift()!\n await node.load(imageCache, diskCacheKeys)\n }\n })\n await Promise.allSettled(workers)\n }\n\n // Step 2: Calculate initial layout\n this.node.calculateLayout(this.targetWidth, undefined, Style.Direction.LTR)\n\n // Step 3: Allow nodes to finalize their layout\n const needRecalculate = this.finalizeLayout()\n if (needRecalculate) {\n this.node.calculateLayout(this.targetWidth, undefined, Style.Direction.LTR)\n }\n\n // Step 4: Create a canvas with calculated dimensions\n const calculatedContentHeight = this.node.getComputedHeight()\n const finalCanvasWidth = Math.ceil(this.targetWidth * this.scale)\n const finalCanvasHeight = this.targetHeight ? Math.ceil(this.targetHeight * this.scale) : Math.max(1, Math.ceil(calculatedContentHeight * this.scale))\n\n // Step 5: Set up canvas context\n this.canvas = new Canvas(finalCanvasWidth, finalCanvasHeight)\n this.ctx = this.canvas.getContext('2d')\n this.ctx.scale(this.scale, this.scale)\n\n // Step 6: Render content\n await super.render(this.ctx, 0, 0)\n\n if (!this.canvas) {\n throw new Error('Canvas not initialized')\n }\n\n return this.canvas\n } finally {\n if (diskCacheKeys?.size) {\n await Promise.allSettled([...diskCacheKeys].map(key => deleteDiskCache(key)))\n }\n }\n }\n}\n\n/**\n * Creates and renders a new root node with the given properties.\n * Rendering runs in worker threads by default for non-blocking operation.\n * @example\n * // Worker mode (default) - .release() available\n * const canvas = await Root({ width: 400, children: [...] })\n * canvas.release() // ✓ OK\n * @example\n * // Worker mode explicit - .release() available\n * const canvas = await Root({ width: 400, workerMode: true, workers: 2 })\n * canvas.release() // ✓ OK\n * @example\n * // Non-worker mode - .release() NOT available, workers not allowed\n * const canvas = await Root({ width: 400, workerMode: false })\n * canvas.release() // ✗ TypeScript error\n * @param props Configuration properties for the root node\n * @returns Canvas with .release() in worker mode, plain Canvas otherwise\n */\nexport function Root(props: RootPropsWithWorker): Promise<Canvas & { release(): void }>\nexport function Root(props: RootPropsWithoutWorker): Promise<Canvas>\nexport async function Root(props: RootProps): Promise<Canvas | (Canvas & { release(): void })> {\n // Determine worker mode: props override legacy configure()\n const workerMode = props.workerMode ?? _defaultWorkerMode\n const workerPoolSize = props.workers ?? _defaultWorkerPoolSize\n\n if (workerMode) {\n // Lazy initialize worker pool — dynamic import to avoid loading Comlink in non-worker contexts\n if (!_workerPool) {\n const { ComlinkPool } = await import('@/worker/comlink.pool.js')\n _workerPool = new ComlinkPool(workerPoolSize)\n }\n const result = await _workerPool.render(props)\n return new WorkerCanvas({ ...result, pool: _workerPool }) as unknown as Canvas & { release(): void }\n }\n\n // Non-worker mode — render directly and return Canvas\n return new RootNode(props).render()\n}\n"],"names":["cpus","BoxNode","ColumnNode","RowNode","GridNode","GridItemNode","ImageNode","TextNode","ChartNode","path","fs","FontLibrary","Style","Canvas","deleteDiskCache"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA;AACA,MAAM,eAAe,GAAG,IAAI,GAAG,EAAuB;AAOtD;;;AAGG;AACH,MAAM,cAAc,GAAG,IAAI,oBAAoB,CAA0C,SAAS,IAAG;AACnG,IAAA,IAAI;QACF,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC;IACrE;AAAE,IAAA,MAAM;;IAER;AACF,CAAC,CAAC;AAEF;AACA,IAAI,kBAAkB,GAAG,IAAI;AAC7B,IAAI,sBAAsB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAEA,YAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3D,IAAI,WAAW,GAA2B,IAAI;AAS9C;;;;AAIG;AACG,SAAU,SAAS,CAAC,OAA2B,EAAA;AACnD,IAAA,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;AAAE,QAAA,kBAAkB,GAAG,OAAO,CAAC,UAAU;AAC7E,IAAA,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;AAAE,QAAA,sBAAsB,GAAG,OAAO,CAAC,OAAO;AAC7E;AAEA;;;;AAIG;SACa,SAAS,GAAA;IACvB,IAAI,WAAW,EAAE;QACf,WAAW,CAAC,SAAS,EAAE;QACvB,WAAW,GAAG,IAAI;IACpB;AACF;AAEA;;;;AAIG;AACH,MAAM,YAAY,CAAA;AACP,IAAA,KAAK;AACL,IAAA,MAAM;AACE,IAAA,OAAO;AACP,IAAA,KAAK;AACL,IAAA,UAAU;AACV,IAAA,SAAS;AAE1B,IAAA,WAAA,CAAY,IAAkD,EAAA;AAC5D,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM;AAC1B,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;AACvB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;AACzB,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS;AAChC,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ;QAC9B,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC;IAC7F;;IAIA,YAAY,CAAC,OAAsB,EAAE,QAAwB,EAAA;QAC3D,OAAO,IAAI,CAAC,OAAO;IACrB;IAEA,SAAS,CAAC,OAAsB,EAAE,QAAwB,EAAA;QACxD,OAAO,CAAA,sBAAA,EAAyB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA,CAAE;IACnE;;IAIA,QAAQ,CAAC,MAAoB,EAAE,OAAuB,EAAA;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAoB;IACnH;IAEA,KAAK,CAAC,MAAoB,EAAE,OAAuB,EAAA;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAoB;IAChH;IAEA,MAAM,CAAC,QAAgB,EAAE,OAAqB,EAAA;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAkB;IACjH;AAEA,IAAA,OAAO,CAAC,OAAuB,EAAA;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,CAAoB;IAC1G;AAEA,IAAA,WAAW,CAAC,QAAwB,EAAA;AAClC,QAAA,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC;IACnG;;AAIA,IAAA,IAAI,GAAG,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B;AACA,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B;AACA,IAAA,IAAI,GAAG,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B;AACA,IAAA,IAAI,GAAG,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B;AACA,IAAA,IAAI,GAAG,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B;AACA,IAAA,IAAI,GAAG,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B;;IAGA,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;AACzD,QAAA,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC;IACjC;AACD;AAED;;;;AAIG;AACG,SAAU,SAAS,CAAC,UAAyB,EAAA;AACjD,IAAA,QAAQ,UAAU,CAAC,MAAM;AACvB,QAAA,KAAK,KAAK;YACR,OAAO,IAAIC,qBAAO,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;AAC5F,QAAA,KAAK,QAAQ;YACX,OAAO,IAAIC,wBAAU,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;AAC/F,QAAA,KAAK,KAAK;YACR,OAAO,IAAIC,qBAAO,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;AAC5F,QAAA,KAAK,MAAM;YACT,OAAO,IAAIC,oBAAQ,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAQ,EAAE,CAAC;AACpG,QAAA,KAAK,UAAU;YACb,OAAO,IAAIC,wBAAY,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAQ,EAAE,CAAC;AACxG,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,IAAIC,sBAAS,CAAC,UAAU,CAAC,KAAY,CAAC;AAC/C,QAAA,KAAK,MAAM;YACT,OAAO,IAAIC,oBAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC;AACxD,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,IAAIC,sBAAS,CAAC,UAAU,CAAC,KAAY,CAAC;;AAEnD;AAEA;;;AAGG;AACG,MAAO,QAAS,SAAQN,wBAAU,CAAA;;AAG9B,IAAA,MAAM;;IAEN,GAAG,GAAoC,IAAI;;AAElC,IAAA,WAAW;;AAEX,IAAA,YAAY;;AAEZ,IAAA,KAAK;AAEtB;;;;AAIG;AACH,IAAA,WAAA,CAAY,KAA4B,EAAA;;QAEtC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;AAEjC,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;;AAGlB,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AAChB,YAAA,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC;QAC3D;;AAGA,QAAA,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE;AACvB,YAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AAC9B,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;AAC1B,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAIO,eAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAElD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;oBAChC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACxC;gBAEA,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAE;gBAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAIC,aAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAE3E,gBAAA,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;oBACvBC,sBAAW,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;AACvC,oBAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC3C;YACF;QACF;;QAGA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC;AAC7B,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK;AAC9B,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM;QAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;;AAGpC,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,YAAA,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACnG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,IAAG;gBAC3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE;AAC3D,oBAAA,OAAO,SAAS,CAAC,KAAsB,CAAC;gBAC1C;AACA,gBAAA,OAAO,KAAK;AACd,YAAA,CAAC,CAAQ;QACX;;QAGA,IAAI,CAAC,sBAAsB,EAAE;IAC/B;AAEA;;;AAGG;IACK,iBAAiB,GAAA;QACvB,MAAM,UAAU,GAAgB,EAAE;AAClC,QAAA,MAAM,KAAK,GAAc,CAAC,IAAI,CAAC;AAC/B,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AACvB,YAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG;AAC3B,YAAA,IAAI,IAAI,YAAYL,sBAAS,EAAE;AAC7B,gBAAA,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB;YACA,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B;AACA,QAAA,OAAO,UAAU;IACnB;IASA,MAAM,MAAM,CAAC,GAA8B,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAA;;QAEnE,IAAI,GAAG,EAAE;YACP,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;YACzC;QACF;AAEA,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,GAAG,EAAU,GAAG,SAAS;AAE7E,QAAA,IAAI;;;AAGF,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC3C,YAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;AACzB,gBAAA,MAAM,UAAU,GAAqB,IAAI,GAAG,EAAE;gBAC9C,MAAM,WAAW,GAAG,CAAC;AACrB,gBAAA,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC;gBAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,YAAW;AACrF,oBAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AACvB,wBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG;wBAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;oBAC5C;AACF,gBAAA,CAAC,CAAC;AACF,gBAAA,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;YACnC;;AAGA,YAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAEM,kBAAK,CAAC,SAAS,CAAC,GAAG,CAAC;;AAG3E,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE;YAC7C,IAAI,eAAe,EAAE;AACnB,gBAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAEA,kBAAK,CAAC,SAAS,CAAC,GAAG,CAAC;YAC7E;;YAGA,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;AAC7D,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;AACjE,YAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;;YAGtJ,IAAI,CAAC,MAAM,GAAG,IAAIC,iBAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;YAC7D,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;AACvC,YAAA,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC;;AAGtC,YAAA,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AAElC,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAChB,gBAAA,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC;YAC3C;YAEA,OAAO,IAAI,CAAC,MAAM;QACpB;gBAAU;AACR,YAAA,IAAI,aAAa,EAAE,IAAI,EAAE;gBACvB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,IAAIC,0BAAe,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/E;QACF;IACF;AACD;AAsBM,eAAe,IAAI,CAAC,KAAgB,EAAA;;AAEzC,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,kBAAkB;AACzD,IAAA,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,IAAI,sBAAsB;IAE9D,IAAI,UAAU,EAAE;;QAEd,IAAI,CAAC,WAAW,EAAE;YAChB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,oDAAO,2BAA0B,KAAC;AAChE,YAAA,WAAW,GAAG,IAAI,WAAW,CAAC,cAAc,CAAC;QAC/C;QACA,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;AAC9C,QAAA,OAAO,IAAI,YAAY,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAA4C;IACtG;;IAGA,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;AACrC;;;;;;;;"}
@@ -818,8 +818,8 @@ class TextNode extends layout_canvas.BoxNode {
818
818
  * @param width Content box total width including padding
819
819
  * @param height Content box total height including padding
820
820
  */
821
- _renderContent(ctx, x, y, width, height) {
822
- super._renderContent(ctx, x, y, width, height);
821
+ async _renderContent(ctx, x, y, width, height) {
822
+ await super._renderContent(ctx, x, y, width, height);
823
823
  ctx.save();
824
824
  ctx.textBaseline = 'alphabetic';
825
825
  ctx.letterSpacing = this.formatSpacing(this.props.letterSpacing);
@@ -1 +1 @@
1
- {"version":3,"file":"text.canvas.js","sources":["../../../../../src/canvas/text.canvas.ts"],"sourcesContent":["import type { TextProps, TextSegment, CanvasElement } from '@/canvas/canvas.type.js'\nimport { Canvas, type CanvasRenderingContext2D, type FontVariantSetting } from 'skia-canvas'\nimport { BoxNode } from '@/canvas/layout.canvas.js'\nimport { Style, MeasureMode } from '@/constant/common.const.js'\n\n/**\n * Node for rendering text content with rich text styling support\n * Supports color and weight variations through HTML-like tags\n */\nexport class TextNode extends BoxNode {\n private readonly segments: TextSegment[] = []\n private lines: TextSegment[][] = []\n private static measurementContext: CanvasRenderingContext2D | null = null\n private readonly metricsString = 'Ag|``'\n private lineHeights: number[] = []\n private lineAscents: number[] = []\n private lineContentHeights: number[] = []\n\n declare props: TextProps & { lineGap: number }\n\n constructor(text: number | string = '', props: TextProps = {}) {\n const initialProps = {\n name: 'TextNode',\n flexShrink: 1,\n lineGap: 0,\n ...props,\n children: undefined,\n }\n super(initialProps)\n this.props = initialProps\n // Process escape sequences before parsing rich text\n const processedText = this.processEscapeSequences(String(text ?? ''))\n this.segments = this.parseRichText(processedText, {\n color: this.props.color,\n weight: this.props.fontWeight,\n size: this.props.fontSize,\n b: this.props.fontWeight === 'bold',\n i: this.props.fontStyle === 'italic',\n })\n this.node.setMeasureFunc(this.measureText.bind(this))\n this.applyDefaults()\n }\n\n /**\n * Renders a simple, single-line text string without complex layout calculations.\n * A lightweight, static utility for drawing text where layout is handled externally.\n * @param ctx The canvas rendering context.\n * @param text The string to render.\n * @param x The x-coordinate for rendering.\n * @param y The y-coordinate for rendering.\n * @param props Basic text styling properties.\n */\n public static renderSimpleText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n props: {\n fontFamily?: string\n fontSize?: number\n fontWeight?: TextProps['fontWeight']\n fontStyle?: TextProps['fontStyle']\n color?: string\n textAlign?: CanvasRenderingContext2D['textAlign']\n textBaseline?: CanvasRenderingContext2D['textBaseline']\n } = {},\n ) {\n ctx.save()\n\n const {\n fontFamily = 'sans-serif',\n fontSize = 12,\n fontWeight = 'normal',\n fontStyle = 'normal',\n color = '#333',\n textAlign = 'left',\n textBaseline = 'alphabetic',\n } = props\n\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`\n ctx.fillStyle = color\n ctx.textAlign = textAlign\n ctx.textBaseline = textBaseline\n\n ctx.fillText(text, x, y)\n\n ctx.restore()\n }\n\n protected override applyDefaults(): void {\n const textDefaults: Required<\n Pick<TextProps, 'fontSize' | 'fontFamily' | 'fontWeight' | 'fontStyle' | 'color' | 'textAlign' | 'verticalAlign' | 'ellipsis' | 'lineGap'>\n > & {\n lineHeight: undefined | number\n maxLines: undefined | number\n letterSpacing: undefined | number\n wordSpacing: undefined | number\n fontVariant: undefined | FontVariantSetting\n } = {\n fontSize: 16,\n fontFamily: 'sans-serif',\n fontWeight: 'normal',\n fontStyle: 'normal',\n color: 'black',\n textAlign: 'left',\n verticalAlign: 'top',\n fontVariant: undefined,\n lineHeight: undefined,\n lineGap: 0,\n maxLines: undefined,\n ellipsis: false,\n letterSpacing: undefined,\n wordSpacing: undefined,\n }\n\n let defaultsApplied = false\n for (const key of Object.keys(textDefaults) as (keyof typeof textDefaults)[]) {\n if (this.props[key] === undefined && textDefaults[key] !== undefined) {\n ;(this.props as unknown as Record<string, unknown>)[key] = textDefaults[key]\n defaultsApplied = true\n }\n }\n\n if (defaultsApplied && !this.node.isDirty()) {\n const affectsMeasurement = [\n 'fontSize',\n 'fontFamily',\n 'fontWeight',\n 'fontStyle',\n 'lineHeight',\n 'maxLines',\n 'lineGap',\n 'letterSpacing',\n 'wordSpacing',\n ].some(measureKey => this.props[measureKey as keyof typeof textDefaults] === textDefaults[measureKey as keyof typeof textDefaults])\n if (affectsMeasurement) {\n this.node.markDirty()\n }\n }\n }\n\n /**\n * Processes Unix-like escape sequences in text strings.\n * Converts escaped characters into their actual representations.\n *\n * Supported escape sequences:\n * - \\n - Newline (line feed)\n * - \\t - Tab (converted to 4 spaces)\n * - \\r - Carriage return (treated as newline)\n * - \\\\ - Literal backslash\n * - \\' - Single quote\n * - \\\" - Double quote\n * - \\0 - Null character (removed)\n * - \\b - Backspace (removed)\n * - \\f - Form feed (treated as newline)\n * - \\v - Vertical tab (treated as newline)\n * @param input Raw text string potentially containing escape sequences\n * @returns Processed string with escape sequences converted\n */\n private processEscapeSequences(input: string): string {\n return input.replace(/\\\\(.)/g, (match, char) => {\n switch (char) {\n case 'n':\n return '\\n' // Newline\n case 't':\n return ' ' // Tab as 4 spaces\n case 'r':\n return '\\n' // Carriage return treated as newline\n case '\\\\':\n return '\\\\' // Literal backslash\n case \"'\":\n return \"'\" // Single quote\n case '\"':\n return '\"' // Double quote\n case '0':\n return '' // Null character (remove)\n case 'b':\n return '' // Backspace (remove)\n case 'f':\n return '\\n' // Form feed as newline\n case 'v':\n return '\\n' // Vertical tab as newline\n default:\n // Unknown escape sequence - keep original\n return match\n }\n })\n }\n\n /**\n * Parses input text with HTML-style markup into styled text segments.\n *\n * Supported tags:\n * - <color=\"value\"> - Sets text color (hex code or CSS color name)\n * - <weight=\"value\"> - Sets font weight (100-900 or keywords like \"bold\")\n * - <size=\"value\"> - Sets font size in pixels\n * - <b> - Makes text bold (shorthand for weight=\"bold\")\n * - <i> - Makes text italic\n *\n * Tag values can use double quotes, single quotes, or no quotes:\n * <color=\"red\">, <color='red'>, <color=red>\n *\n * Tags can be nested and must be properly closed with </tag>\n * @param input Text string containing markup tags\n * @param baseStyle Default style properties to apply to all segments\n * @returns Array of styled text segments with consistent style properties\n */\n private parseRichText(input: string, baseStyle: Partial<TextSegment>): TextSegment[] {\n // Match opening/closing tags with optional quoted/unquoted values\n // Capture groups: (1) closing slash, (2) tag name, (3) double quoted value, (4) single quoted value, (5) unquoted value\n const tagRegex = /<(\\/?)(\\w+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?>/g\n const stack: Partial<TextSegment>[] = []\n const segments: TextSegment[] = []\n let lastIndex = 0\n let currentStyle: Partial<TextSegment> = { ...baseStyle }\n\n // Helper to create a styled segment ensuring all style properties are included\n const applyStyle = (text: string) => {\n if (!text) return\n segments.push({\n text,\n color: currentStyle.color,\n weight: currentStyle.weight,\n size: currentStyle.size,\n b: currentStyle.b,\n i: currentStyle.i,\n })\n }\n\n let match: RegExpExecArray | null\n while ((match = tagRegex.exec(input))) {\n const [, closingSlash, tagNameStr, quotedVal1, quotedVal2, unquotedVal] = match\n const tagName = tagNameStr.toLowerCase()\n const value = quotedVal1 || quotedVal2 || unquotedVal\n\n // Process text content before the current tag\n applyStyle(input.slice(lastIndex, match.index))\n lastIndex = tagRegex.lastIndex\n\n if (!closingSlash) {\n // Opening tag: Save current style state and apply new style\n stack.push({ ...currentStyle })\n\n switch (tagName) {\n case 'color':\n // Support any valid CSS color value\n currentStyle.color = value as TextSegment['color']\n break\n\n case 'weight':\n // Support numeric weights (100-900) or keywords\n currentStyle.weight = value as TextSegment['weight']\n break\n\n case 'size':\n // Parse pixel size as number, revert to default if invalid\n currentStyle.size = value ? Number(value) : undefined\n if (isNaN(currentStyle.size as number)) {\n console.warn(`[TextNode ${this.key || ''}] Invalid numeric value for size tag: ${value}`)\n currentStyle.size = undefined\n }\n break\n\n case 'b':\n // Simple bold flag\n currentStyle.b = true\n break\n\n case 'i':\n // Simple italic flag\n currentStyle.i = true\n break\n }\n } else {\n // Closing tag: Restore previous style state\n currentStyle = stack.pop() || { ...baseStyle }\n }\n }\n\n // Process remaining text after last tag\n applyStyle(input.slice(lastIndex))\n\n // Don't filter out empty segments - they might represent empty lines\n return segments\n }\n\n private formatSpacing(value: TextProps['letterSpacing'] | TextProps['wordSpacing']) {\n if (typeof value === 'number') return `${value}px`\n return value || 'normal'\n }\n\n private parseSpacingToPx(spacingValue: number | string | undefined, fontSize: number): number {\n if (spacingValue === undefined || spacingValue === 'normal') {\n return 0\n }\n if (typeof spacingValue === 'number') {\n return spacingValue // Treat raw number as px\n }\n if (typeof spacingValue === 'string') {\n const trimmed = spacingValue.trim()\n if (trimmed.endsWith('px')) {\n return parseFloat(trimmed) || 0\n }\n if (trimmed.endsWith('em')) {\n // Convert em based on the current font size\n return (parseFloat(trimmed) || 0) * fontSize\n }\n // Attempt to parse as a raw number (pixels) if no unit\n const parsed = parseFloat(trimmed)\n if (!isNaN(parsed)) {\n return parsed\n }\n }\n return 0 // Default fallback\n }\n\n /**\n * Adds manual letter spacing compensation to a measured text width.\n * Needed because skia-canvas ctx.measureText() does not include letterSpacing in the returned width,\n * even though letterSpacing IS applied during rendering (fillText/strokeText).\n */\n private addLetterSpacingExtra(text: string, measuredWidth: number, letterSpacingPx: number): number {\n if (letterSpacingPx === 0 || text.length === 0) return measuredWidth\n const charCount = [...text].length\n return measuredWidth + (charCount > 1 ? (charCount - 1) * letterSpacingPx : 0)\n }\n\n /**\n * Generates a CSS font string by combining base TextProps with optional TextSegment styling.\n * Follows browser font string format: \"font-style font-weight font-size font-family\"\n *\n * Priority for style properties:\n * - Weight: segment <weight> tag > segment <b> tag > base fontWeight prop\n * - Style: segment <i> > base fontStyle\n * - Size: segment size > base fontSize\n * - Family: base fontFamily\n * @param segmentStyle Optional TextSegment styling to override base props\n * @returns Formatted CSS font string for canvas context\n */\n private getFontString(segmentStyle?: Partial<TextSegment>): string {\n const baseStyle = this.props\n let effectiveWeight: TextSegment['weight'] | number | undefined\n\n // Determine italic style - segment <i> tag overrides base style\n const effectiveStyle = segmentStyle?.i ? 'italic' : baseStyle.fontStyle || 'normal'\n\n // Determine font weight with priority:\n // 1. Segment explicit weight (<weight> tag)\n // 2. Segment bold flag (<b> tag)\n // 3. Base font weight prop\n if (segmentStyle?.weight) {\n effectiveWeight = segmentStyle.weight\n } else if (segmentStyle?.b) {\n effectiveWeight = 'bold'\n } else {\n effectiveWeight = baseStyle.fontWeight || 'normal'\n }\n\n // Use segment size if specified, otherwise base size with 16px default\n const effectiveSize = segmentStyle?.size ? segmentStyle.size : baseStyle.fontSize || 16\n\n // Combine properties into CSS font string format\n const style = {\n fontStyle: effectiveStyle,\n fontWeight: effectiveWeight,\n fontSize: effectiveSize,\n fontFamily: baseStyle.fontFamily || 'sans-serif',\n }\n\n return `${style.fontStyle} ${style.fontWeight} ${style.fontSize}px ${style.fontFamily}`\n }\n\n /**\n * Gets lines to process respecting maxLines constraint\n */\n private getLinesToMeasureOrRender(): TextSegment[][] {\n const maxLines = this.props.maxLines\n if (maxLines !== undefined && maxLines > 0 && this.lines.length > maxLines) {\n return this.lines.slice(0, maxLines)\n }\n return this.lines\n }\n\n /**\n * Measures text dimensions and calculates layout metrics for the YogaLayout engine.\n * Handles text wrapping, line height calculations, and dynamic leading.\n *\n * Line heights are determined by:\n * 1. Using props.lineHeight as fixed pixel value if provided\n * 2. Otherwise calculating dynamic height based on largest font size per line\n * 3. Adding leading space above/below text content\n * 4. Including specified line gaps between lines\n * @param widthConstraint Maximum allowed width in pixels for text layout\n * @param widthMode YogaLayout mode determining how width constraint is applied\n * @returns Calculated minimum dimensions required to render text content\n * - width: Total width needed for text layout\n * - height: Total height including line heights and gaps\n */\n private measureText(widthConstraint: number, widthMode: MeasureMode): { width: number; height: number } {\n // Create measurement canvas if not exists\n if (!TextNode.measurementContext) {\n TextNode.measurementContext = new Canvas(1, 1).getContext('2d')\n }\n const baseFontSize = this.props.fontSize || 16\n const ctx = TextNode.measurementContext!\n ctx.save()\n\n // Setup text measurement context\n ctx.letterSpacing = this.formatSpacing(this.props.letterSpacing)\n ctx.wordSpacing = 'normal' // Handled manually via parsedWordSpacingPx\n const parsedWordSpacingPx = this.parseSpacingToPx(this.props.wordSpacing, baseFontSize)\n const parsedLetterSpacingPx = this.parseSpacingToPx(this.props.letterSpacing, baseFontSize)\n\n // Pre-measure each text segment width with its specific styling\n for (const segment of this.segments) {\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (segment width):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n segment.width = this.addLetterSpacingExtra(segment.text, ctx.measureText(segment.text).width, parsedLetterSpacingPx)\n }\n\n // Calculate available layout width\n const availableWidthForContent = widthMode === Style.MeasureMode.Undefined ? Infinity : Math.max(0, widthConstraint)\n const epsilon = 0.001 // Float precision compensation\n\n // Wrap text into lines based on available width\n this.lines = this.wrapTextRich(ctx, this.segments, availableWidthForContent + epsilon, parsedWordSpacingPx, parsedLetterSpacingPx)\n\n // Initialize line metrics arrays\n this.lineHeights = [] // Final heights including leading\n this.lineAscents = [] // Text ascent heights\n this.lineContentHeights = [] // Raw content heights (ascent + descent)\n\n let totalTextHeight = 0\n const linesToMeasure = this.getLinesToMeasureOrRender()\n const numLines = linesToMeasure.length\n const defaultLineHeightMultiplier = 1.2 // Base leading multiplier\n\n // Calculate metrics for each line\n for (const line of linesToMeasure) {\n let maxAscent = 0\n let maxDescent = 0\n let maxFontSizeOnLine = 0\n\n // Handle empty line metrics\n if (line.length === 0) {\n ctx.font = this.getFontString()\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (empty line):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = baseFontSize\n } else {\n // Calculate max metrics across all segments in line\n for (const segment of line) {\n if (/^\\s+$/.test(segment.text)) continue\n\n const segmentSize = segment.size || baseFontSize\n maxFontSizeOnLine = Math.max(maxFontSizeOnLine, segmentSize)\n\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (segment height):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n const metrics = ctx.measureText(this.metricsString)\n const ascent = metrics.actualBoundingBoxAscent ?? segmentSize * 0.8\n const descent = metrics.actualBoundingBoxDescent ?? segmentSize * 0.2\n\n maxAscent = Math.max(maxAscent, ascent)\n maxDescent = Math.max(maxDescent, descent)\n }\n }\n\n // Fallback metrics for lines with only whitespace\n if (maxAscent === 0 && maxDescent === 0 && line.length > 0) {\n ctx.font = this.getFontString()\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (fallback):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n }\n\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n\n // Calculate total content height for line\n const actualContentHeight = maxAscent + maxDescent\n\n // Determine final line box height with leading\n const targetLineBoxHeight =\n typeof this.props.lineHeight === 'number' && this.props.lineHeight > 0 ? this.props.lineHeight : maxFontSizeOnLine * defaultLineHeightMultiplier\n\n // Use larger of target height or content height to prevent clipping\n const finalLineHeight = Math.max(actualContentHeight, targetLineBoxHeight)\n\n // Store line metrics for rendering\n this.lineHeights.push(finalLineHeight)\n this.lineAscents.push(maxAscent)\n this.lineContentHeights.push(actualContentHeight)\n\n totalTextHeight += finalLineHeight\n }\n\n // Add line gap spacing to total height\n const lineGapValue = this.props.lineGap\n const totalGapHeight = Math.max(0, (numLines - 1) * lineGapValue)\n const calculatedContentHeight = totalTextHeight + totalGapHeight\n\n // Calculate width required for text content\n const spaceWidth = this.measureSpaceWidth(ctx)\n let singleLineWidth = 0\n let firstWordInSingleLine = true\n for (const segment of this.segments) {\n const words = segment.text.split(/(\\s+)/).filter(Boolean)\n for (const word of words) {\n if (/^\\s+$/.test(word)) continue\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (single line width):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const wordWidth = this.addLetterSpacingExtra(word, ctx.measureText(word).width, parsedLetterSpacingPx)\n if (!firstWordInSingleLine) {\n singleLineWidth += spaceWidth + parsedWordSpacingPx\n }\n singleLineWidth += wordWidth\n firstWordInSingleLine = false\n }\n }\n\n // Determine final content width based on wrapping\n let requiredContentWidth: number\n if (singleLineWidth <= availableWidthForContent) {\n requiredContentWidth = singleLineWidth\n if (linesToMeasure.length > 1 && this.props.maxLines !== 1 && !this.segments.some(s => s.text.includes('\\n'))) {\n console.warn(\n `[TextNode ${this.key || ''}] Rich text should fit (${singleLineWidth.toFixed(2)} <= ${availableWidthForContent.toFixed(2)}) but wrapTextRich produced ${linesToMeasure.length} lines. Width calculation might be slightly off due to complex spacing/kerning.`,\n )\n let maxWrappedLineWidth = 0\n for (const line of linesToMeasure) {\n let currentLineWidth = 0\n let firstWordOnWrappedLine = true\n for (const segment of line) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n if (!isSpaceSegment) {\n if (!firstWordOnWrappedLine) {\n currentLineWidth += spaceWidth + parsedWordSpacingPx\n }\n currentLineWidth += segmentWidth\n firstWordOnWrappedLine = false\n }\n }\n maxWrappedLineWidth = Math.max(maxWrappedLineWidth, currentLineWidth)\n }\n requiredContentWidth = Math.max(singleLineWidth, maxWrappedLineWidth)\n }\n } else {\n let maxWrappedLineWidth = 0\n for (const line of linesToMeasure) {\n let currentLineWidth = 0\n let firstWordOnWrappedLine = true\n for (const segment of line) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n if (!isSpaceSegment) {\n if (!firstWordOnWrappedLine) {\n currentLineWidth += spaceWidth + parsedWordSpacingPx\n }\n currentLineWidth += segmentWidth\n firstWordOnWrappedLine = false\n }\n }\n maxWrappedLineWidth = Math.max(maxWrappedLineWidth, currentLineWidth)\n }\n requiredContentWidth = maxWrappedLineWidth\n }\n\n // Constrain width if needed\n let finalContentWidth = requiredContentWidth\n if (availableWidthForContent !== Infinity) {\n finalContentWidth = Math.min(requiredContentWidth, availableWidthForContent)\n }\n\n ctx.restore()\n return {\n width: Math.max(0, finalContentWidth),\n height: Math.max(0, calculatedContentHeight),\n }\n }\n\n /**\n * Wraps text segments into multiple lines while respecting width constraints and preserving styling.\n * Handles rich text attributes (color, weight, size, bold, italic) and proper word wrapping.\n * Also respects explicit newline characters (\\n) for forced line breaks.\n * @param ctx Canvas rendering context used for text measurements\n * @param segments Array of text segments with styling information\n * @param maxWidth Maximum allowed width for each line in pixels\n * @param parsedWordSpacingPx Additional spacing to add between words in pixels\n * @returns Array of lines, where each line contains styled text segments\n */\n private wrapTextRich(\n ctx: CanvasRenderingContext2D,\n segments: TextSegment[],\n maxWidth: number,\n parsedWordSpacingPx: number,\n parsedLetterSpacingPx: number = 0,\n ): TextSegment[][] {\n const lines: TextSegment[][] = []\n\n if (segments.length === 0 || maxWidth <= 0) return lines\n\n let currentLineSegments: TextSegment[] = []\n let currentLineWidth = 0\n const spaceWidth = this.measureSpaceWidth(ctx)\n\n // Helper to finalize current line and start new one\n const finalizeLine = (forceEmpty = false) => {\n // Remove trailing whitespace segments unless we're forcing an empty line\n if (!forceEmpty) {\n while (currentLineSegments.length > 0 && /^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)) {\n currentLineSegments.pop()\n }\n }\n // Always push the line, even if empty (for \\n\\n cases)\n lines.push(currentLineSegments)\n currentLineSegments = []\n currentLineWidth = 0\n }\n\n for (const segment of segments) {\n // Preserve all style attributes for consistency\n const segmentStyle = {\n color: segment.color,\n weight: segment.weight,\n size: segment.size,\n b: segment.b,\n i: segment.i,\n }\n\n // Check if segment contains newline characters\n if (segment.text.includes('\\n')) {\n // Split by newlines and process each part\n const parts = segment.text.split('\\n')\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const isLastPart = i === parts.length - 1\n\n if (part.length > 0) {\n // Process this part normally\n const wordsAndSpaces = part.split(/(\\s+)/).filter(Boolean)\n\n for (const wordOrSpace of wordsAndSpaces) {\n const isSpace = /^\\s+$/.test(wordOrSpace)\n let wordSegment: TextSegment\n let wordWidth: number\n\n if (isSpace) {\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: 0 }\n wordWidth = 0\n } else {\n ctx.font = this.getFontString(segmentStyle)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n wordWidth = this.addLetterSpacingExtra(wordOrSpace, ctx.measureText(wordOrSpace).width, parsedLetterSpacingPx)\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: wordWidth }\n }\n\n const needsSpace = currentLineSegments.length > 0 && !/^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)\n const spaceToAdd = needsSpace ? spaceWidth + parsedWordSpacingPx : 0\n\n if (currentLineWidth + spaceToAdd + wordWidth <= maxWidth || currentLineSegments.length === 0) {\n if (needsSpace) {\n currentLineSegments.push({ text: ' ', ...segmentStyle, width: 0 })\n currentLineWidth += spaceToAdd\n }\n currentLineSegments.push(wordSegment)\n currentLineWidth += wordWidth\n } else {\n if (currentLineSegments.length > 0) {\n finalizeLine()\n }\n\n if (!isSpace) {\n if (wordWidth > maxWidth && maxWidth > 0) {\n const brokenParts = this.breakWordRich(ctx, wordSegment, maxWidth, parsedLetterSpacingPx)\n\n if (brokenParts.length > 0) {\n for (let k = 0; k < brokenParts.length - 1; k++) {\n lines.push([brokenParts[k]])\n }\n currentLineSegments = [brokenParts[brokenParts.length - 1]]\n currentLineWidth = brokenParts[brokenParts.length - 1].width ?? 0\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n }\n }\n }\n }\n\n // Force line break after each part except the last\n // If part is empty, this creates an empty line (like \\n\\n)\n if (!isLastPart) {\n finalizeLine(part.length === 0)\n }\n }\n } else {\n // No newlines - process normally\n const wordsAndSpaces = segment.text.split(/(\\s+)/).filter(Boolean)\n\n for (const wordOrSpace of wordsAndSpaces) {\n const isSpace = /^\\s+$/.test(wordOrSpace)\n let wordSegment: TextSegment\n let wordWidth: number\n\n if (isSpace) {\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: 0 }\n wordWidth = 0\n } else {\n ctx.font = this.getFontString(segmentStyle)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n wordWidth = this.addLetterSpacingExtra(wordOrSpace, ctx.measureText(wordOrSpace).width, parsedLetterSpacingPx)\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: wordWidth }\n }\n\n const needsSpace = currentLineSegments.length > 0 && !/^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)\n const spaceToAdd = needsSpace ? spaceWidth + parsedWordSpacingPx : 0\n\n if (currentLineWidth + spaceToAdd + wordWidth <= maxWidth || currentLineSegments.length === 0) {\n if (needsSpace) {\n currentLineSegments.push({ text: ' ', ...segmentStyle, width: 0 })\n currentLineWidth += spaceToAdd\n }\n currentLineSegments.push(wordSegment)\n currentLineWidth += wordWidth\n } else {\n if (currentLineSegments.length > 0) {\n finalizeLine()\n }\n\n if (!isSpace) {\n if (wordWidth > maxWidth && maxWidth > 0) {\n const brokenParts = this.breakWordRich(ctx, wordSegment, maxWidth, parsedLetterSpacingPx)\n\n if (brokenParts.length > 0) {\n for (let k = 0; k < brokenParts.length - 1; k++) {\n lines.push([brokenParts[k]])\n }\n currentLineSegments = [brokenParts[brokenParts.length - 1]]\n currentLineWidth = brokenParts[brokenParts.length - 1].width ?? 0\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n }\n }\n }\n }\n }\n\n finalizeLine()\n return lines\n }\n\n /**\n * Breaks a word segment into multiple segments that each fit within the specified width constraint.\n * Maintains all styling properties (color, weight, size, bold, italic) across broken segments.\n * @param ctx Canvas rendering context used for text measurements\n * @param segmentToBreak Original text segment to split\n * @param maxWidth Maximum width allowed for each resulting segment\n * @returns Array of TextSegments, each fitting maxWidth, or original segment if no breaking needed\n */\n private breakWordRich(ctx: CanvasRenderingContext2D, segmentToBreak: TextSegment, maxWidth: number, parsedLetterSpacingPx: number = 0): TextSegment[] {\n const word = segmentToBreak.text\n\n // Copy all style properties to maintain consistent styling across broken segments\n const style = {\n color: segmentToBreak.color,\n weight: segmentToBreak.weight,\n size: segmentToBreak.size,\n b: segmentToBreak.b,\n i: segmentToBreak.i,\n }\n\n if (maxWidth <= 0) return [segmentToBreak]\n\n const brokenSegments: TextSegment[] = []\n let currentPartText = ''\n\n // Configure context with segment style for accurate measurements\n ctx.font = this.getFontString(style)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n\n // Process word character by character to find valid break points\n for (const char of word) {\n const testPartText = currentPartText + char\n const testPartWidth = this.addLetterSpacingExtra(testPartText, ctx.measureText(testPartText).width, parsedLetterSpacingPx)\n\n if (testPartWidth > maxWidth) {\n // Current accumulated text exceeds width - create new segment\n if (currentPartText) {\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: this.addLetterSpacingExtra(currentPartText, ctx.measureText(currentPartText).width, parsedLetterSpacingPx),\n })\n }\n\n // Handle current character that caused overflow\n currentPartText = char\n const currentCharWidth = ctx.measureText(currentPartText).width\n\n if (currentCharWidth > maxWidth) {\n // Single character is too wide - force break after it\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: currentCharWidth,\n })\n currentPartText = ''\n }\n } else {\n // Character fits - add to current part\n currentPartText = testPartText\n }\n }\n\n // Handle any remaining text as final segment\n if (currentPartText) {\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: this.addLetterSpacingExtra(currentPartText, ctx.measureText(currentPartText).width, parsedLetterSpacingPx),\n })\n }\n\n return brokenSegments.length > 0 ? brokenSegments : [segmentToBreak]\n }\n\n /**\n * Measures width of space character using base font\n */\n private measureSpaceWidth(ctx: CanvasRenderingContext2D): number {\n const originalFont = ctx.font\n ctx.font = this.getFontString()\n const width = ctx.measureText(' ').width\n ctx.font = originalFont\n return width > 0 ? width : (this.props.fontSize || 16) * 0.3\n }\n\n /**\n * Renders multi-line text content with rich text styling and layout features\n *\n * Core features:\n * - Dynamic line heights with leading/spacing controls\n * - Vertical text alignment (top/middle/bottom)\n * - Horizontal text alignment (left/center/right/justify)\n * - Text wrapping within bounds\n * - Ellipsis truncation\n * - Rich text styling per segment (color, weight, size, etc)\n * - Performance optimizations (clipping, visibility checks)\n * @param ctx Canvas rendering context\n * @param x Content box left position in pixels\n * @param y Content box top position in pixels\n * @param width Content box total width including padding\n * @param height Content box total height including padding\n */\n protected override _renderContent(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number) {\n super._renderContent(ctx, x, y, width, height)\n\n ctx.save()\n ctx.textBaseline = 'alphabetic'\n ctx.letterSpacing = this.formatSpacing(this.props.letterSpacing)\n ctx.wordSpacing = 'normal'\n\n const baseFontSize = this.props.fontSize || 16\n const parsedWordSpacingPx = this.parseSpacingToPx(this.props.wordSpacing, baseFontSize)\n\n // Calculate content box with padding\n const paddingLeft = this.node.getComputedPadding(Style.Edge.Left) ?? 0\n const paddingTop = this.node.getComputedPadding(Style.Edge.Top) ?? 0\n const paddingRight = this.node.getComputedPadding(Style.Edge.Right) ?? 0\n const paddingBottom = this.node.getComputedPadding(Style.Edge.Bottom) ?? 0\n const contentX = x + paddingLeft\n const contentY = y + paddingTop\n const contentWidth = Math.max(0, width - paddingLeft - paddingRight)\n const contentHeight = Math.max(0, height - paddingTop - paddingBottom)\n\n if (contentWidth <= 0 || contentHeight <= 0) {\n ctx.restore()\n return\n }\n\n // Re-calculate lines based on the actual render width to ensure consistency\n // This fixes issues where Yoga Layout might use a cached measurement from a different\n // width constraint (e.g., during a flex shrink pass) but final layout is wider.\n const spaceWidth = this.measureSpaceWidth(ctx)\n // Use a small epsilon for float precision issues\n const epsilon = 0.01\n const parsedLetterSpacingPx = this.parseSpacingToPx(this.props.letterSpacing, baseFontSize)\n const allLines = this.wrapTextRich(ctx, this.segments, contentWidth + epsilon, parsedWordSpacingPx, parsedLetterSpacingPx)\n\n const needsEllipsis = this.props.ellipsis && this.props.maxLines !== undefined && allLines.length > this.props.maxLines\n\n // Apply maxLines constraint to get the visible lines\n const visibleLines = this.props.maxLines !== undefined && this.props.maxLines > 0 ? allLines.slice(0, this.props.maxLines) : allLines\n\n const numLinesToRender = visibleLines.length\n\n // Recalculate line metrics for the rendered lines\n // We cannot rely on this.lineHeights from measureText because it might correspond to different wrapping\n const lineHeights: number[] = []\n const lineAscents: number[] = []\n const lineContentHeights: number[] = []\n const defaultLineHeightMultiplier = 1.2\n let totalTextHeight = 0\n\n for (const line of visibleLines) {\n let maxAscent = 0\n let maxDescent = 0\n let maxFontSizeOnLine = 0\n\n if (line.length === 0) {\n ctx.font = this.getFontString()\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = baseFontSize\n } else {\n for (const segment of line) {\n if (/^\\s+$/.test(segment.text)) continue\n const segmentSize = segment.size || baseFontSize\n maxFontSizeOnLine = Math.max(maxFontSizeOnLine, segmentSize)\n\n // Style context for accurate metrics\n ctx.font = this.getFontString(segment)\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n\n const metrics = ctx.measureText(this.metricsString)\n const ascent = metrics.actualBoundingBoxAscent ?? segmentSize * 0.8\n const descent = metrics.actualBoundingBoxDescent ?? segmentSize * 0.2\n maxAscent = Math.max(maxAscent, ascent)\n maxDescent = Math.max(maxDescent, descent)\n }\n }\n if (maxAscent === 0 && maxDescent === 0 && line.length > 0) {\n // Fallback\n ctx.font = this.getFontString()\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n }\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n const actualContentHeight = maxAscent + maxDescent\n const targetLineBoxHeight =\n typeof this.props.lineHeight === 'number' && this.props.lineHeight > 0 ? this.props.lineHeight : maxFontSizeOnLine * defaultLineHeightMultiplier\n const finalLineHeight = Math.max(actualContentHeight, targetLineBoxHeight)\n\n lineHeights.push(finalLineHeight)\n lineAscents.push(maxAscent)\n lineContentHeights.push(actualContentHeight)\n totalTextHeight += finalLineHeight\n }\n\n if (numLinesToRender === 0) {\n ctx.restore()\n return\n }\n\n // Calculate vertical alignment offset\n const lineGapValue = this.props.lineGap\n const totalCalculatedTextHeight = totalTextHeight + Math.max(0, numLinesToRender - 1) * lineGapValue\n\n let blockStartY: number\n switch (this.props.verticalAlign) {\n case 'middle':\n blockStartY = contentY + (contentHeight - totalCalculatedTextHeight) / 2\n break\n case 'bottom':\n blockStartY = contentY + contentHeight - totalCalculatedTextHeight\n break\n case 'top':\n default:\n blockStartY = contentY\n }\n\n let currentLineTopY = blockStartY\n\n // Setup text content clipping region\n ctx.beginPath()\n ctx.rect(contentX, contentY, contentWidth, contentHeight)\n ctx.clip()\n\n // Configure ellipsis if needed\n const ellipsisChar = typeof this.props.ellipsis === 'string' ? this.props.ellipsis : '...'\n let ellipsisWidth = 0\n let ellipsisStyle: Partial<TextSegment> | undefined = undefined\n\n if (needsEllipsis) {\n const lastRenderedLine = visibleLines[visibleLines.length - 1]\n // ... ellipsis calculation ...\n const lastTextStyleSegment = [...lastRenderedLine].reverse().find(seg => !/^\\s+$/.test(seg.text))\n ellipsisStyle = lastTextStyleSegment\n ? {\n color: lastTextStyleSegment.color,\n weight: lastTextStyleSegment.weight,\n size: lastTextStyleSegment.size,\n b: lastTextStyleSegment.b,\n i: lastTextStyleSegment.i,\n }\n : undefined\n\n ctx.save()\n ctx.font = this.getFontString(ellipsisStyle)\n if (this.props.fontVariant) {\n ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n }\n ellipsisWidth = ctx.measureText(ellipsisChar).width\n ctx.restore()\n }\n\n // Render text content line by line\n for (let i = 0; i < numLinesToRender; i++) {\n const lineSegments = visibleLines[i]\n const currentLineFinalHeight = lineHeights[i]\n const currentLineMaxAscent = lineAscents[i]\n const currentLineContentHeight = lineContentHeights[i]\n\n // Calculate line spacing metrics\n const currentLineLeading = currentLineFinalHeight - currentLineContentHeight\n const currentLineSpaceAbove = Math.max(0, currentLineLeading / 2)\n const lineY = currentLineTopY + currentLineSpaceAbove + currentLineMaxAscent\n\n // Visibility culling check\n const lineTop = currentLineTopY\n const lineBottom = currentLineTopY + currentLineFinalHeight\n\n // Don't skip empty lines - they're intentional (from \\n\\n)\n // Only skip if the line is completely outside the visible area\n if (lineBottom <= contentY || lineTop >= contentY + contentHeight) {\n currentLineTopY += currentLineFinalHeight + lineGapValue\n continue\n }\n\n const isLastRenderedLine = i === numLinesToRender - 1\n\n // Calculate line width metrics for alignment\n let totalLineWidth = 0\n let totalWordsWidth = 0\n let numWordGaps = 0\n let firstWordOnLine = true\n const noSpaceBeforePunctuation = /^[.,!?;:)\\]}]/\n\n for (const segment of lineSegments) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n\n if (!isSpaceSegment) {\n if (!firstWordOnLine) {\n totalLineWidth += spaceWidth + parsedWordSpacingPx\n if (!noSpaceBeforePunctuation.test(segment.text)) {\n numWordGaps++\n }\n }\n totalLineWidth += segmentWidth\n totalWordsWidth += segmentWidth\n firstWordOnLine = false\n }\n }\n\n // Calculate horizontal alignment position\n const isJustify = this.props.textAlign === 'justify' && !isLastRenderedLine\n const lineTextAlign = isJustify ? 'left' : this.props.textAlign || 'left'\n let currentX: number\n\n switch (lineTextAlign) {\n case 'center':\n currentX = contentX + (contentWidth - totalLineWidth) / 2\n break\n case 'right':\n case 'end':\n currentX = contentX + contentWidth - totalLineWidth\n break\n case 'left':\n case 'start':\n default:\n currentX = contentX\n }\n currentX = Math.max(contentX, currentX)\n\n // Calculate justification spacing\n let spacePerWordGapPlusSpacing = spaceWidth + parsedWordSpacingPx\n if (isJustify && numWordGaps > 0 && totalLineWidth < contentWidth) {\n const totalBaseSpacingWidth = numWordGaps * (spaceWidth + parsedWordSpacingPx)\n const remainingSpace = contentWidth - totalWordsWidth - totalBaseSpacingWidth\n if (remainingSpace > 0) {\n spacePerWordGapPlusSpacing += remainingSpace / numWordGaps\n }\n }\n\n // Render line segments (skip rendering for truly empty lines)\n if (lineSegments.length > 0 && !lineSegments.every(s => s.text.trim() === '')) {\n let accumulatedWidth = 0\n let ellipsisApplied = false\n let firstWordDrawn = false\n\n for (let j = 0; j < lineSegments.length; j++) {\n const segment = lineSegments[j]\n const segmentWidth = segment.width ?? 0\n const isLastSegmentOnLine = j === lineSegments.length - 1\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n\n // Calculate word spacing\n let spaceToAddBefore = 0\n if (!isSpaceSegment && firstWordDrawn && !noSpaceBeforePunctuation.test(segment.text)) {\n spaceToAddBefore = isJustify ? spacePerWordGapPlusSpacing : spaceWidth + parsedWordSpacingPx\n }\n\n // Apply segment styles\n ctx.font = this.getFontString(segment)\n ctx.fillStyle = segment.color || this.props.color || 'black'\n\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in _renderContent (segment render):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n // Handle text truncation and ellipsis\n let textToDraw = segment.text\n let currentSegmentRenderWidth = segmentWidth\n let applyEllipsisAfter = false\n\n if (isLastRenderedLine && needsEllipsis && !isSpaceSegment) {\n const currentTotalWidth = accumulatedWidth + spaceToAddBefore + segmentWidth\n const spaceNeededAfter = isLastSegmentOnLine ? 0 : isJustify ? spacePerWordGapPlusSpacing : spaceWidth + parsedWordSpacingPx\n\n if (currentTotalWidth > contentWidth - spaceNeededAfter) {\n const availableWidthForSegment = contentWidth - accumulatedWidth - spaceToAddBefore - ellipsisWidth\n if (availableWidthForSegment > 0) {\n let truncatedText = ''\n for (const char of segment.text) {\n if (ctx.measureText(truncatedText + char).width <= availableWidthForSegment) {\n truncatedText += char\n } else {\n break\n }\n }\n textToDraw = truncatedText\n currentSegmentRenderWidth = ctx.measureText(textToDraw).width\n } else {\n textToDraw = ''\n currentSegmentRenderWidth = 0\n }\n applyEllipsisAfter = true\n ellipsisApplied = true\n } else if (isLastSegmentOnLine) {\n applyEllipsisAfter = true\n ellipsisApplied = true\n }\n }\n\n // Render text segment\n currentX += spaceToAddBefore\n accumulatedWidth += spaceToAddBefore\n\n const remainingRenderWidth = contentX + contentWidth - currentX\n if (currentSegmentRenderWidth > 0 && remainingRenderWidth > 0 && !isSpaceSegment) {\n ctx.textAlign = 'left'\n\n const shadows = this.props.textShadow ? (Array.isArray(this.props.textShadow) ? this.props.textShadow : [this.props.textShadow]) : []\n\n ctx.save()\n\n // Draw shadows\n for (const shadow of shadows) {\n ctx.shadowColor = shadow.color || 'transparent'\n ctx.shadowBlur = shadow.blur || 0\n ctx.shadowOffsetX = shadow.offsetX || 0\n ctx.shadowOffsetY = shadow.offsetY || 0\n ctx.fillText(textToDraw, currentX, lineY, Math.max(0, remainingRenderWidth + 1))\n }\n\n // Reset shadow to draw the main text\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n\n ctx.fillText(textToDraw, currentX, lineY, Math.max(0, remainingRenderWidth + 1))\n\n ctx.restore()\n\n firstWordDrawn = true\n }\n\n currentX += currentSegmentRenderWidth\n accumulatedWidth += currentSegmentRenderWidth\n\n // Render ellipsis\n if (applyEllipsisAfter) {\n const ellipsisRemainingWidth = contentX + contentWidth - currentX\n if (ellipsisRemainingWidth >= ellipsisWidth) {\n ctx.save()\n ctx.font = this.getFontString(ellipsisStyle)\n\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in _renderContent (ellipsis draw):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n ctx.fillStyle = ellipsisStyle?.color || this.props.color || 'black'\n ctx.fillText(ellipsisChar, currentX, lineY, Math.max(0, ellipsisRemainingWidth + 1))\n ctx.restore()\n }\n break\n }\n\n if (ellipsisApplied && currentX >= contentX + contentWidth) break\n }\n }\n\n currentLineTopY += currentLineFinalHeight + lineGapValue\n }\n\n ctx.restore()\n }\n}\n\n/**\n * Creates a new TextNode instance with rich text support\n */\nexport const Text = (text: number | string, props?: TextProps): CanvasElement => ({\n __type: 'Text',\n text,\n props,\n})\n"],"names":["BoxNode","Canvas","Style"],"mappings":"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"}
1
+ {"version":3,"file":"text.canvas.js","sources":["../../../../../src/canvas/text.canvas.ts"],"sourcesContent":["import type { TextProps, TextSegment, CanvasElement } from '@/canvas/canvas.type.js'\nimport { Canvas, type CanvasRenderingContext2D, type FontVariantSetting } from 'skia-canvas'\nimport { BoxNode } from '@/canvas/layout.canvas.js'\nimport { Style, MeasureMode } from '@/constant/common.const.js'\n\n/**\n * Node for rendering text content with rich text styling support\n * Supports color and weight variations through HTML-like tags\n */\nexport class TextNode extends BoxNode {\n private readonly segments: TextSegment[] = []\n private lines: TextSegment[][] = []\n private static measurementContext: CanvasRenderingContext2D | null = null\n private readonly metricsString = 'Ag|``'\n private lineHeights: number[] = []\n private lineAscents: number[] = []\n private lineContentHeights: number[] = []\n\n declare props: TextProps & { lineGap: number }\n\n constructor(text: number | string = '', props: TextProps = {}) {\n const initialProps = {\n name: 'TextNode',\n flexShrink: 1,\n lineGap: 0,\n ...props,\n children: undefined,\n }\n super(initialProps)\n this.props = initialProps\n // Process escape sequences before parsing rich text\n const processedText = this.processEscapeSequences(String(text ?? ''))\n this.segments = this.parseRichText(processedText, {\n color: this.props.color,\n weight: this.props.fontWeight,\n size: this.props.fontSize,\n b: this.props.fontWeight === 'bold',\n i: this.props.fontStyle === 'italic',\n })\n this.node.setMeasureFunc(this.measureText.bind(this))\n this.applyDefaults()\n }\n\n /**\n * Renders a simple, single-line text string without complex layout calculations.\n * A lightweight, static utility for drawing text where layout is handled externally.\n * @param ctx The canvas rendering context.\n * @param text The string to render.\n * @param x The x-coordinate for rendering.\n * @param y The y-coordinate for rendering.\n * @param props Basic text styling properties.\n */\n public static renderSimpleText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n props: {\n fontFamily?: string\n fontSize?: number\n fontWeight?: TextProps['fontWeight']\n fontStyle?: TextProps['fontStyle']\n color?: string\n textAlign?: CanvasRenderingContext2D['textAlign']\n textBaseline?: CanvasRenderingContext2D['textBaseline']\n } = {},\n ) {\n ctx.save()\n\n const {\n fontFamily = 'sans-serif',\n fontSize = 12,\n fontWeight = 'normal',\n fontStyle = 'normal',\n color = '#333',\n textAlign = 'left',\n textBaseline = 'alphabetic',\n } = props\n\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`\n ctx.fillStyle = color\n ctx.textAlign = textAlign\n ctx.textBaseline = textBaseline\n\n ctx.fillText(text, x, y)\n\n ctx.restore()\n }\n\n protected override applyDefaults(): void {\n const textDefaults: Required<\n Pick<TextProps, 'fontSize' | 'fontFamily' | 'fontWeight' | 'fontStyle' | 'color' | 'textAlign' | 'verticalAlign' | 'ellipsis' | 'lineGap'>\n > & {\n lineHeight: undefined | number\n maxLines: undefined | number\n letterSpacing: undefined | number\n wordSpacing: undefined | number\n fontVariant: undefined | FontVariantSetting\n } = {\n fontSize: 16,\n fontFamily: 'sans-serif',\n fontWeight: 'normal',\n fontStyle: 'normal',\n color: 'black',\n textAlign: 'left',\n verticalAlign: 'top',\n fontVariant: undefined,\n lineHeight: undefined,\n lineGap: 0,\n maxLines: undefined,\n ellipsis: false,\n letterSpacing: undefined,\n wordSpacing: undefined,\n }\n\n let defaultsApplied = false\n for (const key of Object.keys(textDefaults) as (keyof typeof textDefaults)[]) {\n if (this.props[key] === undefined && textDefaults[key] !== undefined) {\n ;(this.props as unknown as Record<string, unknown>)[key] = textDefaults[key]\n defaultsApplied = true\n }\n }\n\n if (defaultsApplied && !this.node.isDirty()) {\n const affectsMeasurement = [\n 'fontSize',\n 'fontFamily',\n 'fontWeight',\n 'fontStyle',\n 'lineHeight',\n 'maxLines',\n 'lineGap',\n 'letterSpacing',\n 'wordSpacing',\n ].some(measureKey => this.props[measureKey as keyof typeof textDefaults] === textDefaults[measureKey as keyof typeof textDefaults])\n if (affectsMeasurement) {\n this.node.markDirty()\n }\n }\n }\n\n /**\n * Processes Unix-like escape sequences in text strings.\n * Converts escaped characters into their actual representations.\n *\n * Supported escape sequences:\n * - \\n - Newline (line feed)\n * - \\t - Tab (converted to 4 spaces)\n * - \\r - Carriage return (treated as newline)\n * - \\\\ - Literal backslash\n * - \\' - Single quote\n * - \\\" - Double quote\n * - \\0 - Null character (removed)\n * - \\b - Backspace (removed)\n * - \\f - Form feed (treated as newline)\n * - \\v - Vertical tab (treated as newline)\n * @param input Raw text string potentially containing escape sequences\n * @returns Processed string with escape sequences converted\n */\n private processEscapeSequences(input: string): string {\n return input.replace(/\\\\(.)/g, (match, char) => {\n switch (char) {\n case 'n':\n return '\\n' // Newline\n case 't':\n return ' ' // Tab as 4 spaces\n case 'r':\n return '\\n' // Carriage return treated as newline\n case '\\\\':\n return '\\\\' // Literal backslash\n case \"'\":\n return \"'\" // Single quote\n case '\"':\n return '\"' // Double quote\n case '0':\n return '' // Null character (remove)\n case 'b':\n return '' // Backspace (remove)\n case 'f':\n return '\\n' // Form feed as newline\n case 'v':\n return '\\n' // Vertical tab as newline\n default:\n // Unknown escape sequence - keep original\n return match\n }\n })\n }\n\n /**\n * Parses input text with HTML-style markup into styled text segments.\n *\n * Supported tags:\n * - <color=\"value\"> - Sets text color (hex code or CSS color name)\n * - <weight=\"value\"> - Sets font weight (100-900 or keywords like \"bold\")\n * - <size=\"value\"> - Sets font size in pixels\n * - <b> - Makes text bold (shorthand for weight=\"bold\")\n * - <i> - Makes text italic\n *\n * Tag values can use double quotes, single quotes, or no quotes:\n * <color=\"red\">, <color='red'>, <color=red>\n *\n * Tags can be nested and must be properly closed with </tag>\n * @param input Text string containing markup tags\n * @param baseStyle Default style properties to apply to all segments\n * @returns Array of styled text segments with consistent style properties\n */\n private parseRichText(input: string, baseStyle: Partial<TextSegment>): TextSegment[] {\n // Match opening/closing tags with optional quoted/unquoted values\n // Capture groups: (1) closing slash, (2) tag name, (3) double quoted value, (4) single quoted value, (5) unquoted value\n const tagRegex = /<(\\/?)(\\w+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?>/g\n const stack: Partial<TextSegment>[] = []\n const segments: TextSegment[] = []\n let lastIndex = 0\n let currentStyle: Partial<TextSegment> = { ...baseStyle }\n\n // Helper to create a styled segment ensuring all style properties are included\n const applyStyle = (text: string) => {\n if (!text) return\n segments.push({\n text,\n color: currentStyle.color,\n weight: currentStyle.weight,\n size: currentStyle.size,\n b: currentStyle.b,\n i: currentStyle.i,\n })\n }\n\n let match: RegExpExecArray | null\n while ((match = tagRegex.exec(input))) {\n const [, closingSlash, tagNameStr, quotedVal1, quotedVal2, unquotedVal] = match\n const tagName = tagNameStr.toLowerCase()\n const value = quotedVal1 || quotedVal2 || unquotedVal\n\n // Process text content before the current tag\n applyStyle(input.slice(lastIndex, match.index))\n lastIndex = tagRegex.lastIndex\n\n if (!closingSlash) {\n // Opening tag: Save current style state and apply new style\n stack.push({ ...currentStyle })\n\n switch (tagName) {\n case 'color':\n // Support any valid CSS color value\n currentStyle.color = value as TextSegment['color']\n break\n\n case 'weight':\n // Support numeric weights (100-900) or keywords\n currentStyle.weight = value as TextSegment['weight']\n break\n\n case 'size':\n // Parse pixel size as number, revert to default if invalid\n currentStyle.size = value ? Number(value) : undefined\n if (isNaN(currentStyle.size as number)) {\n console.warn(`[TextNode ${this.key || ''}] Invalid numeric value for size tag: ${value}`)\n currentStyle.size = undefined\n }\n break\n\n case 'b':\n // Simple bold flag\n currentStyle.b = true\n break\n\n case 'i':\n // Simple italic flag\n currentStyle.i = true\n break\n }\n } else {\n // Closing tag: Restore previous style state\n currentStyle = stack.pop() || { ...baseStyle }\n }\n }\n\n // Process remaining text after last tag\n applyStyle(input.slice(lastIndex))\n\n // Don't filter out empty segments - they might represent empty lines\n return segments\n }\n\n private formatSpacing(value: TextProps['letterSpacing'] | TextProps['wordSpacing']) {\n if (typeof value === 'number') return `${value}px`\n return value || 'normal'\n }\n\n private parseSpacingToPx(spacingValue: number | string | undefined, fontSize: number): number {\n if (spacingValue === undefined || spacingValue === 'normal') {\n return 0\n }\n if (typeof spacingValue === 'number') {\n return spacingValue // Treat raw number as px\n }\n if (typeof spacingValue === 'string') {\n const trimmed = spacingValue.trim()\n if (trimmed.endsWith('px')) {\n return parseFloat(trimmed) || 0\n }\n if (trimmed.endsWith('em')) {\n // Convert em based on the current font size\n return (parseFloat(trimmed) || 0) * fontSize\n }\n // Attempt to parse as a raw number (pixels) if no unit\n const parsed = parseFloat(trimmed)\n if (!isNaN(parsed)) {\n return parsed\n }\n }\n return 0 // Default fallback\n }\n\n /**\n * Adds manual letter spacing compensation to a measured text width.\n * Needed because skia-canvas ctx.measureText() does not include letterSpacing in the returned width,\n * even though letterSpacing IS applied during rendering (fillText/strokeText).\n */\n private addLetterSpacingExtra(text: string, measuredWidth: number, letterSpacingPx: number): number {\n if (letterSpacingPx === 0 || text.length === 0) return measuredWidth\n const charCount = [...text].length\n return measuredWidth + (charCount > 1 ? (charCount - 1) * letterSpacingPx : 0)\n }\n\n /**\n * Generates a CSS font string by combining base TextProps with optional TextSegment styling.\n * Follows browser font string format: \"font-style font-weight font-size font-family\"\n *\n * Priority for style properties:\n * - Weight: segment <weight> tag > segment <b> tag > base fontWeight prop\n * - Style: segment <i> > base fontStyle\n * - Size: segment size > base fontSize\n * - Family: base fontFamily\n * @param segmentStyle Optional TextSegment styling to override base props\n * @returns Formatted CSS font string for canvas context\n */\n private getFontString(segmentStyle?: Partial<TextSegment>): string {\n const baseStyle = this.props\n let effectiveWeight: TextSegment['weight'] | number | undefined\n\n // Determine italic style - segment <i> tag overrides base style\n const effectiveStyle = segmentStyle?.i ? 'italic' : baseStyle.fontStyle || 'normal'\n\n // Determine font weight with priority:\n // 1. Segment explicit weight (<weight> tag)\n // 2. Segment bold flag (<b> tag)\n // 3. Base font weight prop\n if (segmentStyle?.weight) {\n effectiveWeight = segmentStyle.weight\n } else if (segmentStyle?.b) {\n effectiveWeight = 'bold'\n } else {\n effectiveWeight = baseStyle.fontWeight || 'normal'\n }\n\n // Use segment size if specified, otherwise base size with 16px default\n const effectiveSize = segmentStyle?.size ? segmentStyle.size : baseStyle.fontSize || 16\n\n // Combine properties into CSS font string format\n const style = {\n fontStyle: effectiveStyle,\n fontWeight: effectiveWeight,\n fontSize: effectiveSize,\n fontFamily: baseStyle.fontFamily || 'sans-serif',\n }\n\n return `${style.fontStyle} ${style.fontWeight} ${style.fontSize}px ${style.fontFamily}`\n }\n\n /**\n * Gets lines to process respecting maxLines constraint\n */\n private getLinesToMeasureOrRender(): TextSegment[][] {\n const maxLines = this.props.maxLines\n if (maxLines !== undefined && maxLines > 0 && this.lines.length > maxLines) {\n return this.lines.slice(0, maxLines)\n }\n return this.lines\n }\n\n /**\n * Measures text dimensions and calculates layout metrics for the YogaLayout engine.\n * Handles text wrapping, line height calculations, and dynamic leading.\n *\n * Line heights are determined by:\n * 1. Using props.lineHeight as fixed pixel value if provided\n * 2. Otherwise calculating dynamic height based on largest font size per line\n * 3. Adding leading space above/below text content\n * 4. Including specified line gaps between lines\n * @param widthConstraint Maximum allowed width in pixels for text layout\n * @param widthMode YogaLayout mode determining how width constraint is applied\n * @returns Calculated minimum dimensions required to render text content\n * - width: Total width needed for text layout\n * - height: Total height including line heights and gaps\n */\n private measureText(widthConstraint: number, widthMode: MeasureMode): { width: number; height: number } {\n // Create measurement canvas if not exists\n if (!TextNode.measurementContext) {\n TextNode.measurementContext = new Canvas(1, 1).getContext('2d')\n }\n const baseFontSize = this.props.fontSize || 16\n const ctx = TextNode.measurementContext!\n ctx.save()\n\n // Setup text measurement context\n ctx.letterSpacing = this.formatSpacing(this.props.letterSpacing)\n ctx.wordSpacing = 'normal' // Handled manually via parsedWordSpacingPx\n const parsedWordSpacingPx = this.parseSpacingToPx(this.props.wordSpacing, baseFontSize)\n const parsedLetterSpacingPx = this.parseSpacingToPx(this.props.letterSpacing, baseFontSize)\n\n // Pre-measure each text segment width with its specific styling\n for (const segment of this.segments) {\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (segment width):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n segment.width = this.addLetterSpacingExtra(segment.text, ctx.measureText(segment.text).width, parsedLetterSpacingPx)\n }\n\n // Calculate available layout width\n const availableWidthForContent = widthMode === Style.MeasureMode.Undefined ? Infinity : Math.max(0, widthConstraint)\n const epsilon = 0.001 // Float precision compensation\n\n // Wrap text into lines based on available width\n this.lines = this.wrapTextRich(ctx, this.segments, availableWidthForContent + epsilon, parsedWordSpacingPx, parsedLetterSpacingPx)\n\n // Initialize line metrics arrays\n this.lineHeights = [] // Final heights including leading\n this.lineAscents = [] // Text ascent heights\n this.lineContentHeights = [] // Raw content heights (ascent + descent)\n\n let totalTextHeight = 0\n const linesToMeasure = this.getLinesToMeasureOrRender()\n const numLines = linesToMeasure.length\n const defaultLineHeightMultiplier = 1.2 // Base leading multiplier\n\n // Calculate metrics for each line\n for (const line of linesToMeasure) {\n let maxAscent = 0\n let maxDescent = 0\n let maxFontSizeOnLine = 0\n\n // Handle empty line metrics\n if (line.length === 0) {\n ctx.font = this.getFontString()\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (empty line):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = baseFontSize\n } else {\n // Calculate max metrics across all segments in line\n for (const segment of line) {\n if (/^\\s+$/.test(segment.text)) continue\n\n const segmentSize = segment.size || baseFontSize\n maxFontSizeOnLine = Math.max(maxFontSizeOnLine, segmentSize)\n\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (segment height):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n const metrics = ctx.measureText(this.metricsString)\n const ascent = metrics.actualBoundingBoxAscent ?? segmentSize * 0.8\n const descent = metrics.actualBoundingBoxDescent ?? segmentSize * 0.2\n\n maxAscent = Math.max(maxAscent, ascent)\n maxDescent = Math.max(maxDescent, descent)\n }\n }\n\n // Fallback metrics for lines with only whitespace\n if (maxAscent === 0 && maxDescent === 0 && line.length > 0) {\n ctx.font = this.getFontString()\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (fallback):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n }\n\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n\n // Calculate total content height for line\n const actualContentHeight = maxAscent + maxDescent\n\n // Determine final line box height with leading\n const targetLineBoxHeight =\n typeof this.props.lineHeight === 'number' && this.props.lineHeight > 0 ? this.props.lineHeight : maxFontSizeOnLine * defaultLineHeightMultiplier\n\n // Use larger of target height or content height to prevent clipping\n const finalLineHeight = Math.max(actualContentHeight, targetLineBoxHeight)\n\n // Store line metrics for rendering\n this.lineHeights.push(finalLineHeight)\n this.lineAscents.push(maxAscent)\n this.lineContentHeights.push(actualContentHeight)\n\n totalTextHeight += finalLineHeight\n }\n\n // Add line gap spacing to total height\n const lineGapValue = this.props.lineGap\n const totalGapHeight = Math.max(0, (numLines - 1) * lineGapValue)\n const calculatedContentHeight = totalTextHeight + totalGapHeight\n\n // Calculate width required for text content\n const spaceWidth = this.measureSpaceWidth(ctx)\n let singleLineWidth = 0\n let firstWordInSingleLine = true\n for (const segment of this.segments) {\n const words = segment.text.split(/(\\s+)/).filter(Boolean)\n for (const word of words) {\n if (/^\\s+$/.test(word)) continue\n ctx.font = this.getFontString(segment)\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in measureText (single line width):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n const wordWidth = this.addLetterSpacingExtra(word, ctx.measureText(word).width, parsedLetterSpacingPx)\n if (!firstWordInSingleLine) {\n singleLineWidth += spaceWidth + parsedWordSpacingPx\n }\n singleLineWidth += wordWidth\n firstWordInSingleLine = false\n }\n }\n\n // Determine final content width based on wrapping\n let requiredContentWidth: number\n if (singleLineWidth <= availableWidthForContent) {\n requiredContentWidth = singleLineWidth\n if (linesToMeasure.length > 1 && this.props.maxLines !== 1 && !this.segments.some(s => s.text.includes('\\n'))) {\n console.warn(\n `[TextNode ${this.key || ''}] Rich text should fit (${singleLineWidth.toFixed(2)} <= ${availableWidthForContent.toFixed(2)}) but wrapTextRich produced ${linesToMeasure.length} lines. Width calculation might be slightly off due to complex spacing/kerning.`,\n )\n let maxWrappedLineWidth = 0\n for (const line of linesToMeasure) {\n let currentLineWidth = 0\n let firstWordOnWrappedLine = true\n for (const segment of line) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n if (!isSpaceSegment) {\n if (!firstWordOnWrappedLine) {\n currentLineWidth += spaceWidth + parsedWordSpacingPx\n }\n currentLineWidth += segmentWidth\n firstWordOnWrappedLine = false\n }\n }\n maxWrappedLineWidth = Math.max(maxWrappedLineWidth, currentLineWidth)\n }\n requiredContentWidth = Math.max(singleLineWidth, maxWrappedLineWidth)\n }\n } else {\n let maxWrappedLineWidth = 0\n for (const line of linesToMeasure) {\n let currentLineWidth = 0\n let firstWordOnWrappedLine = true\n for (const segment of line) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n if (!isSpaceSegment) {\n if (!firstWordOnWrappedLine) {\n currentLineWidth += spaceWidth + parsedWordSpacingPx\n }\n currentLineWidth += segmentWidth\n firstWordOnWrappedLine = false\n }\n }\n maxWrappedLineWidth = Math.max(maxWrappedLineWidth, currentLineWidth)\n }\n requiredContentWidth = maxWrappedLineWidth\n }\n\n // Constrain width if needed\n let finalContentWidth = requiredContentWidth\n if (availableWidthForContent !== Infinity) {\n finalContentWidth = Math.min(requiredContentWidth, availableWidthForContent)\n }\n\n ctx.restore()\n return {\n width: Math.max(0, finalContentWidth),\n height: Math.max(0, calculatedContentHeight),\n }\n }\n\n /**\n * Wraps text segments into multiple lines while respecting width constraints and preserving styling.\n * Handles rich text attributes (color, weight, size, bold, italic) and proper word wrapping.\n * Also respects explicit newline characters (\\n) for forced line breaks.\n * @param ctx Canvas rendering context used for text measurements\n * @param segments Array of text segments with styling information\n * @param maxWidth Maximum allowed width for each line in pixels\n * @param parsedWordSpacingPx Additional spacing to add between words in pixels\n * @returns Array of lines, where each line contains styled text segments\n */\n private wrapTextRich(\n ctx: CanvasRenderingContext2D,\n segments: TextSegment[],\n maxWidth: number,\n parsedWordSpacingPx: number,\n parsedLetterSpacingPx: number = 0,\n ): TextSegment[][] {\n const lines: TextSegment[][] = []\n\n if (segments.length === 0 || maxWidth <= 0) return lines\n\n let currentLineSegments: TextSegment[] = []\n let currentLineWidth = 0\n const spaceWidth = this.measureSpaceWidth(ctx)\n\n // Helper to finalize current line and start new one\n const finalizeLine = (forceEmpty = false) => {\n // Remove trailing whitespace segments unless we're forcing an empty line\n if (!forceEmpty) {\n while (currentLineSegments.length > 0 && /^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)) {\n currentLineSegments.pop()\n }\n }\n // Always push the line, even if empty (for \\n\\n cases)\n lines.push(currentLineSegments)\n currentLineSegments = []\n currentLineWidth = 0\n }\n\n for (const segment of segments) {\n // Preserve all style attributes for consistency\n const segmentStyle = {\n color: segment.color,\n weight: segment.weight,\n size: segment.size,\n b: segment.b,\n i: segment.i,\n }\n\n // Check if segment contains newline characters\n if (segment.text.includes('\\n')) {\n // Split by newlines and process each part\n const parts = segment.text.split('\\n')\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const isLastPart = i === parts.length - 1\n\n if (part.length > 0) {\n // Process this part normally\n const wordsAndSpaces = part.split(/(\\s+)/).filter(Boolean)\n\n for (const wordOrSpace of wordsAndSpaces) {\n const isSpace = /^\\s+$/.test(wordOrSpace)\n let wordSegment: TextSegment\n let wordWidth: number\n\n if (isSpace) {\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: 0 }\n wordWidth = 0\n } else {\n ctx.font = this.getFontString(segmentStyle)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n wordWidth = this.addLetterSpacingExtra(wordOrSpace, ctx.measureText(wordOrSpace).width, parsedLetterSpacingPx)\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: wordWidth }\n }\n\n const needsSpace = currentLineSegments.length > 0 && !/^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)\n const spaceToAdd = needsSpace ? spaceWidth + parsedWordSpacingPx : 0\n\n if (currentLineWidth + spaceToAdd + wordWidth <= maxWidth || currentLineSegments.length === 0) {\n if (needsSpace) {\n currentLineSegments.push({ text: ' ', ...segmentStyle, width: 0 })\n currentLineWidth += spaceToAdd\n }\n currentLineSegments.push(wordSegment)\n currentLineWidth += wordWidth\n } else {\n if (currentLineSegments.length > 0) {\n finalizeLine()\n }\n\n if (!isSpace) {\n if (wordWidth > maxWidth && maxWidth > 0) {\n const brokenParts = this.breakWordRich(ctx, wordSegment, maxWidth, parsedLetterSpacingPx)\n\n if (brokenParts.length > 0) {\n for (let k = 0; k < brokenParts.length - 1; k++) {\n lines.push([brokenParts[k]])\n }\n currentLineSegments = [brokenParts[brokenParts.length - 1]]\n currentLineWidth = brokenParts[brokenParts.length - 1].width ?? 0\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n }\n }\n }\n }\n\n // Force line break after each part except the last\n // If part is empty, this creates an empty line (like \\n\\n)\n if (!isLastPart) {\n finalizeLine(part.length === 0)\n }\n }\n } else {\n // No newlines - process normally\n const wordsAndSpaces = segment.text.split(/(\\s+)/).filter(Boolean)\n\n for (const wordOrSpace of wordsAndSpaces) {\n const isSpace = /^\\s+$/.test(wordOrSpace)\n let wordSegment: TextSegment\n let wordWidth: number\n\n if (isSpace) {\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: 0 }\n wordWidth = 0\n } else {\n ctx.font = this.getFontString(segmentStyle)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n wordWidth = this.addLetterSpacingExtra(wordOrSpace, ctx.measureText(wordOrSpace).width, parsedLetterSpacingPx)\n wordSegment = { text: wordOrSpace, ...segmentStyle, width: wordWidth }\n }\n\n const needsSpace = currentLineSegments.length > 0 && !/^\\s+$/.test(currentLineSegments[currentLineSegments.length - 1].text)\n const spaceToAdd = needsSpace ? spaceWidth + parsedWordSpacingPx : 0\n\n if (currentLineWidth + spaceToAdd + wordWidth <= maxWidth || currentLineSegments.length === 0) {\n if (needsSpace) {\n currentLineSegments.push({ text: ' ', ...segmentStyle, width: 0 })\n currentLineWidth += spaceToAdd\n }\n currentLineSegments.push(wordSegment)\n currentLineWidth += wordWidth\n } else {\n if (currentLineSegments.length > 0) {\n finalizeLine()\n }\n\n if (!isSpace) {\n if (wordWidth > maxWidth && maxWidth > 0) {\n const brokenParts = this.breakWordRich(ctx, wordSegment, maxWidth, parsedLetterSpacingPx)\n\n if (brokenParts.length > 0) {\n for (let k = 0; k < brokenParts.length - 1; k++) {\n lines.push([brokenParts[k]])\n }\n currentLineSegments = [brokenParts[brokenParts.length - 1]]\n currentLineWidth = brokenParts[brokenParts.length - 1].width ?? 0\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n } else {\n currentLineSegments = [wordSegment]\n currentLineWidth = wordWidth\n }\n }\n }\n }\n }\n }\n\n finalizeLine()\n return lines\n }\n\n /**\n * Breaks a word segment into multiple segments that each fit within the specified width constraint.\n * Maintains all styling properties (color, weight, size, bold, italic) across broken segments.\n * @param ctx Canvas rendering context used for text measurements\n * @param segmentToBreak Original text segment to split\n * @param maxWidth Maximum width allowed for each resulting segment\n * @returns Array of TextSegments, each fitting maxWidth, or original segment if no breaking needed\n */\n private breakWordRich(ctx: CanvasRenderingContext2D, segmentToBreak: TextSegment, maxWidth: number, parsedLetterSpacingPx: number = 0): TextSegment[] {\n const word = segmentToBreak.text\n\n // Copy all style properties to maintain consistent styling across broken segments\n const style = {\n color: segmentToBreak.color,\n weight: segmentToBreak.weight,\n size: segmentToBreak.size,\n b: segmentToBreak.b,\n i: segmentToBreak.i,\n }\n\n if (maxWidth <= 0) return [segmentToBreak]\n\n const brokenSegments: TextSegment[] = []\n let currentPartText = ''\n\n // Configure context with segment style for accurate measurements\n ctx.font = this.getFontString(style)\n if (this.props.fontVariant) ctx.fontVariant = this.props.fontVariant\n\n // Process word character by character to find valid break points\n for (const char of word) {\n const testPartText = currentPartText + char\n const testPartWidth = this.addLetterSpacingExtra(testPartText, ctx.measureText(testPartText).width, parsedLetterSpacingPx)\n\n if (testPartWidth > maxWidth) {\n // Current accumulated text exceeds width - create new segment\n if (currentPartText) {\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: this.addLetterSpacingExtra(currentPartText, ctx.measureText(currentPartText).width, parsedLetterSpacingPx),\n })\n }\n\n // Handle current character that caused overflow\n currentPartText = char\n const currentCharWidth = ctx.measureText(currentPartText).width\n\n if (currentCharWidth > maxWidth) {\n // Single character is too wide - force break after it\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: currentCharWidth,\n })\n currentPartText = ''\n }\n } else {\n // Character fits - add to current part\n currentPartText = testPartText\n }\n }\n\n // Handle any remaining text as final segment\n if (currentPartText) {\n brokenSegments.push({\n text: currentPartText,\n ...style,\n width: this.addLetterSpacingExtra(currentPartText, ctx.measureText(currentPartText).width, parsedLetterSpacingPx),\n })\n }\n\n return brokenSegments.length > 0 ? brokenSegments : [segmentToBreak]\n }\n\n /**\n * Measures width of space character using base font\n */\n private measureSpaceWidth(ctx: CanvasRenderingContext2D): number {\n const originalFont = ctx.font\n ctx.font = this.getFontString()\n const width = ctx.measureText(' ').width\n ctx.font = originalFont\n return width > 0 ? width : (this.props.fontSize || 16) * 0.3\n }\n\n /**\n * Renders multi-line text content with rich text styling and layout features\n *\n * Core features:\n * - Dynamic line heights with leading/spacing controls\n * - Vertical text alignment (top/middle/bottom)\n * - Horizontal text alignment (left/center/right/justify)\n * - Text wrapping within bounds\n * - Ellipsis truncation\n * - Rich text styling per segment (color, weight, size, etc)\n * - Performance optimizations (clipping, visibility checks)\n * @param ctx Canvas rendering context\n * @param x Content box left position in pixels\n * @param y Content box top position in pixels\n * @param width Content box total width including padding\n * @param height Content box total height including padding\n */\n protected override async _renderContent(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number) {\n await super._renderContent(ctx, x, y, width, height)\n\n ctx.save()\n ctx.textBaseline = 'alphabetic'\n ctx.letterSpacing = this.formatSpacing(this.props.letterSpacing)\n ctx.wordSpacing = 'normal'\n\n const baseFontSize = this.props.fontSize || 16\n const parsedWordSpacingPx = this.parseSpacingToPx(this.props.wordSpacing, baseFontSize)\n\n // Calculate content box with padding\n const paddingLeft = this.node.getComputedPadding(Style.Edge.Left) ?? 0\n const paddingTop = this.node.getComputedPadding(Style.Edge.Top) ?? 0\n const paddingRight = this.node.getComputedPadding(Style.Edge.Right) ?? 0\n const paddingBottom = this.node.getComputedPadding(Style.Edge.Bottom) ?? 0\n const contentX = x + paddingLeft\n const contentY = y + paddingTop\n const contentWidth = Math.max(0, width - paddingLeft - paddingRight)\n const contentHeight = Math.max(0, height - paddingTop - paddingBottom)\n\n if (contentWidth <= 0 || contentHeight <= 0) {\n ctx.restore()\n return\n }\n\n // Re-calculate lines based on the actual render width to ensure consistency\n // This fixes issues where Yoga Layout might use a cached measurement from a different\n // width constraint (e.g., during a flex shrink pass) but final layout is wider.\n const spaceWidth = this.measureSpaceWidth(ctx)\n // Use a small epsilon for float precision issues\n const epsilon = 0.01\n const parsedLetterSpacingPx = this.parseSpacingToPx(this.props.letterSpacing, baseFontSize)\n const allLines = this.wrapTextRich(ctx, this.segments, contentWidth + epsilon, parsedWordSpacingPx, parsedLetterSpacingPx)\n\n const needsEllipsis = this.props.ellipsis && this.props.maxLines !== undefined && allLines.length > this.props.maxLines\n\n // Apply maxLines constraint to get the visible lines\n const visibleLines = this.props.maxLines !== undefined && this.props.maxLines > 0 ? allLines.slice(0, this.props.maxLines) : allLines\n\n const numLinesToRender = visibleLines.length\n\n // Recalculate line metrics for the rendered lines\n // We cannot rely on this.lineHeights from measureText because it might correspond to different wrapping\n const lineHeights: number[] = []\n const lineAscents: number[] = []\n const lineContentHeights: number[] = []\n const defaultLineHeightMultiplier = 1.2\n let totalTextHeight = 0\n\n for (const line of visibleLines) {\n let maxAscent = 0\n let maxDescent = 0\n let maxFontSizeOnLine = 0\n\n if (line.length === 0) {\n ctx.font = this.getFontString()\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = baseFontSize\n } else {\n for (const segment of line) {\n if (/^\\s+$/.test(segment.text)) continue\n const segmentSize = segment.size || baseFontSize\n maxFontSizeOnLine = Math.max(maxFontSizeOnLine, segmentSize)\n\n // Style context for accurate metrics\n ctx.font = this.getFontString(segment)\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n\n const metrics = ctx.measureText(this.metricsString)\n const ascent = metrics.actualBoundingBoxAscent ?? segmentSize * 0.8\n const descent = metrics.actualBoundingBoxDescent ?? segmentSize * 0.2\n maxAscent = Math.max(maxAscent, ascent)\n maxDescent = Math.max(maxDescent, descent)\n }\n }\n if (maxAscent === 0 && maxDescent === 0 && line.length > 0) {\n // Fallback\n ctx.font = this.getFontString()\n if (this.props.fontVariant) ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n const metrics = ctx.measureText(this.metricsString)\n maxAscent = metrics.actualBoundingBoxAscent ?? baseFontSize * 0.8\n maxDescent = metrics.actualBoundingBoxDescent ?? baseFontSize * 0.2\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n }\n maxFontSizeOnLine = maxFontSizeOnLine || baseFontSize\n const actualContentHeight = maxAscent + maxDescent\n const targetLineBoxHeight =\n typeof this.props.lineHeight === 'number' && this.props.lineHeight > 0 ? this.props.lineHeight : maxFontSizeOnLine * defaultLineHeightMultiplier\n const finalLineHeight = Math.max(actualContentHeight, targetLineBoxHeight)\n\n lineHeights.push(finalLineHeight)\n lineAscents.push(maxAscent)\n lineContentHeights.push(actualContentHeight)\n totalTextHeight += finalLineHeight\n }\n\n if (numLinesToRender === 0) {\n ctx.restore()\n return\n }\n\n // Calculate vertical alignment offset\n const lineGapValue = this.props.lineGap\n const totalCalculatedTextHeight = totalTextHeight + Math.max(0, numLinesToRender - 1) * lineGapValue\n\n let blockStartY: number\n switch (this.props.verticalAlign) {\n case 'middle':\n blockStartY = contentY + (contentHeight - totalCalculatedTextHeight) / 2\n break\n case 'bottom':\n blockStartY = contentY + contentHeight - totalCalculatedTextHeight\n break\n case 'top':\n default:\n blockStartY = contentY\n }\n\n let currentLineTopY = blockStartY\n\n // Setup text content clipping region\n ctx.beginPath()\n ctx.rect(contentX, contentY, contentWidth, contentHeight)\n ctx.clip()\n\n // Configure ellipsis if needed\n const ellipsisChar = typeof this.props.ellipsis === 'string' ? this.props.ellipsis : '...'\n let ellipsisWidth = 0\n let ellipsisStyle: Partial<TextSegment> | undefined = undefined\n\n if (needsEllipsis) {\n const lastRenderedLine = visibleLines[visibleLines.length - 1]\n // ... ellipsis calculation ...\n const lastTextStyleSegment = [...lastRenderedLine].reverse().find(seg => !/^\\s+$/.test(seg.text))\n ellipsisStyle = lastTextStyleSegment\n ? {\n color: lastTextStyleSegment.color,\n weight: lastTextStyleSegment.weight,\n size: lastTextStyleSegment.size,\n b: lastTextStyleSegment.b,\n i: lastTextStyleSegment.i,\n }\n : undefined\n\n ctx.save()\n ctx.font = this.getFontString(ellipsisStyle)\n if (this.props.fontVariant) {\n ctx.fontVariant = typeof this.props.fontVariant === 'string' ? this.props.fontVariant : 'normal'\n }\n ellipsisWidth = ctx.measureText(ellipsisChar).width\n ctx.restore()\n }\n\n // Render text content line by line\n for (let i = 0; i < numLinesToRender; i++) {\n const lineSegments = visibleLines[i]\n const currentLineFinalHeight = lineHeights[i]\n const currentLineMaxAscent = lineAscents[i]\n const currentLineContentHeight = lineContentHeights[i]\n\n // Calculate line spacing metrics\n const currentLineLeading = currentLineFinalHeight - currentLineContentHeight\n const currentLineSpaceAbove = Math.max(0, currentLineLeading / 2)\n const lineY = currentLineTopY + currentLineSpaceAbove + currentLineMaxAscent\n\n // Visibility culling check\n const lineTop = currentLineTopY\n const lineBottom = currentLineTopY + currentLineFinalHeight\n\n // Don't skip empty lines - they're intentional (from \\n\\n)\n // Only skip if the line is completely outside the visible area\n if (lineBottom <= contentY || lineTop >= contentY + contentHeight) {\n currentLineTopY += currentLineFinalHeight + lineGapValue\n continue\n }\n\n const isLastRenderedLine = i === numLinesToRender - 1\n\n // Calculate line width metrics for alignment\n let totalLineWidth = 0\n let totalWordsWidth = 0\n let numWordGaps = 0\n let firstWordOnLine = true\n const noSpaceBeforePunctuation = /^[.,!?;:)\\]}]/\n\n for (const segment of lineSegments) {\n const segmentWidth = segment.width ?? 0\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n\n if (!isSpaceSegment) {\n if (!firstWordOnLine) {\n totalLineWidth += spaceWidth + parsedWordSpacingPx\n if (!noSpaceBeforePunctuation.test(segment.text)) {\n numWordGaps++\n }\n }\n totalLineWidth += segmentWidth\n totalWordsWidth += segmentWidth\n firstWordOnLine = false\n }\n }\n\n // Calculate horizontal alignment position\n const isJustify = this.props.textAlign === 'justify' && !isLastRenderedLine\n const lineTextAlign = isJustify ? 'left' : this.props.textAlign || 'left'\n let currentX: number\n\n switch (lineTextAlign) {\n case 'center':\n currentX = contentX + (contentWidth - totalLineWidth) / 2\n break\n case 'right':\n case 'end':\n currentX = contentX + contentWidth - totalLineWidth\n break\n case 'left':\n case 'start':\n default:\n currentX = contentX\n }\n currentX = Math.max(contentX, currentX)\n\n // Calculate justification spacing\n let spacePerWordGapPlusSpacing = spaceWidth + parsedWordSpacingPx\n if (isJustify && numWordGaps > 0 && totalLineWidth < contentWidth) {\n const totalBaseSpacingWidth = numWordGaps * (spaceWidth + parsedWordSpacingPx)\n const remainingSpace = contentWidth - totalWordsWidth - totalBaseSpacingWidth\n if (remainingSpace > 0) {\n spacePerWordGapPlusSpacing += remainingSpace / numWordGaps\n }\n }\n\n // Render line segments (skip rendering for truly empty lines)\n if (lineSegments.length > 0 && !lineSegments.every(s => s.text.trim() === '')) {\n let accumulatedWidth = 0\n let ellipsisApplied = false\n let firstWordDrawn = false\n\n for (let j = 0; j < lineSegments.length; j++) {\n const segment = lineSegments[j]\n const segmentWidth = segment.width ?? 0\n const isLastSegmentOnLine = j === lineSegments.length - 1\n const isSpaceSegment = /^\\s+$/.test(segment.text)\n\n // Calculate word spacing\n let spaceToAddBefore = 0\n if (!isSpaceSegment && firstWordDrawn && !noSpaceBeforePunctuation.test(segment.text)) {\n spaceToAddBefore = isJustify ? spacePerWordGapPlusSpacing : spaceWidth + parsedWordSpacingPx\n }\n\n // Apply segment styles\n ctx.font = this.getFontString(segment)\n ctx.fillStyle = segment.color || this.props.color || 'black'\n\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in _renderContent (segment render):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n // Handle text truncation and ellipsis\n let textToDraw = segment.text\n let currentSegmentRenderWidth = segmentWidth\n let applyEllipsisAfter = false\n\n if (isLastRenderedLine && needsEllipsis && !isSpaceSegment) {\n const currentTotalWidth = accumulatedWidth + spaceToAddBefore + segmentWidth\n const spaceNeededAfter = isLastSegmentOnLine ? 0 : isJustify ? spacePerWordGapPlusSpacing : spaceWidth + parsedWordSpacingPx\n\n if (currentTotalWidth > contentWidth - spaceNeededAfter) {\n const availableWidthForSegment = contentWidth - accumulatedWidth - spaceToAddBefore - ellipsisWidth\n if (availableWidthForSegment > 0) {\n let truncatedText = ''\n for (const char of segment.text) {\n if (ctx.measureText(truncatedText + char).width <= availableWidthForSegment) {\n truncatedText += char\n } else {\n break\n }\n }\n textToDraw = truncatedText\n currentSegmentRenderWidth = ctx.measureText(textToDraw).width\n } else {\n textToDraw = ''\n currentSegmentRenderWidth = 0\n }\n applyEllipsisAfter = true\n ellipsisApplied = true\n } else if (isLastSegmentOnLine) {\n applyEllipsisAfter = true\n ellipsisApplied = true\n }\n }\n\n // Render text segment\n currentX += spaceToAddBefore\n accumulatedWidth += spaceToAddBefore\n\n const remainingRenderWidth = contentX + contentWidth - currentX\n if (currentSegmentRenderWidth > 0 && remainingRenderWidth > 0 && !isSpaceSegment) {\n ctx.textAlign = 'left'\n\n const shadows = this.props.textShadow ? (Array.isArray(this.props.textShadow) ? this.props.textShadow : [this.props.textShadow]) : []\n\n ctx.save()\n\n // Draw shadows\n for (const shadow of shadows) {\n ctx.shadowColor = shadow.color || 'transparent'\n ctx.shadowBlur = shadow.blur || 0\n ctx.shadowOffsetX = shadow.offsetX || 0\n ctx.shadowOffsetY = shadow.offsetY || 0\n ctx.fillText(textToDraw, currentX, lineY, Math.max(0, remainingRenderWidth + 1))\n }\n\n // Reset shadow to draw the main text\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n\n ctx.fillText(textToDraw, currentX, lineY, Math.max(0, remainingRenderWidth + 1))\n\n ctx.restore()\n\n firstWordDrawn = true\n }\n\n currentX += currentSegmentRenderWidth\n accumulatedWidth += currentSegmentRenderWidth\n\n // Render ellipsis\n if (applyEllipsisAfter) {\n const ellipsisRemainingWidth = contentX + contentWidth - currentX\n if (ellipsisRemainingWidth >= ellipsisWidth) {\n ctx.save()\n ctx.font = this.getFontString(ellipsisStyle)\n\n if (typeof this.props.fontVariant === 'string') {\n ctx.fontVariant = this.props.fontVariant\n } else if (this.props.fontVariant !== undefined) {\n console.warn(`[TextNode ${this.key || ''}] Invalid fontVariant prop type in _renderContent (ellipsis draw):`, this.props.fontVariant)\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n } else {\n if (ctx.fontVariant !== 'normal') ctx.fontVariant = 'normal'\n }\n\n ctx.fillStyle = ellipsisStyle?.color || this.props.color || 'black'\n ctx.fillText(ellipsisChar, currentX, lineY, Math.max(0, ellipsisRemainingWidth + 1))\n ctx.restore()\n }\n break\n }\n\n if (ellipsisApplied && currentX >= contentX + contentWidth) break\n }\n }\n\n currentLineTopY += currentLineFinalHeight + lineGapValue\n }\n\n ctx.restore()\n }\n}\n\n/**\n * Creates a new TextNode instance with rich text support\n */\nexport const Text = (text: number | string, props?: TextProps): CanvasElement => ({\n __type: 'Text',\n text,\n props,\n})\n"],"names":["BoxNode","Canvas","Style"],"mappings":"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"}