英文页面是权威参考。本译文可能已经过期,可能落后英文版若干个版本;翻译之后有改动的条目会显示英文原文,并带有译文已过期标记。

Kimi Design API 参考

TypeScript 包与 C++ 渲染器的公开 API,由提交 e036c066cb 的源码生成。标有原生的条目会链接到该 TypeScript 方法经由 Wasm 调用的 C 函数;C 函数则用由 TS 调用反向链接回来,并链接到实现它的 C++ 代码。

@taco-slides/model:633 项中已记录 556 项 · @taco-slides/editor:474 项中已记录 308 项 · @taco-slides/render-core:270 项中已记录 196 项 · @taco-design/electron:58 项中已记录 57 项 · C++ 渲染器:310 项中已记录 157 项

@taco-slides/model TypeScript

633 个导出中已记录 556 个 · 大纲

model 包是 Kimi Design 文档与框架无关的唯一可信来源。它定义文档类型,负责加载、保存和校验文档,并把每次编辑记录为一组带撤销历史的操作。它不包含任何编辑器、渲染器或网络代码。

文档被规范化为按 ID 索引的扁平映射:pageOrder、pages、nodes 和 assets,外加一个 theme。每个页面指向一个从不裁剪的根画框或编组,因此页面是一块无边界的画布。容器持有有序的 children 列表。节点不存储父级指针,因此层级结构只有一个可信来源。assertDocument 会拒绝缺失的节点、环、被共享的子节点、不可达的节点、失效的引用以及格式错误的几何数据。

本包返回的值都是深度冻结的。要修改文档,请把 DocumentOperation 传给 applyOperations,或者分派给 DocumentStore;后者还会保存用于撤销、重做和分支的提交历史。

当前版本

本包当前写入的版本号,在构建本页时从源码读取。

文档 schema0.27.0CURRENT_DOCUMENT_SCHEMA_VERSION;参见schema 历史
存储的历史记录1CURRENT_STORE_SCHEMA_VERSION

文档与页面

DesignDocument 保存所有页面、节点、资源和主题资源。页面按 pageOrder 排序,每个页面指明自己的根节点。

type DesignDocument = DesignDocumentV1

源码

一个 Kimi Design 文档。此包返回的值都是深度冻结的;要修改,请使用 applyOperations 或通过 DocumentStore。

interface DesignDocumentV1

源码

CURRENT_DOCUMENT_SCHEMA_VERSION 版本下文档的存储结构。代码中请使用 DesignDocument 别名。

数据被规范化为以 ID 为键的扁平映射。assertDocument 会检查:每个页面根节点都存在,每个节点恰好能从一个页面到达且最多有一个父节点,不存在环,并且样式、变量、连接线、媒体节点和字体的引用都能解析。(ImagePaint.assetId 不会对照资源映射检查。)

readonly schemaVersion: typeof CURRENT_DOCUMENT_SCHEMA_VERSION源码
readonly id: DocumentId源码
readonly title: string源码
readonly pageOrder: readonly PageId[]源码

每个页面 ID 恰好出现一次,按显示顺序排列。

readonly pages: Readonly<Record<string, Page>>源码
readonly nodes: Readonly<Record<string, SceneNode>>源码

所有页面上的所有节点,以 NodeId 为键。

readonly assets: Readonly<Record<string, Asset>>源码

图片、视频和字体,以 AssetId 为键。

readonly theme: DocumentTheme源码
readonly components?: Readonly<Record<string, ComponentDefinition>>自 0.23.0源码

Reusable layer trees, keyed by ComponentId. Omitted when empty. Each component’s layers live in nodes under its rootId, on no page.

readonly metadata?: Readonly<Record<string, JsonValue>>源码

随文档保存的自由格式 JSON 数据。模型不会读取它。

interface Page

源码

文档中的一个页面。页面是无边界的画布:其根容器从不裁剪,因此顶层节点可以位于任何位置,根节点的 frame 只记录可见范围(见 pageRootFrame)。

readonly id: PageId源码

与该页面在 DesignDocument.pages 中的键一致。

readonly name: string源码

不能为空。

readonly rootId: NodeId源码

页面的根节点:没有父节点的画框或编组。

readonly guides?: readonly Guide[]自 0.11.0源码

页面画布上的标尺参考线,使用页面坐标。为空时省略。

readonly variableModes?: VariableModes自 0.26.0源码

The page’s mode per variable collection. Layers set to Auto inherit it; a collection left out uses the collection’s activeModeId.

readonly metadata?: Readonly<Record<string, JsonValue>>源码

interface Guide

自 0.11.0源码

标尺参考线:仅在编辑器中使用的直线,用于定位对象。渲染器从不绘制它,因此它永远不会出现在导出结果中。

readonly axis: "x" | "y"源码

“x” 表示位于 x = offset 处的竖直线;“y” 表示位于 y = offset 处的水平线。

readonly offset: number源码

沿坐标轴的位置,以文档单位表示,相对于承载该参考线的对象:页面参考线相对于页面原点,画框参考线相对于画框的左上角。

type DocumentSchemaVersion = number | SemanticVersion

源码

文档 schema 版本。当前文档使用 SemanticVersion;数字形式只在读取 0.0.0 版本之前保存的旧文件时使用。

type SemanticVersion = `${number}.${number}.${number}`

源码

major.minor.patch 形式的版本字符串,例如 "0.14.0"。

const CURRENT_DOCUMENT_SCHEMA_VERSION: "0.27.0"

源码

此包读写的 schema 版本。deserializeDocument 会把较旧的文档迁移到此版本,assertDocument 会拒绝任何其他版本。

function pageRootFrame( document: DesignDocument, pageId: PageId ): Rect | undefined

源码

页面根节点的 frame 即页面的可见范围:编辑器将其适配到屏幕上的区域,渲染器也据此确定场景尺寸。页面根节点从不裁剪,因此顶层节点可以位于其外部。

场景节点

SceneNode 是一个按 type 区分的联合类型:frame、group、text、code、shape、image、video 和 connector。形状再按 shape 进一步区分。每个节点都具有 NodeBase 的字段;除路径外,每个节点还通过一个框和旋转来定位(FramedNodeBase)。

type SceneNode = | FrameNode | GroupNode | TextNode | CodeNode | ShapeNode | ImageNode | VideoNode | ConnectorNode | InstanceNode

源码

页面树中的任意节点,通过其 type 字段区分。节点存放在扁平的 DesignDocument.nodes 映射中;容器按 ID 列出其子节点,父节点不被存储。

interface NodeBase

源码

每个 SceneNode 都具有的字段。

readonly id: NodeId源码

与该节点在 DesignDocument.nodes 中的键一致。

readonly name: string源码

图层名称。不能为空。

readonly visible: boolean源码
readonly locked: boolean源码

防止该节点在编辑器画布上被编辑。

readonly opacity: number源码

取值从 0(透明)到 1(不透明)。

readonly blendMode?: BlendMode自 0.8.0源码

该节点如何与其后方的内容合成;省略时为 normal。

readonly mask?: boolean自 0.8.0源码

蒙版会在其自身绘制的 alpha 之外隐藏其后续同级节点,而自身不绘制任何内容。隐藏的蒙版不遮罩任何内容。

readonly aspectRatioLocked?: boolean自 0.1.1源码

调整节点大小时保持宽高成比例。

readonly variableBindings?: VariableBindings源码

其值来自主题变量的属性。

readonly exportSettings?: readonly ExportSetting[]自 0.14.0源码

该节点导出区域中的各行,按顺序排列。为空时省略。

readonly expressions?: NodeExpressions自 0.24.0源码

Computed fields: expression source text keyed by field, for nodes under a component root only (see ComputableField and computableFieldsOf). The plain field keeps the base value, which the expression reads as stored and which is shown when the expression does not check. A field holds a variable binding or an expression, never both. Omitted when empty.

readonly condition?: string自 0.24.0源码

A boolean expression; when it is false the layer and its sublayers are left out of every instance. Only on layers under a component root, never on the root itself. An expression that does not check counts as no condition.

readonly constraints?: ResizeConstraints自 0.25.0源码

How the layer follows its frame when the frame is resized (see ResizeConstraints). Omitted means Left and Top: the layer keeps its position and size. Used for children of frames without auto layout and for absolute children of auto layout frames; ignored elsewhere. Never on a group: constraints set on a group are set on its layers, as in Figma.

readonly layoutPositioning?: "absolute"自 0.25.0源码

"absolute" takes a child of an auto layout frame out of the flow, like Figma’s “Ignore auto layout”: the layout neither moves it nor counts it when hugging, and it follows the frame’s size changes by its constraints. Ignored when the parent has no auto layout.

readonly variableModes?: VariableModes自 0.26.0源码

The mode this layer and its sublayers use for each variable collection (see VariableModes). A collection left out is Auto: the layer inherits the mode from its parent. On an instance, the modes apply to the component’s layers, so two instances of one component can show two modes.

readonly metadata?: Readonly<Record<string, JsonValue>>源码

与节点一起保存的自由格式 JSON 数据。模型不会读取它。

interface FramedNodeBase extends NodeBase

源码

所有由矩形定位的节点共有的字段:适用于除 PathNode 以外的所有类型,后者改用变换矩阵定位。

readonly frame: Rect源码

位置和未旋转时的尺寸,位于父节点的坐标系中(相对于父节点画框的左上角)。

readonly rotation: number源码

角度,单位为度,在屏幕上顺时针,绕画框中心旋转。

readonly flipX?: boolean源码

以局部水平中心为轴镜像渲染后的节点。

readonly flipY?: boolean源码

以局部垂直中心为轴镜像渲染后的节点。

frame、rotation 和翻转共同把局部点 p\mathbf{p}(原点位于画框左上角)放到父节点中的

pparent=[x+w/2y+h/2]+RθF(p−[w/2h/2]),Rθ=[cos⁡θ−sin⁡θsin⁡θcos⁡θ],F=[±100±1]\mathbf{p}_\text{parent} = \begin{bmatrix} x + w/2 \\ y + h/2 \end{bmatrix} + R_\theta F \left(\mathbf{p} - \begin{bmatrix} w/2 \\ h/2 \end{bmatrix}\right), \quad R_\theta = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}, \quad F = \begin{bmatrix} \pm 1 & 0 \\ 0 & \pm 1 \end{bmatrix}

其中 θ\theta 是以弧度表示的 rotation,FF 在每个已设置翻转的轴上取 −1-1。先翻转,再旋转。

readonly resizing?: NodeResizing自 0.15.0源码

填充尺寸和尺寸限制。为空时省略。

type ContainerNode = FrameNode | GroupNode

源码

拥有 children 的节点。用 isContainerNode 判断。

const isContainerNode: (node: SceneNode) => node is ContainerNode

源码

对画框和编组为 true,即拥有 children 的节点。

interface FrameNode extends FramedNodeBase

源码

拥有自身尺寸、填充、描边和效果的容器,可选择使用自动布局。每个页面的根节点是一个画框或编组;页面根节点从不裁切内容。

readonly type: "frame"源码
readonly children: readonly NodeId[]源码

按绘制顺序排列的子节点 ID:第一个子节点位于最底层。

readonly layout: Layout源码

子节点的定位方式:自由定位,或由堆叠或网格自动布局定位。

readonly style?: VisualStyle源码
readonly clipContent?: boolean源码

隐藏子节点中超出画框的部分。

readonly guides?: readonly Guide[]自 0.11.0源码

属于此画框并随其移动的标尺参考线。编辑器只在既未旋转也未翻转的顶层画框上显示它们。为空时省略。

interface GroupNode extends FramedNodeBase

源码

自身没有尺寸的容器:它的 frame 始终适配为其子节点边界的并集(见 fitGroupToChildren)。当 applyOperations 移除了编组的最后一个子节点时,该编组也会被移除。

readonly type: "group"源码
readonly variableBindings?: GroupVariableBindings源码

Properties whose values come from theme variables. A group’s size is computed from its layers, so it cannot bind width or height.

readonly children: readonly NodeId[]源码

按绘制顺序排列的子节点 ID:第一个子节点位于最底层。

readonly clipContent?: boolean源码

interface TextNode extends FramedNodeBase

源码

由带样式的段落组成的文本框。

readonly type: "text"源码
readonly paragraphs: readonly TextParagraph[]源码
readonly verticalAlign: "top" | "middle" | "bottom"源码

当 frame 比文本高时,文本在 frame 中的垂直位置。

readonly overflow: "clip" | "visible"源码

超出 frame 的文本是被裁掉还是仍然绘制。

readonly autoResize: "none" | "height" | "width-and-height"源码

none 保持 frame 的两个尺寸固定,height 保持宽度并让高度随文本变化,width-and-height 让两者都随文本变化。

readonly wrap: "none" | "word" | "character"源码

长行可以在何处换行:从不换行、在单词之间换行,或在任意字符之间换行。

type TextualNode = TextNode

源码

包含可编辑富文本的节点。目前只有 TextNode。

const isTextualNode: (node: SceneNode) => node is TextualNode

源码

对包含富文本的节点(TextNode)为 true。

interface CodeNode extends FramedNodeBase

源码

一段源代码。语法高亮在渲染时计算,只存储原始源代码。

readonly type: "code"源码
readonly source: string源码
readonly language: string源码

用于高亮的语言标识符。不能为空。

readonly fontFamily: string源码

统一应用于整段源代码,而不是单个文本片段。

readonly fontSize: number源码

统一应用于整段源代码,而不是单个文本片段。为正数。

readonly codeStyleId?: CodeStyleId源码

主题中的代码样式;省略时使用主题的 defaultCodeStyleId。

readonly codeStyleOverrides?: Partial< Pick< CodeStyle, "lineHeight" | "letterSpacing" | "background" | "foreground" | "syntax" > >源码

仅对此节点替换代码样式中对应值的取值。

readonly lineNumbers: boolean | number源码

false 隐藏行号,true 从 1 开始编号,数字则设置首行的行号。

readonly autoResize: "none" | "height" | "width-and-height"自 0.1.3源码

含义与 TextNode.autoResize 相同。

readonly wordWrap: boolean源码

按画框宽度对过长的源代码行自动换行。

readonly stroke?: Stroke自 0.1.4源码

绘制在代码块四周的描边。

readonly decorations: readonly CodeDecoration[]源码

interface CodeDecoration

源码

CodeNode 源代码中被标记的一段范围。

readonly from: number源码

在 source 中的起始偏移,以 UTF-16 码元计。

readonly to: number源码

结束偏移(不含),取值从 from 到源代码长度。

readonly kind: "emphasis" | "addition" | "deletion" | "annotation"源码
readonly label?: string源码

type ShapeNode = | RectangleNode | EllipseNode | PolygonNode | StarNode | LineNode | PathNode

源码

所有 type: "shape" 的节点,通过其 shape 字段区分。

interface RectangleNode extends FramedNodeBase

源码

填满其 frame 的矩形;VisualStyle.cornerRadius 为其设置圆角。

readonly type: "shape"源码
readonly shape: "rectangle"源码
readonly style: VisualStyle源码

interface EllipseNode extends FramedNodeBase

源码

填满其画框的椭圆,或椭圆的圆弧、扇形或圆环。

readonly type: "shape"源码
readonly shape: "ellipse"源码
readonly style: VisualStyle源码
readonly arc?: EllipseArc自 0.12.0源码

省略时绘制完整的椭圆。

interface EllipseArc

自 0.12.0源码

把椭圆变成圆弧、扇形或圆环,与 Figma 的弧形数据相同。角度以度为单位,在椭圆的参数角上从 x 轴正方向顺时针测量。扫描范围从起始角度到结束角度,任一方向上最多一整圈。

readonly startingAngle: number源码
readonly endingAngle: number源码
readonly innerRadius: number源码

内半径,以外半径的比例表示,取值从 0(扇形)到小于 1(圆环)。

interface PolygonNode extends FramedNodeBase

自 0.12.0源码

正多边形,其顶点经缩放以填满 frame,第一个顶点位于顶部中央,与 Figma 的绘制方式一致。

readonly type: "shape"源码
readonly shape: "polygon"源码
readonly pointCount: number源码

角的数量,为 3 到 60 之间的整数。

readonly style: VisualStyle源码

interface StarNode extends FramedNodeBase

自 0.12.0源码

星形,其外顶点和内顶点经缩放以填满 frame。

readonly type: "shape"源码
readonly shape: "star"源码
readonly pointCount: number源码

外顶点的数量,为 3 到 60 之间的整数。

readonly innerRadius: number源码

内顶点的距离,以外半径的比例表示,范围为 0 到 1。

readonly style: VisualStyle源码

interface LineNode extends FramedNodeBase

自 0.12.0源码

单条直线描边。与 Figma 一样,其 frame 高度为零:直线从 frame 局部坐标 (0, 0) 延伸到 (width, 0),旋转使其绕 frame 中心转动。箭头就是带有箭头端点的直线。

readonly type: "shape"源码
readonly shape: "line"源码
readonly style: VisualStyle源码
readonly startCap: StrokeCap源码
readonly endCap: StrokeCap源码

interface PathNode extends NodeBase

源码

可编辑的矢量形状。与其他形状不同,它没有 frame 或旋转:transform 将矢量网络放置到父节点中,其边界由变换后的网络推导得出(见 getNodeBounds)。

readonly type: "shape"源码
readonly shape: "path"源码
readonly vectorNetwork: VectorNetwork自 0.2.0源码

路径的几何形状。

readonly transform: TransformMatrix源码

将网络坐标映射到父节点的坐标系。

readonly style: VisualStyle源码
readonly startCap?: StrokeCap自 0.22.0源码

The end points of an open path whose segments form one chain, each in order from the end of the one before (see openPathChainEnds): the start cap sits on the first segment’s start and the end cap on the last segment’s end, the same styles a line has. Omitted is round, which every path drew before 0.22.0. Closed paths and paths with branches or several chains ignore them, and so does a path with an inside or outside stroke.

readonly endCap?: StrokeCap自 0.22.0源码

interface ImageNode extends FramedNodeBase

源码

放置的图片。像素数据存放在 ImageAsset 中。

readonly type: "image"源码
readonly assetId: AssetId源码

必须指向一个类型为 image 的资源。

readonly fit: MediaFit源码
readonly crop?: Rect源码

要显示的源图片部分,以源像素表示。

readonly alt: string源码

用于无障碍访问的替代文本;可以为空。

interface VideoNode extends FramedNodeBase

源码

放置的视频。文件存放在 VideoAsset 中。

readonly type: "video"源码
readonly assetId: AssetId源码

必须指向一个类型为 video 的资源。

readonly fit: MediaFit源码
readonly crop?: Rect源码

要显示的视频画面部分,以源像素表示。

readonly alt: string源码

用于无障碍访问的替代文本;可以为空。

type MediaFit = "contain" | "cover" | "fill"

源码

图片或视频如何填满其 frame,与 CSS object-fit 相同。

interface ConnectorNode extends FramedNodeBase

源码

两点之间带描边的直线或箭头,每个端点都可以选择连接到某个节点。

readonly type: "connector"源码
readonly start: ConnectorEndpoint源码
readonly end: ConnectorEndpoint源码
readonly routing: "straight" | "elbow" | "curve"源码
readonly stroke: Stroke源码
readonly startCap: StrokeCap自 0.20.0源码

The end styles, the same set a line has (STROKE_CAPS). Before 0.20.0 a connector had only "none", "arrow" and "dot"; loading an older document turns "arrow" into "triangle-arrow" and "dot" into "circle-arrow".

readonly endCap: StrokeCap源码
readonly cornerRadius?: number自 0.21.0源码

How far, in pixels, each bend of an elbow connector is rounded, as Figma’s ConnectorNode.cornerRadius. A bend never rounds past half of either part of the line it joins, so a short part keeps a smaller curve. The ends and end styles are not rounded. Straight and curved connectors have no bends and ignore it. Missing means 0: sharp bends. Not negative.

readonly cornerSmoothing?: number自 0.21.0源码

How far each rounded bend of an elbow connector eases into the line, from 0 (a circular arc) to 1 (a continuous curve), the same fraction as a rectangle’s NodeVisualStyle.cornerSmoothing and drawn the same way. A smoothed bend takes up to (1 + cornerSmoothing) * cornerRadius of each part of the line it joins, capped at half of the shorter part, which also caps the smoothing. It has no effect without a corner radius, or on straight and curved connectors. Figma’s ConnectorNode has no smoothing; this extends it. Missing means 0.

interface ConnectorEndpoint

源码

译文已过期

One end of a ConnectorNode.

An end with nodeId attaches to that layer, and the page compiler places it from the layer’s frame each time, so it follows the layer when the layer moves or resizes. Where on the layer it goes is set by at most one of:

  • side: the middle of that side, and an elbow connector leaves the layer at a right angle to it. Figma calls this a magnet (TOP, RIGHT, BOTTOM or LEFT in the plugin API’s ConnectorEndpointConnectedWithMagnet). On an ellipse, polygon or star the end is where the shape’s outline meets the line from its centre toward that side, so it sits on the drawn shape.
  • anchor: a corner or edge middle of a polygon, star or ellipse arc (ConnectorAnchor); the end leaves along the outline’s outward direction there.
  • point: a fixed point on the layer, as FigJam places an end dropped with Command or Ctrl held (ConnectorEndpointConnectedWithPosition). Figma stores it in the layer’s pixels; here it is a fraction of the layer’s width and height, so the point keeps its place when the layer resizes.

With none of them (Figma’s AUTO magnet), the end goes where the layer’s outline faces the other end. x and y are the end’s position in the connector’s frame; for an attached end they record where it was last placed and are replaced when the connector is drawn.

readonly nodeId?: NodeId源码

此端连接的节点。它必须与连接线位于同一页面。

readonly x: number源码
readonly y: number源码
readonly side?: ConnectorSide自 0.20.0源码

The side of the attached layer this end is pinned to. Needs nodeId, and cannot be set together with point or anchor.

readonly anchor?: ConnectorAnchor自 0.20.0源码

The key point on the attached shape’s outline this end is pinned to. Needs nodeId, and cannot be set together with side or point.

readonly point?: { readonly x: number; readonly y: number }自 0.20.0源码

The point on the attached layer this end is fixed to, as fractions of the layer’s width (x) and height (y) from its top-left corner: { x: 1, y: 0.5 } is the middle of the right side. Each fraction is between 0 and 1. Needs nodeId, and cannot be set together with side or anchor.

type ConnectorSide = "top" | "right" | "bottom" | "left"

自 0.20.0源码

A side of a layer that an attached connector end is pinned to.

interface ConnectorAnchor

自 0.20.0源码

A key point on a shape’s outline that an attached connector end is pinned to, found from the shape’s geometry each time the connector is drawn, so the end follows the shape when it moves, resizes or changes its points.

  • vertex: corner index of the outline, counted as polygonPoints and starPoints list them (clockwise from the top point; a star’s outer tips are the even indices). On an ellipse arc, vertex 0 is where the arc starts and vertex 1 where it ends, on the outer rim.
  • edge: the middle of the outline’s edge from vertex index to the next.

An index the shape does not have (for example after a polygon loses points), or an anchor on a layer without such points, leaves the end automatic, as if it had no anchor.

readonly kind: "vertex" | "edge"源码
readonly index: number源码

A whole number from 0.

type BlendMode = (typeof BLEND_MODES)[number]

源码

const BLEND_MODES: readonly [ "normal", "darken", "multiply", "color-burn", "lighten", "screen", "color-dodge", "overlay", "soft-light", "hard-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity" ]

自 0.8.0源码

可分离与不可分离的合成模式,采用 CSS mix-blend-mode 的术语。

画框可以用自动布局来定位子节点,而不必手动摆放。堆叠把子节点排成一行或一列,并可换到多行;网格把子节点放进等宽的列中。画框在每个轴上选择固定(Fixed)或包裹内容(Hug),而每个子节点在 NodeResizing 中选择是否填充父节点给出的空间,以及适用的尺寸限制。这些都遵循 Figma 的自动布局,包括它的规则:当某个堆叠子节点在某个轴上填充时,画框在该轴上停止包裹内容。

type Layout = AbsoluteLayout | AutoLayout

源码

interface AbsoluteLayout

源码
readonly kind: "absolute"源码

type AutoLayout = StackAutoLayout | GridAutoLayout

源码

interface StackAutoLayout extends AutoLayoutConstraints

源码

横排("horizontal")或竖排("vertical")的自动布局。主轴沿堆叠方向,交叉轴与之垂直。

readonly kind: "vertical" | "horizontal"源码
readonly gap: number源码

子节点在主轴上的间距。

readonly padding: LayoutPadding源码
readonly align: "start" | "center" | "end"源码

子节点在所在行内的交叉轴位置。子节点要横跨整行,需在 FramedNodeBase.resizing 中设置交叉轴填充。schema 0.15.0 移除了作用于整个画框的 "stretch"。

readonly justify: | "start" | "center" | "end" | "space-between" | "space-around" | "space-evenly"源码

子节点在每一行内沿主轴如何分布。space-* 取值用一个永不为负的自动间距代替 gap:space-between 把所有剩余空间放在子节点之间(只有一个子节点时它位于起点),space-around 在第一个子节点之前和最后一个之后各放半个间距,space-evenly 则各放一整个间距(两者都把单个子节点居中)。子节点溢出时,三者都从起点依次排列。schema 0.15.0 新增了 "space-around" 和 "space-evenly"。

readonly wrap?: boolean自 0.15.0源码

把放不下的子节点移到新的一行:横向堆叠换到新行,竖向堆叠换到新列。省略表示只有一行。

readonly wrapGap?: number自 0.15.0源码

换行后各行之间的间距。省略表示与 gap 相同。wrap 关闭时保留但不使用。

readonly alignContent?: "auto" | "space-between"自 0.15.0源码

换行后的各行如何分配交叉轴。"auto"(默认)按 align 排列各行,或在每个子节点都在交叉轴上填充时,把剩余空间平均分给各行;"space-between" 用永不为负的自动间距把各行分开。wrap 关闭时保留但不使用。

interface GridAutoLayout extends AutoLayoutConstraints

源码
readonly kind: "grid"源码
readonly columns: number源码
readonly columnGap: number源码
readonly rowGap: number源码
readonly padding: LayoutPadding源码

interface AutoLayoutConstraints

源码

画框自身的尺寸设置。尺寸限制已在 0.15.0 中移到 FramedNodeBase.resizing。

readonly widthSizing: LayoutSizing源码

"hug" 让画框在这个轴上按内容定尺寸。在堆叠中,若有子节点在同一轴上填充,画框改为保持其存储的尺寸,这与 Figma 在这种情况下停止包裹内容一致。网格仍保持包裹内容:其填充子节点占据所在的单元格,而单元格的尺寸由其他子节点决定。

readonly heightSizing: LayoutSizing源码

interface LayoutPadding

源码
readonly top: number源码
readonly right: number源码
readonly bottom: number源码
readonly left: number源码

type LayoutSizing = "fixed" | "hug"

源码

自动布局画框在一个轴上如何确定自身尺寸:保持存储的尺寸(Fixed,固定),或包裹内容(Hug)。填充父节点则在子节点上用 FramedNodeBase.resizing 设置。

interface NodeResizing

自 0.15.0源码

自动布局可以如何让节点的尺寸不同于其存储的画框。

把 width 或 height 设为 "fill",会让堆叠或网格自动布局的子节点在该轴上占据父节点给出的空间:同一行中的填充子节点平分该行主轴上的剩余空间,交叉轴上的填充占据该行的交叉尺寸,网格子节点填满其单元格。这个标志在自动布局之外、对旋转的节点、编组和连接线都不起作用。节点不能在它包裹自身内容的轴上填充(自动布局画框的 "hug" 尺寸,或文本和代码节点的 autoResize)。

尺寸限制约束自动布局给节点的尺寸:填充子节点分得的空间,以及自动布局画框自身的包裹内容或固定尺寸。

readonly width?: "fill"源码
readonly height?: "fill"源码
readonly minWidth?: number源码
readonly maxWidth?: number源码
readonly minHeight?: number源码
readonly maxHeight?: number源码

译文已过期

A few rules are shared with the editor’s drop slots so both break a wrapping row or column at the same children. stackLineBreaks splits the children into lines from the sizes stackLineBreakSize gives; fillsAxis and canFillParent say when a child takes a Fill size.

type LayoutAxis = "width" | "height"

源码

节点的一个尺寸轴:宽度或高度。

function nodeResizing(node: SceneNode): NodeResizing | undefined

源码

节点的填充标志和尺寸限制;路径返回 undefined。

function canFillParent(node: SceneNode): boolean

源码

自动布局能否给 node 一个填充(Fill)尺寸:它的框必须就是它的画框(不是路径,没有旋转),并且它不能是编组或连接线,因为它们的尺寸来自其他节点。

function fillsAxis(node: SceneNode, axis: LayoutAxis): boolean

源码

node 是否在 axis 上填充其自动布局父节点。

function stackLineBreakSize(node: SceneNode, mainAxis: LayoutAxis): number

源码

拆分行时堆叠子节点所取的主轴尺寸:其框的尺寸,或在它于主轴上填充时取其最小尺寸。

function stackLineBreaks( layout: Pick<StackAutoLayout, "gap" | "justify" | "wrap">, availableMain: number, sizes: readonly number[] ): number[][]

源码

像 Figma 的换行那样把一行或一列拆分成多行:子节点保持顺序,一个子节点会超出 availableMain(画框去掉内边距后的主轴尺寸)时就开始新的一行。自动间距(between、around 或 evenly)在这里按零计算。不换行时只有一行。

sizes 是 stackLineBreakSize 给出的子节点主轴尺寸。按行分组返回子节点的索引;没有子节点时没有行。

The layout itself runs whenever the editor edits the document: withAutoLayoutOperations adds the node replacements that keep every affected auto layout frame laid out. layoutFrameTree lays out one frame and the frames inside it, and applyFrameLayout places one frame’s children. createFrameLayout makes a new layout of a given kind.

function withAutoLayoutOperations( document: DesignDocument, operations: readonly DocumentOperation[] ): readonly DocumentOperation[]

源码

operations followed by the node replacements that keep auto layout frames laid out after them: frames the operations touch are laid out again, deepest first, and nodes the operations leave filling a parent without auto layout become Fixed. In a document with components, a text whose content is computed is first sized for the text it shows (fitComputedTextContent), and the component cascade then runs (cascadeComponentChanges): instances of changed components are refitted to their hugging size, their dead override keys dropped, and their ancestors laid out again, nested components first. The operations come back unchanged when nothing needs it.

function layoutFrameTree( nodes: Record<string, SceneNode>, frameId: NodeId, changed: Set<NodeId> = new Set() ): Set<NodeId>

源码

Lays out the auto layout frame frameId in nodes (changed in place), then lays out again each child frame whose size it changed, so Fill sizes reach nested auto layouts, and each auto layout frame that constraints resized. Returns the IDs of every node it changed. The caller lays out hugging descendants first, deepest first, so their sizes are known.

function applyFrameLayout( frame: FrameNode, childNodes: readonly SceneNode[], layout: Layout ): AppliedFrameLayout

源码

Lays out one frame’s direct children with layout and returns the frame with its new size and the moved or resized children. Child frames are not laid out again here; layoutFrameTree does that.

interface AppliedFrameLayout

源码

A frame and its children after applyFrameLayout has placed them.

readonly frame: FrameNode源码
readonly children: ReadonlyMap<NodeId, SceneNode>源码

function createFrameLayout( kind: Layout["kind"], gap = DEFAULT_AUTO_LAYOUT_GAP ): Layout

源码

A new layout of the given kind. Auto layouts start with a fixed width, a hugged height, no padding and gap between children (a grid uses it for both its column and row gaps).

function frameLayoutGap(layout: Layout): number

源码

The gap a layout keeps between children: a stack’s gap or a grid’s column gap. Without an auto layout it is DEFAULT_AUTO_LAYOUT_GAP.

const DEFAULT_AUTO_LAYOUT_GAP: 24

源码

The gap, in pixels, a new auto layout starts with.

Resize constraints say how a layer follows its frame when the frame is resized, with Figma’s five options on each axis: Left, Right, Left and right, Center and Scale horizontally, and their vertical counterparts. They apply to the children of frames without auto layout and to the absolute children of auto layout frames (layoutPositioning: "absolute", Figma’s “Ignore auto layout”), which the layout leaves out of its flow. constrainChildren places a frame’s children for a change of its size; the editor’s frame resize, the selection box and group resizing all use it, and so does layoutFrameTree when a layout changes a frame’s size. scaleLayerInParent scales one layer the way a resized box does.

interface ResizeConstraints

自 0.25.0源码

A layer’s resize constraints, Figma’s five options on each axis. They act on the layer’s axis-aligned bounds in its frame (see constrainChildren).

readonly horizontal: HorizontalConstraint源码
readonly vertical: VerticalConstraint源码

type HorizontalConstraint = "left" | "right" | "left-right" | "center" | "scale"

自 0.25.0源码

How a layer’s horizontal position and width follow its frame’s width. "left", "right" and "center" keep the width and the distance to the left edge, the right edge or the center line; "left-right" keeps both distances, so the width changes with the frame; "scale" keeps the layer’s position and width as shares of the frame’s width.

type VerticalConstraint = "top" | "bottom" | "top-bottom" | "center" | "scale"

自 0.25.0源码

How a layer’s vertical position and height follow its frame’s height; the vertical counterpart of HorizontalConstraint.

const DEFAULT_RESIZE_CONSTRAINTS: ResizeConstraints

自 0.25.0源码

The constraints a layer has when it stores none: Left and Top, Figma’s default, which keeps the layer’s position and size.

function nodeConstraints(node: SceneNode): ResizeConstraints

自 0.25.0源码

A layer’s constraints, with DEFAULT_RESIZE_CONSTRAINTS when it stores none.

function followsConstraints(parent: FrameNode, child: SceneNode): boolean

自 0.25.0源码

Whether a child of parent is placed by its constraints when parent resizes: every child of a frame without auto layout, and only the absolute children (layoutPositioning: "absolute") of an auto layout frame, whose other children the layout places.

function constrainChildren( nodes: NodeRecord, parentId: NodeId, from: FrameSize, to: FrameSize ): readonly SceneNode[]

自 0.25.0源码

Places each child of the frame parentId for a resize of that frame from from to to, by the child’s constraints (NodeBase.constraints), as Figma does when a frame is resized. nodes holds the frame and its descendants before the change; the frame’s own record is only read for its children and layout, so it may hold either size.

  • Constraints act on each child’s axis-aligned bounds in the frame. A child whose bounds change size is resized like a layer in a resized selection box (scaleLayerInParent): a rotated or flipped layer keeps its rotation and flips, and a frame’s own children follow by their constraints in turn.
  • An auto layout frame’s flow children are left to its layout; only its absolute children move (followsConstraints). A child auto layout frame whose size changes is not laid out again here: the caller does that, as layoutFrameTree or the editor’s auto layout step do.
  • A group has no constraints of its own. The layers of an upright group (not rotated or flipped) are placed one by one by their own constraints relative to the frame, and the group is fitted to them again. A rotated or flipped group moves and resizes as one layer, by the option its layers share on each axis, or Left or Top when they differ.

Returns every changed node, children before descendants, each at most once. An unchanged size returns an empty list.

The instance resolver calls this to lay out a resized instance whose component root has no auto layout: constrainChildren(nodes, rootId, componentRoot.frame, instance.frame), writing the result into its node record before it lays out auto layout frames with layoutFrameTree.

interface FrameSize

自 0.25.0源码

A frame’s size before or after a resize. Constraints only need sizes: children are placed relative to their frame’s top-left corner, so where the frame moves on the page does not matter.

readonly width: number源码
readonly height: number源码

function scaleLayerInParent( nodes: NodeRecord, node: SceneNode, scaleX: number, scaleY: number ): readonly SceneNode[]

自 0.25.0源码

Scales a layer’s position and size by (scaleX, scaleY) about its parent’s origin, in the parent’s coordinates, the way resizing a group or a selection box moves the layers inside it. Positions, sizes and vector geometry scale; stroke widths, corner radii, effects and font sizes do not.

  • A rotated layer keeps its rotation and takes the size whose bounds are its old bounds scaled, when the rotation allows it (see the source of rotatedSize for the fallback near 45 degrees).
  • A group’s descendants scale with it.
  • A frame’s box scales and its children follow by their constraints (constrainChildren); an auto layout places its other children later.
  • Text or code that grew with its content gets a fixed size.

Returns the layer followed by every changed descendant. nodes must hold the layer’s descendants.

The sizing helpers read and change a node’s Fixed, Hug or Fill sizing on each axis, keeping the rules of Figma’s resizing menu: only auto layout frames, instances of a component with auto layout, text and code can hug, and only children of an auto layout frame can fill. nodeAxisSizing is the one reader and withAxisSizing the one writer of Fixed and Hug: an instance’s sizing is its override of its component root’s sizing, so both take the document. withManualSize is the one place a size changed by hand (a resize, the Scale tool, a size variable) gets the sizing that keeps it: commands and drag previews pass their node through it.

type AxisSizing = "fixed" | "hug" | "fill"

源码

How a node is sized on one axis, as the width and height menus show it (Figma’s resizing menu): a stored size, its content’s size, or the space its auto layout parent gives it.

type SizingAxis = "width" | "height"

源码

The axis a sizing applies to.

function nodeAxisSizing( document: DesignDocument, node: SceneNode, axis: SizingAxis ): AxisSizing

源码

The node’s sizing on an axis: the one reader of it. Nodes that cannot hug or fill are Fixed. An auto layout frame’s is its layout’s; text and code read their automatic sizing. An instance has no layout of its own: its sizing is its override of its component root’s sizing (LayerSizingOverride, stored under the root’s path), and the root’s own sizing where it has none, which is what the instance resolver lays it out with. Fill is the node’s own resizing for every kind of node.

function canHugAxis(document: DesignDocument, node: SceneNode): boolean

源码

Auto layout frames hug their children, text and code blocks hug their content, and an instance hugs as its component root does: only when the root has auto layout.

function canFillAxis( document: DesignDocument, node: SceneNode, axis: SizingAxis, parent: SceneNode | undefined = parentNodeOf(document, node.id) ): boolean

源码

Whether the node can fill its parent on an axis: it must be a child of an auto layout frame, and not a path, group or connector, a rotated node, or (for the height) a line, whose height is always zero. Figma offers Fill container only on children of auto layout frames.

function withoutFill(node: SceneNode, axis: SizingAxis): SceneNode

源码

The node without a Fill flag on the axis.

function withoutAnyFill(node: SceneNode): SceneNode

源码

The node without any Fill flag, keeping its size limits.

function withAxisSizing( document: DesignDocument, node: SceneNode, axis: SizingAxis, sizing: "fixed" | "hug" ): SceneNode

源码

The node with its sizing on axis set to Fixed or Hug: the one writer of it, the counterpart of nodeAxisSizing. An auto layout frame stores it in its layout; an instance stores it as its override of its component root’s sizing. A node that has neither (a shape, a frame without auto layout, an instance of a component without auto layout) is returned as it is, and so is text or code, whose automatic sizing has rules of its own (sizingReplacements). Fill is not touched: see withoutFill.

type ManualSizeChange = "resize" | "scale" | "variable"

源码

How a layer’s size was changed by hand, as opposed to by a layout, a constraint or its content:

  • "resize": a resize handle, a typed W or H, the box around a selection, a moved end of a line.
  • "scale": the Scale tool, on one layer or on the box around a selection.
  • "variable": a size variable bound to W or H.

function withManualSize( document: DesignDocument, before: SceneNode, after: SceneNode, change: ManualSizeChange, axes: readonly SizingAxis[] = changedSizeAxes(before, after) ): SceneNode

源码

after, the node before with a size changed by hand, with the sizing that change leaves: the one place the rule “a size set by hand is kept” is written. Every command that changes a size by hand, and every preview of one, passes its node through here, so the release commits what the drag drew and the next layout does not undo it.

  • A resize, on each axis whose size changed: Fill and Hug become Fixed (an instance’s Hug too) and a size variable on the axis is dropped.
  • The Scale tool, on each axis whose size changed: an instance’s Hug becomes Fixed, since its layers are its component’s and do not scale. A frame keeps Hug: its children scaled with it, so it hugs the scaled size. Fill and a size variable are left as they are.
  • A size variable: Fill and Hug become Fixed on axes, which the caller names because the variable’s value may equal the size the node has.

A size that a layout, a constraint or the node’s content gives is not a change by hand and does not come here: the sizing stays.

function withManualSizes( document: DesignDocument, nodes: readonly SceneNode[], change: ManualSizeChange, only?: ReadonlySet<NodeId> ): readonly SceneNode[]

源码

nodes, the output of a resize or a scale of layers of document, each passed through withManualSize against the node it replaces. only limits the rule to the layers the user changed, where the others were only carried along (the descendants of a resized group or selection).

function withoutStretchWhereHugging( document: DesignDocument, node: SceneNode ): SceneNode

源码

The node without a stretching constraint on an axis it hugs: what the rule “no node hugs and stretches on the same axis” does to one node. Commands do not call it; stretchWhereHuggingReplacements applies the rule to every edit, on the axes the edit brings to break it.

function stretchWhereHuggingReplacements( previous: DesignDocument, next: DesignDocument, changedNodeIds: ReadonlySet<NodeId> ): readonly SceneNode[]

源码

The one place the rule “no node has a stretching constraint (Left and right, Top and bottom, Scale) on an axis whose sizing is Hug” is enforced. applyOperations calls it for every batch of operations, so every command, preview, paste, undo-able edit and replayed commit passes through it and no command applies the rule itself.

next is previous after the batch and changedNodeIds the nodes the batch wrote. The nodes looked at are the ones whose sizing or constraints can have changed:

  • every changed node that still exists (its own layout, automatic text sizing, overrides, component or constraints may be new);
  • every instance, at any depth and on any page or inside any component, of a component whose root or root sizing changed. An instance with a sizing override on the axis keeps its own sizing, so only the ones that follow the component can lose a constraint.

Only a break of the rule that the batch brings is removed: an axis of a node that hugs and stretches in next and did not in previous (the node is new, or it kept the rule on that axis there). A node that already hugged and stretched on an axis in previous, as a document stored before the rule existed can hold, is left on that axis exactly as the batch leaves it, so a batch that does not touch the break, or keeps it, can be reversed exactly.

Returned are those nodes, each with the stretching constraint turned into Left or Top on the axes that newly break the rule, in a stable order (the batch’s own, then the document’s). The sizing is never changed here, so one pass is enough. The cost is two sizing reads per changed node, two more for one that breaks the rule, and one comparison per component; the walk over every node of the document happens only for a batch that changed a component root’s sizing.

function sizingReplacements( document: DesignDocument, nodeIds: readonly NodeId[], axis: SizingAxis, sizing: AxisSizing ): ReadonlyMap<NodeId, SceneNode>

源码

The nodes that change when nodeIds are set to sizing on axis, by id. Nodes that cannot take that sizing are left out.

An instance follows every rule here as an auto layout frame does, through nodeAxisSizing and withAxisSizing, except the last part of the Hug rule: its layers are its component’s, so their Fill is not changed.

  • Fill turns the node’s own Hug on the axis into Fixed (text and code stop sizing that axis to their content), drops a size variable on the axis, and turns a hugging stack parent Fixed on the axis, as Figma does: “If any child objects within an auto layout frame are set to Fill container, the parent frame will no longer hug contents and become Fixed for the axis.”
  • Hug on an auto layout frame turns its stack children that fill the axis into Fixed. A grid keeps its Fill children: they take their cell.
  • Fixed and Hug drop the node’s own Fill on the axis.

Hug leaves a stretching constraint on the axis for applyOperations to turn into Left or Top, as it does after every edit (stretchWhereHuggingReplacements).

function resizingReplacements( document: DesignDocument, nodeId: NodeId, resizing: NodeResizing | undefined ): ReadonlyMap<NodeId, SceneNode>

源码

The nodes that change when a node’s Fill flags and size limits are replaced with resizing (undefined removes them all). A newly set Fill follows the same rules as choosing Fill container in the sizing menu.

function isAutoLayoutFrame(node: SceneNode | undefined): node is AutoLayoutFrame

源码

Whether the node is a frame with a stack or grid auto layout.

function parentNodeOf( document: DesignDocument, nodeId: NodeId ): SceneNode | undefined

源码

The container that holds the node, or undefined for a page’s top level node.

function documentWithNodes( document: DesignDocument, nodes: ReadonlyMap<NodeId, SceneNode> ): DesignDocument

源码

The document with nodes replacing their stored versions.

Paint、描边与样式

填充和描边接受一个 Paint:纯色、渐变或图片。每个 paint 都可以隐藏(visible: false),并可以与同一图层上位于其下方的 paint 混合(blendMode),与 Figma 相同;参见 PaintVisibility。VisualStyle 汇集了节点的填充、描边、圆角和效果。矩形和画框可以用 CornerRadii 单独设置每个角的圆角;styleCornerRadii 读取样式绘制时使用的四个半径。描边同样可以用 StrokeSides 给每条边单独设置粗细;strokeSideWeights 读取描边绘制时使用的四个粗细。

interface VisualStyle

源码
readonly styleId?: NodeStyleId源码
readonly fills?: readonly Paint[]源码
readonly strokes?: readonly Stroke[]自 0.5.0源码

在填充之后绘制的有序描边,第一项位于最底层。

readonly cornerRadius?: number源码

所有角共用的一个半径。矩形和画框在有 cornerRadii 时改用它;多边形、星形和路径用这个半径给每个顶点倒圆角。

readonly cornerRadii?: CornerRadii自 0.16.0源码

矩形和画框各自独立的圆角半径。存在时在这些节点上代替 cornerRadius;其他形状忽略它。编辑器写入此字段时会清除 cornerRadius,因此两者中只有一个描述圆角。

readonly cornerSmoothing?: number自 0.9.0源码

圆角平滑,取值从 0(圆形圆角)到 1(完全连续的曲率),与 Figma 相同。它只影响具有半径的圆角,每个平滑后的圆角最多占用 (1 + smoothing) * radius 的边长。

对于矩形,渲染器首先将半径 rr 和平滑度 ss 限制在预算 B=12min⁡(w,h)B = \tfrac12 \min(w, h) 以内,然后计算圆角占用每条边的长度:

r′=min⁡(r,B),s′=min⁡(s,max⁡(0,B/r′−1)),p=min⁡((1+s′) r′, B)r' = \min(r, B), \qquad s' = \min\bigl(s, \max(0, B / r' - 1)\bigr), \qquad p = \min\bigl((1 + s')\,r',\ B\bigr)

沿边进入圆角时,先由一段三次曲线平缓地离开该边,再由半径为 r′r' 的圆弧转过 90(1−s′)90(1 - s') 度,最后由一段镜像的三次曲线平缓地接入下一条边。设 β=45s′\beta = 45 s' 度,圆弧在每条边上覆盖 ℓ\ell,三次曲线的控制距离为

ℓ=2 r′sin⁡ ⁣(90(1−s′)2),c=r′tan⁡ ⁣(β2)cos⁡β,d=ctan⁡β,b=p−ℓ−c−d3,a=2b\ell = \sqrt{2}\, r' \sin\!\Bigl(\frac{90(1 - s')}{2}\Bigr), \quad c = r' \tan\!\Bigl(\frac{\beta}{2}\Bigr) \cos\beta, \quad d = c \tan\beta, \quad b = \frac{p - \ell - c - d}{3}, \quad a = 2b

因此 a+b+c+d+ℓ=pa + b + c + d + \ell = p。当 s′=0s' = 0 时,它就是普通的四分之一圆。

readonly shadows?: readonly Shadow[]源码
readonly layerBlur?: number自 0.7.0源码

将节点及其后代作为一个图层整体应用的高斯模糊半径。

readonly backgroundBlur?: number自 0.7.0源码

对节点形状后方的所有内容应用的高斯模糊半径。

interface CornerRadii

自 0.16.0源码

矩形或画框四个角各自的半径,与 Figma 的 topLeftRadius、topRightRadius、bottomRightRadius 和 bottomLeftRadius 相同。每个半径都是非负的单位数;渲染器把每个半径限制在较短边的一半,与统一半径的限制相同,因此相邻的角不会重叠。

readonly topLeft: number源码
readonly topRight: number源码
readonly bottomRight: number源码
readonly bottomLeft: number源码

const CORNER_KEYS: readonly ["topLeft", "topRight", "bottomRight", "bottomLeft"]

源码

按 Figma 面板顺序排列的四个角:左上、右上、右下、左下。

type CornerKey = (typeof CORNER_KEYS)[number]

源码

矩形或画框的一个角,名称与 CornerRadii 中的相同。

function styleCornerRadii( style: | Pick<VisualStyle, "cornerRadius" | "cornerRadii"> | undefined ): CornerRadii

源码

矩形或画框绘制时使用的半径:有 cornerRadii 时取它,否则每个角都取统一的 cornerRadius(缺省时为零)。

function uniformCornerRadii(radius: number): CornerRadii

源码

四个相等的半径。

function cornerRadiiAreUniform(radii: CornerRadii): boolean

源码

四个角半径相同时为 true。

function cornerRadiiAreRounded(radii: CornerRadii): boolean

源码

任一角有圆角时为 true。

function scaleCornerRadii(radii: CornerRadii, factor: number): CornerRadii

源码

把每个半径乘以 factor,与缩放工具的做法相同。

type Paint = SolidPaint | GradientPaint | ImagePaint

源码

interface PaintVisibility

自 0.18.0源码

所有 paint 共有的字段,与 Figma 的 Paint 相同:是否显示,以及如何与同一图层上位于其下方的 paint 混合。

readonly visible?: boolean自 0.18.0源码

为 false 时隐藏该 paint 而不删除它,如同 Figma 填充和描边列表中的眼睛按钮。默认为 true。

readonly blendMode?: BlendMode自 0.18.0源码

该 paint 如何与同一图层上位于其下方的 paint 混合:填充下方的填充,或描边下方的填充和描边。使用与节点 blendMode 相同的模式。默认为 "normal"。

interface SolidPaint extends PaintVisibility

源码
readonly kind: "solid"源码
readonly color: string源码
readonly opacity?: number源码

type GradientPaint = | LinearGradientPaint | RadialGradientPaint | AngularGradientPaint

源码

interface LinearGradientPaint extends PaintVisibility

源码
readonly kind: "linear-gradient"源码
readonly angle: number源码
readonly stops: readonly GradientStop[]源码
readonly opacity?: number源码

interface RadialGradientPaint extends PaintVisibility

自 0.6.0源码

从中心点向外扩散的渐变。

readonly kind: "radial-gradient"源码
readonly center?: PaintAnchor源码

默认为边界的中心。

readonly radius?: PaintAnchor源码

椭圆半径,以边界的比例表示;默认为宽度和高度的一半。

readonly stops: readonly GradientStop[]源码
readonly opacity?: number源码

interface AngularGradientPaint extends PaintVisibility

自 0.6.0源码

围绕中心点旋转扫过的渐变。

readonly kind: "angular-gradient"源码
readonly center?: PaintAnchor源码

默认为边界框的中心。

readonly angle?: number源码

起始角度,单位为度,从 x 轴正方向顺时针计算;默认为 0。

readonly stops: readonly GradientStop[]源码
readonly opacity?: number源码

interface GradientStop

源码
readonly offset: number源码
readonly color: string源码

interface PaintAnchor

自 0.6.0源码

被绘制形状边界内的一个点,以其宽度和高度的比例表示。

readonly x: number源码
readonly y: number源码

interface ImagePaint extends PaintVisibility

自 0.6.0源码

使用图片资源进行绘制。

readonly kind: "image"源码
readonly assetId: AssetId源码
readonly fit?: ImagePaintFit源码

默认为 cover。

readonly opacity?: number源码

type ImagePaintFit = "contain" | "cover" | "fill"

自 0.6.0源码

图片绘制如何缩放到被绘制形状的边界中。

interface Stroke

源码
readonly paint: Paint源码
readonly width: number源码

每条边的粗细。有 sides 时,编辑器让它保持为最大的一条边的粗细。

readonly dash?: readonly number[]源码
readonly position?: StrokePosition自 0.0.1源码

旧的操作或文档省略此字段时默认为 center。

readonly sides?: StrokeSides自 0.17.0源码

上、右、下、左四条边各自的粗细,在矩形和画框上代替 width。其他形状、连接线和代码块忽略它。粗细为 0 的边不绘制,粗细不同的边之间的角跟随形状的圆角。

readonly join?: StrokeJoin自 0.22.0源码

How the stroke turns a corner where two segments meet, as Figma’s strokeJoin. Omitted keeps what the layer drew before 0.22.0: round on paths, ellipses, polygons, stars, lines and connectors, and on rectangles drawn as paths (rounded or with gradient, image or several fills); miter on frames, other rectangles and code blocks. See defaultStrokeJoin. Rectangles and frames with side weights ignore it.

readonly miterAngle?: number自 0.22.0源码

The miter angle in degrees, as Figma’s “Miter angle” (the REST API’s strokeMiterAngle): a miter join whose corner is sharper than this is drawn beveled. Only a miter join uses it. It is more than 0 and at most 180; omitted is DEFAULT_STROKE_MITER_ANGLE, Figma’s default of about 28.96 degrees, which is a miter limit of 4 (limit = 1 / sin(angle / 2)).

readonly dashCap?: DashCap自 0.22.0源码

The ends of every dash of a dashed stroke, as Figma’s “Dash cap”. None stops a dash flat; round and square extend it by half the stroke width. Omitted keeps what the layer drew before 0.22.0: round on the layers whose join defaults to round, none on the others (see defaultDashCap). A solid stroke ignores it.

type StrokePosition = "center" | "inside" | "outside"

自 0.0.1源码

描边绘制在轮廓的哪一侧。

interface StrokeSides

自 0.17.0源码

矩形或画框四条边的描边粗细。Figma 每个节点只保存一组边粗细,这里则是 VisualStyle.strokes 中的每个描边各自携带一组。

readonly top: number源码
readonly right: number源码
readonly bottom: number源码
readonly left: number源码

const STROKE_SIDE_KEYS: readonly ["top", "right", "bottom", "left"]

源码

按 wire 格式和面板所用顺序排列的四条描边边。

type StrokeSideKey = (typeof STROKE_SIDE_KEYS)[number]

源码

描边的一条边,名称与 StrokeSides 中的相同。

function strokeSideWeights(stroke: Pick<Stroke, "width" | "sides">): StrokeSides

源码

描边绘制时每条边的粗细:sides,或四条边都取 width。

function widestStrokeSide(sides: StrokeSides): number

源码

四条边粗细中的最大值。

type StrokeCap = (typeof STROKE_CAPS)[number]

源码

const STROKE_CAPS: readonly [ "none", "round", "square", "line-arrow", "triangle-arrow", "reversed-triangle", "circle-arrow", "diamond-arrow" ]

自 0.12.0源码

译文已过期

Stroke end caps as Figma names them. None ends the stroke flat at the endpoint; round and square extend it by half the stroke width; the arrow caps draw a head in the stroke’s paint whose size follows the stroke width. Lines and connectors share these end styles and draw them the same way. Heads are always solid, even on a dashed stroke.

A stroke also sets how its corners join, how each dash of a dashed stroke ends, and the miter angle below which a miter join is beveled, as in Figma’s Stroke settings. A stroke that sets none of these draws as layers did before schema 0.22.0: defaultStrokeJoin and defaultDashCap give those defaults. Figma sets a miter angle where Skia takes a miter limit; miterLimitFromAngle and miterAngleFromLimit convert between them. Only an open path with one unbranched chain of segments takes end points (openPathChain).

type StrokeJoin = (typeof STROKE_JOINS)[number]

源码

How a stroke’s corners join: sharp (miter), cut off (bevel) or round.

const STROKE_JOINS: readonly ["miter", "bevel", "round"]

自 0.22.0源码

The stroke joins, as Figma names them (MITER, BEVEL, ROUND).

type DashCap = (typeof DASH_CAPS)[number]

源码

How each dash of a dashed stroke ends: flat at the dash (none), round or square.

const DASH_CAPS: readonly ["none", "round", "square"]

自 0.22.0源码

The ends of each dash of a dashed stroke, as in Figma’s Dash cap menu.

const DEFAULT_STROKE_MITER_ANGLE: number

自 0.22.0源码

Figma’s default miter angle in degrees, 2 * asin(1 / 4): the angle at which a miter limit of 4 bevels.

function strokeMiterAngle(stroke: Pick<Stroke, "miterAngle">): number

源码

A stroke’s miter angle, or Figma’s default when it has none.

function miterLimitFromAngle(angle: number): number

自 0.22.0源码

The miter limit a miter angle gives, as SVG and Skia use it: the longest a miter may be, as a multiple of half the stroke width, before the join is beveled. A corner sharper than angle degrees has a longer miter.

function miterAngleFromLimit(limit: number): number

源码

The miter angle, in degrees, that a miter limit of at least 1 gives.

function defaultStrokeJoin( node: SceneNode, style: VisualStyle | undefined ): StrokeJoin

自 0.22.0源码

The join a stroke of node draws with when it names none: what the layer drew before schema 0.22.0, round on layers stroked along a path and miter on layers stroked around a box. style is the layer’s resolved style.

function defaultDashCap( node: SceneNode, style: VisualStyle | undefined ): DashCap

自 0.22.0源码

The dash ends a dashed stroke of node draws with when it names none: round on layers stroked along a path and none on layers stroked around a box, as before schema 0.22.0.

const DEFAULT_PATH_STROKE_CAP: StrokeCap

源码

The end style an open path draws when it names none: round, as before 0.22.0.

function openPathChain(network: VectorNetwork): readonly VectorSegment[] | null

自 0.22.0源码

The segments of network when they form one open chain in order: each segment starts where the one before it ends, and the first segment’s start and the last segment’s end are each touched by that segment only. Only such a path takes end points (PathNode.startCap and endCap). Returns null for a closed, branched or empty network.

interface Shadow

源码
readonly kind?: ShadowKind自 0.7.0源码

旧文档省略此字段时默认为投影。

readonly x: number源码
readonly y: number源码
readonly blur: number源码
readonly spread: number源码
readonly color: string源码

type ShadowKind = "drop" | "inner"

自 0.7.0源码

投影绘制在节点后方;内阴影绘制在节点内部。

矢量网络

路径保存一个可编辑的矢量网络:顶点、顶点之间的线段、可选的切线约束,以及由有向环构成的填充区域。SVG 路径数据只是一种交换格式。

interface VectorNetwork

自 0.2.0源码

构成路径形状的顶点、线段和填充区域。

readonly vertices: readonly VectorVertex[]源码
readonly segments: readonly VectorSegment[]源码
readonly constraints?: readonly VectorTangentConstraint[]源码

省略时等同于空的约束列表。

readonly regions: readonly VectorRegion[]源码

按绘制顺序从后到前排列。

interface VectorVertex

自 0.2.0源码

VectorNetwork 中的一个点,使用网络坐标。

readonly id: VectorVertexId源码
readonly x: number源码
readonly y: number源码
readonly cornerRadius?: number自 0.10.0源码

该顶点处的圆角半径,覆盖节点样式的圆角半径。只有恰好连接两条线段的顶点才会被圆角化;渲染器会将半径限制为相邻较短线段长度的一半。

type VectorSegment = | VectorLineSegment | VectorCubicSegment | VectorEllipticalArcSegment

自 0.2.0源码

VectorNetwork 中两个顶点之间的边。

interface VectorLineSegment extends VectorSegmentBase

源码
readonly kind: "line"源码

interface VectorCubicSegment extends VectorSegmentBase

源码
readonly kind: "cubic"源码
readonly startHandle: VectorHandle源码
readonly endHandle: VectorHandle源码

interface VectorEllipticalArcSegment extends VectorSegmentBase

源码

用于精确迁移和 SVG 互转的兼容几何。编辑器最初只创建并直接编辑直线段和三次曲线段。

readonly kind: "elliptical-arc"源码
readonly radiusX: number源码
readonly radiusY: number源码
readonly xAxisRotation: number源码
readonly largeArc: boolean源码
readonly sweep: boolean源码

interface VectorHandle

源码
readonly id: VectorHandleId源码
readonly dx: number源码

控制点相对于线段端点的水平偏移。

readonly dy: number源码

控制点相对于线段端点的垂直偏移。

interface VectorTangentConstraint

源码

将交汇于同一顶点的两个端点控制柄关联起来。成对的约束让分支网络能够描述彼此独立的平滑延续,而不必为整个顶点指定一种含糊的平滑模式。

readonly vertexId: VectorVertexId源码
readonly handleIds: readonly [VectorHandleId, VectorHandleId]源码
readonly mode: "angle" | "angle-and-length"源码

仅镜像角度,或同时镜像角度和控制柄长度。

interface VectorRegion

自 0.2.0源码

VectorNetwork 中的一块填充区域,由线段组成的环围成。

readonly id: VectorRegionId源码
readonly windingRule: "nonzero" | "evenodd"源码
readonly loops: readonly VectorRegionLoop[]源码
readonly fills?: readonly Paint[]源码

省略时继承路径解析后的填充;空数组表示禁用填充。

interface VectorRegionLoop

源码
readonly segments: readonly VectorSegmentReference[]源码
readonly implicitClose?: true源码

为填充而闭合一条开放的链,但不添加或描边另一条边,与 SVG 对开放子路径的隐式填充闭合一致。

interface VectorSegmentReference

源码
readonly segmentId: VectorSegmentId源码
readonly direction: "forward" | "reverse"源码

type VectorWindingRule = VectorRegion["windingRule"]

源码

function vectorNetworkFromSvgPathData( pathData: string, windingRule: VectorWindingRule = "nonzero" ): VectorNetwork

源码

将 SVG 路径转换为确定性的、节点局部的矢量网络拓扑。相对命令、简写命令、水平命令、垂直命令和二次曲线命令会被规范化。椭圆弧保留为精确的兼容线段。

function vectorRegionToSvgPathData( network: VectorNetwork, region: VectorRegion ): string

源码

将一个可填充区域投影为 SVG 路径数据。

function vectorRegionPathDataById( network: VectorNetwork, regionId: string ): string | undefined

源码

投影第一个匹配的区域,适合保留了区域 ID 的调用方使用。

function vectorNetworkToStrokePathData(network: VectorNetwork): string

源码

将网络中的每条边各投影一次,用于与 SVG 兼容的描边和边界计算。区域环会尽可能保留作者绘制的链;其余的图边会成为独立的子路径,因为 SVG 无法表示分支连接。

function transformVectorPoint( x: number, y: number, transform: TransformMatrix ): { readonly x: number; readonly y: number }

源码

对一个点应用与 SVG 兼容的仿射矩阵。

function scaleVectorNetwork( network: VectorNetwork, scale: { readonly x: number; readonly y: number }, anchor: { readonly x: number; readonly y: number } ): VectorNetwork

源码

译文已过期

Scales a vector network in its own coordinate space around one anchor. An elliptical arc keeps its exact shape: see scaleEllipticalArc.

function assertValidPathData(pathData: string): void

源码

function isClosedPathData(pathData: string): boolean

源码

当每个子路径都闭合回到其起点时返回 true。

文本

文本节点保存由带样式的文本片段(run)组成的段落。每个文本片段指明一个主题 TextStyle,并可带有直接覆盖;段落则添加对齐、间距、缩进和列表标记。

interface TextParagraph

源码

TextNode 的一个段落:其文本片段加上段落级布局。

readonly runs: readonly TextRun[]源码
readonly direction?: "auto" | "ltr" | "rtl"源码

省略或显式设置为 auto 时,根据段落内容确定书写方向。

readonly align?: "left" | "center" | "right" | "justify"源码
readonly spacingBefore?: number源码
readonly spacingAfter?: number源码
readonly indent?: { readonly left: number; readonly right: number; readonly firstLine: number; }源码
readonly list?: { readonly kind: "ordered" | "unordered"; readonly level: number; readonly start?: number; readonly marker?: TextListMarker; }源码

使该段落成为列表项。

interface TextRun

源码

共享同一样式的一段文本。

readonly text: string源码
readonly styleId?: TextStyleId源码

主题文本样式;省略时为主题的 defaultTextStyleId。

readonly overrides?: TextStyleOverrides源码

在样式之上直接应用的格式。

interface TextListMarker

源码

显示在列表段落前的项目符号或编号,及其样式。

readonly text?: string源码

自定义标记文本;提供时不能为空。

readonly styleId?: TextStyleId源码
readonly overrides?: TextStyleOverrides源码
readonly gap?: number源码

标记与段落文本之间的间距。非负。

interface TextStyle

源码
readonly name: string源码
readonly fontFamily: string源码
readonly fontAssetId?: AssetId源码
readonly fontFallbackAssetIds?: readonly AssetId[]源码

在 fontAssetId 之后按顺序尝试的嵌入字体资源。

readonly language?: string源码

采用规范大小写的 BCP 47 语言标签,用于文本整形和断行。

readonly fontSize: number源码
readonly fontWeight: number源码
readonly lineHeight: number源码
readonly letterSpacing?: number源码
readonly color: string源码
readonly italic?: boolean源码
readonly underline?: boolean源码
readonly strikethrough?: boolean自 0.2.0源码

在文本中间绘制一条删除线。

readonly openTypeFeatures?: Readonly<Record<string, boolean | number>>自 0.2.0源码

相对于字体 OpenType 特性默认值的显式调整。

readonly fontVariations?: Readonly<Record<string, number>>自 0.2.0源码

显式指定的可变字体轴坐标,以四字节 OpenType 标签为键。

type TextStyleOverrides = & Partial<Omit<TextStyle, "name" | "fontAssetId" | "fontFallbackAssetIds">> & { readonly fontAssetId?: AssetId | null; readonly fontFallbackAssetIds?: readonly AssetId[]; }

自 0.2.1源码

在单个文本片段或列表标记上直接设置的文本格式。

字体资源需要明确的清除语义,因为省略某个覆盖项会继承所选主题样式。将主字体设为 null 会清除继承的 fontAssetId,而空的回退列表会清除继承的回退字体。

function assertTextStyleOverrides( value: unknown ): asserts value is TextStyleOverrides

源码

校验一个独立的、由作者设置的文本片段或列表标记的文本样式覆盖。

const MAX_TEXT_FONT_FALLBACK_ASSETS: 4095

源码

规范上限;保留文本还另外携带一个主字体资源。

type OpenTypeTag = Brand<string, "OpenTypeTag">

自 0.2.0源码

由四个字符组成的 OpenType 特性标签或轴标签。使用 openTypeTag 创建。

function openTypeTag(value: string): OpenTypeTag

源码

OpenType 特性标签和变体标签恰好由四个可打印的 ASCII 字节组成。

资源与字体

图片、视频和字体存放在文档的资源映射中,通过 AssetId 引用。字体来自 Google Fonts(GoogleFontsSource)或电脑上安装的字体(LocalFontSource);本地字体只记下名称,其文件从不存入文档。

type Asset = ImageAsset | VideoAsset | FontAsset

源码

存储在 DesignDocument.assets 中的文件,通过其 kind 字段区分类型。

interface ImageAsset

源码

ImageNode 和 ImagePaint 使用的图片文件。

readonly id: AssetId源码

与该资源在 DesignDocument.assets 中的键一致。

readonly kind: "image"源码
readonly mimeType: string源码
readonly source: AssetSource源码
readonly width?: number源码

固有宽度(像素),已知时提供。

readonly height?: number源码

固有高度(像素),已知时提供。

interface VideoAsset

源码

VideoNode 使用的视频文件。

readonly id: AssetId源码

与该资源在 DesignDocument.assets 中的键一致。

readonly kind: "video"源码
readonly mimeType: string源码
readonly source: AssetSource源码
readonly width?: number源码

固有宽度(像素),已知时提供。

readonly height?: number源码

固有高度(像素),已知时提供。

interface FontAsset

源码

一个字体字面(font face),由 TextStyle.fontAssetId、TextStyle.fontFallbackAssetIds 和 CodeStyle.fontAssetId 引用。

readonly id: AssetId源码

与该资源在 DesignDocument.assets 中的键一致。

readonly kind: "font"源码
readonly mimeType: string源码

来源为 Google Fonts 时必须为 font/woff2,来源为本地字体时必须为 font/ttf 或 font/otf。

readonly source: FontAssetSource源码
readonly family: string源码
readonly weight: number源码

取值 1 到 1000,与 CSS font-weight 相同。

readonly style: "normal" | "italic" | "oblique"源码

type AssetSource = | { readonly kind: "url"; readonly url: string } | { readonly kind: "data"; readonly data: string }

源码

资源字节的来源:一个 URL,或存储在文档中的数据。

type FontAssetSource = AssetSource | GoogleFontsSource | LocalFontSource

自 0.13.0源码

字体文件的来源。

interface GoogleFontsSource

自 0.13.0源码

由 Google Fonts 以许多小型 WOFF2 文件提供的字体族,每个文件覆盖 Unicode 的一部分(由 Google Fonts CSS 中的 unicode-range 声明)。应用为每个内置字体族保存文件列表,只加载包含文档所用字符的文件。

readonly kind: "google-fonts"源码
readonly family: string源码

Google Fonts 字体族名称,例如“Noto Sans SC”。

interface LocalFontSource

自 0.19.0源码

选择该字体的人的电脑上安装的字体,通过浏览器的本地字体访问 API(window.queryLocalFonts())读取。文档只记下字体名称而不携带字体文件,因此一台电脑上安装的字体列表不会进入文档;只有文档中文本用到的字体才会被记下。在没有安装该字体的电脑上,应用会把这段文本显示为使用了缺失的字体。

readonly kind: "local"源码
readonly family: string源码

已安装字体的字体族名称,例如 “Helvetica Neue”。

readonly postScriptName: string源码

字面的 PostScript 名称,用于在已安装的字体中识别它。

readonly styleName: string源码

已安装字体的样式名称,例如 “Bold Italic”。

readonly sha256: string源码

字面字体文件的 SHA-256,为 64 位小写十六进制数字。PostScript 名称相同但字节不同的已安装字面是该字体的另一个版本,排版结果可能不同。

主题、样式与变量

主题保存共享的节点样式、文本样式和代码样式、命名颜色以及变量集合。节点可以把受支持的属性绑定到变量;绑定的值同时也写在节点上,因此解除绑定后外观保持不变。

interface DocumentTheme

源码

文档共享的样式、命名颜色和变量。节点通过 ID 引用它们,并可以在其上保留直接覆盖的值。

readonly defaultTextStyleId: TextStyleId源码

未指定文本样式的文本片段所使用的文本样式。

readonly defaultCodeStyleId: CodeStyleId源码

未指定代码样式的代码节点所使用的代码样式。

readonly colors: Readonly<Record<string, string>>源码

命名颜色,以名称为键。

readonly nodeStyles: Readonly<Record<string, NodeStyle>>源码
readonly textStyles: Readonly<Record<string, TextStyle>>源码
readonly codeStyles: Readonly<Record<string, CodeStyle>>源码
readonly variableCollections?: Readonly<Record<string, VariableCollection>>源码

存储在本文档中的变量集合。跨文档共享的库有意不在支持范围内。

interface NodeStyle extends Omit<VisualStyle, "styleId">

源码
readonly name: string源码

interface CodeStyle

源码

提供调色板颜色,以及新建代码节点时使用的默认排版设置。

readonly name: string源码
readonly fontFamily: string源码
readonly fontAssetId?: AssetId源码
readonly fontSize: number源码
readonly lineHeight: number源码
readonly letterSpacing?: number自 0.1.2源码

字符之间额外增加的间距。

readonly background: string源码
readonly foreground: string源码
readonly syntax: Readonly<Record<string, string>>源码

interface VariableCollection

源码
readonly name: string源码
readonly defaultModeId: VariableModeId源码
readonly activeModeId?: VariableModeId源码

译文已过期

The mode this document shows where no page or layer chooses one (see VariableModes). It defaults to defaultModeId when omitted.

readonly modeOrder: readonly VariableModeId[]源码
readonly modes: Readonly<Record<string, VariableMode>>源码
readonly variables: Readonly<Record<string, VariableDefinition>>源码

interface VariableMode

源码
readonly name: string源码

type VariableDefinition = | VariableDefinitionBase<"color", string> | VariableDefinitionBase<"number", number> | VariableDefinitionBase<"string", string> | VariableDefinitionBase<"boolean", boolean>

源码

type VariableType = "color" | "number" | "string" | "boolean"

源码

type VariableValue = string | number | boolean

源码

type VariableProperty = | "visibility" | "opacity" | "width" | "height" | "cornerRadius" | "fillColor" | "strokeColor" | "strokeWidth" | "gap" | "wrapGap" | "columnGap" | "rowGap" | "paddingTop" | "paddingRight" | "paddingBottom" | "paddingLeft" | "fontFamily" | "fontSize" | "fontWeight" | "lineHeight" | "letterSpacing" | "textColor"

源码

type VariableBindings = Readonly<Partial<Record<VariableProperty, VariableId>>>

源码

const VARIABLE_PROPERTY_TYPES: Readonly<Record<VariableProperty, VariableType>>

源码

interface LocatedVariable

源码
readonly collectionId: string源码
readonly collection: VariableCollection源码
readonly variableId: VariableId源码
readonly variable: VariableDefinition源码

function findVariable( theme: DocumentTheme, variableId: VariableId | string ): LocatedVariable | undefined

源码

function resolveVariableValue( theme: DocumentTheme, variableId: VariableId | string, modes?: VariableModes ): VariableValue | undefined

源码

The variable’s value in the mode its collection shows under modes (the modes in effect at a layer, see variableModesAt): the inherited choice, else the collection’s active mode, else its default mode. A mode without a value reads the default mode’s value.

function listVariablesForProperty( theme: DocumentTheme, property: VariableProperty ): readonly LocatedVariable[]

源码

function variableSupportsProperty( variable: VariableDefinition, property: VariableProperty ): boolean

源码

function nodeSupportsVariableProperty( node: SceneNode, property: VariableProperty ): boolean

源码

### Variable modes

A page, frame, group, component or instance can choose a mode per variable collection in variableModes. A collection it leaves out is Auto: the layer inherits the mode from its parent, up to the page, and a page without one uses the collection’s activeModeId. An instance’s modes apply to its component’s layers. Stored bound values are written for the active modes; the resolver and the page compiler write them again for layers under other modes.

type VariableModes = Readonly<Record<string, VariableModeId>>

自 0.26.0源码

A variable mode per collection, keyed by collection ID. A collection left out is Auto: the layer takes the mode of its parent, up to the page, and a page without one uses the collection’s activeModeId (else its defaultModeId). Omitted when empty.

function inheritVariableModes( parent: VariableModes | undefined, own: VariableModes | undefined ): VariableModes | undefined

自 0.26.0源码

The modes a layer uses: its parent’s modes with the layer’s own choices on top. A collection the layer leaves out (Auto) keeps the parent’s mode. Returns parent itself when own chooses nothing.

function variableModeFor( collectionId: string, collection: VariableCollection, modes?: VariableModes ): VariableModeId

自 0.26.0源码

The mode a collection shows under modes: the inherited choice, else the collection’s activeModeId, else its defaultModeId.

function variableModesAt( document: DesignDocument, nodeId: NodeId ): VariableModes | undefined

自 0.26.0源码

The modes in effect at a stored node: the page’s modes, then each ancestor’s, then the node’s own. A layer of a component (outside any page) starts from the document’s active modes at the component root; an instance applies its own modes on top when it is resolved. Undefined means every collection shows its active mode.

function inheritedVariableModes( document: DesignDocument, nodeId: NodeId ): VariableModes | undefined

自 0.26.0源码

The modes a stored node inherits: variableModesAt its parent, or the page’s modes for a page root. The node’s own choices are not included.

function locatedVariableValue( located: LocatedVariable, modes?: VariableModes ): VariableValue | undefined

自 0.26.0源码

resolveVariableValue for a variable already found with findVariable.

function applyVariableBindings( document: DesignDocument, node: SceneNode, modes: VariableModes | undefined ): SceneNode

自 0.26.0源码

Writes each of the node’s variable bindings in the modes modes into the bound field (see withVariableValue). A binding to a missing variable, or one the node cannot take, is skipped. A text layer that sizes itself is measured again. Returns node itself when it has no bindings.

function withVariableValue( theme: DocumentTheme, node: SceneNode, property: VariableProperty, value: VariableValue ): SceneNode

自 0.26.0源码

Writes one variable value into the node field it is bound to, the way the editor does when a variable is applied: a color drives the bottom fill or the first stroke, a radius sets every corner, a text property restyles every run. Sizes and opacity are clamped. A value of the wrong type changes nothing.

function bindingsDependOnModes( theme: DocumentTheme, node: SceneNode, modes: VariableModes | undefined ): boolean

自 0.26.0源码

Whether a node’s variable bindings read any collection in a mode other than its active mode under modes. Stored values are written for the active modes, so only such a node needs applyVariableBindings.

function variableModesKey( theme: DocumentTheme, modes: VariableModes | undefined ): string

自 0.26.0源码

A stable text form of modes for cache keys: the collections in sorted order. Modes that match a collection’s active mode are left out, so Auto and an explicit choice of the active mode give the same key.

ID

ID 是带品牌标记的字符串(branded string):运行时就是普通字符串,但类型系统会阻止把一种 ID 当作另一种使用。每种 ID 都有一个构造函数,会拒绝空字符串。

type DocumentId = Brand<string, "DocumentId">

源码

带品牌的字符串 ID。运行时它们都是普通字符串,但品牌可以防止把一种 ID 传到需要另一种 ID 的地方。请用对应的构造函数创建,例如 nodeId,它会拒绝空字符串。

const documentId: (value: string) => DocumentId

源码

把字符串标记为 DocumentId 品牌类型。空字符串会抛出 TypeError。

type PageId = Brand<string, "PageId">

源码

Page 的 ID。

const pageId: (value: string) => PageId

源码

将字符串标记(brand)为 PageId 类型。对空字符串抛出 TypeError。

type NodeId = Brand<string, "NodeId">

源码

SceneNode 的 ID。

const nodeId: (value: string) => NodeId

源码

将字符串标记(brand)为 NodeId 类型。对空字符串抛出 TypeError。

type AssetId = Brand<string, "AssetId">

源码

Asset 的 ID。

const assetId: (value: string) => AssetId

源码

把字符串标记为 AssetId 品牌类型。空字符串会抛出 TypeError。

type NodeStyleId = Brand<string, "NodeStyleId">

源码

DocumentTheme.nodeStyles 中某个 NodeStyle 的 ID。

const nodeStyleId: (value: string) => NodeStyleId

源码

将字符串标记(brand)为 NodeStyleId 类型。对空字符串抛出 TypeError。

type TextStyleId = Brand<string, "TextStyleId">

源码

DocumentTheme.textStyles 中某个 TextStyle 的 ID。

const textStyleId: (value: string) => TextStyleId

源码

将字符串标记(brand)为 TextStyleId 类型。对空字符串抛出 TypeError。

type CodeStyleId = Brand<string, "CodeStyleId">

源码

DocumentTheme.codeStyles 中某个 CodeStyle 的 ID。

const codeStyleId: (value: string) => CodeStyleId

源码

把字符串标记为 CodeStyleId 品牌类型。空字符串会抛出 TypeError。

type VariableCollectionId = Brand<string, "VariableCollectionId">

源码

VariableCollection 的 ID。

const variableCollectionId: (value: string) => VariableCollectionId

源码

将字符串标记(brand)为 VariableCollectionId 类型。对空字符串抛出 TypeError。

type VariableModeId = Brand<string, "VariableModeId">

源码

VariableMode 在其所属集合中的 ID。

const variableModeId: (value: string) => VariableModeId

源码

将字符串标记(brand)为 VariableModeId 类型。对空字符串抛出 TypeError。

type VariableId = Brand<string, "VariableId">

源码

VariableDefinition 的 ID。

const variableId: (value: string) => VariableId

源码

将字符串标记(brand)为 VariableId 类型。对空字符串抛出 TypeError。

type CommitId = Brand<string, "CommitId">

源码

DocumentStore 中某个 CommitRecord 的 ID。

const commitId: (value: string) => CommitId

源码

把字符串标记为 CommitId 品牌类型。空字符串会抛出 TypeError。

type VectorVertexId = Brand<string, "VectorVertexId">

自 0.2.0源码

VectorVertex 的 ID。

const vectorVertexId: (value: string) => VectorVertexId

源码

将字符串标记(brand)为 VectorVertexId 类型。对空字符串抛出 TypeError。

type VectorSegmentId = Brand<string, "VectorSegmentId">

自 0.2.0源码

VectorSegment 的 ID。

const vectorSegmentId: (value: string) => VectorSegmentId

源码

将字符串标记(brand)为 VectorSegmentId 类型。对空字符串抛出 TypeError。

type VectorHandleId = Brand<string, "VectorHandleId">

自 0.2.0源码

VectorHandle 的 ID。

const vectorHandleId: (value: string) => VectorHandleId

源码

将字符串标记(brand)为 VectorHandleId 类型。对空字符串抛出 TypeError。

type VectorRegionId = Brand<string, "VectorRegionId">

自 0.2.0源码

VectorRegion 的 ID。

const vectorRegionId: (value: string) => VectorRegionId

源码

将字符串标记(brand)为 VectorRegionId 类型。对空字符串抛出 TypeError。

加载与保存

deserializeDocument 对文档进行迁移、校验和冻结;serializeDocument 把它写回为键已排序的 JSON。每种失败都是一个带有错误码和 JSON 路径的 ModelError。

function deserializeDocument( input: string | unknown, migrations: MigrationRegistry = defaultMigrations ): DesignDocument

源码

从 JSON 字符串或已解析的值加载文档。

依次运行 migrations 直到 CURRENT_DOCUMENT_SCHEMA_VERSION,用 assertDocument 校验结果,把每个编组重新适配到其子节点的范围(这会修复以过时编组尺寸保存的文件),并返回一个深度冻结的副本。输入不会被修改。

抛出 ModelError:字符串无法解析时为 INVALID_JSON,也可能是迁移错误码(见 MigrationRegistry.migrate)或校验错误。

function serializeDocument(document: DesignDocument, indentation = 0): string

源码

使用 assertDocument 校验 document,并以键排序的 JSON 写出,因此同一文档总是得到相同的文本。indentation 会传给 JSON.stringify;为 0 时写成一行。

function snapshotDocument(input: DesignDocument | unknown): DesignDocument

源码

返回经过校验且深度冻结的文档副本。等同于使用默认迁移的 deserializeDocument。

function assertDocument(value: unknown): asserts value is DesignDocument

源码

检查 value 是否为 CURRENT_DOCUMENT_SCHEMA_VERSION 版本下有效的 DesignDocument:包括每个实体的结构、节点树(每个节点恰好能从一个页面到达,没有环,也没有共享的子节点)、页面顺序,以及样式、变量、连接线、媒体节点和字体的引用。它不做迁移;较旧的数据请使用 deserializeDocument。

抛出的 ModelError 会指明发现的第一个问题。

function assertSceneNode(value: unknown): asserts value is SceneNode

源码

单独检查一个节点的结构。不检查对其他节点、样式和资源的引用。失败时抛出 ModelError。

function assertDocumentTheme(value: unknown): asserts value is DocumentTheme

源码

单独检查一个主题的结构。失败时抛出 ModelError。

function assertAsset(value: unknown): asserts value is Asset

源码

单独检查一个资源的结构。失败时抛出 ModelError。

class ModelError extends Error

源码

本包在数据无效和编辑被拒绝时抛出的错误。消息以 at <path> 结尾。

new ( readonly code: ModelErrorCode, message: string, readonly path = "$", options?: ErrorOptions )源码

type ModelErrorCode = | "INVALID_JSON" | "INVALID_SCHEMA" | "INVALID_TREE" | "UNSUPPORTED_VERSION" | "MISSING_MIGRATION" | "MIGRATION_FAILED" | "NOT_IMPLEMENTED"

源码

ModelError 报告的问题类型:

  • INVALID_JSON:输入字符串不是 JSON,或某个值不是纯 JSON(包含 undefined、非有限数字、循环引用或类实例)。
  • INVALID_SCHEMA:某个值的结构错误、含有未知属性或数字超出范围。被拒绝的操作和 store 调用也使用此代码。
  • INVALID_TREE:值的格式正确,但其引用之间不匹配:缺失或被共享的子节点、循环、不可达的节点,或者缺失的样式、变量、资源或提交。
  • UNSUPPORTED_VERSION:数据比本包支持的版本更新。
  • MISSING_MIGRATION:没有从该数据版本出发的迁移步骤。
  • MIGRATION_FAILED:某个迁移步骤抛出了异常或产生了错误的版本。

较旧的文档在校验前会经过一串迁移步骤升级。

class MigrationRegistry

源码

由 DocumentMigration 步骤组成的有序链。除非另行传入注册表,deserializeDocument 和 deserializeStore 使用 defaultMigrations。

new (migrations: readonly DocumentMigration[] = [])源码
register(migration: DocumentMigration): this源码

添加一个步骤并返回该注册表。如果该步骤没有按 DocumentMigration.to 所述向前推进版本,或者已注册了从同一版本出发的步骤,则抛出代码为 INVALID_SCHEMA 的 ModelError。

migrateOperation( operation: unknown, from: DocumentSchemaVersion, target: DocumentSchemaVersion = CURRENT_DOCUMENT_SCHEMA_VERSION ): unknown源码

使用与文档相同的有序步骤,把一条已存储的操作从其记录时的版本迁移到当前版本。没有 migrateOperation 的步骤会原样传递该操作。当某个步骤返回 null 时返回 null。

migrate( input: unknown, target: DocumentSchemaVersion = CURRENT_DOCUMENT_SCHEMA_VERSION ): unknown源码

从输入的 schemaVersion 开始依次运行各步骤直到 target,并以纯 JSON 形式返回结果。它不会校验结果。

抛出 ModelError:输入比 target 新时为 UNSUPPORTED_VERSION;途中某个版本没有对应的起始步骤时为 MISSING_MIGRATION;某个步骤抛出异常或写入了错误的版本时为 MIGRATION_FAILED。

interface DocumentMigration

源码

把文档从一个 schema 版本升级到下一个版本的一个步骤。请在 MigrationRegistry 中注册这些步骤。

readonly from: DocumentSchemaVersion源码

此步骤读取的版本。每个版本只能有一个从它开始的步骤。

readonly to: DocumentSchemaVersion源码

此步骤写出的版本:对旧式数字版本为 from + 1,从旧式版本 1 升级时为 "0.0.0",否则为一个更新的语义化版本。

migrate(input: unknown): unknown源码

以纯 JSON 返回升级后的文档,并把 schemaVersion 设为 to。输入是私有副本,可以直接原地修改。

migrateOperation?(operation: unknown): unknown源码

把一个已存储的操作迁移过同一个版本步骤。

已存储的历史在操作中保存了完整的节点、页面、主题和资源,因此这些结构中任何一个发生变化,都会让已记录的操作过时。只要 migrate 改写了操作可能携带的内容,就应提供此函数;如果变化只涉及没有任何操作会包含的文档级字段,则可以省略。

操作以纯 JSON 形式传入。原样返回没有问题,返回一个不再改变文档的操作也没有问题:该提交会被丢弃,而它的子提交在历史中保持原位。

const defaultMigrations: MigrationRegistry

源码

此包自带的迁移:每个 schema 版本一步,从旧式版本 1 到 0.0.0,再到之后直至 CURRENT_DOCUMENT_SCHEMA_VERSION 的每个版本。以没有对应迁移步骤的版本保存的数据会以 MISSING_MIGRATION 失败。

function readDocumentSchemaVersion( value: unknown, path: string ): DocumentSchemaVersion

源码

检查 value 是否为文档 schema 版本:非负整数(旧格式)或 major.minor.patch 字符串。原样返回该值。否则在 path 处抛出代码为 INVALID_SCHEMA 的 ModelError。

function compareDocumentSchemaVersions( left: DocumentSchemaVersion, right: DocumentSchemaVersion ): number

源码

比较两个 schema 版本的先后,返回 -1、0 或 1。语义化版本逐段比较。旧式数字版本 0 和 1 排在所有语义化版本之前,更大的数字排在其后。版本字符串格式错误时抛出 TypeError。

这些辅助函数适用于任意普通 JSON 值。

type JsonValue = | JsonPrimitive | readonly JsonValue[] | { readonly [key: string]: JsonValue }

源码

任意 JSON 值。用于自由格式的 metadata 字段。

type JsonPrimitive = string | number | boolean | null

源码

JSON 标量:字符串、有限数字、布尔值或 null。

function canonicalJson(value: unknown, indentation = 0): string

源码

序列化一个 JSON 值,并对对象的键排序,使相等的值得到相同的文本。如果 value 不是纯 JSON(例如 undefined、NaN 或类实例),抛出 ModelError。

function cloneJson<Value>(value: Value): Value

源码

深拷贝一个纯 JSON 值。如果它不是纯 JSON,抛出 ModelError。

function deepFreeze<Value>(value: Value): Readonly<Value>

源码

冻结一个值及其包含的所有内容。

已冻结的对象会被视为整体都已深度冻结,因为此包只通过这个函数冻结值。如果没有这条规则,每次编辑后重新冻结文档都要遍历所有节点。

Schema 历史

对存储的文档结构的每次改动都会提升 schema 版本,并新增一个迁移步骤。下表由这些步骤生成,最新的在前:摘要是 codec.ts 中每个步骤上方的注释,提交是引入该版本字符串的那次提交。标注了引入版本的类型和字段列在对应行下方,并在其文档处带有“since”徽标。

版本变更内容引入于
0.27.0Two rules that earlier versions did not check: a group never binds its width or height to a variable, and a text size or line height is greater than zero.1aaacdd 2026-10-04
0.26.0Variable modes on pages and layers (variableModes).c3ea40f 2026-09-29
0.25.0Resize constraints (constraints) and absolute children of auto layout (layoutPositioning).be76658 2026-09-29
0.24.0Component properties (ComponentDefinition.properties), instance and override propertyValues, and node expressions and condition.
新增:changeComponentPropertyOperations, COMPONENT_NUMBER_UNITS, COMPONENT_PROPERTY_KINDS, ComponentDefinition.properties, componentExpressionEnvironment, ComponentExpressionSite, componentExpressionSites, componentLayerIds, ComponentNumberUnit, ComponentPropertyBase, ComponentPropertyDefinition, componentPropertyExpressionType, componentPropertyExpressionValue, componentPropertyId, ComponentPropertyId, ComponentPropertyKind, ComponentPropertyOption, componentPropertyUsage, ComponentPropertyValue, ComponentPropertyValues, componentValueEnvironment, COMPUTABLE_FIELD_VARIABLE_PROPERTIES, COMPUTABLE_FIELDS, ComputableField, computableFieldsOf, computableFieldType, deleteComponentPropertyOperations, deleteComponentPropertyOptionOperations, effectivePropertyValue, ExpressionEditResult, ExpressionField, expressionFieldContext, ExpressionFieldContext, expressionFieldValueEnvironment, findComponentProperty, findComponentPropertyByName, InstanceNode.propertyValues, isComputableField, isExpressionIdentifier, isLayoutFieldInUse, LayerOverride.propertyValues, LAYOUT_ALIGN_TYPE, LAYOUT_DIRECTION_TYPE, LAYOUT_JUSTIFY_TYPE, LENGTH_VARIABLE_PROPERTIES, NamedComputableField, nestedPropertyEnumName, NodeBase.expressions, NodeBase.condition, NodeExpressions, PROPERTY_VALUE_FIELD_PREFIX, propertyButtonSample, propertySampleIds, propertyValueFieldId, propertyValueFits, renameComponentPropertyOperations, renameComponentPropertyOptionOperations, renameVariableCollectionOperations, renameVariableOperations, storedFieldValue, variableExpressionName, variableExpressionType, variableExpressionValue, variablePropertiesOfField, variablesByExpressionName
aa54f10 2026-09-29
0.23.0Components (ComponentDefinition, DesignDocument.components), instances (InstanceNode) and their overrides.686162a 2026-09-29
0.22.0Stroke join, miterAngle and dashCap, and end points on open paths.dad417a #88 2026-09-28
0.21.0ConnectorNode.cornerRadius, which rounds the bends of an elbow connector, and ConnectorNode.cornerSmoothing, which smooths them.60f0497 #87 2026-09-28
0.20.0Connector end side, point and anchor, which pin an attached end on its layer.f6199e2 #73 2026-09-28
0.19.0LocalFontSource 字体来源,记下电脑上安装的字体名称。2474003 #63 2026-09-26
0.18.0每个填充和描边 paint 上的 paint visible 和 paint blendMode。c753479 #59 2026-09-26
0.17.0矩形和画框上按边设置的描边粗细(Stroke.sides)。7382f68 #55 2026-09-26
0.16.0矩形和画框上各自独立的 cornerRadii。e6739c6 #54 2026-09-26
0.15.0堆叠换行、Around/Evenly 间距和按节点设置的填充尺寸(resizing)。761dddf #48 2026-09-26
0.14.0每个节点的 exportSettings 列表,用于图层导出。cba94d9 #30 2026-09-23
0.13.0GoogleFontsSource 字体来源,指明一个 Google Fonts 字体族。b0bab12 #15 2026-09-23
0.12.0直线(带箭头端点)、多边形和星形,以及可选的椭圆 arc。4c61909 #20 2026-09-23
0.11.0页面和画框上的标尺 guides。0a7ec97 #16 2026-09-23
0.10.0矢量顶点上的逐顶点 cornerRadius。837342a 2026-09-18
0.9.0用于曲率连续圆角的 cornerSmoothing。a9795ca 2026-09-17
0.8.0节点 blendMode,以及用于同级蒙版的 mask 标志。b90c0f5 2026-09-17
0.7.0内阴影(Shadow.kind)、layerBlur 和 backgroundBlur。ebc9460 2026-09-17
0.6.0径向渐变、角度渐变和图片 Paint。142ea63 2026-09-17
0.5.0多重描边:strokes 列表取代单个 stroke。d037d4d 2026-09-17
0.4.0幻灯片变为无边界画布上的页面,每个幻灯片根节点都包裹在一个页面画框中。40b14c0 2026-09-16
0.3.0移除幻灯片分节、演讲者备注和构建步骤;幻灯片编号变为文本。36e77a7 2026-09-16
0.2.1TextStyleOverrides 可以用 null 或空列表清除继承的字体资源。e5b85b5 2026-08-10
0.2.0vectorNetwork 取代路径数据;新增文本删除线、OpenType 特性和字体轴。a392f5a 2026-08-10
0.1.4代码节点上可选的 stroke。a2b4483 2026-07-30
0.1.3代码节点 autoResize;旧代码节点取值为 "none"。9216adf 2026-07-30
0.1.2代码样式及代码节点样式覆盖中的 letterSpacing。bfbe3b5 2026-07-30
0.1.1节点上的 aspectRatioLocked。29eb87f 2026-07-30
0.1.0自动生成的幻灯片编号节点和 slideNumberSettings;已在 0.3.0 中再次移除。38e3cd2 2026-07-28
0.0.2用于给幻灯片分组的幻灯片分节(slideSections);已在 0.3.0 中再次移除。63f6094 2026-07-28
0.0.1Stroke.position:描边沿轮廓居中、在内侧或在外侧绘制。56029ef 2026-07-28
0.0.0改用语义化版本;文档本身没有变化。1985db2 2026-07-28

defaultMigrations 中每个迁移步骤对应一行;编解码器可以迁移版本 1 及之后的文档。摘要取自 codec.ts 中每个步骤上方的注释;提交信息来自对版本字符串执行的 git log -S。

操作

每次编辑都是一组 DocumentOperation。applyOperations 要么全部应用,要么全部不应用,并返回新文档、用于撤销它的操作,以及一个指明改动内容的 ChangeSet。

function applyOperations( input: DesignDocument, operations: readonly DocumentOperation[] ): ApplyOperationsResult

源码

译文已过期

Applies operations in order and returns the new document, the inverse operations, and a ChangeSet. It never changes the input.

After the operations run, every group that contains a changed node, at any depth, is refitted to its children, and a group left with no children is removed; the inverse operations undo that too. A connector end attached to a node that is gone after that (a removed node, anything inside it, or such a group) becomes a free end at the x and y it has, so removing a connector’s target is never refused; the inverse operations attach the end again. Then every changed node, and every instance of a component whose root’s sizing changed, loses a stretching constraint (Left and right, Top and bottom, Scale) on an axis it hugs: it becomes Left or Top, and the inverse operations put it back. That is done only where the operations bring it: an axis of a node that already hugged and stretched in the input document (one stored before this rule) is left as the operations write it. The result is then validated. A document that is not frozen is first validated and copied with snapshotDocument.

All or nothing: if any operation does not fit the document, or the result is invalid, it throws a ModelError and returns nothing.

interface ApplyOperationsResult

源码

applyOperations 的返回值。

readonly document: DesignDocument源码

新的、深度冻结的文档;没有任何变化时为输入文档本身。

readonly inverseOperations: readonly DocumentOperation[]源码

译文已过期

Operations that turn document back into the input, already in the order to apply them. Empty when nothing changed.

One exception: when the input held a node with a stretching constraint on an axis it hugs (a document stored before applyOperations kept that rule) and the operations themselves repaired that axis or removed the node, these operations bring it back with Left or Top on that axis.

readonly changes: ChangeSet源码

type DocumentOperation = | { readonly type: "document.set-title"; readonly title: string } | { readonly type: "document.set-metadata"; readonly metadata: Readonly<Record<string, JsonValue>> | null; } | { readonly type: "node.insert"; readonly parentId: NodeId; readonly index: number; readonly subtree: SerializedSubtree; } | { readonly type: "node.remove"; readonly nodeId: NodeId } | { readonly type: "node.move"; readonly nodeId: NodeId; readonly newParentId: NodeId; readonly index: number; } | { readonly type: "node.replace"; readonly node: SceneNode } | { readonly type: "page.insert"; readonly index: number; readonly page: Page; readonly subtree: SerializedSubtree; } | { readonly type: "page.remove"; readonly pageId: PageId } | { readonly type: "page.move"; readonly pageId: PageId; readonly index: number; } | { readonly type: "page.replace"; readonly page: Page } | { readonly type: "theme.replace"; readonly theme: DocumentTheme } | { readonly type: "asset.put"; readonly asset: Asset } | { readonly type: "asset.remove"; readonly assetId: AssetId } | { readonly type: "component.insert"; readonly component: ComponentDefinition; readonly subtree: SerializedSubtree; } | { readonly type: "component.remove"; readonly componentId: ComponentId } | { readonly type: "component.replace"; readonly component: ComponentDefinition; }

源码

译文已过期

One edit to a document. Every change goes through these operations, so each can be recorded, inverted for undo, and sent over the wire as JSON.

  • document.set-title, document.set-metadata: change document fields; null metadata removes it.
  • node.insert: adds subtree as a child of parentId at index (0 to the child count). None of its node IDs may exist yet.
  • node.remove: removes a node and its descendants. Not for a page root. A connector end attached to a removed node becomes a free end.
  • node.move: moves a node to newParentId at index, counted after the node is taken out of its old parent. Not for a page root, and not into the node’s own subtree.
  • node.replace: replaces a node’s data by ID. It cannot change the node’s type or a container’s children; use insert, remove and move.
  • page.insert, page.remove, page.move: add, delete or reorder pages. An inserted page’s rootId must match its subtree’s root. Removing a page removes its nodes.
  • page.replace: replaces a page’s fields; it cannot change rootId.
  • theme.replace: replaces the whole theme.
  • asset.put: adds an asset or replaces the one with the same ID.
  • asset.remove: deletes an asset. It fails validation while an image or video node or a text or code style still refers to it.

interface SerializedSubtree

源码

一个节点及其所有后代,由插入操作携带。

readonly rootId: NodeId源码
readonly nodes: Readonly<Record<string, SceneNode>>源码

根节点及其每个后代,以 NodeId 为键。

function serializeSubtree( document: DesignDocument, rootId: NodeId ): SerializedSubtree

源码

将一个节点及其后代复制到 SerializedSubtree 中,可直接用于 node.insert 或 page.insert 操作。节点不存在时抛出 ModelError。

function getSubtreeNodeIds( document: DesignDocument, rootId: NodeId ): ReadonlySet<NodeId>

源码

一个节点及其所有后代的 ID。节点不存在时为空。

function nodeIdsRemovedBy( input: DesignDocument, operations: readonly DocumentOperation[] ): readonly NodeId[]

源码

The IDs of the nodes that are in input and gone once operations have run, in the order input.nodes lists them. That is every node the operations remove themselves (node.remove, page.remove and component.remove, each with everything inside) and every group removed because the edit left it with no children. A node that is removed and put back by the same operations is not listed.

It runs the same steps as applyOperations but does not validate the result and returns no document. Use it to learn what an edit removes before applying it, for example to let go of the connector ends attached to those nodes, without which applyOperations would refuse the edit.

It throws a ModelError when an operation does not fit the document.

interface ChangeSet

源码

一次编辑改变了什么,用来决定要重绘哪些内容以及通知哪些订阅者。每个 ID 列表都已排序。没有任何变化时,其值为 EMPTY_CHANGE_SET。

readonly documentChanged: boolean源码

仅当文档未变化时为 false;此时每个列表都为空。

readonly themeChanged: boolean源码
readonly changedNodeIds: readonly NodeId[]源码

数据或位置发生变化、或外观可能不同的节点。包括插入和移除的节点、子节点发生变化的父节点、被移动子树中的每个节点、使用了已变化资源的节点,以及主题变化时的所有节点。

readonly insertedNodeIds: readonly NodeId[]源码

之前不存在的节点。在同一次编辑中被移除后又重新插入的节点,既不在此列表中,也不在 removedNodeIds 中。

readonly removedNodeIds: readonly NodeId[]源码

已不再存在的节点。

readonly changedPageIds: readonly PageId[]源码

被添加、移除、修改或在 pageOrder 中移动的页面。

readonly changedAssetIds: readonly AssetId[]源码
readonly changedComponentIds: readonly ComponentId[]自 0.23.0源码

Components added, removed or replaced, and components any of whose layers changed. Their instances, and the instances of every component that nests them, may look different (see componentsNesting).

const EMPTY_CHANGE_SET: ChangeSet

源码

没有任何变化时返回的冻结 ChangeSet。

function diffDocuments( previous: DesignDocument, current: DesignDocument ): ChangeSet

源码

计算两个有效文档之间的 ChangeSet,用于并非来自 applyOperations 的变化(例如 DocumentStore 中的撤销或检出)。按引用共享的部分会直接跳过,不读取。

function serializeOperations( operations: readonly DocumentOperation[], indentation = 0 ): string

源码

使用 assertOperation 检查每个操作,并将列表以键排序的 JSON 写出。indentation 会传给 JSON.stringify。

function deserializeOperations( input: string | unknown ): readonly DocumentOperation[]

源码

从 JSON 字符串或已解析的值读取操作列表,用 assertOperation 逐一检查,并返回深度冻结的副本。抛出 ModelError(字符串无法解析时为 INVALID_JSON)。

function assertOperation(value: unknown): asserts value is DocumentOperation

源码

检查一个操作的结构:它的 type、确切的键集合,以及它携带的任何节点、页面、主题或资源。它是否适用于某个具体文档,只由 applyOperations 检查。抛出 ModelError。

function assertChangedDocument( value: unknown, changed: ChangedDocumentEntities ): asserts value is DesignDocument

源码

校验由一个已有效的文档编辑而来的文档。会检查被修改实体的结构,并完整检查所有跨实体的规则——节点树、页面顺序、分区和引用。

interface ChangedDocumentEntities

源码

列出一个事务涉及的部分。文档中原样保留的内容在首次进入文档时已经校验过,因此只有出现在这里时才会再次检查其结构。

如果变更集遗漏了事务写入的内容,就会放过无效的值,因此只应在产生它的那次编辑中一并生成变更集。

readonly nodeIds: ReadonlySet<string>源码
readonly pageIds: ReadonlySet<string>源码
readonly assetIds: ReadonlySet<string>源码
readonly componentIds: ReadonlySet<string>自 0.23.0源码

Components whose definition was written.

readonly themeChanged: boolean源码

Store 与历史记录

DocumentStore 保存当前文档和一棵提交树。它支持撤销、重做、把多次分派合并为一个撤销步骤、命名分支,以及对文档局部的订阅。

class DocumentStore

源码

保存一个文档及其编辑历史。每次修改都是由 DocumentOperation 组成的一个提交;head 提交的文档就是当前文档。

历史是一棵提交树,而不是一条直线:撤销后再派发会开出一个新的子提交,较早的子提交仍可通过 DocumentStore.checkout 或带 ID 的 DocumentStore.redo 访问。命名分支指向提交,在被检出时会跟随 head 移动。新的 store 从 main 分支开始,包含一个根提交。

监听器在每次修改后同步运行。监听器可以读取 store,但不能修改它:在通知期间调用 dispatch、undo、redo、检出和分支相关方法都会抛出 ModelError。

new (initialDocument: DesignDocument | unknown, options: StoreOptions = {})源码

用 snapshotDocument 校验并冻结 initialDocument,并把它作为根提交。

getSnapshot(): DesignDocument源码

head 提交的文档。

getHeadCommitId(): CommitId源码
getRootCommitId(): CommitId源码
getCurrentBranch(): string | null源码

当前检出的分支;head 处于分离状态时为 null。

getBranches(): Readonly<Record<string, CommitId>>源码

每个分支名及其指向的提交。

getCommit(id: CommitId): CommitRecord | undefined源码
getHistoryGroupId(id: CommitId = this.#headCommitId): string | undefined源码

提交所属的历史分组(如果派发时指定了分组)。之后使用相同分组的派发会修订该提交,而不是新增一条撤销记录。

getDocumentAt(id: CommitId): DesignDocument | undefined源码

某个提交时的文档;ID 未知时为 undefined。

listCommits(): readonly CommitRecord[]源码

所有提交,按 CommitRecord.sequence 排序。

listChildren(id: CommitId = this.#headCommitId): readonly CommitId[]源码

直接基于 id(默认为 head)创建的提交。

preview( operations: readonly DocumentOperation[] ): ReturnType<typeof applyOperations>源码

把操作应用到 head 文档上,但不提交。

dispatch(input: TransactionInput): CommitResult | null源码

把 input.operations 应用到 head 文档并记录结果。通常会在 head 之上新增一个提交,把当前分支移到该提交,并清空重做记录。如果指定了 amendHead,或 historyGroupId 与 head 的相同,这些操作会被合并进 head 提交;如果合并后的提交不再改变任何内容,它会被移除,head 退回到其父提交。

返回新的 head;没有任何变化(或被修订的提交被移除)时返回 null。当 baseCommitId 不是 head、某个操作不适用或结果无效时,抛出 ModelError,此时 store 保持不变。

setFrozen(frozen: boolean): void自 0.27.0源码

Freezes or unfreezes the document. While frozen, dispatch, undo, redo, squashHistory, checkout and checkoutBranch change nothing and return null, the same answer as for a change that changes nothing, and no listener is called. Reading still works. A caller that hands the document to someone else (before the page that shows it is loaded again, for example) freezes it first, so that what it handed over stays the latest document.

isFrozen(): boolean源码

True between setFrozen(true) and setFrozen(false).

canUndo(): boolean源码

只要 head 不是根提交,就为 true。

canRedo(): boolean源码

不带参数调用 redo 时有可移动到的提交,则为 true。

undo(): CommitResult | null源码

把 head(以及当前分支)移到 head 的父提交,并记住旧的 head 以供 redo 使用。在根提交处返回 null。

redo(id?: CommitId): CommitResult | null源码

把 head 移到一个子提交。不传 id 时,选择最近被撤销的子提交,或者在恰好只有一个子提交时选择它;没有可选的子提交时返回 null。id 不是 head 的子提交时抛出 ModelError。

getNextSequence(): number源码

The sequence number the next new commit gets.

squashHistory( fromSequence: number, options: { readonly onlyCommits?: ReadonlySet<CommitId>; } = {} ): CommitResult | null源码

Folds the commits made since fromSequence (see getNextSequence) on the way to the head into one commit, so one undo takes them all back. The walk from the head stops at the first commit made before fromSequence, which becomes the folded commit’s parent. Commits that hang off the folded ones (typing undone and then replaced) are removed with them; the head’s own children stay. The folded commit keeps the head’s ID and document, so the document does not change; when the folded commits change nothing in total, they are all removed and the head moves to the parent.

With onlyCommits, nothing changes and null is returned when a commit it would fold or remove is not in that set, so commits made by someone else (another tab, an outside change) are never folded into or removed with the caller’s.

Returns the folded commit, or null when there were fewer than two commits to fold, they were removed, or a commit outside onlyCommits was found. Throws a ModelError when a branch other than the checked-out one points at a commit it would remove.

checkout(id: CommitId): CommitResult | null源码

把 head 移到任意提交,并使其脱离所在分支,因此之后的提交不会移动任何分支。清空重做记录。id 已经是 head 时返回 null。提交未知时抛出 ModelError。

createBranch(name: string, from: CommitId = this.#headCommitId): void源码

新增一个指向 from(默认为 head)的分支,但不检出它。如果名称为空、包含 null 字符或已被占用,或者提交未知,抛出 ModelError。

checkoutBranch(name: string): CommitResult | null源码

把 name 设为当前分支,并把 head 移到它指向的提交。清空重做记录。head 没有移动时返回 null。分支未知时抛出 ModelError。

renameBranch(previousName: string, nextName: string): void源码

重命名分支。如果旧名称未知,或新名称无效或已被占用,抛出 ModelError。

deleteBranch(name: string): void源码

删除一个分支名;它的提交会保留。删除当前分支会使 head 处于分离状态。分支未知时抛出 ModelError。

subscribe(target: SubscriptionTarget, listener: StoreListener): Unsubscribe源码

每当 head 移动且其变化涉及 target(见 SubscriptionTarget)时调用 listener。返回一个用于移除该监听器的函数。

subscribeState(listener: StoreStateListener): Unsubscribe源码

store 的状态发生任何变化后(head、分支、当前分支或重做记录),不带参数调用 listener。适合显示撤销、重做按钮或分支列表的 UI。

toJSON(): PersistedStore源码

整个 store 的保存形式,为一个冻结的纯对象。

serialize(indentation = 0): string源码

把 toJSON 写成键已排序的 JSON。与 serializeStore 相同。

static fromJSON( input: string | unknown, options: StoreOptions = {}, storeMigrations: StoreMigrationRegistry = defaultStoreMigrations, documentMigrations: MigrationRegistry = defaultMigrations ): DocumentStore源码

加载由 serialize 保存的 store。与 deserializeStore 相同。

interface StoreOptions

源码

DocumentStore 和 deserializeStore 的选项。

readonly rootCommitId?: CommitId源码

根提交的 ID。加载时忽略此项,保留已保存的 ID。

readonly idFactory?: () => CommitId源码

生成新的提交 ID。它不能生成 store 中已有的 ID,否则 dispatch 会抛出异常。默认实现组合了时间、计数器和随机字符。

readonly now?: () => number源码

CommitRecord.timestamp 使用的时钟。默认为 Date.now。

readonly onListenerError?: (error: unknown) => void源码

接收监听器抛出的错误,使一个监听器失败不会影响其他监听器。省略时这些错误会被丢弃。

interface TransactionInput

源码

DocumentStore.dispatch 的参数。

readonly operations: readonly DocumentOperation[]源码
readonly baseCommitId?: CommitId源码

调用方生成这些操作时所基于的 head 提交。如果提供了此项且 head 此后已移动,dispatch 会抛出异常,而不是应用这些操作。

readonly historyGroupId?: string源码

将一连串 dispatch(例如一次拖拽的各个步骤)合并为一个撤销步骤。当 head 提交是以相同的编组 ID dispatch 的时,这些操作会并入该提交,而不是新增一个提交。必须是不含 null 字符的非空字符串。

readonly message?: string源码
readonly actor?: CommitActor源码
readonly amendHead?: boolean源码

将这些操作并入 head 提交而不是新增提交,因此不会增加撤销步骤;除非提供了新消息,head 保留原有消息。用于从 head 提交派生出的变更,例如渲染器为该提交所编辑的文本测得的尺寸。根提交不能被修改,并且修改会丢弃重做条目,因此调用方应先检查 canRedo。

interface CommitResult

源码

head 当前指向的提交及其文档。

readonly commit: CommitRecord源码
readonly document: DesignDocument源码

interface CommitRecord

源码

DocumentStore 历史中的一条记录。提交构成一棵树。

readonly id: CommitId源码
readonly parentId: CommitId | null源码

此提交所基于的提交;仅根提交为 null。

readonly sequence: number源码

在 store 内的创建顺序:根提交为 0,之后依次递增。它也决定了 DocumentStore.listCommits 的顺序。

readonly timestamp: number源码

提交创建或最近一次修订的时间,取自 StoreOptions.now。

readonly message?: string源码
readonly actor?: CommitActor源码
readonly operations: readonly DocumentOperation[]源码

把父提交的文档变为此提交文档的操作。

readonly inverseOperations: readonly DocumentOperation[]源码

把此提交的文档变回父提交文档的操作。

readonly changes: ChangeSet源码

operations 相对于父提交所做的变化。

interface CommitActor

源码

提交的作者。根提交的作者为 { kind: "system", id: "taco-slides" }。

readonly kind: "human" | "assistant" | "system"源码
readonly id: string源码

由应用定义的、代表某个人或智能体的标识符。

interface StoreChangeEvent

源码

head 移动后传给 DocumentStore.subscribe 监听器的事件。该事件是深度冻结的。

readonly reason: TransitionReason源码
readonly previousCommitId: CommitId源码

变更前的 head。当某次 dispatch 原地修改了 head 提交时,它等于 currentCommitId。

readonly currentCommitId: CommitId源码
readonly previous: DesignDocument源码
readonly current: DesignDocument源码
readonly operations: readonly DocumentOperation[]源码

在此次转换中把 previous 变换为 current 的操作。

readonly changes: ChangeSet源码

type TransitionReason = "dispatch" | "undo" | "redo" | "checkout"

源码

是哪个 DocumentStore 调用移动了 head。checkout 也涵盖 checkoutBranch。

type SubscriptionTarget = | { readonly kind: "document" } | { readonly kind: "node"; readonly nodeId: NodeId } | { readonly kind: "page"; readonly pageId: PageId } | { readonly kind: "asset"; readonly assetId: AssetId }

源码

DocumentStore.subscribe 监听器所关注的对象:

  • document:所有变更。
  • node:该节点或其任意后代发生的变更,无论是变更前还是变更后的后代。
  • page:该页面出现在 ChangeSet.changedPageIds 中,或其树中的任意节点发生了变更。
  • asset:该资源发生的变更。

type StoreListener = (event: StoreChangeEvent) => void

源码

DocumentStore.subscribe 的回调。

type StoreStateListener = () => void

源码

DocumentStore.subscribeState 的回调。

type Unsubscribe = () => void

源码

移除返回此函数的那次订阅所注册的监听器。

整个历史记录都可以保存和加载。保存的历史有自己的整数版本和迁移;其中的文档和操作则经过文档迁移。

function serializeStore(store: DocumentStore, indentation = 0): string

源码

将 store 的完整历史以键排序的 JSON 写出:根文档和每个提交的操作,以及 head、分支和重做条目。

function deserializeStore( input: string | unknown, options: StoreOptions = {}, storeMigrations: StoreMigrationRegistry = defaultStoreMigrations, documentMigrations: MigrationRegistry = defaultMigrations ): DocumentStore

源码

从 serializeStore 写出的 JSON 字符串或已解析的值加载 store。

它先运行 storeMigrations,再用 documentMigrations 把根文档和每个已存储的操作迁移到当前文档 schema(见 DocumentMigration.migrateOperation),然后重放每个提交,以重建文档、逆操作和变更集。迁移后不再改变任何内容的提交会被丢弃,由其子提交取代它的位置。未经迁移时,这样的提交会被视为错误。

数据无效或不一致时抛出 ModelError。

type PersistedStore = PersistedStoreV1

源码

当前的已保存历史格式。

interface PersistedStoreV1

源码

DocumentStore 的保存形式:根文档加上每个提交的操作、head、分支和重做栈。由 DocumentStore.toJSON 生成。

readonly storeVersion: typeof CURRENT_STORE_SCHEMA_VERSION源码
readonly documentSchemaVersion: typeof CURRENT_DOCUMENT_SCHEMA_VERSION源码
readonly rootCommitId: CommitId源码
readonly rootDocument: DesignDocument源码
readonly commits: readonly PersistedCommitV1[]源码
readonly headCommitId: CommitId源码
readonly branches: Readonly<Record<string, CommitId>>源码
readonly currentBranch: string | null源码
readonly redoStack: readonly CommitId[]源码

interface PersistedCommitV1

源码

保存时的提交。逆操作和变更不会被保存;加载时通过重放操作重新计算它们。

readonly id: CommitId源码
readonly parentId: CommitId | null源码
readonly sequence: number源码
readonly timestamp: number源码
readonly message?: string源码
readonly actor?: CommitActor源码
readonly operations: readonly DocumentOperation[]源码

const CURRENT_STORE_SCHEMA_VERSION: 1

源码

serializeStore 写出的已保存历史格式的版本。它独立于 CURRENT_DOCUMENT_SCHEMA_VERSION,按整数递增。

class StoreMigrationRegistry

源码

由 StoreMigration 步骤组成的有序链,供 deserializeStore 使用。

new (migrations: readonly StoreMigration[] = [])源码
register(migration: StoreMigration): this源码

添加一个步骤并返回该注册表。如果该步骤不是从一个非负版本恰好前进一个版本,或者已存在从同一版本出发的步骤,则抛出代码为 INVALID_SCHEMA 的 ModelError。

migrate(input: unknown): unknown源码

从输入的 storeVersion 开始依次运行各步骤直到 CURRENT_STORE_SCHEMA_VERSION。抛出代码为 UNSUPPORTED_VERSION、MISSING_MIGRATION 或 MIGRATION_FAILED 的 ModelError。

interface StoreMigration

源码

将已保存历史升级一个 storeVersion 的单个步骤。其中的文档数据由文档迁移单独升级。

readonly from: number源码
readonly to: number源码

必须为 from + 1。

migrate(input: unknown): unknown源码

以纯 JSON 返回升级后的 store,其 storeVersion 设为 to。

const defaultStoreMigrations: StoreMigrationRegistry

源码

此包自带的 store 迁移。只存在版本 1 时为空。

几何与形状

用于节点边界、旋转后的框、编组以及内置形状顶点的辅助函数。

interface Rect

源码

与坐标轴对齐的矩形;x 和 y 是其左上角。

readonly x: number源码
readonly y: number源码
readonly width: number源码
readonly height: number源码

type TransformMatrix = readonly [ a: number, b: number, c: number, d: number, e: number, f: number ]

源码

SVG 风格的仿射矩阵 [a, b, c, d, e, f]。它将点 (x, y) 映射为 (a*x + c*y + e, b*x + d*y + f),即如下 3×3 矩阵乘积:

[x′y′1]=[acebdf001][xy1]\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}

const IDENTITY_TRANSFORM: TransformMatrix

源码

function getNodeBounds(node: SceneNode): Rect

源码

返回节点在其父节点坐标系中的布局边界。

function getRotatedRectBounds(frame: Rect, rotation: number): Rect

源码

返回旋转画框在父空间中的轴对齐边界。

function resizeRotatedRect( frame: Rect, rotation: number, size: { readonly width: number; readonly height: number }, anchor: { readonly x: number; readonly y: number } = { x: 0, y: 0 } ): Rect

源码

改变 frame 的尺寸,同时保持其某个局部点在父坐标系中固定不动。默认锚点是局部左上角。anchor 是相对于尺寸的比例,因此 (α,β)=(0.5,0.5)(\alpha, \beta) = (0.5, 0.5) 表示中心。设 RθR_\theta 为旋转 rotation 度的旋转(在 y 轴向下的空间中为顺时针),锚点相对于 frame 的 x、y 的偏移为:

o(w,h)=[w/2h/2]+Rθ[(α−12) w(β−12) h],Rθ=[cos⁡θ−sin⁡θsin⁡θcos⁡θ]\mathbf{o}(w, h) = \begin{bmatrix} w/2 \\ h/2 \end{bmatrix} + R_\theta \begin{bmatrix} (\alpha - \tfrac12)\,w \\ (\beta - \tfrac12)\,h \end{bmatrix}, \qquad R_\theta = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}

新位置为 (x′,y′)=(x,y)+o(wold,hold)−o(wnew,hnew)(x', y') = (x, y) + \mathbf{o}(w_\text{old}, h_\text{old}) - \mathbf{o}(w_\text{new}, h_\text{new})。

function getPathBounds( pathData: string, transform: TransformMatrix = IDENTITY_TRANSFORM ): Rect | null

源码

返回应用与 SVG 兼容的仿射变换后,填充区域的紧密边界。

function getVectorNetworkBounds( vectorNetwork: VectorNetwork, transform: TransformMatrix = IDENTITY_TRANSFORM ): Rect | null

源码

返回应用仿射变换后,网络各边的紧密边界。

function getGroupChildrenBounds( nodes: NodeRecord, group: GroupNode ): Rect | null

源码

返回编组各子节点边界在编组自身坐标系中的并集;没有子节点的编组返回 null。旋转的子节点贡献其旋转后的包围盒,嵌套编组贡献其自身(已适配的)画框。

function fitGroupToChildren( nodes: NodeRecord, group: GroupNode ): FittedGroup | null

源码

把编组的画框适配到其子节点,而不移动页面上的任何内容。画框已经匹配时返回 null。空编组保持其位置,尺寸收缩为零。

interface FittedGroup

源码
readonly group: GroupNode源码
readonly children: readonly SceneNode[]源码

由于编组原点移动而改变了局部位置的子节点。

function fitAllGroups(nodes: NodeRecord): NodeRecord

源码

适配节点记录中的每个编组,最深层的编组优先,这样父编组看到的是其嵌套编组的最终画框。在加载文档时使用,可修复以过时编组尺寸保存的文件。

function buildParentMap(nodes: NodeRecord): Map<NodeId, NodeId>

源码

function nodeDepth(parents: ReadonlyMap<NodeId, NodeId>, nodeId: NodeId): number

源码

interface ShapePoint

源码

参数化形状(多边形、星形、椭圆弧和直线)的纯几何计算。渲染器编译器、编辑器和测试共用这些辅助函数,使所有使用方得到相同的顶点。

readonly x: number源码
readonly y: number源码

const MIN_SHAPE_POINT_COUNT: 3

自 0.12.0源码

Figma 的多边形和星形顶点数。

const MAX_SHAPE_POINT_COUNT: 60

源码

const DEFAULT_POLYGON_POINT_COUNT: 3

源码

Figma 为新绘制图形设置的默认值。

const DEFAULT_STAR_POINT_COUNT: 5

源码

const DEFAULT_STAR_INNER_RADIUS: 0.382

源码

function isValidShapePointCount(value: number): boolean

源码

function polygonPoints( pointCount: number, width: number, height: number ): ShapePoint[]

源码

正多边形在 frame 局部坐标中的各个角,从顶部中央开始按顺时针排列。多边形会被拉伸,使其边界等于 frame。nn 个角中的第 kk 个角起初位于单位圆上(y 轴向下)

θk=−π2+2πkn,(uk,vk)=(cos⁡θk,sin⁡θk)\theta_k = -\frac{\pi}{2} + \frac{2\pi k}{n}, \qquad (u_k, v_k) = (\cos\theta_k, \sin\theta_k)

然后按其包围盒缩放到 frame 中: xk=w⋅(uk−umin)/(umax−umin)x_k = w \cdot (u_k - u_\text{min}) / (u_\text{max} - u_\text{min}),yky_k 同理使用高度计算(跨度为 0 时取 0)。

function starPoints( pointCount: number, innerRadius: number, width: number, height: number ): ShapePoint[]

源码

星形在 frame 局部坐标中交替排列的外顶点和内顶点,从顶部外顶点开始按顺时针排列。innerRadius 是内顶点距离相对于外半径的比例。星形会被拉伸,使其所有顶点的边界等于 frame。拉伸前,2n2n 个顶点中的第 kk 个为

θk=−π2+πkn,rk={1k evenρk odd,(uk,vk)=(rkcos⁡θk, rksin⁡θk)\theta_k = -\frac{\pi}{2} + \frac{\pi k}{n}, \qquad r_k = \begin{cases} 1 & k \text{ even} \\ \rho & k \text{ odd} \end{cases}, \qquad (u_k, v_k) = (r_k\cos\theta_k,\ r_k\sin\theta_k)

其中 ρ\rho = innerRadius;拉伸方式与 polygonPoints 相同。

function closedPolygonVectorNetwork( points: readonly ShapePoint[], idPrefix = "shape" ): VectorNetwork

源码

穿过给定各点、由直边构成的闭合网络,包含一个区域。

function validateEllipseArc(arc: EllipseArc): string | null

源码

function ellipseArcSweep(arc: EllipseArc): number

源码

扫描角度,单位为度,顺时针为正;最多一整圈: sweep=endingAngle−startingAngle\text{sweep} = \text{endingAngle} - \text{startingAngle}。

function isWholeEllipseArc(arc: EllipseArc | undefined): boolean

源码

当该圆弧绘制的是完整的普通椭圆时为 true。

function ellipseVectorNetwork( width: number, height: number, arc?: EllipseArc, idPrefix = "shape" ): VectorNetwork

源码

填满 width × height 画框的椭圆所对应的网络,可以用可选的弧形裁切:完整椭圆、圆环(完整扫描并带内半径)、扇形(部分扫描且无内半径)或环形扇区。扫描角为零时不绘制任何内容,返回空网络。以度为单位的角度 ϕ\phi(0 指向右方;由于 y 轴向下,正值为顺时针)落在

(w2+w2 tcos⁡ϕ, h2+h2 tsin⁡ϕ)\left(\frac{w}{2} + \frac{w}{2}\,t\cos\phi,\ \frac{h}{2} + \frac{h}{2}\,t\sin\phi\right)

其中外边缘上 t=1t = 1,内边缘上 tt = innerRadius。

function lineEndpoints( line: Pick< LineNode, | "frame" | "rotation" | "flipX" | "flipY" > ): { readonly start: ShapePoint; readonly end: ShapePoint }

源码

直线在其父节点坐标系中的起点和终点。设 frame 中心为 (cx,cy)(c_x, c_y),宽度为 ww,旋转角为 θ\theta(由角度换算为弧度),设置了 flipX 时 s=−1s = -1,否则 s=1s = 1:

start,end=(cx,cy)∓sw2(cos⁡θ,sin⁡θ)\text{start}, \text{end} = (c_x, c_y) \mp \frac{s w}{2}(\cos\theta, \sin\theta)

function lineFrameFromEndpoints( start: ShapePoint, end: ShapePoint ): { readonly frame: Rect; readonly rotation: number }

源码

连接两个父空间点的直线所对应的零高度 frame 和旋转。旋转以角度表示,范围为 (-180, 180]。

function constrainLineEndpoint( anchor: ShapePoint, point: ShapePoint ): ShapePoint

源码

移动 point,使从 anchor 出发的线段保持长度不变,但转到最接近的 45 度整数倍方向,效果与绘制直线时按住 Shift 相同。

Connectors

Where connector ends go on a layer’s outline. The Connector tool offers a layer’s key points as dots (connectorKeyPoints); an end pinned to one of them stores a side or an anchor (ConnectorKeyPlace), and connectorPinnedPlace finds where it sits on the layer. An automatic end sits where the outline meets the line toward the other end (connectorOutlinePointToward). The page compiler and the editor share these, so the dot a connector is dropped on is where its end is drawn. Positions are in the layer’s own coordinates.

function connectorKeyPoints(node: SceneNode): readonly ConnectorKeyPoint[]

源码

The key points of a layer, in the order the Connector tool shows them:

  • A rectangle, frame, text, image or any other box: the middle of each side, as FigJam’s TOP, RIGHT, BOTTOM and LEFT magnets.
  • An ellipse: its top, right, bottom and left points (on the curve, which touches its box there), keeping only those an arc draws, and the two ends of an arc that stops short of a full turn.
  • A polygon: every corner, and the middle of every edge when it has at most MAX_CONNECTOR_EDGE_KEY_POINT_COUNT points.
  • A star: its outer tips. Its inner corners point into the star, so a connector there would cross it.

interface ConnectorKeyPoint extends ShapePoint

源码

A point on a layer’s outline that a connector end can be pinned to.

readonly place: ConnectorKeyPlace源码
readonly normal: ShapePoint源码

The outline’s outward direction at the point.

type ConnectorKeyPlace = | { readonly side: ConnectorSide; readonly anchor?: undefined } | { readonly anchor: ConnectorAnchor; readonly side?: undefined }

源码

How an end is pinned to a key point: by a side (Figma’s magnet) or an anchor.

function sameConnectorKeyPlace( a: ConnectorKeyPlace, b: ConnectorKeyPlace ): boolean

源码

Two places are the same pin: the same side, or the same kind and index of anchor.

function connectorPinnedPlace( node: SceneNode, endpoint: ConnectorEndpoint ): ConnectorOutlinePlace | undefined

源码

The place of an attached end pinned by side, point or anchor on node, or undefined for an automatic end (including an anchor the layer does not have). A side on a box or ellipse is the middle of that side of the box; on a polygon or star it is where the outline meets the line from the centre (the average of its corners) straight toward that side. A side or anchor has the outward normal; a fixed point has none.

function connectorAnchorPoint( node: SceneNode, anchor: ConnectorAnchor ): ConnectorOutlinePlace | undefined

源码

The place of an anchor on a layer, or undefined when the layer has no such point: an index past its corners, or an anchor on a box or whole ellipse.

function connectorOutlinePointToward( node: SceneNode, toward: ShapePoint ): ShapePoint

源码

Where on its outline a layer meets the line from its centre toward toward: the box’s edge, the ellipse’s curve (a whole ellipse, even for an arc) or the polygon’s or star’s outermost crossing. The layer’s centre when toward is the centre.

interface ConnectorOutlinePlace extends ShapePoint

源码

A place on a layer an end is drawn at, with the outward direction when it has one.

readonly normal?: ShapePoint源码

const CONNECTOR_SIDE_NORMALS: Readonly<Record<ConnectorSide, ShapePoint>>

源码

The outward direction of each side of a layer’s box.

const MAX_CONNECTOR_EDGE_KEY_POINT_COUNT: 8

源码

A polygon above this many points shows its corners only: with more, the dots in the middle of its edges crowd the corners.

Components and instances

A component is a reusable layer tree stored once per document, never on a page: its layers live in nodes under ComponentDefinition.rootId, listed in DesignDocument.components. An InstanceNode shows it on a page. It stores a reference and LayerOverrides keyed by layer path, and its layers are derived by resolveInstance with virtual IDs <instance>;<path> (parseVirtualNodeId). editTargetFor decides whether an edit to a selected ID goes to a stored node or to an instance override, and setOverrideOperations writes one. After an edit, withAutoLayoutOperations runs the component cascade (cascadeComponentChanges): instances of changed components are refitted to their hugging size, their override keys that name deleted layers are dropped (pruneOverrides), and their auto layout ancestors are laid out again, nested components first. remapOverrides carries overrides over to another component tree by layer name and position, for swap, redefine and paste. The nesting graph (componentNestingGraph) says which components contain which, for the cycle rule and for invalidation. The sample documents are what the compiler, editor and web tests build on. See docs/components/design.md.

interface ComponentDefinition

自 0.23.0源码

A reusable layer tree, stored once per document and shown in the Assets panel, never on a page. Its layers live in DesignDocument.nodes under rootId, so every node operation, undo and validation works on them unchanged. Instances (InstanceNode) show it on pages.

readonly id: ComponentId源码

Matches the key in DesignDocument.components.

readonly key: string源码

A stable identity separate from id, a UUID string, unique in the document. Paste between documents and, later, libraries match components by key, so a component edited after a paste is still recognised as the same component. It never changes.

readonly name: string源码

Shown in the Assets panel. Must not be empty.

readonly description?: string源码

Optional free text shown in the Assets panel.

readonly rootId: NodeId源码

The root of the component’s layer tree: always a frame with no parent that no page uses. Its frame.x and frame.y are 0; its width and height are the natural size, which is the size shown in the component view. Its layout sizing (Hug or Fixed) is the size behaviour every instance starts with; see LayerOverride.sizing.

readonly properties?: readonly ComponentPropertyDefinition[]自 0.24.0源码

The component’s properties, in the order the instance section lists them. IDs and names are unique within the component. Omitted when empty.

readonly metadata?: Readonly<Record<string, JsonValue>>源码

Free-form JSON data kept with the component. The model does not read it.

type ComponentId = Brand<string, "ComponentId">

自 0.23.0源码

The ID of a ComponentDefinition, its key in DesignDocument.components.

const componentId: (value: string) => ComponentId

自 0.23.0源码

Brands a string as a ComponentId. Throws a TypeError for an empty string.

interface InstanceNode extends FramedNodeBase

自 0.23.0源码

One use of a component on a page, or inside another component. It stores a reference and its overrides; its layers are derived when the page is compiled (see resolveInstance) and get virtual IDs <instance id>;<layer path> (see parseVirtualNodeId).

The instance has no children; isContainerNode is false for it. Its NodeBase fields apply to the whole instance, like a frame’s, and its frame, rotation, flips and resizing place it like any framed node. frame holds the resolved size, so geometry, selection and snapping code works without the resolver; applyOperations keeps hugging axes equal to the resolved size (from step 1.2). The instance’s own paints come from the component root and are overridden under the component root’s path.

readonly type: "instance"源码
readonly componentId: ComponentId源码
readonly overrides?: Readonly<Record<string, LayerOverride>>源码

Changes to the component’s layers, keyed by layer path: the component node IDs from the component root down to the layer, joined by ;, without the instance ID. Omitted when empty. A key naming a node the component no longer has is allowed and has no effect.

readonly propertyValues?: ComponentPropertyValues自 0.24.0源码

The instance’s values for the component’s properties, keyed by property ID. Missing means the default; a value equal to the default is still kept, so Reset is what makes the instance follow the default again. Omitted when empty.

interface LayerOverride

自 0.23.0源码

The changes one instance makes to one layer of its component, stored in InstanceNode.overrides under the layer’s path. Every field replaces the layer’s resolved value as a whole; a field that is absent follows the component. Structure (layers, layout kind and spacing, geometry of inner layers, masks, blend modes, names) is not overridable: that needs an edit to the component, or Detach.

Precedence for one field of one layer, decided per field:

  1. A variable ID in variableBindings for the field’s property: the variable’s value wins.
  2. Otherwise a plain value in this override for the field (or null in variableBindings for its property): the override value wins, and the component layer’s own binding for that property is ignored in this instance. Overriding a field therefore never gets repainted by the component’s binding.
  3. Otherwise the component layer’s own binding, then its stored value.

When instances nest, the override stored on the outer instance wins over the one stored on the nested instance node inside the component, which wins over the component’s value, again field by field.

readonly visible?: boolean源码
readonly opacity?: number源码

From 0 (transparent) to 1 (opaque).

readonly characters?: string源码

Text layers: the whole text as plain characters, paragraphs separated by "\n". Every character takes the style of the component’s first run, so a component font change still reaches an instance that only changed its label. Not allowed together with paragraphs.

readonly paragraphs?: readonly TextParagraph[]源码

Text layers: the whole content with styled runs, stored only when the user styles part of the text differently from the rest. Not allowed together with characters.

readonly textStyleId?: TextStyleId | null源码

Text layers: the theme text style every run takes instead of its own; null clears the runs’ style IDs so they use the theme default.

readonly textStyle?: TextStyleOverrides源码

Text layers: direct formatting (font, size, weight, line height, letter spacing, colour and the rest) applied on top of every run’s style.

readonly styleId?: NodeStyleId | null源码

Frames and shapes: the node style to use; null clears the layer’s.

readonly fills?: readonly Paint[]源码
readonly strokes?: readonly Stroke[]源码
readonly shadows?: readonly Shadow[]源码
readonly layerBlur?: number源码
readonly backgroundBlur?: number源码
readonly imageAssetId?: AssetId源码

Image layers: the image asset to show instead.

readonly componentId?: ComponentId源码

Nested instance layers: the component to show instead (a swap).

readonly sizing?: LayerSizingOverride源码

Frame layers, and the component root for the instance’s own size.

readonly variableBindings?: LayerOverrideVariableBindings源码
readonly propertyValues?: ComponentPropertyValues自 0.24.0源码

Nested instance layers: property values keyed by property ID, each replacing the value the nested instance has in the component (stored or computed). Overrides are constants, never expressions.

interface LayerSizingOverride

自 0.23.0源码

Which axes of a layer inside an instance hug their content or keep a fixed size, replacing the component frame’s layout.widthSizing and layout.heightSizing. Under the component root’s path it is the instance’s own size behaviour: resizing an instance on the canvas stores "fixed" on that axis, and Reset size removes the entry, so the instance follows the component root again. Fill is not stored here: an instance fills its parent through its own resizing, like any framed node.

readonly width?: "hug" | "fixed"源码
readonly height?: "hug" | "fixed"源码

type LayerOverrideVariableBindings = Readonly< Partial<Record<VariableProperty, VariableId | null>> >

自 0.23.0源码

Variable bindings an instance stores for one layer, keyed by property. A variable ID binds the property in that instance; null removes the component’s binding for that property in that instance and leaves the plain value (the layer’s, or the override’s) in force.

const LAYER_PATH_SEPARATOR: ";"

自 0.23.0源码

The character that joins the IDs in a layer path and a virtual node ID. Stored node IDs never contain it.

interface VirtualNodeId

自 0.23.0源码

The parts of a virtual node ID: the stored instance the layer belongs to and the layer path inside it.

readonly instanceId: NodeId源码

The stored InstanceNode on a page or inside a component.

readonly path: readonly NodeId[]源码

The component node IDs from the instance down to the layer, in order. Component roots that are passed through are left out; a component root is only named when it is the addressed layer itself (for the instance’s own paints and size). Never empty.

const isVirtualNodeId: (id: string) => boolean

源码

True when id names a layer inside an instance rather than a stored node.

function parseVirtualNodeId(id: string): VirtualNodeId | null

自 0.23.0源码

Splits a virtual node ID <instance id>;<layer path> into its instance and layer path. Returns null for a stored node ID (no separator) and for a malformed ID with an empty segment. This is the only place that splits virtual IDs.

function virtualNodeId(instanceId: NodeId, path: readonly NodeId[]): NodeId

源码

Builds the virtual node ID of the layer at path inside instanceId.

function layerPathKey(path: readonly NodeId[]): string

源码

The key of InstanceNode.overrides for the layer at path.

function parseLayerPath(key: string): readonly NodeId[] | null

自 0.23.0源码

Splits an override key into its component node IDs, or returns null when the key is malformed (empty, or with an empty segment). Whether the named nodes still exist is not checked: such a key is allowed and has no effect.

function storedNodeIdOf(id: NodeId): NodeId

源码

The stored node an ID refers to: the instance for a virtual ID, the ID itself otherwise. Selection code uses it to find the node that moves, deletes or reorders when a layer inside an instance is selected.

function componentRootIds(document: DesignDocument): readonly NodeId[]

源码

The root node IDs of every component, in components order.

function findComponentByRoot( document: DesignDocument, rootId: NodeId ): ComponentDefinition | undefined

源码

The component whose root is rootId, if any.

function componentOwningNode( document: DesignDocument, nodeId: NodeId, parents: ReadonlyMap< NodeId, NodeId > = buildParentMap(document.nodes) ): ComponentDefinition | undefined

源码

The component whose layer tree contains the stored node nodeId (the root included), or undefined when the node is on a page or does not exist. Pass parents (from buildParentMap) when calling this for many nodes.

function isComponentLayer(document: DesignDocument, nodeId: NodeId): boolean

源码

True when the stored node is a component layer (its root included) rather than a page node.

function instanceNodeOf( document: DesignDocument, instanceId: NodeId ): InstanceNode | undefined

源码

The node an instance ID names, checked to be an InstanceNode.

function componentReferencesOf(node: SceneNode): readonly ComponentId[]

源码

The components a node refers to: an instance’s componentId, and every component its overrides swap a nested instance to. Empty for other nodes.

function instancesOfComponent( document: DesignDocument, componentId: ComponentId ): readonly NodeId[]

源码

The stored instance nodes of componentId, by ID, sorted. Swaps in overrides do not count.

interface ComponentNestingGraph

自 0.23.0源码

Which components contain which. nests.get(a) holds every b such that a node under a’s root is an instance of b, or an override under a’s root swaps a nested instance to b. nestedBy is the reverse. Every component appears as a key of both maps, with an empty set when it has no edges. Instances on pages add no edges.

readonly nests: ReadonlyMap<ComponentId, ReadonlySet<ComponentId>>源码
readonly nestedBy: ReadonlyMap<ComponentId, ReadonlySet<ComponentId>>源码

function componentNestingGraph(document: DesignDocument): ComponentNestingGraph

源码

Builds the ComponentNestingGraph of a document. Missing component references are kept as edges.

function findComponentCycle( graph: ComponentNestingGraph ): readonly ComponentId[] | null

自 0.23.0源码

Finds a cycle in the nesting graph: a list of component IDs where each nests the next and the last equals the first. Returns null when the graph has no cycle.

function componentsNesting( graph: ComponentNestingGraph, componentId: ComponentId ): ReadonlySet<ComponentId>

源码

Every component whose tree contains componentId, directly or through nesting. A change to componentId also changes the instances of these.

function componentsNestedIn( graph: ComponentNestingGraph, componentId: ComponentId ): ReadonlySet<ComponentId>

源码

Every component that componentId’s tree contains, directly or through nesting.

function wouldNestCycle( document: DesignDocument, hostId: ComponentId, placedId: ComponentId ): boolean

自 0.23.0源码

Reports whether placing an instance of placedId inside hostId’s tree, or swapping a nested instance there to placedId, would make a component contain itself. The editor disables such choices; assertDocument rejects the result.

interface ResolvedLayer

自 0.23.0源码

One derived layer of a resolved instance. node is the component node with the instance’s overrides applied (by the precedence on LayerOverride) and its frame laid out for the instance’s size, so the compiler compiles it exactly as it compiles a stored node, with virtualId as the render node ID.

  • node.id equals virtualId, and a container’s children list holds the virtual IDs of children, in paint order.
  • path names the nested instance nodes passed through and then the layer itself; frames passed through inside one component are left out, as component roots are, since node IDs are unique in the document.
  • The root layer stands for the instance itself: its virtualId is the instance’s own ID, its path is [component root ID] (the override key for the instance’s paints and size), and its node is a FrameNode carrying the instance’s NodeBase fields, frame, rotation, flips and resizing, with the component root’s layout, style and clipContent (overrides applied). instance names the stored instance. A nested instance layer’s path is the path to the nested instance node, which is also its override key on the outer instance for its paints and sizing, as editTargetFor writes it.
  • A nested instance inside the component is expanded the same way: its node is a FrameNode built like the root layer (the nested instance node’s placement and NodeBase fields, after the outer overrides, with the nested component root’s layout, style and clipContent), instance gives the nested instance and the component it shows after any swap, and children are the nested component’s layers, whose paths continue through it.
readonly virtualId: NodeId源码
readonly sourceNodeId: NodeId源码

The component node this layer is derived from.

readonly path: readonly NodeId[]源码

The layer path inside the outermost instance; see VirtualNodeId.path.

readonly node: SceneNode源码
readonly children: readonly ResolvedLayer[]源码
readonly instance?: ResolvedLayerInstance源码

Present on the root layer and on nested instance layers.

readonly inheritedVariableModes?: VariableModes自 0.26.0源码

The variable modes the layer inherits from its parent layer, as inheritedVariableModes gives them for a stored node; the layer’s own choices (an instance’s, for the root and nested instance layers) are not included. Present on the layers of a resolved instance.

readonly variableModes?: VariableModes自 0.26.0源码

The variable modes in effect at the layer, which its bound fields read. Present on the layers of a resolved instance.

interface ResolvedLayerInstance

自 0.23.0源码

The stored instance a resolved layer stands for, set on the root layer and on every nested instance layer.

readonly instanceId: NodeId源码

The stored InstanceNode: the outer instance, or a nested one inside a component.

readonly componentId: ComponentId源码

The component shown, after any swap by an outer override.

readonly node: InstanceNode自 0.26.0源码

The instance node as resolved: swapped, with outer overrides and the enclosing component’s computed fields (its own propertyValues included) applied. The component view draws a nested instance from it.

readonly propertyValues?: ComponentPropertyValues自 0.26.0源码

The property values the component is resolved with: the stored instance’s own, or for a nested instance its outer override, else its expression over the outer properties, else its stored value. Absent when none is set (every property at its default).

interface ResolvedInstance

自 0.23.0源码

What resolveInstance returns: the instance’s derived layer tree.

readonly instanceId: NodeId源码
readonly componentId: ComponentId源码
readonly root: ResolvedLayer源码

The layer standing for the instance itself; see ResolvedLayer.

readonly layers: ReadonlyMap<NodeId, ResolvedLayer>源码

Every resolved layer by virtual ID, the root under the instance ID.

readonly componentIds: readonly ComponentId[]源码

The components this instance draws, its own first, then every nested one after swaps, without repeats. A change to any of them changes the result.

readonly expressionErrors: readonly ComponentExpressionError[]自 0.25.0源码

Computed values this instance’s property values make invalid, such as a font family with no font in the document, for every component it draws; each such field shows its stored value.

interface InstanceResolveCache

自 0.23.0源码

Resolved trees kept between calls so a component is resolved once for all its instances (design 4.3). One cache belongs to one document line; call clear when the document is replaced.

A component’s version rises when any node in its own layer tree is a new object; an entry is reused only while every component it draws keeps its version and the theme and assets are the same objects. An instance entry also needs the instance node itself to be the same object.

clear(): void源码
readonly stats: { readonly hits: number; readonly misses: number; readonly evaluations: number; }源码

How many resolveInstance and resolveComponent calls were served from the cache, and how many times a component’s conditions and computed fields were evaluated (evaluations, since 0.25.0): once per component, component version, variables and property values with defaults filled in, however many instances share them.

function createInstanceResolveCache(): InstanceResolveCache

源码

Makes an InstanceResolveCache to pass to resolveInstance.

interface ResolveInstanceOptions

自 0.23.0源码
readonly cache?: InstanceResolveCache源码
readonly variableModes?: VariableModes自 0.26.0源码

The variable modes the instance inherits from its parent, as inheritedVariableModes returns them. Read from the document when omitted; the page compiler passes them as it walks the page.

function resolveInstance( document: DesignDocument, instanceId: NodeId, options?: ResolveInstanceOptions ): ResolvedInstance

自 0.23.0源码

Derives the layers an instance shows: virtual IDs, overrides applied by precedence, nested instances expanded, and the component root’s auto layout run for the instance’s size and overridden text. A hugging axis takes its natural size, whatever the stored frame says; a fixed axis and an axis the instance fills keep the stored size.

With component properties (design 8.6, since 0.25.0), each component in the instance is resolved in this order: conditions leave layers out (with their sublayers, taking no space in auto layout), computed fields are evaluated for the instance’s property values and written into the model fields, overrides go on top (an override wins over a computed value), and then layout runs. A nested instance’s property values are its outer override, else its expression over the outer properties, else its stored value, else the nested component’s default. An expression that does not check is skipped (see componentExpressionErrors). A root without auto layout lays out a resized instance by its children’s constraints (constrainChildren).

Throws a ModelError with code INVALID_TREE when instanceId is not an instance node or its component is missing.

function resolveComponent( document: DesignDocument, componentId: ComponentId, options?: ResolveInstanceOptions ): ResolvedLayer

自 0.23.0源码

Derives the component view: the component’s own layer tree at its natural size with no overrides, as ResolvedLayers whose virtualIds are the stored node IDs. Isolation mode draws it; a nested instance inside it is expanded as in resolveInstance, under its own stored ID. A component with properties or expressions shows its default values (design 8.9): conditions and computed fields are evaluated with the defaults, and its auto layout frames are laid out again.

function huggedInstanceSize( document: DesignDocument, instanceId: NodeId, options?: ResolveInstanceOptions ): { readonly width?: number; readonly height?: number }

自 0.23.0源码

The size an instance takes on each axis it hugs, from its resolved root. undefined on an axis the instance keeps as stored (Fixed, Fill, or a component root without auto layout).

function cascadeComponentChanges( document: DesignDocument, nodes: Record<string, SceneNode>, changedNodeIds: ReadonlySet<NodeId>, changedComponentIds: readonly ComponentId[], changed: Set<NodeId> ): void

源码

The component cascade of one edit (design question D): after the ordinary layout pass, refits every instance whose component changed (or that nests a changed component, or that the edit touched itself) to its hugging size, drops its override keys that name deleted layers, and lays out its auto layout ancestors again, on pages and inside components. Nested components go first, so a component that nests a changed one is laid out with the new nested sizes before its own instances are refitted.

nodes is the working copy after the operations and the layout pass; it is changed in place, and every node it changes is added to changed. changedNodeIds are the nodes the operations and the layout pass changed.

interface OverrideRemapTree

自 0.23.0源码

One component’s layer tree as a remap or prune reads it: the document that holds the nodes and the component’s root. Swap passes one document with two roots; redefine and paste pass the old and the new document.

readonly document: DesignDocument源码
readonly rootId: NodeId源码
readonly shownComponentAt?: (path: readonly NodeId[]) => ComponentId | undefined自 0.26.0源码

The component the nested instance at a layer path (inside the instance whose overrides are remapped) shows, for when its component is computed from a property value. Without it, or when it returns undefined, the nested instance node’s stored component counts. An override swap at the path still wins.

function remapOverrides( overrides: | Readonly<Record<string, LayerOverride>> | undefined, from: OverrideRemapTree, to: OverrideRemapTree, mapComponent: ( id: ComponentId ) => ComponentId = (id) => id ): Record<string, LayerOverride>

自 0.23.0源码

Carries an instance’s overrides over to another component tree by layer name and position (design 3.5): each key’s layers are matched from the root down by name at the same index among their siblings, else by the first sibling with that name; a nested instance segment continues into the component it shows. Keys with no match are dropped, and a key that is remapped onto another key’s target is dropped as well (the earlier key wins). Property values on a nested instance’s entry are carried to the component that layer shows on the other side (carryPropertyValues, with mapComponent for instance swap values). Swap, redefine and paste use this, then store the result.

function overridePathResolves( document: DesignDocument, componentId: ComponentId, path: readonly NodeId[], overrides: Readonly<Record<string, LayerOverride>> = {}, shownComponentAt?: (path: readonly NodeId[]) => | ComponentId | undefined ): boolean

自 0.23.0源码

Whether an override key names a layer the component still has: every segment but the last must be a nested instance node in the tree entered so far (after any swap in overrides, else the component shownComponentAt gives), and the last a node in that tree.

function pruneOverrides( document: DesignDocument, instance: InstanceNode ): InstanceNode

自 0.23.0源码

The instance without the override keys that name layers its component no longer has (design 3.5); the same node when every key still resolves.

type OverrideField = keyof LayerOverride

自 0.23.0源码

The fields an instance can override; the keys of LayerOverride.

const OVERRIDE_FIELDS: readonly OverrideField[]

源码

Every OverrideField, in LayerOverride order.

type EditTarget = | { readonly kind: "node"; readonly nodeId: NodeId; readonly node: SceneNode } | { readonly kind: "override"; readonly instanceId: NodeId; readonly instance: InstanceNode; readonly key: string; readonly path: readonly NodeId[]; readonly sourceNodeId: NodeId; readonly field: OverrideField; } | { readonly kind: "unsupported"; readonly reason: string }

自 0.23.0源码

Where an edit to one field of one selected ID goes.

  • node: a stored node on a page or inside a component (editing in isolation changes the component). Write it with node.replace.
  • override: a layer inside an instance, or an instance’s own paints and size. Write it with setOverrideOperations (a node.replace of the instance with the changed overrides[key]); sourceNodeId is the component node the layer is derived from, for reading the base value.
  • unsupported: the edit cannot be made here; reason says why, for the user (a structural field on a layer inside an instance, or a layer the component no longer has).

function editTargetFor( document: DesignDocument, id: string, field: string ): EditTarget

自 0.23.0源码

Decides where an edit goes. id is a stored node ID or a virtual ID (<instance>;<path>); field is the layer field being edited: an OverrideField, a node field name with the same meaning (assetId for imageAssetId), or variableBindings.<property> for one binding.

A virtual ID always targets an override on its outermost instance, so an edit to a layer of a nested instance is stored on the instance the user selected through. Fields that are not in LayerOverride (position, size, rotation, name, layout, masks, blend mode) are unsupported on a virtual ID: they need an edit to the component, or Detach.

type LayerOverridePatch = { readonly [Field in OverrideField]?: LayerOverride[Field] | undefined }

自 0.23.0源码

A change to one override entry: each present key replaces that field, and a key set to undefined removes it (Reset for that field).

function withOverride( instance: InstanceNode, key: string, patch: LayerOverridePatch ): InstanceNode

自 0.23.0源码

Returns the instance with patch merged into overrides[key]. Setting characters removes paragraphs and the other way round, so the two never coexist. An entry left with no fields is removed, and an empty overrides map is dropped. Pure: the input is not changed.

function withoutOverride( instance: InstanceNode, key?: string, field?: OverrideField ): InstanceNode

自 0.23.0源码

Returns the instance without an override: one field of one layer, one whole layer (field omitted), or every override (key omitted). Pure.

function setOverrideOperations( document: DesignDocument, instanceId: NodeId, key: string, patch: LayerOverridePatch ): readonly DocumentOperation[]

自 0.23.0源码

The operations that write patch into overrides[key] of the instance: one node.replace, or none when the instance is not an instance node. applyOperations drops a replace that changes nothing.

function resetOverrideOperations( document: DesignDocument, instanceId: NodeId, key?: string, field?: OverrideField ): readonly DocumentOperation[]

自 0.23.0源码

The operations that reset overrides of the instance: one field of one layer, one layer, or all (see withoutOverride). An axis that hugs again loses its stretching constraint when the operations are applied, as after every edit (applyOperations).

const componentSampleIds: { readonly document: DocumentId; readonly page: PageId; readonly pageRoot: NodeId; readonly textStyle: TextStyleId; readonly button: ComponentId; readonly buttonRoot: NodeId; readonly buttonLabel: NodeId; readonly buttonIcon: NodeId; readonly card: ComponentId; readonly cardRoot: NodeId; readonly cardTitle: NodeId; readonly cardButton: NodeId; readonly iconButton: ComponentId; readonly iconButtonRoot: NodeId; readonly iconButtonIcon: NodeId; readonly buttonInstance: NodeId; readonly secondButtonInstance: NodeId; readonly cardInstance: NodeId; readonly colors: VariableCollectionId; readonly lightMode: VariableModeId; readonly primary: VariableId; readonly danger: VariableId; }

自 0.23.0源码

The IDs the component sample documents use, so tests can refer to them by name. Layer paths for overrides are built from the node IDs, for example layerPathKey([componentSampleIds.cardButton, componentSampleIds.buttonLabel]).

const componentSampleDocuments: { readonly plain: () => DesignDocument; readonly nested: () => DesignDocument; readonly textOverride: () => DesignDocument; readonly variableBoundOverride: () => DesignDocument; readonly swappedNested: () => DesignDocument; }

自 0.23.0源码

Every component sample by name, for tests that run over all of them.

function plainInstanceSample(): DesignDocument

自 0.23.0源码

One Button component and one instance of it on the page, with no overrides. The instance is at the component’s natural size.

function nestedInstanceSample(): DesignDocument

自 0.23.0源码

A Card component whose tree holds an instance of Button, and one Card instance on the page. The nesting graph has the edge Card → Button.

function textOverrideSample(): DesignDocument

自 0.23.0源码

Two Button instances with text overrides: button-1 changes the label’s characters only, and button-2 stores styled paragraphs because part of its label is bold. Both keep the component’s font.

function variableBoundOverrideSample(): DesignDocument

自 0.23.0源码

The Button label’s colour is bound to the primary variable in the component. The instance rebinds it to danger for the label, and for the root it overrides the fills with a plain colour while removing the component’s fillColor binding, so the plain override cannot be repainted by the variable.

function swappedNestedInstanceSample(): DesignDocument

自 0.23.0源码

The nested sample plus an Icon button component. The Card instance swaps its nested Button to Icon button, and keeps a characters override under the old label’s path, which Icon button does not have: the entry is allowed and has no effect.

### Isolation mode

Editing a component in isolation (design 5.5) keeps a stack of IsolationLevels, one per opened component. isolationEditRoute applies the edit rules: in the instance view an edit changes the override that wins at that place when the opened instance side already overrides the field, and the component otherwise; in the component view it always changes the component. Its reach says whether the edit changes only this instance or a component and how many instances that has. isolationViews is what the canvas draws besides the instance in place: the component views, laid out as a grid inside one set outline when there are several, never saved or exported. The editor draws them in the split’s component pane.

interface IsolationLevel

自 0.23.0源码

One level of isolation mode (design 5.5): the component being edited and the instance it was opened from.

Levels form a stack. The first level opens a component from an instance on a page (or from the Assets panel, with no instance); each deeper level opens the component of a nested instance seen in the level above.

readonly componentId: ComponentId源码

The component edited at this level. For a swapped nested instance, the component it is swapped to.

readonly instanceId: NodeId | null源码

The instance the level was opened from, drawn as the instance view, or null when the level was opened from the Assets panel (only the component view is shown). It is a stored instance ID (an instance on a page, or a nested instance node inside the component view of the level above) or a virtual ID (<instance>;<path>, a nested instance as it appears inside the instance view of the level above).

type IsolationView = "instance" | "component"

自 0.23.0源码

Which of the two isolation views an edit is made in (design 5.5): the instance view shows the opened instance with its overrides and uses virtual IDs; the component view shows the component’s own nodes by their stored IDs.

type EditReach = | { readonly kind: "this-instance"; readonly instanceId: NodeId } | { readonly kind: "component"; readonly componentId: ComponentId; readonly instanceCount: number; }

自 0.23.0源码

How far an edit reaches (question F in the components plan): only the opened instance, or a component and so every instance of it. The editor shows “Only this instance” or “Changes the component (N instances)”.

type IsolationEditRoute = | { readonly kind: "edit"; readonly target: WritableTarget; readonly overridden: boolean; readonly reach: EditReach; } | { readonly kind: "unsupported"; readonly reason: string }

自 0.23.0源码

Where an edit made in isolation goes (design 5.5, Edit rules).

  • edit: write target as editTargetFor describes it. overridden is true when the edit changes an override that wins at that place on the instance side of the level (the first row of the design’s table); the editor marks such fields “Overridden”. reach is the question F signal.
  • unsupported: the edit cannot be made in this view; reason is for the user.

function isolationEditRoute( document: DesignDocument, level: IsolationLevel, view: IsolationView, id: NodeId, field: string ): IsolationEditRoute

自 0.23.0源码

Where an edit to field of the layer id, made in view at isolation level level, goes (design 5.5, Edit rules and nesting). field is as for editTargetFor: an override field, a node field name, variableBindings.<property>, or textStyle.<member> for one text style member (routed by that member and its own binding only).

Component view: id is a stored node of the level’s component, or a virtual ID of a layer inside a nested instance node of it. The edit always changes the component; this is editTargetFor’s answer, checked to stay inside the component.

Instance view: id is the level’s instance ID (its root) or a virtual ID under it. The overrides that can apply at that place are those stored on the level’s instance and on every instance it is nested in (the instance side). When the override whose value shows there (by the resolver’s precedence: a binding beats a plain value, then outermost first) is one of them, the edit changes that override: only this instance when that instance is on a page, or the component that holds it when it is a nested instance node inside a component. Otherwise the edit changes the level’s component, as the same edit in the component view would. Isolation never creates an override (design 5.5). Geometry, structure and other fields that cannot be overridden always go to the component.

function componentOfInstance( document: DesignDocument, instanceId: NodeId ): ComponentId | undefined

自 0.23.0源码

The component an instance shows: a stored instance’s componentId, or for a virtual ID naming a nested instance, the component it is swapped to by the override that wins at that place (outer instance first), else the nested instance node’s own componentId.

A nested instance whose componentId is computed from the properties of the component that holds it (an instance swap property) shows the computed component, unless an override swaps it. That one is read from the tree the instance resolver draws, so it is the property values of the instance on the page, or in a component’s own view the property defaults. A nested instance that is not drawn (a condition leaves it out) has its stored component.

undefined when the ID does not name an instance or the component is missing.

function componentInstanceCount( document: DesignDocument, componentId: ComponentId ): number

自 0.23.0源码

How many instances an edit to the component reaches, for “Editing affects N instances”: every stored instance node of the component in the document, on pages and inside other components. A nested instance inside a component counts once, however many instances of the outer component show it, and swaps in overrides do not count (as instancesOfComponent).

interface IsolationBreadcrumb

自 0.23.0源码

One crumb of the isolation bar: the page, then one per level.

readonly label: string源码
readonly depth: number源码

How many levels stay open when the crumb is chosen: 0 for the page.

function isolationBreadcrumbs( document: DesignDocument, pageName: string, levels: readonly IsolationLevel[] ): readonly IsolationBreadcrumb[]

自 0.23.0源码

The isolation bar’s breadcrumbs: page › component › nested component.

interface ComponentView

自 0.23.0源码

One component view: the component drawn by its stored node IDs at its natural size (the root’s frame size), with no overrides, under the label “Component”. “Show all variants” adds one view per combination of property values, laid out beside it inside one set outline (design 8.2).

readonly componentId: ComponentId源码
readonly rootId: NodeId源码

The component root; the view draws the component’s layer tree from it.

readonly label: string源码
readonly bounds: Rect源码

The view’s place at the natural size, in the coordinates of the set of views: the first view (the defaults) is at 0,0.

readonly variant?: { readonly values: ComponentPropertyValues; readonly key: string; }自 0.26.0源码

A variant view’s property values (the ones that differ from the defaults) and its combination key; absent for the view at the defaults, which draws the stored nodes.

interface IsolationViewsOptions

源码

What isolationViews draws besides the component view.

readonly vary?: readonly ComponentPropertyId[]自 0.26.0源码

“Show all variants”: the enum and boolean properties to vary. One view per combination is drawn when there are at most VARIANT_VIEW_CAP; otherwise only the component view.

readonly also?: ComponentPropertyValues自 0.27.0源码

Property values whose view is drawn as well, whatever vary holds: the opened instance’s, so the variant it shows can be edited beside the defaults. Adds nothing when they are the defaults or already drawn.

interface IsolationViews

自 0.23.0源码

What the canvas draws for one isolation level. The views are not part of the document; they are never saved or exported.

readonly componentId: ComponentId源码
readonly instanceId: NodeId | null源码

The instance view: the opened instance, drawn in place with its overrides; null from the Assets panel.

readonly componentViews: readonly ComponentView[]源码

The component views, the defaults first, in reading order (row by row, left to right).

readonly setBounds?: Rect自 0.27.0源码

The outline around the views when more than one is drawn, in the same coordinates as their bounds: the views with COMPONENT_SET_PADDING around them, as Figma outlines a component set. Absent with one view.

const COMPONENT_VIEW_GAP: 40

源码

The gap between two views, in canvas units.

const COMPONENT_SET_PADDING: 40

自 0.27.0源码

The space between the set outline and the views inside it, in canvas units.

function isolationViewCombinations( component: ComponentDefinition, options?: IsolationViewsOptions ): readonly VariantCombination[]

自 0.27.0源码

The combinations isolationViews draws for options, in drawing order: the defaults alone with no options; every combination of vary; and the combination of also after them when it is not one of those already.

function isolationViews( document: DesignDocument, level: IsolationLevel, options?: IsolationViewsOptions ): IsolationViews | undefined

自 0.23.0源码

The views to draw for level, laid out as a grid inside one set outline: with one varied property (or none) the views are one row; with more, the last varied property’s values are the columns and every combination of the others is a row. A column is as wide as its widest view and a row as tall as its tallest, so the views line up. A view added by options.also goes at the end of the first row.

导出设置

每个节点可以为其“导出”面板携带若干行设置。这些辅助函数用于检查这些行、选取默认值并生成文件名。

interface ExportSetting

自 0.14.0源码

图层“导出”区域中的一行。每个字段都始终存储,因此切换格式时该行会保留其值;不适用于当前格式的字段在导出时会被忽略。

readonly format: ExportFormat源码
readonly constraint: ExportConstraint源码

仅适用于 PNG 和 JPEG;SVG 和 PDF 始终以 1x 导出。

readonly suffix: string源码

添加在文件名中图层名之后;可以为空。

readonly quality: ExportQuality源码

仅适用于 JPEG 和 PDF。

readonly resampling: ExportResampling源码

仅适用于 PNG、JPEG 和 PDF。

readonly ignoreOverlappingLayers: boolean源码

仅适用于 PNG、JPEG 和 SVG。为 true 时只绘制该图层及其子图层;为 false 时绘制该图层边界内的所有可见图层。

readonly includeIdAttribute: boolean源码

仅适用于 SVG:为绘制的元素添加由图层名生成的 “id” 属性。

type ExportFormat = (typeof EXPORT_FORMATS)[number]

源码

const EXPORT_FORMATS: readonly ["png", "jpeg", "svg", "pdf"]

自 0.14.0源码

图层可以导出的文件格式。

type ExportConstraint = | { readonly type: "scale"; readonly value: number } | { readonly type: "width"; readonly value: number } | { readonly type: "height"; readonly value: number }

自 0.14.0源码

光栅导出的输出尺寸:图层尺寸的倍数,或固定的像素宽度或高度,另一边按比例保持。

type ExportQuality = (typeof EXPORT_QUALITIES)[number]

源码

const EXPORT_QUALITIES: readonly ["low", "medium", "high"]

自 0.14.0源码

JPEG 压缩级别,或 PDF 中效果的光栅分辨率。

type ExportResampling = (typeof EXPORT_RESAMPLINGS)[number]

源码

const EXPORT_RESAMPLINGS: readonly ["detailed", "basic"]

自 0.14.0源码

“detailed” 使用双三次插值对图片采样;“basic” 使用最近邻像素。

const MAX_EXPORT_SCALE: 100

源码

缩放约束可取的最大倍数。

const MAX_EXPORT_DIMENSION: 16384

源码

尺寸约束可取的最大像素宽度或高度;即渲染器自身的上限。

const MAX_EXPORT_SUFFIX_LENGTH: 100

源码

后缀的最大长度,以 UTF-16 码元计。

const MAX_EXPORT_SETTINGS: 64

源码

一个节点最多可包含的行数。

function defaultExportQuality(format: ExportFormat): ExportQuality

源码

一行导出设置切换到 format 时的初始质量。

function isVectorExportFormat(format: ExportFormat): format is "svg" | "pdf"

源码

当该格式忽略尺寸约束并以 1x 导出时为 true。

function nextExportSetting(existing: readonly ExportSetting[]): ExportSetting

源码

导出区域的 + 按钮所添加的行。第一行为 1x 的 PNG,不带后缀。之后每一行复制最后一行的格式和选项,并取下一个整数倍率,配上对应的“@Nx”后缀,与 Figma 的做法一致。

function exportConstraintProblem(constraint: ExportConstraint): string | null

源码

约束无效的原因;有效时为 null。

function exportSuffixProblem(suffix: string): string | null

源码

后缀无效的原因;有效时为 null。

function formatExportConstraint(constraint: ExportConstraint): string

源码

约束在缩放字段中显示的形式:“2x”、“512w” 或 “512h”。

function parseExportConstraint(text: string): ExportConstraint | null

源码

读取用户在缩放字段中输入的内容。“2”、“2x” 和 “2X” 表示倍数,“512w” 表示固定宽度,“512h” 表示固定高度。当文本不是有效的约束时返回 null。

function exportFileExtension(format: ExportFormat): string

源码

某种格式的文件扩展名;与 Figma 一样,JPEG 文件使用 “.jpg”。

function exportFileStem(name: string): string

源码

图层名中在所有常见系统的文件名里都安全的部分。路径分隔符和保留字符会变为 “-”。

function exportFileName( name: string, setting: Pick<ExportSetting, "format" | "suffix"> ): string

源码

<layer name><suffix>.<extension>,与 Figma 为每个导出文件命名的方式相同。

function uniqueExportFileNames(names: readonly string[]): readonly string[]

源码

使一次导出中的每个文件名都唯一。重复的名称会在扩展名前加上“ 2”、“ 3”等,因此不会有下载文件覆盖另一个。

function uniqueSvgId(name: string, used: Set<string>): string

源码

由图层名称生成的有效 XML id:空格变为“_”,字母、数字、“_”、“-”和“.”以外的其他字符被删除,不以字母或“_”开头的名称会在开头加上“_”。used 保存文件中已有的 id;重复的 id 会加上“_2”、“_3”等。结果会被加入 used。

Component expressions

The component expression language (docs/components/design.md 8.4 and 8.5) lets a layer field inside a component be computed from the component’s properties and the document’s variables. This part of the package parses source text into an Expression tree with spans, type-checks it against an ExpressionEnvironment (the properties, the variables and what stored reads) and the field’s ExpressionType, and rewrites the source when a property, an enum option or a variable is renamed. EXPRESSION_LIBRARY holds the signatures of every constructor and standard library function. evaluateExpression runs a checked expression against an ExpressionValueEnvironment and always gives an ExpressionValue, which wraps the model’s own types where one exists (design.md 8.4, “Values as the model stores them”); ExpressionCache keeps parsed and checked forms per source text and environment version.

function parseExpression(source: string): ExpressionParseResult

源码

Parses source text into an expression tree, or reports the first syntax error.

type ExpressionParseResult = | { readonly ok: true; readonly expression: Expression } | { readonly ok: false; readonly error: ExpressionError }

源码

What parseExpression gives back: a tree, or the first error.

const EXPRESSION_SOURCE_LIMIT: 4000

源码

The longest expression source the parser accepts, in UTF-16 code units.

const EXPRESSION_DEPTH_LIMIT: 64

源码

The deepest nesting of sub-expressions the parser accepts.

type Expression = | { readonly kind: "boolean"; readonly value: boolean; readonly span: ExpressionSpan; } | { readonly kind: "number"; readonly value: number; readonly unit?: ExpressionUnit; readonly span: ExpressionSpan; } | { readonly kind: "string"; readonly value: string; readonly span: ExpressionSpan; } | { readonly kind: "color"; readonly value: ExpressionColor; readonly span: ExpressionSpan; } | { readonly kind: "option"; readonly name: string; readonly span: ExpressionSpan; } | { readonly kind: "name"; readonly name: string; readonly span: ExpressionSpan; } | { readonly kind: "stored"; readonly span: ExpressionSpan } | { readonly kind: "variable"; readonly name: string; readonly nameSpan: ExpressionSpan; readonly span: ExpressionSpan; } | { readonly kind: "call"; readonly callee: string; readonly calleeSpan: ExpressionSpan; readonly args: readonly ExpressionArgument[]; readonly span: ExpressionSpan; } | { readonly kind: "list"; readonly items: readonly Expression[]; readonly span: ExpressionSpan; } | { readonly kind: "field"; readonly target: Expression; readonly name: string; readonly nameSpan: ExpressionSpan; readonly span: ExpressionSpan; } | { readonly kind: "with"; readonly target: Expression; readonly updates: readonly ExpressionFieldUpdate[]; readonly span: ExpressionSpan; } | { readonly kind: "unary"; readonly operator: "-" | "not"; readonly operand: Expression; readonly span: ExpressionSpan; } | { readonly kind: "binary"; readonly operator: ExpressionBinaryOperator; readonly operatorSpan: ExpressionSpan; readonly left: Expression; readonly right: Expression; readonly span: ExpressionSpan; } | { readonly kind: "if"; readonly condition: Expression; readonly then: Expression; readonly else: Expression; readonly span: ExpressionSpan; } | { readonly kind: "let"; readonly name: string; readonly nameSpan: ExpressionSpan; readonly value: Expression; readonly body: Expression; readonly span: ExpressionSpan; } | { readonly kind: "match"; readonly subject: Expression; readonly arms: readonly ExpressionMatchArm[]; readonly otherwise?: Expression; readonly span: ExpressionSpan; }

源码

A node of the expression syntax tree. kind tells the construct.

interface ExpressionSpan

源码

A half-open range of UTF-16 offsets in an expression’s source text.

readonly start: number源码
readonly end: number源码

interface ExpressionError

源码

A parse or type error, with the text it points at and an optional fix.

readonly message: string源码
readonly span: ExpressionSpan源码
readonly hint?: string源码

A short suggested fix, for example “write 8px”.

type ExpressionUnit = "px" | "%" | "deg"

源码

The unit suffix of a number literal: 8px, 50%, 45deg.

type ExpressionBinaryOperator = | "or" | "and" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "++" | "+" | "-" | "*" | "/"

源码

The two-operand operators, from or (lowest precedence) to / (highest).

interface ExpressionColor

源码

An sRGB colour with every channel from 0 to 1, as a #rrggbb[aa] literal parses to.

readonly red: number源码
readonly green: number源码
readonly blue: number源码
readonly alpha: number源码

interface ExpressionArgument

源码

One argument of a call: positional, or named with name: value.

readonly name?: string源码
readonly nameSpan?: ExpressionSpan源码
readonly value: Expression源码

interface ExpressionFieldUpdate

源码

One name: value pair inside with { ... }.

readonly name: string源码
readonly nameSpan: ExpressionSpan源码
readonly value: Expression源码

type ExpressionPattern = | { readonly kind: "option"; readonly name: string; readonly span: ExpressionSpan; } | { readonly kind: "boolean"; readonly value: boolean; readonly span: ExpressionSpan; }

源码

A match arm pattern: an enum option (.small) or a boolean (true).

interface ExpressionMatchArm

源码

One arm of a match: one or more patterns and the value they give.

readonly patterns: readonly ExpressionPattern[]源码
readonly body: Expression源码

const EXPRESSION_KEYWORDS: readonly [ "if", "then", "else", "let", "in", "match", "with", "or", "and", "not", "true", "false", "stored", "var" ]

源码

The words the language reserves; they cannot name a property or a let.

type ExpressionKeyword = (typeof EXPRESSION_KEYWORDS)[number]

源码

function parseColorLiteral(text: string): ExpressionColor | undefined

源码

Reads a #rgb, #rgba, #rrggbb or #rrggbbaa literal into channels from 0 to 1.

type ExpressionType = | { readonly kind: "boolean" } | { readonly kind: "number" } | { readonly kind: ExpressionUnitTypeKind } | { readonly kind: "string" } | { readonly kind: "color" } | { readonly kind: "component" } | ExpressionEnumType | { readonly kind: "point" } | { readonly kind: "size" } | { readonly kind: "insets" } | { readonly kind: "corners" } | { readonly kind: "paint" } | { readonly kind: "stroke" } | { readonly kind: "effect" } | { readonly kind: "text_style" } | { readonly kind: "list"; readonly element: ExpressionType }

源码

A type of the expression language. Every value has exactly one.

type ExpressionUnitTypeKind = "length" | "percent" | "angle"

源码

The unit types: numbers that carry a unit and never mix with each other.

interface ExpressionEnumType

源码

An enum type: a named set of options. Two enum types are the same when their names match.

readonly kind: "enum"源码
readonly name: string源码

Unique within one checking environment. The property model gives each enum property its own name; layer field enums use the field’s name.

readonly options: readonly string[]源码

Option names in display order, as written after the dot: .large.

const EXPRESSION_TYPES: { readonly boolean: { readonly kind: "boolean" }; readonly number: { readonly kind: "number" }; readonly length: { readonly kind: "length" }; readonly percent: { readonly kind: "percent" }; readonly angle: { readonly kind: "angle" }; readonly string: { readonly kind: "string" }; readonly color: { readonly kind: "color" }; readonly component: { readonly kind: "component" }; readonly point: { readonly kind: "point" }; readonly size: { readonly kind: "size" }; readonly insets: { readonly kind: "insets" }; readonly corners: { readonly kind: "corners" }; readonly paint: { readonly kind: "paint" }; readonly stroke: { readonly kind: "stroke" }; readonly effect: { readonly kind: "effect" }; readonly text_style: { readonly kind: "text_style" }; }

源码

The types with a single kind and nothing else, ready to use.

const STROKE_ALIGN_TYPE: ExpressionEnumType

源码

The enum type of a stroke’s align argument and field.

function expressionListType(element: ExpressionType): ExpressionType

源码

list(element).

function expressionEnumType( name: string, options: readonly string[] ): ExpressionEnumType

源码

An enum type with the given name and options.

function expressionTypesEqual(a: ExpressionType, b: ExpressionType): boolean

源码

True when a value of type a is also a value of type b. Enums match by name.

function isExpressionUnitType( type: ExpressionType ): type is { readonly kind: ExpressionUnitTypeKind }

源码

True for length, percent and angle.

function isExpressionNumeric(type: ExpressionType): boolean

源码

True for number and the unit types: what arithmetic, comparison and min accept.

function formatExpressionType(type: ExpressionType): string

源码

The type as the language writes it: length, list(paint), Size (.small, .large).

function expressionRecordFields( type: ExpressionType ): Readonly<Record<string, ExpressionType>> | undefined

源码

The fields a record type exposes to value.field and value with { field: ... }, or undefined for a type that is not a record. Field names follow the language’s snake_case (top_left, line_height).

const EXPRESSION_LIBRARY: Readonly<Record<string, ExpressionFunction>>

源码

Every constructor and standard library function, by name. A null prototype keeps toString and the like out of lookups.

interface ExpressionFunction

源码

A constructor or standard library function with its overloads, tried in order.

readonly name: string源码
readonly group: "numbers" | "colours" | "strings" | "constructors"源码
readonly summary: string源码
readonly overloads: readonly ExpressionSignature[]源码

interface ExpressionSignature

源码

One way to call a function: its parameters, in order, and its result type.

readonly parameters: readonly ExpressionParameter[]源码
readonly rest?: ExpressionType源码

When set, any number of extra positional arguments of this type may follow the parameters.

readonly result: ExpressionType源码

interface ExpressionParameter

源码

One parameter of a signature. A parameter with a default may be left out.

readonly name: string源码
readonly type: ExpressionType源码
readonly defaultSource?: string源码

The default, as expression source text (0px, .center); absent for a required parameter.

function formatExpressionSignature( name: string, signature: ExpressionSignature ): string

源码

A signature as the language writes it: min(a: number, b: number, ...) -> number.

function checkExpression( expression: Expression, expected: ExpressionType, environment: ExpressionEnvironment ): ExpressionCheckResult

源码

Type-checks an expression against the type its field expects (boolean for a condition), the component’s properties and the document’s variables.

function checkExpressionSource( source: string, expected: ExpressionType, environment: ExpressionEnvironment ): ExpressionCheckResult

源码

Parses and checks source text in one step; a syntax error is the only error reported.

interface ExpressionEnvironment

源码

What an expression may read, as the checker sees it. Step 3.2 builds one from a component’s properties and the document’s variables.

propertyType(name: string): ExpressionType | undefined源码

The type of the component property with this name, or undefined when there is none.

variableType(name: string): ExpressionType | undefined源码

The type of the document variable written "Collection/Name", or undefined when there is none.

readonly storedType?: ExpressionType源码

The type of the component’s base value of the field being computed, which is what stored reads. Leave it out for a condition, where stored has no meaning.

interface ExpressionCheckResult

源码

The outcome of checking one expression.

readonly ok: boolean源码

True when there are no errors.

readonly type?: ExpressionType源码

The type of the whole expression, when it could be told.

readonly errors: readonly ExpressionError[]源码
readonly references: readonly ExpressionReference[]源码

Every property, option and variable the expression names, in source order.

type ExpressionReference = | { readonly kind: "property"; readonly name: string; readonly span: ExpressionSpan; } | { readonly kind: "option"; readonly enum: string; readonly name: string; readonly span: ExpressionSpan; } | { readonly kind: "variable"; readonly name: string; readonly span: ExpressionSpan; }

源码

A place in the source that names something the editor can rename.

function renameInExpression( source: string, expected: ExpressionType, environment: ExpressionEnvironment, renames: | ExpressionRename | readonly ExpressionRename[] ): ExpressionRenameResult

源码

Rewrites every reference to the renamed properties, options or variables in the source text. The environment and expected type describe the field as it is before the rename, so .large can be told apart between enums. Several renames are found in one check of the original source, so a reference half-way through a batch never meets names the environment does not know yet. Source that does not parse is returned unchanged; type errors elsewhere in the expression do not stop the references that do resolve from being rewritten. A let name that shadows a property is not a reference to it.

type ExpressionRename = | { readonly kind: "property"; readonly from: string; readonly to: string } | { readonly kind: "option"; readonly enum: string; readonly from: string; readonly to: string; } | { readonly kind: "variable"; readonly from: string; readonly to: string }

源码

What to rename. Names are the ones in force before the rename.

interface ExpressionRenameResult

源码

The rewritten source and how many references changed.

readonly source: string源码
readonly count: number源码

function expressionSignatureAccepts( signature: ExpressionSignature, positionalCount: number, named: ReadonlySet<string> ): boolean

源码

True when this many positional arguments plus these named ones fill the signature without gaps or extras: every parameter is given once, by position, by name or by its default. The checker and the evaluator pick an overload with it.

type ExpressionValue = | { readonly kind: "boolean"; readonly value: boolean } | { readonly kind: "number"; readonly value: number } | { readonly kind: ExpressionUnitTypeKind; readonly value: number } | { readonly kind: "string"; readonly value: string } | { readonly kind: "color"; readonly value: ExpressionColor } | { readonly kind: "component"; readonly id: string } | { readonly kind: "enum"; readonly option: string } | { readonly kind: "point"; readonly x: number; readonly y: number } | { readonly kind: "size"; readonly width: number; readonly height: number } | { readonly kind: "insets"; readonly value: LayoutPadding } | { readonly kind: "corners"; readonly value: CornerRadii } | { readonly kind: "paint"; readonly value: Paint } | { readonly kind: "stroke"; readonly value: Stroke } | { readonly kind: "effect"; readonly value: ExpressionEffect } | { readonly kind: "text_style"; readonly value: ExpressionTextStyle } | { readonly kind: "list"; readonly items: readonly ExpressionValue[] }

源码

A value of the expression language. kind matches the type’s kind.

type ExpressionEffect = | { readonly kind: "shadow"; readonly shadow: Shadow } | { readonly kind: "layer_blur"; readonly radius: number } | { readonly kind: "background_blur"; readonly radius: number }

源码

One effect. The model keeps shadows in shadows and the two blurs as plain radii, so this is the union step 3.3 sorts into those fields.

type ExpressionTextStyle = & Pick<TextStyle, "fontFamily" | "fontWeight" | "fontSize"> & { readonly lineHeightPixels: number; readonly letterSpacing: number }

源码

The parts of a text style an expression can build; the name and colour come from elsewhere. lineHeightPixels is the language’s line_height, a length in pixels. The model’s TextStyle.lineHeight is a multiple of the font size, so whatever applies this value must divide by fontSize first.

function expressionColorToHex(color: ExpressionColor): string

源码

The colour as the model stores it: #rrggbb, or #rrggbbaa when the alpha is below 1.

function expressionColorFromHex(text: string): ExpressionColor

源码

Reads a model colour string; a string that is not a hex colour reads as opaque black.

function zeroExpressionValue(type: ExpressionType): ExpressionValue

源码

The value 0 of a type: false, 0, “”, transparent black, the first option, empty records and lists. It is what a division by zero gives and what a missing value falls back to.

function expressionValuesEqual(a: ExpressionValue, b: ExpressionValue): boolean

源码

True when two values of one type are equal, compared by value; what == gives.

function evaluateExpression( expression: Expression, environment: ExpressionValueEnvironment ): ExpressionValue

源码

Evaluates an expression that has passed the check. It never throws for such an expression when the environment holds every property, variable and stored value the checking environment typed; a missing one is a programming error and throws, since a wrong value would be a silent failure.

interface ExpressionValueEnvironment

源码

What an expression reads while it runs: the counterpart of the checking ExpressionEnvironment, with values in place of types. Every name the checking environment typed must have a value here.

propertyValue(name: string): ExpressionValue | undefined源码

The value of the component property with this name, or undefined when there is none.

variableValue(name: string): ExpressionValue | undefined源码

The value of the document variable "Collection/Name" in the active mode, or undefined when there is none.

readonly stored?: ExpressionValue源码

The component’s base value of the field being computed, which stored reads.

function finiteExpressionNumber(value: number): number

源码

0 for a number that is not finite (from very large values or 0 / 0); negative zero is plain 0.

function clampExpressionAmount(value: number): number

源码

A number held between 0 and 1: what amounts and colour channels become.

class ExpressionCache

源码

Keeps parsed and checked expressions per source text for one version of a checking environment. Bump version whenever the properties, the variables or the components change; the cache then starts over.

check( source: string, expected: ExpressionType, environment: ExpressionEnvironment, version: string | number ): CheckedExpression源码

Parses and checks source against the field’s type, or returns the cached result for this version.

get size(): number源码

How many expressions are cached for the current version.

clear(): void源码

Forgets everything.

interface CheckedExpression

源码

A parsed and checked expression. expression is absent after a syntax error.

readonly expression?: Expression源码
readonly result: ExpressionCheckResult源码

The expression editor reads the rest. expressionTypeNotes gives the type expected and found at every node, which completion uses on unfinished text through completeExpression; highlightExpression colours source text that may not parse. expressionValueSource writes a value back as source. readValueTable and readShowWhen recognise exactly the value table and “Show when” forms of design.md 8.8, and writeValueTable, setValueTableRow and writeShowWhen build them again.

function expressionTypeNotes( expression: Expression, expected: ExpressionType, environment: ExpressionEnvironment ): readonly ExpressionTypeNote[]

源码

Checks the expression and returns, for every node and match pattern, the type expected there and the type found, in the order the checker visited them. The expression editor reads it for completion (which options fit a . here, which fields a value has) and for the type shown under the text.

interface ExpressionTypeNote

源码

What the checker knew about one node or match pattern: the type it expected there, and the type it found.

readonly span: ExpressionSpan源码
readonly expected?: ExpressionType源码

The type the place asks for, when it asks for one (a field, an argument, the other side of ==, a match pattern).

readonly type?: ExpressionType源码

The node’s type, when it could be told.

function completeExpression( source: string, caret: number, context: ExpressionCompletionContext, explicit = false ): ExpressionCompletion | undefined

源码

The completions at caret. After a . that starts an option literal or pattern it offers the options of the enum expected there; after a . that reads a field, the fields of the value’s type; inside var("..."), the variables; in a word, properties, variables written as var("Collection/Name"), functions with their signature and keywords, the ones whose type fits the place first. Names that start with the typed text come before names that only contain it. Returns undefined inside a comment, a colour or another string, or at an empty word unless it follows match or explicit is set (the user asked with Ctrl+Space).

interface ExpressionCompletionContext

源码

What completion offers and where it comes from.

readonly expected: ExpressionType源码

The type the whole expression must have: the field’s type, or boolean for a condition.

readonly environment: ExpressionEnvironment源码
readonly properties: readonly string[]源码

The component’s property names, in panel order.

readonly variables: readonly string[]源码

The document’s variables as "Collection/Name".

interface ExpressionCompletion

源码

The completions at a caret, for the text between from and to.

readonly from: number源码
readonly to: number源码
readonly expected?: ExpressionType源码

The type expected at the caret, when the checker could tell.

readonly items: readonly ExpressionCompletionItem[]源码

interface ExpressionCompletionItem

源码

One completion. Choosing it replaces from–to of the completion with insert.

readonly kind: | "property" | "option" | "field" | "variable" | "function" | "keyword"源码
readonly label: string源码

What the list shows.

readonly insert: string源码
readonly caret?: number源码

Where the caret goes inside insert (after the ( of a function); the end when absent.

readonly detail?: string源码

The type, or a function’s signature.

readonly fits: boolean源码

True when its type is the type expected at the caret; these come first.

function highlightExpression( source: string, isProperty: (name: string) => boolean ): ExpressionHighlight[]

源码

Splits source text into coloured stretches. It never fails: text the lexer would reject (an unknown character, an unfinished string) comes out as invalid or as far as it goes. Names are property when isProperty says so, function before a (, and name otherwise (let names and unknown names).

interface ExpressionHighlight

源码

One coloured stretch; from and to are UTF-16 offsets, to exclusive.

readonly from: number源码
readonly to: number源码
readonly kind: ExpressionHighlightKind源码

type ExpressionHighlightKind = | "keyword" | "property" | "function" | "name" | "option" | "field" | "number" | "string" | "color" | "comment" | "operator" | "punctuation" | "invalid"

源码

What a stretch of source text is, for its colour.

function expressionValueSource(value: ExpressionValue): string | undefined

源码

The value as expression source text that evaluates back to it, such as 8px, .large, insets(4px, 8px) or solid(#ff0000, 0.5), or undefined when the language cannot write it: a component (there is no component literal), an image paint, a gradient with uneven stops, a paint with a blend mode, a dashed stroke. Numbers keep four decimals.

function formatExpressionNumber(value: number): string

源码

Up to four decimals, without trailing zeros and never in exponent form.

function formatExpressionString(value: string): string

源码

A string literal with ", \ and line breaks escaped as the lexer reads them.

function readValueTable( source: string, environment: ExpressionEnvironment ): ExpressionValueTable | undefined

源码

Recognises a value table: a match on one enum or boolean property, one pattern per arm, no else, every arm a constant. Rows follow the property’s option order (“on” before “off”); an option the match does not cover yet (added to the enum later) is a row without source. Returns undefined for anything else, which the editor shows as an expression.

function writeValueTable( table: Pick<ExpressionValueTable, "property" | "subject" | "rows"> ): string

源码

Writes a value table as a match, one arm per row in row order; rows without source are left out. It fits on one line when short enough, as in match size { .small => 4px, .large => 8px }, and otherwise puts each arm on its own line.

function startValueTable( property: string, subject: ValueTableSubject, rowSource: string ): string

源码

A new value table over the property with every row holding rowSource, the field’s current value.

function setValueTableRow( source: string, environment: ExpressionEnvironment, key: string, rowSource: string ): string

源码

Replaces one row’s constant. A row that is already written is replaced in place, so the rest of the text (comments, line breaks) stays; a row the match does not cover yet is added by writing the table again. Throws when source is not a value table or key is not one of its rows: the caller only offers rows of a table it read.

function valueTableSubject( property: string, environment: ExpressionEnvironment ): ValueTableSubject | undefined

源码

The subject for a property, or undefined when a table cannot vary by it (it is not an enum or boolean).

function valueTableKeys( subject: ValueTableSubject ): readonly { readonly key: string; readonly label: string }[]

源码

The rows a value table over this subject has, without values.

function isConstantExpression(expression: Expression): boolean

源码

True when the expression reads nothing that changes with property values: no property, stored, if, let or match.

interface ExpressionValueTable

源码

A value table read from source text: one row per option, in the property’s option order.

readonly property: string源码

The property the table varies by.

readonly subject: ValueTableSubject源码
readonly rows: readonly ValueTableRow[]源码

interface ValueTableRow

源码

One row of a value table.

readonly key: string源码

The option name, or "true" / "false" for a boolean.

readonly label: string源码

What the row shows: the option name, or “on” / “off”.

readonly source?: string源码

The row’s constant as source text; absent when the match has no arm for it yet.

type ValueTableSubject = | { readonly kind: "enum"; readonly type: ExpressionEnumType } | { readonly kind: "boolean" }

源码

What a value table varies by: an enum property’s options, or a boolean’s on and off.

function readShowWhen( source: string, environment: ExpressionEnvironment ): ShowWhenCondition | undefined

源码

Recognises a “Show when” condition: showIcon, not showIcon, size == .large, or size == .a or size == .b ... with one property, known options and no option twice. Options come back in the order written. Returns undefined for anything else.

function writeShowWhen(condition: ShowWhenCondition): string

源码

Writes a “Show when” condition. Throws for an enum condition without options, which would never show the layer.

type ShowWhenCondition = | { readonly kind: "boolean"; readonly property: string; readonly on: boolean; } | { readonly kind: "enum"; readonly property: string; readonly options: readonly string[]; }

源码

A “Show when” condition in one of the forms of design 8.8.

Component properties

A component’s properties (docs/components/design.md 8.2 and 8.7) are named, typed inputs listed in ComponentDefinition.properties; each instance sets values in InstanceNode.propertyValues, keyed by the stable property ID, and an outer instance can set a nested instance’s values in LayerOverride.propertyValues. Layers inside a component can store expressions (source text keyed by ComputableField) and a condition. assertDocument checks only their shape: an expression that does not check is an allowed state, and the field then shows its stored value.

The adapters connect a document to the expression language: componentExpressionEnvironment and componentValueEnvironment give the checking and evaluation environments of a component (its properties, the document’s variables by "Collection/Name" in the active mode, and stored), computableFieldType and storedFieldValue give a field’s expected type and base value, and expressionFieldContext puts them together for one field. A number variable reads as a length when all its scopes are lengths (variableExpressionType). The operation builders keep expressions valid through edits: renames rewrite every affected expression in the same edit; deletions and kind changes remove instance values that no longer apply and report how many expressions use what changed.

type ComponentPropertyDefinition = | (ComponentPropertyBase<"boolean"> & { readonly defaultValue: boolean }) | ( & ComponentPropertyBase<"number"> & { readonly unit: ComponentNumberUnit; readonly defaultValue: number; readonly min?: number; readonly max?: number; readonly step?: number; }) | ( & ComponentPropertyBase<"text"> & { readonly defaultValue: string; readonly multiline?: boolean }) | ( & ComponentPropertyBase<"enum"> & { readonly options: readonly ComponentPropertyOption[]; readonly defaultValue: string; }) | (ComponentPropertyBase<"color"> & { readonly defaultValue: string }) | ( & ComponentPropertyBase<"instance"> & { readonly defaultValue: ComponentId; readonly preferred?: readonly ComponentId[]; })

自 0.24.0源码

A named, typed input on a component. Each instance chooses a value for it in InstanceNode.propertyValues, or leaves the default.

interface ComponentPropertyBase<Kind extends ComponentPropertyKind>

自 0.24.0源码

Fields every component property has.

readonly id: ComponentPropertyId源码

Stable and never shown; instance values are keyed by it.

readonly kind: Kind源码
readonly name: string源码

Unique in the component and an identifier (letters, digits and _, not starting with a digit, not a keyword of the expression language): expressions read the property by this name.

readonly description?: string源码

type ComponentPropertyKind = (typeof COMPONENT_PROPERTY_KINDS)[number]

自 0.24.0源码

One of COMPONENT_PROPERTY_KINDS.

const COMPONENT_PROPERTY_KINDS: readonly [ "boolean", "number", "text", "enum", "color", "instance" ]

自 0.24.0源码

The kinds of component property, as ComponentPropertyDefinition.kind.

type ComponentNumberUnit = (typeof COMPONENT_NUMBER_UNITS)[number]

自 0.24.0源码

One of COMPONENT_NUMBER_UNITS.

const COMPONENT_NUMBER_UNITS: readonly ["none", "px", "%", "deg"]

自 0.24.0源码

The unit of a number property: "none" reads as a number in expressions, "px" as a length, "%" as a percent and "deg" as an angle.

interface ComponentPropertyOption

自 0.24.0源码

One option of an enum property. The ID is stable; the name is what expressions write after the dot (.large) and must be an identifier, unique within the property.

readonly id: string源码
readonly name: string源码

type ComponentPropertyId = Brand<string, "ComponentPropertyId">

自 0.24.0源码

The stable ID of a component property (ComponentPropertyDefinition.id), unique within its component. It never changes, so instance values keyed by it survive a rename.

const componentPropertyId: (value: string) => ComponentPropertyId

自 0.24.0源码

Brands a string as a ComponentPropertyId. Throws a TypeError for an empty string.

type ComponentPropertyValue = boolean | number | string

自 0.24.0源码

A value an instance sets for a property: a boolean, a number, a string (text), an option ID (enum), a colour string or a component ID (instance swap). A value that does not fit the property’s current kind is ignored, as is a value for a property the component no longer has.

type ComponentPropertyValues = Readonly<Record<string, ComponentPropertyValue>>

自 0.24.0源码

Property values keyed by ComponentPropertyId. Missing means the default.

type ComputableField = | (typeof COMPUTABLE_FIELDS)[number] | `propertyValues.${string}`

自 0.24.0源码

A field that can hold an expression: a COMPUTABLE_FIELDS name or propertyValues.<property id>.

const COMPUTABLE_FIELDS: readonly [ "visible", "opacity", "fills", "strokes", "effects", "cornerRadius", "cornerRadii", "cornerSmoothing", "width", "height", "minWidth", "maxWidth", "minHeight", "maxHeight", "gap", "wrapGap", "columnGap", "rowGap", "padding", "direction", "align", "justify", "wrap", "characters", "fontFamily", "fontSize", "fontWeight", "lineHeight", "letterSpacing", "textColor", "textStyle", "componentId" ]

自 0.24.0源码

The layer fields that can hold an expression. Which ones apply depends on the node type (see computableFieldsOf); propertyValues.<property id> computes a nested instance’s property value. Position, rotation, flips, blend modes, masks and the layer name are not computable.

type NamedComputableField = (typeof COMPUTABLE_FIELDS)[number]

自 0.24.0源码

A computable field other than propertyValues.<id>.

type NodeExpressions = Readonly<Partial<Record<ComputableField, string>>>

自 0.24.0源码

Expression source text keyed by computed field.

function computableFieldsOf(node: SceneNode): readonly NamedComputableField[]

自 0.24.0源码

The named fields a node of this type can compute, in COMPUTABLE_FIELDS order. An instance node can also compute propertyValues.<property id> for any property of its component.

function isComputableField( node: SceneNode, field: string ): field is ComputableField

自 0.24.0源码

True when field can hold an expression on this node. It checks the name only: a propertyValues.<id> field naming a property the nested component does not have is allowed and has no effect.

function propertyValueFieldId(field: string): string | undefined

自 0.24.0源码

The property ID in a propertyValues.<property id> field, or undefined for any other field.

const PROPERTY_VALUE_FIELD_PREFIX: "propertyValues."

自 0.24.0源码

The prefix of the computed field that holds a nested instance’s property value.

const COMPUTABLE_FIELD_VARIABLE_PROPERTIES: Readonly< Record<NamedComputableField, readonly VariableProperty[]> >

自 0.24.0源码

The variable binding properties that set the same value as a computed field. A field holds a binding or an expression, never both: saving an expression removes these bindings.

function variablePropertiesOfField(field: string): readonly VariableProperty[]

自 0.24.0源码

The variable binding properties that clash with a computed field; empty for propertyValues.<id>.

function isExpressionIdentifier(name: string): boolean

自 0.24.0源码

True when name can be written in an expression as a property or an enum option name: letters, digits and _, not starting with a digit, and not a keyword of the language.

function findComponentProperty( component: ComponentDefinition, propertyId: string ): ComponentPropertyDefinition | undefined

自 0.24.0源码

The property with this ID, or undefined.

function findComponentPropertyByName( component: ComponentDefinition, name: string ): ComponentPropertyDefinition | undefined

自 0.24.0源码

The property with this name, or undefined.

function propertyValueFits( property: ComponentPropertyDefinition, value: ComponentPropertyValue ): boolean

自 0.24.0源码

True when value fits the property’s kind: a boolean for a boolean, a finite number for a number, a string for text and colour, an existing option ID for an enum, and a non-empty string for an instance swap.

function effectivePropertyValue( property: ComponentPropertyDefinition, value: ComponentPropertyValue | undefined ): ComponentPropertyValue

自 0.24.0源码

The value a property takes: the given value when it fits the property’s kind, else the default.

const LENGTH_VARIABLE_PROPERTIES: readonly VariableProperty[]

自 0.24.0源码

The binding properties that hold a length in pixels. A number variable whose scopes are all in this list reads as a length in expressions.

function variableExpressionType(variable: VariableDefinition): ExpressionType

自 0.24.0源码

The type a variable reads as in expressions. Colour, string and boolean variables read as color, string and boolean. A number variable reads as a length (pixels) when it has scopes and every scope is a length (LENGTH_VARIABLE_PROPERTIES), and as a plain number otherwise: with no scopes, or any scope such as opacity, font weight or line height.

function variableExpressionName( collectionName: string, variableName: string ): string

自 0.24.0源码

The name an expression reads a variable by: "Collection/Name".

function variablesByExpressionName( theme: DocumentTheme ): ReadonlyMap<string, LocatedVariable>

自 0.24.0源码

The document’s variables by "Collection/Name". A name that two variables share is left out, so an expression that uses it shows an unknown-variable error instead of reading either one.

function variableExpressionValue( located: LocatedVariable, modes?: VariableModes ): ExpressionValue | undefined

自 0.24.0源码

The value of a variable in the mode its collection shows under modes (see resolveVariableValue; without modes, the active mode), typed as variableExpressionType.

function componentPropertyExpressionType( property: ComponentPropertyDefinition, enumName: string = property.name ): ExpressionType

自 0.24.0源码

The type a property reads as: boolean, string (text), color, component (instance swap), an enum type named enumName (the property name by default) with the option names, or for a number property number, length, percent or angle by its unit.

function componentPropertyExpressionValue( property: ComponentPropertyDefinition, value?: ComponentPropertyValue ): ExpressionValue

自 0.24.0源码

The expression value of a property: value when it fits the property’s kind, else the default. An enum value reads as its option’s name.

function nestedPropertyEnumName( component: ComponentDefinition, property: ComponentPropertyDefinition ): string

自 0.24.0源码

The enum type name of a nested component’s property, as an outer component’s expressions see it: "<component name>.<property name>". A property name has no dot, so it never clashes with the outer component’s own enum types, which are named after their properties.

function componentExpressionEnvironment( document: DesignDocument, component: ComponentDefinition | ComponentId, storedType?: ExpressionType ): ExpressionEnvironment

自 0.24.0源码

The checking environment of a component’s expressions: its properties by name, the document’s variables by "Collection/Name", and storedType for stored (leave it out for a condition).

function componentValueEnvironment( document: DesignDocument, component: ComponentDefinition | ComponentId, propertyValues: ComponentPropertyValues = {}, stored?: ExpressionValue, modes?: VariableModes ): ExpressionValueEnvironment

自 0.24.0源码

The evaluation environment matching componentExpressionEnvironment: each property’s value from propertyValues (an instance’s values; values that do not fit and missing ones read as the default), each variable in the mode its collection shows under modes (the active mode by default), and stored.

type ExpressionField = ComputableField | "condition"

自 0.24.0源码

A computed field, or "condition".

const LAYOUT_DIRECTION_TYPE: ExpressionEnumType

自 0.24.0源码

The enum type of the direction field.

const LAYOUT_ALIGN_TYPE: ExpressionEnumType

自 0.24.0源码

The enum type of the align field.

const LAYOUT_JUSTIFY_TYPE: ExpressionEnumType

自 0.24.0源码

The enum type of the justify field; space_between and the others are the model’s "space-between" and so on.

function computableFieldType( document: DesignDocument, node: SceneNode, field: ExpressionField ): ExpressionType | undefined

自 0.24.0源码

The type an expression in field must have: boolean for a condition, the field’s type from the table in design 8.3, or for propertyValues.<id> the type of that property of the nested instance’s component (with its enum named by nestedPropertyEnumName). Undefined for a field the node cannot compute or a property the nested component does not have.

function storedFieldValue( document: DesignDocument, node: SceneNode, field: ExpressionField ): ExpressionValue | undefined

自 0.24.0源码

The base value of a computed field, which stored reads: the plain value stored on the node, as an expression value. Absent optional values read as zero (for example a missing maxWidth is 0 px, a missing corner radius 0 px). The text fields read the first run’s resolved style; line height, a multiplier in the model, reads as a percent (1.5 is 150%), and as a length in text_style (1.5 at 16 px is 24 px). A height, a multiplier in the model, reads as a percent (1.5 is 150%), and as pixels inside a text_style (1.5 at 14 px is 21 px). A nested instance’s propertyValues.<id> reads the value stored on the node, else the nested component’s default. Undefined for a condition and for fields computableFieldType does not type.

interface ExpressionFieldContext

自 0.24.0源码

What checking one computed field or condition needs.

readonly expected: ExpressionType源码
readonly environment: ExpressionEnvironment源码

function expressionFieldContext( document: DesignDocument, component: | ComponentDefinition | ComponentId, node: SceneNode, field: ExpressionField ): ExpressionFieldContext | undefined

自 0.24.0源码

The expected type and checking environment of one field of a layer in component, or undefined when the field has no type (see computableFieldType).

function expressionFieldValueEnvironment( document: DesignDocument, component: ComponentDefinition | ComponentId, node: SceneNode, field: ExpressionField, propertyValues: ComponentPropertyValues = {}, modes?: VariableModes ): ExpressionValueEnvironment

自 0.24.0源码

The evaluation environment of one field of a layer in component for an instance with propertyValues: componentValueEnvironment with stored set to storedFieldValue.

interface ComponentExpressionSite

自 0.24.0源码

One stored expression: a computed field or a condition of a layer.

readonly nodeId: NodeId源码
readonly field: ExpressionField源码
readonly source: string源码

function componentLayerIds( document: DesignDocument, component: ComponentDefinition | ComponentId ): readonly NodeId[]

自 0.24.0源码

The IDs of a component’s layers, root first, in tree order.

function componentExpressionSites( document: DesignDocument, component: | ComponentDefinition | ComponentId ): readonly ComponentExpressionSite[]

自 0.24.0源码

Every expression and condition stored on a component’s layers, in tree order, conditions after the node’s computed fields.

function componentPropertyUsage( document: DesignDocument, componentId: ComponentId, propertyId: string, optionId?: string ): number

自 0.24.0源码

How many of component’s expressions and conditions name the property (or, with optionId, that option of an enum property), plus the propertyValues.<id> expressions of nested instances of it in other components that name the option. The editor shows it before a deletion or a kind change (“3 expressions use size”).

interface ExpressionEditResult

自 0.24.0源码

Operations for one edit, and how many expressions it touches.

readonly operations: readonly DocumentOperation[]源码

Apply them together, in one applyOperations call.

readonly count: number源码

For a rename, how many references were rewritten; for a deletion or a kind change, how many expressions use what changed and will stop checking (see componentPropertyUsage).

function renameComponentPropertyOperations( document: DesignDocument, componentId: ComponentId, propertyId: string, name: string ): ExpressionEditResult

自 0.24.0源码

Renames a property and rewrites every expression in the component that reads it, in one edit. Throws a ModelError when the name is not an identifier or another property has it.

function renameComponentPropertyOptionOperations( document: DesignDocument, componentId: ComponentId, propertyId: string, optionId: string, name: string ): ExpressionEditResult

自 0.24.0源码

Renames an option of an enum property and rewrites every expression that names it: in the component, and in propertyValues.<id> expressions of nested instances of the component inside other components. Option IDs do not change, so instance values need no edit.

function deleteComponentPropertyOperations( document: DesignDocument, componentId: ComponentId, propertyId: string ): ExpressionEditResult

自 0.24.0源码

Deletes a property. In the same edit it removes every instance’s value for it (instance nodes and nested instance overrides) and the propertyValues.<id> expressions of nested instances of the component. Expressions that read the property are kept and stop checking, so they fall back to the stored value; count says how many there are.

function deleteComponentPropertyOptionOperations( document: DesignDocument, componentId: ComponentId, propertyId: string, optionId: string ): ExpressionEditResult

自 0.24.0源码

Deletes one option of an enum property. Instance values that chose it are removed in the same edit, so those instances take the default; when the option was the default, the first remaining option becomes the default. Expressions that name the option are kept and stop checking; count says how many. Throws a ModelError for the last option.

function changeComponentPropertyOperations( document: DesignDocument, componentId: ComponentId, next: ComponentPropertyDefinition ): ExpressionEditResult

自 0.24.0源码

Replaces a property’s definition with one of another kind (or the same kind with other settings), keeping its ID and name; rename with renameComponentPropertyOperations. Instance values that do not fit the new definition are removed in the same edit. Expressions that read the property, and propertyValues.<id> expressions of nested instances of the component, are kept and may stop checking; count is how many there are (0 when the kind is unchanged and so are a number’s unit and an enum’s option names: a new option makes a match non-exhaustive and a removed one leaves references unresolved). Throws a ModelError when a number property’s minimum is above its maximum.

function renameVariableOperations( document: DesignDocument, variableId: VariableId, name: string ): ExpressionEditResult

自 0.24.0源码

Renames a variable and rewrites every var("Collection/Name") that reads it, in every component, in one edit.

function renameVariableCollectionOperations( document: DesignDocument, collectionId: VariableCollectionId, name: string ): ExpressionEditResult

自 0.24.0源码

Renames a variable collection and rewrites every var("Collection/Name") that reads one of its variables, in every component, in one edit.

const propertySampleIds: { readonly document: DocumentId; readonly page: PageId; readonly pageRoot: NodeId; readonly textStyle: TextStyleId; readonly button: ComponentId; readonly buttonRoot: NodeId; readonly buttonIcon: NodeId; readonly buttonLabel: NodeId; readonly size: ComponentPropertyId; readonly small: "opt-small"; readonly large: "opt-large"; readonly kind: ComponentPropertyId; readonly primary: "opt-primary"; readonly secondary: "opt-secondary"; readonly disabled: ComponentPropertyId; readonly label: ComponentPropertyId; readonly icon: ComponentPropertyId; readonly showIcon: ComponentPropertyId; readonly plus: ComponentId; readonly plusRoot: NodeId; readonly plusShape: NodeId; readonly iconSize: ComponentPropertyId; readonly iconSmall: "icon-small"; readonly iconLarge: "icon-large"; readonly minus: ComponentId; readonly minusRoot: NodeId; readonly buy: NodeId; readonly plain: NodeId; readonly brand: VariableCollectionId; readonly brandMode: VariableModeId; readonly accent: VariableId; readonly radius: VariableId; readonly fade: VariableId; }

自 0.24.0源码

The IDs the property sample uses, so tests can refer to them by name.

function propertyButtonSample(): DesignDocument

自 0.24.0源码

The Button of design 8.10 with its expressions, nested Icon/Plus instance and text label, two Button instances on the page, and a Brand variable collection with a colour, a length (radius, scoped to corner radius) and a plain number (fade, unscoped).

代码样式

新代码节点的默认值以及两套内置语法配色,改编自采用 MIT 许可证的 Code - OSS 主题。

const CODE_FONT_FAMILY: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"

源码

const CODE_FONT_SIZE: 32

源码

const CODE_LINE_HEIGHT: 1.3

源码

const BUILT_IN_CODE_STYLES: Readonly<Record<string, CodeStyle>>

源码

const DARK_2026_CODE_STYLE: CodeStyle

源码

const DARK_2026_CODE_STYLE_ID: CodeStyleId

源码

const LIGHT_2026_CODE_STYLE: CodeStyle

源码

const LIGHT_2026_CODE_STYLE_ID: CodeStyleId

源码

function getCodeLineNumberStart( lineNumbers: CodeNode["lineNumbers"] ): number | null

源码

行号隐藏时返回 null,否则返回首行行号。

文本测量

解析文本的实际生效样式,并用 2D 画布上下文(OffscreenCanvas 或 DOM 画布)测量文本节点,用于在渲染器之外进行的布局,例如自动调整大小的文本框。两种画布都不可用时,测量会抛出错误。

function resolveTextStyle( document: DesignDocument, styleId: string | undefined, overrides: TextStyleOverrides | undefined ): TextStyle

源码

function resolveTextFontFamily( document: DesignDocument, style: TextStyle ): string

源码

将嵌入字体的标识解析为特定于资源的 CSS 字体族栈。主嵌入字体替换作者指定的主字体族,其后依次是有序的嵌入回退字体,作者指定的 CSS 回退部分保留在最后。资源别名使同一字体族的不同字体保持区分且结果确定。

function documentFontFamilyAlias(assetId: string): string

源码

返回某个文档字体资源标识所使用的稳定 CSS 字体族名。

function textStyleToCanvasFont( style: TextStyle, document?: DesignDocument ): string

源码

function measureTextNode( document: DesignDocument, node: TextualNode, paragraphs: readonly TextParagraph[] = node.paragraphs ): TextMeasurement

源码

interface TextMeasurement

源码
readonly width: number源码
readonly height: number源码
readonly lineCount: number源码
readonly lines: readonly TextLineMetrics[]源码

interface TextLineMetrics

源码
readonly width: number源码
readonly ascent: number源码
readonly descent: number源码
readonly height: number源码

function getTextNodeBaselines( document: DesignDocument, node: TextualNode, paragraphs: readonly TextParagraph[] = node.paragraphs ): readonly number[]

源码

function getAutoSizedTextFrame( document: DesignDocument, node: TextualNode, paragraphs: readonly TextParagraph[] = node.paragraphs ): Rect

源码

译文已过期

The frame an auto-sized text box takes for its content: the size the renderer gave a text like it (recordDrawnTextSize), or, until the renderer has drawn one, an estimate measured with the browser canvas. Fixed-size text keeps its frame. The new frame keeps the point from textAutoResizeAnchor in place on the page.

function autoResizedTextFrame( node: Pick<TextualNode, "frame" | "rotation">, paragraphs: readonly TextParagraph[], size: { readonly width: number; readonly height: number } ): Rect

源码

自动调整大小的文本框在内容改变其尺寸后的画框。文本框绕其中心旋转,因此若保持 frame.x 和 frame.y 不变,旋转的文本会在增长时在页面上移动;此函数改为让 textAutoResizeAnchor 给出的锚点在页面空间中保持不动。

function textAutoResizeAnchor( paragraphs: readonly TextParagraph[] ): { readonly x: number; readonly y: number }

源码

内容改变文本框尺寸时,文本框在页面上保持不动的点,以画框局部宽度和高度的比例表示。与 Figma 相同,顶边保持不动,自动宽度的文本保持其对齐边:左对齐或两端对齐的文本保持左边,居中文本保持中心,右对齐文本保持右边。各段落对齐方式不一致时,保持左边不动。

function resolveTextListLayout( document: DesignDocument, paragraph: TextParagraph, paragraphIndex: number ): TextListLayout | null

源码

interface TextListLayout

源码
readonly text: string源码
readonly style: TextStyle源码
readonly gap: number源码
readonly nestingOffset: number源码

由作者指定的列表层级额外带来的正文和标记缩进。

readonly left: number源码
readonly right: number源码
readonly firstLine: number源码
readonly markerWidth: number源码
readonly markerBoxWidth: number源码

function resolveListMarkerStyle( document: DesignDocument, paragraph: Pick<TextParagraph, "runs" | "list"> ): TextStyle

源码

The style a list marker of the paragraph is drawn in. A marker takes the shared style and the overrides it does not name itself from the first run of its paragraph, each on its own: a marker with a style and no overrides still takes the first run’s overrides. A marker the renderer writes itself (a bullet or a number) takes both. The page compiler, the canvas estimate and textLayoutKey all resolve markers here, so they cannot disagree.

function getTextNodeFontRequests( document: DesignDocument, node: TextualNode, paragraphs: readonly TextParagraph[] = node.paragraphs ): readonly TextFontRequest[]

源码

interface TextFontRequest

源码
readonly font: string源码
readonly text: string源码

function clearTextMeasurementCache(): void

源码

其他导出

尚未归入上述章节的导出,按字母顺序排列。

function applyComputedFields( document: DesignDocument, node: SceneNode, results: readonly { readonly field: ComputableField; readonly value: ExpressionValue; }[], onError?: (field: ComputableField, message: string) => void ): SceneNode

自 0.25.0源码

node with each computed value written into its model field and clamped to the field’s range. Fields the node type cannot compute are ignored. A text layer that sizes itself is measured again when its text changed.

function carryPropertyExpressions( from: ComponentDefinition | undefined, to: ComponentDefinition, expressions: NodeExpressions | undefined ): NodeExpressions | undefined

自 0.26.0源码

Expressions carried from one component’s instance to another’s, as property values are: a propertyValues.<id> field is renamed to the new component’s property with the same name and kind, and dropped when there is none or the old component lacks the ID. Other fields stay. Undefined when nothing is left.

function carryPropertyValues( from: | ComponentDefinition | undefined, to: ComponentDefinition, values: | Readonly< Record< string, ComponentPropertyValue > > | undefined, mapComponent: ( id: ComponentId ) => ComponentId = (id) => id ): Record<string, ComponentPropertyValue> | undefined

自 0.26.0源码

Property values carried from one component to another, as a swap does (design 8.9): a value is kept when the new component has a property with the same name and kind; an enum value only when the new property has an option with the same name, and then as that option’s ID. Values that do not fit, or name a property the old component does not have, are dropped. An instance swap value goes through mapComponent, for a paste that maps component IDs. Undefined when nothing is left.

function clearDrawnTextSizes(documentId?: DocumentId): void

源码

Forgets every drawn text size of one document, or of all documents when none is given.

interface ComponentExpressionError

自 0.25.0源码

A stored expression or condition that does not parse or check. It is not evaluated: the field shows its stored value, and a condition counts as no condition (design 8.5).

readonly nodeId: NodeId源码
readonly field: ExpressionField源码
readonly source: string源码
readonly errors: readonly ExpressionError[]源码

function componentExpressionErrors( document: DesignDocument, componentId: ComponentId, options?: ResolveInstanceOptions ): readonly ComponentExpressionError[]

自 0.25.0源码

The expressions and conditions on componentId’s layers that do not parse or check, in tree order. Each is left out when the component is resolved: the field shows its stored value, and a condition counts as no condition (design 8.5). After them come the computed values the default property values make invalid, such as a font family with no font in the document, which show their stored value too. A nested component’s errors are listed under its own ID.

interface ComputedComponent

自 0.25.0源码

A component’s layer tree for one set of property values, before overrides and layout: the layers a condition leaves out, and the layers with computed fields written into their model fields.

readonly nodes: ReadonlyMap<NodeId, SceneNode>源码

Layers with at least one computed field, by stored ID; every other layer is as stored.

readonly leftOut: ReadonlySet<NodeId>源码

Layers whose condition is false. Their sublayers are left out with them and are not listed.

readonly errors: readonly ComponentExpressionError[]源码

Computed values these property values make invalid; each field shows its stored value.

function computedTextFitOperations( document: DesignDocument, componentIds: readonly ComponentId[] ): readonly DocumentOperation[]

源码

The node replacements that bring the stored sizes of componentIds up to date with the sizes their texts are drawn at, with no edit to follow: each component’s self-sizing computed texts, the auto layout frames around them, and every instance of the components (an instance with its own property values or text overrides included) with the frames around it. Empty when every stored size already fits.

The editor calls it when the renderer has measured a text at another size than the estimate the stored sizes were derived from (recordDrawnTextSize).

function confirmDrawnTextSize(document: DesignDocument, node: TextualNode): void

源码

Marks the remembered size of a text as right for the font files in use: the renderer has just drawn the text at that size. Does nothing for a text with no remembered size, or with another one.

function documentWithVariantInstance( document: DesignDocument, instance: InstanceNode ): DesignDocument

源码

document with instance added to its nodes, so the resolver can read it.

function drawnNodes(document: DesignDocument): readonly SceneNode[]

自 0.26.0源码

Every node the renderer draws, for code that scans the document for the fonts, characters or assets its text uses: the stored nodes (page layers and component layers), then the layers of every stored instance as resolveInstance derives them, with the instance’s overrides, property values and nested instances applied and the virtual ID as id. Text or a font that exists only in an override is found here and nowhere in document.nodes. An instance that cannot be resolved (a missing component or a nesting cycle) adds no layers; the compiler reports that itself. The same document object gives the same array, and unchanged instances give the same layer objects, so per-node caches keyed by object stay warm.

function drawnTextSize( document: DesignDocument, node: TextualNode, paragraphs: readonly TextParagraph[] = node.paragraphs ): DrawnTextSize | undefined

源码

The size the renderer gave a text like this one in this document, when it has drawn one.

interface DrawnTextSize

源码

The size the renderer gave a text it drew.

readonly width: number源码
readonly height: number源码

function filledPropertyValues( component: ComponentDefinition, values: ComponentPropertyValues = {} ): readonly ComponentPropertyValue[]

自 0.25.0源码

The instance’s values for component’s properties with defaults filled in, in the component’s property order: the key of a computed result.

function forgetDrawnTextSizesOfEarlierFonts(documentId: DocumentId): number

源码

Forgets the sizes of a document that were recorded with earlier font files and that no draw has found right since (setDrawnTextFontSet): text that is not drawn now, whose size with the files in use is unknown. Such a text is estimated again and corrected when it is next drawn. Call it once every text on screen is settled. Returns how many sizes were forgotten.

function getDrawnTextSizesVersion(): number

源码

Changes whenever a drawn text size is recorded, changed or forgotten, in any document. Anything that keeps sizes derived from getAutoSizedTextFrame (resolved instances, the component view) compares it to know they are out of date.

type GroupVariableBindings = Readonly< & Partial<Record<GroupVariableProperty, VariableId>> & { readonly width?: never; readonly height?: never } >

源码

A group’s variable bindings. A group’s size is always computed from its layers, so a group never binds width or height.

type GroupVariableProperty = Exclude<VariableProperty, "width" | "height">

源码

The variable properties a group can bind: all but its size.

function hasComputedTextContent(node: SceneNode | undefined): boolean

源码

Whether the node is a text layer whose content is computed: bound to a component property, varied by a property, or written as an expression (all three are stored as its characters expression).

function isLayerInDocument(document: DesignDocument, id: NodeId): boolean

自 0.23.0源码

True when id names a layer the document shows: a stored node that exists, or a virtual ID whose every path segment is a layer of the component shown by the instance above it (the outer instance, then each nested instance as swapped). A node moved out of a component, or deleted, leaves the virtual IDs through it unresolved.

function isLayoutFieldInUse(node: SceneNode, field: string): boolean

自 0.24.0源码

False for a layout field the frame’s current layout kind does not use: gap on a grid or absolute frame, columnGap on a stack, any layout field on an absolute frame. True for every other field. A frame can keep an expression on any layout field (see computableFieldsOf), so it stays valid when the layout kind changes; the resolver applies, and the editor offers, only the fields in use.

const jsonCodecStats: { jsonPathAllocations: number; canonicalJsonCalls: number; }

源码

const modelApplyStats: { documentDiffs: number; operationDeserializes: number; positionMapContainersVisited: number; }

源码

function multiplyTransforms( left: TransformMatrix, right: TransformMatrix ): TransformMatrix

源码

Composes two affine transforms. The result applies right first, then left. Matrices use the [a, b, c, d, e, f] layout, where x' = a*x + c*y + e and y' = b*x + d*y + f. In 3×3 form this is the matrix product M=LRM = L R, so Mp=L(Rp)M\mathbf{p} = L(R\mathbf{p}).

function nodeIdsRenamedWithSuffix(nodeIds: readonly string[]): string[]

源码

The stored node IDs in nodeIds whose 0.23.0 rename needs a collision suffix, because their plain “_” form is already taken. Operation migration cannot see those suffixes, so a stored history whose root document has one is ambiguous.

function nodeLocalTransform(node: SceneNode): TransformMatrix

源码

The transform from a layer’s own coordinates (the top-left of its frame at the origin) to its parent’s: its flips, then its rotation, both about the middle of its frame, then its position. A path carries its transform itself. A layer that is not rotated or flipped gives exactly its position, with no rounding.

function nodePageTransform( document: DesignDocument, id: NodeId, parents: ReadonlyMap< NodeId, NodeId > = buildParentMap(document.nodes), transforms = new Map<NodeId, TransformMatrix>() ): TransformMatrix

源码

The transform from a layer’s own coordinates to canonical page coordinates: every ancestor’s position, rotation and flips, then the layer’s own. The structural root (a page’s root frame, or the root of a component) is the coordinate origin, so its own transform is left out. Pass parents (from buildParentMap) and a transforms cache when calling this for many layers of one document.

const OVERRIDE_FIELD_PROPERTIES: Readonly< Partial<Record<OverrideField, readonly VariableProperty[]>> >

自 0.23.0源码

The variable properties each override field can bind (decision A). A property missing here (size, corner radius, gaps, padding) binds a field that is not overridable, so a binding for it is unsupported on a virtual ID.

function overrideFieldForProperty(property: string): OverrideField | undefined

自 0.23.0源码

The override field a variable property belongs to, or undefined when that property binds a field an instance cannot override.

function recordDrawnTextSize( document: DesignDocument, node: TextualNode, size: DrawnTextSize ): boolean

源码

Remembers the size the renderer gave an auto-sized text it drew, so every text of the same document with the same words, styles, font files and sizing takes that size from now on (getAutoSizedTextFrame). The renderer is the authority for text sizes: it lays text out with the fonts it draws with, which the browser canvas often cannot measure (a Google Fonts family, an automatic fallback font).

node is the text as it was drawn; its frame’s width is part of the key when only its height follows the text. Returns whether the size is new or differs from the one remembered, in which case drawnTextSizesVersion changes and sizes derived before it are out of date.

function resetJsonCodecStats(): void

源码

function resetModelApplyStats(): void

源码

function resetTextMeasurementStats(): void

源码

function resolvedShownComponents( document: DesignDocument, instanceId: NodeId ): (path: readonly NodeId[]) => ComponentId | undefined

自 0.26.0源码

A shownComponentAt for the stored instance instanceId: the component each nested instance shows once the instance resolves, so a component an instance swap property selects counts. The instance resolves on the first lookup. A path the resolved tree leaves out (a layer hidden by its condition), or an instance that does not resolve, gives undefined, and the stored component counts.

function setDrawnTextFontSet(documentId: DocumentId, name: string): boolean

源码

Tells the memory which font files the renderer draws a document with. name stands for the whole set: every file of every font asset that has arrived (a Google Fonts family arrives in parts) and the fallback fonts the renderer picks itself, none of which the document names. The same name twice changes nothing, so every surface that shows the document can say it.

With another name, the sizes recorded so far are from other files and may be wrong. They are kept for now, so text on screen does not jump to the canvas estimate and back: each is either found right by the next draw (confirmDrawnTextSize) or replaced (recordDrawnTextSize), and the ones no draw vouched for are dropped by forgetDrawnTextSizesOfEarlierFonts. Returns whether the name changed.

function splitCssFontFamilies(fontFamily: string): readonly string[]

源码

function textLayoutKey( document: DesignDocument, node: Pick< TextualNode, "autoResize" | "wrap" | "frame" | "paragraphs" >, paragraphs: readonly TextParagraph[] = node.paragraphs ): string

源码

Names everything in the document that decides the size of an auto-sized text: its words, the styles they resolve to in this document (so a theme or variable mode that changes a style changes the key), the font file each of their font assets stands for, the paragraph settings, how the box sizes itself, and its width when only its height follows the text. A list marker is named by the style the renderer draws it in (resolveListMarkerStyle), which can come from the first run of its paragraph. Two texts of one document with the same key are laid out alike by the renderer (the order in which the fields of a style or a paragraph were written is not part of the key), as long as it draws with the same font files; the files that are not in the document (which parts of a Google Fonts family have arrived, the fallback fonts the renderer picks itself) are told apart by setDrawnTextFontSet. The drawn sizes are kept by this key (recordDrawnTextSize), and anything else that remembers or counts something about one layout of a text uses it too, so a change of font, size, wrap width or sizing mode is never taken for the layout before it.

const textMeasurementStats: { layoutComputations: number; fontRequestTextRebuilds: number; resolvedStyleCopies: number; }

源码

const VARIANT_VIEW_CAP: 64

源码

The most views “Show all variants” draws; above it the user picks which properties to vary.

interface VariantCombination

源码

One “Show all variants” view: its property values and label.

readonly values: ComponentPropertyValues源码

The values that differ from the defaults; the defaults view has none.

readonly label: string源码

The values that differ from the defaults (“size: large, disabled”), or “Component” for the defaults.

readonly key: string源码

Stable text for the combination (“” for the defaults), for editor-only IDs.

function variantCombinationOf( component: ComponentDefinition, values: ComponentPropertyValues ): VariantCombination

自 0.27.0源码

The combination that values name: the enum and boolean values that differ from the defaults (a value no option has counts as the default), with the label and key variantCombinations gives the same view. Values of other kinds of property are left out; a view keeps their defaults.

function variantCombinations( component: ComponentDefinition, vary?: readonly ComponentPropertyId[] ): readonly VariantCombination[]

源码

The combinations of the varied properties’ values (every variant property when vary is omitted), the first property changing slowest and each property’s default first, so the first combination is the defaults. Empty when there would be more than VARIANT_VIEW_CAP views.

function variantInstanceNode( document: DesignDocument, componentId: ComponentId, id: NodeId, name: string, values: ComponentPropertyValues ): InstanceNode | undefined

源码

An editor-only instance of componentId with values, at the page origin with the component root’s size for those values (a computed fixed width or height included): what a variant view draws.

function variantLabel( component: ComponentDefinition, values: ComponentPropertyValues ): string

源码

The label of a view with these values: each value that differs from the default, in the component’s order. An enum reads “size: large”, a boolean that is on reads “disabled” and one that is off reads “showIcon: off”. “Component” when every value is the default.

function variantProperties( component: ComponentDefinition ): readonly VariantProperty[]

源码

The component’s enum and boolean properties, in the component’s order.

type VariantProperty = Extract< ComponentPropertyDefinition, { readonly kind: "enum" | "boolean" } >

源码

A property “Show all variants” can vary: an enum or a boolean.

function variantPropertyValues( property: VariantProperty ): readonly ComponentPropertyValue[]

源码

The values a variant property takes across the views, the default first: a boolean’s default then its opposite, an enum’s default option then the other options in their order.

function variantViewCount( component: ComponentDefinition, vary?: readonly ComponentPropertyId[] ): number

源码

How many views varying these properties (every variant property when omitted) gives.

function variantViewSize( document: DesignDocument, componentId: ComponentId, values: ComponentPropertyValues, options?: ResolveInstanceOptions ): { readonly width: number; readonly height: number } | undefined

源码

The natural size of the component with values: the resolved root of an instance with those values (hugging axes take their content’s size).

function withoutClashingBindings<T extends SceneNode>(node: T): T

自 0.26.0源码

The node without the variable bindings that clash with its expressions: a field holds a binding or an expression, never both, and the expression wins. The same node when nothing clashes.

@taco-slides/editor TypeScript

474 个导出中已记录 308 个 · 大纲

@taco-slides/editor 是交互式编辑中不依赖浏览器和渲染器的部分。它依赖文档模型(@taco-slides/model),但不依赖 React、DOM、Playwright、Skia 或原生渲染器。其中大部分是纯函数:接收文档、当前编辑器状态和一个输入事件,返回下一个状态以及对改动内容的描述。文档操作和历史记录由调用方负责。

原始指针输入和屏幕几何使用相对于交互表面的 CSS 像素。ViewportState.documentToScreen 把文档单位映射到这个空间。设备像素只来自 devicePixelRatio,从不作为指针输入接受。

本包还定义了编辑器与渲染器之间的边界:由共享测试场景驱动的 EditorDriver,以及负责回答命中测试和几何查询的 InteractiveRenderSession。渲染会话加载完成后,这些查询都是同步的,因此指针按下、移动和抬起看到的都是同一代保留场景。

文档、命令和历史记录的唯一可信来源始终是 TypeScript。渲染器接收一份已校验的文档、一个选定的页面以及随后的精确状态转换。它从不维护第二份历史记录,也从不自行修改文档。

输入事件

编辑器接受的每个输入都是一个 EditorInput:已经从平台规范化的指针、键盘、IME 组合输入、文本和剪贴板事件。assertEditorInput 在边界处检查单个输入。

type EditorInput = | EditorPointerInput | EditorKeyboardInput | EditorCompositionInput | EditorTextInput | EditorClipboardInput

源码

编辑器接受的所有输入事件。用 assertEditorInput 检查单个事件。

interface EditorPointerInput

源码

从平台事件归一化而来的指针事件。鼠标、触控笔和触摸共用。

readonly kind: "pointer"源码
readonly phase: "down" | "move" | "up" | "cancel" | "lost-capture"源码

cancel 和 lost-capture 会在没有 up 的情况下结束指针序列。updateBodyInteraction 将两者都视为取消,不提交任何内容。

readonly pointerId: number源码

在一个指针的各个事件之间标识该指针。为非负整数。

readonly pointerType: EditorPointerType源码
readonly position: Point源码

相对于交互表面的位置,以 CSS 像素计。

readonly button: number源码

在此事件中状态发生变化的按键,编号方式与 DOM button 字段相同(0 为主按键)。

readonly buttons: number源码

此事件之后仍被按住的按键的位掩码,与 DOM buttons 字段相同。

readonly pressure: number源码

压力,范围为 0 到 1。

readonly modifiers: EditorModifiers源码

type EditorPointerType = "mouse" | "pen" | "touch"

源码

产生指针事件的设备,与 DOM pointerType 相同。

interface EditorModifiers

源码

指针或键盘事件期间按住的修饰键。在 macOS 上,meta 是 Command 键。

readonly alt: boolean源码
readonly control: boolean源码
readonly meta: boolean源码
readonly shift: boolean源码

interface EditorKeyboardInput

源码

一次按键按下或释放。

readonly kind: "keyboard"源码
readonly phase: "down" | "up"源码
readonly key: string源码

产生的键值,与 DOM KeyboardEvent.key 相同(例如 "a" 或 "ArrowLeft")。

readonly code: string源码

物理按键,与 DOM KeyboardEvent.code 相同(例如 "KeyA")。

readonly repeat: boolean源码

按键被按住且平台重复触发时为 true。

readonly composing: boolean源码

IME 组合输入进行中时为 true。

readonly modifiers: EditorModifiers源码

interface EditorCompositionInput

源码

一个 IME 组合输入事件。text 是到目前为止的完整组合文本,而不是相对于上一次更新的差异。

readonly kind: "composition"源码
readonly phase: "start" | "update" | "end" | "cancel"源码
readonly text: string源码
readonly selectionStart: number源码

浏览器组合输入 API 使用的 UTF-16 偏移量。

readonly selectionEnd: number源码

interface EditorTextInput

源码

输入或删除的文本,仿照 DOM beforeinput 事件建模。

readonly kind: "text"源码
readonly inputType: string源码

DOM 输入类型,例如 "insertText" 或 "deleteContentBackward"。

readonly data: string | null源码

插入的文本;对于不携带文本的输入类型(例如删除)为 null。

interface EditorClipboardInput

源码

一次复制、剪切或粘贴。粘贴时,items 保存剪贴板内容。

readonly kind: "clipboard"源码
readonly action: "copy" | "cut" | "paste"源码
readonly items: readonly EditorClipboardItem[]源码

interface EditorClipboardItem

源码

一种剪贴板格式及其字节。一个项列表中每种 MIME 类型最多出现一次。

readonly mimeType: string源码
readonly data: Uint8Array源码

function assertEditorInput(input: unknown): asserts input is EditorInput

源码

在 TypeScript 与渲染器的边界上校验输入。检查每种 EditorInput 的结构:已知的阶段和动作、有限的指针位置、0 到 1 之间的压力值、非负整数指针 id、有序的组合输入选区,以及 MIME 类型唯一且带有字节数据的剪贴板项。富文本剪贴板项会被解码以进行检查。遇到第一个问题时抛出 TypeError 或 RangeError。

富文本以 UTF-8 JSON 形式通过剪贴板传递,使用专属的 MIME 类型,并附带一个 text/plain 回退。

const EDITOR_RICH_TEXT_MIME_TYPE: "application/x-taco-slides-rich-text+json"

源码

EditorRichTextClipboardPayload 的剪贴板 MIME 类型,以 UTF-8 JSON 存储。

interface EditorRichTextClipboardPayload

源码

规范的富文本剪贴板载荷;text/plain 仍是必需的回退格式。

readonly version: 1源码
readonly paragraphs: readonly TextParagraph[]源码

function encodeEditorRichTextClipboardPayload( payload: EditorRichTextClipboardPayload ): Uint8Array

源码

将富文本剪贴板载荷编码为 UTF-8 JSON 字节。编码前会先校验,并以与 decodeEditorRichTextClipboardPayload 相同的方式抛出 TypeError。

function decodeEditorRichTextClipboardPayload( bytes: Uint8Array ): EditorRichTextClipboardPayload

源码

解码 EDITOR_RICH_TEXT_MIME_TYPE 剪贴板项的字节。在以下情况抛出 TypeError:字节不是 UTF-8 JSON、对象含有 version 和 paragraphs 之外的属性、version 不为 1,或段落不是有效的文本节点段落。

interface Point

源码

二维点。其坐标空间取决于使用的位置。

readonly x: number源码
readonly y: number源码

interface Size

源码

宽度和高度。其单位取决于使用的位置。

readonly width: number源码
readonly height: number源码

视口与缩放

ViewportState 把文档放置在交互表面上。这些函数在文档单位、CSS 像素和设备像素之间进行转换。缩放辅助函数把请求的缩放模式转换为画布绘制所用的比例。

interface ViewportState

源码

文档在交互表面上的放置方式。用 createViewportState 创建;用 documentToScreenPoint 及其他视口函数转换点。

readonly screenSize: Size源码

交互表面的尺寸,单位为 CSS 像素。

readonly documentToScreen: TransformMatrix源码

从文档单位到相对于表面的 CSS 像素的仿射变换。 它必须是有限且可逆的。

readonly devicePixelRatio: number源码

每个 CSS 像素对应的设备像素数。必须为正数。

interface ViewportInput

源码

createViewportState 的平移和缩放设置。

readonly screenSize: { readonly width: number; readonly height: number }源码

交互表面的尺寸,单位为 CSS 像素。

readonly origin: Point源码

文档原点在表面上的位置,单位为 CSS 像素。

readonly zoom: number源码

每个文档单位对应的 CSS 像素数。必须为正数。

readonly devicePixelRatio: number源码

每个 CSS 像素对应的设备像素数。必须为正数。

function createViewportState(input: ViewportInput): ViewportState

源码

构建一个没有旋转的 ViewportState:文档点 p 映射到以 CSS 像素计的 origin + p * zoom,因此 documentToScreen 为 [z,0,0,z,ox,oy][z, 0, 0, z, o_x, o_y],屏幕点通过 p=(q−o)/z\mathbf{p} = (\mathbf{q} - \mathbf{o}) / z 映射回来。值非有限时抛出 TypeError;尺寸为负,或缩放比例或设备像素比不为正数时抛出 RangeError。

function assertViewportState(viewport: ViewportState): void

源码

检查 ViewportState 是否可用:屏幕尺寸有限且非负,documentToScreen 变换有限且可逆,设备像素比为正数。抛出 TypeError 或 RangeError。

const documentToScreenPoint: (viewport: ViewportState, point: Point) => Point

源码

将点从文档单位转换为表面上的 CSS 像素。

const screenToDocumentPoint: (viewport: ViewportState, point: Point) => Point

源码

将点从绘制表面上的 CSS 像素转换为文档单位。当视口变换不可逆时抛出 RangeError。

const documentToScreenRect: (viewport: ViewportState, rect: Rect) => Rect

源码

将文档矩形转换为其变换后各角点的包围盒,以 CSS 像素计(见 transformRect)。

const screenToDocumentRect: (viewport: ViewportState, rect: Rect) => Rect

源码

将以 CSS 像素表示的矩形转换为其各角点变换后的包围盒,单位为文档单位(参见 transformRect)。

const screenToDevicePoint: (viewport: ViewportState, point: Point) => Point

源码

乘以设备像素比,将 CSS 像素转换为设备像素。

const deviceToScreenPoint: (viewport: ViewportState, point: Point) => Point

源码

通过除以设备像素比,将设备像素转换为 CSS 像素。

const documentToDevicePoint: (viewport: ViewportState, point: Point) => Point

源码

将点从文档单位转换为设备像素。

const deviceToDocumentPoint: (viewport: ViewportState, point: Point) => Point

源码

将点从设备像素转换为文档单位。

function transformPoint(transform: TransformMatrix, point: Point): Point

源码

对点应用仿射变换。

function transformRect(transform: TransformMatrix, rect: Rect): Rect

源码

变换矩形的四个角点,并返回它们的轴对齐包围盒。存在旋转时,结果会比原矩形大。

function multiplyTransforms( left: TransformMatrix, right: TransformMatrix ): TransformMatrix

源码

译文已过期

Composes two affine transforms. The result applies right first, then left. Matrices use the [a, b, c, d, e, f] layout, where x' = a*x + c*y + e and y' = b*x + d*y + f. In 3×3 form this is the matrix product M=LRM = L R, so Mp=L(Rp)M\mathbf{p} = L(R\mathbf{p}).

The arithmetic is the model’s (multiplyTransforms there), which the layer transforms shared by the page compiler and the editor are built on.

function invertTransform(transform: TransformMatrix): TransformMatrix

源码

求仿射变换(affine transformation)的逆。当行列式不是有限值或过于接近零时,抛出 RangeError。设 Δ=ad−bc\Delta = ad - bc,则:

[acebdf001]−1=1Δ[d−ccf−de−babe−af00Δ]\begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{bmatrix}^{-1} = \frac{1}{\Delta} \begin{bmatrix} d & -c & cf - de \\ -b & a & be - af \\ 0 & 0 & \Delta \end{bmatrix}

type ZoomMode = | { readonly kind: "fit" } | { readonly kind: "ratio"; readonly ratio: number }

源码

用户请求的缩放:让内容适配舞台区域,或使用固定比例。

interface ZoomMetrics

源码

解析后的缩放。用 resolveZoomMetrics 创建。

readonly actualRatio: number源码

画布绘制时使用的比例:每个文档单位对应的 CSS 像素数。

readonly minimumRatio: number源码

允许的最小比例。目前始终为 MIN_ZOOM_RATIO。

readonly fitRatio: number源码

让内容适配舞台区域的比例。

function resolveZoomMetrics(mode: ZoomMode, fitRatio: number): ZoomMetrics

源码

画布针对某种缩放模式实际绘制时使用的缩放值。画布视口和缩放指示器都读取这同一个值,因此指示器不会显示画布未使用的比例。fitRatio 是让页面内容适配舞台区域的比例。

const initialZoomMetrics: ZoomMetrics

源码

初始缩放指标:100%,适配比例为 1。

function clampZoomRatio(ratio: number, minimumRatio = MIN_ZOOM_RATIO): number

源码

将比例限制在 minimumRatio 和 MAX_ZOOM_RATIO 之间。非有限的比例会变为 1;如果 minimumRatio 更大,则变为该值。

function stepZoomRatio(ratio: number, direction: 1 | -1): number

源码

下一个缩放档位:放大(direction 为 1)时乘以 1.25,缩小时乘以 0.8,然后限制在范围内并舍入到两位小数:

z′=round⁡(100⋅clamp⁡(z⋅k, 0.02, 64))100,k={1.25zoom in0.8zoom outz' = \frac{\operatorname{round}\bigl(100 \cdot \operatorname{clamp}(z \cdot k,\ 0.02,\ 64)\bigr)}{100}, \qquad k = \begin{cases} 1.25 & \text{zoom in} \\ 0.8 & \text{zoom out} \end{cases}

function formatZoomPercent(ratio: number): string

源码

将比例格式化为整数百分比,例如 "125%"。

function sameZoomMetrics(left: ZoomMetrics, right: ZoomMetrics): boolean

源码

当两个 ZoomMetrics 的全部三个字段都相等时为 true。

const MIN_ZOOM_RATIO: 0.02

源码

画布是无界的,因此缩放使用固定的上下限,而不是相对于页面的限制。

const MAX_ZOOM_RATIO: 64

源码

最大缩放比例,6400%。

编辑器驱动与快照

EditorDriver 把一个后端(SVG、Wasm 或原生)封装在统一的接口之后。测试向它发送输入,并读回一个 EditorSnapshot,其中包含文档、选区、当前手势、预览、历史记录和渲染出的帧。驱动通过其能力声明自己做不到的事,并以 UnsupportedEditorCapabilityError 拒绝相应的输入。

interface EditorDriver

源码
getCapabilities(): Promise<EditorDriverCapabilities>源码
reset( config: { readonly document: DesignDocument; readonly viewport: ViewportState; } ): Promise<void>源码
setDocument(document: DesignDocument): Promise<void>源码
setViewport(viewport: ViewportState): Promise<void>源码
setTool(tool: EditorTool): Promise<void>源码
sendInput(input: EditorInput): Promise<void>源码
flush(): Promise<EditorSnapshot>源码
getSnapshot(): Promise<EditorSnapshot>源码
hitTest(screenPoint: Point): Promise<readonly EditorHit[]>源码
getNodeGeometry(nodeId: NodeId): Promise<NodeGeometry | null>源码
getTextGeometry(nodeId: NodeId): Promise<TextGeometry | null>源码
hitTestText(query: TextHitQuery): Promise<TextHitResult | null>源码
navigateText(query: TextNavigationQuery): Promise<TextNavigationResult | null>源码
getVectorGeometry(nodeId: NodeId): Promise<VectorGeometry | null>源码
hitTestVector(query: VectorHitQuery): Promise<VectorHitTestResult | null>源码
getAccessibilitySnapshot(): Promise<AccessibilitySnapshotV1 | null>源码
performAccessibilityAction( request: AccessibilityActionRequestV1 ): Promise<boolean>源码
captureFrame(): Promise<RenderedEditorFrame>源码
dispose(): Promise<void>源码

interface EditorDriverCapabilities

源码
readonly pointerTypes: readonly EditorPointerType[]源码
readonly keyboardRepeat: boolean源码
readonly composition: boolean源码
readonly clipboard: readonly EditorClipboardInput["action"][]源码
readonly textEditing: boolean源码

在文本编辑进行时公开选区和组合输入状态。

readonly textGeometry: boolean源码
readonly textHitTesting: boolean源码
readonly textNavigation: boolean源码
readonly vectorGeometry: boolean源码
readonly vectorHitTesting: boolean源码
readonly vectorBooleanOperations: boolean源码
readonly accessibility: boolean源码
readonly frameCapture: boolean源码
readonly variableDevicePixelRatio: boolean源码

重置时能否以不同的设备像素比重新创建表面。

type EditorDriverCapability = | `pointer:${EditorPointerType}` | "keyboard-repeat" | "composition" | `clipboard:${EditorClipboardInput["action"]}` | "text-editing" | "text-geometry" | "text-hit-testing" | "text-navigation" | "vector-geometry" | "vector-hit-testing" | "vector-boolean-operations" | "accessibility" | "frame-capture" | "variable-device-pixel-ratio"

源码

class UnsupportedEditorCapabilityError extends Error

源码

一种稳定的失败,用于驱动明确不提供的输入或观测。

readonly code: "unsupported-editor-capability"源码
new (readonly capability: EditorDriverCapability, message: string)源码

interface EditorSnapshot

源码
readonly document: DesignDocument源码
readonly activePageId: PageId | null源码
readonly selection: EditorSelectionState源码
readonly hoveredNodeId: NodeId | null源码
readonly textEditing: ActiveTextEditingState | null源码

规范的文本选区,以及尚未提交的 IME 替换内容(如果有)。

readonly editingTextNodeId: NodeId | null源码

用于兼容的标识;处于编辑状态时,它必须与 textEditing.nodeId 一致。

readonly vectorEditing: VectorEditingSnapshot | null源码

已有路径的组成部分编辑,及其尚未提交的原生叠加层预览。

readonly editingCodeNodeId: NodeId | null源码
readonly activeTool: EditorTool源码
readonly viewport: ViewportState源码
readonly gesture: EditorGestureState | null源码
readonly previews: readonly EditorPreviewGeometry[]源码
readonly lastHit: EditorHit | null源码
readonly history: EditorHistoryState源码
readonly accessibility: AccessibilitySnapshotV1 | null源码

当前编辑器表面公开的、带版本号的确切语义状态。

readonly revisions: EditorRevisions源码

interface EditorSelectionState

源码
readonly pageIds: readonly PageId[]源码
readonly nodeIds: readonly NodeId[]源码
readonly primaryNodeId: NodeId | null源码

interface EditorHistoryState

源码
readonly canUndo: boolean源码
readonly canRedo: boolean源码
readonly headCommitId: string | null源码
readonly commits: readonly CommitRecord[]源码

interface EditorRevisions

源码
readonly document: number源码
readonly surface: number源码
readonly frame: number源码
readonly accessibility: number源码

type EditorTool = | "move" | "hand" | "scale" | "frame" | "rectangle" | "line" | "arrow" | "connector" | "ellipse" | "polygon" | "star" | "image" | "pen" | "pencil" | "text" | "code" | "text-path" | "comment"

源码

type EditorGestureKind = | "draw" | "marquee" | "move" | "resize" | "connector-endpoint" | "rotate" | "scale" | "pan" | "text" | "vector"

源码

type EditorGestureState = | ( & EditorGestureBase & { readonly kind: "draw" | "marquee" | "text" | "vector" }) | ( & EditorGestureBase & { readonly kind: "move"; readonly duplicate: boolean; readonly previewDelta: Point; }) | ( & EditorGestureBase & { readonly kind: "resize"; readonly handle: EditorResizeHandle }) | ( & EditorGestureBase & { readonly kind: "connector-endpoint"; readonly endpoint: "start" | "end"; }) | ( & EditorGestureBase & { readonly kind: "rotate"; readonly center: Point; readonly previewAngle: number; }) | ( & EditorGestureBase & { readonly kind: "scale"; readonly handle: EditorScaleHandle; readonly anchor: Point; readonly previewFactor: number; }) | (EditorGestureBase & { readonly kind: "pan" })

源码

type EditorResizeHandle = | "north-west" | "north" | "north-east" | "east" | "south-east" | "south" | "south-west" | "west"

源码

type EditorScaleHandle = | "north-west" | "north-east" | "south-east" | "south-west"

源码

type EditorPreviewGeometry = | { readonly kind: "rect"; readonly nodeId?: NodeId; readonly rect: Rect } | { readonly kind: "line"; readonly nodeId?: NodeId; readonly start: Point; readonly end: Point; } | { readonly kind: "path"; readonly nodeId?: NodeId; readonly points: readonly Point[]; readonly closed: boolean; } | { readonly kind: "alignment-guide"; readonly orientation: "horizontal" | "vertical"; readonly start: Point; readonly end: Point; readonly movingAnchor: "start" | "center" | "end" | "baseline"; }

源码

type EditorHit = | { readonly nodeId: NodeId; readonly part: "body"; readonly frameTitle?: true; } | { readonly nodeId: NodeId; readonly part: "resize-handle"; readonly handle: EditorResizeHandle; } | { readonly nodeId: NodeId; readonly part: "rotate-handle"; readonly corner: EditorScaleHandle; } | { readonly nodeId: NodeId; readonly part: "scale-handle"; readonly handle: EditorScaleHandle; } | { readonly nodeId: NodeId; readonly part: "connector-endpoint"; readonly endpoint: "start" | "end"; } | { readonly nodeId: NodeId; readonly part: "vector-anchor"; readonly vertexId: VectorVertexId; } | { readonly nodeId: NodeId; readonly part: "vector-handle"; readonly handleId: VectorHandleId; } | { readonly nodeId: NodeId; readonly part: "vector-segment"; readonly segmentId: VectorSegmentId; } | { readonly nodeId: NodeId; readonly part: "vector-region"; readonly regionId: VectorRegionId; }

源码

interface RenderedEditorFrame

源码
readonly mimeType: "image/png"源码
readonly width: number源码
readonly height: number源码
readonly density: number源码
readonly data: Uint8Array源码

渲染会话边界

InteractiveRenderSession 是渲染器为编辑器实现的接口。它加载文档,应用每次文档状态转换,回答命中测试和几何查询,并绘制叠加了编辑器叠加层的帧。

interface InteractiveRenderSession

源码
loadDocument(load: RenderDocumentLoad): Promise<void>源码

替换规范文档,并为文档 store 的修订号建立精确的连续性起点。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

applyDocumentUpdate(update: DocumentSceneUpdate): Promise<void>源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

setActivePage(pageId: PageId | null): Promise<void>源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

setViewport(viewport: ViewportState): Promise<void>源码
hitTest(screenPoint: Point): readonly EditorHit[]源码

原生,经由 InteractiveRetainedBackend.hitTest: taco_render_session_hit_test

getNodeGeometry(nodeId: NodeId): NodeGeometry | null源码

原生,经由 InteractiveRetainedBackend.getNodeGeometry: taco_render_session_get_node_geometry

getSceneGeometrySnapshot(): SceneGeometrySnapshot源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.getGeometrySnapshot: taco_render_session_get_geometry_snapshot

getTextGeometry(nodeId: NodeId): TextGeometry | null源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

hitTestText(query: TextHitQuery): TextHitResult | null源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

navigateText(query: TextNavigationQuery): TextNavigationResult | null源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getVectorGeometry(nodeId: NodeId): VectorGeometry | null源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

hitTestVector(query: VectorHitQuery): VectorHitTestResult | null源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

booleanVectorPaths(request: VectorBooleanPathRequest): VectorBooleanPathResult源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

setOverlays(overlays: EditorOverlayState): Promise<void>源码

原生,经由 InteractiveRetainedBackend.setOverlays: taco_render_session_set_text_editing_overlay, taco_render_session_clear_text_editing_overlay, taco_render_session_set_vector_editing_overlay, taco_render_session_clear_vector_editing_overlay, taco_render_session_set_selection_chrome, taco_render_session_set_canvas_overlay

renderFrame(): Promise<RenderFrameReport>源码

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getAccessibilitySnapshot(): Promise<AccessibilityNodeSnapshot | null>源码
dispose(): Promise<void>源码

interface RenderDocumentLoad

源码

一次原子性的规范文档加载,及其精确解析后的资源输入。

readonly document: DesignDocument源码
readonly rendererDocument?: DesignDocument源码

仅供渲染器使用的投影,与规范文档原子性地配对。

readonly rendererNodeOwners?: RendererNodeOwners源码

精确的渲染器节点归属关系,与渲染器投影原子性地配对。

readonly rendererQueryTargets?: RendererQueryTargets源码

规范的公开查询 ID,与仅供渲染器使用的查询目标原子性地配对。

readonly commitId: CommitId源码
readonly resourceSnapshot: RenderResourceSnapshot源码

interface DocumentSceneUpdate

源码
readonly reason: TransitionReason源码
readonly previousCommitId: CommitId源码
readonly currentCommitId: CommitId源码
readonly previousDocument: DesignDocument源码
readonly document: DesignDocument源码
readonly previousRendererDocument?: DesignDocument源码

与 previousDocument 一起提交的、仅供渲染器使用的确切投影。

协调器仍然持有 previousDocument,将其作为编辑器的规范权威来源。投影可以用确定性的保留节点替换不受支持的规范节点,但必须保留文档的其他所有部分。省略时,规范文档同时也是渲染器的输入。

readonly previousRendererNodeOwners?: RendererNodeOwners源码

与 previousRendererDocument 一起提交的、确切的渲染器节点归属映射。

每个渲染器节点必须恰好出现一次,并直接解析到一个自身拥有的规范节点。协调器仅用它把渲染器查询的标识转换回编辑器的规范权威来源。

readonly previousRendererQueryTargets?: RendererQueryTargets源码

与上一个投影一起提交的、确切的规范到渲染器的查询目标。

readonly rendererDocument?: DesignDocument源码

与 document 原子地配对的、仅供渲染器使用的投影。

readonly rendererNodeOwners?: RendererNodeOwners源码

与 rendererDocument 原子地配对的、确切的渲染器节点归属映射。

readonly rendererQueryTargets?: RendererQueryTargets源码

规范的公开查询 ID,映射到它们对应的仅供渲染器使用的文本/矢量节点。

readonly operations: readonly DocumentOperation[]源码
readonly changes: ChangeSet源码
readonly rendererChanges?: ChangeSet源码

上一个与当前渲染器投影之间的确切变更集。只要任一方使用了渲染器文档或归属映射,此项就是必需的。

readonly resourceSnapshot: RenderResourceSnapshot源码

document 所需的完整渲染器资源,从同一个不可变修订版本解析而来。

interface RenderResource

源码
readonly assetId: string源码
readonly mimeType: string源码
readonly bytes: Uint8Array源码
readonly slice?: RenderFontSlice源码

当此资源是某个来源为 “google-fonts” 的字体资源中的一个文件时设置。这类资源按 Unicode 覆盖范围拆分成许多文件,因此每个已加载的文件都会出现一次,各自带有不同的 slice.id;在尚未加载任何文件时,它可能一次也不出现。

interface RenderFontSlice

源码

按 Unicode 覆盖范围拆分出的字体资源中的一个文件。

readonly id: string源码

在资源内唯一,由字母、数字、“.”、“_” 和 “-” 组成。

readonly unicodeRanges: readonly (readonly [number, number])[]源码

该文件覆盖的码点范围,已排序、互不重叠且包含两端。

interface RenderResourceSnapshot

源码

某一规范文档修订版本的完整、不可变的渲染器资源输入。

readonly resources: readonly RenderResource[]源码

type RendererNodeOwners = Readonly<Record<string, NodeId>>

源码

不可变且完备的“渲染器节点到规范节点”的归属关系。

interface RendererQueryTargets

源码

为规范查询标识提供的可选、仅供渲染器使用的目标。

文本目标是规范代码节点完整的保留文本实体化结果。矢量目标保留规范的路径拓扑。每个目标都必须能从页面到达,并且与其归属节点共享完全相同的节点局部坐标空间,这样结果就能沿用规范的公开命名空间,而无需进行有损的坐标转换。

readonly text: Readonly<Record<string, NodeId>>源码
readonly vector: Readonly<Record<string, NodeId>>源码

interface RenderFrameReport

源码
readonly changedRegions: readonly Rect[]源码

重新绘制的区域,单位为 CSS 像素,相对于渲染目标。

readonly sceneUpdateMs: number源码
readonly layoutMs: number源码
readonly paintMs: number源码
readonly submitMs: number源码
readonly paint?: RenderFramePaintStatistics源码

在后端报告绘制统计信息时存在。

interface RenderFramePaintStatistics

源码

一帧绘制的内容,用于性能监测。

readonly fullPaint: boolean源码

整个目标被重新绘制,而不是只绘制脏区域。

readonly nodesPainted: number源码
readonly nodesConsidered: number源码

本帧检查过的节点数,包括在绘制前被剔除的节点。

readonly targetWidth: number源码

渲染目标的尺寸,单位为设备像素。

readonly targetHeight: number源码
readonly retainedPayloadBytes: number源码

渲染器持有的保留场景数据的字节数。

readonly decodedFontEntries: number源码
readonly textLayoutEntries: number源码

叠加层是编辑器绘制在文档之上的内容:选区、悬停、手势预览、文本光标和文本选区、矢量编辑控制柄,以及吸附参考线和测量等画布线条。

interface EditorOverlayState

源码
readonly selectedNodeIds: readonly NodeId[]源码
readonly hoveredNodeId: NodeId | null源码
readonly gesture: EditorGestureState | null源码
readonly previews: readonly EditorPreviewGeometry[]源码
readonly decorations: readonly EditorNodeDecoration[]源码
readonly nodePreviews: readonly EditorNodePreview[]源码
readonly textEditing: | (ActiveTextEditingState & { readonly caretVisible: boolean }) | null源码

由共享渲染器绘制的选区、光标和 IME 状态。

readonly vectorEditing: VectorEditingSnapshot | null源码

已有路径的组成部分选区,以及完整的节点局部预览网络。

readonly hitRegions: readonly EditorOverlayHitRegion[]源码

按最上层优先排列的命中区域。叠加层命中始终优先于保留场景主体的命中。

readonly selectionChrome?: EditorSelectionChrome | null源码

选区轮廓和控制柄,供自行绘制它们的后端使用,与场景在同一帧中绘制。当宿主自己绘制选区框与控制柄时省略。

readonly canvasOverlay?: EditorCanvasOverlay | null源码

吸附线、标尺参考线、按住 Option 拖动时的测量值以及像素网格,由后端与场景在同一帧中绘制。省略时保留后端当前的叠加层;null 清除它。

interface EditorCanvasOverlay

源码
readonly anchorNodeId: NodeId | null源码

叠加层所使用的局部坐标所属的节点;使用场景坐标时为 null。

readonly devicePixelRatio: number源码
readonly grid: | { readonly originX: number; readonly originY: number; readonly step: number; readonly rgba: number; } | null源码

从原点起每隔 step 个单位一条线,铺满整个画布。

readonly lines: readonly EditorOverlayLine[]源码
readonly marks: readonly EditorOverlayMark[]源码
readonly titles?: readonly EditorOverlayTitle[]源码

绘制在顶层画框上方的名称;缺省表示没有。

readonly rulers?: EditorOverlayRulers源码

沿顶边和左边的标尺;缺省表示没有。

readonly boxes?: readonly EditorOverlayBox[]源码

填充、斜线填充或描出轮廓的框(自动布局的间距和内边距);缺省表示没有。

readonly handles?: readonly EditorOverlayHandle[]源码

带边框的刻度线(自动布局的间距控制柄);缺省表示没有。

readonly badges?: readonly EditorOverlayBadge[]源码

显示数值的胶囊标签(拖动间距时的数值,最多 16 个);缺省表示没有。

interface EditorOverlayLine

源码
readonly orientation: "vertical" | "horizontal"源码
readonly side: EditorOverlayLineSide源码
readonly position: number源码

垂直线的 x,或水平线的 y。

readonly start: number | null源码

线沿其长度方向的范围;null 表示贯穿整个画布。

readonly end: number | null源码
readonly rgba: number源码

0xRRGGBBAA。

readonly dash?: { readonly dashCssPx: number; readonly gapCssPx: number }源码
readonly scene?: boolean源码

使用场景坐标,而不是叠加层锚点的局部坐标。

readonly anchorNodeId?: NodeId源码

这条线改用其局部坐标的节点(替代叠加层的锚点),例如一个画框,其自身的参考线必须在移动或调整大小预览中跟随它。

readonly spansAnchorBox?: boolean源码

沿锚点节点自身的盒子延伸(从 0 到其宽度或高度);忽略 start 和 end。

type EditorOverlayLineSide = "after" | "before" | "centered"

源码

宽度为一个 CSS 像素的叠加层线在其位置周围覆盖哪些设备像素:左边或上边以及坐标线使用 “after”,右边或下边使用 “before”,中心线使用 “centered”。

interface EditorOverlayMark

源码

以两条交叉线的像素为中心、经过抗锯齿处理的 x 形标记。

readonly x: number源码
readonly y: number源码
readonly xSide: EditorOverlayLineSide源码
readonly ySide: EditorOverlayLineSide源码
readonly halfSizeCssPx: number源码
readonly rgba: number源码
readonly scene?: boolean源码

interface EditorOverlayHitRegion

源码
readonly hit: EditorHit源码
readonly bounds: Rect源码

渲染器还根据同一个叠加层绘制其余的画布界面元素,使页面与这些元素始终保持一致:框(例如自动布局的内边距和间距区域)、控制柄(例如间距控制柄)、带简短文字的胶囊标签、沿顶边和左边的标尺,以及顶层画框上方的名称。

interface EditorOverlayBox

源码

位于其锚点局部坐标中的矩形(省略时使用叠加层的锚点),经锚点的完整变换映射,因此旋转画框的框会随之旋转。每种外观都是可选的:填充、斜线填充,以及框内一个 CSS 像素宽的轮廓。

readonly anchorNodeId?: NodeId源码
readonly x: number源码
readonly y: number源码
readonly width: number源码
readonly height: number源码
readonly fillRgba?: number源码

0xRRGGBBAA。

readonly hatchRgba?: number源码
readonly outlineRgba?: number源码

interface EditorOverlayHandle

源码

两端为圆头、带边框的刻度线,以某个点为中心,沿锚点局部的 x 轴或 y 轴放置。

readonly anchorNodeId?: NodeId源码
readonly x: number源码
readonly y: number源码
readonly axis: "x" | "y"源码
readonly lengthCssPx: number源码
readonly thicknessCssPx: number源码
readonly rgba: number源码

0xRRGGBBAA。

readonly borderRgba: number源码

interface EditorOverlayBadge

源码

带一行文字的圆角胶囊标签,其左上角相对某个点偏移若干 CSS 像素。

readonly anchorNodeId?: NodeId源码
readonly x: number源码
readonly y: number源码
readonly offsetXCssPx: number源码
readonly offsetYCssPx: number源码
readonly fontSizeCssPx: number源码
readonly text: string源码
readonly backgroundRgba: number源码

0xRRGGBBAA。

readonly textRgba: number源码

interface EditorOverlayRulers

源码

标尺,使用叠加层锚点的单位(页面坐标)。渲染器按正在绘制的这一帧中的页面布置刻度和数字。

readonly sizeCssPx: number源码
readonly fontSizeCssPx: number源码
readonly minimumMajorCssPx: number源码
readonly backgroundRgba: number源码

0xRRGGBBAA 颜色。

readonly borderRgba: number源码
readonly inkRgba: number源码
readonly selectionFillRgba: number源码
readonly selectionInkRgba: number源码
readonly selectionX: readonly { readonly start: number; readonly end: number }[]源码

选区的范围:已排序且互不相接;长度为零的范围标记单个数值。

readonly selectionY: readonly { readonly start: number; readonly end: number }[]源码
readonly labels: readonly { readonly axis: "x" | "y"; readonly position: number; readonly backgroundRgba: number; readonly textRgba: number; }[]源码

以标签形式绘制在各自标尺上的参考线位置(最多 16 个)。

interface EditorOverlayTitle

源码

绘制在顶层画框上方的名称,位于画框在正在绘制的这一帧中的屏幕框的左上角,超出画框宽度的部分以省略号截断。

readonly anchorNodeId: NodeId源码
readonly text: string源码
readonly rgba: number源码

0xRRGGBBAA。

readonly fontSizeCssPx: number源码
readonly gapCssPx: number源码

标题行框与画框顶边之间的距离。

interface EditorSelectionChrome

源码
readonly items: readonly EditorSelectionChromeItem[]源码
readonly strokeRgba: number源码

译文已过期

Default colours of items that give none, 0xRRGGBBAA.

readonly handleFillRgba: number源码
readonly devicePixelRatio: number源码

interface EditorSelectionChromeItem

源码

一个轮廓或控制柄,在绘制该帧时根据其节点解析。

readonly nodeId: NodeId | null源码

为 null 时,矩形使用场景坐标,而不是节点局部坐标。

readonly kind: "outline" | "square-handle" | "round-handle"源码
readonly hover?: boolean源码
readonly dashed?: boolean源码
readonly x: number源码

An outline’s rectangle. A handle’s centre is x and y, and its width and height are its finished size on screen in CSS pixels.

readonly y: number源码
readonly width?: number源码
readonly height?: number源码
readonly angle?: number源码

A handle’s turn on screen in radians, clockwise; 0 when omitted.

readonly strokeRgba?: number源码

0xRRGGBBAA overrides of the chrome’s default colours.

readonly fillRgba?: number源码
readonly offsetX?: number源码

场景空间中的偏移量,用于保留场景中不存在的预览。

readonly offsetY?: number源码
readonly sceneTransform?: TransformMatrix源码

以场景为锚点的项从局部到场景的矩阵;省略时为单位矩阵。

readonly nodeTransform?: TransformMatrix源码

Item-to-node matrix of a node-anchored item; identity when omitted.

interface EditorNodeDecoration

源码
readonly nodeId: NodeId源码
readonly role: "hover" | "selection"源码
readonly primary: boolean源码
readonly handles: "none" | "resize" | "rotate" | "scale" | "vector"源码

type EditorNodePreview = | { readonly kind: "subtree-transform"; readonly nodeId: NodeId; readonly transform: TransformMatrix; readonly mode: "replace" | "duplicate"; } | { readonly kind: "node-override"; readonly nodeId: NodeId; readonly documentBounds: Rect; }

源码

场景与文本几何

渲染会话把它所绘制场景的几何信息发布为一个带有代号(generation)的 SceneGeometrySnapshot。文本几何、文本命中测试和光标导航都在节点局部坐标中进行。

interface SceneGeometrySnapshot

源码
readonly generation: bigint源码

保留场景的代次;它有意不作为编辑器历史 ID。

readonly sceneBounds: Rect源码
readonly painterOrder: readonly NodeId[]源码

从后到前的规范绘制顺序。

readonly nodes: readonly NodeGeometry[]源码
readonly byId: ReadonlyMap<NodeId, NodeGeometry>源码

interface NodeGeometry

源码
readonly nodeId: NodeId源码
readonly localBounds: Rect源码
readonly documentBounds: Rect源码
readonly visibleDocumentBounds: Rect | null源码

应用实际可见性和祖先裁剪之后的边界;完全隐藏时为 null。

readonly screenBounds: Rect源码
readonly visibleScreenBounds: Rect | null源码

visibleDocumentBounds 在屏幕空间中的形式。

readonly localToDocument: TransformMatrix源码
readonly localToScreen: TransformMatrix源码
readonly painterOrder: number源码
readonly effectivelyVisible: boolean源码
readonly effectiveOpacity: number源码

function indexSceneGeometryNodes( nodes: readonly NodeGeometry[] ): ReadonlyMap<NodeId, NodeGeometry>

源码

function withSceneGeometryIndex( snapshot: Omit<SceneGeometrySnapshot, "byId"> ): SceneGeometrySnapshot

源码

interface TextGeometry

源码
readonly nodeId: NodeId源码
readonly generation: bigint源码

保留场景的代次,用于在场景更新后拒绝该几何信息。

readonly coordinateSpace: "node-local"源码
readonly carets: readonly TextCaretGeometry[]源码
readonly selection: TextRangeGeometry | null源码
readonly composition: TextRangeGeometry | null源码

interface TextCaretGeometry

源码
readonly position: TextPosition源码
readonly localBounds: Rect源码

光标在被编辑节点局部坐标空间中的边界。

interface TextRangeGeometry

源码
readonly range: TextRange源码
readonly localRects: readonly Rect[]源码

每个已整形的片段对应一个矩形,全部使用节点局部坐标。

interface TextHitQuery

源码
readonly nodeId: NodeId源码
readonly localPoint: Point源码

查询位置,位于文本节点的局部坐标空间中。

interface TextHitResult

源码
readonly nodeId: NodeId源码
readonly generation: bigint源码
readonly position: TextPosition源码
readonly inside: boolean源码

当结果是已排版文本之外最近的光标位置时为 false。

function assertTextHitQuery(value: unknown): asserts value is TextHitQuery

源码

检查一个值是否为带有节点 id 和有限局部坐标点的 TextHitQuery。

interface TextNavigationQuery

源码
readonly nodeId: NodeId源码
readonly from: TextPosition源码
readonly operation: TextNavigationOperation源码
readonly preferredLocalX?: number源码

在垂直移动之间保持不变;节点局部坐标系中的 x 坐标。

type TextNavigationOperation = | "grapheme-backward" | "grapheme-forward" | "word-backward" | "word-forward" | "visual-left" | "visual-right" | "line-up" | "line-down" | "line-start" | "line-end" | "paragraph-start" | "paragraph-end" | "document-start" | "document-end"

源码

interface TextNavigationResult

源码
readonly nodeId: NodeId源码
readonly generation: bigint源码
readonly position: TextPosition源码
readonly preferredLocalX?: number源码

更新后的节点局部 x 坐标,供下一次垂直移动使用。

function assertTextNavigationQuery( value: unknown ): asserts value is TextNavigationQuery

源码

检查一个值是否为 TextNavigationQuery:操作必须已知,且如果给出了首选局部 x,它必须是有限值。

选区

这些函数决定单击、双击、框选或键盘命令会选中什么。普通单击会选中当前范围允许的最外层节点;编组和嵌套画框在被双击进入之前都作为一个整体对象。隐藏和锁定的节点及其内部节点永远不会被选中。

type SelectionMode = "replace" | "toggle" | "add"

源码

updateNodeSelection 如何将新的节点 id 与当前选区合并。

function updateNodeSelection( current: readonly NodeId[], incoming: readonly NodeId[], mode: SelectionMode ): readonly NodeId[]

源码

将选区与传入的节点 id 合并。replace 返回去重后的传入 id;add 追加尚未选中的 id;toggle 移除每个已选中的传入 id,并追加每个尚未选中的 id。 顺序保持不变,因此最后一个 id 是主选区。

interface CanvasSelection

源码

一次按下所选中的节点,以及渲染器为此实际命中的节点。

readonly hitNodeId: NodeId源码
readonly targetId: NodeId源码
readonly frameTitle?: true源码

按下的位置在画框的标题上,这里从不开始框选。

function frontmostCanvasSelection( document: DesignDocument, rootId: NodeId, hits: readonly EditorHit[], primarySelectedNodeId: NodeId | null, deepSelect = false ): CanvasSelection | null

源码

按顺序遍历 hits,返回第一个能被 canvasSelectionTarget 映射到节点的命中项,以及它选中的节点。对于 Cmd 或 Ctrl 点击,传入 deepSelect,此时会选中最内层的节点。

function frontmostCanvasSelectionTarget( document: DesignDocument, rootId: NodeId, hits: readonly EditorHit[], primarySelectedNodeId: NodeId | null, deepSelect = false ): NodeId | null

源码

与 frontmostCanvasSelection 类似,但只返回选中节点的 id。

function canvasSelectionTarget( document: DesignDocument, rootId: NodeId, hitNodeId: NodeId, primarySelectedNodeId: NodeId | null, deepSelect = false ): NodeId | null

源码

一次普通点击选中的节点:被命中节点的最外层祖先,且当前作用域尚未进入到它之内。深度选择会忽略作用域,改为选取指针下最内层的节点。

function descendantSelectionTarget( document: DesignDocument, rootId: NodeId, hitNodeId: NodeId, primarySelectedNodeId: NodeId | null ): NodeId | null

源码

双击选中的节点:恰好比当前向内深入一层。

function selectableBodyHits( document: DesignDocument, rootId: NodeId, hits: readonly EditorHit[] ): readonly Extract<EditorHit, { readonly part: "body" }>[]

源码

只保留落在可选节点上的主体命中项:节点本身以及其在 rootId 之下的每个祖先都必须可见且未锁定。保持原有顺序。

function frameMarqueeTarget( document: DesignDocument, rootId: NodeId, selection: CanvasSelection, selectedNodeIds: readonly NodeId[], deepSelect = false ): NodeId | null

源码

拖动时应在其内部绘制选择框、而不是移动它的画框。规则是:画框必须先被选中,拖动才会移动它。因此,在一个未选中、且点击可以到达其子节点的画框的空白背景上按下,会开始一次框选,选中这些子节点。不拖动的点击仍然选中该画框。

点击能直接进入的画框都算在内:直接绘制在页面上的画框、当前选区所在的画框,以及深度选择(Cmd 或 Ctrl)下的任何画框。嵌套在另一个画框中的画框对点击的响应与编组一样,是一个整体对象,因此拖动它会移动它,与 Figma 一致。在画框内部的子节点上按下,会像以前一样选中并移动该子节点。

function marqueeSelectionNodeIds( document: DesignDocument, rootId: NodeId, geometry: SceneGeometrySnapshot, marquee: Rect, nested: boolean, scopeId: NodeId = rootId, selectionScopeId: NodeId | null = null ): readonly NodeId[]

源码

译文已过期

Returns intersecting selectable nodes in retained back-to-front painter order. marquee is in document units and is tested against each node’s visible document bounds from geometry. scopeId is the container the marquee selects inside: the page root by default, or the frame a marquee started on. A plain marquee selects that container’s direct children; a nested one selects the deepest nodes in it. selectionScopeId is the one layer the canvas selects within, if any.

function selectAllSelectionTargets( document: DesignDocument, rootId: NodeId, primarySelectedNodeId: NodeId | null ): readonly NodeId[]

源码

全选(Cmd+A)时选中的图层,与 Figma 一致:与主选中图层位于同一层级的所有图层,即其父画框或编组的子图层;若没有选中任何内容,则为页面上的所有顶层图层。 与画布点击和框选一样,隐藏和锁定的图层会被跳过。不在当前页面上的选区视为没有选区。

function topLevelSelectableNodeIds( document: DesignDocument, rootId: NodeId ): readonly NodeId[]

源码

页面根节点下可选中的直接子节点,按子节点顺序排列。 隐藏和锁定的节点会被排除。

function childSelectionTarget( document: DesignDocument, rootId: NodeId, nodeId: NodeId ): NodeId | null

源码

译文已过期

The child of a container that Enter selects, or null: the first child in listed order (listedChildIds, front layer first) that can be selected, which is the first row the layers panel shows under the container. An instance, or a layer inside one, opens to its resolved layers. A node can be selected when it and every ancestor below rootId are visible and unlocked.

function parentSelectionTarget( document: DesignDocument, rootId: NodeId, nodeId: NodeId ): NodeId | null

源码

节点的父节点;当父节点是页面根节点 rootId 时为 null。

function siblingSelectionTarget( document: DesignDocument, rootId: NodeId, nodeId: NodeId, direction: 1 | -1 ): NodeId | null

源码

译文已过期

The sibling that Tab (direction 1) or Shift+Tab (-1) selects, following the layers as listed (listedChildIds, front layer first): 1 is the next row down the list (the layer behind) and -1 the row above (the layer in front), wrapping around at the ends. Null when there is no other selectable sibling.

function nodeSelectionPath( document: DesignDocument, rootId: NodeId, nodeId: NodeId ): readonly NodeId[]

源码

译文已过期

The ids from just below rootId down to nodeId, outermost first. Empty when nodeId is the root or is not inside it. A component’s layers are on no page; isolation mode draws them in a component view beside the page (components design 5.5), so a path that ends at a component root counts as a path from the page root, with the component root as an artboard on it.

节点主体交互

updateBodyInteraction 把节点主体上的指针事件转换为选区变化、框选和移动。它从渲染会话读取命中测试和场景几何,但从不修改文档:完成的移动以 BodyMoveCompletion 的形式返回,由调用方提交。

function createBodyInteractionState( options: { readonly selectedNodeIds?: readonly NodeId[]; readonly hoveredNodeId?: NodeId | null; } = {} ): BodyInteractionState

源码

创建一个没有手势的 BodyInteractionState。最后一个选中的 id 成为主选中项。

function updateBodyInteraction( environment: BodyInteractionEnvironment, state: BodyInteractionState, input: EditorPointerInput ): BodyInteractionUpdate

源码

归约主体层级的指针输入,不访问 DOM,也不修改文档。 完成的移动只是描述性的;操作和历史记录由调用方负责。

interface BodyInteractionEnvironment

源码

updateBodyInteraction 读取的文档、页面和渲染器状态。

readonly document: DesignDocument源码
readonly rootId: NodeId源码

当前页面的根节点。

readonly viewport: ViewportState源码

必须与 renderSession 当前快照描述相同的屏幕几何。

readonly renderSession: BodyRenderQueries源码
readonly snapThresholdScreenPx?: number源码

对象对齐距离,以 CSS 像素计。默认为 5。

readonly guideLines?: readonly BodyGuideLine[]源码

移动操作可以吸附到的标尺参考线,与 viewport 处于同一文档空间。“x” 参考线是位于该 x 处的垂直线;“y” 参考线是水平线。

readonly moveRefusal?: (targetId: NodeId) => string | null源码

Why a press on a node starts no move, or null to move it. Without it, a layer inside an instance (a virtual ID) keeps its position; isolation mode passes its own rule (components design 5.5).

readonly autoLayoutDropAllowed?: (frameId: NodeId) => boolean源码

Whether a move may drop into this auto-layout frame. Defaults to every frame; isolation mode allows only the open component’s frames (design 5.5).

readonly marqueeSelectable?: (nodeId: NodeId) => boolean源码

Whether a marquee may preview and select this node. Defaults to every node; isolation mode rejects the page layers outside its level (design 5.5).

readonly selectionScopeId?: NodeId源码

The one layer this canvas selects within, when it does not select the whole page: a press, the hover and a marquee answer inside it (scopedSelectionTarget). The isolation split’s page pane passes the opened instance (components design 5.5).

readonly minimumMarqueeScreenPx?: number源码

框选矩形的两个维度都必须达到这个 CSS 像素尺寸。默认为 1。

readonly autoLayoutDropMarginScreenPx?: number源码

自动布局画框周围可接受放置的额外距离,以 CSS 像素计。默认为 12。

type BodyRenderQueries = Pick< InteractiveRenderSession, "hitTest" | "getSceneGeometrySnapshot" >

源码

主体交互所需的两个渲染会话查询:命中测试和保留场景几何。

interface BodyInteractionState

源码

updateBodyInteraction 的状态。用 createBodyInteractionState 创建。

readonly selection: BodySelectionState源码
readonly hoveredNodeId: NodeId | null源码

在指针下点击会选中的节点,或 null。

readonly gesture: BodyInteractionGesture | null源码

正在进行的手势;两次手势之间为 null。

interface BodySelectionState

源码

主体交互所看到的选中节点。

readonly nodeIds: readonly NodeId[]源码

无重复的选中节点 id,按选择顺序排列。

readonly primaryNodeId: NodeId | null源码

nodeIds 中的最后一个 id;未选中任何内容时为 null。

interface BodyInteractionUpdate

源码

updateBodyInteraction 的结果。

readonly state: BodyInteractionState源码
readonly pointerCapture: "none" | "capture" | "release"源码

调用方应如何处理指针捕获:手势开始时为 capture,手势结束或取消时为 release。

readonly completedMove: BodyMoveCompletion | null源码

仅在结束一次非零位移移动的指针抬起时设置。

readonly refusedMove?: string源码

Why a press that would have started a move did not: a layer inside an instance keeps the position its component gives it (components design 4.2). The caller shows the reason, so nothing fails silently.

interface BodyMoveCompletion

源码

一次已完成的移动,在指针抬起时返回一次。它只描述这次移动;由调用方把它转换为文档操作和历史记录。

readonly kind: "move"源码
readonly nodeIds: readonly NodeId[]源码
readonly documentDelta: Point源码

规范的文档空间位移;命令和历史记录仍由调用方负责。

readonly duplicate: boolean源码
readonly autoLayoutDrop: | Pick<BodyAutoLayoutDropTarget, "frameId" | "insertionIndex"> | null源码

当移动在自动布局插入位置上释放时存在。对于普通移动,索引计算的是不含被移动节点的画框子节点;对于复制,它计算全部子节点,因为原节点仍然保留。

readonly sourceGeneration: bigint源码

移动开始时所用的场景几何快照的代次。

type BodyInteractionGesture = BodyMarqueeGesture | BodyMoveGesture

源码

当前的主体手势:框选或移动。

interface BodyMarqueeGesture extends BodyGestureBase

源码

绘制选择矩形的拖动。从空白画布开始,或从 frameMarqueeTarget 选中的画框的空白背景开始。

readonly kind: "marquee"源码
readonly geometry: SceneGeometrySnapshot源码

在这次框选的整个生命周期内,保留快照固定不变。

readonly additive: boolean源码

按下时按住了 Shift:框选结果会添加到开始时的选区中。

readonly nested: boolean源码

按下时按住了 Cmd 或 Ctrl:框选会选中最深层的节点,而不是直接子节点(见 marqueeSelectionNodeIds)。

readonly frameId: NodeId | null源码

这次框选开始时所在的未选中画框;在空白画布上开始时为 null。框选会在该画框内部进行选择;如果点击始终没有变成拖动,则选中该画框本身。

readonly dragging: boolean源码

在画框上的按下仍处于点击距离之内时为 false。

readonly rect: Rect源码

框选矩形,以文档单位计。

readonly previewNodeIds: readonly NodeId[]源码

当前位于框选矩形内的节点,尚未与开始时的选区合并。

readonly previewSelection: BodySelectionState源码

拖动时要显示的选区。指针抬起时它会成为真正的选区。

interface BodyMoveGesture extends BodyGestureBase

源码

移动选中节点的拖动。只有最外层的选中节点会移动;位于另一个选中节点内部的选中节点会随之一起移动。

readonly kind: "move"源码
readonly geometry: SceneGeometrySnapshot源码

对于与命中测试无关的移动策略(例如放置目标),保留快照固定不变。

readonly nodeIds: readonly NodeId[]源码
readonly rawCurrentAtScreen: Point源码

吸附之前的指针位置,以 CSS 像素计。currentAtScreen 保存吸附后的位置。

readonly previewDelta: Point源码

吸附之后,节点到目前为止移动的距离,以文档单位计。

readonly duplicate: boolean源码

按住了 Alt(Option):释放时放置副本,并保留原节点。

readonly moved: boolean源码

指针一旦离开按下的位置即为 true。

readonly dragged: boolean源码

True once the pointer has traveled DRAG_SCREEN_PX or more from the press point.

readonly clickNarrowsToNodeId: NodeId | null源码

The layer pressed inside a multiple selection, or null. If the press ends without a drag, the selection narrows to this layer, as in Figma.

readonly alignmentGuides: readonly Extract< EditorPreviewGeometry, { readonly kind: "alignment-guide" } >[]源码

要绘制的吸附参考线,以文档单位计。

readonly initialScreenBounds: AlignmentRect源码

按下时移动中节点的合并边界,以 CSS 像素计。吸附基于这些边界进行。

readonly alignmentTargets: readonly AlignmentTarget[]源码

移动可以吸附到的其他节点的边界以及标尺参考线,以 CSS 像素计。

readonly duplicateSourceTargets: readonly AlignmentTarget[]源码

作为吸附目标的移动中对象本身。它们仅在移动为复制时(按住 ⌥)才计入:此时原对象留在原位,因此副本可以吸附到它们上,与 Figma 一致。

readonly autoLayoutDrop: BodyAutoLayoutDropTarget | null源码

指针下方的自动布局画框和插入位置,或 null。设置此项时关闭吸附。

interface BodyGuideLine

源码

移动操作可以吸附到的标尺参考线。

readonly axis: "x" | "y"源码
readonly position: number源码

参考线的 x 或 y,以文档单位计。

readonly frameId?: NodeId源码

拥有该参考线的画框;页面参考线省略此项。与 Figma 一样,画框的参考线只吸附该画框内部的对象。它们从不吸附画框本身,因为画框移动时会带着这些参考线一起移动。

interface BodyAutoLayoutDropTarget

源码

位于移动中选区下方的自动布局画框,及其插入位置。

readonly frameId: NodeId源码
readonly insertionIndex: number源码

离指针最近的插入位置的子节点索引。

readonly activeSlot: number源码

离指针最近的插入位置在 slots 中的位置。要高亮某一个指示器时应使用它而不是 insertionIndex,因为换行布局中的两个插入位置可能共用同一个索引。

readonly slots: readonly BodyAutoLayoutInsertionSlot[]源码

interface BodyAutoLayoutInsertionSlot

源码

被拖动的节点可以插入自动布局画框的一个位置。

在换行的行或列中,每一行都有自己的插入位置,因此一行的末尾和下一行的开头是 index 相同的两个插入位置:两者都把节点放到子节点顺序中的同一位置。

readonly index: number源码

节点插入后将占据的子节点索引。

readonly rect: Rect源码

插入指示器在文档空间中的矩形,与渲染器无关。

这些函数读取手势进行期间需要绘制的内容。

function displayedBodySelection(state: BodyInteractionState): BodySelectionState

源码

框选期间渲染的选区;规范选区只在指针抬起时改变。

function bodyInteractionGesture( state: BodyInteractionState ): EditorGestureState | null

源码

当前手势,以与渲染器无关的 EditorGestureState 表示,其中的点以文档单位计;或为 null。

function bodyInteractionPreviews( state: BodyInteractionState ): readonly EditorPreviewGeometry[]

源码

当前手势的叠加层形状,以文档单位计:开始拖动后的框选矩形、自动布局插入位置,或移动时的吸附参考线。

function bodyMoveNodePreviews( state: BodyInteractionState ): readonly BodyMoveNodePreview[]

源码

移动过程中,每个移动中的节点对应一个 BodyMoveNodePreview;其他情况下为空。

interface BodyMoveNodePreview

源码

移动过程中如何绘制一个节点:偏移 documentDelta(文档单位),可以替代原节点绘制,也可以作为副本绘制在原节点旁边。

readonly nodeId: NodeId源码
readonly documentDelta: Point源码
readonly mode: "replace" | "duplicate"源码

function bodyAutoLayoutDropPreview( state: BodyInteractionState ): BodyAutoLayoutDropTarget | null

源码

当前移动操作的自动布局放置目标,或 null。

function clearBodyInteractionHover( state: BodyInteractionState ): BodyInteractionState

源码

清除悬停节点。手势进行中时不做任何事。

手势进行中视图发生平移时(例如拖动到画布边缘),页面会在指针下方移动。这些函数把手势测得的内容移动相同的偏移,使手势继续进行而不会跳动。

function translateBodyInteractionGesture( state: BodyInteractionState, documentDelta: Point, viewport: ViewportState ): BodyInteractionState

源码

把当前手势在文档空间和屏幕空间中测得的一切移动 documentDelta,使页面在手势下方移动时手势能继续进行,例如在按住指针时视图发生平移。这样,移动会让其选区保持在指针下方,并让吸附目标留在它们所属的图层上。移动的预览偏移等偏移量不变。视口的缩放必须与手势开始时相同;缩放会改变视口并结束手势。

function holdBodyMoveAtPointerThroughPan( state: BodyInteractionState, documentDelta: Point, viewport: ViewportState ): BodyInteractionState

源码

类似 translateBodyInteractionGesture,用于指针静止时发生的平移:页面移动 documentDelta,指针在屏幕上保持不动。进行中的移动让其图层保持在指针下方,因此其预览偏移减少 documentDelta,这正是在同一位置的下一个指针采样在吸附前会测得的值。下一个采样会重新测量这次移动并进行吸附。其他手势的平移方式与 translateBodyInteractionGesture 相同。

function translateSceneGeometry( snapshot: SceneGeometrySnapshot, documentDelta: Point, viewport: ViewportState ): SceneGeometrySnapshot

源码

对快照中的每个节点及其场景包围盒执行 translateNodeGeometry。

function translateNodeGeometry( geometry: NodeGeometry, documentDelta: Point, viewport: ViewportState ): NodeGeometry

源码

把一个节点的几何在文档空间中移动 documentDelta,并在屏幕上移动对应的屏幕偏移。用于页面在手势下方移动时(例如视图平移),使平移前测得的几何仍能描述节点当前被绘制的位置。

function translateRect(rect: Rect, delta: Point): Rect

源码

把矩形在其自身空间中移动一个偏移。

function documentDeltaToScreenDelta( viewport: ViewportState, documentDelta: Point ): Point

源码

在 viewport 下与文档偏移对应的屏幕偏移:视口的缩放和旋转会生效,平移则不会。

绘制、调整大小、缩放与旋转

其他指针手势的几何计算:绘制形状、拖动调整大小的控制柄、旋转和缩放。这些函数在传入点所在的任意空间中工作。

function rectangleFromPoints(start: Point, current: Point): Rect

源码

两个角点之间的矩形,无论拖动方向如何,其宽度和高度都不为负。点不是有限值时抛出 TypeError。

function combineRects(rects: readonly Rect[]): Rect | null

源码

能容纳列表中每个矩形的最小矩形;列表为空时为 null。

function boundsForTransformedRect(rect: Rect, transform: TransformMatrix): Rect

源码

矩形经过变换后的轴对齐边界。与 transformRect 相同。

function constrainLineEndpoint( start: Point, current: Point, constrained: boolean ): Point

源码

当 constrained(按住 Shift)时,将从 start 绘制的直线的终点吸附到最接近的 45 度倍数方向,并保持其长度。否则原样返回 current。

function constrainBoxEndpoint( start: Point, current: Point, constrained: boolean ): Point

源码

当 constrained(按住 Shift)时,移动被拖动的角点,使从 start 绘制的盒子成为正方形,边长取较长的一边。否则原样返回 current。

interface ResizeHandleDirection

源码

调整大小控制柄的拉动方向:-1 表示西或北,1 表示东或南, 0 表示该控制柄不改变的轴。

readonly x: -1 | 0 | 1源码
readonly y: -1 | 0 | 1源码

function directionForResizeHandle( handle: EditorResizeHandle ): ResizeHandleDirection

源码

调整大小控制柄名称对应的 ResizeHandleDirection。

function rotationFromPointerPoints( options: { readonly initialRotation: number; readonly center: Point; readonly start: Point; readonly current: Point; readonly snapIncrement?: number; } ): number

源码

旋转拖动过程中的旋转角度(单位为度):initialRotation 加上指针自 start 以来绕 center 转过的角度,再用 normalizeRotationDegrees 折算范围。提供 snapIncrement 时,结果会舍入为它的倍数(例如按住 Shift 时为 15)。所有点必须位于同一空间。吸附增量不为正数时抛出 RangeError。 其中 atan2⁡\operatorname{atan2} 取各点相对于 center 的偏移:

r=wrap⁡ ⁣(r0+180π(atan2⁡(Δycurrent,Δxcurrent)−atan2⁡(Δystart,Δxstart)))r = \operatorname{wrap}\!\left(r_0 + \frac{180}{\pi} \bigl(\operatorname{atan2}(\Delta y_\text{current}, \Delta x_\text{current}) - \operatorname{atan2}(\Delta y_\text{start}, \Delta x_\text{start})\bigr)\right)

吸附时,r←wrap⁡(s⋅round⁡(r/s))r \leftarrow \operatorname{wrap}(s \cdot \operatorname{round}(r / s)), 其中 ss = snapIncrement。

function rotatePointAround(point: Point, center: Point, degrees: number): Point

源码

将点绕中心旋转 degrees 度。在画布这样 y 轴向下的空间中,正角度表示顺时针旋转。输入不是有限值时抛出 TypeError。 设 θ=degrees⋅π/180\theta = \text{degrees} \cdot \pi / 180,中心为 (cx,cy)(c_x, c_y),则:

x′=cx+(x−cx)cos⁡θ−(y−cy)sin⁡θy′=cy+(x−cx)sin⁡θ+(y−cy)cos⁡θ\begin{aligned} x' &= c_x + (x - c_x)\cos\theta - (y - c_y)\sin\theta \\ y' &= c_y + (x - c_x)\sin\theta + (y - c_y)\cos\theta \end{aligned}

function normalizeRotationDegrees(degrees: number): number

源码

将角度折算到 -180(含)到 180(不含)度的范围内。 角度不是有限值时抛出 TypeError。

调整编组大小时,会缩放其内容的位置和尺寸。缩放工具还会缩放描边宽度、圆角半径、效果和字号。

function resizeGroup( document: DesignDocument, groupId: NodeId, frame: Rect ): readonly SceneNode[]

源码

通过缩放所有后代,将编组调整为 frame 的大小,与在 Figma 中对编组进行普通调整大小的效果相同。位置、尺寸和矢量几何会被缩放;描边宽度、圆角半径、效果和字号不会被缩放(这是缩放工具的用途)。调用方负责选择 frame,使锚定的边保持不动。

返回该编组,后面依次跟着每个发生变化的后代;当编组无法调整大小时,返回空列表。

function uniformScaleFactorFromPointer( options: { readonly anchor: Point; readonly start: Point; readonly current: Point; readonly minimumFactor: number; } ): number

源码

缩放拖动过程中的等比缩放系数。它将指针相对于 anchor 的偏移投影到起始偏移上,因此 1 表示没有变化,2 表示与锚点的距离变为两倍。结果永远不会小于 minimumFactor。当 start 位于锚点上时返回 1。当 minimumFactor 不为正数时抛出 RangeError。设 s\mathbf{s} = start − anchor, p\mathbf{p} = current − anchor,则:

k=max⁡ ⁣(kmin,p⋅s∥s∥2)k = \max\!\left(k_\text{min}, \frac{\mathbf{p} \cdot \mathbf{s}}{\lVert \mathbf{s} \rVert^2}\right)

type ScaleCorner = "north-west" | "north-east" | "south-east" | "south-west"

源码

type ScaleOrigin = ScaleCorner | "center"

源码

缩放时保持不动的点:被拖动控制柄的对角,或在按住 Option/Alt 时取图层的中心。

function scaleAnchor(corner: ScaleOrigin, frame: Pick<Rect, "width" | "height">)

源码

function scaleSubtree( document: DesignDocument, rootId: NodeId, factor: number, corner: ScaleOrigin ): readonly SceneNode[]

源码

A multi-selection moves as one box, as in Figma. selectionBoxBounds is the box around several sibling layers; resizeNodesInBox, rotateNodesAbout and scaleNodesAbout resize, rotate and scale them together. A connector is not turned or stretched: its ends move (connectorWithMovedEnds) and the page compiler places an attached end on its layer again.

function selectionBoxBounds(nodes: readonly SceneNode[]): Rect | null

源码

The bounding box of several sibling layers in their shared parent’s coordinates: the smallest upright box around each layer’s rotated bounds, as Figma draws one box around a multi-selection.

function resizeNodesInBox( document: DesignDocument, nodeIds: readonly NodeId[], from: Rect, to: Rect, boxAngle = 0 ): readonly SceneNode[]

源码

Resizes several sibling layers together, like resizing a multi-selection’s bounding box in Figma: the box from becomes to (both in the layers’ shared parent coordinates), and every layer’s position and size scale with it by the same rules as a group resize (resizeGroup). A rotated layer keeps its rotation and takes the size whose bounds are its old bounds scaled with the box, so the layers fill to (scaleLayerInParent describes when that needs a skew and what happens then); text that grew with its content gets a fixed size; a frame’s box scales and its children follow by their constraints (constrainChildren), as when the frame itself is resized. Stroke widths, radii, effects and font sizes do not change.

boxAngle is the box’s turn in degrees (clockwise, screen y down) when it is not upright, as after rotating the selection: from and to are then in the box’s own coordinates, the parent’s turned by boxAngle about its origin, and the layers scale along the box’s sides.

Returns every changed node, each selected layer followed by its changed descendants, or an empty list when a layer is missing or locked.

function rotateNodesAbout( nodes: readonly SceneNode[], degrees: number, center: Point ): readonly SceneNode[]

源码

Turns sibling layers by degrees (clockwise, screen y down) around center in their parent’s coordinates, as rotating a multi-selection does in Figma: each layer’s center moves around center and its own rotation grows by the same angle. A path’s transform turns as a whole.

An upright connector is not turned: its two ends move around center (connectorWithMovedEnds), so a free end turns with the selection like a line’s end, and an attached end is placed on its layer again by the page compiler, which cannot attach a turned connector.

function scaleNodesAbout( document: DesignDocument, nodeIds: readonly NodeId[], factor: number, anchor: { readonly x: number; readonly y: number } ): readonly SceneNode[]

源码

Scales several sibling layers together by factor about anchor in their shared parent’s coordinates, as the scale tool (K) scales a multi-selection: every layer’s position moves away from the anchor by factor, and each layer scales as scaleSubtree scales one, strokes, radii, effects and text included. Returns every changed node, or an empty list when a layer is missing or locked or factor is not positive.

function connectorWithMovedEnds( node: ConnectorNode, move: (point: Point) => Point ): ConnectorNode

源码

An upright connector whose two ends are moved by move (from and to points in its parent’s coordinates); its frame becomes the box around the moved ends. The web app’s store then refits the frame to the line the renderer draws (apps/web/src/store/connectorFrames.ts), which places an attached end on its layer’s edge whatever point is stored for it.

对齐、吸附与测量

对象吸附把移动中的框的边缘、中心和文本基线与附近的目标对齐,并报告需要绘制的参考线。距离测量给出按住 Option 拖动副本离开原对象时,以及按住 Option 悬停时显示的红色距离。

function snapObjectBounds( initialBounds: AlignmentRect, rawDeltaX: number, rawDeltaY: number, targets: readonly AlignmentTarget[], threshold: number, movingBaselines: readonly number[] = [] ): ObjectSnapResult

源码

interface ObjectSnapResult

源码
readonly deltaX: number源码
readonly deltaY: number源码
readonly guides: readonly AlignmentGuide[]源码

interface AlignmentRect

源码
readonly left: number源码
readonly top: number源码
readonly right: number源码
readonly bottom: number源码

interface AlignmentTarget

源码
readonly id: string源码
readonly bounds: AlignmentRect源码
readonly baselines?: readonly number[]源码
readonly line?: "x" | "y"源码

使目标成为一条单独的线,例如标尺参考线。“x” 线位于 bounds.left,只提供水平位置;“y” 线位于 bounds.top,只提供垂直位置。移动边界的任一边或中心都可以落在这条线上;为它显示的匹配线只跨越移动边界,因为参考线本身已经可见。

type AlignmentAnchor = "start" | "center" | "end" | "baseline"

源码

盒子用于对齐的点:左边/上边、中心、右边/下边,或文本基线。

interface AlignmentGuide

源码
readonly orientation: "horizontal" | "vertical"源码
readonly position: number源码
readonly start: number源码
readonly end: number源码
readonly movingAnchor: AlignmentAnchor源码

移动中的盒子在这条参考线上的锚点。叠加层用它把参考线画在与移动中选区轮廓相同的设备像素上,而渲染器会把选区轮廓画在盒子内部:位于左边或上边的参考线覆盖该线之后的像素,位于右边或下边的参考线覆盖该线之前的像素。

function measureDistances( reference: Rect, moving: Rect ): readonly DistanceMeasurement[]

源码

从 reference 到 moving 的测量结果,两者都是位于同一坐标空间中的轴对齐矩形。距离为零的项会被省略,因此对齐的边不会产生测量。

interface DistanceMeasurement

源码
readonly axis: MeasurementAxis源码

“x” 测量水平距离,绘制为一条水平线。

readonly start: number源码

线段在被测量轴上的起点和终点;start < end。

readonly end: number源码
readonly position: number源码

线段在另一条轴上的坐标。

readonly value: number源码

end - start,即标签显示的数值。

readonly kind: "gap" | "offset" | "inset"源码

这是哪一种距离,用于标签和测试。

readonly extension: MeasurementExtension | null源码

type MeasurementAxis = "x" | "y"

源码

按住 ⌥ 将副本从原对象拖开时显示的红色距离测量,参照 Figma 的 Option 拖动测量和 ⌥ 悬停测量。

每条测量都是某一轴上的一条直线,连接参照对象(原对象)的一条边与移动对象(副本)的一条边:

  • 当两个对象在某一轴上分开时,测量跨越两者之间的间隙。
  • 当两者在该轴上重叠或相接、但在另一轴上分开时,测量跨越移动对象超出参照对象那一侧的两条边之间的偏移。
  • 当两者在两个轴上都重叠时,会在每对对应的边之间显示四条内嵌测量。

测量线穿过参照对象的中心(两个对象在两个轴上都重叠时,则穿过重叠区域的中心)。当移动对象未延伸到这条线时,会用一条虚线延长移动对象的边,使测量有一个落点。

所有数值的单位与输入矩形相同(页面单位)。

interface MeasurementExtension

源码
readonly position: number源码

移动对象的边在被测量轴上的坐标。

readonly start: number源码

在另一轴上的跨度,从移动对象延伸到测量线。

readonly end: number源码

function formatMeasurementValue(value: number): string

源码

测量标签显示的数字:最多两位小数且不带末尾的零,与 Figma 显示距离的方式一致(“84”“12.5”“0.33”)。

富文本编辑

文本位置相对于段落,以 UTF-16 码元计数,并为可以绘制在两处的位置携带一个亲和性(affinity)。选区保留其锚点和焦点,因此方向得以保留。

interface TextPosition

源码

相对于段落的文本位置。偏移量始终以 UTF-16 码元计数。

readonly paragraphIndex: number源码
readonly utf16Offset: number源码
readonly affinity: TextAffinity源码

type TextAffinity = "upstream" | "downstream"

源码

当同一偏移量可以绘制在两个位置时(例如换行处或双向文本片段的边缘),文本位置属于边界的哪一侧。

interface TextRange

源码

锚点(anchor)和焦点(focus)保留选区方向,而不是将范围规范化。

readonly anchor: TextPosition源码
readonly focus: TextPosition源码

interface TextCompositionState

源码

替换规范文档中某一范围的临时输入法(IME)文本。

readonly replacementRange: TextRange源码

组合输入开始时所替换的规范范围。

readonly displayRange: TextRange源码

当前已发布的组合输入预览所占用的范围。

readonly text: string源码
readonly selectionStart: number源码

文本中的 UTF-16 偏移量,与浏览器的组合输入 API 一致。

readonly selectionEnd: number源码

interface ActiveTextEditingState

源码

正在编辑的文本节点、它当前的选区,以及正在进行的 IME 组合输入(如果有)。

readonly nodeId: NodeId源码
readonly selection: TextRange源码
readonly composition: TextCompositionState | null源码

function assertTextPosition( value: unknown, label = "Text position" ): asserts value is TextPosition

源码

检查一个值是否为 TextPosition:段落索引和 UTF-16 偏移量为非负整数,且亲和性(affinity)为已知值。抛出 TypeError 或 RangeError。它不会针对任何文档检查该位置。

function assertTextRange( value: unknown, label = "Text range" ): asserts value is TextRange

源码

检查一个值是否为 TextRange,且其锚点和焦点都能通过 assertTextPosition。

function assertActiveTextEditingState( value: unknown, label = "Active text editing state" ): asserts value is ActiveTextEditingState

源码

检查一个值是否为 ActiveTextEditingState。如果存在组合输入,它必须有有效的范围,且其选区必须有序、非负,并且不超过以 UTF-16 码元计的组合文本长度。

reduceRichTextEditing 是文本编辑的纯状态转换。它从不测量文本、分派文档操作或记录历史,而是返回效果:选区变化、交由渲染器回答的导航查询、事务中的段落编辑,以及剪贴板写入。

function createRichTextEditingState( input: { readonly nodeId: NodeId; readonly paragraphs: readonly TextParagraph[]; readonly selection: TextRange; readonly layoutGeneration: bigint; } ): RichTextEditingState

源码

function reduceRichTextEditing( state: RichTextEditingState, action: RichTextEditingAction ): RichTextEditingTransition

源码

纯粹的富文本状态转换。控制器从不测量文本、选择字素簇导航停靠点、派发文档操作,也不记录历史。

interface RichTextEditingState

源码

不可变的编辑器状态。它包含规范段落,但不拥有文档 store 或历史栈;由调用方应用返回的副作用。

readonly nodeId: NodeId源码
readonly paragraphs: readonly TextParagraph[]源码
readonly selection: TextRange源码
readonly layoutGeneration: bigint | null源码

与段落完全对应的代次;编辑之后为 null。

readonly lastLayoutGeneration: bigint源码

已同步的最高代次,在 layoutGeneration 为 null 期间保留。

readonly composition: RichTextCompositionSession | null源码
readonly pointerSelection: RichTextPointerSelectionState | null源码
readonly pendingNavigation: RichTextPendingNavigation | null源码
readonly pendingRunFormat: RichTextPendingRunFormat | null源码

完整的已编写文本片段(run)样式,用于之后在折叠光标处插入文本。

readonly preferredLocalX: number | undefined源码
readonly nextRequestId: number源码
readonly nextTransactionId: number源码

type RichTextEditingAction = | RichTextPointerAction | { readonly kind: "layout-synchronized"; readonly generation: bigint } | { readonly kind: "navigation-intent"; readonly operation: TextNavigationOperation; readonly extend: boolean; } | { readonly kind: "navigation-result"; readonly requestId: number; readonly result: TextNavigationResult | null; } | { readonly kind: "beforeinput"; readonly input: EditorTextInput } | { readonly kind: "composition"; readonly input: EditorCompositionInput } | { readonly kind: "clipboard"; readonly input: EditorClipboardInput } | { readonly kind: "keyboard"; readonly input: EditorKeyboardInput; readonly platform: RichTextKeyboardPlatform; } | { readonly kind: "format-runs"; readonly expectedSelection: TextRange; readonly expectedLayoutGeneration: bigint; readonly patch: RichTextRunFormatPatch; } | { readonly kind: "format-paragraphs"; readonly expectedSelection: TextRange; readonly expectedLayoutGeneration: bigint; readonly patch: RichTextParagraphFormatPatch; }

源码

interface RichTextEditingTransition

源码
readonly state: RichTextEditingState源码
readonly effects: readonly RichTextEditingEffect[]源码

type RichTextEditingEffect = | { readonly kind: "selection-change"; readonly nodeId: NodeId; readonly selection: TextRange; } | { readonly kind: "navigation-request"; readonly requestId: number; readonly query: TextNavigationQuery; } | { readonly kind: "transaction"; readonly boundary: RichTextTransactionBoundary; readonly transactionId: number; readonly intent: RichTextEditIntent; } | { readonly kind: "paragraph-edit"; readonly transactionId: number; readonly intent: RichTextEditIntent; readonly stage: RichTextParagraphEditStage; readonly nodeId: NodeId; readonly paragraphs: readonly TextParagraph[]; readonly selection: TextRange; readonly composition: TextCompositionState | null; } | { readonly kind: "rejected-intent"; readonly inputType: string; readonly reason: string; } | { readonly kind: "clipboard-write"; readonly action: "copy" | "cut"; readonly items: readonly { readonly mimeType: string; readonly data: Uint8Array; }[]; }

源码

type RichTextEditIntent = | "insert-text" | "insert-paragraph" | "insert-line-break" | "paste-rich" | "paste-plain" | "delete-grapheme-backward" | "delete-grapheme-forward" | "delete-word-backward" | "delete-word-forward" | "delete-line-backward" | "delete-line-forward" | "delete-paragraph-backward" | "delete-paragraph-forward" | "delete-selection" | "format-runs" | "format-paragraphs" | "composition"

源码

type RichTextPointerAction = | { readonly kind: "pointer"; readonly phase: "down"; readonly pointerId: number; readonly hit: TextHitResult; readonly extend: boolean; readonly clickCount?: number; } | { readonly kind: "pointer"; readonly phase: "move" | "up"; readonly pointerId: number; readonly hit: TextHitResult; } | { readonly kind: "pointer"; readonly phase: "cancel" | "lost-capture"; readonly pointerId: number; }

源码

interface RichTextPointerSelectionState

源码
readonly pointerId: number源码
readonly anchor: TextPosition源码
readonly unit?: TextRange源码

双击或三击选中的单词或段落。随后拖动时,它会保持选中,并从其远端边缘开始扩展选区,与浏览器行为一致。

readonly baselineSelection: TextRange源码
readonly baselinePendingRunFormat: RichTextPendingRunFormat | null源码

function pointerUnitRange( paragraphs: readonly TextParagraph[], position: TextPosition, unit: "word" | "paragraph" ): TextRange

源码

双击或三击时选中的单词或段落。与浏览器一样,在单词之间双击会选中所落在的空格或标点。

interface RichTextPendingNavigation

源码
readonly requestId: number源码
readonly layoutGeneration: bigint源码
readonly operation: TextNavigationOperation源码
readonly purpose: RichTextPendingNavigationPurpose源码

type RichTextPendingNavigationPurpose = | { readonly kind: "selection"; readonly extend: boolean } | { readonly kind: "delete"; readonly transactionId: number; readonly intent: RichTextEditIntent; readonly origin: TextPosition; }

源码

interface RichTextCompositionSession extends TextCompositionState

源码
readonly transactionId: number源码
readonly baselineParagraphs: readonly TextParagraph[]源码
readonly baselineSelection: TextRange源码
readonly previewApplied: boolean源码

段落预览是否已发布给宿主。

type RichTextKeyboardPlatform = "macos" | "windows-linux"

源码

type RichTextTransactionBoundary = "begin" | "commit" | "cancel"

源码

type RichTextParagraphEditStage = | "canonical" | "composition-preview" | "composition-commit" | "composition-restore"

源码

function activeTextEditingState( state: RichTextEditingState ): ActiveTextEditingState

源码

将控制器状态转换为渲染器叠加层的约定格式。

格式编辑会修改选区中的文本片段和段落。汇总函数报告工具栏应为某个选区显示的格式。

interface RichTextRunFormatPatch

源码
readonly styleId?: RichTextFieldEdit<TextStyleId>源码
readonly overrides?: { readonly [Key in keyof RichTextRunOverrides]?: RichTextFieldEdit< Exclude<RichTextRunOverrides[Key], undefined> > }源码
readonly openTypeFeatureEdits?: RichTextTaggedValueEdits<boolean | number>源码

逐个合并标签,不会替换无关的已编写特性值。

readonly fontVariationEdits?: RichTextTaggedValueEdits<number>源码

逐个合并轴,不会替换无关的已编写可变字体值。

interface RichTextParagraphFormatPatch

源码

段落字段使用同样的显式 set/remove 编辑约定。

readonly direction?: RichTextFieldEdit<NonNullable<TextParagraph["direction"]>>源码
readonly align?: RichTextFieldEdit<NonNullable<TextParagraph["align"]>>源码
readonly spacingBefore?: RichTextFieldEdit<number>源码
readonly spacingAfter?: RichTextFieldEdit<number>源码
readonly indent?: RichTextFieldEdit<NonNullable<TextParagraph["indent"]>>源码
readonly list?: RichTextFieldEdit<NonNullable<TextParagraph["list"]>>源码
readonly indentFields?: RichTextIndentFieldEdits源码

逐项合并缩进值;remove 会将该值恢复为零。

readonly listFields?: RichTextListFieldEdits源码

合并列表控制项,同时保留未改动的标记。

readonly listMarkerFields?: RichTextListMarkerFieldEdits源码

合并标记控制项,但不会隐式创建列表。

interface RichTextIndentFieldEdits

源码
readonly left?: RichTextFieldEdit<number>源码
readonly right?: RichTextFieldEdit<number>源码
readonly firstLine?: RichTextFieldEdit<number>源码

interface RichTextListFieldEdits

源码
readonly kind?: RichTextFieldEdit<"ordered" | "unordered">源码

移除 kind 会清除列表;更改它会保留标记的编写内容。

readonly level?: RichTextFieldEdit<number>源码

移除 level 会恢复为第 0 级。

readonly start?: RichTextFieldEdit<number>源码

移除 start 会恢复自动编号。

interface RichTextListMarkerFieldEdits

源码
readonly text?: RichTextFieldEdit<NonNullable<TextListMarker["text"]>>源码

移除 text 会恢复渲染器自动生成的标记文本。

readonly styleId?: RichTextFieldEdit<NonNullable<TextListMarker["styleId"]>>源码

移除 styleId 会恢复从第一个文本片段继承共享样式。

readonly overrides?: RichTextFieldEdit<NonNullable<TextListMarker["overrides"]>>源码

移除 overrides 会恢复从第一个文本片段继承直接格式。

readonly gap?: RichTextFieldEdit<NonNullable<TextListMarker["gap"]>>源码

移除 gap 会恢复渲染器根据字体自动计算的间距。

type RichTextFieldEdit<Value> = | { readonly kind: "set"; readonly value: Value } | { readonly kind: "remove" }

源码

省略表示字段保持不变;remove 表示恢复继承。

type RichTextTaggedValueEdits< Value > = Readonly<Record<string, RichTextFieldEdit<Value>>>

源码

type RichTextRunOverrides = NonNullable<TextRun["overrides"]>

源码

type RichTextPendingRunFormat = Readonly<Pick<TextRun, "styleId" | "overrides">>

源码

function selectedRichTextRunFormats( state: RichTextEditingState ): readonly RichTextPendingRunFormat[]

源码

列举与当前选区相交的、不可变的已编写文本片段格式。

function aggregateRichTextSelectionFormatting( state: RichTextEditingState ): RichTextSelectionFormatting

源码

返回选区中文档里记录的格式,不查询 DOM 的编辑状态。

interface RichTextSelectionFormatting

源码
readonly run: { readonly styleId: RichTextAggregatedValue<TextStyleId | undefined>; readonly overrides: RichTextAggregatedRunOverrides; readonly openTypeFeaturesByTag: Readonly< Record<string, RichTextAggregatedValue<boolean | number | undefined>> >; readonly fontVariationsByTag: Readonly< Record<string, RichTextAggregatedValue<number | undefined>> >; }源码
readonly paragraph: { readonly direction: RichTextAggregatedValue<TextParagraph["direction"]>; readonly align: RichTextAggregatedValue<TextParagraph["align"]>; readonly spacingBefore: RichTextAggregatedValue<number | undefined>; readonly spacingAfter: RichTextAggregatedValue<number | undefined>; readonly indent: RichTextAggregatedValue<TextParagraph["indent"]>; readonly list: RichTextAggregatedValue<TextParagraph["list"]>; readonly indentFields: { readonly left: RichTextAggregatedValue<number | undefined>; readonly right: RichTextAggregatedValue<number | undefined>; readonly firstLine: RichTextAggregatedValue<number | undefined>; }; readonly listFields: { readonly kind: RichTextAggregatedValue< "ordered" | "unordered" | undefined >; readonly level: RichTextAggregatedValue<number | undefined>; readonly start: RichTextAggregatedValue<number | undefined>; }; readonly listMarkerFields: { readonly text: RichTextAggregatedValue<TextListMarker["text"]>; readonly styleId: RichTextAggregatedValue<TextListMarker["styleId"]>; readonly overrides: RichTextAggregatedValue<TextListMarker["overrides"]>; readonly gap: RichTextAggregatedValue<TextListMarker["gap"]>; }; }源码

type RichTextAggregatedValue<Value> = | { readonly kind: "uniform"; readonly value: Value } | { readonly kind: "mixed" }

源码

type RichTextAggregatedRunOverrides = { readonly [Key in keyof RichTextRunOverrides]-: RichTextAggregatedValue< RichTextRunOverrides[Key] | undefined > }

源码

矢量编辑

矢量编辑作用于矢量网络:顶点、顶点之间的线段,以及由线段环构成的区域。渲染器以节点局部坐标报告网络的几何信息,并对其进行命中测试。

interface VectorGeometry

源码
readonly nodeId: NodeId源码
readonly generation: bigint源码
readonly vertices: readonly VectorVertexGeometry[]源码
readonly handles: readonly VectorCubicHandleGeometry[]源码
readonly segments: readonly VectorSegmentGeometry[]源码
readonly regions: readonly VectorRegionGeometry[]源码

interface VectorVertexGeometry

源码
readonly id: string源码
readonly kind: "vertex"源码
readonly localPoint: Point源码
readonly screenPoint: Point源码

interface VectorCubicHandleGeometry

源码
readonly id: string源码
readonly kind: "cubic-handle"源码
readonly segmentId: string源码
readonly vertexId: string源码
readonly endpoint: "start" | "end"源码
readonly localPoint: Point源码
readonly screenPoint: Point源码

type VectorSegmentGeometry = | VectorLineSegmentGeometry | VectorCubicSegmentGeometry | VectorArcSegmentGeometry

源码

interface VectorLineSegmentGeometry extends VectorSegmentGeometryBase

源码
readonly kind: "line"源码

interface VectorCubicSegmentGeometry extends VectorSegmentGeometryBase

源码
readonly kind: "cubic"源码
readonly startHandleId: string源码
readonly endHandleId: string源码

interface VectorArcSegmentGeometry extends VectorSegmentGeometryBase

源码
readonly kind: "elliptical-arc"源码
readonly radiusX: number源码
readonly radiusY: number源码
readonly xAxisRotation: number源码
readonly largeArc: boolean源码
readonly sweep: boolean源码

interface VectorRegionGeometry

源码
readonly id: string源码
readonly kind: "region"源码
readonly windingRule: "nonzero" | "evenodd"源码
readonly authoredOrder: number源码
readonly localBounds: Rect源码
readonly screenBounds: Rect源码

interface VectorHitQuery

源码
readonly nodeId: NodeId源码
readonly screenPoint: Point源码
readonly toleranceCssPx: number源码

type VectorQueryHit = & { readonly id: string; readonly priority: number; readonly authoredOrder: number; readonly distanceCssPx: number; } & ( | { readonly kind: "vertex" } | { readonly kind: "cubic-handle"; readonly endpoint: "start" | "end" } | { readonly kind: "segment" } | { readonly kind: "region" })

源码

interface VectorHitTestResult

源码
readonly nodeId: NodeId源码
readonly generation: bigint源码
readonly hits: readonly VectorQueryHit[]源码

拓扑函数返回应用了一处改动的新网络。当改动无法完成时,它们会抛出带错误码的 VectorTopologyError:例如元素缺失、id 重复、参数错误或不安全的区域编辑。

class VectorTopologyError extends Error

源码
readonly code: VectorTopologyErrorCode源码
readonly componentId: string | null源码
new ( code: VectorTopologyErrorCode, message: string, componentId: string | null = null )源码

type VectorTopologyErrorCode = | "DUPLICATE_ID" | "INVALID_PARAMETER" | "MISSING_HANDLE" | "MISSING_LOOP" | "MISSING_REGION" | "MISSING_SEGMENT" | "MISSING_VERTEX" | "UNSAFE_REGION_EDIT" | "UNSUPPORTED_SEGMENT"

源码

function addVectorVertex( network: VectorNetwork, vertex: VectorVertex ): VectorNetwork

源码

添加一个由调用方标识的自由锚点,不改变已有拓扑。

function addVectorSegment( network: VectorNetwork, segment: VectorSegment ): VectorNetwork

源码

使用调用方提供的 ID,在已有锚点之间添加一条直线边或三次曲线边。

function updateVectorVertices( network: VectorNetwork, updates: readonly VectorVertexUpdate[] ): VectorNetwork

源码

移动一个或多个共享顶点,而不改变相对于端点的控制柄。

interface VectorVertexUpdate

源码
readonly vertexId: VectorVertexId源码
readonly x: number源码
readonly y: number源码

function updateVectorHandle( network: VectorNetwork, update: VectorHandleUpdate ): VectorNetwork

源码

原子性地更新一个控制柄,并应用其可选的切线约束。

interface VectorHandleUpdate

源码
readonly handleId: VectorHandleId源码
readonly dx: number源码
readonly dy: number源码

function setVectorTangentConstraint( network: VectorNetwork, update: VectorTangentConstraintUpdate ): VectorNetwork

源码

将同一顶点上的两个控制柄耦合在一起,并替换任一控制柄原先所属的配对。

interface VectorTangentConstraintUpdate

源码
readonly vertexId: VectorVertexId源码
readonly handleIds: readonly [VectorHandleId, VectorHandleId]源码
readonly drivenHandleId: VectorHandleId源码

被驱动的控制柄保持其位置;与之配对的控制柄会与它对齐。

readonly mode: VectorTangentConstraint["mode"]源码

function removeVectorTangentConstraints( network: VectorNetwork, handleIds: readonly VectorHandleId[] ): VectorNetwork

源码

移除所有涉及所给控制柄之一的切线对。

function deleteVectorVertices( network: VectorNetwork, vertexIds: readonly VectorVertexId[] ): VectorNetwork

源码

删除锚点、所有与之相连的边、受影响的填充环以及切线对。

function deleteVectorSegments( network: VectorNetwork, segmentIds: readonly VectorSegmentId[], options: DeleteVectorComponentsOptions = {} ): VectorNetwork

源码

删除边以及依赖这些边的所有填充环。

function deleteVectorRegions( network: VectorNetwork, regionIds: readonly VectorRegionId[] ): VectorNetwork

源码

删除可独立绘制的区域,不改变它们共享的拓扑。

interface DeleteVectorComponentsOptions

源码
readonly deleteOrphanVertices?: boolean源码

删除线段时默认保留自由锚点。

function addVectorRegion( network: VectorNetwork, region: VectorRegion ): VectorNetwork

源码

在一条已有的连通链上添加一个可独立绘制的区域。

function openVectorRegionLoop( network: VectorNetwork, target: VectorRegionLoopTarget, segmentId: VectorSegmentId ): VectorNetwork

源码

通过移除一条独占边,打开一个在网络中闭合的填充轮廓。剩余的链通过 implicitClose 保持相同的填充;共享的填充边会被拒绝,因为移除它会悄无声息地破坏其他区域。

function closeVectorRegionLoop( network: VectorNetwork, target: VectorRegionLoopTarget, segment: VectorSegment ): VectorNetwork

源码

用一条由调用方标识的直线或三次曲线,闭合一个隐式填充的开放轮廓。提供的边可以以任一方向跨越开放缺口。

interface VectorRegionLoopTarget

源码
readonly regionId: VectorRegionId源码
readonly loopIndex: number源码

function joinVectorVertices( network: VectorNetwork, sourceVertexId: VectorVertexId, targetVertexId: VectorVertexId, options: JoinVectorVerticesOptions = {} ): VectorNetwork

源码

将一个共享锚点合并到另一个锚点,并重新连接所有相关的拓扑结构。

interface JoinVectorVerticesOptions

源码
readonly position?: { readonly x: number; readonly y: number }源码

默认为保留下来的目标顶点的位置。

function convertVectorLineToCubic( network: VectorNetwork, segmentId: VectorSegmentId, ids: VectorLineToCubicIds ): VectorNetwork

源码

将直线转换为三次曲线,同时保留其线段 ID 和区域引用。

interface VectorLineToCubicIds

源码
readonly startHandleId: VectorHandleId源码
readonly endHandleId: VectorHandleId源码

function convertVectorCubicToLine( network: VectorNetwork, segmentId: VectorSegmentId ): VectorNetwork

源码

将三次曲线转换为直线,并移除引用其控制柄的约束。

function splitVectorSegment( network: VectorNetwork, segmentId: VectorSegmentId, amount: number, ids: VectorSplitIds ): VectorNetwork

源码

在 0<t<1 处拆分直线或三次曲线。原线段保留其 ID,并覆盖前半部分;原有端点控制柄的 ID 仍留在其编写时所在的端点上。

interface VectorSplitIds

源码
readonly vertexId: VectorVertexId源码
readonly segmentId: VectorSegmentId源码
readonly firstEndHandleId?: VectorHandleId源码

拆分三次线段时必需。

readonly secondStartHandleId?: VectorHandleId源码

拆分三次线段时必需。

type VectorEditableSegment = Extract<VectorSegment, { kind: "line" | "cubic" }>

源码

reduceVectorEditing 保存单条路径的元素选区、拖动状态和预览网络。它向调用方返回效果:指针捕获、选区变化,以及带有原因的 commit-network 请求。

function createVectorEditingState( options: { readonly nodeId: NodeId; readonly network: VectorNetwork; readonly selection?: VectorEditingSelection; } ): VectorEditingState

源码

function reduceVectorEditing( state: VectorEditingState, action: VectorEditingAction ): VectorEditingResult

源码

interface VectorEditingState

源码
readonly nodeId: NodeId源码
readonly network: VectorNetwork源码
readonly previewNetwork: VectorNetwork源码
readonly selection: VectorEditingSelection源码
readonly gesture: VectorEditingGesture | null源码

type VectorEditingAction = | { readonly type: "select"; readonly hit: VectorComponentHit | null; readonly modifiers: EditorModifiers; } | { readonly type: "drag-start"; readonly hit: VectorComponentHit; readonly pointerId: number; readonly position: Point; readonly modifiers: EditorModifiers; readonly bend?: { readonly ids: VectorEditIdAllocator; readonly threshold: number; }; readonly breakThreshold?: number; readonly distanceSpace?: TransformMatrix; } | { readonly type: "point-box-start"; readonly pointerId: number; readonly position: Point; readonly box: VectorPointBox; readonly hit: VectorPointBoxHit; readonly localToBox: TransformMatrix; readonly boxToLocal: TransformMatrix; readonly modifiers: EditorModifiers; } | { readonly type: "drag-move"; readonly pointerId: number; readonly position: Point; readonly modifiers?: EditorModifiers; } | { readonly type: "drag-end" | "drag-cancel" | "lost-capture"; readonly pointerId: number; } | { readonly type: "commit-topology"; readonly network: VectorNetwork; readonly reason: VectorEditingCommitReason; readonly selection?: VectorEditingSelection; } | { readonly type: "external-synchronize"; readonly network: VectorNetwork }

源码

interface VectorEditingResult

源码
readonly state: VectorEditingState源码
readonly effects: readonly VectorEditingEffect[]源码

type VectorEditingEffect = | { readonly type: "capture-pointer"; readonly pointerId: number } | { readonly type: "release-pointer"; readonly pointerId: number } | { readonly type: "selection-changed"; readonly selection: VectorEditingSelection; } | { readonly type: "commit-network"; readonly nodeId: NodeId; readonly network: VectorNetwork; readonly reason: VectorEditingCommitReason; }

源码

type VectorEditingCommitReason = | "move-vertices" | "move-handle" | "move-segment" | "add-segment" | "convert-segment" | "split-segment" | "join-segments" | "delete-components" | "open-path" | "close-path" | "tangent-constraint" | "vertex-corner-radius" | "boolean-operation" | "add-point" | "bend" | "cut" | "region-fill"

源码

interface VectorEditingSelection

源码
readonly vertexIds: readonly VectorVertexId[]源码
readonly handleIds: readonly VectorHandleId[]源码
readonly segmentIds: readonly VectorSegmentId[]源码
readonly regionIds: readonly VectorRegionId[]源码
readonly primary: VectorComponentSelection | null源码

interface VectorEditingGesture

源码
readonly pointerId: number源码
readonly component: Extract< VectorComponentSelection, { readonly kind: "vertex" | "handle" | "segment" } >源码
readonly startedAt: Point源码
readonly currentAt: Point源码
readonly sourceNetwork: VectorNetwork源码
readonly draggedVertexIds: readonly VectorVertexId[]源码
readonly collapseOnClick?: boolean源码

A plain press on a component that was already selected among others: if it ends without moving, it selects just that component, as in Figma.

readonly baseNetwork?: VectorNetwork源码

The network a handle drag edits, when it isn’t sourceNetwork: an Alt drag on a handle first drops the handle’s mirroring pair.

readonly breakThreshold?: number源码

How far the pointer must go before an Alt drag applies baseNetwork; a press that never gets that far changes nothing. In network units, or in the units of distanceSpace when that is set.

readonly distanceSpace?: TransformMatrix源码

A matrix from network coordinates to the space this gesture measures its thresholds in, such as the screen. Without it they are in network units.

readonly breakStarted?: boolean源码

Set once the pointer has gone past breakThreshold, and stays set.

readonly bend?: VectorBendGesture源码

A Bend tool drag, which shapes handles instead of moving points.

readonly pointBox?: VectorPointBoxGesture源码

A drag of the box around several selected points, which scales or rotates them.

type VectorComponentHit = Extract< EditorHit, { readonly part: | "vector-anchor" | "vector-handle" | "vector-segment" | "vector-region"; } >

源码

type VectorComponentSelection = | { readonly kind: "vertex"; readonly id: VectorVertexId } | { readonly kind: "handle"; readonly id: VectorHandleId } | { readonly kind: "segment"; readonly id: VectorSegmentId } | { readonly kind: "region"; readonly id: VectorRegionId }

源码

function vectorComponentHitFromQueryHit( nodeId: NodeId, network: VectorNetwork, hit: VectorQueryHit ): VectorComponentHit | null

源码

将不带品牌类型(branded type)的渲染器查询命中映射回对应的规范记录。 ID 会有意在其组成部分类型内进行校验,因为 ABI 允许顶点、控制柄、线段和区域使用相同的字符串。

updateVectorInteraction 把指针输入接入矢量编辑。它只在指针按下时进行命中测试;拖动中的后续点都经过在那次按下时固定的变换。

function createVectorInteractionState( environment: VectorInteractionEnvironment, selection?: VectorEditingSelection ): VectorInteractionState | null

源码

仅当场景、矢量几何和节点变换都描述同一个保留代次时,才开启组成部分的编辑。

function updateVectorInteraction( environment: VectorInteractionEnvironment, state: VectorInteractionState, input: EditorPointerInput ): VectorInteractionResult

源码

归约针对现有路径组成部分的输入。只有指针按下时才会执行矢量命中查询;一次手势中,之后的每个点都使用该手势冻结的逆变换。

function invalidateVectorInteraction( state: VectorInteractionState, reason: VectorInteractionInvalidationReason ): VectorInteractionResult

源码

interface VectorInteractionEnvironment

源码
readonly nodeId: NodeId源码
readonly network: VectorNetwork源码

当前由 nodeId 拥有的确切规范网络对象。

readonly viewport: ViewportState源码

当前安装在 renderSession 上的确切视口对象。

readonly renderSession: VectorInteractionRenderQueries源码
readonly hitToleranceCssPx?: number源码

原生组成部分命中半径,单位为 CSS 像素。默认为 6。

readonly editTool?: VectorEditToolContext源码

The vector edit mode tool, when it isn’t the Move tool: Pen adds a point where it presses a segment, Bend shapes handles from a point or segment, and Cut breaks the path at a point or segment. ids names what they add.

readonly pointBox?: boolean源码

Offer the box around several selected points (the Move tool does): a press on one of its handles or rotate zones scales or rotates the points.

type VectorInteractionRenderQueries = Pick< InteractiveRenderSession, "getSceneGeometrySnapshot" | "getVectorGeometry" | "hitTestVector" >

源码

interface VectorInteractionState

源码
readonly editing: VectorEditingState源码
readonly binding: VectorInteractionBinding源码
readonly status: "ready" | "awaiting-commit" | "invalidated"源码

interface VectorInteractionBinding

源码
readonly generation: bigint源码
readonly expectedNetwork: VectorNetwork源码
readonly viewport: ViewportState源码
readonly renderSession: VectorInteractionRenderQueries源码
readonly nodeGeometry: NodeGeometry源码
readonly screenToLocal: TransformMatrix源码

type VectorInteractionInvalidationReason = | "node-changed" | "network-changed" | "viewport-changed" | "render-session-changed" | "scene-generation-changed" | "node-geometry-changed" | "vector-query-unavailable" | "coordinate-conversion-failed"

源码

interface VectorInteractionResult

源码
readonly state: VectorInteractionState源码
readonly effects: readonly VectorInteractionEffect[]源码

type VectorInteractionEffect = | { readonly type: "capture-pointer"; readonly pointerId: number } | { readonly type: "release-pointer"; readonly pointerId: number } | { readonly type: "selection-changed"; readonly selection: VectorEditingSelection; } | { readonly type: "commit-network"; readonly nodeId: NodeId; readonly expectedNetwork: VectorNetwork; readonly network: VectorNetwork; readonly reason: Extract< VectorEditingEffect, { readonly type: "commit-network" } >["reason"]; readonly generation: bigint; } | { readonly type: "editing-invalidated"; readonly reason: VectorInteractionInvalidationReason; }

源码

function vectorInteractionLocalPoint( state: VectorInteractionState, screenPoint: Point ): Point | null

源码

通过交互中冻结的精确仿射逆变换转换一个屏幕点。

function vectorEditingSnapshot( state: VectorInteractionState ): VectorEditingSnapshot | null

源码

一旦冻结的渲染器/规范权威状态失效,就返回 null。

interface VectorEditingSnapshot

源码

单个现有路径的组成部分编辑器的状态,与渲染器无关。source network 是授权之后提交的那个确切的规范对象,而 network 是由叠加层绘制的临时预览。

readonly nodeId: NodeId源码
readonly generation: bigint源码
readonly coordinateSpace: "node-local"源码
readonly status: "ready" | "awaiting-commit"源码
readonly sourceNetwork: VectorNetwork源码
readonly network: VectorNetwork源码
readonly selection: VectorEditingSelectionSnapshot源码
readonly gesture: VectorEditingGestureSnapshot | null源码
readonly pendingHandle?: PenPendingHandle | null源码

The handle the Pen is pulling out of a point, or left there for the next segment: drawn as chrome, because no segment of network owns it yet. Its point is in network. Absent or null when there is none.

readonly viewport: ViewportState源码

与此保留场景代次一同冻结的确切视口对象。

readonly localToDocument: TransformMatrix源码
readonly localToScreen: TransformMatrix源码
readonly screenToLocal: TransformMatrix源码

interface VectorEditingSelectionSnapshot

源码
readonly vertexIds: readonly VectorVertexId[]源码
readonly handleIds: readonly VectorHandleId[]源码
readonly segmentIds: readonly VectorSegmentId[]源码
readonly regionIds: readonly VectorRegionId[]源码
readonly primary: VectorEditingComponentSnapshot | null源码

interface VectorEditingGestureSnapshot

源码
readonly pointerId: number源码
readonly component: Extract< VectorEditingComponentSnapshot, { readonly kind: "vertex" | "handle" | "segment" } >源码
readonly startedAt: Point源码

手势开始时冻结的节点局部指针坐标。

readonly currentAt: Point源码

预览所使用的最新节点局部指针坐标。

type VectorEditingComponentSnapshot = | { readonly kind: "vertex"; readonly id: VectorVertexId } | { readonly kind: "handle"; readonly id: VectorHandleId } | { readonly kind: "segment"; readonly id: VectorSegmentId } | { readonly kind: "region"; readonly id: VectorRegionId }

源码

布尔运算(联集、交集、差集、排除)通过 InteractiveRenderSession.booleanVectorPaths 向渲染器请求。

type VectorBooleanOperation = | "union" | "intersection" | "difference" | "exclusion"

源码

interface VectorBooleanPathRequest

源码

一次基于保留场景的布尔运算请求,结果 ID 的分配权归调用方所有。

readonly primaryNodeId: NodeId源码
readonly secondaryNodeId: NodeId源码
readonly operation: VectorBooleanOperation源码
readonly resultIdNamespace: string源码

interface VectorBooleanPathResult

源码

由某一个确切的保留场景代次生成的、位于主对象局部空间中的规范几何。

readonly generation: bigint源码
readonly primaryNodeId: NodeId源码
readonly secondaryNodeId: NodeId源码
readonly operation: VectorBooleanOperation源码
readonly vectorNetwork: VectorNetwork源码

无障碍

createAccessibilitySnapshotV1 根据一份文档、一个页面和一代场景几何构建屏幕阅读器看到的语义树。子节点遵循文档中的子节点顺序,而不是绘制顺序。边界是以 CSS 像素表示的、经过裁剪的屏幕边界。它返回的每个对象都是冻结的。

interface AccessibilitySnapshotV1

源码
readonly version: typeof ACCESSIBILITY_SNAPSHOT_VERSION源码
readonly documentId: DocumentId源码
readonly pageId: PageId源码
readonly generation: bigint源码

保留场景的代次,而不是编辑器历史的修订号。

readonly focusOwner: AccessibilityFocusOwnerV1源码
readonly root: AccessibilityNodeSnapshotV1源码

function createAccessibilitySnapshotV1( input: AccessibilitySnapshotInputV1 ): AccessibilitySnapshotV1

源码

为一个当前页面构建与渲染器无关的 v1 语义镜像。它只读取、从不修改规范文档、几何或叠加层。

interface AccessibilitySnapshotInputV1

源码
readonly document: DesignDocument源码
readonly activePageId: PageId源码
readonly geometry: SceneGeometrySnapshot源码
readonly overlay: AccessibilityOverlayStateV1源码

interface AccessibilityNodeSnapshotV1

源码
readonly id: NodeId源码
readonly role: AccessibilityRoleV1源码
readonly name: string源码
readonly description: string | null源码
readonly value: string | null源码
readonly screenBounds: Rect源码

可见的、经裁剪的边界,单位为 CSS 像素,相对于编辑器表面。

readonly focused: boolean源码
readonly selected: boolean源码
readonly editing: boolean源码
readonly readOnly: boolean源码
readonly actions: readonly AccessibilityActionV1[]源码
readonly textSelection: AccessibilityTextSelectionV1 | null源码
readonly children: readonly AccessibilityNodeSnapshotV1[]源码

type AccessibilityRoleV1 = typeof ACCESSIBILITY_ROLES_V1[number]

源码

const ACCESSIBILITY_ROLES_V1: readonly [ "document", "group", "text", "textbox", "code", "image", "video", "shape", "connector" ]

源码

type AccessibilityActionV1 = typeof ACCESSIBILITY_ACTIONS_V1[number]

源码

const ACCESSIBILITY_ACTIONS_V1: readonly [ "focus", "select", "toggle-selection", "edit" ]

源码

type AccessibilityFocusOwnerV1 = typeof ACCESSIBILITY_FOCUS_OWNERS_V1[number]

源码

const ACCESSIBILITY_FOCUS_OWNERS_V1: readonly [ "none", "react-shell", "canvas", "accessibility-mirror", "text-input" ]

源码

type AccessibilityEditStateV1 = | { readonly kind: "text"; readonly nodeId: NodeId; readonly selection: AccessibilityTextSelectionV1; } | { readonly kind: "code"; readonly nodeId: NodeId }

源码

interface AccessibilityOverlayStateV1

源码

由 UI 持有的状态,叠加在某一个确切的保留场景代次之上。

readonly focusOwner: AccessibilityFocusOwnerV1源码
readonly focusedNodeId: NodeId | null源码
readonly selectedNodeIds: readonly NodeId[]源码
readonly edit: AccessibilityEditStateV1 | null源码
readonly pageLayersHidden?: boolean源码

True when the scene draws none of the page’s own layers, only the open component’s view (the isolation split’s component pane). The mirror then lists the component’s layers alone, and no page layer needs geometry.

interface AccessibilityTextPositionV1

源码

相对于段落的 UTF-16 位置,与渲染器布局无关。

readonly paragraphIndex: number源码
readonly utf16Offset: number源码
readonly affinity: AccessibilityTextAffinityV1源码

interface AccessibilityTextSelectionV1

源码

锚点(anchor)和焦点(focus)保留选区的方向。

readonly anchor: AccessibilityTextPositionV1源码
readonly focus: AccessibilityTextPositionV1源码

type AccessibilityTextAffinityV1 = typeof ACCESSIBILITY_TEXT_AFFINITIES_V1[number]

源码

const ACCESSIBILITY_TEXT_AFFINITIES_V1: readonly ["upstream", "downstream"]

源码

const ACCESSIBILITY_SNAPSHOT_VERSION: 1

源码

class AccessibilitySnapshotErrorV1 extends Error

源码
new (readonly code: AccessibilitySnapshotErrorCodeV1, message: string)源码

type AccessibilitySnapshotErrorCodeV1 = | "invalid-active-page" | "invalid-document-tree" | "invalid-geometry" | "invalid-overlay"

源码

resolveAccessibilityActionAuthorityV1 对照动作请求所来自的快照检查该请求。针对其他文档或页面、旧代号、缺失节点或节点不提供的动作的请求,会在任何改动发生之前被拒绝。

function resolveAccessibilityActionAuthorityV1( snapshot: AccessibilitySnapshotV1, request: AccessibilityActionRequestV1 ): AccessibilityActionAuthorityV1

源码

只负责解析权限。在本函数确认确切的代次和所声明的节点操作之后,路由和修改仍由调用方负责。

interface AccessibilityActionRequestV1

源码
readonly documentId: DocumentId源码
readonly pageId: PageId源码
readonly generation: bigint源码
readonly nodeId: NodeId源码
readonly action: AccessibilityActionV1源码

interface AccessibilityActionAuthorityV1

源码
readonly version: typeof ACCESSIBILITY_SNAPSHOT_VERSION源码
readonly documentId: DocumentId源码
readonly pageId: PageId源码
readonly generation: bigint源码
readonly nodeId: NodeId源码
readonly action: AccessibilityActionV1源码
readonly node: AccessibilityNodeSnapshotV1源码

class AccessibilityActionAuthorityErrorV1 extends Error

源码
new (readonly code: AccessibilityActionAuthorityErrorCodeV1, message: string)源码

type AccessibilityActionAuthorityErrorCodeV1 = | "invalid-request" | "context-mismatch" | "stale-generation" | "node-not-found" | "action-not-advertised"

源码

interface AccessibilityNodeSnapshot

源码
readonly id: string源码
readonly role: string源码
readonly name: string源码
readonly value?: string源码
readonly bounds?: Rect源码
readonly focused: boolean源码
readonly selected: boolean源码
readonly actions: readonly string[]源码
readonly children: readonly AccessibilityNodeSnapshot[]源码

测试场景

共享场景对每个 EditorDriver 运行相同的编辑检查。每个场景都声明自己需要的能力。富文本、矢量和无障碍场景集彼此独立,后端可以在支持时再采用它们。

interface EditorScenario

源码
readonly name: string源码
readonly requirements?: EditorScenarioRequirements源码
run(driver: EditorDriver): Promise<void>源码

interface EditorScenarioRequirements

源码
readonly pointerTypes?: readonly EditorPointerType[]源码
readonly keyboardRepeat?: boolean源码
readonly composition?: boolean源码
readonly clipboard?: readonly EditorClipboardInput["action"][]源码
readonly textEditing?: boolean源码
readonly textGeometry?: boolean源码
readonly textHitTesting?: boolean源码
readonly textNavigation?: boolean源码
readonly vectorGeometry?: boolean源码
readonly vectorHitTesting?: boolean源码
readonly vectorBooleanOperations?: boolean源码
readonly accessibility?: boolean源码
readonly frameCapture?: boolean源码
readonly variableDevicePixelRatio?: boolean源码

function runEditorScenarios( driver: EditorDriver, scenarios: readonly EditorScenario[] ): Promise<void>

源码

function assertEditorDriverCapabilities( actual: EditorDriverCapabilities, required: EditorScenarioRequirements ): void

源码

const standardEditorScenarios: readonly EditorScenario[]

源码

所有后端共享的、与后端无关且信号价值高的编辑工作流。

const richTextEditorScenarios: readonly EditorScenario[]

源码

富文本一致性场景单独存放,直到某个后端明确报告具备所有必需的能力。任何声称支持、却未提供权威的文本整形、导航和输入法(IME)行为的后端,都无法通过这些场景。

const vectorEditorScenarios: readonly EditorScenario[]

源码

针对现有路径的一致性工作流,适用于提供权威矢量查询的后端。

const vectorBooleanEditorScenarios: readonly EditorScenario[]

源码

仅限原生实现的布尔运算工作流,由所有声明具备该能力的后端共享。

const accessibilityEditorDriverScenariosV1: readonly EditorScenario[]

源码

与后端无关的无障碍验收场景,适用于第 1 版 EditorDriver。

function runAccessibilityEditorDriverScenariosV1( driver: EditorDriver ): Promise<void>

源码

检查能力后,运行共享的无障碍 v1 EditorDriver 场景。

无障碍预言(oracle)场景无需驱动,直接检查 createAccessibilitySnapshotV1 和 resolveAccessibilityActionAuthorityV1,或其替代实现。

const accessibilityOracleScenariosV1: readonly AccessibilityOracleScenarioV1[]

源码

function runAccessibilityOracleScenariosV1( adapter: AccessibilityOracleAdapterV1 = defaultAccessibilityOracleAdapterV1 ): void

源码

运行时不查询也不声明任何当前的 EditorDriver 能力。

interface AccessibilityOracleAdapterV1

源码
createSnapshot(input: AccessibilitySnapshotInputV1): AccessibilitySnapshotV1源码
resolveAction( snapshot: AccessibilitySnapshotV1, request: AccessibilityActionRequestV1 ): AccessibilityActionAuthorityV1源码

interface AccessibilityOracleScenarioV1

源码
readonly name: string源码
run(adapter: AccessibilityOracleAdapterV1): void源码

const defaultAccessibilityOracleAdapterV1: AccessibilityOracleAdapterV1

源码

其他导出

尚未归入上述章节的导出,按字母顺序排列。

function abandonVectorSubPath( network: VectorNetwork, vertexId: VectorVertexId, startedVertexId: VectorVertexId | null ): VectorNetwork | null

源码

The network without a sub-path that was started and never drawn: the point is removed when it is the one a Pen click started (startedVertexId), no segment touches it and the network has other points. Returns null when there is nothing to remove. A point without segments that was not started this way stays, because it is the user’s own: for example the end left behind when its segments were deleted. The only point of a network stays too (a layer keeps at least the point it was created with).

function addPenSegment( network: VectorNetwork, shape: PenSegmentShape ): VectorNetwork

源码

Adds the segment a Pen press makes between two points of the network.

  • Plain click from a point without a remembered handle: a straight line.
  • Otherwise a cubic. It leaves the start along the remembered handle, or along a third of the straight way to the end when there is none. It arrives at the end along the mirror of the drag, or with no handle after a plain click.

When the remembered handle still mirrors the handle of the segment that arrived at the start point, the two are paired (angle and length), so the point stays smooth when either handle is moved later.

function bendVectorSegment( prepared: VectorPreparedSegmentBend, delta: Point ): VectorNetwork

源码

A Bend drag on a segment: moves both handles so the point taken hold of at t moves by delta, the handle nearer to it moving more. Handles paired with a neighbouring segment’s handle keep their pair in step; a pair made of the segment’s own two handles is dropped.

function bendVectorVertex( prepared: VectorPreparedVertex, vertexId: VectorVertexId, heldEnd: number, drag: Point ): VectorNetwork

源码

A Bend drag from a point: the held segment end’s handle follows the pointer (drag, from the point) and the other end’s handle mirrors it in angle and length. A point joining more than two segment ends is unchanged.

function compareVectorTangentConstraints( left: VectorTangentConstraint, right: VectorTangentConstraint ): number

源码

Orders tangent constraints the way the document schema requires.

function constrainVectorCutLineEnd(start: Point, end: Point): Point

源码

The end of a cut line held to 45 degree steps from its start, as Shift does: the nearest of the eight directions, at the pointer’s distance along it. Both points are in screen coordinates.

function convertVectorArcToCubics( network: VectorNetwork, segmentId: VectorSegmentId, ids: VectorEditIdAllocator ): VectorArcConversion

源码

Replaces an elliptical arc with the cubic pieces that trace it, joined by new vertices whose two handles keep the same angle. An arc SVG draws as a straight line becomes a line. Fill loops run through the pieces in order.

function cornerVectorVertex( network: VectorNetwork, vertexId: VectorVertexId ): VectorNetwork

源码

Makes a point a corner: every handle at it goes to zero length and its handle pairs are dropped. A cubic left with no handles becomes a line.

function createStandardAccessibilityEditorDriverDocumentV1(): DesignDocument

源码

用于共享 EditorDriver 验收的、资源完整的规范文档。它复用已签入仓库的标准富文本字体,因此渲染不依赖宿主字体或无效的占位资源。原生代码节点的编译仍是生产环境 Wasm 运行所需的构建产物。

function createStandardAccessibilityScenarioDocumentV1(): DesignDocument

源码

由各个语义参照(semantic oracle)实现共享的规范文档。

function createStandardAccessibilityScenarioGeometryV1(): SceneGeometrySnapshot

源码

几何数据有意使用与规范子节点树不同的顺序。

function createStandardAccessibilityScenarioInputV1(): AccessibilitySnapshotInputV1

源码

function createStandardEditorScenarioDocument( kind: StandardEditorScenarioDocument ): DesignDocument

源码

由每个交互式渲染后端共享的规范模型文档。

function createStandardVectorBooleanScenarioDocument( kind: StandardVectorBooleanScenarioDocument ): DesignDocument

源码

function createStandardVectorScenarioDocument( kind: StandardVectorScenarioDocument ): DesignDocument

源码

由每个具备相应能力的交互式后端使用的、包含已有路径的规范文档。

const CROSSING_TOLERANCE: 0.000001

源码

The share of the edges’ size below which two points count as one.

type Cubic = readonly [Point, Point, Point, Point]

源码

A cubic Bézier curve as its four control points.

function cubicLineCrossings( cubic: Cubic, from: Point, to: Point ): readonly number[]

源码

The positions t in [0, 1] where a cubic crosses the straight cut line from from to to, in order. A crossing is where the curve passes from one side of the line to the other within the line’s length, so a curve that only touches the line (a tangent) is not cut. A curve that starts or ends on the line is crossed there (t = 0 or 1). A curve lying along the line is not crossed.

function cutVectorNetworkAlongLine( network: VectorNetwork, from: Point, to: Point, ids: VectorEditIdAllocator ): VectorCut

源码

Cuts the network along the straight line from from to to (network coordinates): each segment the line crosses gets a point at every crossing and breaks there, and each point the line passes through breaks as a Cut click on it does. Fill loops through a break become open loops, as with the click. Returns the network unchanged, with no points, when the line crosses nothing.

function cutVectorSegment( network: VectorNetwork, segmentId: VectorSegmentId, t: number, ids: VectorEditIdAllocator ): VectorCut

源码

Cuts a segment at position t (see VectorSegmentPoint.t): a point goes in there without changing the shape, and the path breaks at it into two ends.

function deleteAndHealVectorVertices( network: VectorNetwork, vertexIds: readonly VectorVertexId[], allocate: VectorHealIdAllocator ): VectorNetwork

源码

Deletes the given anchors one after another, healing each as described above. Anchors an earlier heal already removed are skipped.

function detachVectorVertex( network: VectorNetwork, vertexId: VectorVertexId, ids: VectorEditIdAllocator ): VectorCut

源码

Gives every segment end at a vertex a vertex of its own at the same place; the first segment end keeps the original. Handle pairs at the vertex are dropped, since their handles no longer meet. A vertex with at most one segment end is left as it is.

function doubleClickSelectionAction( document: DesignDocument, rootId: NodeId, hitNodeId: NodeId, primarySelectedNodeId: NodeId | null, mode: InstanceSelectionMode ): DoubleClickSelectionAction | null

源码

The action of a double click on hitNodeId. With the instance as one object ("instance"), a double click on an instance, or on any layer of one, enters isolation for the outermost instance’s component; once the selection is inside that instance it acts as in a group (design question 1). Like a group ("group"), and outside instances, a double click selects one level deeper, and edits the hit layer once it is the selected one.

type DoubleClickSelectionAction = | { readonly kind: "select"; readonly nodeId: NodeId } | { readonly kind: "edit"; readonly nodeId: NodeId } | { readonly kind: "isolate"; readonly instanceId: NodeId }

源码

What a double click with the move tool does (components design 5.5).

function findUnstoredVectorFaces( network: VectorNetwork ): readonly VectorRegionLoop[]

源码

The faces of a network (findVectorFaces) that no region is stored for yet.

function findVectorAreas(network: VectorNetwork): readonly VectorArea[]

源码

The areas a network encloses when every crossing (findVectorCrossings) is treated as a corner: a five-point star drawn in one stroke is six, its middle and five tips; a figure of eight is two; two overlapping loops are three. An area that has a separate loop lying inside it keeps its whole inside. An area no larger than the crossing tolerance times the length of its outline is left out; for a long strip that is a width of twice the tolerance.

These are the areas a fill can be seen in. A region cannot store one of them when its boundary runs along a piece of a segment, so findVectorFaces covers them with loops of whole segments.

function findVectorCrossings(network: VectorNetwork): readonly VectorCrossing[]

源码

Every place where two segments of a network meet away from a point they share: they cross, one ends on the other or touches it, or they run along each other (the two ends of the shared stretch are given). A curve that crosses itself counts. Segments that meet at a point of the network they both use are joined there, and that is no crossing.

Lines are intersected exactly. Curves are intersected as the straight pieces their outline is drawn with (24 per cubic piece), so a crossing with a curve is found to within that flattening, and at is measured along those pieces. Places no further apart, in a straight line, than a millionth of the network’s size count as one (CROSSING_TOLERANCE).

The network is not changed: no point is added at a crossing.

function findVectorFaces(network: VectorNetwork): readonly VectorRegionLoop[]

源码

The areas a network encloses: the bounded faces of the network read as a planar graph, in network order of their first segment. A closed Pen path is one face; a square with a diagonal is two; a loop inside another, not joined to it, is a face of its own next to the outer one, which keeps its whole inside. Open ends, dangling branches and connectors between loops bound nothing and are left out.

Each face is given as the loop a region for it stores: every segment once, from the face’s first segment.

In a connected part whose segments cross or touch away from a shared point the areas are bounded by pieces of segments, which a loop cannot name. Such a part gives loops of whole segments that cover its areas when filled by winding (the nonzero rule): a closed path that crosses itself gives one loop, the path itself, which fills everything it winds around. These loops may cross themselves and lie over each other. An area that no loop of whole segments winds around is not covered: one enclosed by a path that is not closed, or one a closed path circles as often one way as the other. findVectorAreas gives the areas themselves.

function frontFirst<Layer>(storedOrder: readonly Layer[]): readonly Layer[]

源码

The order the layers of one parent are listed in: the front layer first and the back layer last, as Figma does. A parent stores its layers the other way round, back layer first (the order they are drawn in), and that stored order is not changed by the listing.

This one rule holds for every parent: a page, a frame with or without auto layout, a group, an instance and a layer inside one. A mask needs no rule of its own: it is stored before the layers it hides parts of, so it is listed below them.

Everything that lists layers or walks them by keyboard asks here, so the orders cannot disagree: the layers panel’s rows, its Shift-click range, the context menu’s “Select layer” list, Enter, Tab and Shift+Tab on the canvas (childSelectionTarget, siblingSelectionTarget), and the tree a screen reader hears (createAccessibilitySnapshotV1), whose aria-posinset counts from the front layer.

function hitVectorPointBox( box: VectorPointBox, point: Point ): VectorPointBoxHit | null

源码

What a press at point (box space) takes hold of: the nearest resize handle within reach, else a rotate zone, which is the ring just outside a corner and outside the box. Null for anywhere else.

function insertVectorPoint( network: VectorNetwork, segmentId: VectorSegmentId, t: number, ids: VectorEditIdAllocator ): VectorPointInsertion

源码

Adds a point on a segment at position t (see VectorSegmentPoint.t) without changing the shape, as Figma’s Pen tool does when it clicks a path in edit mode. A cubic’s new point has its two handles at the same angle.

function instanceLayerChildren( document: DesignDocument, id: NodeId ): readonly NodeId[]

源码

The resolved children of an instance (its component root’s layers) or of a layer inside one, in paint order; empty for anything else.

function instanceLayerParent( document: DesignDocument, id: NodeId ): NodeId | undefined

源码

The parent of a layer inside an instance: the instance’s own ID for a first-level layer. undefined for a stored ID or one that does not resolve.

function instanceLayerPath( document: DesignDocument, id: NodeId ): readonly NodeId[] | undefined

源码

The virtual IDs from the instance’s first-level layer down to a virtual ID, outermost first. Empty for a stored ID; undefined for a virtual ID that does not resolve.

function instanceLayerResolveStats(): InstanceResolveCache["stats"]

源码

How many instances and component views this module resolved anew (misses) and took from its cache (hits). Tests read it to check that a pass over a document resolves each of them once.

type InstanceSelectionMode = "instance" | "group"

源码

The “Selecting inside instances” preference (components design 5.5).

function invertVectorTransform( transform: TransformMatrix ): TransformMatrix | null

源码

Inverts every finite, nonsingular affine transform with a representable inverse, or returns null. Vector edit mode uses this one rule wherever it inverts a path transform, so a transform that opens the mode (such as a tiny 1e-12 scale) never fails later in a nudge or a typed X/Y position.

function isInSelectionScope( document: DesignDocument, rootId: NodeId, scopeId: NodeId, nodeId: NodeId ): boolean

源码

True for the scope layer and every layer inside it. A pointer on a canvas that selects within the scope acts only on these: a layer of a container around the scope is not under it, though that container stands for the scope when a rule answers with it (scopedSelectionTarget).

function isInstanceLayer(document: DesignDocument, id: NodeId): boolean

源码

True when id is a stored instance or a nested instance layer selected as a whole.

function lassoVectorSelection( network: VectorNetwork, before: VectorEditingSelection, contents: VectorLassoContents, mode: VectorLassoMode ): VectorEditingSelection

源码

The selection after a lasso. “replace” selects just what the lasso holds; “add” (Shift) keeps what was selected before and adds to it; “subtract” (Option or Alt) takes the points the lasso holds out of what was selected before, and with them every selected segment that ends at one of them. Handles and regions selected before an “add” or “subtract” lasso are kept.

function listedChildIds( document: DesignDocument, parentId: NodeId ): readonly NodeId[]

源码

The layers a parent holds, in listed order (frontFirst): the children of a stored frame, group or page root, or the resolved layers of an instance or of a layer inside one. Empty for anything else.

function marqueeVectorSelection( network: VectorNetwork, before: VectorEditingSelection, insideVertexIds: readonly VectorVertexId[], additive: boolean ): VectorEditingSelection

源码

The selection after a marquee: the anchors inside it, added to the anchors selected before the drag when Shift is held. Handles, segments and regions selected before an additive marquee are kept.

function mergeDeletedFaceRegions( before: VectorNetwork, after: VectorNetwork ): VectorNetwork

源码

Keeps a fill over faces that a delete has merged. Deleting a segment that two faces share drops the regions of both, since each used the segment; the face they become gets one region here:

  • with the fills of the largest of the merged faces, when that one had a region (also when that region was emptied: the merged face is then empty);
  • otherwise with the fills of the largest merged face whose region was filled;
  • and none when no merged face had a region, or only emptied ones beside a larger face without one.

The region keeps the ID and the place in the order of the one it follows. before is the network just before the delete removed points and segments, after the one after it. Every region before has and after lacks counts as dropped by that removal, so a region the user deleted on purpose must be gone from before too, or it could come back over the merged face.

function nearestPointOnVectorSegment( network: VectorNetwork, segmentId: VectorSegmentId, target: Point, distanceSpace?: TransformMatrix ): VectorSegmentPoint

源码

The point on a segment nearest to target, in network coordinates.

“Nearest” is measured in network units unless distanceSpace is given: a matrix from network coordinates to the space to measure in. Pass the path’s local-to-screen matrix to find the point nearest on screen, which is a different point when the path is stretched unevenly or skewed.

function nudgeVectorVertices( network: VectorNetwork, vertexIds: readonly VectorVertexId[], localDelta: Point ): VectorNetwork

源码

Moves the given anchors by one local-space offset in one network edit.

function paintVectorTarget( network: VectorNetwork, target: VectorPaintTarget, regionId: VectorRegionId, layerShowsFill: boolean ): VectorPaintResult

源码

A Paint click on a target, decided by what is on screen. A region never gets a colour of its own from Paint: it either takes the layer’s fills (fills omitted) or has none (fills: []), so the Fill panel, which edits the layer’s fills, always changes what is painted.

  • A target that shows a fill loses it: fills: []. Fills of its own (an imported SVG, an older document) are dropped with it; undo brings them back, Paint does not.
  • A target that shows none is filled: it takes the layer’s fills. That holds for a region emptied before and for one whose own fills do not show, which are dropped. A loop without a region gets its region first, named regionId: the same region a shape turned into a path stores for its outline (nonzero, one loop, each segment once), so later edits treat it as they treat any stored region.
  • When the layer shows no fill (layerShowsFill false, see vectorFillsShow), filling asks for one on the layer (layerNeedsFill). Every other region that took the layer’s fills, and so showed nothing, is set to fills: [], so the click changes nothing else on screen.

Only the layer’s fills count for layerShowsFill, not its opacity or visibility. On a hidden layer, or one at 0% opacity, nothing is seen whatever Paint does; a click there still switches the stored fill as it would on a layer that shows, and the result is seen once the layer is shown again.

const PEN_ANGLE_STEP_DEGREES: 45

源码

Shift holds the Pen to multiples of this angle, as in Figma.

function penArmedVertexId( network: VectorNetwork, selection: VectorEditingSelection ): VectorVertexId | null

源码

The point the Pen draws from, or null for none. It is the primary component when that is a point, however many other components are selected with it; otherwise the only selected point, whatever else (a segment, a handle, a region) is selected or primary. A point the network does not have is never armed. Every Pen path asks here, so a click on empty canvas, on a point and on a segment, the cursor badge and Escape all agree on the source.

function pendingPenOutgoingHandle( network: VectorNetwork, selection: VectorEditingSelection, handle: PenOutgoingHandle | null ): PenOutgoingHandle | null

源码

The remembered outgoing handle while it still applies: its point is the one the Pen draws from (penArmedVertexId). Null once another point is armed, the path in progress is ended, or the point is gone (for example by undo).

function pendingVectorSubPath( network: VectorNetwork, startedVertexId: VectorVertexId | null ): VectorVertexId | null

源码

The started sub-path that still waits for its first segment: startedVertexId while the network has that point with no segment at it, otherwise null. A caller that remembers which point a Pen click started passes every network it comes to hold through this, so the point stops counting as a started sub-path once it is drawn from or removed, and never counts again after that.

interface PenHandleOffset

源码

A curve handle as an offset from its point.

readonly dx: number源码
readonly dy: number源码

interface PenOutgoingHandle extends PenHandleOffset

源码

The handle a Pen drag pulled out of a point for the segment that is drawn from it next. A point stores no handle of its own (handles belong to segments), so the handle is remembered here until that segment exists.

readonly vertexId: VectorVertexId源码
readonly mirrorHandleId: VectorHandleId | null源码

The handle of the segment that arrived at the point in the same drag: the exact mirror of this one. Null for the first point of a sub-path, which no segment arrives at.

interface PenPendingHandle extends PenHandleOffset

源码

A handle the canvas draws although no segment owns it yet: the one a Pen drag is pulling out of a point, or the one it left there for the next segment. mirrored also draws its exact mirror about the point, for a point no segment touches (the first point of a sub-path); where a segment arrives in the same drag, that segment’s own handle is the mirror.

readonly vertexId: VectorVertexId源码
readonly mirrored: boolean源码

interface PenSegmentShape

源码
readonly id: VectorSegmentId源码
readonly start: VectorVertexId源码
readonly end: VectorVertexId源码
readonly startHandleId: VectorHandleId源码
readonly endHandleId: VectorHandleId源码
readonly outgoing: PenOutgoingHandle | null源码

The handle remembered at the start point, or null when the point has none.

readonly drag: PenHandleOffset | null源码

How far the pointer was dragged from the end point, or null for a plain click. The pointer holds the handle that leaves the end point, so the segment arrives along its mirror.

function placeVectorVerticesOnAxis( network: VectorNetwork, localToParent: TransformMatrix, vertexIds: readonly VectorVertexId[], axis: "x" | "y", value: number ): VectorNetwork

源码

Places every given anchor at value on one parent-space axis, keeping its other coordinate, as typing into the X or Y field does with points selected.

function pointInVectorLasso(outline: readonly Point[], point: Point): boolean

源码

Whether point lies inside the closed outline through outline (the last point joins the first). A point on the outline counts as inside. An outline that crosses itself encloses everything it winds around (the nonzero rule), so no pocket of a looping drag is left out.

function pointInVectorPolygons( polygons: readonly (readonly Point[])[], windingRule: VectorRegion["windingRule"], point: Point ): boolean

源码

Whether a point is inside polygons filled with the given winding rule.

function prepareVectorSegmentBend( network: VectorNetwork, segmentId: VectorSegmentId, t: number, ids: VectorEditIdAllocator ): VectorPreparedSegmentBend

源码

Turns the segment under the pointer into a cubic without changing the shape: a line gets handles a third of the way along, and an arc becomes cubic pieces, of which the one at t is kept with its own position.

function prepareVectorVertexHandles( network: VectorNetwork, vertexId: VectorVertexId, ids: VectorEditIdAllocator ): VectorPreparedVertex

源码

Turns the segments at a vertex into cubics without changing the shape: a line gets two zero handles, and an arc becomes its cubic pieces.

const reboundVectorScenarioViewport: ViewportState

源码

function resetRichTextEditStats(): void

源码

function resolvedComponentLayersOf( document: DesignDocument, componentId: ComponentId ): ReadonlyMap<NodeId, ResolvedLayer> | undefined

源码

The layers of a component’s own view (resolveComponent: the component with every property at its default), by their stored IDs. undefined when the component cannot be resolved (a nesting cycle, a missing nested component); it is drawn from its stored nodes then.

The component is resolved once and its layers are listed once, however many of its layers are asked for: the resolved view comes from this module’s cache, which gives the same view again for a later document whose component, theme and assets are unchanged.

function resolvedInstanceOf( document: DesignDocument, instanceId: NodeId ): ResolvedInstance | undefined

源码

The resolved tree of an instance, or undefined when instanceId is not an instance or fails to resolve.

function resolvedLayerOf( document: DesignDocument, id: NodeId ): ResolvedLayer | undefined

源码

The resolved layer an ID names: the root layer for an instance ID, the layer for a virtual ID, undefined for any other stored ID or an ID that does not resolve.

const richTextEditStats: { runTextConcats: number; formattingKeySorts: number }

源码

function scopedSelectionTarget( document: DesignDocument, rootId: NodeId, scopeId: NodeId | null, nodeId: NodeId | null ): NodeId | null

源码

What a selection rule’s answer becomes on a canvas that selects only within one layer, the scope: the isolation split’s page pane selects the opened instance and the layers inside it (components design 5.5), at any depth of nesting. The rules above answer from the page root, so their answer is brought into the scope here:

  • the scope layer, or a layer inside it, is itself;
  • a container the scope layer is inside (the instance or frame around a nested instance) stands for the scope layer, as a click on a layer of a closed group selects the group: the scope is as far out as it reaches;
  • any other layer is outside the scope, and the answer is null.

With no scope (null) every answer is itself.

function scopedSelectionTargets( document: DesignDocument, rootId: NodeId, scopeId: NodeId | null, nodeIds: readonly NodeId[] ): readonly NodeId[]

源码

scopedSelectionTarget for several answers: each layer once, in order, the ones outside the scope left out.

function selectAllVectorVertices(network: VectorNetwork): VectorEditingSelection

源码

Selects every anchor of the network, as Cmd+A does in Figma’s vector edit mode.

function setVectorVertexMirroring( network: VectorNetwork, vertexIds: readonly VectorVertexId[], mirroring: VectorMirroring, ids: VectorEditIdAllocator ): VectorNetwork

源码

Sets the mirroring of the given points. A mirrored mode snaps at once: the longer handle stays and the other turns to face it (and, mirroring length, takes its length). A point with no handles yet becomes smooth. Points that cannot mirror are skipped.

function smoothVectorVertex( network: VectorNetwork, vertexId: VectorVertexId, ids: VectorEditIdAllocator, mode: VectorTangentConstraint["mode"] = "angle-and-length" ): VectorNetwork

源码

Makes a corner point smooth: its two handles lie along the line between its two neighbours, each a third of the shorter neighbouring segment long, and mirror each other with mode. Only a point joining exactly two segment ends can be smooth; any other is returned unchanged.

function snapPenOffsetToAngle(offset: PenHandleOffset): PenHandleOffset

源码

Snaps an offset to the nearest of the eight directions that are multiples of 45 degrees: the result is the point of that direction’s line nearest to the offset, so it stays as close to the pointer as the direction allows. Horizontal and vertical results have an exact zero in the other axis, and diagonal results have equal lengths in both. A zero offset stays zero.

The offset is in the axes the angle is measured in. For the Pen these are the canvas axes (snapPenPointToAngle), whatever the layer’s own rotation.

function snapPenPointToAngle( anchor: Point, point: Point, localToCanvas: TransformMatrix ): Point

源码

Moves point so that the line from anchor to it runs at a multiple of 45 degrees in canvas axes. Both points are in the path’s local units; localToCanvas maps those to the canvas (the document or the screen: the two differ only by zoom and scroll, which keep angles). A rotated, flipped or nested layer is therefore snapped as the user sees it, not along its own axes.

The transform is inverted by the rule vector edit mode opens a path with (invertVectorTransform), so every transform the mode accepts snaps here, however small or large its scale. Throws RangeError for a transform that rule refuses, which opens no vector edit mode.

point is returned as it is when the snapped place cannot be stored as numbers: the offset is too large or too small on the canvas to have a direction, or the result leaves the number range. This is the rule a nudge or a typed position follows on such a path (updateFiniteVertices).

function splitCubic(controls: Cubic, t: number): readonly [Cubic, Cubic]

源码

Splits a cubic at t with de Casteljau’s construction; both halves trace it exactly.

const standardAccessibilityEditorDriverCodeV1: "const shared = 1;"

源码

const standardAccessibilityEditorDriverIdsV1: Readonly< { document: DocumentId; replacementDocument: DocumentId; page: PageId; root: NodeId; text: NodeId; code: NodeId; shape: NodeId; } >

源码

共享的 EditorDriver 无障碍验收场景所使用的稳定 ID。

const standardAccessibilityEditorDriverTextV1: "Shared accessibility text"

源码

const standardAccessibilityScenarioIdsV1: Readonly< { frame: NodeId; text: NodeId; code: NodeId; image: NodeId; shape: NodeId; hidden: NodeId; clipped: NodeId; transparent: NodeId; lockedGroup: NodeId; lockedChild: NodeId; imageAsset: AssetId; } >

源码

type StandardEditorScenarioDocument = | "blank" | "text-blank" | "rectangle" | "nested" | "snapping" | "aspect-resize" | "rotation" | "connector" | "group-scale" | "auto-layout" | "hit-order" | "hit-policy" | "rich-text"

源码

const standardEditorScenarioIds: { readonly document: DocumentId; readonly page: PageId; readonly root: NodeId; readonly rectangle: NodeId; readonly target: NodeId; readonly container: NodeId; readonly child: NodeId; readonly connector: NodeId; readonly autoLayout: NodeId; readonly autoFirst: NodeId; readonly autoSecond: NodeId; readonly back: NodeId; readonly front: NodeId; readonly locked: NodeId; readonly hidden: NodeId; readonly text: NodeId; }

源码

const standardEditorScenarioViewport: ViewportState

源码

SVG 驱动所支持的固定 DPR 子集。

const standardRichTextFontAssetIds: { readonly latin: AssetId; readonly hebrew: AssetId; readonly japanese: AssetId; readonly korean: AssetId; readonly emoji: AssetId; }

源码

const standardRichTextSamples: { readonly emojiFamily: "👨‍👩‍👧‍👦"; readonly combiningAcute: "é"; readonly deadKeyComposed: "é"; readonly hebrew: "אבג"; readonly bidi: "abc אבג"; readonly japanese: "日本語"; readonly korean: "한글"; readonly listMarker: "・"; }

源码

type StandardVectorBooleanScenarioDocument = | "editable" | "explicit-primary-fill" | "three-paths" | "non-path" | "locked-secondary" | "disjoint" | "text-editing"

源码

const standardVectorBooleanScenarioIds: { readonly primary: NodeId; readonly secondary: NodeId; readonly third: NodeId; readonly nonPath: NodeId; }

源码

const standardVectorBooleanScenarioViewport: ViewportState

源码

type StandardVectorScenarioDocument = "editable" | "covered"

源码

const standardVectorScenarioIds: { readonly pathA: NodeId; readonly pathB: NodeId; readonly cover: NodeId; readonly a0: VectorVertexId; readonly a1: VectorVertexId; readonly a2: VectorVertexId; readonly a3: VectorVertexId; readonly aStartHandle: VectorHandleId; readonly aEndHandle: VectorHandleId; readonly a0a1: VectorSegmentId; readonly a1a2: VectorSegmentId; readonly a2a3: VectorSegmentId; readonly a3a0: VectorSegmentId; readonly aRegion: VectorRegionId; readonly b0: VectorVertexId; readonly b1: VectorVertexId; readonly b2: VectorVertexId; readonly b0b1: VectorSegmentId; readonly b1b2: VectorSegmentId; readonly b2b0: VectorSegmentId; readonly bRegion: VectorRegionId; }

源码

const standardVectorScenarioViewport: ViewportState

源码

function startCountingVectorWork(): void

源码

Starts a count of comparisons at zero. For tests only.

function startVectorSubPath( network: VectorNetwork, position: Point, vertexId: VectorVertexId ): VectorNetwork

源码

Starts a new, separate sub-path in the network: one point at position that no segment touches yet. This is what a Pen click on empty canvas does in vector edit mode when no point is armed to draw from. The caller arms the new point, so the next click draws the first segment of the sub-path, which stays part of the same layer.

function stopCountingVectorWork(): number

源码

Ends the count a test started and returns it; the checks count nothing again. For tests only.

function storeClosedLoopRegions( before: VectorNetwork, after: VectorNetwork, regionId: () => VectorRegionId ): VectorNetwork

源码

Stores regions for the faces (findVectorFaces) an edit has just made: the faces of after that before did not have.

  • A face in space that was open before, or lying apart inside a face that is still there, gets a new region that takes the layer’s fills, so an enclosed area fills as soon as the layer has a fill, as in Figma, and on a layer without fills it paints nothing.
  • Faces that divide a face before had take over that face’s region: the region is replaced, at its place in the order, by one region per new face with the same fills (its own, the layer’s, or none) and winding rule. The first keeps the region’s ID. When the divided face had no region nothing is stored, and Paint offers the new faces.

Faces that were there before the edit with no region (paths saved before closing made regions) are left as they are, and so is every region that is not stored for a single face (several loops, or an open chain closed for filling).

In a part whose segments cross, a loop can fill several areas and lie over other loops, so its name alone does not say that it is new. There, an edit never changes what an area showed before it:

  • A loop gets a new region only when no area it fills could be filled before: none lay in a face before had, and none is in a stored region. A loop that reaches both a new area and one the user already had (a long diagonal across a ladder of cells, a segment across a filled loop) gets none, and neither does a second new loop that lies over the first. Paint offers what is left without a region (findUnstoredVectorFaces).
  • Loops take over a region only when together they fill exactly what the region filled, each area once. Otherwise the region stays on its loop, which still fills what it filled.

function toggleVectorRegionFill( network: VectorNetwork, regionId: VectorRegionId ): VectorNetwork

源码

Switches a region between filled and not filled. A filled region (one that takes the layer’s fills, or has its own) becomes fills: []; a region that is not filled goes back to taking the layer’s fills.

function toggleVectorVertexSmooth( network: VectorNetwork, vertexId: VectorVertexId, ids: VectorEditIdAllocator ): VectorNetwork

源码

A Bend click on a point: a point with handles becomes a corner, a corner becomes smooth.

function transformVector(transform: TransformMatrix, vector: Point): Point

源码

Maps a direction through the linear part of an affine transform (no translation).

function transformVectorVertices( network: VectorNetwork, vertexIds: readonly VectorVertexId[], matrix: TransformMatrix ): VectorNetwork

源码

Moves the given points through matrix (network coordinates) and carries the rest of the geometry that lives in the same coordinates:

  • A Bézier handle attached to a moved point is turned and scaled by the matrix’s linear part, so the curve keeps its shape relative to its point. A handle pair that mirrored before still mirrors: a linear map keeps opposite offsets opposite and equal lengths equal.
  • An elliptical arc with both end points moved is mapped exactly (see transformEllipticalArc). With one end point moved it keeps its radii, rotation and flags and is drawn again between its end points, which is what dragging or nudging that point does.
  • A point’s corner radius stays as it is, as it does when the whole layer is resized (scaleVectorNetwork).

Returns the network unchanged for the identity, and when a result would leave the representable number range.

const VECTOR_HIT_TOLERANCE_CSS_PX: 6

源码

How far, in CSS pixels, a point, handle or segment of the open path reaches. Every hit test against the open path uses it, so hover and press agree.

const VECTOR_POINT_BOX_HANDLE_REACH: 10

源码

How far from a handle’s centre a press still takes it, in box units (CSS pixels). It is more than the 6 pixels a point is grabbed within, so a handle with a point right under it (a corner of the box often is one of the selected points) can still be taken from just beside the point.

const VECTOR_POINT_BOX_ROTATE_REACH: 26

源码

How far outside a corner a press still rotates, in box units (CSS pixels).

interface VectorArcConversion

源码

The result of turning an elliptical arc into cubic pieces.

readonly network: VectorNetwork源码
readonly segmentIds: readonly VectorSegmentId[]源码

The pieces in order from the arc’s start to its end; the first keeps the arc’s ID.

interface VectorArea

源码

One area a network encloses, with every crossing treated as a corner.

readonly outline: readonly Point[]源码

The boundary as a closed polygon in network coordinates, curves flattened.

readonly area: number源码

type VectorBendGesture = & { readonly threshold: number; readonly moved: boolean; readonly ids: VectorEditIdAllocator; } & ( | { readonly kind: "vertex"; readonly vertexId: VectorVertexId; readonly prepared: VectorPreparedVertex; readonly heldEnd: number | null; } | { readonly kind: "segment"; readonly prepared: VectorPreparedSegmentBend; })

源码

A Bend drag from a point or on a segment. Until the pointer has moved threshold (network units, or the gesture’s distanceSpace) it is a click: on a point, that toggles the point between corner and smooth when the press ends.

function vectorBendHeldEnd( prepared: VectorPreparedVertex, vertexId: VectorVertexId, drag: Point, distanceSpace?: TransformMatrix ): number

源码

Which segment end a drag from a point holds: the one whose segment leads most nearly the way the pointer went. The other end’s handle mirrors it.

Both directions are compared as distanceSpace draws them (see vectorDistance): pass the path’s local-to-screen matrix so the choice matches what the user sees when the path is stretched unevenly or skewed.

interface VectorCrossing

源码

One place where two segments of a network meet away from a point they share.

readonly point: Point源码

Where, in network coordinates.

readonly first: { readonly segmentId: VectorSegment["id"]; readonly at: number }源码

The two segments and how far along each the place is: 0 at the segment’s start, 1 at its end. A segment that crosses itself is named twice.

readonly second: { readonly segmentId: VectorSegment["id"]; readonly at: number; }源码

interface VectorCut

源码

The cut network and the points left where the cut was made.

readonly network: VectorNetwork源码
readonly vertexIds: readonly VectorVertexId[]源码

type VectorCutLineCrossing = | { readonly kind: "segment"; readonly segmentId: VectorSegmentId; readonly t: number; } | { readonly kind: "vertex"; readonly vertexId: VectorVertexId }

源码

One place the cut line crosses the network.

function vectorCutLineCrossings( network: VectorNetwork, from: Point, to: Point ): readonly VectorCutLineCrossing[]

源码

Every place the straight line from from to to (network coordinates) crosses the network: positions inside segments (see VectorSegmentPoint.t), and the points it passes through, each listed once.

interface VectorEditIdAllocator

源码

Supplies fresh, unused IDs for the parts an edit creates.

readonly vertexId: () => VectorVertexId源码
readonly segmentId: () => VectorSegmentId源码
readonly handleId: () => VectorHandleId源码

function vectorEditTargetVertexIds( network: VectorNetwork, selection: VectorEditingSelection ): readonly VectorVertexId[]

源码

Anchors moved by a nudge or a position edit: selected anchors and the ends of selected segments.

interface VectorEditToolContext

源码
readonly tool: "pen" | "bend" | "cut"源码
readonly ids: VectorEditIdAllocator源码
readonly regionId?: () => VectorRegionId源码

Names a region the Pen stores when a click connects the path in progress to a segment and that encloses or divides an area. Without it such a click only adds the point.

function vectorFillsShow(fills: readonly Paint[] | undefined): boolean

源码

Whether a list of fills would put pixels on screen: one of its paints shows (vectorPaintShows). The one test behind every Paint decision: a region’s own fills, the layer’s fills, the cursor and the hover stripes.

function vectorHatchLines( polygons: readonly (readonly Point[])[], windingRule: VectorRegion["windingRule"], spacing: number, maximumLines = 400 ): readonly (readonly [Point, Point])[]

源码

Diagonal stripes over the inside of polygons, for marking a hovered region: straight pieces running up to the right, spacing apart, clipped to the area the winding rule fills. In whatever space the polygons are in (pass screen coordinates for stripes that are even on screen). When the area would take more than maximumLines stripes they are spread wider.

type VectorHealIdAllocator = () => VectorHealSegmentIds

源码

Supplies fresh, unused IDs for each edge the heal creates.

interface VectorHealSegmentIds

源码

Delete and heal for vector networks, after Figma’s “Delete and Heal” (https://www.figma.com/blog/delete-and-heal-for-vector-networks/): removing an anchor joins its neighbours instead of leaving a gap.

  • An anchor with an odd number of edges loses all of them, as a plain delete.
  • An anchor with an even number of edges has them sorted by angle, and each edge is paired with its opposite; every pair becomes one new edge between the two far ends. A pair whose far ends are the same anchor is removed.
  • The new edge’s curve is fitted to the two old edges with fixed end tangents (one pass of Schneider’s least-squares fit), so the shape keeps its course. Elliptical arcs are fitted against their true curve, as cubic pieces.
  • A kept outer handle whose length the fit changed loses the length part of an angle-and-length constraint, as splitting a segment does.
  • Fill loops that ran through the anchor along a healed pair are rewired to the new edge; loops that ran through any other way are removed.
readonly segmentId: VectorSegmentId源码
readonly startHandleId: VectorHandleId源码
readonly endHandleId: VectorHandleId源码

function vectorInteractionPointBox( state: VectorInteractionState ): VectorPointBox | null

源码

The box around the selected points, upright on screen, or null when fewer than two points are selected or they share one place.

function vectorLassoContents( network: VectorNetwork, localToScreen: TransformMatrix, outline: readonly Point[] ): VectorLassoContents

源码

The points inside a lasso drawn on screen, and the segments whose two end points are both inside. localToScreen maps the network to the space the outline was drawn in.

interface VectorLassoContents

源码

The points and segments a lasso outline takes in.

readonly vertexIds: readonly VectorVertexId[]源码
readonly segmentIds: readonly VectorSegmentId[]源码

type VectorLassoMode = "replace" | "add" | "subtract"

源码

How a lasso changes the selection that was there before the drag.

type VectorMirroring = "none" | VectorTangentConstraint["mode"]

源码

Figma’s handle mirroring setting for a point (“No mirroring”, “Mirror angle”, “Mirror angle and length”; VectorVertex.handleMirroring in its plugin API). Our model keeps it as a tangent constraint pairing the two handles at the point, so the setting reads and writes that pair.

interface VectorPaintResult

源码

What a Paint click changes: the network, and whether the layer itself must be given a fill.

readonly network: VectorNetwork源码
readonly layerNeedsFill: boolean源码

The click fills a target on a layer that shows no fill. The target takes the layer’s fills, so the caller adds a fill that shows to the layer’s own fills, in the same undo step as the network.

function vectorPaintShows(paint: Paint): boolean

源码

Whether one paint would put pixels on screen: it is not hidden, its opacity is above zero, and what it paints is not fully transparent.

  • A solid paint needs a colour with some alpha.
  • A gradient needs at least one stop with some alpha.
  • An image paint counts whenever it is not hidden and has opacity. Its pixels are not looked at, and an asset that is missing is not a paint that shows nothing: the renderer refuses the document (MEDIA_ASSET_REQUIRED).

Blend modes are not looked at: none of them paints nothing by itself; what one shows depends on what lies under it. The layer’s own opacity and visibility are not looked at either, see VectorPaintFillRule.

type VectorPaintTarget = | { readonly kind: "region"; readonly region: VectorRegion } | { readonly kind: "loop"; readonly loop: VectorRegionLoop }

源码

What a Paint click acts on: a stored region, or a face (findVectorFaces) that has none yet.

function vectorPaintTargetAtPoint( network: VectorNetwork, point: Point ): VectorPaintTarget | null

源码

What a Paint click at point (network coordinates) acts on, or null when the point is in no paintable area. Of several areas holding the point, the smallest is taken, so a loop inside another is reached by pointing inside it; of equal ones, the frontmost.

function vectorPaintTargetKey(target: VectorPaintTarget): string

源码

A name for a paint target that lasts while the network keeps its IDs.

function vectorPaintTargets( network: VectorNetwork ): readonly VectorPaintTarget[]

源码

Every paint target of a network: its regions from back to front, then its faces without a region.

function vectorPaintTargetShape( target: VectorPaintTarget ): Pick<VectorRegion, "loops" | "windingRule">

源码

The loops and winding rule a paint target fills with.

function vectorPaintTargetShowsFill( target: VectorPaintTarget, layerShowsFill: boolean ): boolean

源码

Whether a paint target shows a fill on screen now. A region that takes the layer’s fills shows one only when the layer has one; a region with fills of its own when one of them shows (vectorFillsShow); a loop without a region never.

function vectorPointBox( network: VectorNetwork, vertexIds: readonly VectorVertexId[], localToBox: TransformMatrix ): VectorPointBox | null

源码

The box around the given points, or null when fewer than two of them exist or they all sit at one place. A box with no width offers only its top and bottom handles, and one with no height only its left and right handles; either still rotates from its two ends.

interface VectorPointBox

源码
readonly vertexIds: readonly VectorVertexId[]源码

The selected points the box surrounds, in network order.

readonly bounds: Rect源码

The box in box space. Its width or its height may be zero, not both.

readonly resizeHandles: readonly { readonly handle: VectorPointBoxHandle; readonly center: Point; }[]源码

The handles on offer: all eight, or the two that scale a box with no width or no height.

readonly rotateCorners: readonly { readonly corner: VectorPointBoxCorner; readonly center: Point; }[]源码

The corners with a rotate zone outside them: four, or the two ends of a flat box.

type VectorPointBoxCorner = "nw" | "ne" | "se" | "sw"

源码

A corner of the box that points can be rotated from.

interface VectorPointBoxGesture

源码

A drag of a handle or rotate zone of the box around the selected points. The box is fixed as the press found it; transform is what the drag applies to it so far, in the box’s own space.

readonly box: VectorPointBox源码
readonly hit: VectorPointBoxHit源码
readonly localToBox: TransformMatrix源码

From network coordinates to the box’s space (the screen), and back.

readonly boxToLocal: TransformMatrix源码
readonly modifiers: VectorPointTransformModifiers源码
readonly transform: TransformMatrix源码

type VectorPointBoxHandle = "nw" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w"

源码

A resize handle, named by the compass side of the box it sits on.

type VectorPointBoxHit = | { readonly kind: "resize"; readonly handle: VectorPointBoxHandle } | { readonly kind: "rotate"; readonly corner: VectorPointBoxCorner }

源码

function vectorPointBoxHitDirection( box: VectorPointBox, hit: VectorPointBoxHit ): number

源码

The direction a handle’s cursor runs along (resize) or faces (rotate), in degrees clockwise from the positive x axis of box space.

function vectorPointBoxLocalTransform( boxTransform: TransformMatrix, localToBox: TransformMatrix, boxToLocal: TransformMatrix ): TransformMatrix

源码

The network-space matrix for a box-space one: into the box’s space, through the matrix, and back. An unchanged box gives exactly the identity.

function vectorPointBoxPress( state: VectorInteractionState, screenPoint: Point, part: VectorComponentHit["part"] | null ): VectorPointBoxPress | null

源码

What a press at screenPoint takes of the box around the selected points, given the part of the path under the press (part, null for none).

Points and Bézier handles stay grabbable: a press within reach of one takes it, not the box. A resize handle wins over a segment under it. A rotate zone, which lies outside the box, gives way to any part of the path.

interface VectorPointBoxPress

源码

A press on the box around the selected points: the box and the part pressed.

readonly box: VectorPointBox源码
readonly hit: VectorPointBoxHit源码

function vectorPointBoxTransform( box: Pick<VectorPointBox, "bounds">, hit: VectorPointBoxHit, start: Point, current: Point, modifiers: VectorPointTransformModifiers ): TransformMatrix

源码

The box-space matrix a drag of hit from start to current applies.

A resize scales about the opposite handle, or about the box’s centre with Alt. With Shift it keeps the proportions: a corner uses the larger of its two factors for both axes, and an edge scales the other axis by the same factor about that axis’s middle. An axis the box has no extent on is never scaled. A rotate turns about the box’s centre by the angle the pointer has swept around it, in 15 degree steps with Shift.

interface VectorPointInsertion

源码

Where a point went in: the vertex now at that place.

readonly network: VectorNetwork源码
readonly vertexId: VectorVertexId源码

interface VectorPointTransformModifiers

源码

The modifier keys a point box drag reads.

readonly shift: boolean源码
readonly alt: boolean源码

interface VectorPreparedSegmentBend

源码

A segment ready to bend: a cubic, and where on it the pointer took hold.

readonly network: VectorNetwork源码
readonly segmentId: VectorSegmentId源码
readonly t: number源码

interface VectorPreparedVertex

源码

A network whose segments at a vertex are all cubics, ready for handle edits.

readonly network: VectorNetwork源码
readonly ends: readonly VectorVertexHandleEnd[]源码

function vectorRegionAtPoint( network: VectorNetwork, point: Point ): VectorRegion | null

源码

The region whose area holds point (network coordinates): the frontmost one, since regions paint from back to front. Null outside every region.

function vectorRegionIsFilled(region: VectorRegion): boolean

源码

Whether a region paints: it takes the layer’s fills, or has fills of its own.

function vectorRegionOutlines( network: VectorNetwork, region: Pick<VectorRegion, "loops"> ): readonly (readonly Point[])[]

源码

A region’s loops as closed polygons in network coordinates, with curves flattened. A loop that fills as an open chain closes straight back to its start, as the renderer fills it.

function vectorSegmentCubics( network: VectorNetwork, segment: VectorSegment ): readonly Cubic[]

源码

The segment as cubic pieces from its start to its end: one piece for a line or cubic, up to four for an elliptical arc (one quarter turn each).

interface VectorSegmentPoint

源码

Where on a segment a point is nearest.

readonly t: number源码

Position along the segment, 0 at its start and 1 at its end. For an arc it runs evenly over its cubic pieces: piece i of n covers [i / n, (i + 1) / n].

readonly point: Point源码
readonly distance: number源码

In network units, or in the units of the space the search measured in.

interface VectorVertexHandleEnd

源码

One segment end at a vertex, and where its segment leads.

readonly segmentId: VectorSegmentId源码
readonly endpoint: "startHandle" | "endHandle"源码
readonly handleId: VectorHandleId源码
readonly far: VectorVertexId源码

The vertex at the other end of the segment.

function vectorVertexHasHandles( network: VectorNetwork, vertexId: VectorVertexId ): boolean

源码

True when any segment end at the vertex has a handle of non-zero length.

function vectorVertexIdsInScreenRect( network: VectorNetwork, localToScreen: TransformMatrix, rect: Rect ): readonly VectorVertexId[]

源码

The anchors whose screen position lies inside rect (edges included).

function vectorVertexIsUnconnected( network: VectorNetwork, vertexId: VectorVertexId ): boolean

源码

Whether no segment starts or ends at the point. False for a point the network does not have.

function vectorVertexMirroring( network: VectorNetwork, vertexId: VectorVertexId ): VectorMirroring | null

源码

A point’s mirroring, or null when it has none to set: only a point joining exactly two segment ends has a pair of handles to mirror.

function vectorVertexParentPositions( network: VectorNetwork, localToParent: TransformMatrix, vertexIds: readonly VectorVertexId[] ): readonly Point[]

源码

The parent-space positions of the given anchors, in network order.

function vectorVertexSelection( network: VectorNetwork, vertexIds: Iterable<VectorVertexId>, primary?: VectorVertexId ): VectorEditingSelection

源码

A selection of anchors only, in network order, with the last one primary.

@taco-slides/render-core TypeScript

270 个导出中已记录 196 个 · 大纲

@taco-slides/render-core 是 Kimi Design 渲染器的 TypeScript 部分。它把 DesignDocument 的一个页面转换为保留场景:由渲染器在帧与帧之间保留的一组节点、Paint 和字体。首个页面之后,每次文档改动都会变成一个小的变更批次,只更新发生变化的节点。

渲染器本身是基于 Skia 的 C++ 代码,编译为 WebAssembly(Wasm)。TypeScript 与 C++ 共享两份契约。第一份是变更批次的小端序字节格式,由 RenderChangeBatchEncoder 写入,并在 PROTOCOL.md 中描述。第二份是稳定的 C ABI(render_core.h 中的 taco_render_* 函数),由 PortableWasmRenderCoreSession 调用。该会话把每个输入复制到 Wasm 内存中,调用一个 C 函数,严格检查结果并把它复制回来,因此不会有 Wasm 内存泄露给调用方。

编辑器并不直接使用该会话。它与 InteractiveRenderSessionCoordinator 通信;后者持有文档,用 ActivePageCompilerSession 编译当前页面,并驱动一个由 Web 应用基于 WebGPU 实现的保留后端。

标记为 Native 的条目链接到它们最终调用的 C 函数,C++ 条目也会反向链接回来。类型或常量上的 Native 链接表示 C 端读写相同的字节或值,而不是一次调用。

当前版本

TypeScript 与 C++ 共享的字节格式,以及两端当前使用的版本号,在构建本页时从源码读取。如果 TypeScript 与 C++ 的值不一致,构建会失败。

场景 wire 格式24RENDER_CORE_WIRE_VERSION 与 TACO_RENDER_WIRE_VERSION;参见wire 格式历史
矢量网络 wire 格式5RENDER_CORE_VECTOR_NETWORK_WIRE_VERSION 与 TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION
画布叠加层字节布局4encodeCanvasOverlay 写入的版本,由 taco_render_session_set_canvas_overlay 读取

交互会话

InteractiveRenderSessionCoordinator 是编辑器眼中的渲染器。它保存一份文档和一个当前页面,逐个执行改动,并针对最近一次提交的场景回答几何、命中和文本查询。底层工作交给 InteractiveRetainedBackend 完成。对于渲染器通过另一个节点绘制的节点(例如作为文本节点绘制的代码块),其上的文本编辑叠加层(光标、选区和输入法组合)绘制在那个节点上,因此代码块可以像文本一样就地编辑。

class InteractiveRenderSessionCoordinator implements InteractiveRenderSession

源码

与后端无关的所有者,持有一个规范文档和一个保留的活动页面。变更按顺序串行执行;同步查询只能观察到已提交的状态。

编辑器通过 InteractiveRenderSession 接口与此类交互。它用 ActivePageCompilerSession 编译活动页面,把变更批次发送给 InteractiveRetainedBackend,并将渲染器结果映射回文档节点 ID。

变更方法(loadDocument、applyDocumentUpdate、setActivePage、setViewport、setOverlays、renderFrame)按调用顺序逐个执行。变更失败时,之前的已提交状态保持不变。有变更待处理时,同步查询会抛出 InteractiveRenderSessionBusyError;请先 await whenQueryable。调用 dispose 之后,查询和变更都会抛出 InteractiveRenderSessionDisposedError。

new (options: InteractiveRenderSessionCoordinatorOptions)源码

创建一个尚未加载文档的协调器。

async whenQueryable(): Promise<void>源码

等待排队中的变更以及任何后端特有的同步查询屏障完成。

async exportDocument( document: DesignDocument, pageId: PageId, options: RenderDocumentExportOptions ): Promise<RenderExportResult>源码

使用此协调器已持有的资源,对 document 进行冷编译,并导出一个页面或其中的一个节点。请传入渲染器文档本身,不要包含外围的编辑器工作区。视频节点会被排除:一次性的导出会话没有解码后的视频帧。

async outlineDocumentStrokes( document: DesignDocument, pageId: PageId, strokes: readonly StrokeOutlineRequest[], budget?: StrokeOutlineBudget, now: () => number = () => performance.now() ): Promise<readonly StrokeOutlineResult[]>源码

Outlines strokes of layers on one page of a document: each requested stroke as a vector network of the area it paints, in its node’s local coordinates (see RenderStrokeOutlineSnapshot). The page is compiled apart from the live scene with the resources this coordinator already holds and outlined in a throwaway session, so the result is the stroke the document describes, whatever the canvas is showing. Pass the renderer document without any editor workspace around it. There is one answer per request, in order; a stroke that cannot be outlined is answered with the reason (see StrokeOutlineResult). A budget is shared by every call of one command: the outline that would take the command past its bytes rejects the call with StrokeOutlineBudgetError, a step that would start after its time is used up rejects it with StrokeOutlineTimeError, and no answer of the call is kept.

Compiling the page is the first step, and it runs on the calling thread like the others: with no time left it is not started, and the time it takes (measured with now, in milliseconds) is counted down in the budget. A compile cannot be interrupted, so one that takes longer than the time left runs to its end; the call is then rejected with StrokeOutlineTimeError and the backend is not asked, so no outlining is added to it.

async loadDocument(load: RenderDocumentLoad): Promise<void>源码

替换整个文档。如果新文档中仍有当前活动页面,则保留该页面;否则场景会被清空,直到 setActivePage 选定一个页面。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

async applyDocumentUpdate(update: DocumentSceneUpdate): Promise<void>源码

应用一次已提交的文档变更。该更新必须以此协调器持有的文档和提交为起点,否则会被以 InteractiveRenderTransitionError 拒绝。活动页面在可能时以增量批次发送,否则整体重新加载。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

async setActivePage(pageId: PageId | null): Promise<void>源码

编译并显示另一个页面;传入 null 时显示空场景。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.apply: taco_render_session_apply

async setViewport(viewport: ViewportState): Promise<void>源码

将新的视口(平移、缩放、画布尺寸)传给后端。

hitTest(screenPoint: Point): readonly EditorHit[]源码

在屏幕上某点执行命中测试:先检查叠加层的命中区域,再检查可选中的文档节点,结果按最上层优先排列。

原生,经由 InteractiveRetainedBackend.hitTest: taco_render_session_hit_test

hitTestIncludingLocked(screenPoint: Point): readonly EditorHit[]源码

The layers painted at a screen point, topmost first, with the layers hitTest leaves out because a click cannot select them: a locked layer and the layers inside one. Overlay hit regions are not included. The canvas menu’s “Select layer” lists from these hits, since it is how a locked layer is selected on the canvas.

原生,经由 InteractiveRetainedBackend.hitTest: taco_render_session_hit_test

getNodeGeometry(nodeId: NodeId): NodeGeometry | null源码

某个文档节点的已提交几何信息;若该节点不在场景中,则为 null。

原生,经由 InteractiveRetainedBackend.getNodeGeometry: taco_render_session_get_node_geometry

getSceneInfo(): RenderSceneInfo源码

后端的场景尺寸、计数和代次。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getSceneGeometrySnapshot(): SceneGeometrySnapshot源码

已提交场景中每个节点的几何信息,按从后到前的顺序排列。结果会被缓存,直到代次、视口或文档发生变化。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

原生,经由 InteractiveRetainedBackend.getGeometrySnapshot: taco_render_session_get_geometry_snapshot

getTextGeometry(nodeId: NodeId): TextGeometry | null源码

文本节点的光标和选区几何信息,来自后端的文本布局。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

hitTestText(queryInput: TextHitQuery): TextHitResult | null源码

文本节点中某点下方的文本位置。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

navigateText(queryInput: TextNavigationQuery): TextNavigationResult | null源码

将文本位置移动一个光标步长,例如一个单词或一行。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getTextLayoutMetrics(nodeId: NodeId): InteractiveTextLayoutMetrics | null源码

文本节点的行度量信息和建议的自动尺寸。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getFontMetadata(fontResourceId: string): RenderFontMetadataSnapshot | null源码

某个已加载字体资源的 OpenType 特性和可变字体轴。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getVectorGeometry(nodeId: NodeId): VectorGeometry | null源码

矢量节点的顶点、控制柄、线段和区域。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

hitTestVector(queryInput: VectorHitQuery): VectorHitTestResult | null源码

屏幕上某点下方的矢量顶点、控制柄、线段或区域。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

booleanVectorPaths(request: VectorBooleanPathRequest): VectorBooleanPathResult源码

用布尔运算合并两个节点的路径,并检查结果是否为有效且带命名空间的矢量网络。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

getDocumentRevision(): | { readonly document: DesignDocument; readonly commitId: CommitId } | null源码

会话当前持有的规范文档和提交;加载第一个文档之前为 null。文档刚发生改动时,应用可能比会话领先一个版本;调用方可以把它与自己的版本比较,以便等待会话跟上,而不是去询问会话尚未拥有的节点。

createAccessibilityBindingV1( overlay: AccessibilityOverlayStateV1 ): InteractiveAccessibilityBindingV1 | null源码

根据 TypeScript 拥有的规范状态和以原生端为准的几何信息,创建 v1 语义镜像。不会使用任何后端无障碍查询。

resolveAccessibilityActionRouteV1( binding: InteractiveAccessibilityBindingV1, request: AccessibilityActionRequestV1 ): InteractiveAccessibilityActionRouteV1源码

将语义操作解析为一个封闭的 UI 命令,不调用回调,也不改变规范状态、选区、焦点或渲染器状态。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

async setOverlays(overlays: EditorOverlayState): Promise<void>源码

替换编辑叠加层:选区框与控制柄、画布叠加层,以及文本或矢量编辑叠加层。之后任何使代次递增的场景变更都会清除它们。

原生,经由 InteractiveRetainedBackend.setOverlays: taco_render_session_set_text_editing_overlay, taco_render_session_clear_text_editing_overlay, taco_render_session_set_vector_editing_overlay, taco_render_session_clear_vector_editing_overlay, taco_render_session_set_selection_chrome, taco_render_session_set_canvas_overlay

async renderFrame(): Promise<EditorRenderFrameReport>源码

在之前所有变更都完成后绘制一帧。

原生,经由 InteractiveRetainedBackend.getSceneInfo: taco_render_session_get_scene_info

async getAccessibilitySnapshot(): Promise<AccessibilityNodeSnapshot | null>源码

向后端请求当前视口的无障碍树。

dispose(): Promise<void>源码

等待待处理的变更完成,然后释放后端和所有缓存状态。再次调用会返回同一个 promise;失败后可以重试。

interface InteractiveRenderSessionCoordinatorOptions

源码

InteractiveRenderSessionCoordinator 的选项。

readonly backend: InteractiveRetainedBackend源码

持有并绘制场景的保留后端。

readonly viewport: ViewportState源码

初始视口。后端会在第一次叠加层更新或第一帧之前收到它;使用“workspace”策略时,要等到有页面处于活动状态后才会收到。

readonly hitToleranceScreenPx?: number源码

几何主体命中的扩展范围,单位为 CSS 像素。默认为 4。

readonly rendererProjectionPolicy?: "nodes-only" | "workspace"源码

允许编辑器在受保护的页面根节点外围替换为一个更大的工作区根节点。

readonly userLanguage?: string源码

参见 CompilePageOptions.userLanguage。

readonly resolveInstance?: InstanceResolver源码

See CompilePageOptions.resolveInstance; the canvas and export both use it.

interface InteractiveRetainedBackend

源码

高层编辑器协调器使用的底层保留后端。

apply 必须具有事务性:当它抛出异常或 reject 时,其已提交的保留场景和代次保持不变。成功的代次变更会原子地使后端的临时叠加层失效。其他所有异步 setter 同样只在 fulfill 时才发布结果,在 reject 时保持之前的状态不变。几何信息和命中结果使用世界(规范文档)坐标。dispose 可以安全重试。

Web 应用用 WasmInteractiveRetainedBackend 实现它:该实现将保留场景存放在 PortableWasmRenderCoreSession 中,并用 WebGPU 绘制。下方的 Native 行列出了该实现通过会话调用的 C 函数。

readonly capabilities: InteractiveRetainedBackendCapabilities源码

此后端实现了哪些可选方法。

apply(batch: Uint8Array): RenderUpdateReport | Promise<RenderUpdateReport>源码

将一个来自 RenderChangeBatchEncoder 的变更批次应用到保留场景,并报告新的代次。

原生: taco_render_session_apply

applyWithStaticImageFrames?( batch: Uint8Array, imageAssets: readonly ImageAsset[] ): RenderUpdateReport | Promise<RenderUpdateReport>源码

原子地应用一个场景批次,以及候选场景所需的完整静态图片资源集合。被拒绝时,两者都不得发布。

applyWithMediaFrames?( batch: Uint8Array, imageAssets: readonly ImageAsset[], videoAssets: readonly VideoAsset[] ): RenderUpdateReport | Promise<RenderUpdateReport>源码

原子地应用一个场景批次以及两个确切的媒体资源集合。

updatePendingVideoFrames?(): RenderUpdateReport | Promise<RenderUpdateReport>源码

发布由后端拥有的待处理视频节拍(tick),而不改变场景标识。

getSceneInfo(): RenderSceneInfo源码

场景尺寸、计数、代次和摘要。

原生: taco_render_session_get_scene_info

getNodeGeometry(nodeId: string): RenderNodeGeometry | undefined源码

某个保留节点的边界和变换;若场景中没有该节点,则为 undefined。

原生: taco_render_session_get_node_geometry

getGeometrySnapshot(): RenderGeometrySnapshot源码

每个保留节点的几何信息,按从后到前的顺序排列。

原生: taco_render_session_get_geometry_snapshot

hitTest( worldX: number, worldY: number, worldTolerance: number ): readonly RenderHit[]源码

按最上层优先排列的保留主体命中结果。

原生: taco_render_session_hit_test

whenQueryable?(): Promise<void>源码

当同步查询可以安全进入后端运行时时 resolve。

setViewport(viewport: ViewportState): void | Promise<void>源码

为新视口调整渲染目标的尺寸。

setOverlays(overlays: EditorOverlayState): void | Promise<void>源码

替换绘制在场景之上的编辑叠加层:文本或矢量编辑叠加层、选区框与控制柄,以及画布叠加层(吸附线、参考线、测量标注和像素网格)。

原生: taco_render_session_set_text_editing_overlay, taco_render_session_clear_text_editing_overlay, taco_render_session_set_vector_editing_overlay, taco_render_session_clear_vector_editing_overlay, taco_render_session_set_selection_chrome, taco_render_session_set_canvas_overlay

renderFrame(): EditorRenderFrameReport | Promise<EditorRenderFrameReport>源码

为当前视口绘制已提交的场景和叠加层。

getTextGeometry?(nodeId: NodeId, viewport: ViewportState): TextGeometry | null源码

文本节点的光标、选区和输入法组合(composition)几何信息。

原生: taco_render_session_get_text_carets, taco_render_session_get_text_range_rects

hitTestText?(query: TextHitQuery): TextHitResult | null源码

文本节点中某点下方的文本位置。

原生: taco_render_session_hit_test_text

navigateText?(query: TextNavigationQuery): TextNavigationResult | null源码

将文本位置移动一个光标步长,例如一个单词或一行。

原生: taco_render_session_navigate_text

getTextLayoutMetrics?(nodeId: NodeId): RenderTextLayoutMetrics | undefined源码

文本节点的行度量信息和建议的自动尺寸。

原生: taco_render_session_get_text_layout_metrics

getFontMetadata?(fontResourceId: string): RenderFontMetadataSnapshot | undefined源码

某个字体资源的 OpenType 特性和可变字体轴。

原生: taco_render_session_get_font_metadata

getVectorGeometry?( nodeId: NodeId, viewport: ViewportState ): VectorGeometry | null源码

矢量节点的顶点、控制柄、线段和区域。

原生: taco_render_session_get_vector_geometry

hitTestVector?( query: VectorHitQuery, viewport: ViewportState ): VectorHitTestResult | null源码

屏幕上某点下方的矢量顶点、控制柄、线段或区域。

原生: taco_render_session_hit_test_vector

booleanVectorPaths?(request: VectorBooleanPathRequest): VectorBooleanPathResult源码

用布尔运算合并两条矢量路径。

原生: taco_render_session_boolean_vector_paths

exportCompiledScene?( request: RenderCompiledExportRequest ): Promise<RenderExportResult>源码

通过一次性会话导出单独编译的页面,从而使实时场景、其视口及其编辑叠加层都不会进入导出文件。

原生: taco_render_session_create, taco_render_session_apply_with_static_image_frames, taco_render_session_apply, taco_render_session_export

outlineCompiledStrokes?( request: RenderCompiledStrokeOutlineRequest ): Promise<readonly StrokeOutlineResult[]>源码

Outlines strokes of a separately compiled page through a throwaway session: one answer per request, in order. A stroke the renderer cannot outline (the page does not draw its node, the node has no such stroke, the geometry does not resolve) is answered with the reason and does not stop the others.

原生: taco_render_session_create, taco_render_session_apply, taco_render_session_outline_stroke

getAccessibilitySnapshot?( viewport: ViewportState ): AccessibilityNodeSnapshot | null | Promise<AccessibilityNodeSnapshot | null>源码
dispose(): void | Promise<void>源码

释放后端。失败后可以安全地再次调用。

interface InteractiveRetainedBackendCapabilities

源码

某个后端实现了 InteractiveRetainedBackend 中的哪些可选部分。协调器在调用可选方法之前会检查这些标志。

readonly staticImageFrames: boolean源码

原子地提交一个保留场景批次及其确切的已解码静态图片集合。

readonly videoFrames: boolean源码

支持原子地安装混合场景,以及同一代次内的视频节拍。

readonly textGeometry: boolean源码
readonly textHitTesting: boolean源码
readonly textNavigation: boolean源码
readonly textLayoutMetrics: boolean源码
readonly fontMetadata: boolean源码
readonly vectorGeometry: boolean源码
readonly vectorHitTesting: boolean源码
readonly vectorBooleanOperations: boolean源码
readonly accessibility: boolean源码

type InteractiveRenderAdvancedCapability = | "text-geometry" | "text-hit-testing" | "text-navigation" | "text-layout-metrics" | "font-metadata" | "vector-geometry" | "vector-hit-testing" | "vector-boolean-operations" | "accessibility"

源码

保留后端可能不具备的可选查询或功能。当编辑器调用后端不支持的方法时,协调器会以此名称抛出 InteractiveRenderCapabilityError。

interface InteractiveTextLayoutMetrics extends RenderTextLayoutMetrics

源码

单个文本节点的文本布局度量信息,以其文档节点 ID 标识。

readonly nodeId: NodeId源码

type VectorBooleanOperation = | "union" | "intersection" | "difference" | "exclusion"

源码

对两条矢量路径执行的布尔运算。

interface VectorBooleanPathRequest

源码

合并两个节点的路径。结果中每个顶点、线段和区域的 ID 都以 resultIdNamespace 加一个冒号开头。

readonly primaryNodeId: NodeId源码
readonly secondaryNodeId: NodeId源码
readonly operation: VectorBooleanOperation源码
readonly resultIdNamespace: string源码

interface VectorBooleanPathResult

源码

布尔运算针对某个场景代生成的矢量网络。

readonly generation: bigint源码
readonly primaryNodeId: NodeId源码
readonly secondaryNodeId: NodeId源码
readonly operation: VectorBooleanOperation源码
readonly vectorNetwork: VectorNetwork源码

interface StrokeOutlineRequest

源码

One stroke to outline: the node, the stroke’s index in the node’s strokes (VisualStyle.strokes, or 0 for a connector’s one stroke), and the prefix of every ID in the result.

readonly nodeId: NodeId源码
readonly strokeIndex: number源码
readonly resultIdNamespace: string源码

type StrokeOutlineResult = | { readonly outlined: true; readonly vectorNetwork: VectorNetwork } | { readonly outlined: false; readonly reason: string }

源码

The answer to one StrokeOutlineRequest: the stroke as a vector network of the area it paints, in its node’s local coordinates (a network without regions when the stroke paints nothing), or the reason the renderer could not outline it.

interface RenderCompiledStrokeOutlineRequest

源码

A cold page batch and the strokes to outline in it.

readonly batch: Uint8Array源码
readonly strokes: readonly StrokeOutlineRequest[]源码
readonly budget?: StrokeOutlineBudget源码

What the command these strokes belong to may still keep, and how long the renderer may still work on it. Every outline is charged to it as it arrives; the one that does not fit is not decoded and fails the whole request with StrokeOutlineBudgetError. Every step is timed, and none is started once the time is used up: the request then fails with StrokeOutlineTimeError.

class InteractiveRenderCapabilityError extends Error

源码

后端未实现的高级编辑器接口所产生的结构化失败。

readonly capability: InteractiveRenderAdvancedCapability源码
new (capability: InteractiveRenderAdvancedCapability)源码

class InteractiveRenderTransitionError extends Error

源码

被拒绝的文档 store 转换;渲染器和编译器状态都不会前进。

readonly code: InteractiveRenderTransitionErrorCode源码
readonly expectedCommitId: CommitId | null源码
readonly actualCommitId: CommitId | null源码
new ( code: InteractiveRenderTransitionErrorCode, message: string, commitIds: { readonly expected: CommitId | null; readonly actual: CommitId | null; } = { expected: null, actual: null } )源码

type InteractiveRenderTransitionErrorCode = | "DOCUMENT_NOT_LOADED" | "PREVIOUS_DOCUMENT_IDENTITY_MISMATCH" | "PREVIOUS_RENDERER_DOCUMENT_IDENTITY_MISMATCH" | "PREVIOUS_RENDERER_NODE_OWNERS_IDENTITY_MISMATCH" | "PREVIOUS_RENDERER_QUERY_TARGETS_IDENTITY_MISMATCH" | "INVALID_RENDERER_DOCUMENT_PROJECTION" | "INVALID_RENDERER_NODE_OWNERS" | "INVALID_RENDERER_QUERY_TARGETS" | "RENDERER_CHANGES_REQUIRED" | "INVALID_RENDERER_CHANGES" | "PREVIOUS_COMMIT_MISMATCH"

源码

InteractiveRenderSessionCoordinator.applyDocumentUpdate(或其他文档变更)被拒绝的原因。大多数代码表示该更新基于的文档、渲染器文档或提交与协调器持有的不同。

class InteractiveRenderSessionDisposedError extends Error

源码

确定性的“释放后使用”失败。

new ()源码

class InteractiveRenderSessionBusyError extends Error

源码

当排队中的变更尚未完成时,同步场景查询不可用。

new ()源码

class InteractiveRenderQueryBusyError extends Error

源码

在原生运行时让出执行期间尝试的同步后端查询。

readonly stage: string源码
readonly operation: string | null源码
new (stage: string, operation: string | null = null)源码

class InteractiveRenderResourceError extends Error

源码

渲染器所需的某个文档资源缺失或不可用:媒体节点指向了缺失的资源或非媒体资源,或者存储的资源与其资源定义不符(例如 MIME 类型不同)。assetId 指明该资源。

readonly assetId: string源码
new (assetId: string, message: string)源码

class InteractiveRenderGeometryError extends Error

源码

后端查询返回了协调器无法信任的几何数据:属于其他节点的结果、过期的场景代次,或编辑器无法表示的值。如果有被查询的节点,nodeId 会指明它。

readonly nodeId: string | null源码
new (message: string, nodeId: string | null = null)源码

无障碍路由

协调器为当前页面构建无障碍快照,并把屏幕阅读器的动作转换为 UI 命令。绑定把快照与其来源的确切文档、提交和场景代次关联起来,因此过期的动作会被拒绝。文档刚发生改动时,应用可能比协调器领先一个提交;getDocumentRevision 返回协调器持有的文档和提交,因此应用可以等待协调器跟上,而不是去询问协调器尚未拥有的节点。

interface InteractiveAccessibilityBindingV1

源码

一个不可变的语义快照,绑定到协调器确切的已提交规范标识和保留标识。只有签发它的协调器才能路由它。

readonly version: typeof ACCESSIBILITY_SNAPSHOT_VERSION源码
readonly document: DesignDocument源码
readonly commitId: CommitId源码
readonly pageId: PageId源码
readonly viewport: ViewportState源码
readonly generation: bigint源码
readonly snapshot: AccessibilitySnapshotV1源码

interface InteractiveAccessibilityActionRouteV1

源码

纯粹的 UI 意图,仅在精确的上下文和操作权限检查通过后才返回。

readonly version: typeof ACCESSIBILITY_SNAPSHOT_VERSION源码
readonly binding: InteractiveAccessibilityBindingV1源码
readonly authority: AccessibilityActionAuthorityV1源码
readonly command: InteractiveAccessibilityActionCommandV1源码

type InteractiveAccessibilityActionCommandV1 = | { readonly kind: "focus-mirror"; readonly nodeId: NodeId; readonly focusOwner: "accessibility-mirror"; } | { readonly kind: "set-node-selection"; readonly nodeId: NodeId; readonly mode: "replace" | "toggle"; readonly focusOwner: "accessibility-mirror"; } | { readonly kind: "begin-text-edit"; readonly nodeId: NodeId; readonly focusOwner: "text-input"; } | { readonly kind: "begin-code-edit"; readonly nodeId: NodeId; readonly focusOwner: "text-input"; }

源码

无障碍操作解析得到的 UI 命令。

class InteractiveAccessibilityContextError extends Error

源码

一个语义操作,其由协调器拥有的场景标识已不是当前的。

new (readonly code: InteractiveAccessibilityContextErrorCode, message: string)源码

type InteractiveAccessibilityContextErrorCode = | "INVALID_BINDING" | "DOCUMENT_IDENTITY_MISMATCH" | "COMMIT_MISMATCH" | "ACTIVE_PAGE_MISMATCH" | "VIEWPORT_IDENTITY_MISMATCH" | "GENERATION_MISMATCH" | "CANONICAL_NODE_MISSING" | "EDIT_TARGET_MISMATCH"

源码

抛出 InteractiveAccessibilityContextError 的原因。

场景查询与结果

RenderCoreSession 报告的关于其保留场景的信息。除非名称另有说明,位置均使用世界(文档)坐标,且大多数结果都带有所属的场景代次。

interface RenderSceneInfo

源码

保留场景以文档单位表示的大小、节点数和资源数, 以及标识其当前内容的代和摘要。

原生: TacoRenderSceneInfo

readonly width: number源码
readonly height: number源码
readonly nodeCount: number源码
readonly resourceCount: number源码
readonly generation: bigint源码
readonly sceneDigest: bigint源码

interface RenderUpdateReport

源码

应用一个批次的结果:各项计数、新的场景代和摘要,以及发生变化的区域。

原生: TacoRenderUpdateReport

readonly commandsApplied: number源码
readonly nodeCount: number源码
readonly resourceCount: number源码
readonly generation: bigint源码
readonly sceneDigest: bigint源码
readonly dirtyBounds: RenderDirtyBounds源码

interface RenderDirtyBounds

源码

上一个批次改动的世界空间区域:被改动节点的旧边界、新边界及二者的并集。

原生: TacoRenderDirtyBounds

readonly oldBounds?: RenderRect源码

脏矩形是场景 / 世界空间中的边界。

readonly newBounds?: RenderRect源码
readonly combinedBounds?: RenderRect源码

interface RenderRect

源码
readonly x: number源码
readonly y: number源码
readonly width: number源码
readonly height: number源码

interface RenderNodeGeometry

源码

一个保留节点的边界、变换、绘制顺序和可见性。

原生: TacoRenderNodeGeometry, TacoRenderGeometryRecord

readonly id: string源码
readonly kind: RetainedNodeRecord["kind"]源码
readonly localBounds?: RenderRect源码
readonly worldBounds?: RenderRect源码
readonly visibleWorldBounds?: RenderRect源码

应用可见性和祖先裁剪之后的世界空间边界。

readonly subtreeVisibleBounds?: RenderRect源码

The union of visibleWorldBounds over this node and all its descendants, with children of a clipping frame clipped to it: everything the subtree paints. Only single-node geometry queries report it.

readonly worldTransform: Transform源码
readonly painterOrder: bigint源码
readonly effectivelyVisible: boolean源码
readonly effectiveOpacity: number源码

interface RenderGeometrySnapshot

源码

针对一个已提交场景代的不可变几何视图,按从后到前排列。

readonly generation: bigint源码
readonly nodes: readonly RenderNodeGeometry[]源码

interface RenderHit

源码

命中测试点下方的一个节点。

原生: TacoRenderHit

readonly id: string源码
readonly kind: RetainedNodeRecord["kind"]源码
readonly painterOrder: bigint源码
readonly visibleWorldBounds: RenderRect源码

interface ViewportMappingOptions

源码

如何将场景适配到视口中,供 RenderCoreSession.mapViewport 使用。

原生: TacoRenderViewportOptions

readonly viewportWidth: number源码
readonly viewportHeight: number源码
readonly mode: "fit" | "fill" | "stretch"源码
readonly alignX?: number源码

零表示对齐到起始边,一表示对齐到末尾边。

readonly alignY?: number源码

interface ViewportMapping

源码

场景坐标与视口坐标之间的变换,以及场景在视口内的边界。 对于大小为 W×HW \times H 的场景和大小为 Vw×VhV_w \times V_h 的视口, 缩放比例初始为 sx=Vw/Ws_x = V_w / W 和 sy=Vh/Hs_y = V_h / H;fit 将二者都设为 min⁡(sx,sy)\min(s_x, s_y),fill 设为 max⁡(sx,sy)\max(s_x, s_y),stretch 则保持不变。 对齐方式为 (αx,αy)(\alpha_x, \alpha_y)(默认 0.5)时:

ox=(Vw−sxW) αx,oy=(Vh−syH) αyo_x = (V_w - s_x W)\,\alpha_x, \qquad o_y = (V_h - s_y H)\,\alpha_y
sceneToViewport=[sx,0,0,sy,ox,oy],viewportToScene=[1sx,0,0,1sy,−oxsx,−oysy]\text{sceneToViewport} = [s_x, 0, 0, s_y, o_x, o_y], \qquad \text{viewportToScene} = \Bigl[\tfrac{1}{s_x}, 0, 0, \tfrac{1}{s_y}, -\tfrac{o_x}{s_x}, -\tfrac{o_y}{s_y}\Bigr]

且 sceneViewportBounds 为 (ox,oy,sxW,syH)(o_x, o_y, s_x W, s_y H)。

原生: TacoRenderViewportMapping

readonly sceneToViewport: Transform源码
readonly viewportToScene: Transform源码
readonly sceneViewportBounds: RenderRect源码

interface RgbaRenderTarget

源码
readonly kind: "rgba"源码
readonly width: number源码
readonly height: number源码
readonly rowBytes: number源码
readonly pixels: Uint8Array源码

interface RenderFrameReport

源码
readonly backend: "skia-cpu" | "skia-webgpu"源码
readonly width: number源码
readonly height: number源码

interface RenderTextPosition

源码

相对于段落的作者文本位置。偏移量以 UTF-16 码元计数。

readonly paragraphIndex: number源码
readonly utf16Offset: number源码
readonly affinity: RenderTextAffinity源码

type RenderTextAffinity = "upstream" | "downstream"

源码

光标属于换行处或双向文本边界的哪一侧。

原生: TacoRenderTextAffinity

interface RenderTextRange

源码

anchor 和 focus 保留作者所做选区的方向。

readonly anchor: RenderTextPosition源码
readonly focus: RenderTextPosition源码

interface RenderTextCaretGeometry

源码
readonly position: RenderTextPosition源码
readonly localBounds: RenderRect源码

interface RenderTextCaretSnapshot

源码
readonly generation: bigint源码
readonly carets: readonly RenderTextCaretGeometry[]源码

interface RenderTextRangeGeometry

源码
readonly generation: bigint源码
readonly localRects: readonly RenderRect[]源码

interface RenderTextHitResult

源码
readonly generation: bigint源码
readonly position: RenderTextPosition源码
readonly inside: boolean源码

type RenderTextNavigationOperation = | "grapheme-backward" | "grapheme-forward" | "word-backward" | "word-forward" | "visual-left" | "visual-right" | "line-up" | "line-down" | "line-start" | "line-end" | "paragraph-start" | "paragraph-end" | "document-start" | "document-end"

源码

RenderCoreSession.navigateText 的一种光标移动方式。C 代码按此顺序从 0 开始编号。

原生: TacoRenderTextNavigationOperation

interface RenderTextNavigationResult

源码
readonly generation: bigint源码
readonly position: RenderTextPosition源码
readonly preferredLocalX?: number源码

interface RenderTextLayoutMetrics

源码
readonly generation: bigint源码
readonly autoResize: RetainedTextNode["autoResize"]源码
readonly frameWidth: number源码
readonly frameHeight: number源码
readonly contentWidth: number源码
readonly contentHeight: number源码
readonly suggestedWidth: number源码
readonly suggestedHeight: number源码
readonly paragraphCount: number源码
readonly lineCount: number源码
readonly caretCount: number源码

interface RenderFontMetadataSnapshot

源码
readonly fontResourceId: string源码
readonly generation: bigint源码
readonly featureTags: readonly string[]源码
readonly axes: readonly RenderFontAxisMetadata[]源码

interface RenderFontAxisMetadata

源码
readonly tag: string源码
readonly hidden: boolean源码
readonly minimum: number源码
readonly defaultValue: number源码
readonly maximum: number源码

interface RenderVectorGeometrySnapshot

源码
readonly generation: bigint源码
readonly vertices: readonly RenderVectorVertexGeometry[]源码
readonly handles: readonly RenderVectorCubicHandleGeometry[]源码
readonly segments: readonly RenderVectorSegmentGeometry[]源码
readonly regions: readonly RenderVectorRegionGeometry[]源码

interface RenderVectorVertexGeometry

源码
readonly kind: "vertex"源码
readonly id: string源码
readonly localPoint: { readonly x: number; readonly y: number }源码
readonly screenPoint: { readonly x: number; readonly y: number }源码

interface RenderVectorCubicHandleGeometry

源码
readonly kind: "cubic-handle"源码
readonly id: string源码
readonly segmentId: string源码
readonly vertexId: string源码
readonly endpoint: "start" | "end"源码
readonly localPoint: { readonly x: number; readonly y: number }源码
readonly screenPoint: { readonly x: number; readonly y: number }源码

type RenderVectorSegmentGeometry = | RenderVectorLineSegmentGeometry | RenderVectorCubicSegmentGeometry | RenderVectorArcSegmentGeometry

源码

interface RenderVectorLineSegmentGeometry extends RenderVectorSegmentGeometryBase

源码
readonly kind: "line"源码

interface RenderVectorCubicSegmentGeometry extends RenderVectorSegmentGeometryBase

源码
readonly kind: "cubic"源码
readonly startHandleId: string源码
readonly endHandleId: string源码

interface RenderVectorArcSegmentGeometry extends RenderVectorSegmentGeometryBase

源码
readonly kind: "elliptical-arc"源码
readonly radiusX: number源码
readonly radiusY: number源码
readonly xAxisRotation: number源码
readonly largeArc: boolean源码
readonly sweep: boolean源码

interface RenderVectorRegionGeometry

源码
readonly kind: "region"源码
readonly id: string源码
readonly windingRule: "nonzero" | "evenodd"源码
readonly authoredOrder: number源码
readonly localBounds: RenderRect源码
readonly screenBounds: RenderRect源码

interface RenderVectorHitQuery

源码
readonly screenPoint: { readonly x: number; readonly y: number }源码
readonly toleranceCssPx: number源码
readonly documentToScreen: Transform源码

interface RenderVectorHitSnapshot

源码
readonly generation: bigint源码
readonly hits: readonly RenderVectorHit[]源码

type RenderVectorHit = & { readonly id: string; readonly priority: number; readonly authoredOrder: number; readonly distanceCssPx: number; } & ( | { readonly kind: "vertex" } | { readonly kind: "cubic-handle"; readonly endpoint: "start" | "end" } | { readonly kind: "segment" } | { readonly kind: "region" })

源码

type RenderVectorBooleanOperation = | "union" | "intersection" | "difference" | "exclusion"

源码

对两条矢量路径执行的布尔运算。C 代码为:union(联集)1、 intersection(交集)2、difference(减去)3、exclusion(排除)4。

原生: TacoRenderVectorBooleanOperation

interface RenderVectorBooleanPathRequest

源码
readonly primaryNodeId: string源码
readonly secondaryNodeId: string源码
readonly operation: RenderVectorBooleanOperation源码
readonly resultIdNamespace: string源码

interface RenderVectorBooleanPathSnapshot

源码
readonly generation: bigint源码
readonly vectorNetwork: VectorNetworkRecord源码

interface RenderStrokeOutlineRequest

源码

Asks for one stroke of a path or container node as the filled shape it paints. strokeIndex counts the node’s strokes in paint order, hidden ones included, which is the stroke’s index in the model’s VisualStyle.strokes. Every vertex, segment, handle and region ID of the result starts with resultIdNamespace followed by a colon.

原生: TacoRenderStrokeOutlineQuery

readonly nodeId: string源码
readonly strokeIndex: number源码
readonly resultIdNamespace: string源码

interface RenderStrokeOutlineSnapshot

源码

The outline of one stroke for one scene generation, in the node’s local coordinates: closed loops in even-odd regions without fills. A ring is one region with a hole, and every dash is a region of its own. A stroke that paints nothing gives a network without components.

原生: TacoRenderStrokeOutlineResult

readonly generation: bigint源码
readonly vectorNetwork: VectorNetworkRecord源码

叠加层

编辑叠加层由渲染器在与场景相同的帧中绘制:选区轮廓和控制柄、吸附线和参考线,以及文本或矢量编辑状态。它们不属于场景,永远不会被导出,并且下一次场景改动会清除编辑叠加层。

interface RenderSelectionChrome

源码

渲染器绘制在场景之上的选区轮廓和变换控制柄。 RenderCoreSession.setSelectionChrome 将其编码为 SessionCache.setSelectionChrome 读取的字节布局。

原生: taco_render_session_set_selection_chrome, SessionCache.setSelectionChrome

readonly items: readonly RenderSelectionChromeItem[]源码
readonly strokeRgba: number源码

译文已过期

Default colours of items that give none, 0xRRGGBBAA.

readonly handleFillRgba: number源码
readonly devicePixelRatio: number源码

interface RenderSelectionChromeItem

源码

译文已过期

One selection outline or transform handle, resolved against a node at paint time. A handle arrives finished: the editor hit-tests handles, so it alone decides their size and turn, and the renderer only places the centre and paints the rectangle it is given.

readonly nodeId: string | null源码

译文已过期

Null places x and y (and an outline’s width and height) in scene coordinates.

readonly kind: "outline" | "square-handle" | "round-handle"源码
readonly hover?: boolean源码
readonly dashed?: boolean源码
readonly x: number源码

译文已过期

An outline’s node-local (or scene) rectangle. For a handle, x and y are its centre, and width and height its size on screen in CSS pixels, width along the turned x direction.

readonly y: number源码
readonly width?: number源码
readonly height?: number源码
readonly angle?: number源码

A handle’s turn on screen in radians, clockwise (screen y points down). 0 when omitted.

readonly strokeRgba?: number源码

0xRRGGBBAA; the chrome’s strokeRgba when omitted.

readonly fillRgba?: number源码

A handle’s fill, 0xRRGGBBAA; the chrome’s handleFillRgba when omitted.

readonly offsetX?: number源码

场景空间中的偏移,用于保留场景中没有的预览。

readonly offsetY?: number源码
readonly sceneTransform?: Transform源码

锚定到场景的项(nodeId 为 null)的局部到场景矩阵, 这样旋转节点的预览会保持旋转后的轮廓。省略时为单位矩阵。

readonly nodeTransform?: Transform源码

Item-to-node matrix of a node-anchored item (wire version 21): the item maps through it, then through the node’s transform. A multi-selection’s box is anchored to one selected node this way. Identity when omitted.

function encodeSelectionChrome(chrome: RenderSelectionChrome): Uint8Array

源码

Encodes the selection chrome in the layout taco_render_session_set_selection_chrome reads (version 3, wire version 20; see render_core.h). Each item carries its own colours, and each handle the size and angle the editor hit-tests it with, so the renderer paints exactly the handle the editor tests against.

原生: taco_render_session_set_selection_chrome, SessionCache.setSelectionChrome

interface RenderCanvasOverlay

源码

渲染器在同一帧中绘制在场景之上的编辑器线条:吸附线和对齐线及其 x 标记、 标尺参考线、option 拖动时的轮廓与测量,以及像素网格。它们从不属于文档内容, 也从不改变保留场景。

readonly anchorNodeId: string | null源码

叠加层使用其局部坐标的节点(页面根节点),这样线条会与页面在同一帧中跟随平移。 为 null 表示全部使用场景坐标。

readonly devicePixelRatio: number源码
readonly grid: RenderOverlayGrid | null源码
readonly lines: readonly RenderOverlayLine[]源码
readonly marks: readonly RenderOverlayMark[]源码
readonly titles?: readonly RenderOverlayTitle[]源码

绘制在顶层画框上方的名称。缺省表示没有。

readonly rulers?: RenderOverlayRulers源码

沿顶边和左边的标尺。缺省表示没有。

readonly boxes?: readonly RenderOverlayBox[]源码

填充、斜线填充或描出轮廓的框,例如自动布局的间距。缺省表示没有。

readonly handles?: readonly RenderOverlayHandle[]源码

带边框的短刻度线,例如自动布局的间距控制柄。缺省表示没有。

readonly badges?: readonly RenderOverlayBadge[]源码

显示数值的小胶囊标签,例如拖动间距时的数值。缺省表示没有。

function encodeCanvasOverlay(overlay: RenderCanvasOverlay): Uint8Array

源码

按 taco_render_session_set_canvas_overlay 读取的布局(版本 4;参见 render_core.h)编码画布叠加层。空叠加层编码为零字节。SessionCache.setCanvasOverlay 负责解码它。

原生: taco_render_session_set_canvas_overlay, SessionCache.setCanvasOverlay

interface RenderOverlayLine

源码

一条直的叠加层线条,按整设备像素绘制。

readonly orientation: "vertical" | "horizontal"源码

竖直线的 x 恒定;水平线的 y 恒定。

readonly side: RenderOverlayLineSide源码
readonly position: number源码

竖直线的 x,或水平线的 y。

readonly start: number | null源码

线条沿其长度方向的起点和终点;为 null 时贯穿整个画布。

readonly end: number | null源码
readonly rgba: number源码

0xRRGGBBAA。

readonly dash?: { readonly dashCssPx: number; readonly gapCssPx: number }源码

以 CSS 像素表示的虚线段长和间隔长度;实线时省略。

readonly scene?: boolean源码

使用场景坐标,而不是相对于叠加层锚点的局部坐标。

readonly anchorNodeId?: string源码

一个节点,此线条使用其局部坐标而非叠加层的锚点, 例如某个画框自己的参考线必须在移动或调整大小预览中跟随该画框。

readonly spansAnchorBox?: boolean源码

沿锚点节点自身的框延伸(从 0 到其宽度或高度);忽略 start 和 end。

type RenderOverlayLineSide = "after" | "before" | "centered"

源码

一条宽 1 CSS 像素的线条在其位置周围覆盖哪些设备像素: 左边缘或上边缘以及坐标线(网格线、标尺参考线)用“after”, 右边缘或下边缘用“before”,中线用“centered”。 这些正是选区轮廓在该处绘制边缘时覆盖的像素。

interface RenderOverlayMark

源码

一个抗锯齿的 x 标记,居中于两条叠加层线条的交点。

readonly x: number源码
readonly y: number源码
readonly xSide: RenderOverlayLineSide源码

相交线条所在的侧:x 标记居中于这些线条的像素上。

readonly ySide: RenderOverlayLineSide源码
readonly halfSizeCssPx: number源码
readonly rgba: number源码
readonly scene?: boolean源码

interface RenderOverlayGrid

源码

从原点起每隔 step 个单位一条线,贯穿整个画布。

readonly originX: number源码
readonly originY: number源码
readonly step: number源码
readonly rgba: number源码

画布叠加层还携带渲染器在同一帧中绘制的画布界面元素:框、控制柄和胶囊标签(自动布局的内边距、间距和间距控制柄)、标尺,以及顶层画框上方的名称。它们的文字使用传给 taco_render_session_set_canvas_overlay_font 的字体。

interface RenderOverlayBox

源码

位于其锚点局部坐标中的矩形,经锚点在正在绘制的这一帧中的完整世界变换映射(因此旋转画框的框会随之旋转)。三种外观都是可选的:纯色填充、每隔 4 个 CSS 像素一条、宽一个 CSS 像素的对角条纹(斜线填充),以及框内一个 CSS 像素宽的轮廓。

readonly anchorNodeId?: string源码

省略时使用叠加层的锚点。

readonly x: number源码
readonly y: number源码
readonly width: number源码
readonly height: number源码
readonly fillRgba?: number源码

0xRRGGBBAA;省略时不绘制填充、斜线填充或轮廓。

readonly hatchRgba?: number源码
readonly outlineRgba?: number源码

interface RenderOverlayHandle

源码

两端为圆头、带边框的短刻度线,以锚点局部坐标中的某个点为中心。它沿锚点局部的 x 轴或 y 轴放置,在任何缩放下都保持其 CSS 像素尺寸。

readonly anchorNodeId?: string源码
readonly x: number源码
readonly y: number源码
readonly axis: "x" | "y"源码

“x” 沿锚点局部的 x 轴,”y” 沿其 y 轴。

readonly lengthCssPx: number源码
readonly thicknessCssPx: number源码
readonly rgba: number源码

0xRRGGBBAA。

readonly borderRgba: number源码

interface RenderOverlayBadge

源码

带一行文字的圆角胶囊标签,其左上角相对锚点局部坐标中的某个点偏移若干 CSS 像素。使用传给 setCanvasOverlayFont 的字体绘制;没有字体时不绘制。

readonly anchorNodeId?: string源码
readonly x: number源码
readonly y: number源码
readonly offsetXCssPx: number源码
readonly offsetYCssPx: number源码
readonly fontSizeCssPx: number源码
readonly text: string源码
readonly backgroundRgba: number源码

0xRRGGBBAA。

readonly textRgba: number源码

interface RenderOverlayRulers

源码

标尺。渲染器根据叠加层锚点(页面根节点)在正在绘制的这一帧中的状态布置刻度和数字,因此在平移、缩放或自动平移的每一步中,标尺都随页面移动。数字使用传给 setCanvasOverlayFont 的字体。使用叠加层的锚点。

readonly sizeCssPx: number源码

标尺的粗细。

readonly fontSizeCssPx: number源码
readonly minimumMajorCssPx: number源码

主刻度按 1-2-5 步长选取,间距至少为此值。

readonly backgroundRgba: number源码

0xRRGGBBAA 颜色。

readonly borderRgba: number源码
readonly inkRgba: number源码
readonly selectionFillRgba: number源码
readonly selectionInkRgba: number源码
readonly selectionX: readonly RenderOverlayRulerSpan[]源码

已排序且互不相接的范围;长度为零的范围标记单个数值。

readonly selectionY: readonly RenderOverlayRulerSpan[]源码
readonly labels: readonly RenderOverlayRulerLabel[]源码

最多 16 个。

interface RenderOverlayRulerSpan

源码

标尺上的一段范围,使用叠加层锚点的单位。

readonly start: number源码
readonly end: number源码

interface RenderOverlayRulerLabel

源码

参考线的位置,以圆角标签的形式绘制在其标尺上。

readonly axis: "x" | "y"源码

“x” 是顶部标尺上的值,”y” 是左侧标尺上的值。

readonly position: number源码

使用叠加层锚点的单位。

readonly backgroundRgba: number源码

0xRRGGBBAA。

readonly textRgba: number源码

interface RenderOverlayTitle

源码

绘制在顶层画框上方的名称。渲染器把它放在画框在正在绘制的这一帧中的屏幕包围盒的左上角,因此它在移动、调整大小、平移或缩放时没有延迟地跟随画框,超出画框宽度的部分以省略号截断。它使用传给 setCanvasOverlayFont 的字体绘制。

readonly anchorNodeId: string源码
readonly text: string源码
readonly rgba: number源码

0xRRGGBBAA。

readonly fontSizeCssPx: number源码

字号,也是标题行框的高度。

readonly gapCssPx: number源码

行框底部与画框顶边之间的距离。

interface RenderTextEditingOverlay

源码

一个带有代标记的临时选区、光标,以及可选的输入法(IME)范围。

readonly selection: RenderTextRange源码
readonly composition?: RenderTextRange源码
readonly caretVisible: boolean源码

interface RenderVectorEditingOverlay

源码
readonly network: VectorNetworkRecord源码
readonly selection: RenderVectorEditingSelection源码
readonly pendingHandle?: RenderVectorPendingHandle | null源码

The Pen’s pending handle, when there is one.

readonly viewport: { readonly documentToScreen: Transform; readonly screenWidthCssPx: number; readonly screenHeightCssPx: number; readonly screenPixelDensity: number; }源码

interface RenderVectorEditingSelection

源码

按类别列出的选中矢量组件,以及主组件(或 null)。

readonly vertexIds: readonly string[]源码
readonly handleIds: readonly string[]源码
readonly segmentIds: readonly string[]源码
readonly regionIds: readonly string[]源码
readonly primary: RenderVectorEditingComponent | null源码

type RenderVectorEditingComponent = | { readonly kind: "vertex"; readonly id: string } | { readonly kind: "handle"; readonly id: string } | { readonly kind: "segment"; readonly id: string } | { readonly kind: "region"; readonly id: string }

源码

矢量网络中按 ID 指定的一个顶点、控制柄、线段或区域。

导出

导出把一个页面或单个图层绘制为 PNG、SVG、PDF 或原始 RGBA 字节。协调器会重新编译页面,并通过一个用后即弃的会话导出,因此实时场景及其叠加层都不会进入文件。

interface RenderDocumentExportOptions

源码

InteractiveRenderSessionCoordinator.exportDocument 导出什么以及如何导出。

readonly format: RenderExportFormat源码
readonly scale?: number源码

每个文档单位对应的输出单位数。默认为 1。

readonly rootNodeId?: string源码

导出此节点的可见边界及其子树;省略时表示整个页面。

readonly options?: RenderExportOptions源码

interface RenderExportOptions

源码

格式、缩放比例和根节点之外的导出选项。

readonly fixedSize?: { readonly dimension: "width" | "height"; readonly value: number; }源码

以输出单位表示的固定输出宽度或高度,用于替代 scale: 缩放比例变为该尺寸除以导出边界的宽度或高度。

readonly includeOverlappingLayers?: boolean源码

指定根节点时,绘制根节点边界内的所有可见节点,而不仅是根节点的子树, 从而包含与之重叠的图层。

readonly imageSampling?: RenderExportImageSampling源码
readonly svgNodeMarkers?: boolean源码
readonly pdfRasterDpi?: number源码
readonly maxPixels?: number源码

The most pixels a raster export (rgba or png) may have. An export over it is refused with RenderExportTooLargeError once its size is measured and before anything is allocated or drawn. Left out: only the renderer’s own limit of 16384 pixels a side applies.

interface RenderCompiledExportRequest

源码

一个冷页面批次,以及新会话绘制和导出它所需的内容。

readonly batch: Uint8Array源码
readonly imageAssets: readonly ImageAsset[]源码

批次引用的所有图片资源,用于解码成帧。

readonly format: RenderExportFormat源码
readonly scale: number源码

每个文档单位对应的输出单位数。

readonly rootNodeId?: string源码

导出此节点的可见边界及其子树;省略时表示整个页面。

readonly options?: RenderExportOptions源码

导出本身的其他选项;见 RenderExportOptions。

interface RenderExportRequest

源码

通过共享绘制器绘制的一个矩形场景区域。编辑叠加层从不导出,背景保持透明。

原生: TacoRenderExportRequest

readonly format: RenderExportFormat源码
readonly x: number源码

以场景坐标表示的区域。

readonly y: number源码
readonly width: number源码
readonly height: number源码
readonly scale?: number源码

每个场景单位对应的输出单位数:光栅像素、SVG 用户单位、PDF 点。默认为 1。

readonly rootNodeId?: string源码

设置后,只绘制此节点及其后代。

readonly imageSampling?: RenderExportImageSampling源码

图片填充和媒体帧的重采样方式;默认使用屏幕的“linear”。

readonly svgNodeMarkers?: boolean源码

仅限 SVG:用节点标记包围每个已绘制节点的元素。见 PROTOCOL.md。

readonly pdfRasterDpi?: number源码

仅限 PDF:光栅化模糊和阴影时使用的 DPI;默认为 72。

interface RenderExportResult

源码

一次导出的字节及其大小。

原生: TacoRenderExportResult

readonly format: RenderExportFormat源码
readonly bytes: Uint8Array源码

RGBA 行紧密排列且非预乘 alpha;其他格式为完整文件。

readonly pixelWidth: number源码

ceil(region * scale);光栅格式以此作为像素尺寸。

readonly pixelHeight: number源码
readonly rowBytes: number源码

每个 RGBA 行的字节数;其他所有格式均为零。

type RenderExportFormat = "rgba" | "png" | "svg" | "pdf"

源码

场景导出目标。PNG 需要带 PNG 编码器的构建;RGBA 从不需要。

原生: TacoRenderExportFormat

type RenderExportImageSampling = "linear" | "cubic" | "nearest"

源码

导出时图片的重采样方式:“linear”(屏幕所用的采样方式)、“cubic”或 “nearest”。

原生: TacoRenderExportImageSampling

页面编译器

页面编译器把文档的一个页面转换为保留记录,并将其编码为变更批次。compilePageBatch 构建整个页面;ActivePageCompilerSession 保留上一个页面,只编码变更集涉及的部分。渲染器无法绘制的模型数据会以 RenderDocumentCompileError 失败,而不是悄悄消失。

function compilePageBatch( document: DesignDocument, pageId: PageId, options: CompilePageOptions ): CompiledPageBatch

源码

将一个规范页面编译为完整的变更批次:把场景重置为页面尺寸,注册其字体,并添加每个节点。不支持的节点和绘制语义会以结构化的 RenderDocumentCompileError 报错,而不是直接消失。

function compileIncrementalPageBatch( previous: DesignDocument, current: DesignDocument, changes: ChangeSet, pageId: PageId, options: CompilePageOptions ): CompiledPageUpdate

源码

编译一次规范文档转换,而不重置保留场景。调用方必须已应用 compilePageBatch(previous, pageId),或同一转换链中上一次成功的结果。

模型变更集是一个保守的失效信号。为保证正确性,编译器还会比较两个选中页面子树的完整保留表示,因此不完整的变更集不会让某次更新悄无声息地丢失。

class ActivePageCompilerSession

源码

当前显示页面的有状态编译器。

规范文档是不可变的,且经过校验的模型变更集会标明每一个受影响的实体。正式运行时的更新只检查这些 ID,以及结构上发生位移的兄弟节点;显式的冷编译审计则执行刻意设计为 O(document) 的验证过程。更新具有事务性:只有整个批次都成功编码后,缓存才会前进。

new (options: CompilePageOptions)源码

创建一个空会话;调用 update 之前需先调用 reset。

get initialized(): boolean源码

reset 是否已编译过一个页面。

reset(document: DesignDocument, pageId: PageId): CompiledActivePageBatch源码

编译并缓存一个完整的活动页面,包括重置命令。

update( document: DesignDocument, documentChanges: ChangeSet ): CompiledActivePageUpdate源码

利用其权威的已变更实体索引,编译一次经过校验的转换。未变更的兄弟节点既不会被遍历,也不会被转换。

auditAgainstColdCompilation( document: | DesignDocument | undefined = this.#active?.document ): ActivePageAuditReport源码

在 update() 之外执行刻意设计为 O(document) 的正确性审计。

clear(): void源码

丢弃缓存的页面;下一次调用必须是 reset。

interface CompilePageOptions

源码

页面编译器从何处获取资源字节和语言偏好。

readonly getAssetBytes: (asset: Asset) => Uint8Array | undefined源码

为注册为 wire 资源的资源提供字节。仅供场景使用的媒体元数据从不解析字节;加载解码后的帧属于后续平台适配器的职责。

readonly getFontSlices?: (asset: FontAsset) => | readonly CompileFontSlice[] | undefined源码

按优先级顺序,提供来源为“google-fonts”的字体资源目前已加载的文件。当该资源是某个样式的主字体时,第一个文件总会被注册,以便文本拥有行度量信息;其余每个文件只有在覆盖了文本节点中的某个字符时才会被注册。仍在加载中的文件直接视为不存在:宿主会显示加载状态,并在文件到达后重新编译。

readonly userLanguage?: string源码

用户的语言,以 BCP 47 标签表示,例如浏览器的 navigator.language。对于样式未指定语言的文本,它用于在 CJK 自动回退字体族之间做出选择;参见 preferredCjkFamily。

readonly resolveInstance?: InstanceResolver源码

Derives an instance’s layers (design 4.1). Defaults to resolveInstance from @taco-slides/model. Each resolved layer compiles as a stored node would, under its virtual ID; the instance compiles as a frame whose paints come from the component root.

interface CompileFontSlice

源码

按 Unicode 覆盖范围拆分的字体资源中已加载的一个文件,例如以许多小 WOFF2 文件提供的 Google Fonts 字体族。

readonly id: string源码

在所属资源内唯一。不得包含“#”。

readonly unicodeRanges: readonly (readonly [number, number])[]源码

该文件覆盖的码点范围(闭区间),已排序且互不重叠。

readonly bytes: Uint8Array源码

interface CompiledPageBatch

源码

以单个变更批次表示的完整页面,会重置保留场景。

readonly batch: Uint8Array源码

已编码的批次,可直接传给 RenderCoreSession.apply。

readonly nodeIds: readonly NodeId[]源码

所有已编译的节点,按遍历顺序排列。

readonly mediaAssetIds: readonly string[]源码

场景使用的图片和视频资源;由宿主附加它们的帧。

readonly resourceIds: readonly string[]源码

批次中注册的 wire 资源 ID(字体和字体文件)。

type CompiledPageUpdate = CompiledIncrementalPageBatch | PageFullReloadRequired

源码

compileIncrementalPageBatch 的结果。

interface CompiledIncrementalPageBatch

源码

编码为批次的页面变更,用于原地更新保留场景。

readonly kind: "incremental"源码
readonly batch: Uint8Array源码

不含重置命令的批次,页面未变更时也是如此。

readonly operations: PageIncrementalOperations源码
readonly nodeIds: readonly NodeId[]源码
readonly mediaAssetIds: readonly string[]源码
readonly resourceIds: readonly string[]源码

interface PageIncrementalOperations

源码

增量批次包含的命令,按节点 ID 和资源 ID 列出。

readonly removeNodeIds: readonly NodeId[]源码

被 wire 命令移除的之前的顶层子树。

readonly upsertNodeIds: readonly NodeId[]源码

按规范遍历顺序插入或替换的当前节点。

readonly transformNodeIds?: readonly NodeId[]源码

除变换外保留数据均未改变的当前节点。

readonly registerResourceIds: readonly string[]源码
readonly removeResourceIds: readonly string[]源码

interface PageFullReloadRequired

源码

该变更无法以增量方式发送;请重新编译整个页面。

readonly kind: "full-reload-required"源码
readonly reasons: readonly PageFullReloadReason[]源码

interface PageFullReloadReason

源码

页面需要整体重新加载的一个原因,附带可读的消息。

readonly code: PageFullReloadReasonCode源码
readonly message: string源码

type PageFullReloadReasonCode = | "PREVIOUS_PAGE_NOT_FOUND" | "CURRENT_PAGE_NOT_FOUND" | "PAGE_ROOT_RESIZED" | "PAGE_ROOT_CHANGED" | "THEME_CHANGED" | "PAGE_VARIABLE_MODES_CHANGED"

源码

增量更新被拒绝、页面必须重新编译的原因。

interface CompiledActivePageBatch extends CompiledPageBatch

源码

来自 ActivePageCompilerSession.reset 的完整页面批次,附带工作量计数。

readonly metrics: ActivePageCompileMetrics源码

interface CompiledActivePageIncrementalBatch extends CompiledIncrementalPageBatch

源码

来自 ActivePageCompilerSession.update 的增量批次,附带工作量计数。

readonly metrics: ActivePageCompileMetrics源码

type CompiledActivePageUpdate = | CompiledActivePageIncrementalBatch | PageFullReloadRequired

源码

ActivePageCompilerSession.update 的结果。

interface ActivePageCompileMetrics

源码

有状态的活动页面编译器报告的确定性工作量计数。

readonly nodesInspected: number源码

由经过校验的变更集和层级索引选出的规范节点。

readonly nodesCompiled: number源码

从规范模型转换而来的选中节点。

readonly nodesReused: number源码

保留给未经重新编译即被选中的已接受缓存记录。

readonly nodesUpserted: number源码

编码进本批次的节点 upsert(插入或更新)命令。

readonly resourcesResolved: number源码

本次编译期间执行的平台资源解析次数。

readonly resourcesRegistered: number源码

编码进本批次的资源数据。

readonly resourcesRemoved: number源码
readonly batchBytes: number源码

interface ActivePageAuditReport

源码

ActivePageCompilerSession.auditAgainstColdCompilation 的结果:缓存的记录是否与一次全新编译的结果一致,以及哪些记录不一致。

readonly matchesColdCompilation: boolean源码
readonly nodesInspected: number源码
readonly mismatchedNodeIds: readonly NodeId[]源码
readonly mismatchedResourceIds: readonly string[]源码

class RenderDocumentCompileError extends Error

源码

一种有意设置的边界错误;不受支持的模型数据绝不能悄无声息地消失。

readonly code: RenderDocumentCompileErrorCode源码
readonly nodeId: NodeId | undefined源码
new (code: RenderDocumentCompileErrorCode, message: string, nodeId?: NodeId)源码

type RenderDocumentCompileErrorCode = | "PAGE_NOT_FOUND" | "PAGE_ROOT_WITHOUT_SIZE" | "NODE_NOT_FOUND" | "UNSUPPORTED_NODE" | "UNSUPPORTED_STYLE" | "INVALID_MEDIA_CROP" | "MEDIA_ASSET_REQUIRED" | "FONT_ASSET_REQUIRED" | "FONT_BYTES_REQUIRED" | "RESOURCE_LIMIT" | "INVALID_COLOR" | "INSTANCE_UNRESOLVED"

源码

function compileRetainedPaint( paint: Paint, nodeId: NodeId, label: string, document?: DesignDocument ): RetainedPaintRecord

源码

将一个规范绘制(paint)降级为其保留记录。图片绘制必须指向 document 中的一个图片资源,因为宿主会通过媒体帧约定按资源 ID 附加其像素。

function parseRetainedColor(value: string, nodeId: NodeId): RgbaColor

源码

解析第一版共享 wire 格式所接受的确定性 CSS 颜色子集。

function fontSliceResourceId(assetId: string, sliceId: string): string

源码

按 Unicode 覆盖范围拆分的字体资源中某个文件的 wire 资源 ID。

function fontResourceAsset( document: DesignDocument, resourceId: string ): Asset | undefined

源码

某个 wire 字体资源编译自的文档资源。资源 ID 要么是资源 ID,要么是“google-fonts”资源或自动回退资源(见 automatic-font-fallback.ts)的 fontSliceResourceId(assetId, sliceId);两种形式冲突的文档会被编译器拒绝。

function textNodeCodePoints(node: TextualNode): Set<number>

源码

文本节点可能绘制的每个码点:其文本片段、显式列表标记, 以及生成的标记所用的字符(“•”和“1.”)。

const RETAINED_IDENTITY_TRANSFORM: Transform

源码

Connectors

The page compiler draws a connector from its stored ends: an attached end goes on its layer’s edge where it faces the other end, spread apart from other connectors on the same side, and an elbow route goes around the other layers under the same parent. The editor asks for the same line, so a connector’s frame and end handles stay on what is drawn.

function connectorLineGeometry( document: DesignDocument, node: Extract<SceneNode, { type: "connector" }>, parentId: NodeId | undefined ): ConnectorLineGeometry

源码

The line node draws, routed exactly as the page compiler draws it: an attached end is placed on its layer’s edge where it faces the other end (spread apart from other automatic ends on the same side), and an elbow route goes around the other layers under the same parent. The editor uses it to keep a connector’s frame and end handles on the drawn line. parentId is the connector’s parent. Throws the compiler’s RenderDocumentCompileError when an attachment cannot be drawn.

interface ConnectorLineGeometry

源码

The line a connector draws, in the connector’s own coordinates.

readonly start: { readonly x: number; readonly y: number }源码

Where the line starts, after an attached start is placed on its layer’s edge.

readonly end: { readonly x: number; readonly y: number }源码

Where the line ends (an arrowhead’s tip), after an attached end is placed.

readonly bounds: { readonly x: number; readonly y: number; readonly width: number; readonly height: number; }源码

The box around the whole line, bends and curves included, without stroke or end caps.

function connectorRoutePoints( node: Extract< SceneNode, { type: "connector"; } >, curveSteps = 24, document?: DesignDocument ): readonly { readonly x: number; readonly y: number }[]

源码

The route node draws, as points along it in the connector’s own coordinates, from start to end: the corners of a bent route, and each curve split into curveSteps straight pieces. The line is not shortened for arrowheads. The editor draws a selected or hovered connector’s outline along it.

With document, an attached connector is routed as the page compiler draws it in that document (around the other layers, apart from other connectors), so pass the document the drawn scene shows. Without it, or for a connector with no attached end, the route runs between the stored ends (the line’s real ends once the editor has fitted the connector).

保留场景记录

页面编译器生成、编码器写入的记录,每个节点一条。它们是贴近 wire 格式的普通数据:颜色是 RGBA 数值,ID 是字符串,每个 Paint、描边和文本片段都完整写出。

type RetainedNodeRecord = | RetainedPathNode | RetainedTextNode | RetainedContainerNode | RetainedMediaNode

源码

interface RetainedNodeBase

源码
readonly id: string源码
readonly parentId?: string源码
readonly zOrder: number源码
readonly visible: boolean源码
readonly blendMode?: RetainedBlendMode源码

wire 版本 10 通过一个隔离图层合成混合模式非 normal 的节点。 省略表示 normal。

readonly mask?: boolean源码

wire 版本 10 允许节点为其后续同级节点充当蒙版:这些节点只保留在蒙版自身绘制 具有 alpha 的地方,而蒙版本身不绘制任何内容。隐藏的蒙版不遮挡任何内容。

readonly transform: Transform源码
readonly style: RetainedNodeStyle源码

interface RetainedNodeStyle

源码
readonly opacity: number源码
readonly fill?: RgbaColor源码

紧凑的通用节点记录携带 fill。wire 版本 5 则可以改为在节点 upsert 中追加 fills,以提供精确有序的绘制列表。这两种表示互斥。

readonly fills?: readonly RetainedPaintRecord[]源码
readonly strokes?: readonly RetainedStrokeRecord[]源码

在填充之后绘制的有序描边,第一项位于最底层。 第一个描边使用紧凑的通用节点记录;wire 版本 7 将其余描边追加到外观尾部。

readonly shadows?: readonly RetainedShadowRecord[]源码

wire 版本 6 追加有序的阴影;wire 版本 9 增加内阴影。

readonly layerBlur?: number源码

wire 版本 9 追加一个高斯模糊半径,作为一个隔离图层应用于该节点及其后代。 为零或省略表示不模糊。

readonly backgroundBlur?: number源码

wire 版本 9 追加一个高斯模糊半径,在节点的填充绘制之前, 应用于节点形状背后的内容。为零或省略表示无。

interface RetainedContainerNode extends RetainedNodeBase

源码

wire 版本 2 引入的与渲染器无关的层级与裁剪节点。

readonly kind: "container"源码
readonly width: number源码
readonly height: number源码
readonly clip: boolean源码
readonly cornerRadius?: number源码

wire 版本 11 在半径为正时追加圆角半径和圆角平滑系数, 并在容器的第一个保留字节中加以标记。正的半径会让容器自身的绘制、 其内阴影、背景模糊和子元素裁剪都变为圆角;半径最大取短边的一半。 为零或省略表示直角。

readonly cornerRadii?: readonly [number, number, number, number]源码

wire 版本 14 用标志位(位 2)表示四个独立的半径,顺序为左上、右上、右下、左下,后跟圆角平滑。每个半径被限制在较短边的一半以内。与非零的 cornerRadius 互斥;编译器只在各半径不同时发送它。

readonly cornerSmoothing?: number源码

圆角平滑,从 0(圆弧)到 1(连续曲率)。每个平滑后的圆角最多占用 (1 + smoothing) * radius 的边长,上限为短边的一半。为零或省略时保持圆弧。

interface RetainedPathNode extends RetainedNodeBase

源码
readonly kind: "path"源码
readonly vectorNetwork: VectorNetworkRecord源码
readonly vertexCornerRadii?: readonly RetainedVertexCornerRadius[]源码

wire 版本 12 为节点设置标志(第 2 位),并在网络记录之后追加此表。 只有恰好连接两条直线或三次曲线线段的顶点才会在绘制时变为圆角; 作者创建的顶点仍作为编辑和查询所用的几何。为空或省略表示尖角。

readonly strokeCaps?: RetainedStrokeCaps源码

译文已过期

Wire version 13 flags the node (bit 4) and appends both caps after any vertex corner table. The start cap sits at the start vertex of the first segment and the end cap at the end vertex of the last one; both must be open chain ends. Omitted keeps round caps at every stroke end. Lines and connectors both send their end styles here; since wire version 22 heads point the way the line arrives across a triangle head’s length, and dashes get round ends while heads stay solid.

interface RetainedTextNode extends RetainedNodeBase

源码
readonly kind: "text"源码
readonly width: number源码
readonly height: number源码
readonly wrap: "none" | "word" | "character"源码
readonly verticalAlign: "top" | "middle" | "bottom"源码
readonly overflow: "clip" | "visible"源码
readonly autoResize: "none" | "height" | "width-and-height"源码
readonly styles: readonly RichTextStyleRecord[]源码
readonly paragraphs: readonly RichTextParagraphRecord[]源码

interface RetainedMediaNode extends RetainedNodeBase

源码

wire 版本 4 引入的仅场景使用的媒体元数据。

readonly kind: "media"源码
readonly mediaKind: "image" | "video"源码
readonly fit: "contain" | "cover" | "fill"源码
readonly width: number源码
readonly height: number源码
readonly assetId: string源码
readonly crop?: { readonly x: number; readonly y: number; readonly width: number; readonly height: number; }源码

type Transform = readonly [ a: number, b: number, c: number, d: number, tx: number, ty: number ]

源码

一个仿射变换矩阵,布局 [a, b, c, d, tx, ty] 与模型的 TransformMatrix 相同。它按 (x′,y′)=(ax+cy+tx, bx+dy+ty)(x', y') = (a x + c y + t_x,\ b x + d y + t_y) 映射一个点。

type RgbaColor = readonly [ red: number, green: number, blue: number, alpha: number ]

源码

type RetainedBlendMode = | "normal" | "darken" | "multiply" | "color-burn" | "lighten" | "screen" | "color-dodge" | "overlay" | "soft-light" | "hard-light" | "difference" | "exclusion" | "hue" | "saturation" | "color" | "luminosity"

源码

wire 版本 10 的混合模式,以 CSS mix-blend-mode 的术语表示。wire 代码 (按此顺序为 0 到 15)即 C++ BlendMode 的值。

原生: BlendMode

type RetainedPaintRecord = | RetainedSolidPaintRecord | RetainedLinearGradientPaintRecord | RetainedRadialGradientPaintRecord | RetainedAngularGradientPaintRecord | RetainedImagePaintRecord

源码

一个填充或描边绘制。wire 类型代码(solid 1、linear 2、radial 3、 angular 4、image 5)即 C++ PaintKind 的值。

原生: PaintKind, RetainedPaint

interface RetainedPaintCompositing

源码

wire 版本 19 在 paint 头部的保留字节中携带两个按 paint 设置的字段:字节 1 是混合模式代码(与节点混合模式代码相同,0 表示正常),字节 2 存放标志,其中位 1 隐藏该 paint。两者取默认值时都省略。

readonly hidden?: true源码

渲染器跳过隐藏的 paint,但保留它在列表中的位置。

readonly blendMode?: RetainedBlendMode源码

让该 paint 与同一节点上位于其下方的 paint 混合;正常模式时省略。只要有任何可见的 paint 设置了混合模式,节点的所有 paint 就会绘制到它们自己的图层中,因此混合不会影响节点后方的内容。

interface RetainedSolidPaintRecord extends RetainedPaintCompositing

源码
readonly kind: "solid"源码
readonly color: RgbaColor源码
readonly opacity: number源码

interface RetainedLinearGradientPaintRecord extends RetainedPaintCompositing

源码
readonly kind: "linear-gradient"源码
readonly angle: number源码
readonly stops: readonly { readonly offset: number; readonly color: RgbaColor; }[]源码
readonly opacity: number源码

interface RetainedRadialGradientPaintRecord extends RetainedPaintCompositing

源码

wire 版本 8 新增以形状边界为参照的径向渐变和角度渐变。

readonly kind: "radial-gradient"源码
readonly centerX: number源码

中心点,以形状边界的比例表示。

readonly centerY: number源码
readonly radiusX: number源码

椭圆半径,以形状边界的比例表示;二者均为正数。

readonly radiusY: number源码
readonly stops: readonly { readonly offset: number; readonly color: RgbaColor; }[]源码
readonly opacity: number源码

interface RetainedAngularGradientPaintRecord extends RetainedPaintCompositing

源码
readonly kind: "angular-gradient"源码
readonly centerX: number源码
readonly centerY: number源码
readonly angle: number源码

起始角度,单位为度,从正 x 轴开始按顺时针方向计算。

readonly stops: readonly { readonly offset: number; readonly color: RgbaColor; }[]源码
readonly opacity: number源码

interface RetainedImagePaintRecord extends RetainedPaintCompositing

源码

wire 版本 8 新增图片绘制。像素通过与图片节点相同的媒体帧约定送达, 以逻辑资源 ID 为键。

readonly kind: "image"源码
readonly assetId: string源码
readonly fit: RetainedImagePaintFit源码
readonly opacity: number源码

type RetainedImagePaintFit = "contain" | "cover" | "fill"

源码

图片绘制如何适配其形状。wire 代码(按此顺序为 0、1、2) 即 C++ MediaFit 的值。

原生: MediaFit

interface RetainedStrokeRecord

源码
readonly color: RgbaColor源码
readonly width: number源码
readonly position?: RetainedStrokePosition源码

wire 版本 6 追加描边位置。省略它或指定为 center 时, 保持紧凑的 wire v5 编码。

readonly dash?: readonly number[]源码

wire 版本 6 追加虚线间隔。长度为奇数的模式会重复成偶数长度的周期, 与 SVG 的 stroke-dasharray 一致。

readonly paint?: RetainedPaintRecord源码

wire 版本 6 可以追加完整的描边绘制。省略时,color 仍是权威的纯色描边绘制。第一个之后的每个描边总是携带绘制, 因为只有第一个描边具有紧凑的颜色字段。

readonly sides?: readonly [number, number, number, number]源码

wire 版本 18 为容器的描边按边设置各自的粗细,顺序为上、右、下、左,由描边的第一个保留字节标记,并追加在虚线间隔之后。此时 width 应保存最大的粗细,包围盒和命中测试都使用它。只有容器接受此字段。

readonly join?: RetainedStrokeJoin源码

Wire version 23 sets the stroke’s join, the ends of its dashes and its miter limit together, flagged in the stroke flags byte (bit 2) and appended after any side weights. Give all three or none. Without them a path strokes with round joins and round dash ends and a container with miter joins (limit 4) and flat dash ends, as before wire version 23. On a path with stroke caps, dashCap sets only the dash ends; the path’s own ends take its caps. Side weights ignore the join.

readonly dashCap?: RetainedDashCap源码

Wire version 23: the ends of every dash; see join.

readonly miterLimit?: number源码

Wire version 23: the longest a miter join may reach, as a multiple of half the stroke width, before it is beveled (SVG’s stroke-miterlimit); at least 1. Only miter joins use it; see join.

type RetainedStrokePosition = "center" | "inside" | "outside"

源码

保留描边相对于形状边界的位置。wire 代码(按此顺序为 0、1、2) 即 C++ StrokePosition 的值。

原生: StrokePosition

type RetainedStrokeCap = | "none" | "round" | "square" | "line-arrow" | "triangle-arrow" | "reversed-triangle" | "circle-arrow" | "diamond-arrow"

源码

wire 版本 13 的描边端点,采用 Figma 的术语。wire 代码(按此顺序为 0 到 7) 即 C++ StrokeCap 的值。

原生: StrokeCap

interface RetainedStrokeCaps

源码
readonly start: RetainedStrokeCap源码
readonly end: RetainedStrokeCap源码

type RetainedStrokeJoin = "miter" | "bevel" | "round"

源码

Wire version 23 stroke joins. The wire codes (0 to 2 in this order) are the C++ StrokeJoin values.

原生: StrokeJoin

type RetainedDashCap = "none" | "round" | "square"

源码

Wire version 23 dash ends. The wire codes (0 to 2 in this order) are the C++ DashCap values.

原生: DashCap

interface RetainedShadowRecord

源码
readonly inner?: boolean源码

wire 版本 9 在每个阴影前加上其类型。内阴影绘制在形状内部、位于填充之上; 投影(默认)绘制在节点背后。

readonly x: number源码
readonly y: number源码
readonly blur: number源码
readonly spread: number源码
readonly color: RgbaColor源码

interface RetainedVertexCornerRadius

源码

wire 版本 12:路径中的一个圆角顶点,由稳定的顶点 ID 指定。

readonly vertexId: string源码
readonly radius: number源码

正数;渲染器会将其限制为较短的相邻线段长度的一半。

interface VectorNetworkRecord

源码
readonly vertices: readonly VectorVertexRecord[]源码
readonly segments: readonly VectorSegmentRecord[]源码
readonly constraints?: readonly VectorTangentConstraintRecord[]源码
readonly regions: readonly VectorRegionRecord[]源码

interface VectorVertexRecord

源码
readonly id: string源码
readonly x: number源码
readonly y: number源码

interface VectorHandleRecord

源码
readonly id: string源码
readonly dx: number源码
readonly dy: number源码

type VectorSegmentRecord = | VectorLineSegmentRecord | VectorCubicSegmentRecord | VectorEllipticalArcSegmentRecord

源码

interface VectorLineSegmentRecord

源码
readonly id: string源码
readonly kind: "line"源码
readonly start: string源码
readonly end: string源码

interface VectorCubicSegmentRecord

源码
readonly id: string源码
readonly kind: "cubic"源码
readonly start: string源码
readonly end: string源码
readonly startHandle: VectorHandleRecord源码
readonly endHandle: VectorHandleRecord源码

interface VectorEllipticalArcSegmentRecord

源码

为迁移和 SVG 交换而保留的精确兼容几何。

readonly id: string源码
readonly kind: "elliptical-arc"源码
readonly start: string源码
readonly end: string源码
readonly radiusX: number源码
readonly radiusY: number源码
readonly xAxisRotation: number源码
readonly largeArc: boolean源码
readonly sweep: boolean源码

interface VectorRegionRecord

源码
readonly id: string源码
readonly windingRule: "nonzero" | "evenodd"源码
readonly loops: readonly VectorRegionLoopRecord[]源码
readonly fills?: readonly RetainedPaintRecord[]源码

省略时继承路径的填充;空列表则明确禁用此区域的填充。

interface VectorRegionLoopRecord

源码
readonly segments: readonly VectorSegmentReferenceRecord[]源码
readonly implicitClose?: true源码

interface VectorSegmentReferenceRecord

源码
readonly segmentId: string源码
readonly direction: "forward" | "reverse"源码

interface VectorTangentConstraintRecord

源码
readonly vertexId: string源码
readonly handleIds: readonly [string, string]源码
readonly mode: "angle" | "angle-and-length"源码

interface RichTextStyleRecord

源码
readonly fontResourceIds: readonly string[]源码

首先是主字体,其后是确定性的整形回退字体。

readonly language?: string源码
readonly fontSize: number源码
readonly lineHeight: number源码

渲染器空间中的绝对行高;不同样式可以使用不同的值。

readonly letterSpacing: number源码
readonly weight: number源码
readonly italic?: boolean源码
readonly underline?: boolean源码
readonly strikethrough?: boolean源码
readonly color: RgbaColor源码
readonly openTypeFeatures?: Readonly<Record<string, boolean | number>>源码
readonly fontVariations?: Readonly<Record<string, number>>源码

interface RichTextParagraphRecord

源码
readonly direction: "auto" | "ltr" | "rtl"源码
readonly align: "left" | "center" | "right" | "justify"源码
readonly spacingBefore: number源码
readonly spacingAfter: number源码
readonly indent?: { readonly left: number; readonly right: number; readonly firstLine: number; }源码
readonly list?: { readonly kind: "ordered" | "unordered"; readonly level: number; readonly start?: number; readonly marker?: { readonly text?: string; readonly styleIndex?: number; readonly gap?: number; }; }源码
readonly runs: readonly RichTextRunRecord[]源码

空段落以及携带样式的空文本片段都会保留。

interface RichTextRunRecord

源码
readonly text: string源码

文本片段携带各自的文本,因此 UTF-8 字节边界的编码不会受 UTF-16 歧义影响。

readonly styleIndex: number源码

type ResourceKind = "font" | "image" | "blob"

源码

已注册资源的类型。wire 代码(font 1、image 2、blob 3) 即 C++ ResourceKind 的值。

原生: ResourceKind

变更批次与 wire 协议

变更批次由一个头部和随后的命令组成,例如“upsert path”或“remove node”。C++ 会话要么完整应用一个批次,要么完全不应用。独立的矢量网络载荷使用另一个冻结的版本,用于叠加层和布尔运算结果。

class RenderChangeBatchEncoder

源码

构建一个保留场景的变更批次:20 字节的头部(魔数 TCR1、 RENDER_CORE_WIRE_VERSION、各项大小和命令数),后跟若干命令。 每个方法追加一条命令并返回编码器,因此可以链式调用; finish 返回字节。每个值在添加时都会按 WIRE_LIMITS 和节点规则进行检查,因此错误的节点会在这里抛出,而不是在渲染器中。 字节布局见 PROTOCOL.md。

渲染器通过 RenderCoreSession.apply 应用批次,它会调用 taco_render_session_apply。RetainedSession.apply 使用 WireReader 读取批次,并且要么应用全部命令,要么一条都不应用。

原生: taco_render_session_apply, RetainedSession.apply, WireReader

resetScene(width: number, height: number, clearResources = true): this源码

移除所有节点,并以文档单位设置场景大小。启用 clearResources(默认)时,还会移除所有资源。

resizeScene(width: number, height: number): this源码

更改场景大小,保留所有节点和资源。编辑器的场景就是以文档单位表示的视口, 因此缩放会调整场景大小;若改用重置,则会白白丢弃已编译的场景和所有绘制缓存。

registerResource(id: string, kind: ResourceKind, bytes: Uint8Array): this源码

在 id 下添加或替换一个资源,例如字体文件。

removeResource(id: string): this源码

移除一个资源。

upsertPath(node: RetainedPathNode): this源码

添加或替换一个路径节点:包括其矢量网络、样式、圆角半径和端点。

upsertText(node: RetainedTextNode): this源码

添加或替换一个文本节点及其样式和段落。

upsertContainer(node: RetainedContainerNode): this源码

添加或替换一个画框或编组:包括大小、裁剪和圆角半径。

upsertMedia(node: RetainedMediaNode): this源码

添加或替换一个图片或视频节点。其像素以媒体帧的形式送达。

removeNode(id: string): this源码

移除一个节点及其所有后代。

setTransform(id: string, transform: RetainedNodeBase["transform"]): this源码

仅更改现有节点的变换。

finish(): Uint8Array源码

写入批次头部,并返回完整的批次字节。

const WIRE_LIMITS: Readonly< { batchBytes: number; commands: 100000; identifierBytes: 1024; textBytes: number; nodes: 100000; resources: 4096; resourceBytes: number; batchResourceBytes: number; retainedPayloadBytes: number; vectorVertices: 1000000; vectorSegments: 1000000; vectorConstraints: 1000000; vectorRegions: 100000; vectorLoops: 1000000; vectorReferences: 3000000; regionPaints: 100000; nodePaints: 100000; gradientStops: 1000000; textStyles: 65536; textParagraphs: 65536; textRuns: 65536; fontFallbacks: 4096; fontFallbackReferences: 65536; openTypeSettings: 256; strokeDashIntervals: 64; shadows: 16; nodeStrokes: 16; } >

源码

单个变更批次和整个保留场景的大小与数量限制。编码器会在写入超出限制之前抛出 RangeError,C++ 读取器也会拒绝任何超出相同限制的批次(即 session.h 中的 kMaximum* 常量)。retainedPayloadBytes 限制整个场景: 节点、标识符、矢量和文本数据以及资源。

const RENDER_CORE_WIRE_VERSION: 24

源码

RenderChangeBatchEncoder 写出的变更批次版本。

原生: TACO_RENDER_WIRE_VERSION

const RENDER_CHANGE_COMMAND_HEADER_BYTES: 8

源码

每个命令头的大小:u8 操作码、三个保留字节、u32 载荷长度。

const RENDER_CORE_VECTOR_NETWORK_WIRE_VERSION: 5

源码

无头部的独立 VectorNetwork 载荷所用的固定 wire 版本。

原生: TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION

function encodeVectorNetworkRecord(network: VectorNetworkRecord): Uint8Array

源码

为临时原生叠加层和布尔运算结果编码一个独立的 VectorNetwork 数据。它的冻结版本为 RENDER_CORE_VECTOR_NETWORK_WIRE_VERSION,与当前批次版本无关。它刻意不带批次头或命令头,并使用与保留路径命令相同的校验、边界、规范顺序和绘制表示。C++ 端用 decodeVectorNetwork 读取它。

原生: decodeVectorNetwork

function decodeVectorNetworkRecord(bytes: Uint8Array): VectorNetworkRecord

源码

解码恰好一个规范的独立 VectorNetwork,例如 C++ 端用 encodeVectorNetwork 写出的布尔运算结果。该数据必须能经共享编码器逐字节往返一致,从而保证布尔查询结果不会与保留路径和矢量叠加层的 wire 语义产生偏差。

原生: encodeVectorNetwork

原生,经由 encodeVectorNetworkRecord: decodeVectorNetwork

Wire 版本历史

场景 wire 格式版本的每次提升,最新的在前,并附上做出该改动的提交。

版本提交标题引入于
24fix(render-core): tight paint bounds for lines/connectors; exports cover everything a layer and its children paintd00b191 #121 2026-10-04
23feat(web): Stroke settings panel with dashes, end points and joins, and round Pencil strokesdad417a #88 2026-09-28
22feat(web): add connectors: Connector tool, key-point attach points, pinned and re-attachable ends, and line end stylesf6199e2 #73 2026-09-28
21feat(web): transform a multi-selection through one box, as in Figmab833870 #72 2026-09-27
20refactor(render-core): paint transform handles with the size and angle the editor sends0d6ea45 #71 2026-09-27
19feat(model): hide paints and give each paint a blend modec753479 #59 2026-09-26
18feat(model): give each rectangle and frame stroke its own side weights7382f68 #55 2026-09-26
17feat(web): auto layout gap and padding handles on the canvas, drawn by the renderera292d32 #67 2026-09-26
16feat(web): draw the rulers in the renderer and hit-test rulers and guides7b2e247 #64 2026-09-26
15feat(web): draw frame titles in the renderer and hit-test them to select, move and rename frames555ae8d #62 2026-09-26
14feat(model): round each corner of rectangles and frames on its owne6739c6 #54 2026-09-26
13feat: draw lines, arrows, ellipses, polygons and stars4c61909 #20 2026-09-23
12feat(render-core): round vector vertices with per-vertex corner radii837342a 2026-09-18
11feat(render-core): support corner smoothing and rounded framesa9795ca 2026-09-17
10feat(render-core): support blend modes and sibling masksb90c0f5 2026-09-17
9feat(render-core): support inner shadows, layer blur, and background blurebc9460 2026-09-17
8feat(render-core): support radial, angular, and image paints142ea63 2026-09-17
7feat(render-core): support multiple strokes per noded037d4d 2026-09-17
6feat(render-core): support positioned strokes9bac561 2026-08-18
5feat(render-core): add wire-v5 retained styling5aa0d67 2026-08-12
4feat(render-core): retain media scene metadatad4dee2d 2026-08-12
3feat(renderer): retain rich text in wire v34a4a289 2026-08-10
2feat(renderer): add interactive C++ foundation5e38c7a 2026-08-10

来自对 RENDER_CORE_WIRE_VERSION 执行的 git log -S。文字是提升该版本的提交的标题(英文)。

Wasm 模块与会话

RenderCoreModule 和 RenderCoreSession 是与具体渲染器无关的会话接口;可移植 Wasm 门面(facade)基于 C ABI 实现它们。不含 Skia 的构建使用 createPortableWasmRenderCore;在同样负责绘制的构建中额外创建会话使用 createOwnedWasmRenderCoreSession;封装由其他后端持有的会话则使用 attachPortableWasmRenderCoreSession。

interface RenderCoreModule

源码

一个可以创建会话的已加载渲染器构建。

readonly capabilities: RenderCoreCapabilities源码

此构建支持的功能。

createSession(): RenderCoreSession源码

创建一个场景为空的会话。

原生: taco_render_session_destroy

原生(在辅助函数中): taco_render_session_create

interface RenderCoreSession

源码

在编辑器契约背后使用的底层同步 wire / C ABI 会话。

一个会话持有一个保留场景。每个方法都是对一个 C 函数的薄封装。 接受 expectedGeneration 的查询在场景自该代之后发生过变化时会失败, 因此过时的结果不会被误当作当前结果。节点或资源不存在时,查询返回 undefined。 PortableWasmRenderCoreSession 是其 Wasm 实现。

apply(batch: Uint8Array): RenderUpdateReport源码

应用一个来自 RenderChangeBatchEncoder 的变更批次。批次要么完全应用, 要么完全不应用;被拒绝的批次会抛出异常。

原生: taco_render_session_apply

原生(在辅助函数中): taco_render_session_get_last_dirty_bounds, taco_render_session_copy_last_error

applyWithStaticImageFrames( batch: Uint8Array, expectedGeneration: bigint, frames: readonly RenderStaticImageFrame[] ): RenderUpdateReport源码

原子地发布批次以及候选代的精确静态图片集合。

原生: taco_render_session_apply_with_static_image_frames

原生(在辅助函数中): taco_render_session_get_last_dirty_bounds, taco_render_session_copy_last_error

applyWithMediaFrames( batch: Uint8Array, expectedGeneration: bigint, frames: readonly RenderMediaFrame[] ): RenderUpdateReport源码

原子地发布批次及其精确的图片 / 视频混合帧集合。

原生: taco_render_session_apply_with_media_frames

原生(在辅助函数中): taco_render_session_get_last_dirty_bounds, taco_render_session_copy_last_error

updateVideoFrames( expectedGeneration: bigint, frames: readonly RenderVideoFrame[] ): RenderUpdateReport源码

仅替换视频帧,同时保持场景标识完全不变。

原生: taco_render_session_update_video_frames

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

getSceneInfo(): RenderSceneInfo源码

场景大小、计数、代和摘要。

原生: taco_render_session_get_scene_info

原生(在辅助函数中): taco_render_session_copy_last_error

getNodeGeometry(id: string): RenderNodeGeometry | undefined源码

一个节点的边界和变换。

原生: taco_render_session_get_node_geometry

原生(在辅助函数中): taco_render_session_copy_last_error

getGeometrySnapshot(): RenderGeometrySnapshot源码

所有节点的几何信息,按从后到前的顺序排列。

原生: taco_render_session_get_geometry_snapshot

原生(在辅助函数中): taco_render_session_copy_last_error

原生,经由 decodeWasmGeometryRecords: TacoRenderGeometryRecord

hitTest(x: number, y: number, worldTolerance?: number): readonly RenderHit[]源码

使用显式的世界空间容差,按从上到下的顺序返回几何命中结果。

原生: taco_render_session_hit_test

原生(在辅助函数中): taco_render_session_copy_last_error

原生,经由 decodeWasmHitRecords: TacoRenderHit

getTextCarets( nodeId: string, expectedGeneration?: bigint ): RenderTextCaretSnapshot | undefined源码

文本节点中的每个光标位置及其几何信息。

原生: taco_render_session_get_text_carets

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

getTextRangeGeometry( nodeId: string, range: RenderTextRange, expectedGeneration?: bigint ): RenderTextRangeGeometry | undefined源码

覆盖某个文本范围的矩形,每行一个或多个。

原生: taco_render_session_get_text_range_rects

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

hitTestText( nodeId: string, localX: number, localY: number, expectedGeneration?: bigint ): RenderTextHitResult | undefined源码

在节点局部坐标中距某点最近的文本位置。

原生: taco_render_session_hit_test_text

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

navigateText( nodeId: string, from: RenderTextPosition, operation: RenderTextNavigationOperation, preferredLocalX?: number, expectedGeneration?: bigint ): RenderTextNavigationResult | undefined源码

将文本位置移动一个光标步长。上下跨行移动时,preferredLocalX 用于保持所在列。

原生: taco_render_session_navigate_text

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

getTextLayoutMetrics( nodeId: string, expectedGeneration?: bigint ): RenderTextLayoutMetrics | undefined源码

文本节点的行度量以及建议的自动尺寸。

原生: taco_render_session_get_text_layout_metrics

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

getFontMetadata( fontResourceId: string, expectedGeneration?: bigint ): RenderFontMetadataSnapshot | undefined源码

一个字体资源的 OpenType 特性标签和可变轴。

原生: taco_render_session_get_font_metadata

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

setTextEditingOverlay( nodeId: string, overlay: RenderTextEditingOverlay, expectedGeneration?: bigint ): void源码

绘制正在编辑的文本节点的选区、输入法组合范围和光标。 下一次场景变更会将其清除。

原生: taco_render_session_set_text_editing_overlay

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

clearTextEditingOverlay(expectedGeneration?: bigint): void源码

移除文本编辑叠加层。

原生: taco_render_session_clear_text_editing_overlay

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

setSelectionChrome(chrome: RenderSelectionChrome | null): boolean源码

替换渲染器绘制在场景之上的选区轮廓和控制柄,或传入 null 将其清除。 若已加载的模块早于原生选区框与控制柄的实现,则返回 false,由宿主继续使用自己的实现。

原生: taco_render_session_set_selection_chrome

原生(在辅助函数中): taco_render_session_copy_last_error

原生,经由 encodeSelectionChrome: taco_render_session_set_selection_chrome, SessionCache.setSelectionChrome

setCanvasOverlay(overlay: RenderCanvasOverlay | null): void源码

替换渲染器绘制在场景之上的叠加层线条,或传入 null 将其清除。 已加载的模块无法绘制这些线条时会抛出异常。

原生: taco_render_session_set_canvas_overlay

原生(在辅助函数中): taco_render_session_copy_last_error

原生,经由 encodeCanvasOverlay: taco_render_session_set_canvas_overlay, SessionCache.setCanvasOverlay

setCanvasOverlayFont(bytes: Uint8Array): boolean源码

设置画布叠加层中画框标题所用的字体文件(TrueType、OpenType 或 WOFF2 字节)。已加载的模块无法绘制标题时返回 false。

原生: taco_render_session_set_canvas_overlay_font

原生(在辅助函数中): taco_render_session_copy_last_error

getVectorGeometry( nodeId: string, documentToScreen: Transform, expectedGeneration?: bigint ): RenderVectorGeometrySnapshot | undefined源码

矢量节点的顶点、控制柄、线段和区域,以及由 documentToScreen 得出的屏幕位置。

原生: taco_render_session_get_vector_geometry

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 decodeWasmVectorGeometry: TacoRenderVectorVertex, TacoRenderVectorCubicHandle, TacoRenderVectorSegment, TacoRenderVectorRegion

hitTestVector( nodeId: string, query: RenderVectorHitQuery, expectedGeneration?: bigint ): RenderVectorHitSnapshot | undefined源码

屏幕上某点附近的矢量顶点、控制柄、线段和区域。

原生: taco_render_session_hit_test_vector

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 decodeWasmVectorHits: TacoRenderVectorHit

booleanVectorPaths( request: RenderVectorBooleanPathRequest, expectedGeneration?: bigint ): RenderVectorBooleanPathSnapshot源码

合并两个节点的路径,并返回结果矢量网络。

原生: taco_render_session_boolean_vector_paths

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 decodeVectorNetworkRecord: encodeVectorNetwork

setVectorEditingOverlay( nodeId: string, overlay: RenderVectorEditingOverlay, expectedGeneration?: bigint ): void源码

绘制一个节点的矢量编辑叠加层(顶点、控制柄和选区)。 下一次场景变更会将其清除。

原生: taco_render_session_set_vector_editing_overlay

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 encodeVectorNetworkRecord: decodeVectorNetwork

clearVectorEditingOverlay(expectedGeneration?: bigint): void源码

移除矢量编辑叠加层。

原生: taco_render_session_clear_vector_editing_overlay

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

mapViewport(options: ViewportMappingOptions): ViewportMapping源码

计算场景如何适配给定大小的视口。

原生: taco_render_session_map_viewport

原生(在辅助函数中): taco_render_session_copy_last_error

render(target: RgbaRenderTarget): RenderFrameReport源码

将场景绘制到 RGBA 像素缓冲区中。没有 CPU 光栅后端的构建(例如可移植的 Wasm 构建)会抛出异常。

原生: taco_render_session_render_rgba

原生(在辅助函数中): taco_render_session_copy_last_error

getLastError(): string源码

复制会话持有的诊断字符串;不会有原生内存泄露到外部。

原生(在辅助函数中): taco_render_session_copy_last_error

dispose(): void源码

释放会话。之后的调用会抛出异常。

原生: taco_render_session_destroy

interface RenderCoreCapabilities

源码

已加载的渲染器构建支持的功能,从 C 能力结构体中读取。 调用对应的会话方法之前,先用 requireRenderCapability 检查标志。

原生: TacoRenderCapabilities, TacoRenderExtendedCapabilities

readonly abiVersion: number源码
readonly wireVersion: number源码

保留场景 / 变更批次的 wire 版本。

readonly vectorNetworkWireVersion: number源码

叠加层和布尔运算结果使用的无头部 VectorNetwork 载荷版本。

readonly retainedScene: boolean源码
readonly structuredPaths: boolean源码
readonly styledTextRecords: boolean源码
readonly embeddedResources: boolean源码
readonly skia: boolean源码
readonly nativeRaster: boolean源码
readonly wasm: boolean源码
readonly webgpu: boolean源码
readonly skparagraph: boolean源码
readonly harfbuzz: boolean源码
readonly icu: boolean源码
readonly geometryQueries: boolean源码
readonly hitTesting: boolean源码
readonly dirtyBounds: boolean源码
readonly textCarets: boolean源码
readonly textRangeRects: boolean源码
readonly textHitTesting: boolean源码
readonly textNavigation: boolean源码
readonly textLayoutMetrics: boolean源码
readonly textEditingOverlays: boolean源码
readonly fontMetadata: boolean源码
readonly incrementalRendering: boolean源码
readonly renderDiagnostics: boolean源码
readonly staticImageFrames: boolean源码
readonly videoFrames: boolean源码
readonly vectorGeometry: boolean源码
readonly vectorHitTesting: boolean源码
readonly vectorEditingOverlays: boolean源码
readonly vectorBooleanOperations: boolean源码

type RequiredRenderCapability = | "skia" | "nativeRaster" | "wasm" | "webgpu" | "skparagraph" | "harfbuzz" | "icu" | "textCarets" | "textRangeRects" | "textHitTesting" | "textNavigation" | "textLayoutMetrics" | "textEditingOverlays" | "fontMetadata" | "incrementalRendering" | "renderDiagnostics" | "staticImageFrames" | "videoFrames" | "vectorGeometry" | "vectorHitTesting" | "vectorEditingOverlays" | "vectorBooleanOperations"

源码

requireRenderCapability 可以检查的能力标志。

function requireRenderCapability( capabilities: RenderCoreCapabilities, capability: RequiredRenderCapability ): void

源码

除非 capabilities 具有该标志,否则抛出 RenderCoreCapabilityError。

class RenderCoreCapabilityError extends Error

源码

当构建缺少某项能力时,由 requireRenderCapability 抛出。

readonly capability: RequiredRenderCapability源码
new (capability: RequiredRenderCapability)源码

function createPortableWasmRenderCore( module: PortableWasmExports, options: PortableWasmFacadeOptions = {} ): PortableWasmRenderCoreModule

源码

包装一个已加载的可移植 Wasm 模块;参见 PortableWasmRenderCoreModule。

class PortableWasmRenderCoreModule implements RenderCoreModule

源码

基于可移植 Wasm 构建(不含 Skia)的 RenderCoreModule。构造函数会检查模块的导出以及 ABI 和 wire 版本,并拒绝带有渲染器的模块;这类模块请使用 createOwnedWasmRenderCoreSession。

readonly capabilities: RenderCoreCapabilities源码
new (module: PortableWasmExports, options: PortableWasmFacadeOptions = {})源码

原生(在辅助函数中): taco_render_wasm_abi_version, taco_render_wasm_wire_version, taco_render_wasm_vector_network_wire_version, taco_render_wasm_portable_capabilities, taco_render_get_capabilities, taco_render_get_extended_capabilities

createSession(): PortableWasmRenderCoreSession源码

原生: taco_render_session_destroy

原生(在辅助函数中): taco_render_session_create

function createOwnedWasmRenderCoreSession( module: PortableWasmExports, options: PortableWasmFacadeOptions = {} ): PortableWasmRenderCoreSession

源码

在同样带有渲染器的模块(例如 Skia WebGPU 构建)中创建第二个由门面拥有的会话。createPortableWasmRenderCore 会拒绝这类模块,因为它要认证的是不含 Skia 的基础模块;此入口只跳过这项认证。释放该门面会销毁原生会话。

原生: taco_render_session_destroy

原生(在辅助函数中): taco_render_wasm_abi_version, taco_render_wasm_wire_version, taco_render_wasm_vector_network_wire_version, taco_render_wasm_portable_capabilities

另有 3 项taco_render_get_capabilities, taco_render_get_extended_capabilities, taco_render_session_create

function attachPortableWasmRenderCoreSession( module: PortableWasmExports, session: number, options: PortableWasmFacadeOptions = {} ): PortableWasmRenderCoreSession

源码

将共享的严格 Wasm C ABI 门面(facade)附加到一个生命周期由渲染器后端管理的会话上。释放该门面只会释放它的暂存内存;原生会话句柄仍由后端负责。

原生(在辅助函数中): taco_render_wasm_abi_version, taco_render_wasm_wire_version, taco_render_wasm_vector_network_wire_version, taco_render_wasm_portable_capabilities, taco_render_get_capabilities, taco_render_get_extended_capabilities

interface PortableWasmRenderCoreSession extends RenderCoreSession

源码

RenderCoreSession 的 Wasm 实现。每个方法都会将输入复制到 Wasm 内存中,调用一个 taco_render_session_* 函数,严格检查结果,再把输出复制回来,因此不会有 Wasm 内存泄露到外部。

readonly capabilities: RenderCoreCapabilities源码

已加载模块支持哪些功能。

readonly transferMetrics: WasmBatchStagingMetrics源码

用于将批次传入 Wasm 内存的复用缓冲区的计数器。

exportScene(request: RenderExportRequest): RenderExportResult源码

将一个场景区域绘制到光栅、SVG 或 PDF 目标中。

原生: taco_render_session_export, taco_render_session_copy_export_bytes

原生(在辅助函数中): taco_render_session_copy_last_error

outlineStroke( request: RenderStrokeOutlineRequest, expectedGeneration?: bigint, budget?: StrokeOutlineBudget ): RenderStrokeOutlineSnapshot | undefined源码

One stroke of a path or container node as the filled shape it paints (see RenderStrokeOutlineSnapshot), or undefined when the node does not exist. Throws PortableWasmStatusError when the node has no such stroke, is a text or media node, or the stroke cannot be outlined; its detail is the renderer’s reason. Throws a plain error when the renderer build predates the query. With a budget, the outline’s size on the wire is charged to it before the outline is copied out and decoded; one that does not fit throws StrokeOutlineBudgetError.

原生: taco_render_session_outline_stroke

原生(在辅助函数中): taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 decodeVectorNetworkRecord: encodeVectorNetwork

interface PortableWasmFacadeOptions extends WasmBatchStagingOptions

源码

可选的上限,限制单次查询可向模块申请的内存量。每个值都必须为正数,且不超过门面内置的最大值。

readonly maximumQueryRecords?: number源码
readonly maximumTextQueryRecords?: number源码
readonly maximumQueryIdentifierBytes?: number源码
readonly maximumVectorQueryRecords?: number源码
readonly maximumVectorIdentifierBytes?: number源码
readonly maximumErrorBytes?: number源码

interface PortableWasmExports extends WasmBatchMemory

源码

门面所需的 Emscripten 模块接口:Wasm 堆、malloc 和 free,以及导出的 taco_render_* C 函数(Emscripten 会给每个函数加上下划线前缀)。

_taco_render_get_capabilities(capabilities: number): number源码
_taco_render_get_extended_capabilities( version: number, capabilities: number ): number源码
_taco_render_session_create(options: number, sessionOutput: number): number源码
_taco_render_session_destroy(session: number): void源码
_taco_render_session_apply( session: number, batch: number, batchSize: number, report: number ): number源码
_taco_render_session_apply_with_static_image_frames( session: number, batch: number, batchSize: number, frameSet: number, report: number ): number源码
_taco_render_session_apply_with_media_frames( session: number, batch: number, batchSize: number, frameSet: number, report: number ): number源码
_taco_render_session_update_video_frames( session: number, frameSet: number, dirtyBounds: number ): number源码
_taco_render_session_get_scene_info(session: number, info: number): number源码
_taco_render_session_get_node_geometry( session: number, nodeId: number, nodeIdSize: number, geometry: number ): number源码
_taco_render_session_get_geometry_snapshot( session: number, records: number, recordCapacity: number, nodeIds: number, nodeIdCapacity: number, generation: number, recordCount: number, nodeIdByteCount: number ): number源码
_taco_render_session_hit_test( session: number, worldX: number, worldY: number, worldTolerance: number, hits: number, hitCapacity: number, nodeIds: number, nodeIdCapacity: number, hitCount: number, nodeIdByteCount: number ): number源码
_taco_render_session_get_last_dirty_bounds( session: number, dirtyBounds: number ): number源码
_taco_render_session_get_text_carets( session: number, nodeId: number, nodeIdSize: number, query: number, carets: number, caretCapacity: number, result: number ): number源码
_taco_render_session_get_text_range_rects( session: number, nodeId: number, nodeIdSize: number, query: number, rects: number, rectCapacity: number, result: number ): number源码
_taco_render_session_hit_test_text( session: number, nodeId: number, nodeIdSize: number, query: number, result: number ): number源码
_taco_render_session_navigate_text( session: number, nodeId: number, nodeIdSize: number, query: number, result: number ): number源码
_taco_render_session_get_text_layout_metrics( session: number, nodeId: number, nodeIdSize: number, query: number, metrics: number ): number源码
_taco_render_session_get_font_metadata( session: number, fontResourceId: number, fontResourceIdSize: number, query: number, features: number, featureCapacity: number, axes: number, axisCapacity: number, result: number ): number源码
_taco_render_session_set_text_editing_overlay( session: number, nodeId: number, nodeIdSize: number, overlay: number ): number源码
_taco_render_session_clear_text_editing_overlay( session: number, query: number ): number源码
_taco_render_session_set_selection_chrome?( session: number, bytes: number, size: number ): number源码

在原生选区框与控制柄之前构建的模块中不存在。

_taco_render_session_set_canvas_overlay?( session: number, bytes: number, size: number ): number源码

在原生叠加层线条之前构建的模块中不存在。

_taco_render_session_set_canvas_overlay_font?( session: number, bytes: number, size: number ): number源码

在画布叠加层支持画框标题之前构建的模块中不存在。

_taco_render_session_get_vector_geometry( session: number, nodeId: number, nodeIdSize: number, query: number, vertices: number, vertexCapacity: number, handles: number, handleCapacity: number, segments: number, segmentCapacity: number, regions: number, regionCapacity: number, identifiers: number, identifierCapacity: number, result: number ): number源码

Absent from modules built before wire version 24.

_taco_render_session_hit_test_vector( session: number, nodeId: number, nodeIdSize: number, query: number, hits: number, hitCapacity: number, identifiers: number, identifierCapacity: number, result: number ): number源码
_taco_render_session_set_vector_editing_overlay( session: number, nodeId: number, nodeIdSize: number, overlay: number, networkBytes: number, networkByteCount: number, components: number, componentCount: number, identifiers: number, identifierByteCount: number ): number源码
_taco_render_session_clear_vector_editing_overlay( session: number, query: number ): number源码
_taco_render_session_boolean_vector_paths( session: number, primaryNodeId: number, primaryNodeIdSize: number, secondaryNodeId: number, secondaryNodeIdSize: number, resultIdNamespace: number, resultIdNamespaceSize: number, query: number, networkBytes: number, networkCapacity: number, result: number ): number源码
_taco_render_session_map_viewport( session: number, options: number, mapping: number ): number源码
_taco_render_session_render_rgba(session: number, target: number): number源码
_taco_render_session_render_rgba_incremental( session: number, target: number, options: number, report: number ): number源码
_taco_render_session_export?( session: number, request: number, result: number ): number源码

可选:在场景导出功能之前的构建中,两个导出入口都不存在。

_taco_render_session_copy_export_bytes?( session: number, destination: number, destinationSize: number ): number源码
_taco_render_session_copy_last_error( session: number, destination: number, destinationSize: number ): number源码
_taco_render_wasm_abi_version(): number源码
_taco_render_session_outline_stroke?( session: number, nodeId: number, nodeIdSize: number, resultIdNamespace: number, resultIdNamespaceSize: number, query: number, networkBytes: number, networkCapacity: number, result: number ): number源码

Absent from renderer builds made before stroke outlines; no capability flag announces it, so outlineStroke checks for the export.

_taco_render_wasm_vector_network_wire_version(): number源码
_taco_render_wasm_wire_version(): number源码
_taco_render_wasm_portable_capabilities(): number源码

class PortableWasmAbiError extends Error

源码

Wasm 模块违反了 C ABI 约定:缺少导出、版本错误,或结果中的大小、保留字节或值不正确。

new (message: string)源码

class PortableWasmStatusError extends Error

源码
readonly operation: string源码
readonly status: RenderCoreStatus源码
readonly statusName: string源码
readonly detail: string源码
new (operation: string, status: RenderCoreStatus, detail = "")源码

const RENDER_CORE_STATUS: Readonly< { readonly ok: 0; readonly invalidArgument: 1; readonly unsupportedVersion: 2; readonly malformedBatch: 3; readonly limitExceeded: 4; readonly invalidScene: 5; readonly notFound: 6; readonly capabilityUnavailable: 7; readonly bufferTooSmall: 8; readonly internalError: 9; readonly staleGeneration: 10; } >

源码

每个 C 函数返回的状态码,按名称列出。其值为 TacoRenderStatus 常量。

原生: TacoRenderStatus

type RenderCoreStatus = (typeof RENDER_CORE_STATUS)[keyof typeof RENDER_CORE_STATUS]

源码

一个 RENDER_CORE_STATUS 值。

const RENDER_CORE_ABI_VERSION: 1

源码

本包使用的 C ABI 版本。Wasm 模块报告的版本必须与之相同。

原生: TACO_RENDER_ABI_VERSION

const PORTABLE_WASM_ABI_LAYOUT: Readonly< { readonly capabilitiesBytes: 28; readonly sessionOptionsBytes: 32; readonly updateReportBytes: 32; readonly sceneInfoBytes: 48; readonly nodeGeometryBytes: 216; readonly geometryRecordBytes: 184; readonly dirtyBoundsBytes: 112; readonly hitRecordBytes: 64; readonly viewportOptionsBytes: 40; readonly viewportMappingBytes: 136; readonly rgbaTargetBytes: 24; readonly staticImageFrameBytes: 56; readonly staticImageFrameSetBytes: 24; readonly extendedCapabilitiesBytes: 88; readonly textQueryBytes: 16; readonly textPositionBytes: 16; readonly textCaretBytes: 56; readonly textBufferResultBytes: 16; readonly textRangeQueryBytes: 48; readonly textRectBytes: 40; readonly textHitQueryBytes: 32; readonly textHitResultBytes: 32; readonly textNavigationQueryBytes: 48; readonly textNavigationResultBytes: 48; readonly textLayoutMetricsBytes: 80; readonly textEditingOverlayBytes: 80; readonly vectorQueryBytes: 64; readonly vectorVertexBytes: 48; readonly vectorHandleBytes: 64; readonly vectorSegmentBytes: 144; readonly vectorRegionBytes: 96; readonly vectorBufferResultBytes: 40; readonly vectorHitQueryBytes: 88; readonly vectorHitBytes: 40; readonly vectorHitBufferResultBytes: 24; readonly vectorEditingOverlayBytes: 128; readonly vectorEditingComponentBytes: 32; readonly vectorEditingOverlayQueryBytes: 16; readonly vectorBooleanQueryBytes: 24; readonly vectorBooleanResultBytes: 16; readonly strokeOutlineQueryBytes: 24; readonly strokeOutlineResultBytes: 16; readonly fontMetadataQueryBytes: 16; readonly fontFeatureBytes: 8; readonly fontAxisBytes: 40; readonly fontMetadataResultBytes: 24; } >

源码

ABI 版本 1 经过审核的 wasm32 布局:门面在 Wasm 内存中读写的每个 C 结构体的字节大小。每一项都必须等于 render_core.h 中对应结构体的大小(例如 updateReportBytes 对应 TacoRenderUpdateReport);C++ 端用 static_assert 检查其中大部分。

原生: TacoRenderCapabilities, TacoRenderSessionOptions, TacoRenderUpdateReport, TacoRenderSceneInfo, TacoRenderNodeGeometry, TacoRenderGeometryRecord, TacoRenderDirtyBounds, TacoRenderHit

另有 36 项TacoRenderViewportOptions, TacoRenderViewportMapping, TacoRenderRgbaTarget, TacoRenderStaticImageFrame, TacoRenderStaticImageFrameSet, TacoRenderExtendedCapabilities, TacoRenderTextQuery, TacoRenderTextPosition, TacoRenderTextCaret, TacoRenderTextBufferResult, TacoRenderTextRangeQuery, TacoRenderTextRect, TacoRenderTextHitQuery, TacoRenderTextHitResult, TacoRenderTextNavigationQuery, TacoRenderTextNavigationResult, TacoRenderTextLayoutMetrics, TacoRenderTextEditingOverlay, TacoRenderVectorQuery, TacoRenderVectorVertex, TacoRenderVectorCubicHandle, TacoRenderVectorSegment, TacoRenderVectorRegion, TacoRenderVectorBufferResult, TacoRenderVectorHitQuery, TacoRenderVectorHit, TacoRenderVectorHitBufferResult, TacoRenderVectorEditingOverlay, TacoRenderVectorEditingComponent, TacoRenderVectorEditingOverlayQuery, TacoRenderVectorBooleanQuery, TacoRenderVectorBooleanResult, TacoRenderFontMetadataQuery, TacoRenderFontFeature, TacoRenderFontAxis, TacoRenderFontMetadataResult

const RENDER_FONT_METADATA_MAX_FEATURES: 131070

源码

字体元数据查询最多返回的 OpenType 特性标签数量。

原生: TACO_RENDER_FONT_METADATA_MAX_FEATURES

const RENDER_FONT_METADATA_MAX_AXES: 65535

源码

字体元数据查询最多返回的可变轴数量。

原生: TACO_RENDER_FONT_METADATA_MAX_AXES

function decodeWasmGeometryRecords( recordBytes: Uint8Array, recordCount: number, identifierBytes: Uint8Array ): readonly RenderNodeGeometry[]

源码

解码 taco_render_session_get_geometry_snapshot 写出的几何记录及其节点 ID,且不保留对 Wasm 内存的引用。

原生: TacoRenderGeometryRecord

function decodeWasmHitRecords( recordBytes: Uint8Array, hitCount: number, identifierBytes: Uint8Array ): readonly RenderHit[]

源码

解码按最上层优先排列的 ABI-v1 命中记录,且不保留 Wasm 内存。

原生: TacoRenderHit

function decodeWasmVectorGeometry( vertexBytes: Uint8Array, vertexCount: number, handleBytes: Uint8Array, handleCount: number, segmentBytes: Uint8Array, segmentCount: number, regionBytes: Uint8Array, regionCount: number, identifierBytes: Uint8Array, generation: bigint ): RenderVectorGeometrySnapshot

源码

严格解码一个带代次标记的矢量几何数据。

原生: TacoRenderVectorVertex, TacoRenderVectorCubicHandle, TacoRenderVectorSegment, TacoRenderVectorRegion

function decodeWasmVectorHits( hitBytes: Uint8Array, hitCount: number, identifierBytes: Uint8Array, generation: bigint ): RenderVectorHitSnapshot

源码

按原生的优先级、距离和顺序严格解码矢量命中结果。

原生: TacoRenderVectorHit

type RenderMediaFrame = | ({ readonly kind: "image" } & RenderStaticImageFrame) | ({ readonly kind: "video" } & RenderVideoFrame)

源码

按资源 ID 全局排序的图片 / 视频混合帧集合中的一个成员。

type RenderStaticImageFrame = | RenderStaticImageFrameReuse | RenderStaticImageFrameRgba8888

源码

完整的、按逻辑资源 ID 去重的静态图片集合中的一个成员。

interface RenderStaticImageFrameRgba8888

源码

一张紧密排列、非预乘 alpha 的 RGBA8888 sRGB 替换图片。

readonly disposition: "rgba8888"源码
readonly assetId: string源码
readonly contentRevision: bigint源码
readonly width: number源码
readonly height: number源码
readonly pixels: Uint8Array源码

interface RenderStaticImageFrameReuse

源码

复用调用方持有的内容修订号相匹配的那张当前活动图片。

readonly disposition: "reuse-active"源码
readonly assetId: string源码
readonly contentRevision: bigint源码

type RenderVideoFrame = RenderVideoFrameReuse | RenderVideoFrameRgba8888

源码

一个精确的已解码视频帧修订;替换时修订号单调递增。

interface RenderVideoFrameRgba8888 extends RenderStaticImageFrameRgba8888

源码

一个紧密排列的已解码视频帧替换。

interface RenderVideoFrameReuse extends RenderStaticImageFrameReuse

源码

复用调用方持有的某个修订号所对应的那一帧当前活动视频帧。

Wasm 内存传输

批次通过一块复用的、只增不减的内存分配进入 Wasm 内存,因此持续不断的编辑不会为每个批次都分配内存。

class ReusableWasmBatchStagingBuffer

源码

为连续的保留 wire 批次复用同一块只增不减的 Wasm 分配。 在下一次写入或释放之前,批次在返回的指针处有效。

new (memory: WasmBatchMemory, options: WasmBatchStagingOptions = {})源码
get metrics(): WasmBatchStagingMetrics源码

当前的计数器。

write(batch: Uint8Array): StagedWasmBatch源码

将批次复制到缓冲区中,需要时扩大缓冲区。

apply<Result>( batch: Uint8Array, applyBatch: (pointer: number, byteLength: number) => Result ): Result源码

写入批次,并将其指针和长度传给 applyBatch。

dispose(): void源码

释放 Wasm 分配。之后的写入会抛出异常。

interface WasmBatchMemory

源码

传输保留 wire 批次所需的最小 Emscripten 内存接口。

readonly HEAPU8: Uint8Array源码
_malloc(bytes: number): number源码
_free(pointer: number): void源码

interface StagedWasmBatch

源码

已暂存批次在 Wasm 内存中的位置。

readonly pointer: number源码
readonly byteLength: number源码

interface WasmBatchStagingOptions

源码

暂存缓冲区大小的上下限,单位为字节。上限默认为 WIRE_LIMITS.batchBytes。

readonly minimumCapacityBytes?: number源码
readonly maximumCapacityBytes?: number源码

interface WasmBatchStagingMetrics

源码

显示暂存缓冲区分配和复制频率的计数器。

readonly allocations: number源码

此暂存缓冲区在整个生命周期内进行的原生分配次数。

readonly copies: number源码

JavaScript 到 Wasm 的 HEAPU8.set 操作次数。

readonly bytesCopied: number源码
readonly capacityBytes: number源码
readonly peakBatchBytes: number源码
readonly heapGrowthBytes: number源码

自构造以来观察到的线性内存增长量,包括 Wasm 自身工作造成的增长。

readonly peakHeapBytes: number源码

字体

当文本样式的所有字体都无法绘制某个字符时,渲染器会回退到来自 Google Fonts 的内置 Noto 字体族,因此字符永远不会显示为空白方框。回退字体在渲染时选定,从不保存到文档中。

const AUTOMATIC_FALLBACK_FAMILIES: readonly [ "Noto Sans", "Noto Sans SC", "Noto Sans TC", "Noto Sans HK", "Noto Sans JP", "Noto Sans KR", "Noto Color Emoji" ]

源码

自动回退可用于绘制的内置 Noto 字体族。

type AutomaticFallbackFamily = typeof AUTOMATIC_FALLBACK_FAMILIES[number]

源码

AUTOMATIC_FALLBACK_FAMILIES 中的某一项。

function automaticFallbackFamilies( cjk: CjkFamily, emoji: boolean ): readonly AutomaticFallbackFamily[]

源码

为单个字素簇依次尝试自动回退字体族的顺序。文本先尝试 Noto Sans(拉丁文、希腊文、西里尔文、天城文和越南文),然后尝试从 cjk 开始的 CJK 字体族,最后尝试 Noto Color Emoji。emoji 字素簇(见 isEmojiGrapheme)会先尝试 Noto Color Emoji,因此带 U+FE0F 的心形会以彩色绘制,即使 CJK 字体中有黑白的心形。

function automaticFallbackAsset(family: AutomaticFallbackFamily): FontAsset

源码

代表一个自动回退字体族的字体资源。它不属于任何文档;宿主通过 CompilePageOptions.getFontSlices 为它传入该字体族已加载的文件,与“google-fonts”文档资源的做法相同。

function automaticFallbackAssetById(id: string): FontAsset | undefined

源码

具有此 ID 的自动回退资源(如果该 ID 属于自动回退资源)。

const AUTOMATIC_FALLBACK_ASSET_ID_PREFIX: "automatic-fallback/"

源码

以此前缀开头的资源 ID 保留给自动回退使用。

function isAutomaticFallbackFamily( family: string ): family is AutomaticFallbackFamily

源码

family 是否为 AUTOMATIC_FALLBACK_FAMILIES 之一。

function preferredCjkFamily( styleLanguage: string | undefined, nodeCodePoints: Iterable<number>, userLanguage: string | undefined ): CjkFamily

源码

选择由哪个 CJK 字体族绘制多个字体族都包含的汉字。字形样式因地区而异,因此按以下顺序决定:

  1. 文本样式上设置的语言(“ja”、“zh-TW”……);
  2. 文本节点本身:出现假名表示日文,出现谚文表示韩文;
  3. 用户的语言(浏览器的 navigator.language);
  4. 否则使用简体中文。

function cjkFamilyForLanguage( language: string | undefined ): CjkFamily | undefined

源码

BCP 47 语言标签所要求的字形样式对应的 CJK 字体族:“ja”对应 JP,“ko”对应 KR;中文在香港和澳门对应 HK,在繁体字(如“zh-TW”或“zh-Hant”)下对应 TC,其他情况对应 SC。其他语言和格式错误的标签返回 undefined。

function graphemeClusters(text: string): string[]

源码

将文本拆分为字素簇,即 Skia 为其选择字体的单位。

function isEmojiGrapheme(grapheme: string): boolean

源码

某个字素簇是否为以彩色绘制的 emoji:即 Unicode 推荐通用的 emoji 和 emoji 序列(RGI)之一,例如“😀”、“❤️”(带 U+FE0F)、“1️⃣”或“🇯🇵”。默认以文本样式呈现的字符(例如不带 U+FE0F 的“❤”)则不是。

function essentialCodePoints(grapheme: string): number[]

源码

字体要绘制某个字素簇时必须能映射的码点。默认可忽略字符(连接符、变体选择符)和控制字符不包括在内:文本整形会隐藏它们,而不是绘制一个空方框。

特性策略

能力说明某个渲染器构建包含什么。特性策略则说明当文档使用某个已建模的特性时产品如何处理:渲染它、在应用中处理它,或以明确的错误拒绝它。每个模型特性都有一条对应条目。

const RENDER_FEATURE_POLICY_VERSION: 25

源码

渲染器策略有意与能力探测分开。能力说明某个二进制文件包含什么; 此表说明当规范文档使用某个已建模的特性时,产品会如何处理。

interface RenderFeaturePolicy

源码
readonly feature: string源码

供测试和开发者诊断使用的稳定语义标识符。

readonly code: RenderFeaturePolicyCode源码

稳定的机器可读代码。实现状态变化时不要重命名。

readonly scope: RenderFeatureScope源码
readonly disposition: RenderFeatureDisposition源码
readonly note: string源码

当前保留模式渲染器的确切边界或归属规则。

type RenderFeaturePolicyCode = `TACO_RENDER_POLICY_${string}`

源码

type RenderFeatureDisposition = | "rendered" | "deliberate-static-policy" | "application-overlay" | "structured-rejection"

源码

type RenderFeatureScope = "node" | "style" | "asset" | "document" | "editor"

源码

const RENDER_FEATURE_POLICIES: readonly RenderFeaturePolicy[]

源码

扁平的注册表,用于诊断、文档生成和不变量测试。

const RENDER_FEATURE_POLICY_TABLES: Readonly< { sceneNodes: { readonly frame: RenderFeaturePolicy; readonly group: RenderFeaturePolicy; readonly text: RenderFeaturePolicy; readonly code: RenderFeaturePolicy; readonly "shape.rectangle": RenderFeaturePolicy; readonly "shape.ellipse": RenderFeaturePolicy; readonly "shape.polygon": RenderFeaturePolicy; readonly "shape.star": RenderFeaturePolicy; readonly "shape.line": RenderFeaturePolicy; readonly "shape.path": RenderFeaturePolicy; readonly image: RenderFeaturePolicy; readonly video: RenderFeaturePolicy; readonly connector: RenderFeaturePolicy; readonly instance: RenderFeaturePolicy; }; paints: { readonly solid: RenderFeaturePolicy; readonly "linear-gradient": RenderFeaturePolicy; readonly "radial-gradient": RenderFeaturePolicy; readonly "angular-gradient": RenderFeaturePolicy; readonly image: RenderFeaturePolicy; }; strokePositions: { readonly center: RenderFeaturePolicy; readonly inside: RenderFeaturePolicy; readonly outside: RenderFeaturePolicy; }; strokeJoins: { readonly miter: RenderFeaturePolicy; readonly bevel: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; }; strokeDashCaps: { readonly none: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; readonly square: RenderFeaturePolicy; }; layouts: { readonly absolute: RenderFeaturePolicy; readonly vertical: RenderFeaturePolicy; readonly horizontal: RenderFeaturePolicy; readonly grid: RenderFeaturePolicy; }; mediaFits: { readonly contain: RenderFeaturePolicy; readonly cover: RenderFeaturePolicy; readonly fill: RenderFeaturePolicy; }; connectorRouting: { readonly straight: RenderFeaturePolicy; readonly elbow: RenderFeaturePolicy; readonly curve: RenderFeaturePolicy; }; connectorCaps: { readonly none: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; readonly square: RenderFeaturePolicy; readonly "line-arrow": RenderFeaturePolicy; readonly "triangle-arrow": RenderFeaturePolicy; readonly "reversed-triangle": RenderFeaturePolicy; readonly "circle-arrow": RenderFeaturePolicy; readonly "diamond-arrow": RenderFeaturePolicy; }; codeDecorations: { readonly emphasis: RenderFeaturePolicy; readonly addition: RenderFeaturePolicy; readonly deletion: RenderFeaturePolicy; readonly annotation: RenderFeaturePolicy; }; vectorSegments: { readonly line: RenderFeaturePolicy; readonly cubic: RenderFeaturePolicy; readonly "elliptical-arc": RenderFeaturePolicy; }; assetKinds: { readonly image: RenderFeaturePolicy; readonly video: RenderFeaturePolicy; readonly font: RenderFeaturePolicy; }; assetSources: { readonly url: RenderFeaturePolicy; readonly data: RenderFeaturePolicy; }; variableBindings: { readonly visibility: RenderFeaturePolicy; readonly opacity: RenderFeaturePolicy; readonly width: RenderFeaturePolicy; readonly height: RenderFeaturePolicy; readonly cornerRadius: RenderFeaturePolicy; readonly fillColor: RenderFeaturePolicy; readonly strokeColor: RenderFeaturePolicy; readonly strokeWidth: RenderFeaturePolicy; readonly gap: RenderFeaturePolicy; readonly wrapGap: RenderFeaturePolicy; readonly columnGap: RenderFeaturePolicy; readonly rowGap: RenderFeaturePolicy; readonly paddingTop: RenderFeaturePolicy; readonly paddingRight: RenderFeaturePolicy; readonly paddingBottom: RenderFeaturePolicy; readonly paddingLeft: RenderFeaturePolicy; readonly fontFamily: RenderFeaturePolicy; readonly fontSize: RenderFeaturePolicy; readonly fontWeight: RenderFeaturePolicy; readonly lineHeight: RenderFeaturePolicy; readonly letterSpacing: RenderFeaturePolicy; readonly textColor: RenderFeaturePolicy; }; crossCutting: { readonly singleFill: RenderFeaturePolicy; readonly multipleFills: RenderFeaturePolicy; readonly singleStroke: RenderFeaturePolicy; readonly multipleStrokes: RenderFeaturePolicy; readonly dashedStroke: RenderFeaturePolicy; readonly rectangleCornerRadius: RenderFeaturePolicy; readonly frameCornerRadius: RenderFeaturePolicy; readonly otherCornerRadius: RenderFeaturePolicy; readonly vectorCornerRadius: RenderFeaturePolicy; readonly strokeCaps: RenderFeaturePolicy; readonly cornerSmoothing: RenderFeaturePolicy; readonly shadows: RenderFeaturePolicy; readonly innerShadows: RenderFeaturePolicy; readonly layerBlur: RenderFeaturePolicy; readonly backgroundBlur: RenderFeaturePolicy; readonly blendModes: RenderFeaturePolicy; readonly masks: RenderFeaturePolicy; readonly paintCompositing: RenderFeaturePolicy; readonly sceneExport: RenderFeaturePolicy; readonly nodeOpacity: RenderFeaturePolicy; readonly isolatedGroupOpacity: RenderFeaturePolicy; readonly rectangularClip: RenderFeaturePolicy; readonly pathRegionPaints: RenderFeaturePolicy; readonly imageCrop: RenderFeaturePolicy; readonly videoCrop: RenderFeaturePolicy; readonly videoPlayback: RenderFeaturePolicy; readonly connectorCoordinates: RenderFeaturePolicy; readonly connectorAttachments: RenderFeaturePolicy; readonly codeSyntax: RenderFeaturePolicy; readonly codeDecorations: RenderFeaturePolicy; readonly codeLineNumbers: RenderFeaturePolicy; readonly variableResolution: RenderFeaturePolicy; readonly comments: RenderFeaturePolicy; readonly rulerGuides: RenderFeaturePolicy; readonly documentMetadata: RenderFeaturePolicy; }; } >

源码

type SceneNodePolicyKey = SceneNodePolicyKeyFor<SceneNode>

源码

新增 SceneNode 或形状判别值时,必须在此处明确指定策略。

const SCENE_NODE_FEATURE_POLICIES: { readonly frame: RenderFeaturePolicy; readonly group: RenderFeaturePolicy; readonly text: RenderFeaturePolicy; readonly code: RenderFeaturePolicy; readonly "shape.rectangle": RenderFeaturePolicy; readonly "shape.ellipse": RenderFeaturePolicy; readonly "shape.polygon": RenderFeaturePolicy; readonly "shape.star": RenderFeaturePolicy; readonly "shape.line": RenderFeaturePolicy; readonly "shape.path": RenderFeaturePolicy; readonly image: RenderFeaturePolicy; readonly video: RenderFeaturePolicy; readonly connector: RenderFeaturePolicy; readonly instance: RenderFeaturePolicy; }

源码

const PAINT_FEATURE_POLICIES: { readonly solid: RenderFeaturePolicy; readonly "linear-gradient": RenderFeaturePolicy; readonly "radial-gradient": RenderFeaturePolicy; readonly "angular-gradient": RenderFeaturePolicy; readonly image: RenderFeaturePolicy; }

源码

const STROKE_POSITION_FEATURE_POLICIES: { readonly center: RenderFeaturePolicy; readonly inside: RenderFeaturePolicy; readonly outside: RenderFeaturePolicy; }

源码

const LAYOUT_FEATURE_POLICIES: { readonly absolute: RenderFeaturePolicy; readonly vertical: RenderFeaturePolicy; readonly horizontal: RenderFeaturePolicy; readonly grid: RenderFeaturePolicy; }

源码

const MEDIA_FIT_FEATURE_POLICIES: { readonly contain: RenderFeaturePolicy; readonly cover: RenderFeaturePolicy; readonly fill: RenderFeaturePolicy; }

源码

const CONNECTOR_ROUTING_FEATURE_POLICIES: { readonly straight: RenderFeaturePolicy; readonly elbow: RenderFeaturePolicy; readonly curve: RenderFeaturePolicy; }

源码

const CONNECTOR_CAP_FEATURE_POLICIES: { readonly none: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; readonly square: RenderFeaturePolicy; readonly "line-arrow": RenderFeaturePolicy; readonly "triangle-arrow": RenderFeaturePolicy; readonly "reversed-triangle": RenderFeaturePolicy; readonly "circle-arrow": RenderFeaturePolicy; readonly "diamond-arrow": RenderFeaturePolicy; }

源码

const STROKE_JOIN_FEATURE_POLICIES: { readonly miter: RenderFeaturePolicy; readonly bevel: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; }

源码

What the renderer does with each stroke join (wire version 23).

const STROKE_DASH_CAP_FEATURE_POLICIES: { readonly none: RenderFeaturePolicy; readonly round: RenderFeaturePolicy; readonly square: RenderFeaturePolicy; }

源码

What the renderer does with each dash end of a dashed stroke (wire version 23).

const CODE_DECORATION_FEATURE_POLICIES: { readonly emphasis: RenderFeaturePolicy; readonly addition: RenderFeaturePolicy; readonly deletion: RenderFeaturePolicy; readonly annotation: RenderFeaturePolicy; }

源码

const VECTOR_SEGMENT_FEATURE_POLICIES: { readonly line: RenderFeaturePolicy; readonly cubic: RenderFeaturePolicy; readonly "elliptical-arc": RenderFeaturePolicy; }

源码

const ASSET_KIND_FEATURE_POLICIES: { readonly image: RenderFeaturePolicy; readonly video: RenderFeaturePolicy; readonly font: RenderFeaturePolicy; }

源码

const ASSET_SOURCE_FEATURE_POLICIES: { readonly url: RenderFeaturePolicy; readonly data: RenderFeaturePolicy; }

源码

const VARIABLE_BINDING_FEATURE_POLICIES: { readonly visibility: RenderFeaturePolicy; readonly opacity: RenderFeaturePolicy; readonly width: RenderFeaturePolicy; readonly height: RenderFeaturePolicy; readonly cornerRadius: RenderFeaturePolicy; readonly fillColor: RenderFeaturePolicy; readonly strokeColor: RenderFeaturePolicy; readonly strokeWidth: RenderFeaturePolicy; readonly gap: RenderFeaturePolicy; readonly wrapGap: RenderFeaturePolicy; readonly columnGap: RenderFeaturePolicy; readonly rowGap: RenderFeaturePolicy; readonly paddingTop: RenderFeaturePolicy; readonly paddingRight: RenderFeaturePolicy; readonly paddingBottom: RenderFeaturePolicy; readonly paddingLeft: RenderFeaturePolicy; readonly fontFamily: RenderFeaturePolicy; readonly fontSize: RenderFeaturePolicy; readonly fontWeight: RenderFeaturePolicy; readonly lineHeight: RenderFeaturePolicy; readonly letterSpacing: RenderFeaturePolicy; readonly textColor: RenderFeaturePolicy; }

源码

新增可绑定的模型属性时,必须为渲染器制定明确的策略。

const CROSS_CUTTING_FEATURE_POLICIES: { readonly singleFill: RenderFeaturePolicy; readonly multipleFills: RenderFeaturePolicy; readonly singleStroke: RenderFeaturePolicy; readonly multipleStrokes: RenderFeaturePolicy; readonly dashedStroke: RenderFeaturePolicy; readonly rectangleCornerRadius: RenderFeaturePolicy; readonly frameCornerRadius: RenderFeaturePolicy; readonly otherCornerRadius: RenderFeaturePolicy; readonly vectorCornerRadius: RenderFeaturePolicy; readonly strokeCaps: RenderFeaturePolicy; readonly cornerSmoothing: RenderFeaturePolicy; readonly shadows: RenderFeaturePolicy; readonly innerShadows: RenderFeaturePolicy; readonly layerBlur: RenderFeaturePolicy; readonly backgroundBlur: RenderFeaturePolicy; readonly blendModes: RenderFeaturePolicy; readonly masks: RenderFeaturePolicy; readonly paintCompositing: RenderFeaturePolicy; readonly sceneExport: RenderFeaturePolicy; readonly nodeOpacity: RenderFeaturePolicy; readonly isolatedGroupOpacity: RenderFeaturePolicy; readonly rectangularClip: RenderFeaturePolicy; readonly pathRegionPaints: RenderFeaturePolicy; readonly imageCrop: RenderFeaturePolicy; readonly videoCrop: RenderFeaturePolicy; readonly videoPlayback: RenderFeaturePolicy; readonly connectorCoordinates: RenderFeaturePolicy; readonly connectorAttachments: RenderFeaturePolicy; readonly codeSyntax: RenderFeaturePolicy; readonly codeDecorations: RenderFeaturePolicy; readonly codeLineNumbers: RenderFeaturePolicy; readonly variableResolution: RenderFeaturePolicy; readonly comments: RenderFeaturePolicy; readonly rulerGuides: RenderFeaturePolicy; readonly documentMetadata: RenderFeaturePolicy; }

源码

描述建模基数、跨字段行为以及由应用拥有的展示/编辑器状态的策略,而不是字符串联合类型。

其他导出

尚未归入上述章节的导出,按字母顺序排列。

function compilePageRecords( document: DesignDocument, pageId: PageId, options: CompilePageOptions ): readonly RetainedNodeRecord[]

源码

The retained node records a page compiles to, in paint order, before they are encoded; compilePageBatch encodes the same records. For tests and tools that compare compiled scenes.

const compilerApplyStats: { orderPathComputations: number; hierarchyRebuilds: number; resourceMapCopies: number; reusableResourceScans: number; incrementalAncestorWalks: number; }

源码

function createStrokeOutlineBudget( maximumNetworkBytes: number, maximumRendererMilliseconds: number ): StrokeOutlineBudget

源码

A new budget for one command, with nothing charged yet.

function documentWithEditorInstances( canonical: DesignDocument, renderer: DesignDocument | undefined ): DesignDocument

自 0.26.0源码

The canonical document with the instance nodes a renderer projection adds for the editor (the “Show all variants” views of isolation mode, which draw a component with other property values). Such an instance and the layers inside it stand for themselves in hits and geometry, as a page instance does, although no canonical node owns them. The canonical document itself when the projection adds none.

function expandPageInstances( document: DesignDocument, pageId: PageId, resolver: InstanceResolver = resolveInstance, cache?: InstanceResolveCache ): InstanceExpansion

源码

Walks a page’s stored tree, expands every instance on it and writes the bound fields of layers under modes other than the active ones.

function exportFromLoadedSession( session: ExportSession, request: Omit< RenderCompiledExportRequest, "batch" | "imageAssets" > ): RenderExportResult

源码

Exports from a session that already holds the page: measures the export with measureExportFromLoadedSession, then asks the session to draw the region at the scale that the measurement gave. The size that is checked and the size that is drawn come from that one measurement, so they cannot differ.

With options.maxPixels, a raster export (rgba or png) whose pixel size is over the limit is refused with RenderExportTooLargeError before exportScene is called, so nothing is allocated or drawn for it.

原生,经由 measureExportFromLoadedSession: taco_render_session_get_scene_info, taco_render_session_get_node_geometry, taco_render_session_copy_last_error

原生,经由 PortableWasmRenderCoreSession.exportScene: taco_render_session_export, taco_render_session_copy_export_bytes, taco_render_session_copy_last_error

function exportPixelSize( region: Pick< RenderRect, | "width" | "height" >, scale: number ): { readonly pixelWidth: number; readonly pixelHeight: number }

源码

The pixel size the renderer gives a raster export of a region at a scale: each side rounded up, as the native export rounds it.

type ExportSession = Pick< PortableWasmRenderCoreSession, "getSceneInfo" | "getNodeGeometry" | "exportScene" >

源码

What exportFromLoadedSession uses of a renderer session.

function inheritedVectorRegionFills( document: DesignDocument, nodeId: NodeId ): readonly Paint[] | undefined

源码

The fills a path’s regions are drawn with when they take the layer’s fills and the renderer needs those written on each region: several fills, or one that is not a plain solid colour (a gradient, an image, an opacity, a blend mode, a hidden fill). undefined when the layer’s one plain fill is enough, or the layer is not a path. The compiler writes these on the regions of the scene; the vector editing overlay, which draws the path from its own copy of the network, needs the same.

interface InstanceExpansion

源码

A page’s document with its instances replaced by plain nodes: each instance becomes a frame whose children are its resolved layers, stored under their virtual IDs. The compiler then compiles it like any page. Layers whose variable bindings read a mode other than the active one (a page, frame, group or instance chose it, design 7.3) are stored with the values of their modes.

readonly document: DesignDocument源码

The input document itself when the page has no instances and no layer needs other modes.

readonly instances: ReadonlyMap<NodeId, ExpandedInstance>源码
readonly inheritedModes: ReadonlyMap<NodeId, VariableModes>源码

The variable modes each page node inherits from its parent. A node left out inherits none, so its collections show their active modes.

readonly rebound: ReadonlyMap<NodeId, SceneNode>源码

Page layers with their bound fields written for their modes.

readonly instancesByComponent: ReadonlyMap<ComponentId, ReadonlySet<NodeId>>源码

The reverse index of design 4.3: every component to the instances that draw it, directly or through nesting (ResolvedInstance.componentIds).

readonly textSizesVersion: number源码

getDrawnTextSizesVersion when the instances were resolved. A resolved text takes the size the renderer measured for text like it; when a size is measured later, every instance is resolved again on the next update.

interface InstanceExpansionUpdate

源码

What updatePageInstances returns.

readonly expansion: InstanceExpansion源码
readonly changes: ChangeSet源码

changes in terms of the expanded documents, virtual layers included.

type InstanceResolver = ( document: DesignDocument, instanceId: NodeId, options?: ResolveInstanceOptions ) => ResolvedInstance

源码

Derives the layers an instance shows. The page compiler calls it once per instance on the page; resolveInstance from @taco-slides/model is the default (design 4.1).

interface MeasuredExport

源码

What an export will draw, as measureExportFromLoadedSession works it out.

readonly region: RenderRect源码

The part of the page the export shows, in page units.

readonly scale: number源码

How many output units one page unit becomes.

readonly pixelWidth: number源码

The size of the output, which for a raster export is its size in pixels: the region times the scale, each side rounded up.

readonly pixelHeight: number源码

function measureExportFromLoadedSession( session: Pick< ExportSession, "getSceneInfo" | "getNodeGeometry" >, request: Pick< RenderCompiledExportRequest, "rootNodeId" | "scale" | "options" > ): MeasuredExport

源码

Measures an export from a session that already holds the page, without drawing: the region (the page, or everything the root layer and its descendants paint, with shadows, blurs and strokes outside the layer’s box), the scale, and the pixel size these give. It only reads geometry the session already has, so it allocates no picture, however large the export would be. Throws when the root layer paints nothing.

原生,经由 RenderCoreSession.getSceneInfo: taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 RenderCoreSession.getNodeGeometry: taco_render_session_get_node_geometry, taco_render_session_copy_last_error

function outlineStrokesInThrowawaySession( createSession: () => StrokeOutlineSession, request: RenderCompiledStrokeOutlineRequest, modelVectorNetwork: ( network: VectorNetworkRecord ) => VectorNetwork, now: () => number = () => performance.now() ): readonly StrokeOutlineResult[]

源码

Outlines the strokes of a request in a session made for it and disposed when it ends, however it ends. A stroke the renderer refuses (PortableWasmStatusError) is answered with the renderer’s reason and the others go on; any other error ends the request with the answers so far dropped.

The renderer works on the calling thread, so with a request.budget the time every step takes is measured with now (milliseconds) and counted down in the budget: making the session, loading the page into it, and each stroke with its decoding, whether the stroke is outlined, refused by the renderer or fails. Before each step, the first included, the time left is checked; when none is left the step is not started and the request fails with StrokeOutlineTimeError. So many slow strokes cannot keep the thread for longer than the budget and one step, however many are asked for and however many of them the renderer refuses. A request whose last step uses up the time is still answered: its work is done. The budget arrives with the time already taken off that compiling the page took (InteractiveRenderSessionCoordinator.outlineDocumentStrokes).

原生,经由 RenderCoreSession.apply: taco_render_session_apply, taco_render_session_get_last_dirty_bounds, taco_render_session_copy_last_error

原生,经由 RenderCoreSession.getSceneInfo: taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 PortableWasmRenderCoreSession.outlineStroke: taco_render_session_outline_stroke, taco_render_session_get_scene_info, taco_render_session_copy_last_error

原生,经由 RenderCoreSession.dispose: taco_render_session_destroy

class RenderExportTooLargeError extends Error

源码

A raster export would have more pixels than RenderExportOptions.maxPixels allows. It is thrown before the renderer is asked to draw, so no picture was allocated.

readonly pixelWidth: number源码
readonly pixelHeight: number源码
readonly maxPixels: number源码
new (pixelWidth: number, pixelHeight: number, maxPixels: number)源码

interface RenderVectorPendingHandle

源码

A curve handle that no segment of the previewed network owns yet: the one a Pen drag pulls out of a point for the segment drawn from it next. The renderer draws it as editing chrome only (a guide line and a knob).

readonly vertexId: string源码

The point the handle belongs to; it must be in the previewed network.

readonly dx: number源码

The handle’s offset from its point, in the path’s local units.

readonly dy: number源码
readonly mirrored: boolean源码

Also draw the exact mirror of the handle about its point.

function resetCompilerApplyStats(): void

源码

function resetSceneGeometrySnapshotStats(): void

源码

function resetWasmGeometryDecodeStats(): void

源码

function resolvedVisualStyle( document: DesignDocument, style: VisualStyle | undefined ): VisualStyle

源码

The style a node is drawn with: its own style over the shared node style it names (styleId). A fill, stroke or shadow list the node sets itself replaces the shared list whole, also when it is empty. A style ID that names no shared style leaves the node’s own style. Every node compiled here goes through this, so an editor tool that must agree with what is on screen reads the style through it too.

function retainInstances( expansion: InstanceExpansion, drawn: (id: NodeId) => boolean ): InstanceExpansion

源码

Drops instances the compiler did not draw, such as ones on another page.

const sceneGeometrySnapshotStats: { nodeArrayCopies: number }

源码

interface StrokeOutlineBudget

源码

How many bytes of outlines one command may still keep. Every outline of the command (all its strokes, layers and views) is charged its size on the wire before it is copied out of the renderer and decoded, so the outlines held at once never pass maximumNetworkBytes, however many are asked for. The object is shared and counted down as outlines arrive.

readonly maximumNetworkBytes: number源码
remainingNetworkBytes: number源码
readonly maximumRendererMilliseconds: number源码

How long the renderer may work on the command’s strokes, in milliseconds, over all its strokes, layers and views. The renderer outlines on the thread that draws the editor, which cannot answer the user meanwhile. Every step is measured and counted down here (timedStrokeOutlineStep): compiling the page (InteractiveRenderSessionCoordinator.outlineDocumentStrokes), then loading it and each stroke, whether it is outlined or refused (outlineStrokesInThrowawaySession). No step is started once nothing is left; the request fails with StrokeOutlineTimeError instead. A step that has started is not interrupted, so a command can take this long and one step more, and that step can be the compile of a large page.

remainingRendererMilliseconds: number源码

class StrokeOutlineBudgetError extends Error

源码

Thrown by outlineStroke for the outline that would take a command past its StrokeOutlineBudget. The outline was sized and nothing else: it was not copied out of the renderer or decoded, and the budget is unchanged.

readonly networkByteCount: number源码
new (networkByteCount: number, budget: StrokeOutlineBudget)源码

type StrokeOutlineSession = Pick< PortableWasmRenderCoreSession, "apply" | "getSceneInfo" | "outlineStroke" | "dispose" >

源码

What outlineStrokesInThrowawaySession uses of a renderer session.

class StrokeOutlineTimeError extends Error

源码

Thrown in place of starting a step of a command (compiling a page, loading it into the renderer, or outlining a stroke) when the command has already kept the thread for as long as its StrokeOutlineBudget allows, by InteractiveRenderSessionCoordinator.outlineDocumentStrokes and outlineStrokesInThrowawaySession. outlinedStrokeCount of the request’s strokeCount strokes were answered before it; their answers are dropped with the request.

readonly outlinedStrokeCount: number源码
readonly strokeCount: number源码
new ( budget: StrokeOutlineBudget, outlinedStrokeCount: number, strokeCount: number )源码

function timedStrokeOutlineStep<Result>( budget: StrokeOutlineBudget | undefined, progress: { readonly outlinedStrokeCount: number; readonly strokeCount: number; }, step: () => Result, now: () => number = () => performance.now() ): Result

源码

Runs one step of a command’s work on the thread that draws the editor and counts the time it takes, measured with now in milliseconds, down in the command’s budget, whether the step answers or throws. A step is not started once no time is left: StrokeOutlineTimeError is thrown in its place, with how many of the request’s strokes were answered by then. A step that has started is not interrupted, so it can run past the time; the budget is then left at 0 and the next step is not started. Without a budget the step runs untimed.

function updatePageInstances( previous: InstanceExpansion, current: DesignDocument, changes: ChangeSet, resolver: InstanceResolver = resolveInstance, cache?: InstanceResolveCache ): InstanceExpansionUpdate

源码

Brings an expansion up to date after an edit without walking the page. An instance is resolved again when its own node changed, or when any component it draws changed (changedComponentIds, looked up in the reverse index, so editing a component nested in another reaches the outer instances too). Instances found in changes may be on another page; the compiler drops their layers, and retainInstances prunes them after.

const wasmGeometryDecodeStats: { identifierSetInserts: number }

源码

从有界的堆切片中解码 ABI v1 几何记录。返回的对象不会持有所提供的 Wasm 内存,也从不包含指针。

function withCanonicalComponentChanges( rendererChanges: ChangeSet | undefined, canonicalChanges: ChangeSet ): ChangeSet

自 0.23.0源码

The change set the compiler updates from: the renderer projection’s, with the changed components of the canonical change set added. An editor projection may draw a component’s root under a frame of its own (the component view of isolation mode, components design 5.5), where a diff of renderer documents no longer sees the component’s layers as component layers; the canonical change set still names the component, so its instances are resolved again.

@taco-design/electron TypeScript

58 个导出中已记录 57 个 · 大纲

@taco-design/electron shows the Taco Design editor inside an Electron app, in a WebContentsView. The package holds the built editor and a small helper for the main process. The helper serves the editor’s files from a custom address, taco-design://app/, makes the view with safe settings, and carries the document and the events between the app and the editor’s page.

Everything here runs in Electron’s main process. The app brings its own Electron, version 42 or later; 44.7.0 on macOS is the one that was tried. The package can be installed from https://packages.luyu.computer/ (stable or next) or from a CI .tgz file.

For a walk through a whole app, from installing the file to closing a window without losing work, read the guide Add Taco Design to an Electron app. The package’s own README lists what does not work yet, and how to build the .tgz file.

Registering the scheme

The editor’s page is loaded from taco-design://app/. Electron only treats that address as a secure page, which WebGPU needs, when the scheme is registered before the app is ready. An app with no custom scheme of its own calls registerTacoDesignScheme. Electron accepts protocol.registerSchemesAsPrivileged once per app, so an app with schemes of its own adds tacoDesignScheme to its own call instead.

function registerTacoDesignScheme(): void

源码

Registers the taco-design scheme. Call it before the app is ready.

Electron accepts protocol.registerSchemesAsPrivileged once per app, so an app with schemes of its own must not call this: it adds the exported tacoDesignScheme object to its own call instead.

const tacoDesignScheme: { readonly scheme: "taco-design"; readonly privileges: { readonly standard: true; readonly secure: true; readonly supportFetchAPI: true; readonly stream: true; readonly codeCache: true; }; }

源码

The entry for Electron’s protocol.registerSchemesAsPrivileged.

Electron accepts that call once per app, before the app is ready. An app with schemes of its own adds this object to its own single call; an app with none calls registerTacoDesignScheme().

  • standard: addresses such as /assets/app.js resolve, and storage works.
  • secure: the page is a secure context, which WebGPU needs.
  • supportFetchAPI: the renderer file is downloaded with fetch.
  • stream, codeCache: the renderer compiles while it downloads, and compiled scripts are kept between starts.

A scheme handler belongs to one session. createTacoDesignView sets the handler up for its own storage partition, so most apps never call handleTacoDesignScheme.

function handleTacoDesignScheme( session: Session, options: { readonly appDirectory?: string } = {} ): void

源码

Serves taco-design://app/ on one session from a folder of editor files.

A scheme handler belongs to a session: a view in its own partition does not see a handler registered on another session. createTacoDesignView calls this for its own partition; call it yourself only when you make the WebContentsView yourself. Calling it again for the same session and folder does nothing. options.appDirectory names another folder of editor files to serve than the package’s own, and must be an absolute path.

const TACO_DESIGN_SCHEME: "taco-design"

源码

The custom scheme the editor’s files are served from.

const TACO_DESIGN_HOST: "app"

源码

The only host the scheme answers for.

const TACO_DESIGN_ORIGIN: "taco-design://app"

源码

The origin of the editor page; permission rules compare against it.

const TACO_DESIGN_APP_URL: "taco-design://app/"

源码

The address createTacoDesignView loads.

The package finds its editor files and its preload script next to its own code on disk. An app that bundles its main process keeps @taco-design/electron out of the bundle for that reason.

const appDirectory: string

源码

The folder of editor files inside this package, served as taco-design://app/.

const preloadPath: string

源码

The preload script of the editor’s view, as a file path.

Creating the view

createTacoDesignView makes the view and starts loading the editor. Add TacoDesignView.view to a window and give it bounds, then wait for TacoDesignView.ready: it resolves when the document is open and the renderer has drawn, and rejects with a TacoDesignError when the editor cannot start. A failed start is never a blank view: the view shows the message too.

function createTacoDesignView( options: TacoDesignViewOptions = {} ): TacoDesignView

源码

Makes a WebContentsView that shows the Taco Design editor, with safe settings: sandbox and context isolation on, no Node.js in the page, its own storage partition, a short list of permissions, no navigation to other addresses and no new windows.

Call it after the app is ready, and after the scheme was registered.

interface TacoDesignViewOptions

源码

The options of createTacoDesignView. Every one can be left out.

readonly document?: unknown源码

The document to open, as plain JSON (what getDocument() returned earlier and the app stored). Leave it out, or pass null, for a new blank document. A document that cannot be opened rejects ready with invalid-document or schema-too-new, and the view shows why.

readonly requestTimeoutMs?: number源码

How long one request (getDocument() and the others) waits for its answer. Default 30 000 ms.

readonly partition?: string源码

The storage partition of the view. Default persist:taco-design.

The package sets its own permission rules on this partition’s session, so do not share the partition with other pages of your app.

readonly appDirectory?: string源码

A folder of editor files to serve instead of the one inside this package, as an absolute path. Anything else throws app-directory-invalid.

readonly readyTimeoutMs?: number源码

How long one load of the editor’s page may take, from its beginning to a drawn editor, before it ends with ready-timeout: ready rejects for the first load, reload() for a later one. Default 60 000 ms.

readonly startupProgress?: TacoDesignStartupProgressDrawer源码

Who draws the progress while the editor starts. "editor" (the default): the editor shows its own slim bar in the view, from the first drawing of the page until the editor’s first frame. "host": the editor shows none, and the app draws its own from the startupProgress event. The event is sent either way.

readonly onDownload?: (item: DownloadItem) => void源码

Called for every download the editor starts (an export, for example). Call item.setSavePath() to save without asking. Without this option Electron shows its own save dialog.

readonly shortcuts?: ShortcutOverrides源码

Changes to the editor’s keyboard shortcuts: a command ID mapped to its new keys ("CmdOrCtrl+Shift+D"), to a list of keys, or to null to switch that shortcut off. getShortcuts() lists the command IDs. Keys that cannot be read throw invalid-shortcut-keys here; an unknown command ID, a command that cannot be changed, or two commands on the same keys reject ready with the matching error code.

readonly menuShortcutConflict?: MenuShortcutConflict源码

What happens to a key that is an editor shortcut and also an accelerator in the app’s menu, while the editor has the keyboard: "editor" (the default) runs the editor’s command only, "app" runs the menu item only, "both" runs both. The README says how each is done.

interface TacoDesignView

源码

What createTacoDesignView returns: the view to put in a window, and the calls and events that reach the editor inside it.

Every call that returns a promise waits for ready first. It rejects with a TacoDesignError when the editor never started or transport fails. Design calls also report domain errors as documented on designRequest.

readonly view: WebContentsView源码

A plain WebContentsView: add it to a window and give it bounds.

readonly ready: Promise<TacoDesignReadyState>源码

Resolves when the editor’s renderer reports ready. Rejects with a TacoDesignError when the page cannot be loaded or the editor cannot start; the view then shows a message instead of staying blank. Always handle the rejection.

getDocument(): Promise<TacoDesignDocumentSnapshot>源码

The open document as plain JSON, without undo history, and the revision it was read at. Call it when you save; the editor stores nothing itself.

setDocument( document: unknown, options?: TacoDesignSetDocumentOptions ): Promise<TacoDesignSetDocumentResult>源码

Replaces the open document. Undo history, selection and zoom start fresh. Rejects with invalid-document or schema-too-new and leaves the open document as it was when the new one cannot be opened.

With { ifRevision } the document is replaced only while the editor’s document is at that revision, the one getDocument() resolved with. Otherwise the call rejects with revision-changed and nothing changes.

newDocument(options?: TacoDesignSetDocumentOptions): Promise<DocumentInfo>源码

Replaces the open document with a new blank one: one empty page, the default fonts and styles, and an ID of its own, like the document a view starts with when it is given none. Everything else is as for setDocument(): undo history, selection and zoom start fresh, the change event has the origin "host", and with { ifRevision } the document is replaced only at that revision (revision-changed otherwise). Resolves with the new document’s ID, title, page count and revision. Read it with getDocument() when you want to store it.

getState(): Promise<EditorState>源码

The versions the editor speaks and a few facts about the open document.

designRequest( request: DesignRequest, options?: TacoDesignRequestOptions ): Promise<DesignReply>源码

Sends a validated read/planning envelope after startup and version discovery. Preserves the explicit editor/document/epoch target. Domain failures resolve as DesignReply; transport failures reject with TacoDesignError. Local catalog or capability failures reject with DesignError. Use createDesignClient for typed results and throwing domain errors. No public writes are enabled.

undo(): Promise<TacoDesignHistoryResult>源码

Undoes one step. done is false when there was nothing to undo.

redo(): Promise<TacoDesignHistoryResult>源码

Redoes one step. done is false when there was nothing to redo.

exportLayers( options: TacoDesignExportOptions ): Promise<TacoDesignExportedFile[]>源码

Draws one layer (nodeId) or one whole page (pageId) into a PNG, JPEG, SVG or PDF file through the editor’s own export, and resolves with the file’s name, type and bytes. The list has one file. Rejects with unknown-layer, unknown-page, unsupported-format, invalid-request, export-too-large (more than 8192 x 8192 pixels), renderer-failed or export-failed. A document with no page has nothing to export: every target is unknown-page or unknown-layer.

getSelection(): Promise<SelectionSummary>源码

The page that is shown and the selected layers, each with its ID, name and kind.

zoomToFit( options?: { readonly target?: "page" | "selection"; } ): Promise<{ done: boolean }>源码

Zooms the canvas so that the whole page fits, or the selected layers with { target: "selection" }. done is false when the selection was asked for and nothing is selected, and when the document has no page.

focusCanvas(): Promise<FocusSummary>源码

Gives the keyboard to the view and, inside it, to the canvas, so that the editor’s shortcuts work. Resolves with where the keyboard is.

getShortcuts(): Promise<ShortcutCommandInfo[]>源码

The editor’s keyboard shortcuts: every command with its stable ID, its title, its default keys and the keys in use now (none when it is switched off).

setShortcuts(overrides: ShortcutOverrides): Promise<ShortcutCommandInfo[]>源码

Replaces this app’s changes to the shortcuts and resolves with the list as it is afterwards. overrides is the whole set: a command that is not named goes back to its default keys, and {} resets them all. When a change is wrong nothing is changed, and the promise rejects with unknown-shortcut-command, invalid-shortcut-keys, shortcut-keys-in-use or shortcut-not-customizable; error.path is the command ID. The changes are kept by this object, not by the page: they last as long as the view and survive reload().

readonly menuShortcutConflict: MenuShortcutConflict源码

The setting for keys that are both an editor shortcut and a menu accelerator.

setMenuShortcutConflict(conflict: MenuShortcutConflict): void源码

Changes that setting. Any other value than the three throws invalid-option.

reload(): Promise<TacoDesignReloaded>源码

Loads the editor’s page again without losing work. The page first ends editing and freezes (it accepts no edit, and refuses setDocument(), undo() and redo() with not-ready), then hands over its document; only after that answer is it loaded again, and the new page gets the document back. No edit can fall in between. Use it after a failure event. Resolves when the new page is ready as it is after ready: the editor answers and its renderer has drawn, so an exportLayers() right after it works. handedOver is false when the page did not hand over (its process had ended, or it did not answer in 5 seconds), and the editor then shows the last document this app set or read. The new page is loaded and watched exactly as the first one, so reload() rejects with every error ready can reject with, as soon as it is known (load-failed, app-files-missing, renderer-failed, page-crashed, ready-timeout after readyTimeoutMs, and the others), and the failure listeners hear the same error. It also rejects with disposed when the view is disposed meanwhile, and with load-failed when the page was not loaded again within 10 seconds of its answer (it then accepts edits again). Two calls at the same time are one reload. The undo history starts empty and the revision at 0.

on<Event extends keyof TacoDesignEvents>( event: Event, listener: TacoDesignEvents[Event] ): () => void源码

Listens for "change" (the document changed), "selection" (the selection changed), "focus" (the keyboard moved), "saveRequested" (the Save keys were pressed in the editor), "startupProgress" (how far the start-up is), "failure" (the editor stopped working after ready, or could not be loaded again) or "reloaded" (the page was loaded again), or "design" (a stamped design invalidation). The returned function removes the listener.

focus(): void源码

Gives the keyboard to the editor’s view.

dispose(): void源码

Closes the view’s page. The view cannot be used afterwards.

interface TacoDesignReadyState

源码

What ready resolves with.

readonly url: string源码

The address the editor was loaded from.

readonly build: TacoDesignBuildInfo | null源码

What the editor was built from, or null when the folder has no build record.

readonly protocolVersion: number源码

The version of the host protocol the editor and this package agreed on.

readonly documentSchemaVersion: string源码

The newest document schema version the editor reads, and the one it writes.

readonly rendererWireVersion: number源码

The version of the format the editor and its renderer talk in.

readonly document: DocumentInfo源码

The open document: its id, title, page count, revision, and whether undo and redo are possible.

interface TacoDesignBuildInfo

源码

What the assemble script wrote next to the editor files.

readonly documentSchemaVersion: string源码

The document schema version the editor reads and writes, such as 0.27.0.

readonly rendererWireVersion: number源码

The version of the format the editor and its renderer talk in.

readonly commit: string源码

The commit the editor was built from.

const DEFAULT_READY_TIMEOUT_MS: 60000

源码

How long ready waits for the editor before it rejects, unless the app says otherwise.

The document

The editor in the view stores no document. It starts from the one the app hands over (TacoDesignViewOptions.document), keeps it in memory, and tells the app when it changes. Saving is the app’s job: read the document with TacoDesignView.getDocument and write it as JSON.

A document holds its pictures, so it can be tens of megabytes. Events therefore carry only a few facts about it (DocumentInfo), never the document itself. The undo history is not part of the document: it lives in the page and starts empty each time a document is handed over.

Read the document once more before a window closes, every time. The page has no “unsaved changes” guard, and TacoDesignView.getDocument is the only call that is never behind the newest edit.

TacoDesignView.setDocument replaces the open document. An app that opens another file saves the open one first, and an edit may arrive between that last read and the replacement, because the page is another process. So pass the revision of the read: setDocument(document, { ifRevision }) replaces the document only while the editor’s document is still at that revision. At any other revision the call rejects with revision-changed and nothing changes; read and write again, then retry. Revisions start at 0 again on every page load, so use a revision read after the last reloaded event.

TacoDesignView.newDocument replaces the open document with a new blank one, like the document a view starts with when it is given none. It takes ifRevision too and is otherwise setDocument. Use it for a “New” command and for a file that does not exist yet. setDocument(null) is refused, so that a file with no document in it never opens as a blank one by accident.

type DocumentJson =

源码

A whole document as plain JSON, without its undo history. The host stores it and hands it back; it need not look inside.

readonly schemaVersion: string源码

The document schema version the document is written in, such as 0.27.0.

readonly id: string源码

The document’s ID.

readonly title: string源码

The document’s title.

readonly [key: string]: unknown源码

Everything else in the document: its pages, layers, components and pictures.

interface TacoDesignDocumentSnapshot

源码

What getDocument() resolves with.

readonly document: DocumentJson源码

The whole document as plain JSON, without undo history. Write it with JSON.stringify.

readonly revision: number源码

The revision the document was read at. It counts every change made so far, also those whose change event has not arrived yet, so a change event’s revision can be lower. Do not compare the two to decide whether to save before closing: always read the document one last time.

interface TacoDesignSetDocumentOptions

源码

What setDocument() takes besides the document, and what newDocument() takes.

readonly ifRevision?: number源码

Replace the document only while the editor’s document is at this revision (the revision that getDocument() resolved with). At any other revision the call rejects with revision-changed and nothing changes: an edit was made since that read. Revisions start at 0 again on every page load, so use one read after the last reloaded event.

interface TacoDesignSetDocumentResult extends DocumentInfo

源码

What setDocument() resolves with.

readonly migratedFrom?: string源码

The schema version the document arrived in, when the editor had to bring it up to date.

interface TacoDesignHistoryResult extends DocumentInfo

源码

What undo() and redo() resolve with.

readonly done: boolean源码

False when there was nothing to undo or redo.

interface DocumentInfo

源码

A few facts about the open document, small enough to send with every change.

readonly id: string源码

The document’s ID.

readonly title: string源码

The document’s title.

readonly pageCount: number源码

How many pages the document has.

readonly revision: number源码

Goes up by one on every change to the document and on every setDocument. Starts at 0 on each page load.

readonly canUndo: boolean源码

True when there is a step to undo.

readonly canRedo: boolean源码

True when there is a step to redo.

interface EditorState

源码

The versions the editor speaks and a few facts about the open document: the answer to a getState request.

readonly design?: DesignCapability源码

Optional read/planning capability; absent in older editors.

readonly protocolVersion: number源码

The version of the host protocol the editor and the host agreed on.

readonly documentSchemaVersion: string源码

The newest document schema version the editor reads, and the one it writes.

readonly rendererWireVersion: number源码

The version of the format the editor and its renderer talk in.

readonly build: string源码

Names the build of the editor’s page, for error reports.

readonly document: DocumentInfo源码

The open document: its ID, title, page count, revision, and whether undo and redo are possible.

Events

TacoDesignView.on takes an event name and a listener and returns a function that removes the listener. A listener that throws does not stop the editor or the other listeners. Events are small: none of them carries the document.

change, selection and focus say what happened in the editor. startupProgress, failure and reloaded say how the page itself is doing. saveRequested says that the person pressed the editor’s Save shortcut (Cmd+S, or Ctrl+S on Windows and Linux). The editor saves nothing itself, so answer it by reading the document and writing it, with the same function the app’s own Save menu item calls.

// Cmd/Ctrl+S in the editor. The editor saves nothing itself.
editor.on("saveRequested", saveNow);
apps/electron-sample/main.mjs,第 260 至 261 行

interface TacoDesignEvents

源码

The events of a TacoDesignView, each with the listener it calls. The names are what TacoDesignView.on takes.

design: (event: DesignEvent) => void源码

Stamped invalidations for the current page, not a resumable synchronization log.

change: (change: TacoDesignChange) => void源码

The document changed. Changes by the person using the editor arrive at most once per 100 ms, and the last one always arrives. Ask for the document with getDocument() when you save.

selection: (selection: SelectionSummary) => void源码

Other layers are selected, another page is shown, or a selected layer was renamed. Arrives at most once per 100 ms, and the last one always arrives.

focus: (focus: FocusSummary) => void源码

The keyboard moved: into or out of the editor, or between its canvas, a text field and the rest.

failure: (error: TacoDesignError) => void源码

The editor stopped working after ready, or could not be loaded again. error.code says how. It worked and stopped: renderer-failed (the canvas stopped drawing; detail is the renderer’s own code), editor-crashed (the editor shows its crash screen) or page-crashed (the page’s process ended). A reload failed: any code ready can reject with (load-failed, app-files-missing, ready-timeout, renderer-failed, page-crashed and the others); a reload() that was waiting rejects with the same error. reload() brings the editor back.

reloaded: (document: TacoDesignReloaded) => void源码

The editor’s page was loaded again (its crash screen’s Reload button, or reload()) and is ready as it is after ready: the editor answers and its renderer has drawn. handedOver says which document it shows.

saveRequested: () => void源码

The Save keys were pressed while the editor had the keyboard (the command file.save: Cmd+S on macOS and Ctrl+S elsewhere, unless the shortcut was changed). The editor saves nothing itself: read the document with getDocument() and store it.

startupProgress: (progress: TacoDesignStartupProgress) => void源码

How far the editor’s start-up is: a fraction, and the step in progress. At most ten arrive per second. They can only start once the page has its connection, so the first one already counts what happened before. The last one is { fraction: 1, step: "done" } and arrives before ready resolves. A start that fails has no last report: ready rejects instead, and no report of that page load follows the rejection, so loading is over when ready settles either way. A page that is loaded again reports its progress again, in the same way: the last report arrives before reloaded is told and reload() resolves, and a reload that fails has no last report and tells failure instead.

interface TacoDesignChange extends DocumentInfo

源码

What a change listener gets: a few facts about the document, never the document.

readonly origin: "user" | "host"源码

"host": caused by setDocument() or newDocument(). "user": everything else (edits, undo and redo, and changes the editor makes by itself after an edit).

Export

TacoDesignView.exportLayers draws one layer or one whole page through the editor’s own export, so the file is what the editor’s Export section would download. It resolves with a list that holds one file. One PNG or JPEG may have at most 8192 x 8192 pixels.

interface TacoDesignExportOptions

源码

What exportLayers() takes: one layer or one page, a format, and the choices of the editor’s own Export section.

readonly nodeId?: string源码

The layer to export, with everything inside it. Give this or pageId.

readonly pageId?: string源码

The page to export whole. Give this or nodeId.

readonly format: HostExportFormat源码

The file format: "png", "jpeg", "svg" or "pdf".

readonly scale?: number源码

PNG and JPEG: pixels per document unit. Default 1. Give at most one of scale, width and height.

readonly width?: number源码

PNG and JPEG: a fixed width in whole pixels.

readonly height?: number源码

PNG and JPEG: a fixed height in whole pixels.

readonly quality?: "low" | "medium" | "high"源码

JPEG: compression. PDF: resolution of effects that cannot be drawn as shapes. Default: high for JPEG, medium for PDF.

readonly resampling?: "detailed" | "basic"源码

How pictures inside the layer are sampled. Default "detailed".

readonly ignoreOverlappingLayers?: boolean源码

For a layer: true (default) draws the layer alone, false also what else lies within its bounds.

readonly includeIdAttribute?: boolean源码

SVG: id attributes made from layer names. Default false.

readonly suffix?: string源码

Added to the file name after the layer’s or page’s name.

readonly timeoutMs?: number源码

How long to wait for the export. Default 120 000 ms.

type HostExportFormat = "png" | "jpeg" | "svg" | "pdf"

源码

The file formats an export can be written in.

interface TacoDesignExportedFile

源码

One exported file.

readonly fileName: string源码

<layer or page name><suffix>.<extension>, safe as a file name.

readonly mimeType: string源码

image/png, image/jpeg, image/svg+xml or application/pdf.

readonly bytes: Uint8Array源码

The file’s bytes; write them with fs.writeFile.

Selection, zoom and focus

TacoDesignView.getSelection and the selection event say which page is shown and which layers are selected. There is no call that sets the selection. TacoDesignView.zoomToFit does what the editor’s “Zoom to fit” and “Zoom to selection” do. TacoDesignView.focusCanvas gives the keyboard to the canvas, and the focus event says where the keyboard is.

interface SelectionSummary

源码

The page that is shown and the selected layers: the answer to a getSelection request, and what a selection event carries.

readonly pageId: string | null源码

The page that is shown, or null when the document has none.

readonly nodes: readonly SelectedLayer[]源码

The selected layers, in the order they were selected. Empty when nothing is selected.

interface SelectedLayer

源码

One selected layer.

readonly id: string源码

The ID the document knows the layer by. A layer inside an instance has an ID made of the instance’s ID and the layer’s place inside it.

readonly name: string源码

The layer’s name, as the layers panel shows it.

readonly type: string源码

The layer’s kind, the same word as its type in the document: "frame", "group", "text", "shape", "image", "instance" and so on. An instance is "instance" wherever it is: on a page, inside a component, or inside another instance. A component’s root is the frame it is stored as.

readonly shape?: string源码

For a layer of type "shape": which shape, the same word as its shape in the document ("rectangle", "ellipse", "line", "path", ...).

readonly componentId?: string源码

For a layer of type "instance": the ID of the component it shows, as in the document’s components. For an instance inside another instance this is the component in effect after a swap by the outer one.

readonly componentName?: string源码

For a layer of type "instance": the name of that component.

interface FocusSummary

源码

Where the keyboard is: the answer to a focusCanvas request, and what a focus event carries.

readonly focused: boolean源码

True while the editor’s page has the keyboard.

readonly target: "canvas" | "text" | "other" | null源码

What has the keyboard inside the page: "canvas"; "text" (a text field, or text being edited on the canvas), where keys such as copy and undo belong to the text; "other" (a button, a panel, or nothing in particular). Null while the page does not have the keyboard.

Reload and failures

Every failure is a TacoDesignError with a code. Before the editor is ready it rejects TacoDesignView.ready. Afterwards it reaches the failure listeners: the renderer stopped, the editor crashed, or the page’s process ended. TacoDesignView.reload loads the editor again; where the page can still answer, it hands its document over first, so no edit is lost.

A call the editor refuses rejects with a TacoDesignError too, and changes nothing: revision-changed from TacoDesignView.setDocument or TacoDesignView.newDocument with ifRevision, and the shortcut codes from TacoDesignView.setShortcuts (unknown-shortcut-command, invalid-shortcut-keys, shortcut-keys-in-use, shortcut-not-customizable). TacoDesignErrorCode lists every code.

There is no automatic retry. When TacoDesignView.ready rejected, dispose the view and make a new one. Do not call TacoDesignView.reload from a failure listener without a limit, because a failure that comes back at once would reload for ever.

interface TacoDesignReloaded extends DocumentInfo

源码

What a reloaded listener gets, and what reload() resolves with.

readonly handedOver: boolean源码

True: the page handed over its document right before it was loaded again, so the editor shows the latest work. False: it could not (its process had ended, for example), and the editor shows the last document this app set or read; edits made after that are lost.

class TacoDesignError extends Error

源码

The error ready rejects with, and the package’s functions throw.

readonly code: TacoDesignErrorCode源码

What went wrong. Decide by this, never by the message, which is written for a person.

readonly url: string | undefined源码

The address that was being loaded.

readonly errorCode: number | undefined源码

Chromium’s network error number, such as -2 for ERR_FAILED.

readonly errorDescription: string | undefined源码

Chromium’s network error name, such as ERR_FAILED.

readonly httpStatus: number | undefined源码

The HTTP status the page answered with.

readonly rendererErrorCode: string | undefined源码

The editor’s own renderer error code, such as WEBGPU_UNAVAILABLE.

readonly path: string | undefined源码

Where a document is wrong, as a JSON path such as $.nodes.n1.opacity.

readonly detail: string | undefined源码

The document model’s own error code, such as INVALID_SCHEMA; for renderer-failed after ready, the renderer’s own code.

new ( code: TacoDesignErrorCode, message: string, details: TacoDesignErrorDetails = {} )源码

Makes an error from a code, a message written for a person, and the extra facts that are known.

type TacoDesignErrorCode = | "app-files-missing" | "load-failed" | "scheme-not-registered" | "scheme-registered-too-late" | "scheme-handler-conflict" | "app-directory-invalid" | "renderer-failed" | "editor-failed" | "page-crashed" | "ready-timeout" | "disposed" | "invalid-document" | "schema-too-new" | "protocol-mismatch" | "not-ready" | "unknown-method" | "request-aborted" | "request-timeout" | "connection-closed" | "editor-crashed" | "invalid-request" | "unknown-layer" | "unknown-page" | "unsupported-format" | "export-too-large" | "export-failed" | "revision-changed" | "unknown-shortcut-command" | "invalid-shortcut-keys" | "shortcut-keys-in-use" | "shortcut-not-customizable" | "invalid-option" | "internal"

源码

Why the editor could not be shown.

  • app-files-missing: the folder of editor files has no index.html (the package was not assembled, or appDirectory is wrong).
  • load-failed: Electron could not load the page (errorCode and errorDescription are Chromium’s), or the page answered with an HTTP error status (httpStatus).
  • scheme-not-registered: the page is not a secure context, which means tacoDesignScheme was not registered before the app was ready.
  • scheme-registered-too-late: registerTacoDesignScheme() ran after the app was ready.
  • scheme-handler-conflict: the session already serves the scheme from another folder.
  • app-directory-invalid: the appDirectory option is not an absolute path of a folder, or is the root of a disk.
  • renderer-failed: the page loaded but the WebGPU renderer did not start (rendererErrorCode is the editor’s own code, such as WEBGPU_UNAVAILABLE).
  • editor-failed: the page loaded but the editor showed its start-up error screen (for example its stored data could not be opened).
  • page-crashed: the page’s process ended. Before ready it rejects ready; afterwards it reaches the failure listeners.
  • ready-timeout: the editor did not report ready in time. reload() rejects with it when the page that was loaded again did not connect, or did not report ready, in that time.
  • disposed: dispose() was called, or the view was destroyed, first.

From the editor, about a document or a request (see the host protocol):

  • invalid-document: the document handed over is not one Taco Design can open. path says where it is wrong (a JSON path such as $.title) and detail holds the document model’s own code.
  • schema-too-new: the document was written by a newer Taco Design.
  • protocol-mismatch: this package and the editor files speak no common version of the host protocol (they come from different releases).
  • not-ready: the editor is not shown (it failed, or is reloading), so the request was not run.
  • unknown-method: the editor files are older than this package and do not know the request.
  • request-timeout: the editor did not answer a request in time.
  • request-aborted: the caller stopped waiting for a design request.
  • connection-closed: the editor’s page went away (it reloaded or crashed) before it answered.
  • internal: the editor failed in a way it has no code for.

From exportLayers():

  • unknown-layer, unknown-page: the document has no such layer on a page, or no such page.
  • unsupported-format: the format is not PNG, JPEG, SVG or PDF.
  • invalid-request: an option has a value the editor cannot use (two sizes at once, a scale of 0, ...). Other requests use it too.
  • export-too-large: the picture would have more than 8192 x 8192 pixels.
  • export-failed: the renderer could not draw or encode the export; the message says why (fonts still loading, for example).

To the failure listeners, after ready:

  • renderer-failed: the canvas stopped drawing (detail is the renderer’s own code).
  • editor-crashed: the editor threw and shows its crash screen.
  • page-crashed: see above.

interface TacoDesignErrorDetails

源码

The extra facts a TacoDesignError can carry besides its code and its message. Which of them are set depends on the code.

readonly url?: string源码

The address that was being loaded.

readonly errorCode?: number源码

Chromium’s network error number, such as -2 for ERR_FAILED.

readonly errorDescription?: string源码

Chromium’s network error name, such as ERR_FAILED.

readonly httpStatus?: number源码

The HTTP status the page answered with.

readonly rendererErrorCode?: string源码

The editor’s own renderer error code, such as WEBGPU_UNAVAILABLE.

readonly path?: string源码

Where a document is wrong, as a JSON path such as $.nodes.n1.opacity.

readonly detail?: string源码

The document model’s own error code, such as INVALID_SCHEMA.

Start-up progress

While the editor starts it shows a slim progress bar of its own, and it tells the app the same thing with the startupProgress event. An app that draws the progress itself, in a splash screen for example, passes TacoDesignViewOptions.startupProgress as "host". Loading is over when TacoDesignView.ready settles: a start that fails sends no last report.

interface TacoDesignStartupProgress

源码

What a startupProgress listener gets.

readonly fraction: number源码

The share of start-up that is finished, 0 to 1. It never goes down within one page load.

readonly step: string源码

The step in progress, in order: page-code, fonts, document, module-download, module-create, creating-session, installing-page, and done in the last report. Later versions may add steps, so show label and do not switch on this.

readonly label: string源码

A few plain words for the step, such as “Downloading the renderer”.

readonly indeterminate: boolean源码

True while the step in progress cannot say how long it is (a download without a known size). fraction then stays where it was: show a bar that moves without a percentage.

type TacoDesignStartupProgressDrawer = "editor" | "host"

源码

The option that says who draws the progress while the editor starts.

Keyboard and menus

While the editor has the keyboard, the editor’s shortcuts are the editor’s: Cmd+Z undoes on the canvas, Cmd+C and Cmd+V copy and paste layers, Cmd+D duplicates, the letter keys choose tools, even when an item of the app’s menu has an accelerator on the same keys. (Cmd is Ctrl on Windows and Linux.) An app can change that in three ways: give a command other keys, switch a command’s shortcut off, and choose who gets a key that its menu wants too.

/** The override the sample's "Duplicate on Cmd/Ctrl+Shift+D" item switches on. */
export const DUPLICATE_REMAP = /** @type {const} */ ({ "edit.duplicate": "CmdOrCtrl+Shift+D" });
apps/electron-sample/appMenu.mjs,第 30 至 31 行
const editor = createTacoDesignView({
  document: startDocument,
  startupProgress: process.argv.includes("--host-progress") ? "host" : "editor",
  menuShortcutConflict: startConflict,
  shortcuts: startRemapped ? DUPLICATE_REMAP : {},
});
apps/electron-sample/main.mjs,第 136 至 141 行

Changing the editor’s shortcuts

The editor’s shortcuts are a list of commands. Each has a stable ID such as edit.duplicate, a title, its default keys and the keys in use now (ShortcutCommandInfo). TacoDesignView.getShortcuts returns the list; the package’s README has it as a table. The IDs are part of the package’s API: they are not renamed or reused.

TacoDesignViewOptions.shortcuts and TacoDesignView.setShortcuts take the same object (ShortcutOverrides): a command ID mapped to its new keys, to a list of keys, or to null to switch the shortcut off. It is always the whole set of the app’s changes: a command that is not named has its default keys, and setShortcuts({}) puts every command back. Keys are written like Electron accelerators, for example CmdOrCtrl+Shift+D.

type ShortcutOverrides =

源码

An embedding app’s changes to the editor’s shortcuts: a command ID mapped to its new key combination, to a list of them, or to null to switch the shortcut off. Commands that are not named keep their default keys.

readonly [commandId: string]: string | readonly string[] | null源码

interface ShortcutCommandInfo

源码

One command of the editor’s shortcut list.

Key combinations are written like Electron accelerators, for example CmdOrCtrl+Shift+D; shortcuts.ts describes the spelling.

readonly id: string源码

The stable name of the command, for example edit.duplicate. Part of the public API.

readonly title: string源码

What the command does, in a few words of English.

readonly defaultKeys: readonly string[]源码

The keys the command has when the embedding app changes nothing.

readonly keys: readonly string[]源码

The keys in use now. Empty when the shortcut is switched off.

readonly customizable: boolean源码

False for a command whose keys cannot be changed or switched off.

A key that is an editor shortcut and a menu accelerator

TacoDesignViewOptions.menuShortcutConflict, and TacoDesignView.setMenuShortcutConflict at run time, say what happens to a key press that runs an editor command and is also the accelerator of an enabled, visible item of the application menu, while the editor has the keyboard. With "editor" (the default) the editor’s command runs and the menu item does not. With "app" the menu item runs and the editor does not see the key. With "both" the menu item runs first, then the editor’s command.

type MenuShortcutConflict = "editor" | "app" | "both"

源码

What happens to a key press that is an editor shortcut and also an accelerator of an item in the app’s menu, while the editor has the keyboard:

  • "editor" (the default): the editor runs its command; the menu item does not run.
  • "app": the menu item runs; the editor does not see the key.
  • "both": the menu item runs and the editor runs its command.

const MENU_SHORTCUT_CONFLICTS: readonly MenuShortcutConflict[]

源码

Every value menuShortcutConflict can have.

A menu for an app that shows the editor

The File, Edit and View items of the sample app’s menu template:

{
  label: "File",
  submenu: [
    { id: SAVE_MENU_ID, label: "Save", accelerator: "CmdOrCtrl+S", click: () => options.save() },
    { type: "separator" },
    mac ? { role: "close" } : { role: "quit" },
  ],
},
{
  label: "Edit",
  submenu: [
    { id: UNDO_MENU_ID, label: "Undo", accelerator: "CmdOrCtrl+Z", click: history("undo") },
    { id: REDO_MENU_ID, label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", click: history("redo") },
    { type: "separator" },
    { role: "cut" },
    { role: "copy" },
    { role: "paste" },
    { role: "selectAll" },
  ],
},
// No zoom roles here: they would scale the whole view.
{ label: "View", submenu: [{ role: "togglefullscreen" }] },
apps/electron-sample/appMenu.mjs,第 89 至 110 行

The guide’s step Keyboard and menus builds the whole menu. The package’s README says how each setting is carried out in Electron, and what is not proven on Windows and Linux.

Security settings and versions

createTacoDesignView sets all of this, so the app does not have to: the page runs in a sandbox with context isolation and without Node.js, in its own storage partition; it may only move inside taco-design://app/ and may open no window; every answer carries the content security policy below; and only the listed permissions are granted, only to the editor’s own page.

const CONTENT_SECURITY_POLICY: string

源码

Sent with every answer. 'wasm-unsafe-eval' lets the renderer compile; 'unsafe-inline' styles are for the editor’s inline styles. There is no 'unsafe-eval' and no inline script. https://fonts.gstatic.com is the only other site, used to fetch a Google font the first time a document needs it.

const ALLOWED_PERMISSIONS: readonly string[]

源码

The only permissions the editor page is given: listing installed fonts, the clipboard, and keeping its storage from being cleared under disk pressure. Everything else (camera, microphone, location, notifications, ...) is refused.

const DEFAULT_PARTITION: "persist:taco-design"

源码

The partition used when the app names none. persist: keeps it on disk.

const HOST_PROTOCOL_VERSION: 1

源码

Counts up by one when a change would confuse an older host or page.

These additions do not count, so they keep the number: a new request (a page that does not know it answers unknown-method), a new event (a host skips events it does not know), a new optional parameter or result field, and a new error code (it arrives as a string with its message). Changing or removing a message, or changing what an existing one means, counts.

Still 1 after the export, selection, view and reload messages were added, and after the shortcut requests (getShortcuts, setShortcuts), the saveRequested event and the four shortcut error codes, and after the newDocument request.

Design reads and plans

TacoDesignView.designRequest uses the explicit binding advertised by getState().design. createDesignClient validates operation arguments and results with the shared catalog. Public mutations remain disabled; geometry is stored model geometry. design events are stamped invalidations, not a resumable log.

const DESIGN_PROTOCOL_VERSION: "taco.design/1.0.0"

源码

Version of the design envelope, independent of document schema and renderer wire versions.

function createDesignClient( send: (request: DesignRequest) => Promise<DesignReply>, target: DesignBinding, requestId: () => string )

源码

A typed transport adapter; the host supplies the binding returned by discovery.

class DesignError extends Error

源码
readonly committed: false源码

Read and planning failures never commit a document change.

new (readonly code: string, message: string, readonly path = "$")源码

type DesignArguments< K extends DesignOperation > = Infer<(typeof operations)[K]["input"]>

源码

Arguments validated by the catalog for an operation.

type DesignBinding = Infer<typeof bindingSchema>

源码

Identifies one editor and one document opening; never substitute a new epoch on retry.

interface DesignCapability

源码

Capability advertised by getState; public mutation remains disabled.

readonly versions: readonly string[]源码
readonly binding: DesignBinding源码
readonly mutationEnabled: false源码

type DesignCommand = Infer<typeof commandSchema>

源码

A duplicate or translate command accepted by the read-only planner.

interface DesignEvent

源码

Stamped invalidation; not a resumable synchronization log.

readonly binding: DesignBinding源码
readonly revision: number源码
readonly kind: "reset" | "transition"源码

type DesignOperation = keyof typeof operations

源码

Operations supported by this version of the read and planning catalog.

type DesignReply = | { readonly ok: true; readonly requestId: string; readonly result: unknown } | { readonly ok: false; readonly requestId: string; readonly error: { readonly code: string; readonly message: string; readonly path: string; readonly committed: false; }; }

源码

Domain errors retain their code, path and committed flag, separate from transport failures.

type DesignRequest = { [K in DesignOperation]: { readonly protocol: typeof DESIGN_PROTOCOL_VERSION; readonly requestId: string; readonly target: DesignBinding; readonly operation: K; readonly arguments: DesignArguments<K>; } }[DesignOperation]

源码

A versioned request with an explicit document-opening target.

type DesignResult< K extends DesignOperation > = Infer<(typeof operations)[K]["output"]>

源码

Result validated by the catalog for an operation.

type DesignTarget = Infer<typeof targetReferenceSchema>

源码

A canonical node or a layer within a component instance.

interface TacoDesignRequestOptions

源码

Limits the entire design call, including startup and capability discovery.

readonly timeoutMs?: number源码

Default 30 seconds. Must be a positive integer no greater than 2,147,483,647.

readonly signal?: AbortSignal源码

Stops waiting and prevents unstarted requests; does not undo a completed remote plan.

C++ 渲染器 C++

310 个条目中已记录 157 个 · 大纲

packages/render-core/cpp 中的 C++ 渲染器只有一个公开接口:include/taco/render_core.h 中的 C 函数和类型。本页的其余内容都是这些函数所调用的内部 C++ 代码。C ABI 是纯 C,因此同一个头文件同时服务于原生构建、测试和 Wasm 构建。

所有工作都在会话上进行。taco_render_session_create 创建一个空会话,taco_render_session_apply 向它输入二进制场景批次(参见 PROTOCOL.md),查询、渲染和叠加层函数则读取它。每个可能失败的函数都返回一个 TacoRenderStatus;大多数失败还会留下一条消息,供 taco_render_session_copy_last_error 读取。输出结构体以一个由调用方设置的 struct_size 字段开头;填充调用方缓冲区的调用会报告所需的大小,并在缓冲区不足时返回 TACO_RENDER_STATUS_BUFFER_TOO_SMALL。针对编辑状态的调用接收它们期望的场景代次,并在场景已经更新时返回 TACO_RENDER_STATUS_STALE_GENERATION。

WebGPU Wasm 构建通过 Emscripten 导出这些 taco_render_* 函数,同时导出 malloc、free 以及它自己的 taco_render_webgpu_* 辅助函数。TypeScript 包以 module._taco_render_session_apply 等形式调用它们,并传入指向 Wasm 堆的指针。一个更小的可移植 Wasm 构建不含 Skia,也不进行绘制;它改为导出“Wasm bridge”下列出的 taco_render_wasm_* 函数。

在 C 函数背后,RetainedSession 保存场景及其计算出的几何信息,SessionCache 保存 Skia 一侧的内容:字体、文本布局、媒体帧、叠加层和增量渲染的脏区域。不含 Skia 的构建保留场景和几何查询,但任何需要绘制或进行文本排版的调用都会返回 TACO_RENDER_STATUS_CAPABILITY_UNAVAILABLE。

版本与能力

ABI 和 wire 格式的版本常量,以及两个报告本构建能力的调用。扩展能力通过追加字段来增长,因此调用方请求自己能理解的版本。

#define TACO_RENDER_ABI_VERSION 1u

源码

该 C ABI 的版本。TacoRenderSessionOptions.abi_version 必须等于它,TacoRenderCapabilities.abi_version 会报告它。

TypeScript: RENDER_CORE_ABI_VERSION

#define TACO_RENDER_WIRE_VERSION 24u

源码

最新的保留场景/变更批次 wire 格式版本。一个批次可以声明从 1 到此版本之间的任意版本;更新的版本会以 UNSUPPORTED_VERSION 失败。

TypeScript: RENDER_CORE_WIRE_VERSION

#define TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION 5u

源码

无头部的独立 VectorNetwork 载荷版本。

TypeScript: RENDER_CORE_VECTOR_NETWORK_WIRE_VERSION

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION 8u

源码

taco_render_get_extended_capabilities 接受的最新版本。每个版本 N 都有对应的 _VERSION_N 和 _VERSION_N_SIZE(该版本所需的结构体大小)。

TacoRenderStatus taco_render_get_capabilities( TacoRenderCapabilities *capabilities ) noexcept

wasm源码

填充版本 1 的能力结构体。调用方设置 struct_size;它必须至少为 sizeof(TacoRenderCapabilities),否则调用返回 INVALID_ARGUMENT。不需要会话。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

struct TacoRenderCapabilities

源码

此构建支持的功能,由 taco_render_get_capabilities 写入。调用方设置 struct_size。每个 uint8_t 字段在支持时为 1。Skia 相关字段(skia、native_raster、skparagraph、harfbuzz、icu)仅在 Skia 构建中为 1;此调用总是将 wasm 和 webgpu 写为 0。较新的功能改由 TacoRenderExtendedCapabilities 报告。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderCoreCapabilities

uint32_t struct_size源码
uint32_t abi_version源码
uint32_t wire_version源码
uint8_t retained_scene源码
uint8_t structured_paths源码
uint8_t styled_text_records源码
uint8_t embedded_resources源码
uint8_t skia源码
uint8_t native_raster源码
uint8_t wasm源码
uint8_t webgpu源码
uint8_t skparagraph源码
uint8_t harfbuzz源码
uint8_t icu源码
uint8_t geometry_queries源码
uint8_t hit_testing源码
uint8_t dirty_bounds源码
uint8_t[2] reserved源码

TacoRenderStatus taco_render_get_extended_capabilities( uint32_t capabilities_version, TacoRenderExtendedCapabilities *capabilities ) noexcept

wasm源码

填充扩展能力,直到 capabilities_version(1 到 TACO_RENDER_EXTENDED_CAPABILITIES_VERSION)为止。只写入前 TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_N_SIZE 个字节,因此使用较小结构体的旧调用方仍然安全。版本未知时返回 UNSUPPORTED_VERSION,struct_size 小于该版本的大小时返回 INVALID_ARGUMENT。不需要会话。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

struct TacoRenderExtendedCapabilities

源码

只追加的能力信息,有意与已冻结的 ABI 版本 1 TacoRenderCapabilities 布局分开。调用方请求一个已声明的版本并提供 struct_size;所有保留字节都写为零。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderCoreCapabilities

uint32_t struct_size源码
uint32_t capabilities_version源码
uint32_t text_query_version源码
uint8_t text_carets源码
uint8_t text_range_rects源码
uint8_t text_hit_testing源码
uint8_t text_navigation源码
uint8_t text_layout_metrics源码
uint8_t text_editing_overlays源码
uint8_t[14] reserved源码
uint32_t vector_query_version源码

版本 2 追加的字段。版本 1 的调用方只能看到前 32 字节。

uint8_t vector_geometry源码
uint8_t vector_hit_testing源码
uint8_t[2] reserved_v2源码
uint32_t vector_editing_overlay_version源码

版本 3 追加的字段。版本 2 的调用方只能看到前 40 字节。

uint8_t vector_editing_overlays源码
uint8_t[3] reserved_v3源码
uint32_t vector_boolean_version源码

版本 4 追加的字段。版本 3 的调用方只能看到前 48 字节。

uint8_t vector_boolean_operations源码
uint8_t[3] reserved_v4源码
uint32_t font_metadata_version源码

版本 5 追加的字段。版本 4 的调用方只能看到前 56 字节。

uint8_t font_metadata源码
uint8_t[3] reserved_v5源码
uint32_t incremental_render_version源码

版本 6 追加的字段。版本 5 的调用方只能看到前 64 字节。

uint8_t incremental_rendering源码
uint8_t render_diagnostics源码
uint8_t[2] reserved_v6源码
uint32_t static_image_frame_version源码

版本 7 追加的字段。版本 6 的调用方只能看到前 72 字节。

uint8_t static_image_frames源码
uint8_t[3] reserved_v7源码
uint32_t video_frame_version源码

版本 8 追加的字段。版本 7 的调用方只能看到前 80 字节。

uint8_t video_frames源码
uint8_t[3] reserved_v8源码

会话与状态码

一个会话持有一个保留场景。可以创建、销毁会话,并读取失败状态背后的消息。

struct TacoRenderSession

不透明类型源码

不透明的渲染器会话:一个保留场景,以及(在 Skia 构建中)用于绘制它的缓存、帧和叠加层。使用 taco_render_session_create 创建,使用 taco_render_session_destroy 释放。会话不是线程安全的;同一时间只能从一个线程调用它。

TacoRenderStatus taco_render_session_create( const TacoRenderSessionOptions *options, TacoRenderSession **session ) noexcept

wasm源码

创建一个空会话并存入 *session(失败时为 NULL)。options 可以为 NULL。提供 options 时,abi_version 不一致返回 UNSUPPORTED_VERSION,struct_size 小于 sizeof(TacoRenderSessionOptions) 返回 INVALID_ARGUMENT。

由 TS 调用: InteractiveRetainedBackend.exportCompiledScene, InteractiveRetainedBackend.outlineCompiledStrokes

由 TS 调用,位于这些条目的辅助函数中: RenderCoreModule.createSession, PortableWasmRenderCoreModule.createSession, createOwnedWasmRenderCoreSession

struct TacoRenderSessionOptions

源码

taco_render_session_create 的可选设置。将 struct_size 设为 sizeof(TacoRenderSessionOptions),将 abi_version 设为 TACO_RENDER_ABI_VERSION。目前还没有其他选项。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t abi_version源码
uint32_t[6] reserved源码

void taco_render_session_destroy(TacoRenderSession *session) noexcept

wasm源码

释放一个会话及其拥有的一切。允许传入 NULL。

由 TS 调用: RenderCoreSession.dispose, RenderCoreModule.createSession, PortableWasmRenderCoreModule.createSession, createOwnedWasmRenderCoreSession

由 TS 调用,经由 RenderCoreSession.dispose: outlineStrokesInThrowawaySession

enum TacoRenderStatus

源码

所有可能失败的 C 函数的返回结果。大多数失败还会保存一条消息,可由 taco_render_session_copy_last_error 返回;taco_render_status_name 给出该常量的名称。

TypeScript: RENDER_CORE_STATUS

TACO_RENDER_STATUS_OK = 0源码
TACO_RENDER_STATUS_INVALID_ARGUMENT = 1源码

空指针、过小的 struct_size,或无效的值。

TACO_RENDER_STATUS_UNSUPPORTED_VERSION = 2源码

此构建不接受的 ABI、wire 格式或载荷版本。

TACO_RENDER_STATUS_MALFORMED_BATCH = 3源码

批次字节被截断,或不符合 wire 格式。

TACO_RENDER_STATUS_LIMIT_EXCEEDED = 4源码

超出了大小、数量或字节数限制。

TACO_RENDER_STATUS_INVALID_SCENE = 5源码

场景,或调用需要从场景中获取的数据无效。

TACO_RENDER_STATUS_NOT_FOUND = 6源码

指定的节点或资源不存在。

TACO_RENDER_STATUS_CAPABILITY_UNAVAILABLE = 7源码

此构建无法执行该操作,例如在没有 Skia 的情况下绘制。

TACO_RENDER_STATUS_BUFFER_TOO_SMALL = 8源码

输出缓冲区过小;所需的大小仍会被写入。

TACO_RENDER_STATUS_INTERNAL_ERROR = 9源码

原生层面的失败,例如内存分配失败或异常。

TACO_RENDER_STATUS_STALE_GENERATION = 10源码

调用传入的 expected_generation 不是场景的当前代次。

size_t taco_render_session_copy_last_error( const TacoRenderSession *session, char *destination, size_t destination_size ) noexcept

wasm源码

把会话的最后一条错误信息复制为以 NUL 结尾的字符串,并返回所需的字节数(包括末尾的 NUL)。复制内容会截断为 destination_size - 1 个字节;传 0 可查询所需大小。大多数成功的调用会清除该信息,但并非每次失败都会设置它,所以请先检查状态码。NULL 会话得到空信息。

由 TS 调用,位于这些条目的辅助函数中: RenderCoreSession.apply, RenderCoreSession.applyWithStaticImageFrames, RenderCoreSession.applyWithMediaFrames, RenderCoreSession.updateVideoFrames, RenderCoreSession.getSceneInfo, RenderCoreSession.getNodeGeometry, RenderCoreSession.getGeometrySnapshot, PortableWasmRenderCoreSession.exportScene

另有 21 项RenderCoreSession.hitTest, RenderCoreSession.getTextCarets, RenderCoreSession.getTextRangeGeometry, RenderCoreSession.hitTestText, RenderCoreSession.navigateText, RenderCoreSession.getTextLayoutMetrics, RenderCoreSession.getFontMetadata, RenderCoreSession.setTextEditingOverlay, RenderCoreSession.setSelectionChrome, RenderCoreSession.setCanvasOverlayFont, RenderCoreSession.setCanvasOverlay, RenderCoreSession.clearTextEditingOverlay, RenderCoreSession.getVectorGeometry, RenderCoreSession.hitTestVector, RenderCoreSession.setVectorEditingOverlay, RenderCoreSession.clearVectorEditingOverlay, PortableWasmRenderCoreSession.outlineStroke, RenderCoreSession.booleanVectorPaths, RenderCoreSession.mapViewport, RenderCoreSession.render, RenderCoreSession.getLastError

由 TS 调用,经由 RenderCoreSession.apply: outlineStrokesInThrowawaySession

由 TS 调用,经由 RenderCoreSession.getSceneInfo: outlineStrokesInThrowawaySession, measureExportFromLoadedSession

由 TS 调用,经由 PortableWasmRenderCoreSession.outlineStroke: outlineStrokesInThrowawaySession

由 TS 调用,经由 RenderCoreSession.getNodeGeometry: measureExportFromLoadedSession

由 TS 调用,经由 measureExportFromLoadedSession: exportFromLoadedSession

由 TS 调用,经由 PortableWasmRenderCoreSession.exportScene: exportFromLoadedSession

const char *taco_render_status_name(TacoRenderStatus status) noexcept

源码

返回状态码的静态名称,例如 “OK” 或 “STALE_GENERATION”;对于 TacoRenderStatus 之外的值,返回 “UNKNOWN_STATUS”。

场景更新

一个批次要么一次性改动整个场景,要么完全不改动。含有图片或视频的场景还会传入解码后的帧,因此像素与场景始终对应同一代号。

TacoRenderStatus taco_render_session_apply( TacoRenderSession *session, const uint8_t *batch, size_t batch_size, TacoRenderUpdateReport *report ) noexcept

wasm源码

应用一个完整的保留场景批次(PROTOCOL.md 中的“TCR1” wire 格式)。批次要么全部生效,要么全部不生效:失败时场景保持不变,不写入报告,状态码通常为 MALFORMED_BATCH、UNSUPPORTED_VERSION、LIMIT_EXCEEDED 或 INVALID_SCENE。report 可以为 NULL。至少包含一条命令的批次会使代次加一。

在 Skia 构建中,成功的应用还会丢弃所有已安装的图片帧和视频帧,因此包含媒体的场景应改用 taco_render_session_apply_with_media_frames;代次变化还会清除文本和矢量编辑叠加层。

由 TS 调用: InteractiveRetainedBackend.apply, InteractiveRetainedBackend.exportCompiledScene, InteractiveRetainedBackend.outlineCompiledStrokes, RenderChangeBatchEncoder, RenderCoreSession.apply

由 TS 调用,经由 InteractiveRetainedBackend.apply: InteractiveRenderSession.loadDocument, InteractiveRenderSessionCoordinator.loadDocument, InteractiveRenderSession.applyDocumentUpdate, InteractiveRenderSessionCoordinator.applyDocumentUpdate, InteractiveRenderSession.setActivePage, InteractiveRenderSessionCoordinator.setActivePage

由 TS 调用,经由 RenderCoreSession.apply: outlineStrokesInThrowawaySession

实现者: RetainedSession.state, RetainedSession.apply, SessionCache.recordSuccessfulApply, SessionCache.invalidateMediaFrames, SessionCache.recordSceneUpdateTime

struct TacoRenderUpdateReport

源码

在批次成功应用后写入。commands_applied 统计该批次的命令数;node_count 和 resource_count 描述应用批次之后的场景。每个至少包含一条命令的批次都会使 generation 加一,scene_digest 是保留场景内容的哈希值。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderUpdateReport

uint32_t struct_size源码
uint32_t commands_applied源码
uint32_t node_count源码
uint32_t resource_count源码
uint64_t generation源码
uint64_t scene_digest源码

TacoRenderStatus taco_render_session_apply_with_static_image_frames( TacoRenderSession *session, const uint8_t *batch, size_t batch_size, const TacoRenderStaticImageFrameSet *frame_set, TacoRenderUpdateReport *report ) noexcept

wasm源码

原子地应用一个保留场景批次,并安装该候选代次精确的静态图片集合。除非整个事务成功,否则场景、图片缓存、待处理的脏区域和报告都保持不变。Portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

frame_set->expected_generation 必须是应用批次之前的代次(否则返回 STALE_GENERATION)。这些帧必须按资源 ID 升序、每个恰好一次地指定新场景使用的每个图片资源;缺少或多出的 ID 返回 INVALID_SCENE。包含视频的场景返回 CAPABILITY_UNAVAILABLE;这种场景请使用 taco_render_session_apply_with_media_frames。

由 TS 调用: InteractiveRetainedBackend.exportCompiledScene, RenderCoreSession.applyWithStaticImageFrames

实现者: RetainedSession.state, SessionCache.applyWithStaticImageFrames, SessionCache.recordSceneUpdateTime, isValidUtf8

TacoRenderStatus taco_render_session_apply_with_media_frames( TacoRenderSession *session, const uint8_t *batch, size_t batch_size, const TacoRenderMediaFrameSet *frame_set, TacoRenderUpdateReport *report ) noexcept

wasm源码

原子地应用一个保留场景批次,并安装该候选代次精确的图片/视频混合帧集合。除非整个事务成功,否则不会发布任何场景、帧缓存、脏区域或报告状态。

规则与 taco_render_session_apply_with_static_image_frames 相同,但帧可以是图片或视频(由每条记录的类型决定),并且合起来要指定新场景使用的每个媒体资源。Portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: RenderCoreSession.applyWithMediaFrames

实现者: RetainedSession.state, SessionCache.applyWithMediaFrames, SessionCache.recordSceneUpdateTime

struct TacoRenderStaticImageFrameSet

源码

expected_generation 是应用该批次之前的当前代次。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码
const TacoRenderStaticImageFrame *frames源码
size_t frame_count源码

struct TacoRenderStaticImageFrame

源码

一个完整的、按逻辑资源 ID 去重的静态图片集合中的一个成员。content_revision 是由调用方持有的、稳定且非零的内容标识。

REUSE_ACTIVE 只提供标识符、kind 和 revision;所有像素字段都为零或 null,并且当前活动的缓存中必须包含相同的 revision。RGBA8888 提供紧密排列、非预乘的 RGBA8888 sRGB 像素。版本 1 要求记录大小与此完全一致、row_bytes == width * 4,并且 byte_length 精确匹配;外围数组没有独立的记录跨度(stride)。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t disposition源码
uint32_t kind源码
uint32_t reserved源码
const char *asset_id源码
size_t asset_id_size源码
uint64_t content_revision源码
uint32_t width源码
uint32_t height源码
uint32_t row_bytes源码
uint32_t reserved_v1源码
const uint8_t *pixels源码
size_t byte_length源码

TacoRenderStatus taco_render_session_update_video_frames( TacoRenderSession *session, const TacoRenderMediaFrameSet *frame_set, TacoRenderDirtyBounds *dirty_bounds ) noexcept

wasm源码

替换完整的视频帧集合,而不改变保留场景的标识。代次(generation)、摘要(digest)、历史和编辑权限都保持不变。成功时,dirty_bounds 包含所有使用了已变化视频资源的可见节点的并集。portable/no-Skia 构建返回 CAPABILITY_UNAVAILABLE。

每一帧都必须是视频帧,并且该集合必须恰好命名场景中的每个视频资源一次。它要求当前代次已有一个由 taco_render_session_apply_with_media_frames 安装的当前混合集合;否则返回 INVALID_SCENE。

由 TS 调用: RenderCoreSession.updateVideoFrames

实现者: RetainedSession.state, SessionCache.updateVideoFrames

场景查询

读回场景:它的尺寸和计数、单个节点的值和几何、所有节点的几何(一次性获取)、点命中、上次更新改动的区域,以及场景如何映射到视口中。

TacoRenderStatus taco_render_session_get_scene_info( const TacoRenderSession *session, TacoRenderSceneInfo *info ) noexcept

wasm源码

写出场景的尺寸、各项计数、代次和摘要。

由 TS 调用: InteractiveRetainedBackend.getSceneInfo, RenderCoreSession.getSceneInfo

由 TS 调用,位于这些条目的辅助函数中: RenderCoreSession.updateVideoFrames, RenderCoreSession.getTextCarets, RenderCoreSession.getTextRangeGeometry, RenderCoreSession.hitTestText

另有 11 项RenderCoreSession.navigateText, RenderCoreSession.getTextLayoutMetrics, RenderCoreSession.getFontMetadata, RenderCoreSession.setTextEditingOverlay, RenderCoreSession.clearTextEditingOverlay, RenderCoreSession.getVectorGeometry, RenderCoreSession.hitTestVector, RenderCoreSession.setVectorEditingOverlay, RenderCoreSession.clearVectorEditingOverlay, PortableWasmRenderCoreSession.outlineStroke, RenderCoreSession.booleanVectorPaths

由 TS 调用,经由 InteractiveRetainedBackend.getSceneInfo: InteractiveRenderSession.getSceneGeometrySnapshot, InteractiveRenderSession.getVectorGeometry, InteractiveRenderSession.hitTestVector, InteractiveRenderSession.loadDocument, InteractiveRenderSessionCoordinator.loadDocument, InteractiveRenderSession.applyDocumentUpdate, InteractiveRenderSessionCoordinator.applyDocumentUpdate, InteractiveRenderSession.setActivePage

另有 18 项InteractiveRenderSessionCoordinator.setActivePage, InteractiveRenderSessionCoordinator.getSceneGeometrySnapshot, InteractiveRenderSession.getTextGeometry, InteractiveRenderSessionCoordinator.getTextGeometry, InteractiveRenderSession.hitTestText, InteractiveRenderSessionCoordinator.hitTestText, InteractiveRenderSession.navigateText, InteractiveRenderSessionCoordinator.navigateText, InteractiveRenderSessionCoordinator.getVectorGeometry, InteractiveRenderSessionCoordinator.hitTestVector, InteractiveRenderSession.booleanVectorPaths, InteractiveRenderSessionCoordinator.booleanVectorPaths, InteractiveRenderSession.renderFrame, InteractiveRenderSessionCoordinator.renderFrame, InteractiveRenderSessionCoordinator.getSceneInfo, InteractiveRenderSessionCoordinator.getTextLayoutMetrics, InteractiveRenderSessionCoordinator.getFontMetadata, InteractiveRenderSessionCoordinator.resolveAccessibilityActionRouteV1

由 TS 调用,经由 RenderCoreSession.getSceneInfo: outlineStrokesInThrowawaySession, measureExportFromLoadedSession

由 TS 调用,经由 PortableWasmRenderCoreSession.outlineStroke: outlineStrokesInThrowawaySession

由 TS 调用,经由 measureExportFromLoadedSession: exportFromLoadedSession

实现者: RetainedSession.state, RetainedSession.digest

struct TacoRenderSceneInfo

源码

场景当前的尺寸(以场景单位计)、节点数与资源数、代次和摘要。由 taco_render_session_get_scene_info 写入。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderSceneInfo

uint32_t struct_size源码
uint32_t node_count源码
uint32_t resource_count源码
uint32_t reserved源码
double width源码
double height源码
uint64_t generation源码
uint64_t scene_digest源码

TacoRenderStatus taco_render_session_get_node_info( const TacoRenderSession *session, const char *node_id, size_t node_id_size, TacoRenderNodeInfo *info ) noexcept

源码

写出一个节点作者设置的类型、z 顺序、可见性、变换、不透明度和最宽描边。node_id 是 node_id_size 个字节的 UTF-8,不以 NUL 结尾,且不能为空。节点未知时返回 NOT_FOUND。

实现者: RetainedSession.findNode, Node.kind, NodeStyle.maximumStrokeWidth

struct TacoRenderNodeInfo

源码

节点的设计值(由作者设置的值),由 taco_render_session_get_node_info 写入。kind 是一个 TacoRenderNodeKind 值。transform 是节点自身的局部变换,形式为 (a, b, c, d, e, f),其中 x’ = a*x + c*y + e,y’ = b*x + d*y + f。stroke_width 是节点所有描边中最宽的宽度;没有描边时为 0。

uint32_t struct_size源码
uint32_t kind源码
int32_t z_order源码
uint8_t visible源码
uint8_t[3] reserved源码
double[6] transform源码
double opacity源码
double stroke_width源码

TacoRenderStatus taco_render_session_get_node_geometry( const TacoRenderSession *session, const char *node_id, size_t node_id_size, TacoRenderNodeGeometry *geometry ) noexcept

wasm源码

写出一个节点计算得到的几何信息:世界变换,局部、世界和可见边界,绘制顺序以及有效不透明度。节点未知时返回 NOT_FOUND。

由 TS 调用: InteractiveRetainedBackend.getNodeGeometry, RenderCoreSession.getNodeGeometry

由 TS 调用,经由 InteractiveRetainedBackend.getNodeGeometry: InteractiveRenderSession.getNodeGeometry, InteractiveRenderSessionCoordinator.getNodeGeometry

由 TS 调用,经由 RenderCoreSession.getNodeGeometry: measureExportFromLoadedSession

由 TS 调用,经由 measureExportFromLoadedSession: exportFromLoadedSession

实现者: RetainedSession.findNode, RetainedSession.geometrySnapshot

struct TacoRenderNodeGeometry

源码

译文已过期

A node’s computed geometry, written by taco_render_session_get_node_geometry. Each has_* byte says whether the matching bounds are present. world_bounds are in scene coordinates; visible_world_bounds are also clipped by clipping ancestors and are absent when the node is not effectively visible. painter_order is the node’s back-to-front paint position, and effective_opacity and effectively_visible include every ancestor. subtree_visible_bounds joins the node’s visible bounds with those of all its descendants, the way they are painted: children of a clipping frame are clipped to it, a masked sibling is clipped to its mask, and a node’s layer blur spreads around its descendants too. So it covers everything the subtree paints. Callers built before it was appended may pass the shorter struct_size; the tail is then left unwritten.

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderNodeGeometry

uint32_t struct_size源码
uint32_t kind源码
uint8_t has_local_bounds源码
uint8_t has_world_bounds源码
uint8_t has_visible_world_bounds源码
uint8_t effectively_visible源码
uint64_t painter_order源码
double effective_opacity源码
double[6] world_transform源码
TacoRenderRect local_bounds源码
TacoRenderRect world_bounds源码
TacoRenderRect visible_world_bounds源码
uint8_t has_subtree_visible_bounds源码
uint8_t[7] reserved源码
TacoRenderRect subtree_visible_bounds源码

TacoRenderStatus taco_render_session_get_geometry_snapshot( const TacoRenderSession *session, TacoRenderGeometryRecord *records, size_t record_capacity, char *node_id_bytes, size_t node_id_capacity, uint64_t *generation, size_t *record_count, size_t *node_id_byte_count ) noexcept

wasm源码

几何记录按绘制顺序从后到前返回。即使提供的缓冲区太小,也会写入代次和两个所需计数。在两个缓冲区都足够之前,不会写入任何记录或标识符字节。

任一缓冲区不足时返回 BUFFER_TOO_SMALL;可先传容量 0 查询所需大小。节点标识符在 node_id_bytes 中首尾相接地紧凑排列,每条记录都指向其中的位置。

由 TS 调用: InteractiveRetainedBackend.getGeometrySnapshot, RenderCoreSession.getGeometrySnapshot

由 TS 调用,经由 InteractiveRetainedBackend.getGeometrySnapshot: InteractiveRenderSession.getSceneGeometrySnapshot, InteractiveRenderSessionCoordinator.getSceneGeometrySnapshot

实现者: RetainedSession.geometrySnapshot, RetainedSession.state

struct TacoRenderGeometryRecord

源码

taco_render_session_get_geometry_snapshot 中的一个节点。它包含与 TacoRenderNodeGeometry 相同的值,只是 has_* 字节被打包进 flags(TacoRenderGeometryFlags)。节点标识符是该调用的标识符缓冲区中,从 node_id_offset 开始的 node_id_size 个字节。

TypeScript: decodeWasmGeometryRecords, PORTABLE_WASM_ABI_LAYOUT, RenderNodeGeometry

TypeScript,经由 decodeWasmGeometryRecords: RenderCoreSession.getGeometrySnapshot

uint32_t struct_size源码
uint32_t node_id_offset源码
uint32_t node_id_size源码
uint32_t kind源码
uint32_t flags源码
uint32_t reserved源码
uint64_t painter_order源码
double effective_opacity源码
double[6] world_transform源码
TacoRenderRect local_bounds源码
TacoRenderRect world_bounds源码
TacoRenderRect visible_world_bounds源码

TacoRenderStatus taco_render_session_hit_test( const TacoRenderSession *session, double world_x, double world_y, double world_tolerance, TacoRenderHit *hits, size_t hit_capacity, char *node_id_bytes, size_t node_id_capacity, size_t *hit_count, size_t *node_id_byte_count ) noexcept

wasm源码

查找场景点(world_x, world_y)下的可见节点;对路径而言,距离在 world_tolerance 个场景单位以内也算命中。祖先节点的裁剪会生效。命中结果按从最上层到最下层的顺序返回。hit_count 和 node_id_byte_count 总会收到所需的大小;任一缓冲区过小时,不会写入其他内容,调用返回 BUFFER_TOO_SMALL。输入必须是有限值,容差必须非负。

由 TS 调用: InteractiveRetainedBackend.hitTest, RenderCoreSession.hitTest

由 TS 调用,经由 InteractiveRetainedBackend.hitTest: InteractiveRenderSession.hitTest, InteractiveRenderSessionCoordinator.hitTest, InteractiveRenderSessionCoordinator.hitTestIncludingLocked

实现者: RetainedSession.state, RetainedSession.hitTest, toRect

struct TacoRenderHit

源码

某点下方的一个节点,由 taco_render_session_hit_test 写入。节点标识符是该调用的标识符缓冲区中,从 node_id_offset 开始的 node_id_size 个字节。kind 是一个 TacoRenderNodeKind 值。

TypeScript: decodeWasmHitRecords, PORTABLE_WASM_ABI_LAYOUT, RenderHit

TypeScript,经由 decodeWasmHitRecords: RenderCoreSession.hitTest

uint32_t struct_size源码
uint32_t node_id_offset源码
uint32_t node_id_size源码
uint32_t kind源码
uint32_t reserved源码
uint64_t painter_order源码
TacoRenderRect visible_world_bounds源码

TacoRenderStatus taco_render_session_get_last_dirty_bounds( const TacoRenderSession *session, TacoRenderDirtyBounds *dirty_bounds ) noexcept

wasm源码

写出最近一次成功的批次应用在场景空间中改变的区域,并标上那一次的代次。

由 TS 调用,位于这些条目的辅助函数中: RenderCoreSession.apply, RenderCoreSession.applyWithStaticImageFrames, RenderCoreSession.applyWithMediaFrames

由 TS 调用,经由 RenderCoreSession.apply: outlineStrokesInThrowawaySession

实现者: RetainedSession.lastDirtyBounds, toRect

struct TacoRenderDirtyBounds

源码

一次更新所改变的场景空间区域:old_bounds 覆盖变化节点之前绘制的内容,new_bounds 覆盖它们之后绘制的内容,combined_bounds 覆盖两者。每个 has_* 字节表示对应矩形是否已设置。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, RenderDirtyBounds

uint32_t struct_size源码
uint8_t has_old_bounds源码
uint8_t has_new_bounds源码
uint8_t has_combined_bounds源码
uint8_t reserved源码
uint64_t generation源码
TacoRenderRect old_bounds源码
TacoRenderRect new_bounds源码
TacoRenderRect combined_bounds源码

TacoRenderStatus taco_render_session_map_viewport( const TacoRenderSession *session, const TacoRenderViewportOptions *options, TacoRenderViewportMapping *mapping ) noexcept

wasm源码

按适应(fit)、填满(fill)或拉伸(stretch)方式,以给定的对齐方式,计算场景的宽高如何映射到视口中。它只做计算,不改变任何状态。选项无效时返回 INVALID_ARGUMENT;场景没有正尺寸或结果不是有限值时返回 INVALID_SCENE。

由 TS 调用: RenderCoreSession.mapViewport

实现者: RetainedSession.state

struct TacoRenderViewportOptions

源码

taco_render_session_map_viewport 的输入。mode 是一个 TacoRenderViewportMode 值。视口尺寸必须是有限的正数。align_x 和 align_y 取值均为 0 到 1,用于在剩余空间中放置场景:0 表示左侧或顶部,0.5 表示居中,1 表示右侧或底部。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, ViewportMappingOptions

uint32_t struct_size源码
uint32_t mode源码
double viewport_width源码
double viewport_height源码
double align_x源码
double align_y源码

struct TacoRenderViewportMapping

源码

taco_render_session_map_viewport 的输出:场景到视口的仿射变换、其逆变换(两者都表示为 a, b, c, d, e, f),以及场景在视口中的位置。

TypeScript: PORTABLE_WASM_ABI_LAYOUT, ViewportMapping

uint32_t struct_size源码
uint32_t reserved源码
double[6] scene_to_viewport源码
double[6] viewport_to_scene源码
TacoRenderRect scene_viewport_bounds源码

渲染与导出

把场景绘制到调用方持有的 RGBA 像素中,可以完整绘制,也可以只绘制发生变化的部分;或者把某个区域导出为 RGBA、PNG、SVG 或 PDF 字节。

TacoRenderStatus taco_render_session_render_rgba( TacoRenderSession *session, const TacoRenderRgbaTarget *target ) noexcept

wasm源码

把整个场景绘制到目标中,将场景的宽高缩放到目标的宽高。每个像素都会在白色背景上重新绘制。编辑叠加层、画布叠加层和选区框与控制柄绘制在场景之上。在 portable/no-Skia 构建中返回 CAPABILITY_UNAVAILABLE;场景含有媒体、但没有已安装的当前帧集合时,也返回该状态码。

由 TS 调用: RenderCoreSession.render

实现者: renderRgba

struct TacoRenderRgbaTarget

源码

渲染调用使用的、由调用方持有的预乘 alpha RGBA8888 像素。row_bytes 必须至少为 width * 4,byte_length 必须至少为 row_bytes * height。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t width源码
uint32_t height源码
uint32_t row_bytes源码
uint8_t *pixels源码
size_t byte_length源码

TacoRenderStatus taco_render_session_render_rgba_incremental( TacoRenderSession *session, const TacoRenderRgbaTarget *target, const TacoRenderIncrementalRenderOptions *options, TacoRenderIncrementalFrameReport *report ) noexcept

wasm源码

与 taco_render_session_render_rgba 类似,但当目标的像素指针、尺寸和行跨度(row stride)都未变化时,只重绘自上次成功渲染以来发生变化的区域。否则,或者传入 TACO_RENDER_INCREMENTAL_RENDER_FORCE_FULL 时,重绘全部内容。options->expected_generation 不是当前代次时返回 STALE_GENERATION。成功时(包括没有任何内容需要重绘的帧)写入报告。portable/no-Skia 构建返回 CAPABILITY_UNAVAILABLE。

实现者: renderRgbaIncremental

struct TacoRenderIncrementalRenderOptions

源码

taco_render_session_render_rgba_incremental 的输入。flags 是 TacoRenderIncrementalRenderFlags 的按位或;expected_generation 必须是场景的当前代次。

uint32_t struct_size源码
uint32_t flags源码
uint64_t expected_generation源码

struct TacoRenderIncrementalFrameReport

源码

耗时是由原生核心测得的有限毫秒数。CPU 渲染将 submit_ms 报告为零。未来的增量 WebGPU 桥接层在把帧暴露给 TypeScript 之前,必须加上其队列提交耗时。报告只在渲染成功之后写入(包括没有任何脏区域、成功完成的帧)。

uint32_t struct_size源码
uint32_t flags源码
uint32_t nodes_painted源码
uint32_t nodes_considered源码
uint64_t generation源码
uint64_t scene_digest源码
TacoRenderDeviceRect device_damage源码
double scene_update_ms源码
double layout_ms源码
double paint_ms源码
double submit_ms源码
uint64_t retained_payload_bytes源码
uint32_t decoded_font_entries源码
uint32_t text_layout_entries源码

TacoRenderStatus taco_render_session_export( TacoRenderSession *session, const TacoRenderExportRequest *request, TacoRenderExportResult *result ) noexcept

wasm源码

导出一个场景区域。这些字节归会话所有,直到下一次导出或会话销毁为止;用 taco_render_session_copy_export_bytes 把它们复制出来。导出失败时不保留任何字节。result 只在成功时写入;result->byte_length 是要复制的大小。Portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: InteractiveRetainedBackend.exportCompiledScene, PortableWasmRenderCoreSession.exportScene

由 TS 调用,经由 PortableWasmRenderCoreSession.exportScene: exportFromLoadedSession

实现者: exportScene

struct TacoRenderExportRequest

源码

taco_render_session_export 的输入;format 是一个 TacoRenderExportFormat 值。

TypeScript: RenderExportRequest

uint32_t struct_size源码
uint32_t format源码
double x源码

导出区域,使用场景坐标。

double y源码
double width源码
double height源码
double scale源码

每个场景单位对应的输出单位数:光栅格式为像素,SVG 为用户单位,PDF 为点(point)。

const char *root_node_id源码

可选。非空时只绘制此节点及其后代,因此与之重叠的兄弟节点和祖先节点不会出现在导出结果中。

size_t root_node_id_size源码
uint32_t image_sampling源码

图片填充和媒体帧的重采样方式;取值为 TacoRenderExportImageSampling。为零时沿用屏幕显示所用的双线性采样。

uint32_t flags源码

TacoRenderExportFlags 值的按位或。

double pdf_raster_dpi源码

仅限 PDF:对 PDF 无法表达的效果(模糊、阴影)进行光栅化时使用的分辨率,单位为每英寸点数(DPI)。为零表示 72。

struct TacoRenderExportResult

源码

taco_render_session_export 成功时的输出。

TypeScript: RenderExportResult

uint32_t struct_size源码
uint32_t pixel_width源码

输出尺寸:ceil(region * scale)。光栅格式以像素为单位使用该值。

uint32_t pixel_height源码
uint32_t row_bytes源码

TACO_RENDER_EXPORT_RGBA 的每行字节数;其他所有格式为零。

size_t byte_length源码
uint32_t request_struct_size源码

此构建读取的请求结构体大小,宿主据此可以判断图片采样、flags 和 PDF 分辨率字段是否已被采用。

enum TacoRenderExportFormat

源码

场景导出。保留场景中的一个矩形区域,经由与屏幕显示相同的绘制器绘制到以下某种目标中。编辑叠加层从不导出,背景保持透明。

TypeScript: RenderExportFormat

TACO_RENDER_EXPORT_RGBA = 1源码

紧密排列、非预乘的 RGBA8888 行,每行 pixel_width * 4 字节。

TACO_RENDER_EXPORT_PNG = 2源码

PNG,前提是构建中带有 PNG 编码器;否则不可用。

TACO_RENDER_EXPORT_SVG = 3源码

SVG,其中文本转换为轮廓。

TACO_RENDER_EXPORT_PDF = 4源码

单页 PDF,其页面即缩放后的区域。

size_t taco_render_session_copy_export_bytes( const TacoRenderSession *session, uint8_t *destination, size_t destination_size ) noexcept

wasm源码

复制最近一次成功导出的最多 destination_size 个字节,并返回实际复制的字节数。session 或 destination 为 NULL 时返回 0。

由 TS 调用: PortableWasmRenderCoreSession.exportScene

由 TS 调用,经由 PortableWasmRenderCoreSession.exportScene: exportFromLoadedSession

文本查询与文本编辑叠加层

单个文本节点的光标、选区矩形、命中测试、光标移动和尺寸度量,读取自与绘制时相同的布局。叠加层在用户编辑时绘制选区、输入法组合文本和光标。

TacoRenderStatus taco_render_session_get_text_carets( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextQuery *query, TacoRenderTextCaret *carets, size_t caret_capacity, TacoRenderTextBufferResult *result ) noexcept

wasm源码

文本查询。它们读取与绘制时相同的缓存布局,使用文本节点的局部坐标,并遵循以下共同规则:节点必须是文本节点(否则返回 INVALID_ARGUMENT,节点不存在时返回 NOT_FOUND),查询的 expected_generation 必须是当前代次(否则返回 STALE_GENERATION),portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

本函数写出文本的每个光标位置。caret_capacity 太小时(传 0 可查询),返回 BUFFER_TOO_SMALL,并且只写入 result->required_count。光标数超过 TACO_RENDER_TEXT_QUERY_MAX_RECORDS 时返回 LIMIT_EXCEEDED。

由 TS 调用: InteractiveRetainedBackend.getTextGeometry, RenderCoreSession.getTextCarets

实现者: SessionCache.getTextCaretCount, RetainedSession.state, SessionCache.getTextCarets

TacoRenderStatus taco_render_session_get_text_range_rects( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextRangeQuery *query, TacoRenderTextRect *rects, size_t rect_capacity, TacoRenderTextBufferResult *result ) noexcept

wasm源码

写出 query->anchor 与 query->focus 之间的选区矩形。大小协商方式与 taco_render_session_get_text_carets 相同。位于文本之外的位置返回 INVALID_ARGUMENT。

由 TS 调用: InteractiveRetainedBackend.getTextGeometry, RenderCoreSession.getTextRangeGeometry

实现者: RetainedSession.state, SessionCache.getTextRangeRects

TacoRenderStatus taco_render_session_hit_test_text( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextHitQuery *query, TacoRenderTextHitResult *result ) noexcept

wasm源码

查找距离节点局部坐标点最近的光标位置。当该点位于已排版的文本之上时,result->inside 为 1。

由 TS 调用: InteractiveRetainedBackend.hitTestText, RenderCoreSession.hitTestText

实现者: SessionCache.hitTestText

TacoRenderStatus taco_render_session_navigate_text( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextNavigationQuery *query, TacoRenderTextNavigationResult *result ) noexcept

wasm源码

按一个 TacoRenderTextNavigationOperation 移动光标位置。光标无法移动时,result->has_result 为 0。向上或向下移动一行时,把返回的 preferred_local_x 传回,以保持光标所在的列。

由 TS 调用: InteractiveRetainedBackend.navigateText, RenderCoreSession.navigateText

实现者: SessionCache.navigateText

TacoRenderStatus taco_render_session_get_text_layout_metrics( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextQuery *query, TacoRenderTextLayoutMetrics *metrics ) noexcept

wasm源码

写出文本的画框尺寸和内容尺寸、其自动调整大小模式建议的画框尺寸,以及段落数、行数和光标数。

由 TS 调用: InteractiveRetainedBackend.getTextLayoutMetrics, RenderCoreSession.getTextLayoutMetrics

实现者: SessionCache.getTextLayoutMetrics

struct TacoRenderTextBufferResult

源码

对于有上限的查询,result 在 OK 和 BUFFER_TOO_SMALL 时写入。在 BUFFER_TOO_SMALL 时,required_count 是精确值,记录缓冲区不会被改动。其他任何失败都不会改动 result 和记录缓冲区。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t required_count源码
uint64_t generation源码

struct TacoRenderTextPosition

源码

相对于段落的偏移量,按设计时文本的 UTF-16 码元计数。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t paragraph_index源码
uint32_t utf16_offset源码
uint32_t affinity源码
uint32_t reserved源码

TacoRenderStatus taco_render_session_set_text_editing_overlay( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderTextEditingOverlay *overlay ) noexcept

wasm源码

在一个文本节点上绘制文本编辑叠加层:从 selection_anchor 到 selection_focus 的选区、可选的输入法(IME)组合范围(标志 HAS_COMPOSITION)以及光标(标志 CARET_VISIBLE)。它会替换之前的任何文本叠加层,从不导出,并在下一次改变代次的批次应用时被清除。校验规则与文本查询相同;未知标志或超出文本范围的位置返回 INVALID_ARGUMENT。

由 TS 调用: InteractiveRetainedBackend.setOverlays, RenderCoreSession.setTextEditingOverlay

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: SessionCache.setTextEditingOverlay

TacoRenderStatus taco_render_session_clear_text_editing_overlay( TacoRenderSession *session, const TacoRenderTextQuery *query ) noexcept

wasm源码

移除文本编辑叠加层。query->expected_generation 不是当前代次时返回 STALE_GENERATION,在 portable/无 Skia 构建中返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: InteractiveRetainedBackend.setOverlays, RenderCoreSession.clearTextEditingOverlay

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: RetainedSession.state, SessionCache.clearTextEditingOverlay

struct TacoRenderTextEditingOverlay

源码

taco_render_session_set_text_editing_overlay 的输入。flags 是 TacoRenderTextEditingOverlayFlags 的按位或;只有设置了 HAS_COMPOSITION 时才会读取组合范围。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t flags源码
uint64_t expected_generation源码
TacoRenderTextPosition selection_anchor源码
TacoRenderTextPosition selection_focus源码
TacoRenderTextPosition composition_anchor源码
TacoRenderTextPosition composition_focus源码

Vector geometry, vector editing overlay, booleans and stroke outlines

Read a path’s vector network in screen space, hit test its parts, preview an edited network over the scene, combine two paths with a Boolean operation, and turn a stroke into the filled shape it paints.

TacoRenderStatus taco_render_session_get_vector_geometry( const TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderVectorQuery *query, TacoRenderVectorVertex *vertices, size_t vertex_capacity, TacoRenderVectorCubicHandle *handles, size_t handle_capacity, TacoRenderVectorSegment *segments, size_t segment_capacity, TacoRenderVectorRegion *regions, size_t region_capacity, char *identifier_bytes, size_t identifier_capacity, TacoRenderVectorBufferResult *result ) noexcept

wasm源码

把路径节点的矢量网络读取为顶点、三次贝塞尔控制柄、线段和区域,每项都带有局部坐标和屏幕坐标。屏幕坐标使用 query->document_to_screen,它必须是有限且可逆的。标识符紧凑排列在 identifier_bytes 中,每条记录都指向其中的位置。在 OK 和 BUFFER_TOO_SMALL 时,result 都包含所有计数(可传容量 0 查询)。节点不存在时返回 NOT_FOUND,节点不是路径时返回 INVALID_ARGUMENT,还可能返回 STALE_GENERATION,超过 TACO_RENDER_VECTOR_QUERY_MAX_RECORDS 时返回 LIMIT_EXCEEDED。适用于所有构建。

由 TS 调用: InteractiveRetainedBackend.getVectorGeometry, RenderCoreSession.getVectorGeometry

实现者: RetainedSession.state, RetainedSession.findNode, RetainedSession.geometrySnapshot, queryVectorGeometry

struct TacoRenderVectorQuery

源码

矢量几何在 CSS 屏幕空间中计算,使用调用方提供的这个文档到屏幕的仿射变换。该仿射变换必须是有限且非奇异的。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码
double[6] document_to_screen源码

struct TacoRenderVectorBufferResult

源码

在 OK 和 BUFFER_TOO_SMALL 时,此结果会被写入,其中包含精确的所需大小。记录缓冲区和标识符缓冲区只在 OK 时、且所有缓冲区都容纳得下之后才会写入。其他失败不会改动任何输出。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t vertex_count源码
uint32_t handle_count源码
uint32_t segment_count源码
uint32_t region_count源码
uint32_t identifier_byte_count源码
uint32_t[2] reserved源码
uint64_t generation源码

TacoRenderStatus taco_render_session_hit_test_vector( const TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderVectorHitQuery *query, TacoRenderVectorHit *hits, size_t hit_capacity, char *identifier_bytes, size_t identifier_capacity, TacoRenderVectorHitBufferResult *result ) noexcept

wasm源码

查找路径节点上靠近某屏幕点、距离在 tolerance_css_px 个 CSS 像素以内的矢量组成部分(顶点、控制柄、线段、区域)。状态码与大小规则同 taco_render_session_get_vector_geometry。

由 TS 调用: InteractiveRetainedBackend.hitTestVector, RenderCoreSession.hitTestVector

实现者: RetainedSession.state, RetainedSession.findNode, RetainedSession.geometrySnapshot, hitTestVectorComponents

TacoRenderStatus taco_render_session_set_vector_editing_overlay( TacoRenderSession *session, const char *node_id, size_t node_id_size, const TacoRenderVectorEditingOverlay *overlay, const uint8_t *network_bytes, size_t network_byte_count, const TacoRenderVectorEditingComponent *components, size_t component_count, const char *identifier_bytes, size_t identifier_byte_count ) noexcept

wasm源码

译文已过期

Installs a transient, generation-stamped full-network preview. The accepted overlay is independent of canonical retained state and replaces prior vector-overlay state only after every byte, component, and owner check succeeds. Portable/no-Skia builds return CAPABILITY_UNAVAILABLE.

node_id names the path node being edited. network_bytes is the edited network; components lists the selected parts, whose identifiers are packed into identifier_bytes. component_count and identifier_byte_count must equal the overlay’s fields. overlay_version is read first, from the 8 bytes every version of the record starts with: a different version returns UNSUPPORTED_VERSION whatever the record’s size, so a 104-byte version-1 record does. A struct_size under those 8 bytes, or under sizeof(TacoRenderVectorEditingOverlay) in a record of the current version, returns INVALID_ARGUMENT. A different network_wire_version returns UNSUPPORTED_VERSION once the rest of the record is valid; an old expected_generation returns STALE_GENERATION. The overlay is never exported and is cleared by the next apply that changes the generation.

由 TS 调用: InteractiveRetainedBackend.setOverlays, RenderCoreSession.setVectorEditingOverlay

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: RetainedSession.state, SessionCache.setVectorEditingOverlay

struct TacoRenderVectorEditingOverlay

源码

矢量网络字节载荷使用 TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION,大小上限为 TACO_RENDER_VECTOR_EDITING_OVERLAY_MAX_NETWORK_BYTES。CSS 视口值描述调用方所安装的确切视口;原生代码从保留场景推导出所属节点的局部到文档变换,并将其与此仿射变换组合,用于所有预览几何、选区强调显示、编辑用的控制框与控制柄,以及相关祖先节点的裁剪。每个仿射系数的绝对值最多为 16,777,216。CSS 尺寸和像素密度必须在闭区间 [1e-28, 16,777,216] 内。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t overlay_version源码
uint64_t expected_generation源码
double[6] document_to_screen源码
double screen_width_css_px源码
double screen_height_css_px源码
double screen_pixel_density源码
uint32_t network_wire_version源码
uint32_t component_count源码
uint32_t identifier_byte_count源码
uint32_t pending_handle_flags源码

TacoRenderVectorEditingPendingHandleFlags; zero when no handle is pending.

uint32_t pending_handle_vertex_index源码

Position of the handle’s vertex in the preview network’s vertex table.

uint32_t reserved源码
double pending_handle_dx源码

The handle’s offset from its vertex, in the owner’s local units.

double pending_handle_dy源码

TacoRenderStatus taco_render_session_clear_vector_editing_overlay( TacoRenderSession *session, const TacoRenderVectorEditingOverlayQuery *query ) noexcept

wasm源码

移除矢量编辑叠加层。query->expected_generation 不是当前代次时返回 STALE_GENERATION,在 portable/无 Skia 构建中返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: InteractiveRetainedBackend.setOverlays, RenderCoreSession.clearVectorEditingOverlay

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: RetainedSession.state, SessionCache.clearVectorEditingOverlay

TacoRenderStatus taco_render_session_boolean_vector_paths( const TacoRenderSession *session, const char *primary_node_id, size_t primary_node_id_size, const char *secondary_node_id, size_t secondary_node_id_size, const char *result_id_namespace, size_t result_id_namespace_size, const TacoRenderVectorBooleanQuery *query, uint8_t *network_bytes, size_t network_capacity, TacoRenderVectorBooleanResult *result ) noexcept

wasm源码

用一个 TacoRenderVectorBooleanOperation 组合两个不同的路径节点,并把结果以主路径的局部坐标写成一个独立的矢量网络。新组成部分的标识符以 result_id_namespace 开头(1 到 TACO_RENDER_VECTOR_BOOLEAN_MAX_NAMESPACE_BYTES 字节的 UTF-8)。network_capacity 太小时(传 0 可查询),返回 BUFFER_TOO_SMALL,并且只写入 result。节点不存在时返回 NOT_FOUND,任一节点不是路径时返回 INVALID_ARGUMENT,还可能返回 STALE_GENERATION。Portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: InteractiveRetainedBackend.booleanVectorPaths, RenderCoreSession.booleanVectorPaths

实现者: RetainedSession.state, RetainedSession.findNode, RetainedSession.geometry, booleanVectorPaths, encodeVectorNetwork

struct TacoRenderVectorBooleanQuery

源码

对两条保留路径执行一次以渲染器结果为准的布尔运算。输出使用 TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION,位于主路径的局部坐标空间中。该查询从不修改保留状态。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t operation源码
uint64_t expected_generation源码
uint32_t[2] reserved源码

struct TacoRenderVectorBooleanResult

源码

在 OK 和 BUFFER_TOO_SMALL 时,此结果会被写入,其中包含独立矢量网络所需的精确字节数。载荷缓冲区只在 OK 时、且能完整容纳之后才会写入。其他失败不会改动这两个输出。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t network_byte_count源码
uint64_t generation源码

TacoRenderStatus taco_render_session_outline_stroke( const TacoRenderSession *session, const char *node_id, size_t node_id_size, const char *result_id_namespace, size_t result_id_namespace_size, const TacoRenderStrokeOutlineQuery *query, uint8_t *network_bytes, size_t network_capacity, TacoRenderStrokeOutlineResult *result ) noexcept

wasm源码

Writes one stroke of a path or container node as a standalone vector network of the area the stroke paints, in the node’s local coordinates: closed loops grouped into even-odd regions, a ring being one region with a hole and each dash a region of its own. The geometry comes from the code that paints the stroke, so it follows the stroke’s width, position (inside, center, outside), join, miter limit, dashes and dash ends, per-side weights, rounded and smoothed corners, and a path’s end shapes. Offset curves lie within 1/32 of a local unit of the exact ones, and circle arcs become cubics within 0.01 of a local unit. The regions carry no fills. A stroke that paints nothing (no width, or a path without segments) gives a network without components.

New component identifiers start with result_id_namespace (1 to TACO_RENDER_STROKE_OUTLINE_MAX_NAMESPACE_BYTES of UTF-8). With too small a network_capacity (pass 0 to ask) it returns BUFFER_TOO_SMALL and writes only result. Returns NOT_FOUND for a missing node, INVALID_ARGUMENT for a text or media node or a stroke index past the node’s strokes, INVALID_SCENE when the stroke cannot be prepared or Skia PathOps cannot resolve its outline, LIMIT_EXCEEDED when the outline is too large for a network, and STALE_GENERATION. Portable/no-Skia builds return CAPABILITY_UNAVAILABLE. Since no capability flag announces it, a caller of an older library must check that the symbol exists.

由 TS 调用: InteractiveRetainedBackend.outlineCompiledStrokes, PortableWasmRenderCoreSession.outlineStroke

由 TS 调用,经由 PortableWasmRenderCoreSession.outlineStroke: outlineStrokesInThrowawaySession

实现者: RetainedSession.state, RetainedSession.findNode, outlineNodeStroke, encodeVectorNetwork

struct TacoRenderStrokeOutlineQuery

源码

Asks for one stroke of a retained path or container as the filled shape it paints. stroke_index counts the node’s strokes in paint order, hidden ones included. The query never mutates retained state.

A call whose buffer is too small (the sizing call) keeps the outline it made, and the next call for the same node, stroke, namespace and generation is answered from it, so the path is stroked and resolved once for the two calls. Any other outline query drops what was kept. Ask for the bytes right after sizing: a font or image that arrives between the two calls without a new generation is not seen by the second.

TypeScript: RenderStrokeOutlineRequest

uint32_t struct_size源码
uint32_t stroke_index源码
uint64_t expected_generation源码
uint32_t[2] reserved源码

struct TacoRenderStrokeOutlineResult

源码

Written as TacoRenderVectorBooleanResult is: on OK and BUFFER_TOO_SMALL with the exact standalone network byte requirement; other failures leave both outputs untouched.

TypeScript: RenderStrokeOutlineSnapshot

uint32_t struct_size源码
uint32_t network_byte_count源码
uint64_t generation源码

选区框、控制柄与画布叠加层

绘制在场景之上但从不属于场景的编辑器图形:选区轮廓和控制柄,以及吸附线、参考线、测量和像素网格。两者都接收一种小型二进制格式,并在绘制时根据节点解析。画布叠加层格式 2 到 4 依次加入画框标题、标尺,以及自动布局间距控制柄的框、控制柄和胶囊标签;它们的文字使用 taco_render_session_set_canvas_overlay_font 设置的字体绘制。

TacoRenderStatus taco_render_session_set_selection_chrome( TacoRenderSession *session, const uint8_t *bytes, size_t size ) noexcept

wasm源码

译文已过期

Replaces the selection outlines and transform handles painted over the scene; size 0 clears them. They resolve against retained nodes at paint time, so they share a frame with the pixels they describe. Items naming a missing node are skipped, which lets the chrome outlive scene updates.

Little-endian bytes: u32 version (3 since wire version 20), u32 count, f32 device pixel ratio. Then per item: u32 kind (0 outline of a rect, 1 square handle, 2 round handle), u32 flags (1 hover, 2 dashed), u32 stroke RGBA, u32 fill RGBA (handles only), f64 x, y, width, height, f64 scene offset x, y, six f64 of a matrix, f64 angle, u32 node id size, node id bytes. x and y map through the item’s matrix, then (since wire version 21) through the named node’s transform; with an empty node id the matrix is local-to-scene, so identity makes them scene coordinates. A multi-selection box is anchored to a selected node this way, so it moves with the node. An outline is the rect (x, y, width, height) through its node’s transform, so a rotated node gets a rotated outline, and its angle is 0. A handle is finished by the editor, which also hit-tests it: (x, y) is its centre, width and height its size on screen in CSS pixels (width along the turned x direction) and angle its turn in radians, clockwise on screen. The renderer rounds the size to whole device pixels and keeps a handle at a whole number of quarter turns on whole device pixels.

Limits: at most 4096 items, a pixel ratio in (0, 16], handle sides in (0, 64] CSS pixels and node ids of at most 1024 bytes. Bytes that break these rules, are truncated or have bytes left over return INVALID_ARGUMENT and keep the old chrome. Portable/no-Skia builds return CAPABILITY_UNAVAILABLE.

由 TS 调用: encodeSelectionChrome, InteractiveRetainedBackend.setOverlays, RenderSelectionChrome, RenderCoreSession.setSelectionChrome

由 TS 调用,经由 encodeSelectionChrome: RenderCoreSession.setSelectionChrome

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: SessionCache.setSelectionChrome

TacoRenderStatus taco_render_session_set_canvas_overlay( TacoRenderSession *session, const uint8_t *bytes, size_t size ) noexcept

wasm源码

替换编辑器绘制在场景之上的叠加线:吸附线和对齐线及其 x 标记、标尺参考线、option 拖动时的轮廓和测量值,以及像素网格。大小为 0 时清除它们。它们从不属于文档内容,从不导出,也从不改变保留场景,因此更新它们无需对场景重新编码。网格绘制在选区框与控制柄之下,每条线和每个标记都绘制在其之上。

每条直线都是整设备像素的填充,宽度为 max(1, round(dpr)),与选区轮廓一样用 std::round 取整:side 0(之后)覆盖 [round(p), round(p) + w),side 1(之前)覆盖 [round(p) - w, round(p)),side 2(居中)从 round(p - w / 2) 开始。线的两端分别取整为 round(start) 和 round(end)。x 标记以其两条交叉线所覆盖像素的中点为中心,并使用抗锯齿绘制。

小端序字节,版本 1 到 3:u32 version,f32 设备像素比,u32 锚点数量,然后每个锚点依次为 u32 节点 id 大小(1 到 1024)和 id 字节。接着是 u32 grid(0 或 1);有网格时:u32 锚点索引,u32 RGBA,f64 原点 x、y,f64 步长。接着是 u32 线条数量,u32 标记数量。每条线(56 字节):u32 axis(0 垂直,1 水平),u32 side,u32 flags(1 横跨整个目标,2 场景坐标,4 横跨锚点自身的框、从 0 到其宽度或高度,忽略 start 和 end),u32 RGBA,u32 锚点索引,u32 zero,f64 position,f64 start,f64 end,f32 dash 和 f32 gap(单位为 CSS 像素,实线时两者均为 0)。每个标记(40 字节):u32 RGBA,u32 sides(x 方向的 side 在位 0-1,y 方向的 side 在位 2-3),u32 flags(2 场景坐标),u32 锚点索引,f32 半尺寸(单位为 CSS 像素),u32 zero,f64 x,f64 y。

每项的坐标是相对其锚点节点的局部坐标,在绘制时经该节点的世界变换映射,因此在平移、移动或调整大小预览中,这些项与节点的像素在同一帧中跟随节点;画框自身的标尺参考线锚定到该画框并横跨其框。锚点必须是轴对齐的。锚点不在场景中的项会被跳过。

版本 2 追加画框标题:u32 标题数量(最多 4096),然后每个标题依次为 u32 锚点索引,u32 RGBA,u32 flags(0),f32 字号和 f32 间距(单位为 CSS 像素),u32 UTF-8 文本大小(1 到 4096)和文本字节。标题是绘制在顶层画框上方的名称。它位于锚点设备空间包围盒的左上角,其行框(高度等于字号)的底部在该包围盒上方 gap 个 CSS 像素处,超出包围盒宽度的部分以省略号截断;连省略号都放不下的标题不绘制。标题使用 taco_render_session_set_canvas_overlay_font 设置的字体,逐字符回退到文档中已解码的字体,在设置该字体之前不绘制。

版本 3 追加标尺:u32 flag(0 或 1);有标尺时:u32 锚点索引,u32 flags(0),f32 粗细(1 到 256)、f32 字号(1 到 256)和 f32 主刻度最小间距(1 到 4096),单位均为 CSS 像素,然后是背景、边框、刻度和数字、选区范围以及选区数值的 u32 RGBA。接着先 x(顶部标尺)后 y(左侧标尺),各为 u32 范围数量(最多 65536),然后每个范围为以锚点单位表示的 f64 起点和终点,已排序且互不相接(长度为零的范围标记单个数值)。接着是 u32 标签数量(最多 16),然后每个标签依次为 u32 axis(0 为 x,1 为 y),u32 背景 RGBA,u32 文字 RGBA,u32 保留(0),以锚点单位表示的 f64 位置:参考线的位置,以圆角标签的形式绘制在其标尺上。标尺在绘制这一帧时根据锚点的世界变换布置(主刻度步长按 1-2-5 选取,间距不小于最小间距,每个步长五个次刻度),因此它们在同一帧中随页面移动。它们绘制在其他所有内容之上,数字使用 taco_render_session_set_canvas_overlay_font 设置的字体(设置之前不绘制数字)。锚点缺失或旋转时标尺留空。

版本 4 追加框、控制柄和胶囊标签,用于自动布局的间距控制柄。它们的坐标是相对其锚点的局部坐标,经锚点完整的世界变换映射,因此与线条不同,它们也会跟随旋转的锚点。u32 框数量(最多 4096),然后每个框(56 字节)依次为 u32 锚点索引,u32 flags(1 填充,2 斜线填充,4 轮廓),u32 填充 RGBA,u32 斜线 RGBA,u32 轮廓 RGBA,u32 保留(0),f64 x、y、宽度和高度(尺寸为零或更大)。斜线填充是每隔 4 个 CSS 像素一条、宽一个 CSS 像素的对角条纹,裁剪到框内;轮廓位于框内一个 CSS 像素处。接着是 u32 控制柄数量(最多 4096),然后每个控制柄(40 字节)依次为 u32 锚点索引,u32 axis(0 沿锚点局部 x 轴,1 沿其局部 y 轴),u32 RGBA,u32 边框 RGBA,以 CSS 像素为单位的 f32 长度 (0 到 64] 和 f32 粗细 (0 到 16],其中心的 f64 x 和 y:一条两端为圆头、带一个 CSS 像素边框的刻度线。接着是 u32 胶囊标签数量(最多 16),然后每个标签依次为 u32 锚点索引,u32 背景 RGBA,u32 文字 RGBA,u32 保留(0),f64 x 和 y,以 CSS 像素为单位到标签左上角的 f32 x 和 y 偏移,f32 字号(1 到 64),u32 UTF-8 文本大小(1 到 256)和文本字节:一个使用叠加层字体、带一行文字的圆角胶囊标签(设置该字体之前不绘制)。框绘制在选区轮廓之上,控制柄在框之上,胶囊标签在控制柄之上,它们都位于画框标题和标尺之下。

不符合此布局的字节返回 INVALID_ARGUMENT,并保留原有叠加层。portable/no-Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: encodeCanvasOverlay, InteractiveRetainedBackend.setOverlays, RenderCoreSession.setCanvasOverlay

由 TS 调用,经由 encodeCanvasOverlay: RenderCoreSession.setCanvasOverlay

由 TS 调用,经由 InteractiveRetainedBackend.setOverlays: InteractiveRenderSession.setOverlays, InteractiveRenderSessionCoordinator.setOverlays

实现者: SessionCache.setCanvasOverlay

TacoRenderStatus taco_render_session_set_canvas_overlay_font( TacoRenderSession *session, const uint8_t *bytes, size_t size ) noexcept

wasm源码

设置画布叠加层绘制画框标题所用的字体:一个字体文件(TrueType、OpenType 或 WOFF2)的字节,会被复制。大小为 0 时移除字体,之后不再绘制标题。Skia 无法解码的字节返回 INVALID_ARGUMENT 并保留原有字体。portable/no-Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: RenderCoreSession.setCanvasOverlayFont

实现者: SessionCache.setCanvasOverlayFont

字体

读取场景中某个字体的特性和轴,或在任何文本使用之前从字体字节中复制出一张表。

TacoRenderStatus taco_render_session_get_font_metadata( TacoRenderSession *session, const char *font_resource_id, size_t font_resource_id_size, const TacoRenderFontMetadataQuery *query, TacoRenderFontFeature *features, size_t feature_capacity, TacoRenderFontAxis *axes, size_t axis_capacity, TacoRenderFontMetadataResult *result ) noexcept

wasm源码

列出场景中某个字体资源的 OpenType 特性(来自 GSUB 和 GPOS)和可变字体轴。没有该 ID 的字体资源时返回 NOT_FOUND,query->expected_generation 不是当前代次时返回 STALE_GENERATION。大小协商方式与文本查询相同:在 OK 和 BUFFER_TOO_SMALL 时,result 都包含两个计数。Portable/无 Skia 构建返回 CAPABILITY_UNAVAILABLE。

由 TS 调用: InteractiveRetainedBackend.getFontMetadata, RenderCoreSession.getFontMetadata

实现者: SessionCache.getFontMetadata

struct TacoRenderFontMetadataResult

源码

在 OK 和 BUFFER_TOO_SMALL 时,此结果包含精确的记录数量以及所查询的保留场景代次。特性和轴缓冲区仅在 OK 时、且两者都容纳得下之后才会写入。其他任何失败都不会改动任何输出。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t feature_count源码
uint32_t axis_count源码
uint32_t reserved源码
uint64_t generation源码

TacoRenderStatus taco_render_copy_font_table( const uint8_t *font_bytes, size_t font_byte_count, uint32_t table_tag, uint8_t *table_bytes, size_t table_capacity, size_t *table_size ) noexcept

wasm源码

从渲染器可解码的任意格式(TrueType、OpenType/CFF、WOFF 和 WOFF2)的字体字节中复制一张 OpenType 表,例如 ‘cmap’(0x636d6170)。它不需要会话,因此宿主可以在任何文本使用某字体之前读取该字体映射了哪些字符。*table_size 接收该表的字节数;当 table_capacity 更小时(传 0 可查询所需大小),不会复制任何内容,调用返回 BUFFER_TOO_SMALL。字体没有该表时返回 NOT_FOUND,字节不是可解码的字体时返回 INVALID_SCENE,在 Portable/无 Skia 构建中返回 CAPABILITY_UNAVAILABLE。

实现者: copyFontTable

Wasm 桥接

不含 Skia 的可移植 Wasm 构建导出这些函数,而不是 C ABI。它应用批次,并返回场景及其几何信息的 JSON 摘要。WebGPU 构建也会导出这四个版本和能力函数。

uint32_t taco_render_wasm_abi_version() noexcept

wasm源码

返回 TACO_RENDER_ABI_VERSION。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

uint32_t taco_render_wasm_wire_version() noexcept

wasm源码

返回 TACO_RENDER_WIRE_VERSION。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

uint32_t taco_render_wasm_vector_network_wire_version() noexcept

wasm源码

返回 TACO_RENDER_VECTOR_NETWORK_WIRE_VERSION。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

uint32_t taco_render_wasm_portable_capabilities() noexcept

wasm源码

返回能力位:保留场景、结构化路径、带样式文本和嵌入资源(位 0 到 3)。此构建从不绘制。

由 TS 调用,位于这些条目的辅助函数中: PortableWasmRenderCoreModule.constructor, createOwnedWasmRenderCoreSession, attachPortableWasmRenderCoreSession

PortableWasmSession *taco_render_wasm_session_create() noexcept

wasm源码

创建一个空的 portable 会话;分配失败时返回 null。

void taco_render_wasm_session_destroy(PortableWasmSession *session) noexcept

wasm源码

释放一个 portable 会话。允许传入 null。

uint32_t taco_render_wasm_session_apply( PortableWasmSession *session, const uint8_t *batch, size_t batch_size ) noexcept

wasm源码

以全有或全无的方式应用一个批次,并返回 TacoRenderStatus。

const char *taco_render_wasm_session_snapshot( PortableWasmSession *session ) noexcept

wasm源码

返回场景的 JSON 摘要,包括其几何信息和绘制顺序;失败时返回 null。该字符串在下一次调用 snapshot 或 apply 之前一直有效。

const char *taco_render_wasm_session_last_error( const PortableWasmSession *session ) noexcept

wasm源码

返回最近一次的错误消息;成功应用后为空。

保留会话

每个会话背后的 C++ 场景。它解码批次,保存节点和资源,并为查询和绘制计算几何信息。

class taco::render::RetainedSession

源码

C 会话背后的保留场景,不负责绘制。它解码 wire 批次,保存场景及其派生几何信息,并回答几何查询和命中查询。Skia 构建和可移植的 Wasm 构建都使用它。

RetainedSession()源码
ApplyResult apply(std::span<const uint8_t> batch, ApplyTransaction *transaction)源码

应用一个完整的批次。要么全部生效,要么全部不生效:失败时场景、几何信息和代次(generation)都保持不变。至少包含一条命令的批次会使代次加一。使用事务时,在事务提交之前该变更都可以撤销。

由 TS 调用: RenderChangeBatchEncoder

C ABI: taco_render_session_apply

const SceneState &state() const源码

C ABI: taco_render_session_apply, taco_render_session_apply_with_static_image_frames, taco_render_session_apply_with_media_frames, taco_render_session_update_video_frames, taco_render_session_get_scene_info, taco_render_session_get_geometry_snapshot, taco_render_session_hit_test, taco_render_session_map_viewport

另有 9 项taco_render_session_get_text_carets, taco_render_session_get_text_range_rects, taco_render_session_clear_text_editing_overlay, taco_render_session_get_vector_geometry, taco_render_session_hit_test_vector, taco_render_session_set_vector_editing_overlay, taco_render_session_clear_vector_editing_overlay, taco_render_session_boolean_vector_paths, taco_render_session_outline_stroke

const Node *findNode(std::string_view id) const源码

具有该 ID 的节点,或 null。

C ABI: taco_render_session_get_node_info, taco_render_session_get_node_geometry, taco_render_session_get_vector_geometry, taco_render_session_hit_test_vector, taco_render_session_boolean_vector_paths, taco_render_session_outline_stroke

uint64_t digest() const源码

场景内容的哈希值,缓存到下一次应用为止。

C ABI: taco_render_session_get_scene_info

size_t retainedPayloadBytes() const源码
const SessionApplyStats &applyStats() const源码
const ApplyChangeSummary &lastApplyChanges() const源码
bool sceneContainsMedia() const源码
bool hasUnboundedVisibleText() const源码
void resetApplyStats()源码
const SceneGeometry &geometry() const源码

C ABI: taco_render_session_boolean_vector_paths

std::shared_ptr<const SceneGeometry> geometrySnapshot() const源码

C ABI: taco_render_session_get_node_geometry, taco_render_session_get_geometry_snapshot, taco_render_session_get_vector_geometry, taco_render_session_hit_test_vector

const PaintedStrokeCache &paintedStrokes() const源码

What hit tests have kept for path strokes, for tests and measurements.

void setMaximumPaintedStrokeBytes(size_t maximum_bytes)源码

Replaces the limit on what hit tests keep (kMaximumPaintedStrokeBytes). Tests use a small one.

std::vector<HitRecord> hitTest( double world_x, double world_y, double world_tolerance ) const源码

位于场景中某点下方的可见节点,最上层的在前(参见 pointHitsNode)。

C ABI: taco_render_session_hit_test

const DirtyBounds &lastDirtyBounds() const源码

最近一次成功应用所改变的区域。

C ABI: taco_render_session_get_last_dirty_bounds

class taco::render::ApplyTransaction

源码

让一次批量应用保持未决,使调用方可以在保留它之前再检查更多状态。SessionCache.applyWithMediaFrames 用它把帧和场景一起安装,要么都装上,要么都不装。

ApplyTransaction()源码
~ApplyTransaction()源码
void commit() noexcept源码

保留已应用的会话状态。仍处于活动状态的事务在离开作用域时会自动回滚。

void rollback() noexcept源码

struct taco::render::ApplyResult

源码

RetainedSession.apply 的结果:失败时为状态码加错误信息,成功时为命令数和脏区域边界。

TacoRenderStatus status源码
uint32_t commands_applied源码
std::string error源码
DirtyBounds dirty_bounds源码

struct taco::render::SceneState

源码

保留场景本身:尺寸、代次,以及按 ID 索引的节点和资源。

double width源码
double height源码
uint64_t generation源码
std::map<std::string_view, std::shared_ptr<const Node>, std::less<>> nodes源码

键是指向各个不可变值所拥有的 ID 的视图。为事务复制这些映射时,只复制树节点、字符串视图和共享指针;永远不会复制保留的标识符、矢量拓扑、文本或资源数据。

std::map<std::string_view, std::shared_ptr<const Resource>, std::less<>> resources源码

struct taco::render::Node

源码

一个保留节点:它的标识、父节点、层叠顺序、样式,以及对应其类型(路径、文本、容器或媒体)的载荷。

std::string id源码
std::string parent_id源码
int32_t z_order源码
bool visible源码
BlendMode blend_mode源码

wire 版本 10 通过一个隔离图层来合成非 normal 的混合模式,并允许一个节点对其后续的兄弟节点施加蒙版,直到父节点结束或另一个蒙版开始新的范围。隐藏的蒙版不遮挡任何内容。

bool mask源码
bool vertex_corners源码

wire 版本 12 节点标志位 2:路径会追加其顶点圆角表。

bool stroke_caps源码

wire 版本 13 节点标志位 4:路径会追加其两个描边端点样式。

Transform transform源码

仅含变换的 wire 更新会刻意修改这个字段,而不可变的节点标识和载荷仍与绘制缓存共享。

NodeStyle style源码
uint16_t source_wire_version源码
std::variant<PathData, TextData, ContainerData, MediaData> data源码
void setTransform(const Transform &value) const源码
TacoRenderNodeKind kind() const源码

C ABI: taco_render_session_get_node_info

struct taco::render::SceneGeometry

源码

整个场景在某一代次下的派生几何信息。快照不可变且被共享,因此读取方可以在会话继续推进时保留它。

uint64_t generation源码
size_t painter_order_id_bytes源码
std::vector<std::shared_ptr<const Node>> retained_nodes源码

几何标识符是指向保留节点的视图。所有权保存在这里,因此会话更新之后几何结果依然有效。在此快照构建之后,仅含变换的更新可能会修改保留节点的实时变换;要获取这个几何结果所捕获的变换,请使用 ComputedNodeGeometry::world_transform。

std::map<std::string_view, ComputedNodeGeometry, std::less<>> nodes源码
std::vector<std::string_view> painter_order源码
SceneHitIndex hit_index源码
std::map<std::string_view, std::string_view, std::less<>> mask_owners源码

从被蒙版的节点 ID 映射到裁剪它的可见兄弟蒙版。它们是指向保留节点的视图,每次构建几何信息时都会完整重新计算。

struct taco::render::ComputedNodeGeometry

源码

为一个节点推导出的几何信息:局部空间、世界空间和裁剪后可见空间中的边界,世界变换,从后到前的绘制顺序(painter order),以及叠加所有祖先后的不透明度和可见性。

Bounds local_bounds源码
Bounds world_bounds源码
Bounds visible_world_bounds源码
Bounds subtree_visible_bounds源码

译文已过期

Everything this node and its descendants paint, after masks and with this node’s layer blur tail around all of it. The renderer uses this box as it is for the node’s compositing layer and for the area a layer blur repaints, so neither adds the tail a second time.

bool subtree_painted源码

Whether the renderer paints this node or any of its descendants. A subtree can be painted and still show nothing, when a mask inside it hides all of it, so this is not the same as a valid subtree box.

Transform world_transform源码
uint64_t painter_order源码
bool effectively_visible源码
double effective_opacity源码

struct taco::render::DirtyBounds

源码

一次更新在场景空间中改变的区域,分为更新前和更新后。C ABI 会把它复制到 TacoRenderDirtyBounds 中。

Bounds old_bounds源码
Bounds new_bounds源码
Bounds combined_bounds源码
uint64_t generation源码

struct taco::render::HitRecord

源码

RetainedSession.hitTest 命中的一个节点,附带其几何信息。

std::shared_ptr<const Node> node源码
ComputedNodeGeometry geometry源码

Stroke settings the session reads from the wire: end caps, corner joins and dash ends, in Figma’s terms.

enum class taco::render::StrokeCap : uint8_t

源码

wire 版本 13 的描边端点样式,采用 Figma 的术语。没有显式端点样式的路径在两端都保留以往的圆头端点。

TypeScript: RetainedStrokeCap

kNone = 0源码
kRound = 1源码
kSquare = 2源码
kLineArrow = 3源码
kTriangleArrow = 4源码
kReversedTriangle = 5源码
kCircleArrow = 6源码
kDiamondArrow = 7源码

enum class taco::render::StrokeJoin : uint8_t

源码

Wire version 23 stroke joins and dash ends, in Figma’s terms.

TypeScript: RetainedStrokeJoin

kMiter = 0源码
kBevel = 1源码
kRound = 2源码

enum class taco::render::DashCap : uint8_t

源码

TypeScript: RetainedDashCap

kNone = 0源码
kRound = 1源码
kSquare = 2源码

Skia 适配器

SessionCache 保存单个会话的 Skia 状态,其后的函数通过它绘制保留场景。

class taco::render::skia_adapter::SessionCache

源码

为一个保留渲染器会话持有与后端无关的整形资源。其实现刻意只对 Skia 适配器可见,这样文本查询可以复用屏幕上实际绘制的段落,而不必通过共享的 C ABI 暴露 Skia 类型。

每个 C 会话在其 RetainedSession 旁边持有一个该对象。它保存已解码的字体、文本布局和已准备的路径,已安装的图片帧和视频帧,文本和矢量编辑叠加层,选区框与控制柄以及画布叠加层,还有等待下一次增量渲染的脏区域。下面的渲染函数都通过它进行绘制。

SessionCache()
SessionCache(const SessionCache &) = delete
源码
~SessionCache()源码
TacoRenderStatus applyWithStaticImageFrames( RetainedSession *session, std::span<const uint8_t> batch, uint64_t expected_generation, std::span<const StaticImageFrame> frames, ApplyResult *result, std::string *error )源码

通过保留会话上的一个事务进行应用,校验并准备完整的图片集合,然后一步提交会话和缓存。被拒绝的帧集合会让会话自动回滚。

C ABI: taco_render_session_apply_with_static_image_frames

TacoRenderStatus applyWithMediaFrames( RetainedSession *session, std::span<const uint8_t> batch, uint64_t expected_generation, std::span<const MediaFrame> frames, ApplyResult *result, std::string *error )源码

与 applyWithStaticImageFrames 类似,但针对图片帧和视频帧的混合集合,该集合必须与新场景的每个媒体资源一一对应。

C ABI: taco_render_session_apply_with_media_frames

TacoRenderStatus updateVideoFrames( const RetainedSession &session, uint64_t expected_generation, std::span<const MediaFrame> frames, DirtyBounds *dirty_bounds, std::string *error )源码

在不应用批次的情况下替换当前代次的视频帧,并写出像素发生变化的场景区域。需要该代次已通过 applyWithMediaFrames 安装了混合集合。

C ABI: taco_render_session_update_video_frames

uint32_t lastVideoFrameUpdateIndexedAssetCountForTesting() const noexcept源码

最近一次成功视频更新(tick)的原生冒烟测试诊断信息。它们只存在于私有的 C++ 适配器接口上,不扩展公共 ABI。

uint32_t lastVideoFrameUpdateSubmittedFrameCountForTesting() const noexcept源码
uint32_t lastRgbaRollbackAllocationsForTesting() const noexcept源码
TacoRenderStatus getTextCarets( const RetainedSession &session, std::string_view node_id, const TacoRenderTextQuery &query, std::vector<TacoRenderTextCaret> *carets, struct RenderStatistics *statistics, std::string *error )源码

taco_render_session_*text* 系列函数背后的文本查询。每个查询都会检查其期望的代次,对节点进行布局(或复用缓存的布局),并以节点局部坐标给出结果。

构建一个文本节点的所有光标记录。

C ABI: taco_render_session_get_text_carets

TacoRenderStatus getTextCaretCount( const RetainedSession &session, std::string_view node_id, const TacoRenderTextQuery &query, uint32_t *caret_count, struct RenderStatistics *statistics, std::string *error )源码

只统计光标数量而不构建它们,这样 C 函数可以先报告 BUFFER_TOO_SMALL。

C ABI: taco_render_session_get_text_carets

TacoRenderStatus getTextRangeRects( const RetainedSession &session, std::string_view node_id, const TacoRenderTextRangeQuery &query, std::vector<TacoRenderTextRect> *rects, struct RenderStatistics *statistics, std::string *error )源码

构建两个文本位置之间的选区矩形。

C ABI: taco_render_session_get_text_range_rects

TacoRenderStatus hitTestText( const RetainedSession &session, std::string_view node_id, const TacoRenderTextHitQuery &query, TacoRenderTextHitResult *result, struct RenderStatistics *statistics, std::string *error )源码

查找离某个节点局部坐标点最近的光标位置。

C ABI: taco_render_session_hit_test_text

TacoRenderStatus navigateText( const RetainedSession &session, std::string_view node_id, const TacoRenderTextNavigationQuery &query, TacoRenderTextNavigationResult *result, struct RenderStatistics *statistics, std::string *error )源码

按一次导航操作移动文本位置。

C ABI: taco_render_session_navigate_text

TacoRenderStatus getTextLayoutMetrics( const RetainedSession &session, std::string_view node_id, const TacoRenderTextQuery &query, TacoRenderTextLayoutMetrics *metrics, struct RenderStatistics *statistics, std::string *error )源码

报告内容尺寸、建议的画框尺寸和行数。

C ABI: taco_render_session_get_text_layout_metrics

TacoRenderStatus getFontMetadata( const RetainedSession &session, std::string_view font_resource_id, const TacoRenderFontMetadataQuery &query, std::vector<TacoRenderFontFeature> *features, std::vector<TacoRenderFontAxis> *axes, struct RenderStatistics *statistics, std::string *error )源码

列出字体资源的 OpenType 特性和可变字体轴。结果与已解码的字体一起缓存。

C ABI: taco_render_session_get_font_metadata

TacoRenderStatus setTextEditingOverlay( const RetainedSession &session, std::string_view node_id, const TacoRenderTextEditingOverlay &overlay, struct RenderStatistics *statistics, std::string *error )源码

安装绘制在一个文本节点上的选区、输入法组合文本(composition)和光标,替换之前的任何文本叠加层。

C ABI: taco_render_session_set_text_editing_overlay

void clearTextEditingOverlay(const RetainedSession &session) noexcept源码

移除文本编辑叠加层,并把它所在的区域标记为需要重绘。

C ABI: taco_render_session_clear_text_editing_overlay

TacoRenderStatus setVectorEditingOverlay( const RetainedSession &session, std::string_view node_id, const TacoRenderVectorEditingOverlay &overlay, std::span<const uint8_t> network_bytes, std::span<const TacoRenderVectorEditingComponent> components, std::string_view identifier_bytes, struct RenderStatistics *statistics, std::string *error )源码

在一个路径节点上安装正在编辑的矢量网络的预览及其选中的组成部分,替换之前的任何矢量叠加层。

C ABI: taco_render_session_set_vector_editing_overlay

void clearVectorEditingOverlay(const RetainedSession &session) noexcept源码

移除矢量编辑叠加层,并把它所在的区域标记为需要重绘。

C ABI: taco_render_session_clear_vector_editing_overlay

TacoRenderStatus setSelectionChrome( std::span<const uint8_t> bytes, std::string *error )源码

替换绘制在场景之上的选区轮廓和控制柄。空字节会清除它们。指向不存在节点的条目会在绘制时跳过,因此选区框与控制柄无需代次检查即可在场景更新后继续保留。

由 TS 调用: encodeSelectionChrome, RenderSelectionChrome

由 TS 调用,经由 encodeSelectionChrome: RenderCoreSession.setSelectionChrome

C ABI: taco_render_session_set_selection_chrome

TacoRenderStatus setCanvasOverlay( std::span<const uint8_t> bytes, std::string *error )源码

替换绘制在场景之上的编辑器叠加线(吸附线、标尺参考线、按住 Option 拖动时的测量线、像素网格)。空字节会清除它们。

由 TS 调用: encodeCanvasOverlay

由 TS 调用,经由 encodeCanvasOverlay: RenderCoreSession.setCanvasOverlay

C ABI: taco_render_session_set_canvas_overlay

TacoRenderStatus setCanvasOverlayFont( std::span<const uint8_t> bytes, std::string *error )源码

设置画布叠加层中画框标题所用的字体。空字节会移除字体,之后不再绘制标题。

C ABI: taco_render_session_set_canvas_overlay_font

void invalidateStaticImageFrames() noexcept源码

与 invalidateMediaFrames 相同。

void invalidateMediaFrames() noexcept源码

丢弃所有已安装的图片帧和视频帧。在普通的批次应用之后调用,因为这种应用不携带任何帧。

C ABI: taco_render_session_apply

void recordSuccessfulApply( const RetainedSession &session, const DirtyBounds &dirty_bounds, bool generation_changed ) noexcept源码

在一次成功的批次应用之后更新缓存:记录脏区域,丢弃已变化节点的文本布局和路径,在字体资源变化时丢弃字体,并在代次变化时清除两个编辑叠加层。

C ABI: taco_render_session_apply

void recordSceneUpdateTime(double scene_update_ms) noexcept源码

把应用耗时累加到下一份增量帧报告的 scene_update_ms 中。负值或非有限值会被忽略。

C ABI: taco_render_session_apply, taco_render_session_apply_with_static_image_frames, taco_render_session_apply_with_media_frames

struct taco::render::skia_adapter::RenderStatistics

源码
uint32_t nodes_considered源码
uint32_t nodes_painted源码
uint32_t paths_painted源码
uint32_t vector_paths_prepared源码
uint32_t vector_path_cache_hits源码
uint32_t vector_region_tight_bounds_computes源码
uint32_t vector_regions_visited源码
uint32_t vector_regions_painted源码
uint32_t vector_region_fills_painted源码
uint32_t inherited_vector_region_fills_painted源码
uint32_t explicit_vector_region_fills_painted源码
uint32_t vector_region_gradient_fills_painted源码
uint32_t vector_network_strokes_painted源码
uint32_t vector_segments_stroked源码
uint32_t vector_stroke_contours源码
uint32_t authored_paragraphs_painted源码

其节点已被绘制的作者文本段落数。空的作者段落也计入此处,尽管其私有行框文本不会暴露给查询。

uint32_t paragraphs_painted源码

已绘制的整形后 SkParagraph 片段数。列表标记和拆分出的首行缩进会使这个值大于 authored_paragraphs_painted。

uint32_t unresolved_glyphs源码
uint32_t font_collection_cache_hits源码
uint32_t font_collections_built源码
uint32_t fonts_decoded源码
uint32_t decoded_font_cache_hits源码
uint32_t unicode_cache_hits源码
uint32_t unicode_services_built源码
uint32_t text_layout_cache_hits源码
uint32_t text_layout_font_set_rebuilds源码
uint32_t rgba_rollback_allocations源码
uint32_t opacity_layer_unbounded_saves源码
uint32_t ancestor_walk_vector_allocations源码
uint32_t text_paragraph_copies源码
uint32_t text_mapping_validations源码
uint32_t text_layouts_built源码
uint32_t text_layout_cache_invalidations源码
uint32_t paragraphs_built源码
double layout_ms源码
double paint_ms源码

TacoRenderStatus taco::render::skia_adapter::renderRgba( const RetainedSession &session, SessionCache *cache, const TacoRenderRgbaTarget &target, RenderStatistics *statistics, std::string *error )

源码

把保留场景绘制到调用方拥有的预乘 alpha RGBA8888 CPU 缓冲区中。不使用任何平台字体管理器或 GPU 上下文。

C ABI: taco_render_session_render_rgba

TacoRenderStatus taco::render::skia_adapter::renderRgbaIncremental( const RetainedSession &session, SessionCache *cache, const TacoRenderRgbaTarget &target, const TacoRenderIncrementalRenderOptions &options, TacoRenderIncrementalFrameReport *report, std::string *error )

源码

当目标标识、尺寸、行跨度(stride)和场景映射都未改变时,复用调用方拥有的像素,只重绘累积的场景/叠加层脏区域。成功的调用(包括没有可见脏区域的调用)会确认累积的工作,并写入一份精确的帧报告。

C ABI: taco_render_session_render_rgba_incremental

TacoRenderStatus taco::render::skia_adapter::renderCanvas( const RetainedSession &session, SessionCache *cache, SkCanvas *canvas, uint32_t width, uint32_t height, RenderStatistics *statistics, std::string *error )

源码

把保留场景绘制到一个已有的 Skia 画布(canvas)中。由调用方决定该画布基于 CPU 还是 GPU;场景遍历、路径构建、文本整形、裁剪和绘制语义保持共享。

TacoRenderStatus taco::render::skia_adapter::renderCanvasIncremental( const RetainedSession &session, SessionCache *cache, SkCanvas *canvas, uint32_t width, uint32_t height, uintptr_t target_identity, const TacoRenderIncrementalRenderOptions &options, TacoRenderIncrementalFrameReport *report, RenderStatistics *statistics, std::string *error )

源码

复用一个由调用方标识的 SkCanvas 目标,只绘制累积的设备脏区域(damage)。在目标像素被保留期间,目标标识必须保持稳定;改变它会强制完整重绘。如果在此调用之后录制的工作无法成功提交,调用方必须使目标失效。成功的绘制只是处于已准备状态;调用方要在后端提交成功之后再确认它,这样待处理的脏区域和诊断信息才不会丢失。

void taco::render::skia_adapter::acknowledgeIncrementalRenderTarget( const RetainedSession &session, SessionCache *cache, uintptr_t target_identity, uint32_t width, uint32_t height ) noexcept

源码

在后端提交之后,确认一次已准备好的增量画布渲染。

void taco::render::skia_adapter::invalidateIncrementalRenderTarget( SessionCache *cache ) noexcept

源码

让下一次增量画布渲染重绘整个目标。

TacoRenderStatus taco::render::skia_adapter::exportScene( const RetainedSession &session, SessionCache *cache, const TacoRenderExportRequest &request, std::vector<uint8_t> *bytes, TacoRenderExportResult *result, std::string *error )

源码

通过共享的绘制器把场景中的一个区域绘制到光栅、SVG 或 PDF 目标中,并返回编码后的字节。编辑用的叠加层永远不会被导出,背景保持透明,非空的根节点只保留该节点的子树。构建版本无法编码的格式返回“能力不可用”(capability-unavailable)。

C ABI: taco_render_session_export

TacoRenderStatus taco::render::skia_adapter::copyFontTable( std::span<const uint8_t> font_bytes, uint32_t table_tag, std::span<uint8_t> out, size_t *table_size )

源码

解码字体字节(TrueType、OpenType/CFF、WOFF 或 WOFF2),并把其中一张 OpenType 表复制到 out 中。状态码见 taco_render_copy_font_table。

C ABI: taco_render_copy_font_table

TacoRenderStatus taco::render::skia_adapter::preflightInstalledMediaFrames( const RetainedSession &session, const SessionCache *cache ) noexcept

源码

校验精确的保留媒体帧集合,不分配内存、不绘制、不录制 Graphite 命令,也不修改缓存或目标状态。WebGPU 在启用错误作用域或进入录制器清理路径之前调用它。

TacoRenderStatus taco::render::skia_adapter::buildVectorRegionPaths( const PathData &network, std::vector<SkPath> *region_paths, std::string *error )

源码

为每个规范化的 VectorRegion 构建一个 SkPath。区域的绘制属性被忽略,而每个作者绘制的环路都使用与保留场景绘制相同的拓扑转换。不属于任何区域的边刻意不参与。

VectorBooleanResult taco::render::skia_path_ops::booleanVectorPaths( const PathData &primary, const Transform &primary_world, const PathData &secondary, const Transform &secondary_world, TacoRenderVectorBooleanOperation operation, std::string_view result_id_namespace )

源码

Applies pinned Skia PathOps to canonical VectorRegion geometry. The result is expressed in primary-local coordinates and owns deterministic IDs under result_id_namespace. Region paint and edges outside regions do not contribute.

C ABI: taco_render_session_boolean_vector_paths

struct taco::render::skia_path_ops::VectorBooleanResult

源码
TacoRenderStatus status源码
PathData network源码
std::string error源码

TacoRenderStatus taco::render::skia_adapter::buildNodeStrokeOutline( const Node &node, size_t stroke_index, SkPath *outline, std::string *error )

源码

Builds the area one stroke of a path or container covers, in the node’s local coordinates, as the non-overlapping closed contours Skia PathOps returns (even-odd). stroke_index counts the node’s strokes in paint order, hidden ones included. The geometry comes from the code painting uses: the stroke’s width, position, join, miter limit, dashes and dash ends, per-side weights, rounded and smoothed corners, and a path’s end shapes. Offset curves are within 1/32 of a local unit of the exact ones; a stroke painted from a prepared outline (a path with end shapes) returns that outline. A stroke that paints nothing (no width, or no segments) leaves outline empty. Returns INVALID_ARGUMENT for a text or media node or an index past the strokes, and INVALID_SCENE when the stroke cannot be prepared or PathOps cannot resolve it.

VectorNetworkResult taco::render::skia_path_ops::vectorNetworkFromPath( const SkPath &path, std::string_view id_namespace )

源码

Converts a filled Skia path into a vector network: the one conversion from a Skia path to the editable model, for stroke outlines now and for any later command that ends in a PathOps result (flatten, Boolean groups).

path must hold the non-overlapping closed contours Skia PathOps (Op, Simplify) returns, filled even-odd; run Simplify first on any other path. Each contour becomes one closed loop of vertices and segments:

  • lines stay lines and cubics stay cubics;
  • a quadratic becomes the cubic that draws the same curve exactly;
  • a conic of weight below one (a circle or ellipse arc) becomes the

fewest cubics within 0.01 of a path unit of it (one for a quarter circle of radius up to about 36), and a conic of weight above one becomes thirty-two quadratics.

Loops are grouped into even-odd regions by nesting: a contour inside an even number of others bounds its own region, and one inside an odd number is a hole in the region right around it. A ring is one region with two loops; separate pieces (the dashes of a stroke) are separate regions. Regions carry no fills, so they take the node’s. Identifiers start with id_namespace (ns:v0, ns:s0, ns:s0:start, ns:r0) and the order of contours is deterministic. An empty path gives an empty network.

Grouping compares every contour with every other, so a path of more than kMaximumOutlineContours contours is refused with TACO_RENDER_STATUS_LIMIT_EXCEEDED before any comparison, and so is one whose nesting would walk more than kMaximumOutlineContainmentSegments segments. A path that would become more segments than maximumOutlineNetworkSegments allows for the length of id_namespace is refused the same way, counted from its verbs before any arc is cut into cubics and before anything of the network is built.

VectorNetworkResult taco::render::skia_path_ops::outlineNodeStroke( const Node &node, size_t stroke_index, std::string_view result_id_namespace )

源码

One stroke of a retained path or container as a vector network of the area it paints, in the node’s local coordinates: buildNodeStrokeOutline followed by vectorNetworkFromPath. A stroke that paints nothing gives an empty network.

C ABI: taco_render_session_outline_stroke

struct taco::render::skia_path_ops::VectorNetworkResult

源码
TacoRenderStatus status源码
PathData network源码
std::string error源码

Wire 读取器与几何辅助函数

有边界检查的 wire 字节读取,以及会话和查询共用的几何函数。

class taco::render::WireReader

源码

带边界检查地从字节区间(byte span)读取小端序值。读取越过末尾时返回 false,并记录 MALFORMED_BATCH 及一条消息;status() 和 error() 保留第一次失败。批次解码器和叠加层解析器都使用它。

TypeScript: RenderChangeBatchEncoder

WireReader(std::span<const uint8_t> bytes)源码
size_t remaining() const源码
size_t offset() const源码
bool atEnd() const源码
TacoRenderStatus status() const源码
const std::string &error() const源码
bool readU8(uint8_t *value)源码
bool readU16(uint16_t *value)源码
bool readU32(uint32_t *value)源码
bool readI32(int32_t *value)源码
bool readU64(uint64_t *value)源码
bool readF32(float *value)源码
bool readF64(double *value)源码
bool readBytes(size_t count, std::span<const uint8_t> *value)源码
bool readString(size_t maximum_bytes, bool allow_empty, std::string *value)源码
bool readReservedZero(size_t count)源码
bool readSubreader(size_t count, WireReader *value)源码
bool requireCountFits( uint64_t count, size_t minimum_item_bytes, const char *context )源码
bool requireEnd(const char *context)源码
bool fail(TacoRenderStatus status, std::string message)源码

bool taco::render::isValidUtf8(std::span<const uint8_t> bytes)

源码

C ABI: taco_render_session_apply_with_static_image_frames

SceneGeometry taco::render::computeSceneGeometry( const SceneState &state, GeometryBuildStats *stats )

源码

从头计算每个节点的几何信息:世界变换、边界、裁剪、绘制顺序、蒙版和命中索引。

SceneGeometry taco::render::computeIncrementalSceneGeometry( const SceneState &state, const SceneGeometry &previous, const std::set<std::string, std::less<>> &changed_ids, const ChildMap &children, GeometryBuildStats *stats, SceneGeometry *reusable_previous )

源码

与 computeSceneGeometry 类似,但只重新计算发生变化的节点,其余部分复用 previous 中的结果。

bool taco::render::pointHitsNode( const SceneState &state, const SceneGeometry &geometry, std::string_view node_id, double world_x, double world_y, double world_tolerance, HitTestStats *stats, PaintedStrokeCache *painted_strokes )

源码

译文已过期

Whether a scene point hits a visible node, after ancestor clips: a path within world_tolerance of its fill or stroke, the box of a text or media node, or a container that has a fill or stroke.

A point outside the node’s visible bounds, which include its stroke, is a miss before anything is built from the path. With painted_strokes, the rounded path and the stroke contours a path’s miter joins and square ends are read from are kept there and built once for a node; without it they are built for this call alone.

TacoRenderStatus taco::render::queryVectorGeometry( const PathData &path, const ComputedNodeGeometry &geometry, const Transform &document_to_screen, VectorGeometryQueryResult *result )

源码

为 taco_render_session_get_vector_geometry 构建记录。

C ABI: taco_render_session_get_vector_geometry

TacoRenderStatus taco::render::hitTestVectorComponents( const SceneState &state, const SceneGeometry &geometry, const Node &node, const Transform &document_to_screen, double screen_x, double screen_y, double tolerance_css_px, VectorHitQueryResult *result )

源码

为 taco_render_session_hit_test_vector 构建记录。

C ABI: taco_render_session_hit_test_vector

EncodeVectorNetworkResult taco::render::encodeVectorNetwork( const PathData &network, size_t maximum_bytes )

源码

在给定的上限内编码一个精确的独立 wire-v4 VectorNetwork。

由 TS 调用: decodeVectorNetworkRecord

由 TS 调用,经由 decodeVectorNetworkRecord: PortableWasmRenderCoreSession.outlineStroke, RenderCoreSession.booleanVectorPaths

C ABI: taco_render_session_boolean_vector_paths, taco_render_session_outline_stroke

DecodeVectorNetworkResult taco::render::decodeVectorNetwork( std::span<const uint8_t> bytes, uint16_t wire_version )

源码

解码一个精确的独立 wire-v4 VectorNetwork,不修改任何会话。

由 TS 调用: encodeVectorNetworkRecord

由 TS 调用,经由 encodeVectorNetworkRecord: decodeVectorNetworkRecord, RenderCoreSession.setVectorEditingOverlay

其他导出

尚未归入上述章节的条目,按字母顺序排列。

bool taco::render::anyRoundedVertex(const PathData &path)

源码

Whether any vertex of path has a corner radius.

struct taco::render::ApplyChangeSummary

源码
bool all_nodes源码
bool resources_changed源码
std::set<std::string, std::less<>> node_ids源码

enum class taco::render::BlendMode : uint8_t

源码

wire 版本 10 的混合模式,按 CSS mix-blend-mode 的顺序排列。节点从 wire 版本 10 起带有混合模式,paint 从 wire 版本 19 起带有混合模式。

TypeScript: RetainedBlendMode

kNormal = 0源码
kDarken = 1源码
kMultiply = 2源码
kColorBurn = 3源码
kLighten = 4源码
kScreen = 5源码
kColorDodge = 6源码
kOverlay = 7源码
kSoftLight = 8源码
kHardLight = 9源码
kDifference = 10源码
kExclusion = 11源码
kHue = 12源码
kSaturation = 13源码
kColor = 14源码
kLuminosity = 15源码

struct taco::render::Bounds

源码
bool valid源码
double min_x源码
double min_y源码
double max_x源码
double max_y源码

bool taco::render::branchJoinPair( const std::vector<double> &angles, size_t *first, size_t *second )

源码

Which two of the segment ends that meet at a vertex a solid stroke joins when three or more meet there: the two neighbours, going round the vertex, that leave more than half a turn open between them. Every other pair of neighbours overlaps on the inside of its corner, so that open side is the only place a join is missing. angles holds the direction each end leaves the vertex in, in radians as std::atan2 gives them; first and second receive the two ends’ places in it. False when no two ends are joined: fewer than three ends, or no side that open. buildStrokeContours joins the two this chooses; the renderer paints those contours and the hit test reads its joins from them. It passes only the ends that have a direction (segmentEndDirection).

ChildMap taco::render::buildChildMap( const SceneState &state, bool sort_siblings )

源码

bool taco::render::buildStrokeContours( const PathData &path, bool joins_open_runs, StrokeContourOrder order, std::vector<StrokeContour> *contours, std::string *error )

源码

Fills contours with the contours a stroke of path is painted along, in the order the renderer adds them to its path. path is the path as painted, with its rounded corners worked in (roundPathVertices).

Region loops come first, in both orders. A loop none of whose segments an earlier loop used is one contour in loop order, closed unless the loop is stored open. Otherwise each run of its segments that no earlier loop used is a contour. Then come the segments outside every loop, as order says; joins_open_runs is strokesJoinOpenRuns for the path’s style.

This is the only place that decides which segment ends a stroke joins: the renderer builds its stroke paths from these contours and the hit test reads each join from them, so a join’s miter point is hit exactly where the stroke is painted with a join, and a square end exactly where a contour stops. False, with error set, when the path cannot be stroked: a loop that is empty or not connected, a missing segment or vertex, or a segment that would be painted twice or not at all.

typedef std::map<std::string_view, std::vector<const Node *>, std::less<>> taco::render::ChildMap

源码

struct taco::render::Color

源码
float red源码
float green源码
float blue源码
float alpha源码

struct taco::render::ContainerData

源码
double width源码
double height源码
bool clip源码
std::array<double, 4> corner_radii源码

wire 版本 11 标记带圆角的容器,并追加一个圆角半径和 0..1 范围内 Figma 风格的圆角平滑;wire 版本 14 可以改为追加四个半径。半径按左上、右上、右下、左下的顺序排列,使用时各自被限制在较短边的一半以内。半径为零表示直角。

double corner_smoothing源码
bool rounded() const源码
bool uniformCorners() const源码
void setUniformCornerRadius(double radius)源码
double effectiveCornerRadius(size_t corner) const源码

某个角实际使用的半径:超过较短边一半的半径会被截断。

struct taco::render::DecodeVectorNetworkResult

源码
TacoRenderStatus status源码
PathData network源码
std::string error源码

struct taco::render::DrawnPoint

源码

One point of a path as the renderer draws it.

float x源码
float y源码

struct taco::render::DrawnSegment

源码

One segment as the renderer draws it. The renderer builds its path from exactly these points, in this order or backwards when a contour runs through the segment from its end, and the hit test builds a join and a square end at the segment’s ends from the same points: at the end as drawn, along the direction the drawn segment leaves it in. So the two cannot work from different numbers there, and a segment is the same shape whichever way a contour runs through it. The rest of the hit test reads the stored numbers; prepareDrawnSegment says how far apart the two are.

Shape shape源码
std::array<DrawnPoint, 9> points源码

From the segment’s start to its end: a line’s two ends; a cubic’s start, two control points and end; an arc’s start, then a control point and an end for each of its one to four pieces.

size_t point_count源码
float arc_piece_weight源码

Each piece of an arc is a conic: a curve from one point to the next that bends toward a control point between them, by an amount this weight sets. Unlike a cubic, a conic can follow an ellipse exactly.

enum class taco::render::DrawnSegment::Shape : uint8_t

源码
kLine源码
kCubic源码
kArcPieces源码

enum class taco::render::DrawnSegmentProblem : uint8_t

源码

Why a segment cannot be drawn.

kNone源码
kVertexOutOfRange源码

A number is not finite or is too large for single precision:

kControlPointOutOfRange源码

A number is not finite or is too large for single precision:

kArcOutOfRange源码

A number is not finite or is too large for single precision:

kUnsupportedKind源码

A number is not finite or is too large for single precision:

struct taco::render::EncodeVectorNetworkResult

源码
TacoRenderStatus status源码
std::vector<uint8_t> bytes源码
std::string error源码

struct taco::render::FontVariation

源码
std::array<char, 4> tag源码
double value源码

void taco::render::forEachImageAssetReference( const Node &node, const std::function<void (std::string_view)> &visit )

源码

访问该节点引用的每个图片绘制资源 ID(包括媒体节点);每出现一次引用,visit 就会收到一次对应的 ID。

struct taco::render::GeometryBuildStats

源码
uint64_t nodes_computed源码
uint64_t path_bounds_index_builds源码
std::vector<std::string_view> computed_node_ids源码

struct taco::render::GradientStop

源码
double offset源码
Color color源码

struct taco::render::HitTestStats

源码
uint64_t path_index_builds源码
uint64_t segment_flatten_calls源码
uint64_t clip_parent_string_copies源码
uint64_t rounded_path_builds源码

Calls of roundPathVertices and of buildStrokeContours.

uint64_t stroke_contour_builds源码

bool taco::render::isUtf8Boundary(std::string_view text, size_t offset)

源码

uint64_t taco::render::maximumOutlineNetworkSegments(size_t namespace_bytes)

源码

The most segments a stroke outline’s network may have when its identifiers start with a namespace of namespace_bytes bytes.

double taco::render::maximumTransformScale(const Transform &transform)

源码

struct taco::render::MediaCrop

源码
double x源码
double y源码
double width源码
double height源码

struct taco::render::MediaData

源码
MediaKind kind源码
MediaFit fit源码
bool has_crop源码
double width源码
double height源码
std::string asset_id源码
MediaCrop crop源码

enum class taco::render::MediaFit : uint8_t

源码

TypeScript: RetainedImagePaintFit

kContain = 0源码
kCover = 1源码
kFill = 2源码

typedef StaticImageFrame taco::render::skia_adapter::MediaFrame

源码

typedef StaticImageFrameDisposition taco::render::skia_adapter::MediaFrameDisposition

源码

混合媒体 ABI 刻意保留静态图片的物理记录。

enum class taco::render::MediaKind : uint8_t

源码
kImage = 1源码
kVideo = 2源码

bool taco::render::nodeReferencesImageAsset(const Node &node)

源码

当节点的任一填充、描边绘制或显式的矢量区域填充是图片绘制时为 true,此时该节点需要一帧已解码的图片。

struct taco::render::NodeStyle

源码
double opacity源码
bool has_fill源码
Color fill源码
std::vector<RetainedPaint> fills源码
std::vector<RetainedStroke> strokes源码

在填充之后绘制的有序描边,第一项位于最底层。第一项使用紧凑的通用节点记录;wire 版本 7 把其余描边追加到外观尾部。

std::vector<RetainedShadow> shadows源码
double layer_blur源码

wire 版本 9 追加高斯模糊半径:图层模糊作为一个隔离图层作用于该节点及其后代,背景模糊作用于节点形状后方已经绘制的内容。零表示无模糊。

double background_blur源码
bool hasStroke() const源码
bool hasDropShadow() const源码
bool hasInnerShadow() const源码
double maximumStrokeWidth() const源码

作者设置的最大描边宽度;没有描边时为零。

C ABI: taco_render_session_get_node_info

struct taco::render::OpenTypeFeature

源码
std::array<char, 4> tag源码
uint32_t value源码

class taco::render::PaintedStrokeCache

源码

What hit tests keep for each path node whose stroke has miter joins or square ends: the path as painted, with its rounded corners worked in (roundPathVertices), and the contours its strokes are painted along (buildStrokeContours). Working these out visits every vertex and segment of the path, so it is done once for a node and not on every pointer move.

Both are read from the node’s path and style alone. A retained Node never changes either (an update that changes them puts a new Node in the scene; an update of the transform alone keeps the same one), so what is kept belongs to one Node object and is used only for that object. Each entry holds its node, which keeps the object and the segments its contours point at alive.

What is kept has a size limit in bytes. Each entry is measured after the hit test that built it or added to it, by the capacity of what it holds. When the entries together would pass the limit, the ones used longest ago are dropped first. An entry that is larger than the limit on its own is not kept: the hit test that built it uses it once, and the next hit test on that node builds it again.

PaintedStrokeCache(size_t maximum_bytes)源码
~PaintedStrokeCache()源码
Entry &entryFor(const std::shared_ptr<const Node> &node)源码

The entry for node, empty when nothing is kept for this object yet, and now the most recently used one. An entry kept for another object with the same ID is dropped first. The entry stays in place until settle is called for it or for another entry.

void settle(Entry *entry)源码

Call once a hit test has built something into entry and no longer reads it. Measures the entry, then drops the entries used longest ago until all of them fit the limit, or entry itself when it alone is larger than the limit.

void dropUnless(std::string_view id, const Node *current)源码

Drops the entry for the node with this ID unless it was built from current, the object now in the scene (null when the node is gone).

void clear()源码
void setMaximumBytes(size_t maximum_bytes)源码

Changes the limit and drops the entries used longest ago until the rest fit it.

size_t maximumBytes() const源码
size_t size() const源码
bool holds(std::string_view id) const源码
size_t bytes() const源码

The size of all entries, as added up when each was last settled.

size_t measuredBytes() const源码

The same size, found by measuring every entry again. Tests compare the two.

enum class taco::render::PaintKind : uint8_t

源码

TypeScript: RetainedPaintRecord

kSolid = 1源码
kLinearGradient = 2源码
kRadialGradient = 3源码

wire 版本 8 新增下面三种类型。

kAngularGradient = 4源码

wire 版本 8 新增下面三种类型。

kImage = 5源码

wire 版本 8 新增下面三种类型。

struct taco::render::PathData

源码
std::vector<VectorVertex> vertices源码
std::vector<VectorSegment> segments源码
std::vector<VectorTangentConstraint> constraints源码
std::vector<VectorRegion> regions源码
bool explicit_stroke_caps源码

wire 版本 13:显式端点样式作用于第一条作者绘制线段的起始顶点和最后一条线段的结束顶点,二者都是开放链的端点。没有显式端点样式时,每个描边端点都是圆头,与之前一致。

StrokeCap start_cap源码
StrokeCap end_cap源码
std::unique_ptr<std::pmr::monotonic_buffer_resource> identifier_arena源码

标识符字节从一个单调增长的内存池(arena)中分配,因此解码路径时不会为每个不同的 wire 标识符各做一次堆分配。该内存池单独持有,因为当 PathData 被移动到保留的 Node 中时,string_views 必须仍然有效。

std::unique_ptr<std::pmr::unsynchronized_pool_resource> identifier_index_pool源码

查找索引是解码期间的状态。池分配让它的节点不进入通用堆,结束处理(finalization)时会释放它们。

std::unique_ptr<IdentifierIndex> identifier_index源码
uint32_t identifier_reads源码
bool identifier_index_finalized源码
std::string_view internIdentifier(std::string_view value)源码
void finalizeIdentifierInterning()源码
PathData()
PathData(PathData &&) noexcept
PathData(const PathData &other)
源码

DrawnSegmentProblem taco::render::prepareDrawnSegment( const VectorSegment &segment, double start_x, double start_y, double end_x, double end_y, DrawnSegment *drawn )

源码

Fills drawn with segment as the renderer draws it between its own start and end vertices. Everything the renderer changes on the way from the stored numbers to the path happens here:

  • The two vertices and a cubic’s two control points (each a vertex plus

its handle) are rounded to single precision.

  • An arc’s two radii lose their sign and are rounded to single precision,

and its rotation is rounded to single precision as well, in degrees and again in radians. A rotation of millions of degrees ends up at a different angle from the one the stored number means.

  • An arc becomes a straight line when a rounded radius is zero, when its

rounded ends are one point, or when it sweeps less than a millionth of half a turn.

  • Radii too small to reach from one end to the other are scaled up until

the arc is half an ellipse, and large_arc and sweep choose among the four arcs that fit. All of this is worked out in single precision, by the steps Skia’s SkPathBuilder::arcTo takes, so the pieces are the ones that call would make.

  • When an arc’s pieces are a quarter turn each and its radii and end are

whole numbers, the pieces’ points are rounded to whole numbers too, as Skia does to keep a rounded rectangle’s corners exact.

  • Radii so small or so large beside the arc’s length that single precision

cannot work out an angle for it give a straight line. (Skia’s own call would add nothing for these and leave the path a segment short.)

How far the hit test is from this. A join’s miter point and a square end are built from the drawn segment. Everything else in the hit test works from the stored numbers in double precision: the stroke between a segment’s ends, arrow heads, fills, and the bounds, which the editor reads and outside which nothing is hit. Those sit as far from the painted shape as the steps above move it:

  • Single precision numbers of size m are at most m / 2^23 apart, about

m * 1.2e-7. Call that a step. A line’s ends and a cubic’s four points are each drawn within half a step of where they are stored, on each axis.

  • An arc is worked out in single precision from start to finish. Its

points are drawn within about two steps of the stored arc, where m is the larger of its coordinates and its radii.

  • An arc of nearly half a turn is drawn less exactly, because its centre

comes from the square root of a difference that rounding leaves uncertain. Within 15 degrees of half a turn the two steps no longer hold, and an arc of exactly half a turn, which is what an arc with radii too small becomes, was measured up to a 2000th of its radius from the stored arc.

  • The whole-number rounding above moves an arc’s points by up to half a

unit on each axis, whatever the arc’s size, unless the stored arc has them on whole numbers already, as a rounded rectangle’s corner does.

Supported range: the painted stroke and the stroke the hit test covers agree to within 2.5% of the stroke width when, in the path’s own units,

  • coordinates and arc radii are at most 50,000 times the stroke width,
  • an arc’s rotation is within one turn,
  • an arc within 15 degrees of half a turn has radii of at most 25 times

the stroke width, and

  • an arc whose points are rounded to whole numbers has them on whole

numbers as stored. That is on top of the 0.05 of a unit, measured on the page, that the hit test allows itself when it splits a curve into straight pieces. The session test checks the range at its edge. Outside it the two drift apart in proportion. From 2^24 (16,777,216) units on, a step is 2 units or more, so a vertex is drawn up to a unit or more from where it is stored, and a stroke thinner than that can be painted wholly outside the place the hit test looks. Skia also works a stroke’s outline out in single precision, in the path’s own units, so by then the painted stroke is not exactly the stroke of the drawn segments either. docs/render-core/futures.md says what closing this would take.

void taco::render::skia_path_ops::resetVectorPathOpsStats()

源码

struct taco::render::Resource

源码
std::string id源码
ResourceKind kind源码
std::vector<uint8_t> bytes源码

enum class taco::render::ResourceKind : uint8_t

源码

TypeScript: ResourceKind

kFont = 1源码
kImage = 2源码
kBlob = 3源码

struct taco::render::RetainedPaint

源码

TypeScript: RetainedPaintRecord

PaintKind kind源码
BlendMode blend_mode源码

wire 版本 19:kind 之后的字节是该 paint 的混合模式,下一个字节的位 1 隐藏该 paint。隐藏的 paint 在列表中保留其位置但不绘制任何内容;设置了混合模式的 paint 与同一节点上位于其下方的 paint 混合,混合发生在节点自身的 paint 图层内。

bool hidden源码
double opacity源码
Color color源码
double angle源码

线性渐变只使用 angle。径向渐变和角度渐变以形状边界的比例来确定中心;径向渐变额外以比例表示椭圆半径,角度渐变把 angle 复用为起始角度。

double center_x源码
double center_y源码
double radius_x源码
double radius_y源码
std::vector<GradientStop> stops源码
std::string asset_id源码

图片绘制指定一个通过媒体帧集合附加的逻辑资源。

MediaFit image_fit源码
bool isGradient() const源码

struct taco::render::RetainedShadow

源码
bool inner源码

wire 版本 9 在每条记录前加上其类型。内阴影绘制在形状内部、填充之上;投影绘制在节点后方。

double x源码
double y源码
double blur源码
double spread源码
Color color源码

struct taco::render::RetainedStroke

源码
Color color源码
double width源码
StrokePosition position源码
std::vector<double> dash源码
bool has_paint源码

wire 版本 6 可以携带完整的描边绘制。缺失时,以紧凑的 color 为准。第一个之后的每个描边都携带一个。

RetainedPaint paint源码
bool has_sides源码

wire 版本 18 可以为容器的描边按边设置各自的粗细,顺序为上、右、下、左;此时 width 保存其中最大的一个。

std::array<double, 4> sides源码
bool has_style源码

Wire version 23 can set the join, the ends of every dash and the miter limit together. Without them a path strokes with round joins and round dash ends and a container with miter joins (limit 4) and flat dash ends.

StrokeJoin join源码
DashCap dash_cap源码
double miter_limit源码

struct taco::render::RichTextRun

源码
uint32_t start_byte源码
uint32_t end_byte源码
uint32_t style_index源码

struct taco::render::RichTextStyle

源码
std::vector<std::string> font_resource_ids源码
std::string language源码
double font_size源码
double line_height源码
double letter_spacing源码
uint16_t weight源码
bool italic源码
bool underline源码
bool strikethrough源码
Color color源码
std::vector<OpenTypeFeature> open_type_features源码
std::vector<FontVariation> font_variations源码

struct taco::render::RoundedPathData

源码

A path with its rounded corners worked into its segments (roundPathVertices). ids owns the identifiers of the vertices and segments a rounded corner adds.

std::deque<std::string> ids源码
PathData data源码

bool taco::render::roundPathVertices( const PathData &authored, RoundedPathData *out, std::string *error )

源码

Fills out with authored as the renderer paints it. A vertex with a corner radius is rounded when exactly two segment ends meet there, they belong to two different segments, both are lines or cubics with a direction at the vertex, and they are neither in one straight line nor folded back on each other. Each of the two segments is cut short and a corner segment joins the cuts. Every other vertex is left as stored, whatever its radius: the end of a path, a vertex three or more segment ends meet at, a vertex an arc meets, and a vertex whose two ends are one closed curve’s. No vertex of out has a corner radius. This is the only place that decides whether a corner is rounded: the renderer paints out and the hit test reads the stroke’s joins from it (buildStrokeContours), so a join is hit at exactly the vertices that are painted with one. False, with error set, when a segment or region names a missing vertex or segment.

struct taco::render::SceneHitIndex

源码
bool valid源码
Bounds bounds源码
std::array<std::vector<uint32_t>, kCellCount> cells源码
std::vector<uint32_t> unbounded源码

enum class taco::render::SegmentDirection : uint8_t

源码
kForward = 0源码
kReverse = 1源码

bool taco::render::segmentEndDirection( const VectorSegment &segment, double start_x, double start_y, double end_x, double end_y, bool at_start, double *away_x, double *away_y )

源码

The unit direction a segment leaves one of its ends in, pointing from that end into the segment: the direction the stroke has there, which its joins and square ends are built along. start and end are the segment’s own start and end vertices; at_start picks the end. The direction is read from the segment as drawn (prepareDrawnSegment): it points from the end toward the nearest drawn point that is not at the end itself. So a line leaves along itself; a cubic along its handle, however short, or toward its next control point when the handle is too short to move its control point off the vertex in single precision, or along its chord when that is too; and an arc toward the control point of its first or last piece, which lies on the ellipse’s tangent. False when there is no direction to take: when every drawn point is the same, when a line’s two drawn ends are within kDrawnPointTolerance of each other, when the same holds for a cubic that has no bend to draw (at least two of its three steps from one point to the next have no length), and when the segment cannot be drawn at all. The renderer chooses which ends to join from this and the hit test builds the join from it, at the end as drawn, so both call this instead of measuring the curve in their own ways. This only reads the drawn points; what is painted is the drawn segment unchanged.

Skia’s two stroke painters agree with this for a curve that bends. They differ from each other for a cubic whose control points all lie within about 0.3% of its length of one straight line, and for an arc that sweeps less than about half a degree: the one that runs on the processor paints either as straight lines, so a turn that small at an end does not move its join, while the one that runs on the graphics card follows the curve as this does (see docs/render-core/futures.md).

enum class taco::render::SegmentKind : uint8_t

源码
kLine = 1源码
kCubic = 2源码
kEllipticalArc = 3源码

struct taco::render::SessionApplyStats

源码

应用/摘要开销的计数器。测试会断言复杂度上限;生产环境的调用方可以忽略它们。只有当 digest() 真正遍历保留场景时,digest_walks 才会递增。

uint64_t digest_walks源码
uint64_t payload_walks源码
uint64_t geometry_nodes_computed源码
uint64_t path_bounds_index_builds源码
uint64_t dirty_nodes_visited源码
uint64_t scene_nodes_validated源码
uint64_t geometry_nodes_validated源码
uint64_t hit_path_index_builds源码
uint64_t hit_segment_flatten_calls源码
uint64_t hit_clip_parent_string_copies源码
uint64_t hit_rounded_path_builds源码

How often a hit test worked out a path with its rounded corners (roundPathVertices) and a path’s stroke contours (buildStrokeContours). Both are kept per node (PaintedStrokeCache), so hit tests on a node that has not changed add to these once, for as long as what is kept for the node fits that cache’s size limit.

uint64_t hit_stroke_contour_builds源码
uint64_t hit_test_traversals源码
uint64_t hit_nodes_tested源码
uint64_t scene_state_node_entries_copied源码

bool taco::render::singlePrecision(double value, float *rounded)

源码

Rounds value to single precision, the precision the renderer builds every path in. False when value is not finite or is too large for single precision to hold. Every number that reaches a drawn path is rounded here and nowhere else.

struct taco::render::skia_adapter::StaticImageFrame

源码

内部调用方(包括 GPU 桥接层)可以提供已经创建好的 SkImage。替换用的图片可以基于光栅,也可以基于纹理;公共 C 边界在进入这条路径之前会构造自有的光栅图片。

std::string_view asset_id源码
uint64_t content_revision源码
uint32_t kind源码
StaticImageFrameDisposition disposition源码
sk_sp<SkImage> image源码

enum class taco::render::skia_adapter::StaticImageFrameDisposition : uint8_t

源码
kReuseActive源码
kReplace源码

double taco::render::strokeCapReach(StrokeCap cap, double width)

源码

描边宽度为 width 的端点样式绘制到的离端点最远的距离,包括描边自身在箭头两翼周围的半宽。

struct taco::render::StrokeContour

源码

One run of segments a stroke is painted along without a break. The stroke has a join between each step and the next, and between the last and the first when closed; the two ends of a contour that is not closed get the stroke’s ends instead. The renderer paints every step. Where a step is too short to have a direction (segmentEndDirection), the hit test reads the join from the steps on either side of it and a stroke’s end from the first or last step that has one.

std::vector<StrokeContourStep> steps源码
bool closed源码

StrokeContourOrder taco::render::strokeContourOrder( const NodeStyle &style, const PathData &path, const RetainedStroke &stroke )

源码

Which contours of a path the renderer paints stroke along. path is the path as stored, which says whether it has stroke caps.

enum class taco::render::StrokeContourOrder : uint8_t

源码
kStored源码

Segments outside every region loop keep the order and direction they are stored in: a segment continues the contour of the one stored before it only when it starts where that one ends, at a vertex no other segment touches. A dashed stroke and a path with stroke caps are painted along these, because a dash pattern and a cap follow the stored order.

kJoined源码

Segments outside every region loop are followed through every vertex where the stroke should join, whatever order and direction they are stored in: a vertex two segment ends touch joins those two, and a vertex three or more touch joins the two branchJoinPair chooses among the ends that have a direction, or the only two that have one. A solid stroke that names its join is painted along these.

struct taco::render::StrokeContourStep

源码

One segment of a stroke contour: forward when the contour runs through it from its start vertex to its end vertex.

const VectorSegment *segment源码
bool forward源码

StrokeOutlineStats &taco::render::skia_adapter::strokeOutlineStats()

源码

struct taco::render::skia_adapter::StrokeOutlineStats

源码

Counts for tests of buildNodeStrokeOutline: how many strokes were turned into the area they cover (Skia made their dashes and stroked them), and how many of those went on to Skia PathOps (one refused for too many contours or too much work does not). capped_stroke_bodies counts the lines of strokes with end shapes that were dashed and stroked, for painting and for outlines alike. dash_estimate is the last count of dashes made before dashing; path_ops_segments and path_ops_work are the segments and the estimate of work last checked before PathOps (the work of a refused stroke is only counted until it passes the limit).

uint64_t stroked_paths源码
uint64_t path_ops_runs源码
uint64_t capped_stroke_bodies源码
double dash_estimate源码
uint64_t path_ops_segments源码
uint64_t path_ops_work源码

enum class taco::render::StrokePosition : uint8_t

源码

TypeScript: RetainedStrokePosition

kCenter = 0源码
kInside = 1源码
kOutside = 2源码

bool taco::render::strokesJoinOpenRuns(const NodeStyle &style)

源码

Whether any stroke of style names its join (wire version 23). Only then do segments outside the region loops run on into each other; otherwise each is a contour of its own.

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_1 1u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_1_SIZE 32u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_2 2u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_2_SIZE 40u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_3 3u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_3_SIZE 48u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_4 4u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_4_SIZE 56u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_5 5u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_5_SIZE 64u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_6 6u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_6_SIZE 72u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_7 7u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_7_SIZE 80u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_8 8u

源码

#define TACO_RENDER_EXTENDED_CAPABILITIES_VERSION_8_SIZE 88u

源码

#define TACO_RENDER_FONT_METADATA_MAX_AXES 65535u

源码

TypeScript: RENDER_FONT_METADATA_MAX_AXES

#define TACO_RENDER_FONT_METADATA_MAX_FEATURES 131070u

源码

TypeScript: RENDER_FONT_METADATA_MAX_FEATURES

#define TACO_RENDER_FONT_METADATA_VERSION 1u

源码

#define TACO_RENDER_INCREMENTAL_RENDER_VERSION 1u

源码

#define TACO_RENDER_MEDIA_FRAME_MAX_BYTES TACO_RENDER_STATIC_IMAGE_FRAME_MAX_BYTES

源码

#define TACO_RENDER_MEDIA_FRAME_MAX_COUNT TACO_RENDER_STATIC_IMAGE_FRAME_MAX_COUNT

源码

图片帧和视频帧共享同一个有上限的媒体预算,按解码后的等效大小计算。

#define TACO_RENDER_MEDIA_FRAME_MAX_DIMENSION TACO_RENDER_STATIC_IMAGE_FRAME_MAX_DIMENSION

源码

#define TACO_RENDER_MEDIA_FRAME_REUSE_ACTIVE TACO_RENDER_STATIC_IMAGE_FRAME_REUSE_ACTIVE

源码

#define TACO_RENDER_MEDIA_FRAME_RGBA8888 TACO_RENDER_STATIC_IMAGE_FRAME_RGBA8888

源码

#define TACO_RENDER_STATIC_IMAGE_FRAME_MAX_BYTES (64u * 1024u * 1024u)

源码

#define TACO_RENDER_STATIC_IMAGE_FRAME_MAX_COUNT 16u

源码

#define TACO_RENDER_STATIC_IMAGE_FRAME_MAX_DIMENSION 32768u

源码

#define TACO_RENDER_STATIC_IMAGE_FRAME_VERSION 1u

源码

#define TACO_RENDER_STROKE_OUTLINE_MAX_NAMESPACE_BYTES TACO_RENDER_VECTOR_BOOLEAN_MAX_NAMESPACE_BYTES

源码

#define TACO_RENDER_STROKE_OUTLINE_MAX_NETWORK_BYTES TACO_RENDER_VECTOR_BOOLEAN_MAX_NETWORK_BYTES

源码

#define TACO_RENDER_TEXT_QUERY_MAX_RECORDS 65536u

源码

文本几何计算在这个固定上限以内是精确的。更大的光标集合,或者跨越的已选 UTF-8 字节数加段落分隔符数超过该上限的范围或叠加层,返回 LIMIT_EXCEEDED,且不写入任何内容。这使原生会话和 512 MiB 的 Wasm 会话的资源占用有可预期的上界。

#define TACO_RENDER_TEXT_QUERY_VERSION 1u

源码

#define TACO_RENDER_VECTOR_BOOLEAN_MAX_NAMESPACE_BYTES 1008u

源码

#define TACO_RENDER_VECTOR_BOOLEAN_MAX_NETWORK_BYTES (64u * 1024u * 1024u)

源码

#define TACO_RENDER_VECTOR_BOOLEAN_VERSION 1u

源码

#define TACO_RENDER_VECTOR_EDITING_OVERLAY_MAX_COMPONENTS 65536u

源码

#define TACO_RENDER_VECTOR_EDITING_OVERLAY_MAX_NETWORK_BYTES (64u * 1024u * 1024u)

源码

#define TACO_RENDER_VECTOR_EDITING_OVERLAY_VERSION 2u

源码

#define TACO_RENDER_VECTOR_QUERY_MAX_IDENTIFIER_BYTES (16u * 1024u * 1024u)

源码

#define TACO_RENDER_VECTOR_QUERY_MAX_RECORDS 65536u

源码

几何查询对每个记录数组分别应用此上限;命中结果只应用一次。

#define TACO_RENDER_VECTOR_QUERY_VERSION 1u

源码

#define TACO_RENDER_VIDEO_FRAME_MAX_BYTES TACO_RENDER_MEDIA_FRAME_MAX_BYTES

源码

#define TACO_RENDER_VIDEO_FRAME_MAX_COUNT TACO_RENDER_MEDIA_FRAME_MAX_COUNT

源码

#define TACO_RENDER_VIDEO_FRAME_MAX_DIMENSION TACO_RENDER_MEDIA_FRAME_MAX_DIMENSION

源码

#define TACO_RENDER_VIDEO_FRAME_VERSION 1u

源码

struct TacoRenderDeviceRect

源码
uint32_t x源码
uint32_t y源码
uint32_t width源码
uint32_t height源码

enum TacoRenderExportFlags

源码
TACO_RENDER_EXPORT_FLAG_SVG_NODE_MARKERS = 1源码

仅用于 SVG:用两个链接标注 <a xlink:href="taco-node-start:HEX"> 和 <a xlink:href="taco-node-end:HEX"> 包住每个被绘制节点的元素,其中 HEX 是节点标识符 UTF-8 字节的小写十六进制形式,以便宿主将它们转换为 id 属性。

enum TacoRenderExportImageSampling

源码

TypeScript: RenderExportImageSampling

TACO_RENDER_EXPORT_IMAGE_SAMPLING_DEFAULT = 0源码
TACO_RENDER_EXPORT_IMAGE_SAMPLING_CUBIC = 1源码

双三次(Mitchell)采样,适用于照片和渐变。

TACO_RENDER_EXPORT_IMAGE_SAMPLING_NEAREST = 2源码

最近像素采样,适用于像素画和硬边缘。

struct TacoRenderFontAxis

源码

来自所保留的那个 SkTypeface 的一个可变字体轴,已排序。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
char[4] tag源码
uint8_t hidden源码
uint8_t[7] reserved源码
double minimum源码
double default_value源码
double maximum源码

struct TacoRenderFontFeature

源码

来自 GSUB 或 GPOS 的一个 OpenType 特性标签:四字节、可打印、已排序且唯一。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
char[4] tag源码

struct TacoRenderFontMetadataQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码

enum TacoRenderGeometryFlags

源码
TACO_RENDER_GEOMETRY_FLAG_HAS_LOCAL_BOUNDS = 1源码
TACO_RENDER_GEOMETRY_FLAG_HAS_WORLD_BOUNDS = 2源码
TACO_RENDER_GEOMETRY_FLAG_HAS_VISIBLE_WORLD_BOUNDS = 4源码
TACO_RENDER_GEOMETRY_FLAG_EFFECTIVELY_VISIBLE = 8源码

enum TacoRenderIncrementalFrameFlags

源码
TACO_RENDER_INCREMENTAL_FRAME_HAS_DAMAGE = 1源码
TACO_RENDER_INCREMENTAL_FRAME_FULL_PAINT = 2源码
TACO_RENDER_INCREMENTAL_FRAME_REUSED_TARGET = 4源码

enum TacoRenderIncrementalRenderFlags

源码
TACO_RENDER_INCREMENTAL_RENDER_FORCE_FULL = 1源码

typedef TacoRenderStaticImageFrame TacoRenderMediaFrame

源码

视频帧版本 1 有意复用已验证可靠的静态图片物理记录布局。kind 字段区分图片和视频的归属。混合集合按逻辑资源 ID 全局排序;视频更新集合只包含场景中确切的、去重后的视频资源集合。

typedef TacoRenderStaticImageFrameDisposition TacoRenderMediaFrameDisposition

源码

enum TacoRenderMediaFrameKind

源码
TACO_RENDER_MEDIA_FRAME_STATIC_IMAGE = 1源码
TACO_RENDER_MEDIA_FRAME_VIDEO = 2源码

typedef TacoRenderStaticImageFrameSet TacoRenderMediaFrameSet

源码

enum TacoRenderNodeKind

源码

保留节点的类型,由节点查询和几何查询报告。

TACO_RENDER_NODE_PATH = 1源码
TACO_RENDER_NODE_TEXT = 2源码
TACO_RENDER_NODE_CONTAINER = 3源码
TACO_RENDER_NODE_MEDIA = 4源码

struct TacoRenderRect

源码

轴对齐矩形:左上角加尺寸。

double x源码
double y源码
double width源码
double height源码

enum TacoRenderStaticImageFrameDisposition

源码
TACO_RENDER_STATIC_IMAGE_FRAME_REUSE_ACTIVE = 1源码
TACO_RENDER_STATIC_IMAGE_FRAME_RGBA8888 = 2源码

enum TacoRenderTextAffinity

源码

TypeScript: RenderTextAffinity

TACO_RENDER_TEXT_AFFINITY_UPSTREAM = 0源码
TACO_RENDER_TEXT_AFFINITY_DOWNSTREAM = 1源码

enum TacoRenderTextAutoResize

源码
TACO_RENDER_TEXT_AUTO_RESIZE_NONE = 0源码
TACO_RENDER_TEXT_AUTO_RESIZE_HEIGHT = 1源码
TACO_RENDER_TEXT_AUTO_RESIZE_WIDTH_AND_HEIGHT = 2源码

struct TacoRenderTextCaret

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
TacoRenderTextPosition position源码
TacoRenderRect local_bounds源码

enum TacoRenderTextEditingOverlayFlags

源码
TACO_RENDER_TEXT_EDITING_OVERLAY_HAS_COMPOSITION = 1源码
TACO_RENDER_TEXT_EDITING_OVERLAY_CARET_VISIBLE = 2源码

struct TacoRenderTextHitQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码
double local_x源码
double local_y源码

struct TacoRenderTextHitResult

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t inside源码
uint64_t generation源码
TacoRenderTextPosition position源码

struct TacoRenderTextLayoutMetrics

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t auto_resize源码
uint64_t generation源码
double frame_width源码
double frame_height源码
double content_width源码
double content_height源码
double suggested_width源码
double suggested_height源码
uint32_t paragraph_count源码
uint32_t line_count源码
uint32_t caret_count源码
uint32_t reserved源码

enum TacoRenderTextNavigationOperation

源码

TypeScript: RenderTextNavigationOperation

TACO_RENDER_TEXT_NAVIGATION_GRAPHEME_BACKWARD = 0源码
TACO_RENDER_TEXT_NAVIGATION_GRAPHEME_FORWARD = 1源码
TACO_RENDER_TEXT_NAVIGATION_WORD_BACKWARD = 2源码
TACO_RENDER_TEXT_NAVIGATION_WORD_FORWARD = 3源码
TACO_RENDER_TEXT_NAVIGATION_VISUAL_LEFT = 4源码
TACO_RENDER_TEXT_NAVIGATION_VISUAL_RIGHT = 5源码
TACO_RENDER_TEXT_NAVIGATION_LINE_UP = 6源码
TACO_RENDER_TEXT_NAVIGATION_LINE_DOWN = 7源码
TACO_RENDER_TEXT_NAVIGATION_LINE_START = 8源码
TACO_RENDER_TEXT_NAVIGATION_LINE_END = 9源码
TACO_RENDER_TEXT_NAVIGATION_PARAGRAPH_START = 10源码
TACO_RENDER_TEXT_NAVIGATION_PARAGRAPH_END = 11源码
TACO_RENDER_TEXT_NAVIGATION_DOCUMENT_START = 12源码
TACO_RENDER_TEXT_NAVIGATION_DOCUMENT_END = 13源码

struct TacoRenderTextNavigationQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t operation源码
uint64_t expected_generation源码
TacoRenderTextPosition from源码
double preferred_local_x源码
uint32_t has_preferred_local_x源码
uint32_t reserved源码

struct TacoRenderTextNavigationResult

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t has_result源码
uint64_t generation源码
TacoRenderTextPosition position源码
double preferred_local_x源码
uint32_t has_preferred_local_x源码
uint32_t reserved源码

struct TacoRenderTextQuery

源码

通用的文本查询输入:调用方预期的场景代次。reserved 必须为 0。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码

struct TacoRenderTextRangeQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码
TacoRenderTextPosition anchor源码
TacoRenderTextPosition focus源码

struct TacoRenderTextRect

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
TacoRenderRect local_bounds源码

enum TacoRenderVectorBooleanOperation

源码

TypeScript: RenderVectorBooleanOperation

TACO_RENDER_VECTOR_BOOLEAN_UNION = 1源码
TACO_RENDER_VECTOR_BOOLEAN_INTERSECTION = 2源码
TACO_RENDER_VECTOR_BOOLEAN_DIFFERENCE = 3源码
TACO_RENDER_VECTOR_BOOLEAN_EXCLUSION = 4源码

enum TacoRenderVectorComponentKind

源码
TACO_RENDER_VECTOR_COMPONENT_VERTEX = 1源码
TACO_RENDER_VECTOR_COMPONENT_CUBIC_HANDLE = 2源码
TACO_RENDER_VECTOR_COMPONENT_SEGMENT = 3源码
TACO_RENDER_VECTOR_COMPONENT_REGION = 4源码

struct TacoRenderVectorCubicHandle

源码

TypeScript: decodeWasmVectorGeometry, PORTABLE_WASM_ABI_LAYOUT

TypeScript,经由 decodeWasmVectorGeometry: RenderCoreSession.getVectorGeometry

uint32_t struct_size源码
uint32_t endpoint源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t segment_id_offset源码
uint32_t segment_id_size源码
uint32_t vertex_id_offset源码
uint32_t vertex_id_size源码
double local_x源码
double local_y源码
double screen_x源码
double screen_y源码

struct TacoRenderVectorEditingComponent

源码

临时矢量编辑叠加层中一个选中的组成部分。其标识是 (kind, identifier) 这一对值;不同 kind 之间的 identifier 可以相同。最多只能有一条记录带有 PRIMARY,并且该记录属于选区。

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t kind源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t flags源码
uint32_t[3] reserved源码

enum TacoRenderVectorEditingComponentFlags

源码
TACO_RENDER_VECTOR_EDITING_COMPONENT_PRIMARY = 1源码

struct TacoRenderVectorEditingOverlayQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码

enum TacoRenderVectorEditingPendingHandleFlags

源码

A pending handle is a curve handle that no segment of the preview network owns yet: the one a Pen drag pulls out of a vertex for the segment drawn from it next. It is editing chrome only (a guide line and a knob) and never changes the painted preview. MIRRORED also draws its exact mirror about the vertex, for a vertex no segment arrives at. Without PRESENT every pending handle field is zero.

TACO_RENDER_VECTOR_EDITING_PENDING_HANDLE_PRESENT = 1源码
TACO_RENDER_VECTOR_EDITING_PENDING_HANDLE_MIRRORED = 2源码

enum TacoRenderVectorEndpoint

源码
TACO_RENDER_VECTOR_ENDPOINT_NONE = 0源码
TACO_RENDER_VECTOR_ENDPOINT_START = 1源码
TACO_RENDER_VECTOR_ENDPOINT_END = 2源码

struct TacoRenderVectorHit

源码

TypeScript: decodeWasmVectorHits, PORTABLE_WASM_ABI_LAYOUT

TypeScript,经由 decodeWasmVectorHits: RenderCoreSession.hitTestVector

uint32_t struct_size源码
uint32_t kind源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t priority源码
uint32_t endpoint源码
uint32_t authored_order源码
uint32_t reserved源码
double distance_css_px源码

struct TacoRenderVectorHitBufferResult

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t hit_count源码
uint32_t identifier_byte_count源码
uint32_t reserved源码
uint64_t generation源码

struct TacoRenderVectorHitQuery

源码

TypeScript: PORTABLE_WASM_ABI_LAYOUT

uint32_t struct_size源码
uint32_t reserved源码
uint64_t expected_generation源码
double screen_x源码
double screen_y源码
double tolerance_css_px源码
double[6] document_to_screen源码

struct TacoRenderVectorRegion

源码

TypeScript: decodeWasmVectorGeometry, PORTABLE_WASM_ABI_LAYOUT

TypeScript,经由 decodeWasmVectorGeometry: RenderCoreSession.getVectorGeometry

uint32_t struct_size源码
uint32_t winding_rule源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t authored_order源码
uint32_t[3] reserved源码
TacoRenderRect local_bounds源码
TacoRenderRect screen_bounds源码

struct TacoRenderVectorSegment

源码

TypeScript: decodeWasmVectorGeometry, PORTABLE_WASM_ABI_LAYOUT

TypeScript,经由 decodeWasmVectorGeometry: RenderCoreSession.getVectorGeometry

uint32_t struct_size源码
uint32_t kind源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t start_vertex_id_offset源码
uint32_t start_vertex_id_size源码
uint32_t end_vertex_id_offset源码
uint32_t end_vertex_id_size源码
uint32_t start_handle_id_offset源码
uint32_t start_handle_id_size源码
uint32_t end_handle_id_offset源码
uint32_t end_handle_id_size源码
uint32_t flags源码
uint32_t authored_order源码
TacoRenderRect local_bounds源码
TacoRenderRect screen_bounds源码
double radius_x源码
double radius_y源码
double x_axis_rotation源码

enum TacoRenderVectorSegmentFlags

源码
TACO_RENDER_VECTOR_SEGMENT_LARGE_ARC = 1源码
TACO_RENDER_VECTOR_SEGMENT_SWEEP = 2源码

enum TacoRenderVectorSegmentKind

源码
TACO_RENDER_VECTOR_SEGMENT_LINE = 1源码
TACO_RENDER_VECTOR_SEGMENT_CUBIC = 2源码
TACO_RENDER_VECTOR_SEGMENT_ELLIPTICAL_ARC = 3源码

struct TacoRenderVectorVertex

源码

TypeScript: decodeWasmVectorGeometry, PORTABLE_WASM_ABI_LAYOUT

TypeScript,经由 decodeWasmVectorGeometry: RenderCoreSession.getVectorGeometry

uint32_t struct_size源码
uint32_t id_offset源码
uint32_t id_size源码
uint32_t reserved源码
double local_x源码
double local_y源码
double screen_x源码
double screen_y源码

enum TacoRenderVectorWindingRule

源码
TACO_RENDER_VECTOR_WINDING_NONZERO = 0源码
TACO_RENDER_VECTOR_WINDING_EVENODD = 1源码

enum TacoRenderViewportMode

源码

taco_render_session_map_viewport 如何把场景缩放到视口中。

TACO_RENDER_VIEWPORT_FIT = 0源码

等比缩放;整个场景完整放入视口内。

TACO_RENDER_VIEWPORT_FILL = 1源码

等比缩放;场景铺满整个视口。

TACO_RENDER_VIEWPORT_STRETCH = 2源码

x 和 y 分别缩放;场景与视口完全重合。

enum class taco::render::TangentConstraintMode : uint8_t

源码
kAngle = 0源码
kAngleAndLength = 1源码

enum class taco::render::TextAlign : uint8_t

源码
kLeft = 0源码
kCenter = 1源码
kRight = 2源码
kJustify = 3源码

enum class taco::render::TextAutoResize : uint8_t

源码
kNone = 0源码
kHeight = 1源码
kWidthAndHeight = 2源码

struct taco::render::TextData

源码
double width源码
double height源码
double line_height源码
TextWrap wrap源码
TextAlign align源码
std::string text源码
std::vector<TextRun> runs源码
TextVerticalAlign vertical_align源码
TextOverflow overflow源码
TextAutoResize auto_resize源码
std::vector<RichTextStyle> styles源码
std::vector<TextParagraph> paragraphs源码

enum class taco::render::TextDirection : uint8_t

源码
kAuto = 0源码
kLtr = 1源码
kRtl = 2源码

enum class taco::render::TextListKind : uint8_t

源码
kNone = 0源码
kOrdered = 1源码
kUnordered = 2源码

struct taco::render::TextListMarker

源码
bool has_text源码
std::string text源码
bool has_style源码
uint32_t style_index源码
bool has_gap源码
double gap源码

enum class taco::render::TextOverflow : uint8_t

源码
kClip = 0源码
kVisible = 1源码

struct taco::render::TextParagraph

源码
TextDirection direction源码
TextAlign align源码
double spacing_before源码
double spacing_after源码
bool has_indent源码
TextParagraphIndent indent源码
TextParagraphList list源码
std::string text源码
std::vector<RichTextRun> runs源码

struct taco::render::TextParagraphIndent

源码
double left源码
double right源码
double first_line源码

struct taco::render::TextParagraphList

源码
TextListKind kind源码
uint32_t level源码
bool has_start源码
uint32_t start源码
bool has_marker源码
TextListMarker marker源码

struct taco::render::TextRun

源码
uint32_t start_byte源码
uint32_t end_byte源码
std::string font_resource_id源码
double font_size源码
double letter_spacing源码
uint16_t weight源码
bool italic源码
bool underline源码
bool strikethrough源码
Color color源码
std::vector<OpenTypeFeature> open_type_features源码
std::vector<FontVariation> font_variations源码

enum class taco::render::TextVerticalAlign : uint8_t

源码
kTop = 0源码
kMiddle = 1源码
kBottom = 2源码

enum class taco::render::TextWrap : uint8_t

源码
kNone = 0源码
kWord = 1源码
kCharacter = 2源码

TacoRenderRect taco::render::toRect(const Bounds &bounds)

源码

C ABI: taco_render_session_hit_test, taco_render_session_get_last_dirty_bounds

struct taco::render::Transform

源码

以 values = [a, b, c, d, e, f] 存储的仿射矩阵,布局与 TypeScript 的 Transform 相同。点的映射方式为 (x′,y′)=(ax+cy+e, bx+dy+f)(x', y') = (a x + c y + e, \ b x + d y + f)。

std::array<double, 6> values源码

Bounds taco::render::unionBounds(const Bounds &first, const Bounds &second)

源码

struct taco::render::VectorGeometryQueryResult

源码
std::vector<TacoRenderVectorVertex> vertices源码
std::vector<TacoRenderVectorCubicHandle> handles源码
std::vector<TacoRenderVectorSegment> segments源码
std::vector<TacoRenderVectorRegion> regions源码
std::string identifiers源码

struct taco::render::VectorHandle

源码
std::string_view id源码
double dx源码
double dy源码

struct taco::render::VectorHitQueryResult

源码
std::vector<TacoRenderVectorHit> hits源码
std::string identifiers源码

VectorPathOpsStats &taco::render::skia_path_ops::vectorPathOpsStats()

源码

struct taco::render::skia_path_ops::VectorPathOpsStats

源码
int id_concat_temporaries源码
uint64_t contour_pair_checks源码

Pairs of contours vectorNetworkFromPath compared to group contours into regions.

uint64_t projected_segments源码

Segments vectorNetworkFromPath last counted in a path before making any (counting stops just past the limit), and segments made from path verbs since the last reset: none when a path was refused by that count.

uint64_t contour_segments源码

struct taco::render::VectorRegion

源码
std::string_view id源码
WindingRule winding_rule源码
bool has_explicit_fills源码
std::vector<RetainedPaint> fills源码
std::vector<VectorRegionLoop> loops源码

struct taco::render::VectorRegionLoop

源码
bool implicit_close源码
std::vector<VectorSegmentReference> segments源码

struct taco::render::VectorSegment

源码
std::string_view id源码
std::string_view start_vertex_id源码
std::string_view end_vertex_id源码
SegmentKind kind源码
VectorHandle start_handle源码
VectorHandle end_handle源码
double radius_x源码
double radius_y源码
double x_axis_rotation源码
bool large_arc源码
bool sweep源码

struct taco::render::VectorSegmentReference

源码
std::string_view segment_id源码
SegmentDirection direction源码

struct taco::render::VectorTangentConstraint

源码
std::string_view vertex_id源码
std::array<std::string_view, 2> handle_ids源码
TangentConstraintMode mode源码

struct taco::render::VectorVertex

源码
std::string_view id源码
double x源码
double y源码
double corner_radius源码

Wire 版本 12:当该顶点恰好连接两条直线段或三次曲线段时,正的半径会在绘制时将其圆角化。设计时的位置仍作为编辑和查询所用的几何。

enum class taco::render::WindingRule : uint8_t

源码
kNonzero = 0源码
kEvenodd = 1源码