fix(kiwi): export EXCLUDE booleans as XOR
This commit is contained in:
parent
f6a8bd8580
commit
1ea6631ffd
|
|
@ -1,9 +1,10 @@
|
|||
import { guidToString } from '@open-pencil/kiwi/fig/guid'
|
||||
|
||||
/* eslint-disable max-lines -- kiwi↔scene conversion helpers are tightly coupled */
|
||||
import { DEFAULT_FONT_FAMILY, DEFAULT_STROKE_MITER_LIMIT } from '#core/constants'
|
||||
import { parseVariantName } from '#core/scene-graph/variant-name'
|
||||
import { styleToWeight } from '#core/text/fonts'
|
||||
|
||||
import { guidToString } from '@open-pencil/kiwi/fig/guid'
|
||||
import { convertEffects, convertFills, convertStrokes } from './paint'
|
||||
import { importStyleRuns } from './style-runs'
|
||||
export { importStyleRuns } from './style-runs'
|
||||
|
|
@ -133,10 +134,11 @@ function mapNodeType(type?: string): NodeType | 'DOCUMENT' | 'VARIABLE' {
|
|||
|
||||
function mapBooleanOperation(nc: NodeChange): SceneNode['booleanOperation'] {
|
||||
if (nc.type !== 'BOOLEAN_OPERATION') return undefined
|
||||
switch (nc.booleanOperation) {
|
||||
const operation = nc.booleanOperation as NodeChange['booleanOperation'] | 'EXCLUDE' | undefined
|
||||
switch (operation) {
|
||||
case 'SUBTRACT':
|
||||
case 'INTERSECT':
|
||||
return nc.booleanOperation
|
||||
return operation
|
||||
case 'EXCLUDE':
|
||||
case 'XOR':
|
||||
return 'EXCLUDE'
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { NodeChange, Paint } from '@open-pencil/kiwi/fig/codec'
|
||||
import { stringToGuid } from '@open-pencil/kiwi/fig/guid'
|
||||
|
||||
/* eslint-disable max-lines */
|
||||
import { bytesToHex } from '#core/bytes/hex'
|
||||
import type { SceneGraph, SceneNode } from '#core/scene-graph'
|
||||
import type { Color, GUID, Matrix, Vector } from '#core/types'
|
||||
|
||||
import { stringToGuid } from '@open-pencil/kiwi/fig/guid'
|
||||
import {
|
||||
applyExportSettingsPluginData,
|
||||
mergePluginData,
|
||||
|
|
@ -16,6 +16,12 @@ import {
|
|||
|
||||
export type KiwiNodeChange = NodeChange & Record<string, unknown>
|
||||
|
||||
type KiwiBooleanOperation = NonNullable<NodeChange['booleanOperation']>
|
||||
|
||||
function toKiwiBooleanOperation(operation: SceneNode['booleanOperation']): KiwiBooleanOperation {
|
||||
return operation === 'EXCLUDE' ? 'XOR' : (operation ?? 'UNION')
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a mapping from assetRef key strings ("key@version" or "key") to
|
||||
* variable GUIDs. This is used to convert colorVar.assetRef references in raw
|
||||
|
|
@ -704,8 +710,7 @@ export function sceneNodeToKiwiWithContext(
|
|||
if (node.type === 'COMPONENT_SET') upsertPluginData(node, NODE_TYPE_PLUGIN_KEY, node.type)
|
||||
if (nc.type === 'CANVAS') nc.pageType = 'DESIGN'
|
||||
if (node.type === 'BOOLEAN_OPERATION')
|
||||
nc.booleanOperation =
|
||||
node.booleanOperation === 'EXCLUDE' ? 'XOR' : (node.booleanOperation ?? 'UNION')
|
||||
nc.booleanOperation = toKiwiBooleanOperation(node.booleanOperation)
|
||||
if (strokePaints.length > 0) nc.strokePaints = strokePaints
|
||||
|
||||
context.serializeLayoutProps(node, nc)
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ export interface NodeChange {
|
|||
frameMaskDisabled?: boolean
|
||||
resizeToFit?: boolean
|
||||
// Vector
|
||||
booleanOperation?: 'UNION' | 'SUBTRACT' | 'INTERSECT' | 'EXCLUDE' | 'XOR'
|
||||
booleanOperation?: 'UNION' | 'SUBTRACT' | 'INTERSECT' | 'XOR'
|
||||
vectorData?: unknown
|
||||
fillGeometry?: Array<{ windingRule?: string; commandsBlob?: number }>
|
||||
strokeGeometry?: Array<{ windingRule?: string; commandsBlob?: number }>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { createNodeChangesMessage, encodeMessage, initCodec } from '@open-pencil/kiwi/fig/codec'
|
||||
|
||||
import { sceneNodeToKiwi } from '#core/kiwi/fig/node-change/serialize'
|
||||
import { SceneGraph } from '#core/scene-graph'
|
||||
|
||||
|
|
@ -17,6 +19,21 @@ describe('Figma boolean operation export', () => {
|
|||
expect(changes[0].booleanOperation).toBe('INTERSECT')
|
||||
})
|
||||
|
||||
test('exports exclude as Kiwi XOR', async () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = graph.getPages()[0]
|
||||
const node = graph.createNode('BOOLEAN_OPERATION', page.id, {
|
||||
booleanOperation: 'EXCLUDE'
|
||||
})
|
||||
|
||||
const changes = sceneNodeToKiwi(node, { sessionID: 1, localID: 1 }, 0, { value: 2 }, graph, [])
|
||||
|
||||
expect(changes[0].booleanOperation).toBe('XOR')
|
||||
|
||||
await initCodec()
|
||||
expect(() => encodeMessage(createNodeChangesMessage(1, 1, changes))).not.toThrow()
|
||||
})
|
||||
|
||||
test('exports boolean operation children in order', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = graph.getPages()[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue