mirror of
https://github.com/aphrody-labs/opentui.git
synced 2026-10-13 21:08:53 +00:00
`EditBuffer.measureText(text)` returns the editor offset at the end of a
text: its cells under the buffer's width method, tab width, and control
notation, plus one per line break. The result depends only on the text
and those three settings, but an app needed a live native `EditBuffer`
to get it. opencode passed a measure closure into otherwise pure helpers,
kept a spare detached `EditBuffer` for when no textarea was mounted, and
built a renderer and a textarea in tests only to measure strings.
`measureEditText(text, { widthMethod, tabWidth })` returns what
`measureText()` and the end offset after `setText()` give on an edit
buffer with those settings, without a buffer or an owner. `tabWidth`
defaults to the tab width of a new edit buffer and rounds as
`setTabWidth()` does. It calls the new `ot_edit_measure_text(context,
bytes, byte_count, width_method, tab_width, out_width)`. That entry point
checks the width method as `ot_unicode_create` does, rejects a tab width
over 255 and rounds it as `ot_edit_buffer_set_tab_width` does, applies
the byte limit and UTF-8 check of `set_text`, and leaves the output
unchanged on failure. Tab width 0 rounds to the tab width of a new
buffer, so TypeScript passes 0 for the default and keeps no second copy
of it.
Both entry points share one native function, `Context.measureEditText`.
It adds the width of each line between LF, CR, and CRLF, as
`textToSegments` splits them, and one per break. It does not build
segments, so neither entry point allocates any more. `validateTextBytes`
takes the tab width instead of a buffer.
Each native call needs a Context, so the library owns one for these
measures: `FFIRenderLib` creates it on the first call and releases it in
`dispose()`, as it does for audio engines. A module-level
`ResourceContext` would be smaller, but `dispose()` refuses while any
other Context is live, so one measure would make the public
`resolveRenderLib().dispose()` fail with no way to release that Context.
No test or tool otherwise checks for leaked Contexts. Creating the
Context and measuring need no Yoga mutation and use read admission, so a
measure works in input handlers, during render, and in a layout
callback, as `EditBuffer.measureText()` does.
A differential table in `edit-buffer.test.ts` runs under Bun and Node.
For every public width method and the tab widths default, 0, 1, 3, 8,
and 255, it measures C0 controls, DEL, C1, tabs, CJK with a combining
mark, ZWJ, skin-tone, and flag emoji, CR, LF, CRLF, mixed lines, a CRLF
across the 16-byte blocks of `findLineBreaks` before a long line, and the
empty string. `measureEditText()`, `measureText()`, and the end offset
after `setText()` agree on each. New rows in the native malformed-argument
table cover a null span, malformed UTF-8, an unknown width method, tab
width 256, a null output, and one byte over the limit; one byte less
measures the widest tabs within u32. The dispose test measures first in
a Yoga callback, keeps the measure Context through a refused dispose,
and releases it in the next. Hidden controls, CRLF as two breaks, LF-only
breaks, no break count, no tab rounding, a wrong default, each removed
argument check, write admission, an `assertMutable()` guard, and each
dispose change make a test fail.
317 lines
19 KiB
TypeScript
317 lines
19 KiB
TypeScript
export interface PointerPolicy {
|
|
ffi: "buffer" | "ptr"
|
|
nullable: "never" | "empty" | "optional"
|
|
retention:
|
|
| "call"
|
|
| "until-measure-replaced-unset-or-node-context-destroyed"
|
|
| "until-observer-replaced-unset-or-context-destroyed"
|
|
source: "view" | "native-address" | "view-or-native-address" | "callback"
|
|
result?: { nullable: "on-error"; release: "ot_context_destroy" }
|
|
}
|
|
|
|
export type PointerPolicies = Record<string, Partial<Record<number | "returns", PointerPolicy>>>
|
|
|
|
export type AddressFields = Record<
|
|
string,
|
|
Record<string, { type: string; nullable: boolean; lifetime: string; release: string; element: string }>
|
|
>
|
|
|
|
const context = { ffi: "ptr", nullable: "never", retention: "call", source: "native-address" } as const
|
|
const buffer = { ffi: "buffer", nullable: "never", retention: "call", source: "view" } as const
|
|
const optional = { ffi: "ptr", nullable: "optional", retention: "call", source: "view" } as const
|
|
const empty = { ffi: "ptr", nullable: "empty", retention: "call", source: "view" } as const
|
|
const pixels = { ffi: "ptr", nullable: "empty", retention: "call", source: "view-or-native-address" } as const
|
|
const measure = {
|
|
ffi: "ptr",
|
|
nullable: "optional",
|
|
source: "callback",
|
|
retention: "until-measure-replaced-unset-or-node-context-destroyed",
|
|
} as const
|
|
const observer = {
|
|
ffi: "ptr",
|
|
nullable: "optional",
|
|
source: "callback",
|
|
retention: "until-observer-replaced-unset-or-context-destroyed",
|
|
} as const
|
|
|
|
// This is host policy, not a second C signature table. Each pointer position is
|
|
// explicit; scalar widths, pointer types, symbols and records come from Translate-C.
|
|
// `nullable` describes values passed by this binding. Several C spans also accept
|
|
// NULL at zero length, but their existing TS callers always pass a view (`buffer`).
|
|
// `retention` describes borrowing the pointer itself, not copying/retaining handles.
|
|
// Changes to C ownership comments require review here: C pointer types cannot prove lifetimes.
|
|
export const nativePointerPolicies = {
|
|
ot_output_write_callback: {
|
|
0: { ...optional, source: "native-address" },
|
|
1: { ...context, source: "native-address" },
|
|
},
|
|
ot_context_create: { 0: buffer, 1: { ...buffer, result: { nullable: "on-error", release: "ot_context_destroy" } } },
|
|
ot_context_destroy: { 0: context },
|
|
ot_context_get_last_error: { 0: context, 1: buffer },
|
|
ot_context_drain_diagnostics: { 0: context, 1: empty, 3: buffer },
|
|
ot_context_get_link_url: { 0: context, 2: buffer, 4: buffer },
|
|
ot_unicode_create: { 0: context, 1: empty, 4: buffer },
|
|
ot_unicode_destroy: { 0: context, 1: buffer },
|
|
ot_unicode_get: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_buffer_draw_unicode: { 0: context, 1: buffer, 2: optional, 3: buffer, 7: buffer, 8: buffer },
|
|
ot_embedded_terminal_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_embedded_terminal_destroy: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_write: { 0: context, 1: buffer, 2: empty },
|
|
ot_embedded_terminal_resize: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_command: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_set_selection: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_embedded_terminal_compose: { 0: context, 1: buffer, 2: buffer, 3: optional },
|
|
ot_embedded_terminal_cursor_get: { 0: context, 1: buffer, 2: buffer },
|
|
ot_embedded_terminal_encode_key: { 0: context, 1: buffer, 2: buffer, 3: empty, 5: empty, 7: empty, 9: buffer },
|
|
ot_embedded_terminal_encode_mouse: { 0: context, 1: buffer, 2: buffer, 3: buffer, 5: buffer },
|
|
ot_embedded_terminal_encode_paste: { 0: context, 1: buffer, 2: empty, 4: empty, 6: buffer },
|
|
ot_embedded_terminal_encode_focus: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_embedded_terminal_drain_responses: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_image_destroy: { 0: context, 1: buffer },
|
|
ot_image_inspect: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_decode: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_create_pixels: { 0: context, 1: buffer, 8: buffer },
|
|
ot_image_update_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_clone: { 0: context, 1: context, 2: buffer, 3: buffer },
|
|
ot_image_retain: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_resize: { 0: context, 1: buffer, 5: buffer },
|
|
ot_image_extract: { 0: context, 1: buffer, 6: buffer },
|
|
ot_image_extend: { 0: context, 1: buffer, 6: buffer, 7: buffer },
|
|
ot_image_transform: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_composite: { 0: context, 1: buffer, 2: buffer, 7: buffer },
|
|
ot_image_copy_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_copy_png: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_image_take_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_pixels_release: { 0: context, 1: buffer },
|
|
ot_scene_set_image: { 0: context, 1: buffer, 2: optional, 5: optional },
|
|
ot_buffer_draw_image: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: buffer, 5: buffer },
|
|
ot_session_set_image_resolution: { 0: context, 1: buffer },
|
|
ot_session_set_kitty_image_transport: { 0: context, 1: buffer },
|
|
ot_session_get_kitty_image_transport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_poll_kitty_image_transport: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_cancel_kitty_image_transport: { 0: context, 1: buffer },
|
|
ot_session_process_kitty_image_reply: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_session_start_kitty_file_probe: { 0: context, 1: buffer },
|
|
ot_text_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_text_buffer_view_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_destroy: { 0: context, 1: buffer },
|
|
ot_text_buffer_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_text_buffer_append: { 0: context, 1: buffer, 2: empty },
|
|
ot_text_buffer_clear: { 0: context, 1: buffer },
|
|
ot_text_buffer_set_styled_text: { 0: context, 1: buffer, 2: empty, 4: empty, 6: empty },
|
|
ot_text_buffer_replace_styled_batch: { 0: context, 1: buffer, 3: buffer, 5: buffer, 7: buffer, 9: buffer },
|
|
ot_text_buffer_set_syntax_style: { 0: context, 1: buffer, 2: optional },
|
|
ot_text_buffer_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_text_buffer_get_range: { 0: context, 1: buffer, 4: empty, 6: buffer },
|
|
ot_text_buffer_set_defaults: { 0: context, 1: buffer, 3: buffer },
|
|
ot_text_buffer_set_tab_width: { 0: context, 1: buffer },
|
|
ot_text_buffer_highlight: { 0: context, 1: buffer, 4: optional },
|
|
ot_text_buffer_get_highlights: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_text_buffer_view_set_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_command: { 0: context, 1: buffer },
|
|
ot_text_buffer_view_set_tab_color: { 0: context, 1: buffer, 2: optional },
|
|
ot_text_buffer_view_select: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_text_buffer_view_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_text_buffer_view_get_lines: { 0: context, 1: buffer, 4: empty, 6: buffer },
|
|
ot_text_buffer_view_measure: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_set_text_view: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_text_view_paint: { 0: context, 1: buffer },
|
|
ot_buffer_draw_text_view: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_buffer_draw_editor_view: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_buffer_draw_scene_text: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_edit_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_editor_view_create: { 0: context, 1: buffer, 4: buffer },
|
|
ot_editor_view_destroy: { 0: context, 1: buffer },
|
|
ot_syntax_style_create: { 0: context, 1: buffer },
|
|
ot_syntax_style_destroy: { 0: context, 1: buffer },
|
|
ot_edit_buffer_set_syntax_style: { 0: context, 1: buffer, 2: optional },
|
|
ot_edit_buffer_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_edit_buffer_insert_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_edit_buffer_delete_range: { 0: context, 1: buffer },
|
|
ot_edit_buffer_set_cursor: { 0: context, 1: buffer },
|
|
ot_edit_buffer_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_edit_buffer_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_set_tab_width: { 0: context, 1: buffer },
|
|
ot_edit_buffer_command: { 0: context, 1: buffer },
|
|
ot_edit_buffer_history: { 0: context, 1: buffer, 3: buffer, 5: buffer },
|
|
ot_edit_buffer_get_position: { 0: context, 1: buffer, 5: buffer },
|
|
ot_edit_buffer_get_range: { 0: context, 1: buffer, 7: empty, 9: buffer },
|
|
ot_edit_buffer_measure_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_edit_measure_text: { 0: context, 1: empty, 5: buffer },
|
|
ot_edit_buffer_set_defaults: { 0: context, 1: buffer, 3: buffer },
|
|
ot_syntax_style_register: { 0: context, 1: buffer, 2: empty, 4: buffer, 5: buffer },
|
|
ot_syntax_style_resolve: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_syntax_style_get_count: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_highlight: { 0: context, 1: buffer, 4: optional },
|
|
ot_edit_buffer_get_highlights: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_editor_view_set_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_get_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_set_scroll_margin: { 0: context, 1: buffer },
|
|
ot_editor_view_command: { 0: context, 1: buffer },
|
|
ot_editor_view_replace_selection: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_editor_view_set_tab_color: { 0: context, 1: buffer, 2: optional },
|
|
ot_editor_view_select: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_editor_view_get_info: { 0: context, 1: buffer, 3: buffer },
|
|
ot_editor_view_get_selection: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_editor_view_get_position: { 0: context, 1: buffer, 3: buffer },
|
|
ot_editor_view_get_lines: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_editor_view_measure: { 0: context, 1: buffer, 4: buffer },
|
|
ot_editor_view_set_placeholder: { 0: context, 1: buffer, 2: empty, 4: empty },
|
|
ot_context_set_edit_event_callback: { 0: context, 1: observer },
|
|
ot_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_buffer_resize: { 0: context, 1: buffer },
|
|
ot_buffer_draw: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: optional, 5: buffer, 7: buffer },
|
|
ot_buffer_stack: { 0: context, 1: buffer, 2: optional, 8: buffer, 9: buffer },
|
|
ot_buffer_draw_grid: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: buffer, 6: buffer },
|
|
ot_buffer_draw_packed: { 0: context, 1: buffer, 2: optional, 3: pixels },
|
|
ot_buffer_draw_supersample: { 0: context, 1: buffer, 2: optional, 3: pixels },
|
|
ot_buffer_draw_grayscale: { 0: context, 1: buffer, 2: optional, 3: buffer, 9: optional, 10: optional },
|
|
ot_buffer_color_matrix: { 0: context, 1: buffer, 2: optional, 3: buffer, 5: optional, 7: buffer },
|
|
ot_buffer_acquire_lease: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_attach_renderer: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_attach_renderer_with_env: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_session_render: { 0: context, 1: buffer, 3: buffer },
|
|
ot_scene_frame_copy_buffer: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_measure_layout: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_render_split: { 0: context, 1: buffer, 2: optional, 3: empty, 7: buffer },
|
|
ot_session_split_control: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_session_set_screen: { 0: context, 1: buffer, 5: buffer },
|
|
ot_session_sync_detached: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_resize_renderer: { 0: context, 1: buffer },
|
|
ot_session_draw_buffer: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_set_debug_overlay: { 0: context, 1: buffer },
|
|
ot_session_update_stats: { 0: context, 1: buffer },
|
|
ot_session_update_memory_stats: { 0: context, 1: buffer },
|
|
ot_session_dump_hit_grid: { 0: context, 1: buffer },
|
|
ot_session_get_renderer_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_acquire_buffer_lease: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_get_link_id: { 0: context, 1: buffer, 4: buffer },
|
|
ot_buffer_lease_validate: { 0: context, 1: buffer },
|
|
ot_buffer_lease_release: { 0: context, 1: buffer },
|
|
ot_buffer_lease_get_real_char_size: { 0: context, 1: buffer, 3: buffer },
|
|
ot_buffer_lease_write_resolved_chars: { 0: context, 1: buffer, 2: empty, 5: empty, 7: buffer },
|
|
ot_session_setup_terminal: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_suspend: { 0: context, 1: buffer },
|
|
ot_session_resume: { 0: context, 1: buffer },
|
|
ot_session_get_terminal_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_pump: { 0: context, 1: buffer, 4: buffer },
|
|
ot_session_pump_exit: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_control: { 0: context, 1: buffer, 2: buffer, 3: empty },
|
|
ot_session_clipboard: { 0: context, 1: buffer, 3: buffer, 5: buffer },
|
|
ot_session_notification: { 0: context, 1: buffer, 2: buffer, 4: empty, 6: buffer },
|
|
ot_session_set_palette_state: { 0: context, 1: buffer, 2: buffer, 4: buffer, 5: buffer },
|
|
ot_session_get_capabilities: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_get_write_limit: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_write: { 0: context, 1: buffer, 2: empty },
|
|
ot_session_read_output: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_session_drain_output: {
|
|
0: context,
|
|
1: buffer,
|
|
3: buffer,
|
|
4: { ...optional, source: "view-or-native-address" },
|
|
5: { ffi: "ptr", nullable: "never", retention: "call", source: "callback" },
|
|
},
|
|
ot_session_drain_stdout: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_complete_output: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_close: { 0: context, 1: buffer },
|
|
ot_session_cancel: { 0: context, 1: buffer },
|
|
ot_session_get_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_destroy: { 0: context, 1: buffer },
|
|
ot_clipboard_service_create: { 0: context, 3: empty },
|
|
ot_clipboard_service_begin_shutdown: { 0: context },
|
|
ot_clipboard_service_poll_shutdown: { 0: context },
|
|
ot_clipboard_service_destroy: { 0: context },
|
|
ot_clipboard_service_drain: { 0: context },
|
|
ot_clipboard_read_operation_start: { 0: context, 1: buffer, 8: buffer },
|
|
ot_clipboard_write_operation_start: { 0: context, 1: buffer, 5: buffer },
|
|
ot_clipboard_clear_operation_start: { 0: context, 3: buffer },
|
|
ot_clipboard_operation_poll: { 0: context, 1: buffer },
|
|
ot_clipboard_operation_cancel: { 0: context, 1: buffer },
|
|
ot_clipboard_operation_result_mime_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_mime_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_data_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_data_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_error_code: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_diagnostic_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_diagnostic_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_destroy: { 0: context, 1: buffer },
|
|
ot_scene_create_node: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_destroy_node: { 0: context, 1: buffer },
|
|
ot_scene_move_node: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_viewport: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_focus: { 0: context, 1: buffer },
|
|
ot_scene_set_style: { 0: context, 1: buffer },
|
|
ot_scene_flush: { 0: context, 1: empty, 3: buffer },
|
|
ot_scene_set_measure: { 0: context, 1: buffer, 2: measure },
|
|
ot_scene_has_measure: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_mark_dirty: { 0: context, 1: buffer },
|
|
ot_scene_get_style: { 0: context, 1: buffer, 5: buffer },
|
|
ot_scene_set_paint: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_surface: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_box_details: { 0: context, 1: buffer, 2: buffer, 3: empty, 5: empty },
|
|
ot_scene_set_slider: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_slider_thumb: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_arrow: { 0: context, 1: buffer, 2: buffer, 3: optional },
|
|
ot_scene_set_editor_view: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_editor_options: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_scene_set_styled_text: { 0: context, 1: buffer, 2: empty, 4: empty, 6: empty },
|
|
ot_scene_set_text_options: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_text_selection: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_get_text_selection: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_scene_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_scene_get_text_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_text_lines: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_scene_get_layout: { 0: context, 1: buffer, 3: buffer },
|
|
ot_scene_paint: { 0: context, 1: buffer, 2: buffer, 5: buffer },
|
|
ot_scene_set_hooks: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_frame_step_with_geometry: {
|
|
0: context,
|
|
1: buffer,
|
|
2: optional,
|
|
3: buffer,
|
|
5: optional,
|
|
7: buffer,
|
|
8: buffer,
|
|
},
|
|
ot_scene_frame_get_paint_slots: { 0: context, 1: buffer, 2: buffer, 3: buffer, 5: buffer },
|
|
ot_scene_frame_acquire_buffer_lease: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_scene_frame_draw_buffer: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_frame_commit: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_scene_frame_cancel: { 0: context, 1: buffer },
|
|
ot_scene_hit_test: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_get_stats: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_cursor_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_measure_callback: { 7: { ffi: "ptr", nullable: "never", retention: "call", source: "native-address" } },
|
|
} satisfies PointerPolicies
|
|
|
|
// The header intentionally transports these native addresses as fixed-width u64.
|
|
// Their storage is borrowed until lease release; record copying never retains it.
|
|
export const nativeAddressFields = {
|
|
ot_image_pixels: {
|
|
pixels: { type: "u64", nullable: false, lifetime: "lease", release: "ot_image_pixels_release", element: "u8" },
|
|
},
|
|
ot_buffer_lease_snapshot: {
|
|
char_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u32" },
|
|
fg_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u16" },
|
|
bg_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u16" },
|
|
attributes_ptr: {
|
|
type: "u64",
|
|
nullable: false,
|
|
lifetime: "lease",
|
|
release: "ot_buffer_lease_release",
|
|
element: "u32",
|
|
},
|
|
},
|
|
} as const satisfies AddressFields
|