fix(kiwi): support raw OpenType toggles
This commit is contained in:
parent
4cd187c766
commit
f77f58e2f6
|
|
@ -6,18 +6,35 @@ const LIGATURE_FEATURES = [
|
|||
['fontVariantContextualLigatures', 'CALT']
|
||||
] as const
|
||||
|
||||
function addFeature(features: FontFeature[], tag: string, enabled: boolean): void {
|
||||
const normalizedTag = tag.toUpperCase()
|
||||
if (features.some((feature) => feature.tag === normalizedTag)) return
|
||||
features.push({ tag: normalizedTag, enabled })
|
||||
}
|
||||
|
||||
export function convertFontFeatures(nc: NodeChange): FontFeature[] {
|
||||
const features: FontFeature[] = []
|
||||
for (const [field, tag] of LIGATURE_FEATURES) {
|
||||
const enabled = nc[field]
|
||||
if (enabled !== undefined) features.push({ tag, enabled })
|
||||
if (enabled !== undefined) addFeature(features, tag, enabled)
|
||||
}
|
||||
for (const tag of nc.toggledOnOTFeatures ?? []) addFeature(features, tag, true)
|
||||
for (const tag of nc.toggledOffOTFeatures ?? []) addFeature(features, tag, false)
|
||||
return features
|
||||
}
|
||||
|
||||
export function applyFontFeaturesToKiwi(nc: NodeChange, features: FontFeature[]): void {
|
||||
const toggledOn: string[] = []
|
||||
const toggledOff: string[] = []
|
||||
|
||||
for (const feature of features) {
|
||||
if (feature.tag === 'LIGA') nc.fontVariantCommonLigatures = feature.enabled
|
||||
else if (feature.tag === 'CALT') nc.fontVariantContextualLigatures = feature.enabled
|
||||
const tag = feature.tag.toUpperCase()
|
||||
if (tag === 'LIGA') nc.fontVariantCommonLigatures = feature.enabled
|
||||
else if (tag === 'CALT') nc.fontVariantContextualLigatures = feature.enabled
|
||||
else if (feature.enabled) toggledOn.push(tag)
|
||||
else toggledOff.push(tag)
|
||||
}
|
||||
|
||||
if (toggledOn.length > 0) nc.toggledOnOTFeatures = toggledOn
|
||||
if (toggledOff.length > 0) nc.toggledOffOTFeatures = toggledOff
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ Figma's design documentation groups features into these areas:
|
|||
| Text case | ✅ | ◐ | — | ✅ | ✅ | Model/export/JSX support; UI missing. |
|
||||
| Vertical text alignment | ✅ | ◐ | — | ✅ | ✅ | Modeled; UI/render parity needs more coverage. |
|
||||
| Justified text | ✅ | ◐ | — | ✅ | ✅ | Modeled; UI does not expose it. |
|
||||
| Font variations / OpenType features | ✅ | ✅ | — | ✅ | — | Imported `fontVariations` and common ligature toggles are applied to CanvasKit text styles and exported; broader OpenType controls are not exposed. |
|
||||
| Font variations / OpenType features | ✅ | ✅ | — | ✅ | — | Imported `fontVariations`, common ligature toggles, and raw `toggledOnOTFeatures` / `toggledOffOTFeatures` are applied to CanvasKit text styles and exported; UI controls are not exposed. |
|
||||
| Variables: collections/modes/aliases | ✅ | ◐ | ◐ | ✅ | ✅ | Color/number/string/boolean model exists; inspector coverage is still incomplete. |
|
||||
| Variables bound to fills/strokes | ✅ | ✅ | ✅ | ✅ | ✅ | Common color bindings render and edit. |
|
||||
| Variables bound to text/layout/visibility/effects | ◐ | ◐ | ◐ | ◐ | ✅ | Some bindings exist; not full Figma property coverage. |
|
||||
|
|
@ -206,7 +206,7 @@ These are parsed or visible in Figma docs and most likely to cause visible diffe
|
|||
1. **Masks** — tune remaining exact Figma stack semantics beyond common alpha/vector/luminance and consecutive-mask paths.
|
||||
2. **Corner smoothing** — expand Figma fixture comparisons and tune remaining stroke/effect edge cases.
|
||||
3. **Pattern/noise/custom fills** — replace the current solid-color fallback with Figma-oracle rendering for schema-level paint objects and transforms beyond image tile fills.
|
||||
4. **Variable-font and rich text fixtures** — broaden real-file coverage for variable axes, derived text data, leading trim, decoration style, semantic font metadata, and additional OpenType feature metadata beyond common ligature toggles.
|
||||
4. **Variable-font and rich text fixtures** — broaden real-file coverage for variable axes, derived text data, leading trim, decoration style, semantic font metadata, and raw OpenType feature metadata.
|
||||
5. **Boolean operation editing** — improve inspector/tooling workflows for imported boolean-operation nodes.
|
||||
6. **Layout grids and guides** — render/edit page guides and Figma layout grids, or clearly keep them round-trip-only.
|
||||
7. **Full component property and slot workflows** — support authoring, not just preserving imported payloads.
|
||||
|
|
|
|||
|
|
@ -10,14 +10,21 @@ describe('Figma font variation export', () => {
|
|||
const text = graph.createNode('TEXT', page.id, {
|
||||
text: 'Axis',
|
||||
fontVariations: [{ axis: 'wght', value: 650 }],
|
||||
fontFeatures: [{ tag: 'LIGA', enabled: false }],
|
||||
fontFeatures: [
|
||||
{ tag: 'LIGA', enabled: false },
|
||||
{ tag: 'DLIG', enabled: true },
|
||||
{ tag: 'KERN', enabled: false }
|
||||
],
|
||||
styleRuns: [
|
||||
{
|
||||
start: 0,
|
||||
length: 2,
|
||||
style: {
|
||||
fontVariations: [{ axis: 'wdth', value: 88 }],
|
||||
fontFeatures: [{ tag: 'CALT', enabled: false }]
|
||||
fontFeatures: [
|
||||
{ tag: 'CALT', enabled: false },
|
||||
{ tag: 'SS01', enabled: true }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -31,9 +38,12 @@ describe('Figma font variation export', () => {
|
|||
])
|
||||
expect(nodeChange.fontVariantCommonLigatures).toBe(false)
|
||||
expect(nodeChange.fontVariantContextualLigatures).toBe(true)
|
||||
expect(nodeChange.toggledOnOTFeatures).toEqual(['DLIG'])
|
||||
expect(nodeChange.toggledOffOTFeatures).toEqual(['KERN'])
|
||||
expect(nodeChange.textData?.styleOverrideTable?.[0]?.fontVariations).toEqual([
|
||||
{ axisTag: 0x77647468, axisName: 'wdth', value: 88 }
|
||||
])
|
||||
expect(nodeChange.textData?.styleOverrideTable?.[0]?.fontVariantContextualLigatures).toBe(false)
|
||||
expect(nodeChange.textData?.styleOverrideTable?.[0]?.toggledOnOTFeatures).toEqual(['SS01'])
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -29,14 +29,18 @@ describe('Figma font variation import', () => {
|
|||
type: 'TEXT',
|
||||
textData: { characters: 'Ligatures' },
|
||||
fontVariantCommonLigatures: false,
|
||||
fontVariantContextualLigatures: true
|
||||
fontVariantContextualLigatures: true,
|
||||
toggledOnOTFeatures: ['DLIG'],
|
||||
toggledOffOTFeatures: ['KERN']
|
||||
} as NodeChange,
|
||||
[]
|
||||
)
|
||||
|
||||
expect(props.fontFeatures).toEqual([
|
||||
{ tag: 'LIGA', enabled: false },
|
||||
{ tag: 'CALT', enabled: true }
|
||||
{ tag: 'CALT', enabled: true },
|
||||
{ tag: 'DLIG', enabled: true },
|
||||
{ tag: 'KERN', enabled: false }
|
||||
])
|
||||
})
|
||||
|
||||
|
|
@ -51,7 +55,8 @@ describe('Figma font variation import', () => {
|
|||
{
|
||||
styleID: 1,
|
||||
fontVariations: [{ axisName: 'GRAD', value: -50 }],
|
||||
fontVariantCommonLigatures: false
|
||||
fontVariantCommonLigatures: false,
|
||||
toggledOnOTFeatures: ['SS01']
|
||||
} as NodeChange
|
||||
]
|
||||
}
|
||||
|
|
@ -63,7 +68,10 @@ describe('Figma font variation import', () => {
|
|||
length: 2,
|
||||
style: {
|
||||
fontVariations: [{ axis: 'GRAD', value: -50 }],
|
||||
fontFeatures: [{ tag: 'LIGA', enabled: false }]
|
||||
fontFeatures: [
|
||||
{ tag: 'LIGA', enabled: false },
|
||||
{ tag: 'SS01', enabled: true }
|
||||
]
|
||||
}
|
||||
}
|
||||
])
|
||||
|
|
|
|||
Loading…
Reference in a new issue