From db056317a807533e9e7493dabc124362f71f063c Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sat, 18 Jul 2026 01:36:00 +0300 Subject: [PATCH] refactor(fig): extract paint import policy - Move paint/effect normalization and derived glyph conversion into the Fig package\n- Rewire core import and instance paths through the public node-change boundary\n- Keep static renderer evidence pointed at the new format-policy source --- .../derived-symbol-data/layout.ts | 2 +- packages/core/src/kiwi/fig/node-change/convert.ts | 13 +++++++++---- .../core/src/kiwi/fig/node-change/style-runs.ts | 3 +-- .../src}/node-change/derived-text-glyphs.ts | 0 packages/fig/src/node-change/index.ts | 2 ++ .../src/kiwi/fig => fig/src}/node-change/paint.ts | 8 +++++--- packages/fig/tests/node-change.test.ts | 15 +++++++++++++++ .../render/canvas/silhouette-autopsy.test.ts | 2 +- 8 files changed, 34 insertions(+), 11 deletions(-) rename packages/{core/src/kiwi/fig => fig/src}/node-change/derived-text-glyphs.ts (100%) rename packages/{core/src/kiwi/fig => fig/src}/node-change/paint.ts (95%) diff --git a/packages/core/src/kiwi/fig/instance-overrides/derived-symbol-data/layout.ts b/packages/core/src/kiwi/fig/instance-overrides/derived-symbol-data/layout.ts index f991eabb6..09f26fbde 100644 --- a/packages/core/src/kiwi/fig/instance-overrides/derived-symbol-data/layout.ts +++ b/packages/core/src/kiwi/fig/instance-overrides/derived-symbol-data/layout.ts @@ -1,3 +1,4 @@ +import { convertFigmaDerivedTextGlyphs } from '@open-pencil/fig/node-change' import type { SceneNode } from '@open-pencil/scene-graph' import type { @@ -5,7 +6,6 @@ import type { OverrideContext } from '#core/kiwi/fig/instance-overrides/types' import { convertLetterSpacing, convertLineHeight } from '#core/kiwi/fig/node-change/convert' -import { convertFigmaDerivedTextGlyphs } from '#core/kiwi/fig/node-change/derived-text-glyphs' import { resolveDsdGeometry } from './geometry' diff --git a/packages/core/src/kiwi/fig/node-change/convert.ts b/packages/core/src/kiwi/fig/node-change/convert.ts index cbbc17fcb..848722d6b 100644 --- a/packages/core/src/kiwi/fig/node-change/convert.ts +++ b/packages/core/src/kiwi/fig/node-change/convert.ts @@ -5,14 +5,17 @@ import { parseVariantName } from '@open-pencil/scene-graph/variant-name' import { DEFAULT_FONT_FAMILY, DEFAULT_STROKE_MITER_LIMIT } from '#core/constants' import { styleToWeight } from '#core/text/fonts' -import { convertEffects, convertFills, convertStrokes } from './paint' import { importStyleRuns } from './style-runs' export { importStyleRuns } from './style-runs' import { + convertEffects, + convertFigmaDerivedTextGlyphs, + convertFills, convertFontFeatures, convertFontVariations, convertLetterSpacing, convertLineHeight, + convertStrokes, extractBoundVariables, extractExportSettings, extractPluginData, @@ -24,12 +27,14 @@ import { mapTextDecoration } from '@open-pencil/fig/node-change' -import { convertFigmaDerivedTextGlyphs } from './derived-text-glyphs' -export { convertEffects, convertFills, convertStrokes, setVariableColorResolver } from './paint' export { + convertEffects, + convertFills, convertLetterSpacing, convertLineHeight, - mapTextDecoration + convertStrokes, + mapTextDecoration, + setVariableColorResolver } from '@open-pencil/fig/node-change' import { resolveGeometryPaths, resolveVectorNetwork } from './vector-geometry' export { resolveGeometryPaths } from './vector-geometry' diff --git a/packages/core/src/kiwi/fig/node-change/style-runs.ts b/packages/core/src/kiwi/fig/node-change/style-runs.ts index 56bdb4451..fea68afcb 100644 --- a/packages/core/src/kiwi/fig/node-change/style-runs.ts +++ b/packages/core/src/kiwi/fig/node-change/style-runs.ts @@ -1,6 +1,7 @@ import { convertFontFeatures, convertFontVariations, + convertFills, convertLetterSpacing, convertLineHeight, mapTextDecoration @@ -10,8 +11,6 @@ import type { CharacterStyleOverride, StyleRun } from '@open-pencil/scene-graph' import { styleToWeight } from '#core/text/fonts' -import { convertFills } from './paint' - function applyTextDecorationOverride(style: CharacterStyleOverride, override: NodeChange): void { const deco = override.textDecoration if (deco) style.textDecoration = mapTextDecoration(deco) diff --git a/packages/core/src/kiwi/fig/node-change/derived-text-glyphs.ts b/packages/fig/src/node-change/derived-text-glyphs.ts similarity index 100% rename from packages/core/src/kiwi/fig/node-change/derived-text-glyphs.ts rename to packages/fig/src/node-change/derived-text-glyphs.ts diff --git a/packages/fig/src/node-change/index.ts b/packages/fig/src/node-change/index.ts index 090f460b2..a4ce75f5e 100644 --- a/packages/fig/src/node-change/index.ts +++ b/packages/fig/src/node-change/index.ts @@ -1,5 +1,7 @@ +export * from './derived-text-glyphs' export * from './font/features' export * from './font/variations' +export * from './paint' export * from './plugin-data' export * from './style-refs' export * from './text-values' diff --git a/packages/core/src/kiwi/fig/node-change/paint.ts b/packages/fig/src/node-change/paint.ts similarity index 95% rename from packages/core/src/kiwi/fig/node-change/paint.ts rename to packages/fig/src/node-change/paint.ts index e0576b9c0..a23eb4933 100644 --- a/packages/core/src/kiwi/fig/node-change/paint.ts +++ b/packages/fig/src/node-change/paint.ts @@ -11,11 +11,13 @@ import type { StrokeCap, StrokeJoin } from '@open-pencil/scene-graph' +import { BLACK } from '@open-pencil/scene-graph/constants' import type { Color, Matrix } from '@open-pencil/scene-graph/primitives' -import { normalizeColor } from '#core/color' - -const convertColor = normalizeColor +function convertColor(color?: Partial): Color { + if (!color) return { ...BLACK } + return { r: color.r ?? 0, g: color.g ?? 0, b: color.b ?? 0, a: color.a ?? 1 } +} function imageHashToString(hash: Record): string { const bytes = Object.keys(hash) diff --git a/packages/fig/tests/node-change.test.ts b/packages/fig/tests/node-change.test.ts index 2bd9778ac..a754ed673 100644 --- a/packages/fig/tests/node-change.test.ts +++ b/packages/fig/tests/node-change.test.ts @@ -2,6 +2,8 @@ import { describe, expect, test } from 'bun:test' import { applyStyleRefsToFields, + convertEffects, + convertFills, convertFontFeatures, convertLetterSpacing, convertLineHeight, @@ -27,6 +29,19 @@ describe('@open-pencil/fig NodeChange policy', () => { ]) }) + test('normalizes imported paints and effects', () => { + expect(convertFills([{ type: 'SOLID' }])[0]).toMatchObject({ + color: { r: 0, g: 0, b: 0, a: 1 }, + opacity: 1, + visible: true + }) + expect(convertEffects([{ type: 'DROP_SHADOW' }])[0]).toMatchObject({ + type: 'DROP_SHADOW', + radius: 0, + visible: true + }) + }) + test('resolves imported style references before SceneGraph conversion', () => { const fields: Record = { styleIdForFill: { guid: { sessionID: 2, localID: 3 } } diff --git a/tests/engine/render/canvas/silhouette-autopsy.test.ts b/tests/engine/render/canvas/silhouette-autopsy.test.ts index a33039897..5cadf5592 100644 --- a/tests/engine/render/canvas/silhouette-autopsy.test.ts +++ b/tests/engine/render/canvas/silhouette-autopsy.test.ts @@ -39,7 +39,7 @@ const scenePath = coreSourcePath('canvas/scene.ts') const rendererPath = coreSourcePath('canvas/renderer.ts') const sgTypesPath = repoPath('packages/scene-graph/src/types.ts') const nodeExportPath = coreSourcePath('kiwi/fig/node-change/export-node.ts') -const convertPath = coreSourcePath('kiwi/fig/node-change/paint.ts') +const convertPath = repoPath('packages/fig/src/node-change/paint.ts') const schemaPath = repoPath('packages/kiwi/src/fig/schema/fig.kiwi') const codecPath = repoPath('packages/kiwi/src/fig/codec.ts') const lifecyclePath = coreSourcePath('canvas/renderer/lifecycle.ts')