diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 13:04:32 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 13:04:32 +0300 |
| commit | bdaedce69b17b654bd0060579dd9b9ff120009b5 (patch) | |
| tree | 0e9cd8597652263a96c48ba678fb0b66e1fc131b /include/term | |
| parent | ba75c8b0a1bba03ad92c53375432f122ddb4cb98 (diff) | |
| parent | dcebf9c7f954a55350b68d0ead1935612c4e2e05 (diff) | |
Merge branch 'wt/rename' into api-hardening
# Conflicts:
# README.md
Diffstat (limited to 'include/term')
| -rw-r--r-- | include/term/term.h | 492 | ||||
| -rw-r--r-- | include/term/term_input.h | 202 | ||||
| -rw-r--r-- | include/term/term_types.h | 32 | ||||
| -rw-r--r-- | include/term/unicode/grapheme.h | 26 | ||||
| -rw-r--r-- | include/term/unicode/unicode.h | 6 | ||||
| -rw-r--r-- | include/term/unicode/unicode_data.inc | 258 | ||||
| -rw-r--r-- | include/term/unicode/utf8.h | 243 | ||||
| -rw-r--r-- | include/term/unicode/width.h | 56 |
8 files changed, 0 insertions, 1315 deletions
diff --git a/include/term/term.h b/include/term/term.h deleted file mode 100644 index 8b98a25..0000000 --- a/include/term/term.h +++ /dev/null @@ -1,492 +0,0 @@ -#ifndef TERM_H -#define TERM_H - -/* - * Terminal emulator core. - * - * A struct term parses the bytes that a program writes and keeps the screen, - * the history, and the modes. The application feeds bytes with term_feed() - * and reads state with the getters below. A renderer never reads the - * terminal directly: it copies the viewport into a struct term_snapshot and - * paints from that copy. - * - * All functions take the terminal as the first argument. Functions that take - * a const struct term do not change what it shows. Selection, history, link, - * directory, and pointer-shape queries return owned strings; release them - * with term_text_free(). - * - * Threads. Any thread can call any function. Each call that reads or changes - * a terminal enters its writer section, so calls on one terminal run one at a - * time. A thread that waits for the section sleeps. On POSIX the section is a - * mutex with priority inheritance where the platform has it. A snapshot - * belongs to one thread at a time. term_free() is the last call on a terminal. - */ - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -#include "term_input.h" -#include "term_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct term; -struct term_snapshot; - -/* A row holds at most this many cells. */ -#define TERM_MAX_COLS 65535 -/* The history limit when term_options.scrollback is 0. */ -#define TERM_SCROLLBACK_DEFAULT 10000 -/* The largest term_options.scrollback. */ -#define TERM_SCROLLBACK_MAX 1000000 - -/* - * The version of this header. A host compares TERM_VERSION_CODE with - * term_version() to check that the library matches the header. - */ -#define TERM_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch)) -#define TERM_VERSION_MAJOR 0 -#define TERM_VERSION_MINOR 1 -#define TERM_VERSION_PATCH 0 -#define TERM_VERSION_CODE TERM_VERSION(TERM_VERSION_MAJOR, TERM_VERSION_MINOR, TERM_VERSION_PATCH) - -/* - * Colors. A term_color is either a direct color (alpha 0xFF, then RGB) or a - * palette slot: an index 0-255, the default foreground, or the default - * background. A slot resolves when a snapshot is painted, so a theme change - * recolors text that is already on screen. - */ -typedef uint32_t term_color; - -#define TERM_COLOR_SLOT 0x01000000u -/* The palette index of a slot; see struct term_view.palette. */ -#define TERM_COLOR_SLOT_INDEX 0x1FFu -#define TERM_COLOR_FG (TERM_COLOR_SLOT | 0x100u) -#define TERM_COLOR_BG (TERM_COLOR_SLOT | 0x101u) - -static inline term_color term_color_index(int n) -{ - return TERM_COLOR_SLOT | ((uint32_t)n & 0xFFu); -} - -static inline term_color term_color_rgb(uint8_t r, uint8_t g, uint8_t b) -{ - return 0xFF000000u | (uint32_t)r << 16 | (uint32_t)g << 8 | b; -} - -static inline bool term_color_is_slot(term_color c) -{ - return (c >> 24) == (TERM_COLOR_SLOT >> 24); -} - -/* Parse an X11 or OSC color specification ("#rgb", "rgb:r/g/b", ...). */ -TERM_API bool term_color_parse(const char *spec, uint32_t *argb); - -/* The colors a terminal starts with. All values are ARGB. An all-zero theme - * selects the built-in theme. */ -struct term_theme { - uint32_t fg, bg, cursor; - uint32_t ansi[16]; -}; - -/* Fill theme with the built-in theme. */ -TERM_API void term_theme_default(struct term_theme *theme); -/* Fill theme with the high-contrast theme. */ -TERM_API void term_theme_high_contrast(struct term_theme *theme); -/* Sets one palette key: foreground, background, or color0 to color15. - * An empty value resets the key to the built-in theme. False, with no - * change, for an unknown key or a bad color. */ -TERM_API bool term_theme_set_key(struct term_theme *p, const char *key, const char *val); - -enum term_cursor_style { - TERM_CURSOR_BLOCK, - TERM_CURSOR_UNDERLINE, - TERM_CURSOR_BAR, -}; - -/* Mouse reporting modes and encodings. The values are the DEC mode numbers. */ -enum term_mouse { - TERM_MOUSE_OFF = 0, - TERM_MOUSE_X10 = 9, - TERM_MOUSE_NORMAL = 1000, - TERM_MOUSE_BUTTON = 1002, - TERM_MOUSE_ANY = 1003, -}; - -enum term_mouse_encoding { - TERM_MOUSE_ENC_X10 = 0, - TERM_MOUSE_ENC_UTF8 = 1005, - TERM_MOUSE_ENC_SGR = 1006, - TERM_MOUSE_ENC_URXVT = 1015, - TERM_MOUSE_ENC_SGR_PIXELS = 1016, -}; - -/* - * Callbacks. They run inside term_feed() and term_focus(), on the thread - * that calls those functions. A callback must not call back into the - * terminal. String arguments are valid only during the call. - */ -struct term_callbacks { - void *ud; - /* Bytes the terminal sends back to the program (replies to queries). */ - void (*reply)(void *ud, const char *bytes, size_t len); - void (*title)(void *ud, const char *title); - /* - * OSC 52 clipboard callback. - * selection names the target clipboard buffer(s), commonly: - * "c" - clipboard (system clipboard) - * "p" - primary selection (X11 primary) - * "q" - secondary selection - * "s" - select selection - * "0".."7" - cut buffers 0 to 7 - * A parameter may contain multiple targets (e.g. "cp"). - * data contains decoded bytes of length len. - */ - void (*clipboard)(void *ud, const char *selection, const char *data, size_t len); - void (*notify)(void *ud, const char *title, const char *body); - void (*bell)(void *ud); - /* Parser trace lines for debugging. NULL turns tracing off. The line has no newline. */ - void (*trace)(void *ud, const char *line); -}; - -/* - * Options for term_new(). An all-zero value is valid. A size component of 0 - * selects 80 columns or 24 rows. A negative component, or columns above - * TERM_MAX_COLS, makes term_new() fail. A scrollback below 0 or above - * TERM_SCROLLBACK_MAX fails too. - * cursor_style must be a value of enum term_cursor_style. - */ -struct term_options { - struct term_vector2i size; /* columns and rows */ - int scrollback; /* history lines; 0 selects TERM_SCROLLBACK_DEFAULT */ - struct term_theme theme; - enum term_cursor_style cursor_style; - bool cursor_steady; /* false: the cursor blinks */ - /* - * The terminal's name. Programs read it with XTVERSION and XTGETTCAP. - * It is also the title of a notification that has none. NULL or "" - * selects "term". Otherwise 1 to 63 printable ASCII bytes, or term_new() - * returns NULL. term_new() copies the name. - */ - const char *name; - struct term_callbacks callbacks; - /* Must be zero. term_new() returns NULL if any word is nonzero, so a - * later version can give a word a meaning. */ - uint32_t reserved[8]; -}; - -/* The Unicode version of the width tables, such as "18.0.0". A host can - * pass it to programs as UNICODE_VERSION. */ -TERM_API const char *term_unicode_version(void); -/* The TERM_VERSION_CODE the library was built with. */ -TERM_API unsigned term_version(void); - -/* The length of the prefix of buf made of bytes in [0x20, hi). With hi - * 0x7f, it finds a run of printable ASCII in UTF-8 text, so a host can - * skip shaping for it. Any thread can call it. */ -TERM_API size_t term_scan_printable_span(const char *buf, size_t len, unsigned char hi); - -/* The instruction set level of the running code: "base", "avx2", "avx512", - * or "neon". On x86-64, the first term_new() picks the highest level the CPU - * supports. Set TERM_HEADLESS_ISA to a lower level to force it, for tests - * and comparisons. */ -TERM_API const char *term_isa(void); - -/* NULL when memory runs out or an option is invalid. */ -TERM_API struct term *term_new(const struct term_options *opt); -TERM_API void term_free(struct term *t); - -/* Hold the writer section across several calls, so that no other thread - * changes the terminal between them. The section is a mutex, and a waiting - * thread sleeps. Keep it short. The thread that holds it can call every - * function, and it can enter the section again. Each term_lock() needs one - * term_unlock(). */ -TERM_API void term_lock(struct term *t); -TERM_API void term_unlock(struct term *t); - -/* Change the size in cells. Returns false, and the terminal is unchanged, - * when a component is below 1, when cols is above TERM_MAX_COLS, or when - * memory runs out. The screen reflows to the new width. */ -TERM_API bool term_resize(struct term *t, struct term_vector2i size); - -/* Replace the theme. A different theme also drops the colors that the - * program set with OSC; the same theme changes nothing. */ -TERM_API void term_set_theme(struct term *t, const struct term_theme *theme); - -/* The cursor style that DECSCUSR 0 and a reset restore. */ -TERM_API void term_set_cursor_default(struct term *t, enum term_cursor_style style, bool steady); - -/* - * Bytes from the program. - * - * TERM_FEED_ONLCR: a line feed also returns the cursor to column 0, as a tty - * with OPOST and ONLCR does. Set it when the bytes did not pass through the - * tty output processing (for example the fast pipe). - */ -enum term_feed_flags { - TERM_FEED_ONLCR = 1u << 0, -}; - -/* - * Feed bytes from the program. Returns false, and changes nothing, when t is - * NULL, when bytes is NULL and len is not 0, or when flags has a bit that is - * not in enum term_feed_flags. A len of 0 is a no-op that returns true. - */ -TERM_API bool term_feed(struct term *t, const char *bytes, size_t len, unsigned flags); - -/* Report a focus change. The terminal replies only in focus-event mode. */ -TERM_API void term_focus(struct term *t, bool focused); - -/* Modes that affect how the application encodes input. */ -struct term_modes { - unsigned keyboard; /* kitty keyboard protocol flags */ - enum term_mouse mouse; - enum term_mouse_encoding mouse_encoding; - struct term_vector2i grid; /* columns and rows */ - bool app_cursor; /* DECCKM */ - bool app_keypad; /* DECKPAM */ - bool backarrow_bs; /* DECBKM */ - bool bracketed_paste; - bool focus_events; - bool alternate; /* the alternate screen is active */ - bool reverse_video; /* DECSCNM */ - bool synchronized; /* mode 2026 */ -}; - -struct term_cursor { - struct term_vector2i pos; - enum term_cursor_style style; - bool visible; - bool blink; -}; - -TERM_API struct term_vector2i term_size(const struct term *t); -TERM_API struct term_modes term_modes(const struct term *t); - -/* - * Encode an input event as the bytes the program expects. Get modes from - * term_modes(). Record ev in keyboard with term_keyboard_update() first. Send - * the bytes to the program yourself. - */ -TERM_API struct term_input_result term_input_encode_key( - const struct term_keyboard_state *keyboard, - const struct term_key_event *ev, - const struct term_modes *modes, - char *buf, size_t capacity -); - -TERM_API struct term_input_result term_input_encode_mouse( - const struct term_mouse_event *ev, - const struct term_modes *modes, - char *buf, size_t capacity -); - -/* Bytes term_input_encode_paste() adds to the text at most. */ -#define TERM_PASTE_EXTRA 12 - -/* - * Encode pasted text. Drop control characters and bidi controls, so the - * program sees only what the user saw. Send a line break as CR. Add the - * bracketed-paste markers when the program asked for them. A buffer of - * len + TERM_PASTE_EXTRA bytes is always large enough. Text that is empty - * after the filter gives TERM_INPUT_CONSUMED. - */ -TERM_API struct term_input_result term_input_encode_paste( - const struct term_modes *modes, - const char *text, size_t len, - char *buf, size_t capacity -); -/* The cursor in screen coordinates (not the viewport). */ -TERM_API struct term_cursor term_cursor(const struct term *t); -/* Owned, NUL-terminated text from OSC 7 and OSC 22. NULL when unavailable - * or allocation fails. The strings stay valid after the terminal changes - * or is freed. Release them with term_text_free(). */ -TERM_API char *term_cwd(const struct term *t); -TERM_API char *term_pointer_shape(const struct term *t); -/* Release any owned text returned by the library. NULL is safe. */ -TERM_API void term_text_free(char *text); - -/* - * Viewport. The viewport shows as many rows as the screen. Offset 0 shows - * the live screen; a larger offset shows that many rows of history above it. - * The alternate screen has no history, so its offset is always 0. - */ -struct term_scrollback { - int offset; /* rows between the viewport and the live screen */ - int total; /* history rows at the current width */ -}; - -TERM_API struct term_scrollback term_scrollback(const struct term *t); -/* Scroll the viewport. A positive count moves back into history. */ -TERM_API void term_scroll(struct term *t, int lines); -TERM_API void term_scroll_to(struct term *t, int offset); - -/* - * Selection, in viewport coordinates. A selection starts at one cell and - * extends to another; the unit widens both ends to words or whole lines. - * The terminal clears the selection when the text under it changes. - */ -enum term_select_unit { - TERM_SELECT_CELL, - TERM_SELECT_WORD, - TERM_SELECT_LINE, -}; - -/* Start a selection at cell. For TERM_SELECT_CELL, right_half means the - * pointer is on the right half of the cell, so the selection starts after it. - * Returns false when memory runs out; the selection is then unchanged. */ -TERM_API bool term_select_start(struct term *t, struct term_vector2i cell, bool right_half, - enum term_select_unit unit); -/* Extend the selection from its start to cell. Returns false when memory runs - * out; the selection is then unchanged. */ -TERM_API bool term_select_extend(struct term *t, struct term_vector2i cell, bool right_half); -TERM_API void term_select_clear(struct term *t); -TERM_API bool term_has_selection(const struct term *t); -/* Owned, NUL-terminated UTF-8 of the selection. NULL when nothing is - * selected or allocation fails; a selection of blanks may produce an empty - * string. Capture is atomic with respect to other calls on t. Release the - * result with term_text_free(). */ -TERM_API char *term_selection_text(const struct term *t); -/* Owned OSC 8 link or detected URL at a viewport cell. NULL when there is - * no link or allocation fails. Release the result with term_text_free(). */ -TERM_API char *term_link_at(const struct term *t, struct term_vector2i cell); - -/* Cell attributes share the write core's bit layout. Underline styles are - * mutually exclusive flags, not a shifted enum; use term_attr_underline(). */ -enum term_attr { - TERM_ATTR_BOLD = 1u << 0, - TERM_ATTR_ITALIC = 1u << 1, - TERM_ATTR_UNDERLINE = 1u << 2, - TERM_ATTR_STRIKE = 1u << 3, - TERM_ATTR_OVERLINE = 1u << 4, - TERM_ATTR_EMOJI = 1u << 5, /* the text requested emoji presentation */ - TERM_ATTR_TEXT = 1u << 6, /* the text requested text presentation */ - TERM_ATTR_FAINT = 1u << 10, - TERM_ATTR_DOUBLE_UNDERLINE = 1u << 11, - TERM_ATTR_CURLY_UNDERLINE = 1u << 12, - TERM_ATTR_DOTTED_UNDERLINE = 1u << 13, - TERM_ATTR_DASHED_UNDERLINE = 1u << 14, - TERM_ATTR_LINK = 1u << 15, -}; - -#define TERM_ATTR_UNDERLINE_MASK \ - (TERM_ATTR_UNDERLINE | TERM_ATTR_DOUBLE_UNDERLINE | TERM_ATTR_CURLY_UNDERLINE | \ - TERM_ATTR_DOTTED_UNDERLINE | TERM_ATTR_DASHED_UNDERLINE) - -enum term_underline { - TERM_UNDERLINE_NONE, - TERM_UNDERLINE_SINGLE, - TERM_UNDERLINE_DOUBLE, - TERM_UNDERLINE_CURLY, - TERM_UNDERLINE_DOTTED, - TERM_UNDERLINE_DASHED, -}; - -static inline enum term_underline term_attr_underline(uint16_t attrs) -{ - if (attrs & TERM_ATTR_DOUBLE_UNDERLINE) return TERM_UNDERLINE_DOUBLE; - if (attrs & TERM_ATTR_CURLY_UNDERLINE) return TERM_UNDERLINE_CURLY; - if (attrs & TERM_ATTR_DOTTED_UNDERLINE) return TERM_UNDERLINE_DOTTED; - if (attrs & TERM_ATTR_DASHED_UNDERLINE) return TERM_UNDERLINE_DASHED; - return attrs & TERM_ATTR_UNDERLINE ? TERM_UNDERLINE_SINGLE : TERM_UNDERLINE_NONE; -} - -/* text refers to a grapheme cluster in the snapshot; see term_snapshot_cluster(). */ -#define TERM_TEXT_CLUSTER 0x80000000u - -/* One cell as a snapshot shows it. */ -struct term_cell { - uint32_t text; /* a code point, TERM_TEXT_CLUSTER | n, or 0 for an empty cell */ - term_color fg, bg; - uint16_t attrs; /* enum term_attr flags; at most one underline flag */ - uint8_t width; /* 1; 2 for a wide glyph; 0 for the right half of a wide glyph */ - uint8_t reserved; -}; - -#ifdef __cplusplus -static_assert(sizeof(struct term_cell) == 16, "four cells fill one 64-byte line"); -#else -_Static_assert(sizeof(struct term_cell) == 16, "four cells fill one 64-byte line"); -#endif - -/* - * Snapshot: a copy of the viewport for a renderer. It holds no pointer into - * the terminal, so it stays valid while the terminal changes. One terminal - * may have several snapshots, for example a window and a tab preview. - */ -TERM_API struct term_snapshot *term_snapshot_new(void); -TERM_API void term_snapshot_free(struct term_snapshot *s); - -/* Copy the viewport of t into s. Keep rows with unchanged content keys. - * Update the history view index and refine counts for visible wide lines. - * Return false when memory runs out. The snapshot then keeps its previous content. */ -TERM_API bool term_snapshot_update(struct term_snapshot *s, struct term *t); - -/* Palette entries of struct term_view.palette after the 256 indexed colors. */ -enum { - TERM_PALETTE_FG = 256, - TERM_PALETTE_BG = 257, - TERM_PALETTE_CURSOR = 258, - TERM_PALETTE_SIZE = 259, -}; - -struct term_view { - struct term_vector2i size; - struct term_cursor cursor; /* viewport coordinates; not visible when scrolled away */ - int scroll_offset; - /* Rows the content moved up since the previous update, when that movement - * explains the change; otherwise 0. */ - int scrolled; - bool reverse_video; - /* Changes when any part of the view changes. */ - uint64_t version; - /* Changes when a palette entry changes. */ - uint64_t palette_version; - const uint32_t *palette; /* TERM_PALETTE_SIZE ARGB entries */ -}; - -/* The view of s, NULL for a NULL s. The view and view->palette keep their - * address until term_snapshot_free(); their contents change on each update. */ -TERM_API const struct term_view *term_snapshot_view(const struct term_snapshot *s); -/* The cells of viewport row y: view->size.x entries. NULL when y is outside - * the viewport or s is NULL. An update can move the cells, so the pointer is - * valid only until the next term_snapshot_update() or term_snapshot_free() of s. */ -TERM_API const struct term_cell *term_snapshot_row(const struct term_snapshot *s, int y); -/* An identity for the content of row y. Two rows with the same key hold the - * same cells, also when the content moved to another row. 0 when y is outside - * the viewport or s is NULL. */ -TERM_API uint64_t term_snapshot_row_key(const struct term_snapshot *s, int y); - -/* Number of rows in history above the screen. 0 if alternate screen or no history. */ -TERM_API int term_history_rows(const struct term *t); -/* Owned, NUL-terminated UTF-8 of up to max_rows history rows before the - * current viewport. Join soft-wrapped rows and end closed lines with a - * newline. Does not change the selection. No history or max_rows <= 0 gives - * an empty string; NULL means allocation failed or t is NULL. Release the - * result with term_text_free(). */ -TERM_API char *term_history_text(struct term *t, int max_rows); -/* The selected columns of viewport row y, end exclusive. An empty span when y - * is outside the viewport or s is NULL. */ -TERM_API struct term_span term_snapshot_row_selection(const struct term_snapshot *s, int y); - -/* The code points of a cluster cell. Returns the number of code points and - * writes at most cap of them. Writes nothing when cps is NULL or cap is 0. - * Returns 0 when s is NULL. */ -TERM_API int term_snapshot_cluster(const struct term_snapshot *s, uint32_t text, uint32_t *cps, int cap); - -/* The ARGB value of a color in a view. */ -static inline uint32_t term_view_color(const struct term_view *v, term_color c) -{ - if (!term_color_is_slot(c)) - return c; - return v->palette[c & TERM_COLOR_SLOT_INDEX]; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/term/term_input.h b/include/term/term_input.h deleted file mode 100644 index 19d9355..0000000 --- a/include/term/term_input.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef TERM_INPUT_H -#define TERM_INPUT_H - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> -#include "term_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum term_key { - TERM_KEY_NONE = 0, - - TERM_KEY_RETURN, - TERM_KEY_BACKSPACE, - TERM_KEY_TAB, - TERM_KEY_ESCAPE, - - TERM_KEY_UP, - TERM_KEY_DOWN, - TERM_KEY_RIGHT, - TERM_KEY_LEFT, - TERM_KEY_HOME, - TERM_KEY_END, - TERM_KEY_PAGE_UP, - TERM_KEY_PAGE_DOWN, - TERM_KEY_INSERT, - TERM_KEY_DELETE, - - TERM_KEY_F1, TERM_KEY_F2, TERM_KEY_F3, TERM_KEY_F4, TERM_KEY_F5, - TERM_KEY_F6, TERM_KEY_F7, TERM_KEY_F8, TERM_KEY_F9, TERM_KEY_F10, - TERM_KEY_F11, TERM_KEY_F12, TERM_KEY_F13, TERM_KEY_F14, TERM_KEY_F15, - TERM_KEY_F16, TERM_KEY_F17, TERM_KEY_F18, TERM_KEY_F19, TERM_KEY_F20, - TERM_KEY_F21, TERM_KEY_F22, TERM_KEY_F23, TERM_KEY_F24, TERM_KEY_F25, - TERM_KEY_F26, TERM_KEY_F27, TERM_KEY_F28, TERM_KEY_F29, TERM_KEY_F30, - TERM_KEY_F31, TERM_KEY_F32, TERM_KEY_F33, TERM_KEY_F34, TERM_KEY_F35, - - TERM_KEY_KP_0, TERM_KEY_KP_1, TERM_KEY_KP_2, TERM_KEY_KP_3, TERM_KEY_KP_4, - TERM_KEY_KP_5, TERM_KEY_KP_6, TERM_KEY_KP_7, TERM_KEY_KP_8, TERM_KEY_KP_9, - TERM_KEY_KP_DECIMAL, - TERM_KEY_KP_ENTER, - TERM_KEY_KP_ADD, - TERM_KEY_KP_SUBTRACT, - TERM_KEY_KP_MULTIPLY, - TERM_KEY_KP_DIVIDE, - TERM_KEY_KP_EQUAL, - TERM_KEY_KP_SEPARATOR, - TERM_KEY_KP_LEFT, - TERM_KEY_KP_RIGHT, - TERM_KEY_KP_UP, - TERM_KEY_KP_DOWN, - TERM_KEY_KP_PAGE_UP, - TERM_KEY_KP_PAGE_DOWN, - TERM_KEY_KP_HOME, - TERM_KEY_KP_END, - TERM_KEY_KP_INSERT, - TERM_KEY_KP_DELETE, - TERM_KEY_KP_BEGIN, - - TERM_KEY_CAPS_LOCK, - TERM_KEY_SCROLL_LOCK, - TERM_KEY_NUM_LOCK, - TERM_KEY_PRINT_SCREEN, - TERM_KEY_PAUSE, - TERM_KEY_MENU, - - TERM_KEY_MEDIA_PLAY, - TERM_KEY_MEDIA_PAUSE, - TERM_KEY_MEDIA_STOP, - TERM_KEY_MEDIA_FORWARD, - TERM_KEY_MEDIA_REWIND, - TERM_KEY_MEDIA_NEXT, - TERM_KEY_MEDIA_PREV, - TERM_KEY_MEDIA_RECORD, - TERM_KEY_VOLUME_DOWN, - TERM_KEY_VOLUME_UP, - TERM_KEY_MUTE, - - TERM_KEY_LSHIFT, - TERM_KEY_LCTRL, - TERM_KEY_LALT, - TERM_KEY_LSUPER, - TERM_KEY_LHYPER, - TERM_KEY_LMETA, - TERM_KEY_RSHIFT, - TERM_KEY_RCTRL, - TERM_KEY_RALT, - TERM_KEY_RSUPER, - TERM_KEY_RHYPER, - TERM_KEY_RMETA, - TERM_KEY_ISO_LEVEL3_SHIFT, - TERM_KEY_ISO_LEVEL5_SHIFT, - - TERM_KEY_COUNT -}; - -enum term_mod { - TERM_MOD_SHIFT = 1, - TERM_MOD_ALT = 2, - TERM_MOD_CTRL = 4, - TERM_MOD_SUPER = 8, - TERM_MOD_HYPER = 16, - TERM_MOD_META = 32, - TERM_MOD_CAPS = 64, - TERM_MOD_NUM = 128, -}; - -enum term_key_action { - TERM_KEY_PRESS = 1, - TERM_KEY_REPEAT = 2, - TERM_KEY_RELEASE = 3, -}; - -enum term_mouse_button { - TERM_MOUSE_BUTTON_PRIMARY = 0, - TERM_MOUSE_BUTTON_MIDDLE, - TERM_MOUSE_BUTTON_SECONDARY, - TERM_MOUSE_BUTTON_NONE, - /* Extra buttons 8 through 11 in xterm mouse reporting (encoded as 128..131). */ - TERM_MOUSE_BUTTON_EXTRA_1, - TERM_MOUSE_BUTTON_EXTRA_2, - TERM_MOUSE_BUTTON_EXTRA_3, - TERM_MOUSE_BUTTON_EXTRA_4, - TERM_MOUSE_WHEEL_UP = 16, - TERM_MOUSE_WHEEL_DOWN, - TERM_MOUSE_WHEEL_LEFT, - TERM_MOUSE_WHEEL_RIGHT, -}; - -enum term_mouse_event_kind { - TERM_MOUSE_PRESS = 0, - TERM_MOUSE_RELEASE, - TERM_MOUSE_MOTION, - TERM_MOUSE_SCROLL, - TERM_MOUSE_LEAVE, -}; - -struct term_key_event { - enum term_key_action action; - uint16_t key; /* enum term_key; TERM_KEY_NONE for a text key */ - uint16_t keypad; /* the TERM_KEY_KP_* key when the key is on the keypad */ - unsigned mods; /* enum term_mod */ - uint32_t codepoint; /* the code point of the key without modifiers */ - uint32_t shifted; /* the code point of the key with Shift */ - uint32_t base; /* the code point of the key in the US layout */ - uint32_t text; /* the code point the key types, or 0 */ - bool text_deferred; /* an input method sends the text later */ -}; - -struct term_mouse_event { - struct term_vector2i pos; /* Grid cell coordinates (col, row) */ - struct term_vector2i pixel; /* Absolute pixel position in terminal grid */ - /* - * Button identifier: - * - Press and release: the button that changed state (TERM_MOUSE_BUTTON_*). - * - Motion: the held button for drag events, or TERM_MOUSE_BUTTON_NONE for hover. - * - Scroll: the wheel direction (TERM_MOUSE_WHEEL_*). - */ - int button; - unsigned mods; - int scroll_lines; - float scroll_delta; - enum term_mouse_event_kind kind; -}; - -/* The keys that are down. An all-zero value has no keys down. */ -struct term_keyboard_state { - uint64_t down[(TERM_KEY_COUNT + 63) / 64]; -}; - -/* Record a press, repeat, or release in s. */ -TERM_API void term_keyboard_update(struct term_keyboard_state *s, const struct term_key_event *ev); -TERM_API bool term_keyboard_key_down(const struct term_keyboard_state *s, enum term_key key); - -/* Kitty keyboard protocol flags, as in term_modes.keyboard. */ -enum term_keyboard_flag { - TERM_KEYBOARD_DISAMBIGUATE = 1, - TERM_KEYBOARD_EVENT_TYPES = 2, - TERM_KEYBOARD_ALTERNATE_KEYS = 4, - TERM_KEYBOARD_ALL_KEYS = 8, - TERM_KEYBOARD_ASSOCIATED_TEXT = 16, -}; - -enum term_input_status { - TERM_INPUT_UNHANDLED = 0, /* the terminal does not use the event */ - TERM_INPUT_CONSUMED, /* the terminal uses the event but sends nothing */ - TERM_INPUT_BYTES, /* send the len bytes in buf to the program */ - TERM_INPUT_BUFFER_FULL, /* buf is too small; len is 0 */ -}; - -struct term_input_result { - size_t len; - enum term_input_status status; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* TERM_INPUT_H */ diff --git a/include/term/term_types.h b/include/term/term_types.h deleted file mode 100644 index 78be371..0000000 --- a/include/term/term_types.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef TERM_TYPES_H -#define TERM_TYPES_H - -/* Marks the public functions. The library builds with hidden symbols, so - * only these are visible outside a shared build. A host can define it - * first, for example as __declspec(dllimport). */ -#ifndef TERM_API -#if defined(__GNUC__) || defined(__clang__) -#define TERM_API __attribute__((visibility("default"))) -#else -#define TERM_API -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -struct term_vector2i { - int x, y; -}; - -struct term_span { - int begin; - int end; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/term/unicode/grapheme.h b/include/term/unicode/grapheme.h deleted file mode 100644 index 0946bb6..0000000 --- a/include/term/unicode/grapheme.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TERM_UNICODE_GRAPHEME_H -#define TERM_UNICODE_GRAPHEME_H - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -#define TERM_GRAPHEME_MAX_LEN 20 -#define TERM_GRAPHEME_HANDLE_BASE 0x7F000000u - -static inline bool term_grapheme_is_handle(uint32_t c) -{ - return c >= TERM_GRAPHEME_HANDLE_BASE; -} - -static inline bool term_grapheme_regional_indicator(uint32_t cp) -{ - return cp >= 0x1F1E6 && cp <= 0x1F1FF; -} - -static inline bool term_grapheme_emoji_modifier(uint32_t cp) -{ - return cp >= 0x1F3FB && cp <= 0x1F3FF; -} - -#endif diff --git a/include/term/unicode/unicode.h b/include/term/unicode/unicode.h deleted file mode 100644 index 932cbf6..0000000 --- a/include/term/unicode/unicode.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef TERM_UNICODE_UNICODE_H -#define TERM_UNICODE_UNICODE_H - -#include "width.h" - -#endif diff --git a/include/term/unicode/unicode_data.inc b/include/term/unicode/unicode_data.inc deleted file mode 100644 index 4ab1461..0000000 --- a/include/term/unicode/unicode_data.inc +++ /dev/null @@ -1,258 +0,0 @@ -/* Generated from Unicode 18.0.0 data by tools/generate_unicode.py. */ - -#define TERM_UNICODE_DATA_VERSION "18.0.0" - -static const struct term_unicode_range term_zero_width[] = { - {0xAD,0xAD},{0x300,0x36F},{0x483,0x489},{0x591,0x5BD}, - {0x5BF,0x5BF},{0x5C1,0x5C2},{0x5C4,0x5C5},{0x5C7,0x5C9}, - {0x600,0x605},{0x610,0x61A},{0x61C,0x61C},{0x64B,0x65F}, - {0x670,0x670},{0x6D6,0x6DD},{0x6DF,0x6E4},{0x6E7,0x6E8}, - {0x6EA,0x6ED},{0x70F,0x70F},{0x711,0x711},{0x730,0x74A}, - {0x7A6,0x7B0},{0x7EB,0x7F3},{0x7FD,0x7FD},{0x816,0x819}, - {0x81B,0x823},{0x825,0x827},{0x829,0x82D},{0x859,0x85B}, - {0x890,0x891},{0x897,0x89F},{0x8CA,0x902},{0x93A,0x93A}, - {0x93C,0x93C},{0x941,0x948},{0x94D,0x94D},{0x951,0x957}, - {0x962,0x963},{0x981,0x981},{0x9BC,0x9BC},{0x9C1,0x9C4}, - {0x9CD,0x9CD},{0x9E2,0x9E3},{0x9FE,0x9FE},{0xA01,0xA02}, - {0xA3C,0xA3C},{0xA41,0xA42},{0xA47,0xA48},{0xA4B,0xA4D}, - {0xA51,0xA51},{0xA70,0xA71},{0xA75,0xA75},{0xA81,0xA82}, - {0xABC,0xABC},{0xAC1,0xAC5},{0xAC7,0xAC8},{0xACD,0xACD}, - {0xAE2,0xAE3},{0xAFA,0xAFF},{0xB01,0xB01},{0xB3C,0xB3C}, - {0xB3F,0xB3F},{0xB41,0xB44},{0xB4D,0xB4D},{0xB53,0xB56}, - {0xB62,0xB63},{0xB82,0xB82},{0xBC0,0xBC0},{0xBCD,0xBCD}, - {0xC00,0xC00},{0xC04,0xC04},{0xC3C,0xC3C},{0xC3E,0xC40}, - {0xC46,0xC48},{0xC4A,0xC4D},{0xC55,0xC56},{0xC62,0xC63}, - {0xC81,0xC81},{0xCBC,0xCBC},{0xCBF,0xCBF},{0xCC6,0xCC6}, - {0xCCC,0xCCD},{0xCE2,0xCE3},{0xD00,0xD01},{0xD3B,0xD3C}, - {0xD41,0xD44},{0xD4D,0xD4D},{0xD62,0xD63},{0xD81,0xD81}, - {0xDCA,0xDCA},{0xDD2,0xDD4},{0xDD6,0xDD6},{0xE31,0xE31}, - {0xE34,0xE3A},{0xE47,0xE4E},{0xEB1,0xEB1},{0xEB4,0xEBC}, - {0xEC8,0xECE},{0xF18,0xF19},{0xF35,0xF35},{0xF37,0xF37}, - {0xF39,0xF39},{0xF71,0xF7E},{0xF80,0xF84},{0xF86,0xF87}, - {0xF8D,0xF97},{0xF99,0xFBC},{0xFC6,0xFC6},{0x102D,0x1030}, - {0x1032,0x1037},{0x1039,0x103A},{0x103D,0x103E},{0x1058,0x1059}, - {0x105E,0x1060},{0x1071,0x1074},{0x1082,0x1082},{0x1085,0x1086}, - {0x108D,0x108D},{0x109D,0x109D},{0x1160,0x11FF},{0x135D,0x135F}, - {0x1712,0x1714},{0x1732,0x1733},{0x1752,0x1753},{0x1772,0x1773}, - {0x17B4,0x17B5},{0x17B7,0x17BD},{0x17C6,0x17C6},{0x17C9,0x17D3}, - {0x17DD,0x17DD},{0x180B,0x180F},{0x1885,0x1886},{0x18A9,0x18A9}, - {0x1920,0x1922},{0x1927,0x1928},{0x1932,0x1932},{0x1939,0x193B}, - {0x1A17,0x1A18},{0x1A1B,0x1A1B},{0x1A56,0x1A56},{0x1A58,0x1A5E}, - {0x1A60,0x1A60},{0x1A62,0x1A62},{0x1A65,0x1A6C},{0x1A73,0x1A7C}, - {0x1A7F,0x1A7F},{0x1AB0,0x1AF0},{0x1B00,0x1B03},{0x1B34,0x1B34}, - {0x1B36,0x1B3A},{0x1B3C,0x1B3C},{0x1B42,0x1B42},{0x1B6B,0x1B73}, - {0x1B80,0x1B81},{0x1BA2,0x1BA5},{0x1BA8,0x1BA9},{0x1BAB,0x1BAD}, - {0x1BE6,0x1BE6},{0x1BE8,0x1BE9},{0x1BED,0x1BED},{0x1BEF,0x1BF1}, - {0x1C2C,0x1C33},{0x1C36,0x1C37},{0x1CD0,0x1CD2},{0x1CD4,0x1CE0}, - {0x1CE2,0x1CE8},{0x1CED,0x1CED},{0x1CF4,0x1CF4},{0x1CF8,0x1CF9}, - {0x1DC0,0x1DFF},{0x200B,0x200F},{0x202A,0x202E},{0x2060,0x2064}, - {0x2066,0x206F},{0x20D0,0x20F0},{0x2CEF,0x2CF1},{0x2D7F,0x2D7F}, - {0x2DE0,0x2DFF},{0x302A,0x302D},{0x3099,0x309A},{0xA66F,0xA672}, - {0xA674,0xA67D},{0xA69E,0xA69F},{0xA6F0,0xA6F1},{0xA802,0xA802}, - {0xA806,0xA806},{0xA80B,0xA80B},{0xA825,0xA826},{0xA82C,0xA82C}, - {0xA8C4,0xA8C5},{0xA8E0,0xA8F1},{0xA8FF,0xA8FF},{0xA926,0xA92D}, - {0xA947,0xA951},{0xA980,0xA982},{0xA9B3,0xA9B3},{0xA9B6,0xA9B9}, - {0xA9BC,0xA9BD},{0xA9E5,0xA9E5},{0xAA29,0xAA2E},{0xAA31,0xAA32}, - {0xAA35,0xAA36},{0xAA43,0xAA43},{0xAA4C,0xAA4C},{0xAA7C,0xAA7C}, - {0xAAB0,0xAAB0},{0xAAB2,0xAAB4},{0xAAB7,0xAAB8},{0xAABE,0xAABF}, - {0xAAC1,0xAAC1},{0xAAEC,0xAAED},{0xAAF6,0xAAF6},{0xABE5,0xABE5}, - {0xABE8,0xABE8},{0xABED,0xABED},{0xD7B0,0xD7C6},{0xD7CB,0xD7FB}, - {0xFB1E,0xFB1E},{0xFE00,0xFE0F},{0xFE20,0xFE2F},{0xFEFF,0xFEFF}, - {0xFFF9,0xFFFB},{0x101FD,0x101FD},{0x102E0,0x102E0},{0x10376,0x1037A}, - {0x10A01,0x10A03},{0x10A05,0x10A06},{0x10A0C,0x10A0F},{0x10A38,0x10A3A}, - {0x10A3F,0x10A3F},{0x10AE5,0x10AE6},{0x10D24,0x10D27},{0x10D69,0x10D6D}, - {0x10EAB,0x10EAC},{0x10ECB,0x10ECF},{0x10EF0,0x10EFF},{0x10F46,0x10F50}, - {0x10F82,0x10F85},{0x11001,0x11001},{0x11038,0x11046},{0x11070,0x11070}, - {0x11073,0x11074},{0x1107F,0x11081},{0x110B3,0x110B6},{0x110B9,0x110BA}, - {0x110BD,0x110BD},{0x110C2,0x110C2},{0x110CD,0x110CD},{0x11100,0x11102}, - {0x11127,0x1112B},{0x1112D,0x11134},{0x11173,0x11173},{0x11180,0x11181}, - {0x111B6,0x111BE},{0x111C9,0x111CC},{0x111CF,0x111CF},{0x1122F,0x11231}, - {0x11234,0x11234},{0x11236,0x11237},{0x1123E,0x1123E},{0x11241,0x11241}, - {0x112DF,0x112DF},{0x112E3,0x112EA},{0x11300,0x11301},{0x1133B,0x1133C}, - {0x11340,0x11340},{0x11366,0x1136C},{0x11370,0x11374},{0x113BB,0x113C0}, - {0x113CE,0x113CE},{0x113D0,0x113D0},{0x113D2,0x113D2},{0x113E1,0x113E2}, - {0x11438,0x1143F},{0x11442,0x11444},{0x11446,0x11446},{0x1145E,0x1145E}, - {0x114B3,0x114B8},{0x114BA,0x114BA},{0x114BF,0x114C0},{0x114C2,0x114C3}, - {0x115B2,0x115B5},{0x115BC,0x115BD},{0x115BF,0x115C0},{0x115DC,0x115DD}, - {0x11633,0x1163A},{0x1163D,0x1163D},{0x1163F,0x11640},{0x116AB,0x116AB}, - {0x116AD,0x116AD},{0x116B0,0x116B5},{0x116B7,0x116B7},{0x1171D,0x1171D}, - {0x1171F,0x1171F},{0x11722,0x11725},{0x11727,0x1172B},{0x1182F,0x11837}, - {0x11839,0x1183A},{0x1193B,0x1193C},{0x1193E,0x1193E},{0x11943,0x11943}, - {0x119D4,0x119D7},{0x119DA,0x119DB},{0x119E0,0x119E0},{0x11A01,0x11A0A}, - {0x11A33,0x11A38},{0x11A3B,0x11A3E},{0x11A47,0x11A47},{0x11A51,0x11A56}, - {0x11A59,0x11A5B},{0x11A8A,0x11A96},{0x11A98,0x11A99},{0x11B60,0x11B60}, - {0x11B62,0x11B64},{0x11B66,0x11B66},{0x11C30,0x11C36},{0x11C38,0x11C3D}, - {0x11C3F,0x11C3F},{0x11C92,0x11CA7},{0x11CAA,0x11CB0},{0x11CB2,0x11CB3}, - {0x11CB5,0x11CB6},{0x11D31,0x11D36},{0x11D3A,0x11D3A},{0x11D3C,0x11D3D}, - {0x11D3F,0x11D45},{0x11D47,0x11D47},{0x11D90,0x11D91},{0x11D95,0x11D95}, - {0x11D97,0x11D97},{0x11DF0,0x11DF0},{0x11EF3,0x11EF4},{0x11F00,0x11F01}, - {0x11F36,0x11F3A},{0x11F40,0x11F40},{0x11F42,0x11F42},{0x11F5A,0x11F5A}, - {0x13430,0x13440},{0x13447,0x13455},{0x1611E,0x16129},{0x1612D,0x1612F}, - {0x16AF0,0x16AF4},{0x16B30,0x16B36},{0x16F4F,0x16F4F},{0x16F8F,0x16F92}, - {0x16FE4,0x16FE4},{0x1BC9D,0x1BC9E},{0x1BCA0,0x1BCA3},{0x1CF00,0x1CF2D}, - {0x1CF30,0x1CF46},{0x1D127,0x1D128},{0x1D167,0x1D169},{0x1D173,0x1D182}, - {0x1D185,0x1D18B},{0x1D1AA,0x1D1AD},{0x1D242,0x1D244},{0x1D25B,0x1D25C}, - {0x1DA00,0x1DA36},{0x1DA3B,0x1DA6C},{0x1DA75,0x1DA75},{0x1DA84,0x1DA84}, - {0x1DA9B,0x1DA9F},{0x1DAA1,0x1DAAF},{0x1E000,0x1E006},{0x1E008,0x1E018}, - {0x1E01B,0x1E021},{0x1E023,0x1E024},{0x1E026,0x1E02A},{0x1E08F,0x1E08F}, - {0x1E130,0x1E136},{0x1E2AE,0x1E2AE},{0x1E2EC,0x1E2EF},{0x1E4EC,0x1E4EF}, - {0x1E5EE,0x1E5EF},{0x1E6E3,0x1E6E3},{0x1E6E6,0x1E6E6},{0x1E6EE,0x1E6EF}, - {0x1E6F5,0x1E6F5},{0x1E8D0,0x1E8D6},{0x1E944,0x1E94A},{0xE0001,0xE0001}, - {0xE0020,0xE007F},{0xE0100,0xE01EF}, -}; - -static const struct term_unicode_range term_nonprintable[] = { - {0x0,0x1F},{0x7F,0x9F},{0xD800,0xDFFF}, -}; - -static const struct term_unicode_range term_unicode_wide[] = { - {0x1100,0x115F},{0x231A,0x231B},{0x2329,0x232A},{0x23E9,0x23EC}, - {0x23F0,0x23F0},{0x23F3,0x23F3},{0x25FD,0x25FE},{0x2614,0x2615}, - {0x2630,0x2637},{0x2648,0x2653},{0x267F,0x267F},{0x268A,0x268F}, - {0x2693,0x2693},{0x26A1,0x26A1},{0x26AA,0x26AB},{0x26BD,0x26BE}, - {0x26C4,0x26C5},{0x26CE,0x26CE},{0x26D4,0x26D4},{0x26EA,0x26EA}, - {0x26F2,0x26F3},{0x26F5,0x26F5},{0x26FA,0x26FA},{0x26FD,0x26FD}, - {0x2705,0x2705},{0x270A,0x270B},{0x2728,0x2728},{0x274C,0x274C}, - {0x274E,0x274E},{0x2753,0x2755},{0x2757,0x2757},{0x2795,0x2797}, - {0x27B0,0x27B0},{0x27BF,0x27BF},{0x2B1B,0x2B1C},{0x2B50,0x2B50}, - {0x2B55,0x2B55},{0x2E80,0x2E99},{0x2E9B,0x2EF3},{0x2F00,0x2FD5}, - {0x2FF0,0x303E},{0x3041,0x3096},{0x3099,0x30FF},{0x3105,0x312F}, - {0x3131,0x318E},{0x3190,0x31E5},{0x31EF,0x321E},{0x3220,0x3247}, - {0x3250,0xA48C},{0xA490,0xA4C6},{0xA960,0xA97C},{0xAC00,0xD7A3}, - {0xF900,0xFAFF},{0xFE10,0xFE19},{0xFE30,0xFE52},{0xFE54,0xFE66}, - {0xFE68,0xFE6B},{0xFF01,0xFF60},{0xFFE0,0xFFE6},{0x16FE0,0x16FE4}, - {0x16FF0,0x16FF6},{0x17000,0x18CDA},{0x18CFF,0x18D20},{0x18D80,0x18DF2}, - {0x18E00,0x19191},{0x191A0,0x191D2},{0x1AFF0,0x1AFF3},{0x1AFF5,0x1AFFB}, - {0x1AFFD,0x1AFFE},{0x1B000,0x1B128},{0x1B132,0x1B132},{0x1B150,0x1B152}, - {0x1B155,0x1B155},{0x1B164,0x1B168},{0x1B170,0x1B2FB},{0x1D300,0x1D356}, - {0x1D360,0x1D376},{0x1F004,0x1F004},{0x1F0CF,0x1F0CF},{0x1F18E,0x1F18E}, - {0x1F191,0x1F19A},{0x1F1AE,0x1F1AE},{0x1F200,0x1F202},{0x1F210,0x1F23B}, - {0x1F240,0x1F248},{0x1F250,0x1F251},{0x1F260,0x1F265},{0x1F300,0x1F320}, - {0x1F32D,0x1F335},{0x1F337,0x1F37C},{0x1F37E,0x1F393},{0x1F3A0,0x1F3CA}, - {0x1F3CF,0x1F3D3},{0x1F3E0,0x1F3F0},{0x1F3F4,0x1F3F4},{0x1F3F8,0x1F43E}, - {0x1F440,0x1F440},{0x1F442,0x1F4FC},{0x1F4FF,0x1F53D},{0x1F54B,0x1F54E}, - {0x1F550,0x1F567},{0x1F57A,0x1F57A},{0x1F595,0x1F596},{0x1F5A4,0x1F5A4}, - {0x1F5FB,0x1F64F},{0x1F680,0x1F6C5},{0x1F6CC,0x1F6CC},{0x1F6D0,0x1F6D2}, - {0x1F6D5,0x1F6D9},{0x1F6DC,0x1F6DF},{0x1F6EB,0x1F6EC},{0x1F6F4,0x1F6FC}, - {0x1F7DA,0x1F7DA},{0x1F7E0,0x1F7EB},{0x1F7F0,0x1F7F0},{0x1F90C,0x1F93A}, - {0x1F93C,0x1F945},{0x1F947,0x1F9FF},{0x1FA70,0x1FA7C},{0x1FA80,0x1FAC6}, - {0x1FAC8,0x1FAC8},{0x1FACC,0x1FADD},{0x1FADF,0x1FAEB},{0x1FAEF,0x1FAFA}, - {0x20000,0x2FFFD},{0x30000,0x3FFFD}, -}; - -static const struct term_unicode_range term_spacing_mark[] = { - {0x903,0x903},{0x93B,0x93B},{0x93E,0x940},{0x949,0x94C}, - {0x94E,0x94F},{0x982,0x983},{0x9BE,0x9C0},{0x9C7,0x9C8}, - {0x9CB,0x9CC},{0x9D7,0x9D7},{0xA03,0xA03},{0xA3E,0xA40}, - {0xA83,0xA83},{0xABE,0xAC0},{0xAC9,0xAC9},{0xACB,0xACC}, - {0xB02,0xB03},{0xB3E,0xB3E},{0xB40,0xB40},{0xB47,0xB48}, - {0xB4B,0xB4C},{0xB57,0xB57},{0xBBE,0xBBF},{0xBC1,0xBC2}, - {0xBC6,0xBC8},{0xBCA,0xBCC},{0xBD7,0xBD7},{0xC01,0xC03}, - {0xC41,0xC44},{0xC82,0xC83},{0xCBE,0xCBE},{0xCC0,0xCC4}, - {0xCC7,0xCC8},{0xCCA,0xCCB},{0xCD5,0xCD6},{0xCF3,0xCF3}, - {0xD02,0xD03},{0xD3E,0xD40},{0xD46,0xD48},{0xD4A,0xD4C}, - {0xD57,0xD57},{0xD82,0xD83},{0xDCF,0xDD1},{0xDD8,0xDDF}, - {0xDF2,0xDF3},{0xF3E,0xF3F},{0xF7F,0xF7F},{0x102B,0x102C}, - {0x1031,0x1031},{0x1038,0x1038},{0x103B,0x103C},{0x1056,0x1057}, - {0x1062,0x1064},{0x1067,0x106D},{0x1083,0x1084},{0x1087,0x108C}, - {0x108F,0x108F},{0x109A,0x109C},{0x1715,0x1715},{0x1734,0x1734}, - {0x17B6,0x17B6},{0x17BE,0x17C5},{0x17C7,0x17C8},{0x1923,0x1926}, - {0x1929,0x192B},{0x1930,0x1931},{0x1933,0x1938},{0x1A19,0x1A1A}, - {0x1A55,0x1A55},{0x1A57,0x1A57},{0x1A61,0x1A61},{0x1A63,0x1A64}, - {0x1A6D,0x1A72},{0x1B04,0x1B04},{0x1B35,0x1B35},{0x1B3B,0x1B3B}, - {0x1B3D,0x1B41},{0x1B43,0x1B44},{0x1B82,0x1B82},{0x1BA1,0x1BA1}, - {0x1BA6,0x1BA7},{0x1BAA,0x1BAA},{0x1BE7,0x1BE7},{0x1BEA,0x1BEC}, - {0x1BEE,0x1BEE},{0x1BF2,0x1BF3},{0x1C24,0x1C2B},{0x1C34,0x1C35}, - {0x1CE1,0x1CE1},{0x1CF7,0x1CF7},{0x302E,0x302F},{0xA823,0xA824}, - {0xA827,0xA827},{0xA880,0xA881},{0xA8B4,0xA8C3},{0xA952,0xA953}, - {0xA983,0xA983},{0xA9B4,0xA9B5},{0xA9BA,0xA9BB},{0xA9BE,0xA9C0}, - {0xAA2F,0xAA30},{0xAA33,0xAA34},{0xAA4D,0xAA4D},{0xAA7B,0xAA7B}, - {0xAA7D,0xAA7D},{0xAAEB,0xAAEB},{0xAAEE,0xAAEF},{0xAAF5,0xAAF5}, - {0xABE3,0xABE4},{0xABE6,0xABE7},{0xABE9,0xABEA},{0xABEC,0xABEC}, - {0x11000,0x11000},{0x11002,0x11002},{0x11082,0x11082},{0x110B0,0x110B2}, - {0x110B7,0x110B8},{0x1112C,0x1112C},{0x11145,0x11146},{0x11182,0x11182}, - {0x111B3,0x111B5},{0x111BF,0x111C0},{0x111CE,0x111CE},{0x1122C,0x1122E}, - {0x11232,0x11233},{0x11235,0x11235},{0x112E0,0x112E2},{0x11302,0x11303}, - {0x1133E,0x1133F},{0x11341,0x11344},{0x11347,0x11348},{0x1134B,0x1134D}, - {0x11357,0x11357},{0x11362,0x11363},{0x113B8,0x113BA},{0x113C2,0x113C2}, - {0x113C5,0x113C5},{0x113C7,0x113CA},{0x113CC,0x113CD},{0x113CF,0x113CF}, - {0x11435,0x11437},{0x11440,0x11441},{0x11445,0x11445},{0x114B0,0x114B2}, - {0x114B9,0x114B9},{0x114BB,0x114BE},{0x114C1,0x114C1},{0x115AF,0x115B1}, - {0x115B8,0x115BB},{0x115BE,0x115BE},{0x11630,0x11632},{0x1163B,0x1163C}, - {0x1163E,0x1163E},{0x116AC,0x116AC},{0x116AE,0x116AF},{0x116B6,0x116B6}, - {0x1171E,0x1171E},{0x11720,0x11721},{0x11726,0x11726},{0x1182C,0x1182E}, - {0x11838,0x11838},{0x11930,0x11935},{0x11937,0x11938},{0x1193D,0x1193D}, - {0x11940,0x11940},{0x11942,0x11942},{0x119D1,0x119D3},{0x119DC,0x119DF}, - {0x119E4,0x119E4},{0x11A39,0x11A39},{0x11A57,0x11A58},{0x11A97,0x11A97}, - {0x11B61,0x11B61},{0x11B65,0x11B65},{0x11B67,0x11B67},{0x11C2F,0x11C2F}, - {0x11C3E,0x11C3E},{0x11CA9,0x11CA9},{0x11CB1,0x11CB1},{0x11CB4,0x11CB4}, - {0x11D8A,0x11D8E},{0x11D93,0x11D94},{0x11D96,0x11D96},{0x11EF5,0x11EF6}, - {0x11F03,0x11F03},{0x11F34,0x11F35},{0x11F3E,0x11F3F},{0x11F41,0x11F41}, - {0x1612A,0x1612C},{0x16F51,0x16F87},{0x16FF0,0x16FF1},{0x1D165,0x1D166}, - {0x1D16D,0x1D172},{0x1D250,0x1D252},{0x1D25F,0x1D25F},{0x1D280,0x1D281}, -}; - -static const struct term_unicode_range term_extended_pictographic[] = { - {0xA9,0xA9},{0xAE,0xAE},{0x203C,0x203C},{0x2049,0x2049}, - {0x2122,0x2122},{0x2139,0x2139},{0x2194,0x2199},{0x21A9,0x21AA}, - {0x231A,0x231B},{0x2328,0x2328},{0x23CF,0x23CF},{0x23E9,0x23F3}, - {0x23F8,0x23FA},{0x24C2,0x24C2},{0x25AA,0x25AB},{0x25B6,0x25B6}, - {0x25C0,0x25C0},{0x25FB,0x25FE},{0x2600,0x2604},{0x260E,0x260E}, - {0x2611,0x2611},{0x2614,0x2615},{0x2618,0x2618},{0x261D,0x261D}, - {0x2620,0x2620},{0x2622,0x2623},{0x2626,0x2626},{0x262A,0x262A}, - {0x262E,0x262F},{0x2638,0x263A},{0x2640,0x2640},{0x2642,0x2642}, - {0x2648,0x2653},{0x265F,0x2660},{0x2663,0x2663},{0x2665,0x2666}, - {0x2668,0x2668},{0x267B,0x267B},{0x267E,0x267F},{0x2692,0x2697}, - {0x2699,0x2699},{0x269B,0x269C},{0x26A0,0x26A1},{0x26A7,0x26A7}, - {0x26AA,0x26AB},{0x26B0,0x26B1},{0x26BD,0x26BE},{0x26C4,0x26C5}, - {0x26C8,0x26C8},{0x26CE,0x26CF},{0x26D1,0x26D1},{0x26D3,0x26D4}, - {0x26E9,0x26EA},{0x26F0,0x26F5},{0x26F7,0x26FA},{0x26FD,0x26FD}, - {0x2702,0x2702},{0x2705,0x2705},{0x2708,0x270D},{0x270F,0x270F}, - {0x2712,0x2712},{0x2714,0x2714},{0x2716,0x2716},{0x271D,0x271D}, - {0x2721,0x2721},{0x2728,0x2728},{0x2733,0x2734},{0x2744,0x2744}, - {0x2747,0x2747},{0x274C,0x274C},{0x274E,0x274E},{0x2753,0x2755}, - {0x2757,0x2757},{0x2763,0x2764},{0x2795,0x2797},{0x27A1,0x27A1}, - {0x27B0,0x27B0},{0x27BF,0x27BF},{0x2934,0x2935},{0x2B05,0x2B07}, - {0x2B1B,0x2B1C},{0x2B50,0x2B50},{0x2B55,0x2B55},{0x3030,0x3030}, - {0x303D,0x303D},{0x3297,0x3297},{0x3299,0x3299},{0x1F004,0x1F004}, - {0x1F02C,0x1F02F},{0x1F094,0x1F09F},{0x1F0AF,0x1F0B0},{0x1F0C0,0x1F0C0}, - {0x1F0CF,0x1F0D0},{0x1F0F6,0x1F0FF},{0x1F170,0x1F171},{0x1F17E,0x1F17F}, - {0x1F18E,0x1F18E},{0x1F191,0x1F19A},{0x1F1AF,0x1F1E5},{0x1F201,0x1F20F}, - {0x1F21A,0x1F21A},{0x1F22F,0x1F22F},{0x1F232,0x1F23A},{0x1F23C,0x1F23F}, - {0x1F249,0x1F25F},{0x1F266,0x1F321},{0x1F324,0x1F393},{0x1F396,0x1F397}, - {0x1F399,0x1F39B},{0x1F39E,0x1F3F0},{0x1F3F3,0x1F3F5},{0x1F3F7,0x1F3FA}, - {0x1F400,0x1F4FD},{0x1F4FF,0x1F53D},{0x1F549,0x1F54E},{0x1F550,0x1F567}, - {0x1F56F,0x1F570},{0x1F573,0x1F57A},{0x1F587,0x1F587},{0x1F58A,0x1F58D}, - {0x1F590,0x1F590},{0x1F595,0x1F596},{0x1F5A4,0x1F5A5},{0x1F5A8,0x1F5A8}, - {0x1F5B1,0x1F5B2},{0x1F5BC,0x1F5BC},{0x1F5C2,0x1F5C4},{0x1F5D1,0x1F5D3}, - {0x1F5DC,0x1F5DE},{0x1F5E1,0x1F5E1},{0x1F5E3,0x1F5E3},{0x1F5E8,0x1F5E8}, - {0x1F5EF,0x1F5EF},{0x1F5F3,0x1F5F3},{0x1F5FA,0x1F64F},{0x1F680,0x1F6C5}, - {0x1F6CB,0x1F6D2},{0x1F6D5,0x1F6E5},{0x1F6E9,0x1F6E9},{0x1F6EB,0x1F6F0}, - {0x1F6F3,0x1F6FF},{0x1F7DC,0x1F7F0},{0x1F80C,0x1F80F},{0x1F848,0x1F84F}, - {0x1F85A,0x1F85F},{0x1F888,0x1F88F},{0x1F8AE,0x1F8AF},{0x1F8BC,0x1F8BF}, - {0x1F8C2,0x1F8CF},{0x1F8D9,0x1F8FF},{0x1F90C,0x1F93A},{0x1F93C,0x1F945}, - {0x1F947,0x1F9FF},{0x1FA58,0x1FA5F},{0x1FA6E,0x1FAFF},{0x1FC00,0x1FFFD}, -}; - -static const struct term_unicode_range term_emoji_presentation[] = { - {0x231A,0x231B},{0x23E9,0x23EC},{0x23F0,0x23F0},{0x23F3,0x23F3}, - {0x25FD,0x25FE},{0x2614,0x2615},{0x2648,0x2653},{0x267F,0x267F}, - {0x2693,0x2693},{0x26A1,0x26A1},{0x26AA,0x26AB},{0x26BD,0x26BE}, - {0x26C4,0x26C5},{0x26CE,0x26CE},{0x26D4,0x26D4},{0x26EA,0x26EA}, - {0x26F2,0x26F3},{0x26F5,0x26F5},{0x26FA,0x26FA},{0x26FD,0x26FD}, - {0x2705,0x2705},{0x270A,0x270B},{0x2728,0x2728},{0x274C,0x274C}, - {0x274E,0x274E},{0x2753,0x2755},{0x2757,0x2757},{0x2795,0x2797}, - {0x27B0,0x27B0},{0x27BF,0x27BF},{0x2B1B,0x2B1C},{0x2B50,0x2B50}, - {0x2B55,0x2B55},{0x1F004,0x1F004},{0x1F0CF,0x1F0CF},{0x1F18E,0x1F18E}, - {0x1F191,0x1F19A},{0x1F1E6,0x1F1FF},{0x1F201,0x1F201},{0x1F21A,0x1F21A}, - {0x1F22F,0x1F22F},{0x1F232,0x1F236},{0x1F238,0x1F23A},{0x1F250,0x1F251}, - {0x1F300,0x1F320},{0x1F32D,0x1F335},{0x1F337,0x1F37C},{0x1F37E,0x1F393}, - {0x1F3A0,0x1F3CA},{0x1F3CF,0x1F3D3},{0x1F3E0,0x1F3F0},{0x1F3F4,0x1F3F4}, - {0x1F3F8,0x1F43E},{0x1F440,0x1F440},{0x1F442,0x1F4FC},{0x1F4FF,0x1F53D}, - {0x1F54B,0x1F54E},{0x1F550,0x1F567},{0x1F57A,0x1F57A},{0x1F595,0x1F596}, - {0x1F5A4,0x1F5A4},{0x1F5FB,0x1F64F},{0x1F680,0x1F6C5},{0x1F6CC,0x1F6CC}, - {0x1F6D0,0x1F6D2},{0x1F6D5,0x1F6D9},{0x1F6DC,0x1F6DF},{0x1F6EB,0x1F6EC}, - {0x1F6F4,0x1F6FC},{0x1F7E0,0x1F7EB},{0x1F7F0,0x1F7F0},{0x1F90C,0x1F93A}, - {0x1F93C,0x1F945},{0x1F947,0x1F9FF},{0x1FA70,0x1FA7C},{0x1FA80,0x1FAC6}, - {0x1FAC8,0x1FAC8},{0x1FACC,0x1FADD},{0x1FADF,0x1FAEB},{0x1FAEF,0x1FAFA}, -}; diff --git a/include/term/unicode/utf8.h b/include/term/unicode/utf8.h deleted file mode 100644 index ad44465..0000000 --- a/include/term/unicode/utf8.h +++ /dev/null @@ -1,243 +0,0 @@ -#ifndef TERM_UNICODE_UTF8_H -#define TERM_UNICODE_UTF8_H - -#include <stdint.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#define TERM_UTF8_ACCEPT 0 -#define TERM_UTF8_REJECT 1 - -#define TERM_UTF8_3BYTE_MIN 0x800u -#define TERM_UTF8_SURROGATE_LO 0xd800u -#define TERM_UTF8_SURROGATE_HI 0xdfffu - -static const uint8_t term_utf8d[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -}; - -static inline uint32_t term_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte) { - byte &= 0xff; - uint32_t type = term_utf8d[byte]; - - *codep = (*state != TERM_UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); - - *state = term_utf8d[256 + *state*16 + type]; - return *state; -} - -static const uint8_t term_utf8_acc_state[256] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, -6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; -static const uint8_t term_utf8_acc_codep[256] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, -48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, -112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, -0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, -0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -/* - * Decode one code point at the start of buf and return the bytes it used. - * Each maximal invalid subpart gives U+FFFD (Unicode 3.9); the byte that - * ends a subpart stays unused, so the caller reads it again. A C0 control - * ends an unfinished sequence the same way. An unfinished sequence at the - * end of buf gives *cp = 0 and keeps the state. - */ -static inline int term_utf8_decode_ground(uint32_t *state, uint32_t *codep, - const char *buf, size_t len, uint32_t *cp) { - uint32_t st = *state; - uint32_t cpv = *codep; - int n = 0; - *cp = 0; - if (len == 0) - return 0; - do { - unsigned char c = (unsigned char)buf[n]; - if (c < 0x20) { - if (st != TERM_UTF8_ACCEPT) *cp = 0xFFFD; - st = TERM_UTF8_ACCEPT; - break; - } - uint32_t before = st; - n++; - if (st == TERM_UTF8_ACCEPT) { - cpv = term_utf8_acc_codep[c]; - st = term_utf8_acc_state[c]; - } else { - uint32_t type = term_utf8d[c]; - cpv = (c & 0x3fu) | (cpv << 6); - st = term_utf8d[256 + st*16 + type]; - } - if (st == TERM_UTF8_ACCEPT) { *cp = cpv; break; } - if (st == TERM_UTF8_REJECT) { - st = TERM_UTF8_ACCEPT; - *cp = 0xFFFD; - if (before != TERM_UTF8_ACCEPT) n--; - break; - } - } while ((size_t)n < len); - *state = st; - *codep = cpv; - return n; -} - -static inline int -term_utf8_decode_one(const char *buf, size_t len, uint32_t *codep) -{ - const unsigned char *s = (const unsigned char *)buf; - unsigned c0, c1, c2, c3; - uint32_t cp; - - if (len == 0) - return 0; - c0 = s[0]; - if (c0 < 0x80) { - *codep = c0; - return 1; - } - if (c0 < 0xc2 || c0 > 0xf4) - return 0; - - if (c0 <= 0xdf) { - if (len < 2) - return 0; - c1 = s[1]; - if ((c1 & 0xc0) != 0x80) - return 0; - *codep = ((c0 & 0x1f) << 6) | (c1 & 0x3f); - return 2; - } - - if (c0 <= 0xef) { - if (len < 3) - return 0; - c1 = s[1]; - c2 = s[2]; - if ((c1 & 0xc0) != 0x80 || (c2 & 0xc0) != 0x80) - return 0; - cp = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f); - if (cp < TERM_UTF8_3BYTE_MIN || - (cp >= TERM_UTF8_SURROGATE_LO && cp <= TERM_UTF8_SURROGATE_HI)) - return 0; - *codep = cp; - return 3; - } - - if (len < 4) - return 0; - c1 = s[1]; - c2 = s[2]; - c3 = s[3]; - if ((c1 & 0xc0) != 0x80 || (c2 & 0xc0) != 0x80 || - (c3 & 0xc0) != 0x80) - return 0; - cp = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | - ((c2 & 0x3f) << 6) | (c3 & 0x3f); - if (cp < 0x10000 || cp > 0x10ffff) - return 0; - *codep = cp; - return 4; -} - -static inline void -term_utf8_sanitize(char *dst, size_t cap, const char *src) -{ - if (!cap) - return; - size_t i = 0, len = strlen(src), off = 0; - while (off < len && i + 1 < cap) { - uint32_t cp; - int n = term_utf8_decode_one(src + off, len - off, &cp); - if (n <= 0 || i + (size_t)n >= cap) { - off++; - continue; - } - memcpy(dst + i, src + off, (size_t)n); - i += (size_t)n; - off += (size_t)n; - } - dst[i] = '\0'; -} - -/* A sanitized copy of src. Sanitizing only drops bytes, so the copy is - * never longer than src. */ -static inline char *term_utf8_sanitize_dup(const char *src) -{ - size_t cap = strlen(src) + 1; - char *dst = (char *)malloc(cap); - if (dst) - term_utf8_sanitize(dst, cap, src); - return dst; -} - -#define TERM_UTF8_MAX_BYTES 4 -static inline int term_utf8_encode(uint32_t cp, char *out) -{ - if (cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) - cp = 0xfffd; - if (cp < 0x80) { - out[0] = (char)cp; - return 1; - } - if (cp < 0x800) { - out[0] = (char)(0xc0 | (cp >> 6)); - out[1] = (char)(0x80 | (cp & 0x3f)); - return 2; - } - if (cp < 0x10000) { - out[0] = (char)(0xe0 | (cp >> 12)); - out[1] = (char)(0x80 | ((cp >> 6) & 0x3f)); - out[2] = (char)(0x80 | (cp & 0x3f)); - return 3; - } - out[0] = (char)(0xf0 | (cp >> 18)); - out[1] = (char)(0x80 | ((cp >> 12) & 0x3f)); - out[2] = (char)(0x80 | ((cp >> 6) & 0x3f)); - out[3] = (char)(0x80 | (cp & 0x3f)); - return 4; -} - -#endif diff --git a/include/term/unicode/width.h b/include/term/unicode/width.h deleted file mode 100644 index a85ec77..0000000 --- a/include/term/unicode/width.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef TERM_UNICODE_WIDTH_H -#define TERM_UNICODE_WIDTH_H - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -struct term_unicode_range { uint32_t lo, hi; }; - -#include "unicode_data.inc" - -static inline bool term_in_ranges(const struct term_unicode_range *ranges, size_t count, uint32_t cp) -{ - if (count == 0 || cp < ranges[0].lo || cp > ranges[count - 1].hi) - return false; - const struct term_unicode_range *base = ranges; - size_t n = count; - while (n > 1) { - size_t half = n / 2; - base = (base[half].lo <= cp) ? base + half : base; - n -= half; - } - return cp <= base->hi; -} - -#define TERM_IN_TABLE(table, cp) term_in_ranges(table, sizeof(table) / sizeof(table[0]), cp) - -static inline int term_unicode_width(uint32_t cp) -{ - if (cp > 0x10FFFF || TERM_IN_TABLE(term_nonprintable, cp)) - return -1; - if (TERM_IN_TABLE(term_zero_width, cp)) - return 0; - return TERM_IN_TABLE(term_unicode_wide, cp) ? 2 : 1; -} - -static inline bool term_unicode_extended_pictographic(uint32_t cp) -{ - return TERM_IN_TABLE(term_extended_pictographic, cp); -} - -static inline bool term_unicode_emoji_presentation(uint32_t cp) -{ - return TERM_IN_TABLE(term_emoji_presentation, cp); -} - -static inline bool term_unicode_spacing_mark(uint32_t cp) -{ - if (cp < 0x903 || ((cp - 0xABEDu) < (0x11000u - 0xABEDu)) || cp > 0x1D281) - return false; - return TERM_IN_TABLE(term_spacing_mark, cp); -} - -#undef TERM_IN_TABLE - -#endif |
