/** * @file kitty_graphics.h * * Kitty graphics protocol image storage. */ #ifndef GHOSTTY_VT_KITTY_GRAPHICS_H #define GHOSTTY_VT_KITTY_GRAPHICS_H #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** @defgroup kitty_graphics Kitty Graphics * * Opaque handle to the Kitty graphics image storage associated with a * terminal screen, and an iterator for inspecting placements. * * @{ */ /** * Queryable data kinds for ghostty_kitty_graphics_get(). * * @ingroup kitty_graphics */ typedef enum { /** Invalid / sentinel value. */ GHOSTTY_KITTY_GRAPHICS_DATA_INVALID = 0, /** * Populate a pre-allocated placement iterator with placement data from * the storage. Iterator data is only valid as long as the underlying * terminal is not mutated. * * Output type: GhosttyKittyGraphicsPlacementIterator * */ GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR = 1, } GhosttyKittyGraphicsData; /** * Queryable data kinds for ghostty_kitty_graphics_placement_get(). * * @ingroup kitty_graphics */ typedef enum { /** Invalid / sentinel value. */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID = 0, /** * The image ID this placement belongs to. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID = 1, /** * The placement ID. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_PLACEMENT_ID = 2, /** * Whether this is a virtual placement (unicode placeholder). * * Output type: bool * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IS_VIRTUAL = 3, /** * Pixel offset from the left edge of the cell. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_X_OFFSET = 4, /** * Pixel offset from the top edge of the cell. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Y_OFFSET = 5, /** * Source rectangle x origin in pixels. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_X = 6, /** * Source rectangle y origin in pixels. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_Y = 7, /** * Source rectangle width in pixels (0 = full image width). * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_WIDTH = 8, /** * Source rectangle height in pixels (0 = full image height). * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_HEIGHT = 9, /** * Number of columns this placement occupies. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_COLUMNS = 10, /** * Number of rows this placement occupies. * * Output type: uint32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_ROWS = 11, /** * Z-index for this placement. * * Output type: int32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z = 12, } GhosttyKittyGraphicsPlacementData; /** * Z-layer classification for kitty graphics placements. * * Based on the kitty protocol z-index conventions: * - BELOW_BG: z < INT32_MIN/2 (drawn below cell background) * - BELOW_TEXT: INT32_MIN/2 <= z < 0 (above background, below text) * - ABOVE_TEXT: z >= 0 (above text) * - ALL: no filtering (current behavior) * * @ingroup kitty_graphics */ typedef enum { GHOSTTY_KITTY_PLACEMENT_LAYER_ALL = 0, GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1, GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2, GHOSTTY_KITTY_PLACEMENT_LAYER_ABOVE_TEXT = 3, } GhosttyKittyPlacementLayer; /** * Settable options for ghostty_kitty_graphics_placement_iterator_set(). * * @ingroup kitty_graphics */ typedef enum { /** * Set the z-layer filter for the iterator. * * Input type: GhosttyKittyPlacementLayer * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER = 0, } GhosttyKittyGraphicsPlacementIteratorOption; /** * Pixel format of a Kitty graphics image. * * @ingroup kitty_graphics */ typedef enum { GHOSTTY_KITTY_IMAGE_FORMAT_RGB = 0, GHOSTTY_KITTY_IMAGE_FORMAT_RGBA = 1, GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2, GHOSTTY_KITTY_IMAGE_FORMAT_GRAY_ALPHA = 3, GHOSTTY_KITTY_IMAGE_FORMAT_GRAY = 4, } GhosttyKittyImageFormat; /** * Compression of a Kitty graphics image. * * @ingroup kitty_graphics */ typedef enum { GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0, GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1, } GhosttyKittyImageCompression; /** * Queryable data kinds for ghostty_kitty_graphics_image_get(). * * @ingroup kitty_graphics */ typedef enum { /** Invalid / sentinel value. */ GHOSTTY_KITTY_IMAGE_DATA_INVALID = 0, /** * The image ID. * * Output type: uint32_t * */ GHOSTTY_KITTY_IMAGE_DATA_ID = 1, /** * The image number. * * Output type: uint32_t * */ GHOSTTY_KITTY_IMAGE_DATA_NUMBER = 2, /** * Image width in pixels. * * Output type: uint32_t * */ GHOSTTY_KITTY_IMAGE_DATA_WIDTH = 3, /** * Image height in pixels. * * Output type: uint32_t * */ GHOSTTY_KITTY_IMAGE_DATA_HEIGHT = 4, /** * Pixel format of the image. * * Output type: GhosttyKittyImageFormat * */ GHOSTTY_KITTY_IMAGE_DATA_FORMAT = 5, /** * Compression of the image. * * Output type: GhosttyKittyImageCompression * */ GHOSTTY_KITTY_IMAGE_DATA_COMPRESSION = 6, /** * Borrowed pointer to the raw pixel data. Valid as long as the * underlying terminal is not mutated. * * Output type: const uint8_t ** */ GHOSTTY_KITTY_IMAGE_DATA_DATA_PTR = 7, /** * Length of the raw pixel data in bytes. * * Output type: size_t * */ GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN = 8, } GhosttyKittyGraphicsImageData; /** * Get data from a kitty graphics storage instance. * * The output pointer must be of the appropriate type for the requested * data kind. * * Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time. * * @param graphics The kitty graphics handle * @param data The type of data to extract * @param[out] out Pointer to store the extracted data * @return GHOSTTY_SUCCESS on success * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_get( GhosttyKittyGraphics graphics, GhosttyKittyGraphicsData data, void* out); /** * Look up a Kitty graphics image by its image ID. * * Returns NULL if no image with the given ID exists or if Kitty graphics * are disabled at build time. * * @param graphics The kitty graphics handle * @param image_id The image ID to look up * @return An opaque image handle, or NULL if not found * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyKittyGraphicsImage ghostty_kitty_graphics_image( GhosttyKittyGraphics graphics, uint32_t image_id); /** * Get data from a Kitty graphics image. * * The output pointer must be of the appropriate type for the requested * data kind. * * @param image The image handle (NULL returns GHOSTTY_INVALID_VALUE) * @param data The data kind to query * @param[out] out Pointer to receive the queried value * @return GHOSTTY_SUCCESS on success * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get( GhosttyKittyGraphicsImage image, GhosttyKittyGraphicsImageData data, void* out); /** * Create a new placement iterator instance. * * All fields except the allocator are left undefined until populated * via ghostty_kitty_graphics_get() with * GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR. * * @param allocator Pointer to allocator, or NULL to use the default allocator * @param[out] out_iterator On success, receives the created iterator handle * @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation * failure * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_new( const GhosttyAllocator* allocator, GhosttyKittyGraphicsPlacementIterator* out_iterator); /** * Free a placement iterator. * * @param iterator The iterator handle to free (may be NULL) * * @ingroup kitty_graphics */ GHOSTTY_API void ghostty_kitty_graphics_placement_iterator_free( GhosttyKittyGraphicsPlacementIterator iterator); /** * Set an option on a placement iterator. * * Use GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER with a * GhosttyKittyPlacementLayer value to filter placements by z-layer. * The filter is applied during iteration: ghostty_kitty_graphics_placement_next() * will skip placements that do not match the configured layer. * * The default layer is GHOSTTY_KITTY_PLACEMENT_LAYER_ALL (no filtering). * * @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE) * @param option The option to set * @param value Pointer to the value (type depends on option; NULL returns * GHOSTTY_INVALID_VALUE) * @return GHOSTTY_SUCCESS on success * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_set( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsPlacementIteratorOption option, const void* value); /** * Advance the placement iterator to the next placement. * * If a layer filter has been set via * ghostty_kitty_graphics_placement_iterator_set(), only placements * matching that layer are returned. * * @param iterator The iterator handle (may be NULL) * @return true if advanced to the next placement, false if at the end * * @ingroup kitty_graphics */ GHOSTTY_API bool ghostty_kitty_graphics_placement_next( GhosttyKittyGraphicsPlacementIterator iterator); /** * Get data from the current placement in a placement iterator. * * Call ghostty_kitty_graphics_placement_next() at least once before * calling this function. * * @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE) * @param data The data kind to query * @param[out] out Pointer to receive the queried value * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the * iterator is NULL or not positioned on a placement * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsPlacementData data, void* out); /** * Compute the grid rectangle occupied by the current placement. * * Uses the placement's pin, the image dimensions, and the terminal's * cell/pixel geometry to calculate the bounding rectangle. Virtual * placements (unicode placeholders) return GHOSTTY_NO_VALUE. * * @param terminal The terminal handle * @param image The image handle for this placement's image * @param iterator The placement iterator positioned on a placement * @param[out] out_selection On success, receives the bounding rectangle * as a selection with rectangle=true * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle * is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE for * virtual placements or when Kitty graphics are disabled * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_rect( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, GhosttySelection* out_selection); /** * Compute the rendered pixel size of the current placement. * * Takes into account the placement's source rectangle, specified * columns/rows, and aspect ratio to calculate the final rendered * pixel dimensions. * * @param iterator The placement iterator positioned on a placement * @param image The image handle for this placement's image * @param terminal The terminal handle * @param[out] out_width On success, receives the width in pixels * @param[out] out_height On success, receives the height in pixels * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle * is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when * Kitty graphics are disabled * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_pixel_size( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, uint32_t* out_width, uint32_t* out_height); /** * Compute the grid cell size of the current placement. * * Returns the number of columns and rows that the placement occupies * in the terminal grid. If the placement specifies explicit columns * and rows, those are returned directly; otherwise they are calculated * from the pixel size and cell dimensions. * * @param iterator The placement iterator positioned on a placement * @param image The image handle for this placement's image * @param terminal The terminal handle * @param[out] out_cols On success, receives the number of columns * @param[out] out_rows On success, receives the number of rows * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle * is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when * Kitty graphics are disabled * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_grid_size( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, uint32_t* out_cols, uint32_t* out_rows); /** * Get the viewport-relative grid position of the current placement. * * Converts the placement's internal pin to viewport-relative column and * row coordinates. The returned coordinates represent the top-left * corner of the placement in the viewport's grid coordinate space. * * The row value can be negative when the placement's origin has * scrolled above the top of the viewport. For example, a 4-row * image that has scrolled up by 2 rows returns row=-2, meaning * its top 2 rows are above the visible area but its bottom 2 rows * are still on screen. Embedders should use these coordinates * directly when computing the destination rectangle for rendering; * the embedder is responsible for clipping the portion of the image * that falls outside the viewport. * * Returns GHOSTTY_SUCCESS for any placement that is at least * partially visible in the viewport. Returns GHOSTTY_NO_VALUE when * the placement is completely outside the viewport (its bottom edge * is above the viewport or its top edge is at or below the last * viewport row), or when the placement is a virtual (unicode * placeholder) placement. * * @param iterator The placement iterator positioned on a placement * @param image The image handle for this placement's image * @param terminal The terminal handle * @param[out] out_col On success, receives the viewport-relative column * @param[out] out_row On success, receives the viewport-relative row * (may be negative for partially visible placements) * @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if fully * off-screen or virtual, GHOSTTY_INVALID_VALUE if any handle * is NULL or the iterator is not positioned * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_viewport_pos( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, int32_t* out_col, int32_t* out_row); /** * Get the resolved source rectangle for the current placement. * * Applies kitty protocol semantics: a width or height of 0 in the * placement means "use the full image dimension", and the resulting * rectangle is clamped to the actual image bounds. The returned * values are in pixels and are ready to use for texture sampling. * * @param iterator The placement iterator positioned on a placement * @param image The image handle for this placement's image * @param[out] out_x Source rect x origin in pixels * @param[out] out_y Source rect y origin in pixels * @param[out] out_width Source rect width in pixels * @param[out] out_height Source rect height in pixels * @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any * handle is NULL or the iterator is not positioned * * @ingroup kitty_graphics */ GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_source_rect( GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, uint32_t* out_x, uint32_t* out_y, uint32_t* out_width, uint32_t* out_height); /** @} */ #ifdef __cplusplus } #endif #endif /* GHOSTTY_VT_KITTY_GRAPHICS_H */