Full Code of nicbarker/clay for AI

main 76ec3632d80c cached
99 files
1.3 MB
351.6k tokens
610 symbols
1 requests
Download .txt
Showing preview only (1,373K chars total). Download the full file or copy to clipboard to get everything.
Repository: nicbarker/clay
Branch: main
Commit: 76ec3632d80c
Files: 99
Total size: 1.3 MB

Directory structure:
gitextract_vqarsh70/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── cmake-multi-platform.yml
│       └── odin-bindings-update.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE.md
├── README.md
├── bindings/
│   ├── cpp/
│   │   └── README.md
│   ├── csharp/
│   │   └── README
│   ├── rust/
│   │   └── README
│   └── zig/
│       └── README
├── clay.h
├── cmake/
│   └── FindCairo.cmake
├── examples/
│   ├── GLES3-GLFW-video-demo/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── GLES3-SDL2-sidebar-scrolling-container/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── GLES3-SDL2-video-demo/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── SDL2-video-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── SDL3-simple-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── cairo-pdf-rendering/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── clay-official-website/
│   │   ├── CMakeLists.txt
│   │   ├── build/
│   │   │   └── clay/
│   │   │       ├── index.html
│   │   │       └── index.wasm
│   │   ├── build.sh
│   │   ├── index.html
│   │   └── main.c
│   ├── cpp-project-example/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── introducing-clay-video-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── playdate-project-example/
│   │   ├── .gitignore
│   │   ├── CmakeLists.txt
│   │   ├── README.md
│   │   ├── Source/
│   │   │   └── pdxinfo
│   │   ├── clay-video-demo-playdate.c
│   │   └── main.c
│   ├── raylib-multi-context/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── raylib-sidebar-scrolling-container/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── multi-compilation-unit.c
│   ├── shared-layouts/
│   │   └── clay-video-demo.c
│   ├── sokol-corner-radius/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── sokol-video-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── sokol.c
│   ├── termbox2-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── readme.md
│   ├── termbox2-image-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── readme.md
│   ├── terminal-example/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   └── win32_gdi/
│       ├── CMakeLists.txt
│       ├── build.ps1
│       └── main.c
├── renderers/
│   ├── GLES3/
│   │   ├── clay_renderer_gles3.h
│   │   └── clay_renderer_gles3_loader_stb.c
│   ├── SDL2/
│   │   ├── README
│   │   └── clay_renderer_SDL2.c
│   ├── SDL3/
│   │   └── clay_renderer_SDL3.c
│   ├── cairo/
│   │   └── clay_renderer_cairo.c
│   ├── playdate/
│   │   └── clay_renderer_playdate.c
│   ├── raylib/
│   │   ├── clay_renderer_raylib.c
│   │   ├── raylib.h
│   │   └── raymath.h
│   ├── sokol/
│   │   └── sokol_clay.h
│   ├── termbox2/
│   │   ├── clay_renderer_termbox2.c
│   │   └── image_character_masks.h
│   ├── terminal/
│   │   └── clay_renderer_terminal_ansi.c
│   ├── web/
│   │   ├── build-wasm.sh
│   │   ├── canvas2d/
│   │   │   └── clay-canvas2d-renderer.html
│   │   ├── clay.wasm
│   │   └── html/
│   │       └── clay-html-renderer.html
│   └── win32_gdi/
│       ├── README.md
│       └── clay_renderer_gdi.c
└── tests/
    ├── docker-compose.yml
    ├── gcc/
    │   └── 9.4/
    │       └── Dockerfile
    └── run-tests.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
cmake-build-debug/
cmake-build-release/
.DS_Store
.idea/
build/
node_modules/

================================================
FILE: .github/FUNDING.yml
================================================
github: [nicbarker]


================================================
FILE: .github/workflows/cmake-multi-platform.yml
================================================
name: CMake on multiple platforms

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ${{ matrix.os }}

    strategy:
      # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
      fail-fast: false

      # Set up a matrix to run the following 3 configurations:
      # 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
      # 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
      # 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
      #
      # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
      matrix:
        os: [ubuntu-latest, windows-latest]
        build_type: [Release]
        c_compiler: [gcc, clang, cl]
        include:
          - os: windows-latest
            c_compiler: cl
            cpp_compiler: cl
          - os: ubuntu-latest
            c_compiler: gcc
            cpp_compiler: g++
          - os: ubuntu-latest
            c_compiler: clang
            cpp_compiler: clang++
        exclude:
          - os: windows-latest
            c_compiler: gcc
          - os: windows-latest
            c_compiler: clang
          - os: ubuntu-latest
            c_compiler: cl

    steps:
    - uses: actions/checkout@v4

    - name: Set reusable strings
      # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
      id: strings
      shell: bash
      run: |
        echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"

    - name: Cache
      uses: actions/cache@v4.2.0
      with:
        # A list of files, directories, and wildcard patterns to cache and restore
        path: "/home/runner/work/clay/clay/build/_deps"
        # An explicit key for restoring and saving the cache
        key: "_deps"

    - name: Install Dependencies
      if: runner.os == 'Linux'
      run: |
        DEBIAN_FRONTEND=noninteractive sudo apt-get update -y
        DEBIAN_FRONTEND=noninteractive sudo apt-get install -y git
        DEBIAN_FRONTEND=noninteractive sudo apt-get install -y libwayland-dev
        DEBIAN_FRONTEND=noninteractive sudo apt-get install -y pkg-config
        DEBIAN_FRONTEND=noninteractive sudo apt-get install -y libxkbcommon-dev
        DEBIAN_FRONTEND=noninteractive sudo apt-get install -y xorg-dev


    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: >
        cmake -B ${{ steps.strings.outputs.build-output-dir }}
        -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
        -DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
        -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
        -S ${{ github.workspace }}

    - name: Build
      # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
      run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

    - name: Test
      working-directory: ${{ steps.strings.outputs.build-output-dir }}
      # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: ctest --build-config ${{ matrix.build_type }}


================================================
FILE: .github/workflows/odin-bindings-update.yml
================================================
name: Odin Bindings Update
on:
  push:
    branches: [main]
jobs:
  check_changes:
    runs-on: ubuntu-latest
    outputs:
      changed: ${{ steps.check_clay.outputs.changed }}
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Check if clay.h changed
        id: check_clay
        run: |
          if git diff --name-only HEAD^ HEAD | grep -Fx "clay.h"; then
            echo "changed=true" >> $GITHUB_OUTPUT
          else
            echo "changed=false" >> $GITHUB_OUTPUT
          fi

  build:
    needs: check_changes
    if: needs.check_changes.outputs.changed == 'true'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install clang (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y clang

      - name: Build libs
        run: |
          mkdir -p build
          mkdir -p artifacts
          cp clay.h clay.c

          COMMON_FLAGS="-DCLAY_IMPLEMENTATION -fno-ident -frandom-seed=clay"

          if [[ "$(uname)" == "Linux" ]]; then
            mkdir -p artifacts/linux
            mkdir -p artifacts/windows
            mkdir -p artifacts/wasm

            echo "Building for Linux..."
            clang -c $COMMON_FLAGS -fPIC -ffreestanding -static -target x86_64-unknown-linux-gnu clay.c -o build/linux.o
            ar rD artifacts/linux/clay.a build/linux.o

            echo "Building for Windows..."
            clang -c $COMMON_FLAGS -ffreestanding -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib clay.c -o artifacts/windows/clay.lib

            echo "Building for WASM..."
            clang -c $COMMON_FLAGS -fPIC -target wasm32 -nostdlib -static clay.c -o artifacts/wasm/clay.o
          elif [[ "$(uname)" == "Darwin" ]]; then
            mkdir -p artifacts/macos
            mkdir -p artifacts/macos-arm64
            echo "Building for macOS (x86_64)..."
            clang -c $COMMON_FLAGS -fPIC -target x86_64-apple-macos clay.c -o build/macos.o
            libtool -static -o artifacts/macos/clay.a build/macos.o

            echo "Building for macOS (ARM64)..."
            clang -c $COMMON_FLAGS -fPIC -target arm64-apple-macos clay.c -o build/macos-arm64.o
            libtool -static -o artifacts/macos-arm64/clay.a build/macos-arm64.o
          fi
          rm -f clay.c build/*.o

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: artifacts-${{ matrix.os }}
          path: artifacts/

  commit:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Download artifacts
        uses: actions/download-artifact@v4

      - name: Move artifacts
        run: |
          cp -r artifacts-ubuntu-latest/* bindings/odin/clay-odin/
          cp -r artifacts-macos-latest/* bindings/odin/clay-odin/

      - name: Commit/Push changes
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add bindings/odin/clay-odin/
          git commit -m "[bindings/odin] Update Odin bindings"
          git push


================================================
FILE: .gitignore
================================================
cmake-build-debug/
cmake-build-release/
.DS_Store
.idea/
node_modules/
*.dSYM
.vs/

================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.27)
project(clay)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

option(CLAY_INCLUDE_ALL_EXAMPLES "Build all examples" ON)
option(CLAY_INCLUDE_DEMOS "Build video demo and website" OFF)
option(CLAY_INCLUDE_CPP_EXAMPLE "Build C++ example" OFF)
option(CLAY_INCLUDE_RAYLIB_EXAMPLES "Build raylib examples" OFF)
option(CLAY_INCLUDE_SDL2_EXAMPLES "Build SDL 2 examples" OFF)
option(CLAY_INCLUDE_SDL3_EXAMPLES "Build SDL 3 examples" OFF)
option(CLAY_INCLUDE_WIN32_GDI_EXAMPLES "Build Win32 GDI examples" OFF)
option(CLAY_INCLUDE_SOKOL_EXAMPLES "Build Sokol examples" OFF)
option(CLAY_INCLUDE_PLAYDATE_EXAMPLES "Build Playdate examples" OFF)

message(STATUS "CLAY_INCLUDE_DEMOS: ${CLAY_INCLUDE_DEMOS}")

if(APPLE)
  enable_language(OBJC)
endif()

if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_CPP_EXAMPLE)
  add_subdirectory("examples/cpp-project-example")
endif()
if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_DEMOS)
  if(NOT MSVC)
    add_subdirectory("examples/clay-official-website")
    add_subdirectory("examples/terminal-example")
  endif()
  add_subdirectory("examples/introducing-clay-video-demo")
endif ()

if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_RAYLIB_EXAMPLES)
  add_subdirectory("examples/raylib-multi-context")
  add_subdirectory("examples/raylib-sidebar-scrolling-container")
endif ()
if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SDL2_EXAMPLES)
  add_subdirectory("examples/SDL2-video-demo")
endif ()
if(NOT MSVC AND (CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SDL3_EXAMPLES))
    add_subdirectory("examples/SDL3-simple-demo")
endif()
if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SOKOL_EXAMPLES)
  add_subdirectory("examples/sokol-video-demo")
  add_subdirectory("examples/sokol-corner-radius")
endif()

# Playdate example not included in ALL because users need to install the playdate SDK first which requires a license agreement
if(CLAY_INCLUDE_PLAYDATE_EXAMPLES)
  add_subdirectory("examples/playdate-project-example")
endif()

if(WIN32)   # Build only for Win or Wine
    if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_WIN32_GDI_EXAMPLES)
        add_subdirectory("examples/win32_gdi")
    endif()
endif()

#  add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now

#add_library(${PROJECT_NAME} INTERFACE)
#target_include_directories(${PROJECT_NAME} INTERFACE .)


================================================
FILE: LICENSE.md
================================================
zlib/libpng license

Copyright (c) 2024 Nic Barker

This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the
use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

    1. The origin of this software must not be misrepresented; you must not
    claim that you wrote the original software. If you use this software in a
    product, an acknowledgment in the product documentation would be
    appreciated but is not required.

    2. Altered source versions must be plainly marked as such, and must not
    be misrepresented as being the original software.

    3. This notice may not be removed or altered from any source
    distribution.

================================================
FILE: README.md
================================================
# Clay, A UI Layout Library
**_Clay_** (short for **C Layout**) is a high performance 2D UI layout library.

### Major Features
- Microsecond layout performance
- Flex-box like layout model for complex, responsive layouts including text wrapping, scrolling containers and aspect ratio scaling
- Single ~4k LOC **clay.h** file with **zero** dependencies (including no standard library)
- Wasm support: compile with clang to a 15kb uncompressed **.wasm** file for use in the browser
- Static arena based memory use with no malloc / free, and low total memory overhead (e.g. ~3.5mb for 8192 layout elements).
- React-like nested declarative syntax
- Renderer agnostic: outputs a sorted list of rendering primitives that can be easily composited in any 3D engine, and even compiled to HTML (examples provided)

Take a look at the [clay website](https://nicbarker.com/clay) for an example of clay compiled to wasm and running in the browser, or others in the [examples directory](https://github.com/nicbarker/clay/tree/main/examples).

You can also watch the [introduction video](https://youtu.be/DYWTw19_8r4) for an overview of the motivation behind Clay's development and a short demo of its usage.

<img width="1394" alt="A screenshot of a code IDE with lots of visual and textual elements" src="https://github.com/user-attachments/assets/9986149a-ee0f-449a-a83e-64a392267e3d">

_An example GUI application built with clay_

## Quick Start

Download or clone clay.h and include it after defining `CLAY_IMPLEMENTATION` in one file.

```C
// Must be defined in one file, _before_ #include "clay.h"
#define CLAY_IMPLEMENTATION
#include "../../clay.h"

const Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255};
const Clay_Color COLOR_RED = (Clay_Color) {168, 66, 28, 255};
const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};

void HandleClayErrors(Clay_ErrorData errorData) {
    // See the Clay_ErrorData struct for more information
    printf("%s", errorData.errorText.chars);
    switch(errorData.errorType) {
        // etc
    }
}

// Example measure text function
static inline Clay_Dimensions MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData) {
    // Clay_TextElementConfig contains members such as fontId, fontSize, letterSpacing etc
    // Note: Clay_String->chars is not guaranteed to be null terminated
    return (Clay_Dimensions) {
            .width = text.length * config->fontSize, // <- this will only work for monospace fonts, see the renderers/ directory for more advanced text measurement
            .height = config->fontSize
    };
}

// Layout config is just a struct that can be declared statically, or inline
Clay_ElementDeclaration sidebarItemConfig = (Clay_ElementDeclaration) {
    .layout = {
        .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }
    },
    .backgroundColor = COLOR_ORANGE
};

// Re-useable components are just normal functions
void SidebarItemComponent() {
    CLAY(id, sidebarItemConfig) {
        // children go here...
    }
}

int main() {
    // Note: malloc is only used here as an example, any allocator that provides
    // a pointer to addressable memory of at least totalMemorySize will work
    uint64_t totalMemorySize = Clay_MinMemorySize();
    Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));

    // Note: screenWidth and screenHeight will need to come from your environment, Clay doesn't handle window related tasks
    Clay_Initialize(arena, (Clay_Dimensions) { screenWidth, screenHeight }, (Clay_ErrorHandler) { HandleClayErrors });

    while(renderLoop()) { // Will be different for each renderer / environment
        // Optional: Update internal layout dimensions to support resizing
        Clay_SetLayoutDimensions((Clay_Dimensions) { screenWidth, screenHeight });
        // Optional: Update internal pointer position for handling mouseover / click / touch events - needed for scrolling & debug tools
        Clay_SetPointerState((Clay_Vector2) { mousePositionX, mousePositionY }, isMouseDown);
        // Optional: Update internal pointer position for handling mouseover / click / touch events - needed for scrolling and debug tools
        Clay_UpdateScrollContainers(true, (Clay_Vector2) { mouseWheelX, mouseWheelY }, deltaTime);

        // All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout
        Clay_BeginLayout();

        // An example of laying out a UI with a fixed width sidebar and flexible width main content
        CLAY(CLAY_ID("OuterContainer"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }, .backgroundColor = {250,250,255,255} }) {
            CLAY(CLAY_ID("SideBar"), {
                .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 },
                .backgroundColor = COLOR_LIGHT
            }) {
                CLAY(CLAY_ID("ProfilePictureOuter"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .backgroundColor = COLOR_RED }) {
                    CLAY(CLAY_ID("ProfilePicture"), {.layout = { .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}, .image = { .imageData = &profilePicture } }) {}
                    CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} }));
                }

                // Standard C code like loops etc work inside components
                for (int i = 0; i < 5; i++) {
                    SidebarItemComponent();
                }

                CLAY(CLAY_ID("MainContent"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {}
            }
        }

        // All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout
        Clay_RenderCommandArray renderCommands = Clay_EndLayout();

        // More comprehensive rendering examples can be found in the renderers/ directory
        for (int i = 0; i < renderCommands.length; i++) {
            Clay_RenderCommand *renderCommand = &renderCommands.internalArray[i];

            switch (renderCommand->commandType) {
                case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
                    DrawRectangle( renderCommand->boundingBox, renderCommand->renderData.rectangle.backgroundColor);
                }
                // ... Implement handling of other command types
            }
        }
    }
}
```
    
The above example, rendered correctly will look something like the following:

![Clay Example](https://github.com/user-attachments/assets/1928c6d4-ada9-4a4c-a3d1-44fe9b23b3bd)

In summary, the general order of steps is:

1. [Clay_SetLayoutDimensions(dimensions)](#clay_setlayoutdimensions)	
2. [Clay_SetPointerState(pointerPosition, isPointerDown)](#clay_setpointerstate)
3. [Clay_UpdateScrollContainers(enableDragScrolling, scrollDelta, deltaTime)](#clay_updatescrollcontainers)
4. [Clay_BeginLayout()](#clay_beginlayout)
5. Declare your layout with the provided [Element Macros](#element-macros)
6. [Clay_EndLayout()](#clay_endlayout)
7. Render the results using the outputted [Clay_RenderCommandArray](#clay_rendercommandarray)

For help starting out or to discuss clay, considering joining [the discord server.](https://discord.gg/b4FTWkxdvT)

## Summary

- [High Level Documentation](#high-level-documentation)
  - [Building UI Hierarchies](#building-ui-hierarchies)
  - [Configuring Layout and Styling UI Elements](#configuring-layout-and-styling-ui-elements)
  - [Element IDs](#element-ids)
  - [Mouse, Touch and Pointer Interactions](#mouse-touch-and-pointer-interactions)
  - [Scrolling Elements](#scrolling-elements)
  - [Floating Elements](#floating-elements-absolute-positioning)
  - [Custom Elements](#laying-out-your-own-custom-elements)
  - [Retained Mode Rendering](#retained-mode-rendering)
  - [Visibility Culling](#visibility-culling)
  - [Preprocessor Directives](#preprocessor-directives)
  - [Bindings](#bindings-for-non-c)
  - [Debug Tools](#debug-tools)
- [API](#api)
  - [Naming Conventions](#naming-conventions)
  - [Public Functions](#public-functions)
    - [Lifecycle](#lifecycle-for-public-functions)
    - [Clay_MinMemorySize](#clay_minmemorysize)
    - [Clay_CreateArenaWithCapacityAndMemory](#clay_createarenawithcapacityandmemory)
    - [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction)
    - [Clay_ResetMeasureTextCache](#clay_resetmeasuretextcache)
    - [Clay_SetMaxElementCount](#clay_setmaxelementcount)
    - [Clay_SetMaxMeasureTextCacheWordCount](#clay_setmaxmeasuretextcachewordcount)
    - [Clay_Initialize](#clay_initialize)
    - [Clay_GetCurrentContext](#clay_getcurrentcontext)
    - [Clay_SetCurrentContext](#clay_setcurrentcontext)
    - [Clay_SetLayoutDimensions](#clay_setlayoutdimensions)
    - [Clay_SetPointerState](#clay_setpointerstate)
    - [Clay_UpdateScrollContainers](#clay_updatescrollcontainers)
    - [Clay_BeginLayout](#clay_beginlayout)
    - [Clay_EndLayout](#clay_endlayout)
    - [Clay_Hovered](#clay_hovered)
    - [Clay_OnHover](#clay_onhover)
    - [Clay_PointerOver](#clay_pointerover)
    - [Clay_GetScrollContainerData](#clay_getscrollcontainerdata)
    - [Clay_GetElementData](#clay_getelementdata)
    - [Clay_GetElementId](#clay_getelementid)
  - [Element Macros](#element-macros)
    - [CLAY](#clay)
    - [CLAY_ID](#clay_id)
    - [CLAY_IDI](#clay_idi)
  - [Data Structures & Defs](#data-structures--definitions)
    - [Clay_String](#clay_string)
    - [Clay_ElementId](#clay_elementid)
    - [Clay_RenderCommandArray](#clay_rendercommandarray)
    - [Clay_RenderCommand](#clay_rendercommand)
    - [Clay_ScrollContainerData](#clay_scrollcontainerdata)
    - [Clay_ErrorHandler](#clay_errorhandler)
    - [Clay_ErrorData](#clay_errordata)

## High Level Documentation

### Building UI Hierarchies
Clay UIs are built using the C macro `CLAY(id, { configuration })`. This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The `CLAY()` macro can also be _nested_, similar to other declarative UI systems like HTML.

Child elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces.
```C
// Parent element with 8px of padding
CLAY(CLAY_ID("parent"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    // Child element 1
    CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
    // Child element 2 with red background
    CLAY((CLAY_ID("child"), { .backgroundColor = COLOR_RED }) {
        // etc
    }
}
```

However, unlike HTML and other declarative DSLs, this macro is just C. As a result, you can use arbitrary C code such as loops, functions and conditions inside your layout declaration code:
```C
// Re-usable "components" are just functions that declare more UI
void ButtonComponent(Clay_String buttonText) {
    // Red box button with 8px of padding
    CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(8) }, .backgroundColor = COLOR_RED }) {
        CLAY_TEXT(buttonText, textConfig);
    }
}

// Parent element
CLAY(CLAY_ID("parent"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    // Render a bunch of text elements
    for (int i = 0; i < textArray.length; i++) {
        CLAY_TEXT(textArray.elements[i], textConfig);
    }
    // Only render this element if we're on a mobile screen
    if (isMobileScreen) {
        CLAY(0) {
            // etc
        }
    }
    // Re-usable components
    ButtonComponent(CLAY_STRING("Click me!"));
    ButtonComponent(CLAY_STRING("No, click me!"));
});
```

### Configuring Layout and Styling UI Elements
The layout and style of clay elements is configured with the [Clay_ElementDeclaration](#clay_elementdeclaration) struct passed to the `CLAY()` macro. 
```C
CLAY(CLAY_ID("box"), { .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    // Children are 8px inset into parent, and laid out top to bottom
}
```
This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax. e.g. `(Clay_ElementDeclaration) { .layout = { .padding = { .left = 8, .right = 8 } ...`.

See the [Clay_ElementDeclaration](#clay_elementdeclaration) API for the full list of options.

A `Clay_ElementDeclaration` struct can be defined in file scope or elsewhere, and reused.
```C
// Define a style in the global / file scope
Clay_ElementDeclaration reuseableStyle = (Clay_ElementDeclaration) {
    .layout = { .padding = { .left = 12 } },
    .backgroundColor = { 120, 120, 120, 255 },
    .cornerRadius = { 12, 12, 12, 12 }
};

CLAY(CLAY_ID("box"), reuseableStyle) {
    // ...
}
```

### Element IDs

The Clay macro by default accepts an ID as its first argument, which is usually provided by the [CLAY_ID()](#clay_id) convenience macro. Elements can also be created with auto generated IDs, by using the [CLAY_AUTO_ID()](#clay-auto-id) macro.

```C
// Will always produce the same ID from the same input string
CLAY(CLAY_ID("OuterContainer"), { ...configuration }) {}

// Generates a unique ID that may not be the same between two layout calls
CLAY_AUTO_ID({ ...configuration }) {}
```

Element IDs have two main use cases. Firstly, tagging an element with an ID allows you to query information about the element later, such as its [mouseover state](#clay_pointerover) or dimensions.

Secondly, IDs are visually useful when attempting to read and modify UI code, as well as when using the built-in [debug tools](#debug-tools).

To avoid having to construct dynamic strings at runtime to differentiate ids in loops, clay provides the [CLAY_IDI(string, index)](#clay_idi) macro to generate different ids from a single input string. Think of IDI as "**ID** + **I**ndex"
```C
// This is the equivalent of calling CLAY_ID("Item0"), CLAY_ID("Item1") etc
for (int index = 0; index < items.length; index++) {
    CLAY(CLAY_IDI("Item", index), { ..configuration }) {}
}
```

This ID will be forwarded to the final `Clay_RenderCommandArray` for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you're trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)

### Mouse, Touch and Pointer Interactions

Clay provides several functions for handling mouse and pointer interactions.

All pointer interactions depend on the function `void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)` being called after each mouse position update and before any other clay functions.

**During UI declaration**

The function `bool Clay_Hovered()` can be called during element construction or in the body of an element, and returns `true` if the mouse / pointer is over the currently open element.

```C
// An orange button that turns blue when hovered
CLAY(CLAY_ID("Button"), { .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {
    bool buttonHovered = Clay_Hovered();
    CLAY_TEXT(buttonHovered ? CLAY_STRING("Hovered") : CLAY_STRING("Hover me!"), headerTextConfig);
}
```

The function `void Clay_OnHover()` allows you to attach a function pointer to the currently open element, which will be called if the mouse / pointer is over the element.

```C
void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerInfo, void *userData) {
    ButtonData *buttonData = (ButtonData *)userData;
    // Pointer state allows you to detect mouse down / hold / release
    if (pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
        // Do some click handling
        NavigateTo(buttonData->link);
    }
}

ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };

// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_ID("Button"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    Clay_OnHover(HandleButtonInteraction, &linkButton);
    CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
}
```

**Before / After UI declaration**

If you want to query mouse / pointer overlaps outside layout declarations, you can use the function `bool Clay_PointerOver(Clay_ElementId id)`, which takes an [element id](#element-ids) and returns a bool representing whether the current pointer position is within its bounding box. 
```C
// Reminder: Clay_SetPointerState must be called before functions that rely on pointer position otherwise it will have no effect
Clay_Vector2 mousePosition = { x, y };
Clay_SetPointerState(mousePosition);
// ...
// If profile picture was clicked
if (mouseButtonDown(0) && Clay_PointerOver(Clay_GetElementId("ProfilePicture"))) {
    // Handle profile picture clicked
}
```

Note that the bounding box queried by `Clay_PointerOver` is from the last frame. This generally shouldn't make a difference except in the case of animations that move at high speed.
If this is an issue for you, performing layout twice per frame with the same data will give you the correct interaction the second time.

### Scrolling Elements

Elements are configured as scrollable with the `.clip` configuration. Clipping instructs the renderer to not draw any pixels outside the clipped element's boundaries, and by specifying the `.childOffset` field, the clipped element's contents can be shifted around to provide "scrolling" behaviour.

You can either calculate scrolling yourself and simply provide the current offset each frame to `.childOffset`, or alternatively, Clay provides a built in mechanism for tracking and updating scroll container offsets, detailed below.

To make scroll containers respond to mouse wheel and scroll events, two functions need to be called before `BeginLayout()`:
```C
Clay_Vector2 mousePosition = { x, y };
// Reminder: Clay_SetPointerState must be called before Clay_UpdateScrollContainers otherwise it will have no effect
Clay_SetPointerState(mousePosition);
// Clay_UpdateScrollContainers needs to be called before Clay_BeginLayout for the position to avoid a 1 frame delay
Clay_UpdateScrollContainers(
    true, // Enable drag scrolling
    scrollDelta, // Clay_Vector2 scrollwheel / trackpad scroll x and y delta this frame
    float deltaTime, // Time since last frame in seconds as a float e.g. 8ms is 0.008f
);
// ...
// Clay internally tracks the scroll containers offset, and Clay_GetScrollOffset returns the x,y offset of the currently open element
CLAY(CLAY_ID("ScrollContainer"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
    // Scrolling contents
}
// .childOffset can be provided directly if you would prefer to manage scrolling outside of clay
CLAY(CLAY_ID("ScrollContainer"), { .clip = { .vertical = true, .childOffset = myData.scrollContainer.offset } }) {
    // Scrolling contents
}
```

More specific details can be found in the docs for [Clay_UpdateScrollContainers](#clay_updatescrollcontainers), [Clay_SetPointerState](#clay_setpointerstate), [Clay_ClipElementConfig](#clay_clipelementconfig) and [Clay_GetScrollOffset](#clay_getscrolloffset).

### Floating Elements ("Absolute" Positioning)

All standard elements in clay are laid out on top of, and _within_ their parent, positioned according to their parent's layout rules, and affect the positioning and sizing of siblings.

**"Floating"** is configured with the `CLAY_FLOATING()` macro. Floating elements don't affect the parent they are defined in, or the position of their siblings.
They also have a **z-index**, and as a result can intersect and render over the top of other elements.

A classic example use case for floating elements is tooltips and modals.

```C
// The two text elements will be laid out top to bottom, and the floating container
// will be attached to "Outer"
CLAY(CLAY_ID("Outer"), { .layout = { .layoutDirection = TOP_TO_BOTTOM } }) {
    CLAY_TEXT(text, &headerTextConfig);
    CLAY(CLAY_ID("Tooltip"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } }) {}
    CLAY_TEXT(text, &headerTextConfig);
}
```

More specific details can be found in the full [Floating API](#clay_floatingelementconfig).

### Laying Out Your Own Custom Elements

Clay only supports a simple set of UI element primitives, such as rectangles, text and images. Clay provides a singular API for layout out custom elements:
```C
#include "clay.h"

typedef enum {
    CUSTOM_ELEMENT_TYPE_MODEL,
    CUSTOM_ELEMENT_TYPE_VIDEO
} CustomElementType;

// A rough example of how you could handle laying out 3d models in your UI
typedef struct {
    CustomElementType type;
    union {
        Model model;
        Video video;
        // ...
    };
} CustomElementData;

Model myModel = Load3DModel(filePath);
CustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }

typedef struct {
    void* memory;
    uintptr_t offset;
} Arena;

// During init
Arena frameArena = (Arena) { .memory = malloc(1024) };

// Custom elements only take a single pointer, so we need to store the data somewhere
CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
frameArena.offset += sizeof(CustomElementData);
CLAY(CLAY_ID("3DModelViewer"), { .custom = { .customData = modelData } }) {}

// Later during your rendering
switch (renderCommand->commandType) {
    // ...
    case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
        // Your extended struct is passed through
        CustomElementData *customElement = renderCommand->config.customElementConfig->customData;
        if (!customElement) continue;
        switch (customElement->type) {
            case CUSTOM_ELEMENT_TYPE_MODEL: {
                // Render your 3d model here
                break;
            }
            case CUSTOM_ELEMENT_TYPE_VIDEO: {
                // Render your video here
                break;
            }
            // ...
        }
        break;
    }
}
```

More specific details can be found in the full [Custom Element API](#clay_customelementconfig).

### Retained Mode Rendering
Clay was originally designed for [Immediate Mode](https://www.youtube.com/watch?v=Z1qyvQsjK5Y) rendering - where the entire UI is redrawn every frame. This may not be possible with your platform, renderer design or performance constraints.

There are some general techniques that can be used to integrate clay into a retained mode rendering system:

- `Clay_RenderCommand` includes the `uint32_t id` that was used to declare the element. If unique ids are used, these can be mapped to persistent graphics objects across multiple frames / layouts.
- Render commands are culled automatically to only currently visible elements, and `Clay_RenderCommand` is a small enough struct that you can simply compare the memory of two render commands with matching IDs to determine if the element is "dirty" and needs to be re-rendered or updated.

For a worked example, see the provided [HTML renderer](https://github.com/nicbarker/clay/blob/main/renderers/web/html/clay-html-renderer.html). This renderer converts clay layouts into persistent HTML documents with minimal changes per frame.  

### Visibility Culling
Clay provides a built-in visibility-culling mechanism that is **enabled by default**. It will only output render commands for elements that are visible - that is, **at least one pixel of their bounding box is inside the viewport.**

This culling mechanism can be disabled via the use of the `#define CLAY_DISABLE_CULLING` directive. See [Preprocessor Directives](#preprocessor-directives) for more information.

### Preprocessor Directives
Clay supports C preprocessor directives to modulate functionality at compile time. These can be set either in code using `#define CLAY_DISABLE_CULLING` or on the command line when compiling using the appropriate compiler specific arguments, e.g. `clang -DCLAY_DISABLE_CULLING main.c ...`

The supported directives are:

- `CLAY_WASM` - Required when targeting Web Assembly.
- `CLAY_DLL` - Required when creating a .Dll file.

### Bindings for non C

Clay is usable out of the box as a `.h` include in both C99 and C++20 with designated initializer support.
There are also supported bindings for other languages, including:

- [Odin Bindings](https://github.com/nicbarker/clay/tree/main/bindings/odin)
- [Rust Bindings](https://github.com/clay-ui-rs/clay)

### Other implementations
Clay has also been implemented in other languages:

- [`glay`](https://github.com/soypat/glay) - Go line-by-line rewrite with readability as main goal.
- [`totallygamerjet/clay`](https://github.com/totallygamerjet/clay) - Port using `cxgo`, a C to Go transpiler.
- [`goclay`](https://github.com/igadmg/goclay) - Go line-by-line rewrite closely matching the reference.

### Debug Tools

Clay includes built-in UI debugging tools, similar to the "inspector" in browsers such as Chrome or Firefox. These tools are included in `clay.h`, and work by injecting additional render commands into the output [Clay_RenderCommandArray](#clay_rendercommandarray).

As long as the renderer that you're using works correctly, no additional setup or configuration is required to use the debug tools.

To enable the debug tools, use the function `Clay_SetDebugModeEnabled(bool enabled)`. This boolean is persistent and does not need to be set every frame.

The debug tooling by default will render as a panel to the right side of the screen, compressing your layout by its width. The default width is 400 and is currently configurable via the direct mutation of the internal variable `Clay__debugViewWidth`, however this is an internal API and is potentially subject to change.

<img width="1506" alt="Screenshot 2024-09-12 at 12 54 03 PM" src="https://github.com/user-attachments/assets/2d122658-3305-4e27-88d6-44f08c0cb4e6">

_The official Clay website with debug tooling visible_

### Running more than one Clay instance

Clay allows you to run more than one instance in a program. To do this, [Clay_Initialize](#clay_initialize) returns a [Clay_Context*](#clay_context) reference. You can activate a specific instance using [Clay_SetCurrentContext](#clay_setcurrentcontext). If [Clay_SetCurrentContext](#clay_setcurrentcontext) is not called, then Clay will default to using the context from the most recently called [Clay_Initialize](#clay_initialize).

**⚠ Important: Do not render instances across different threads simultaneously, as Clay does not currently support proper multi-threading.**

```c++
// Define separate arenas for the instances.
Clay_Arena arena1, arena2;
// ... allocate arenas

// Initialize both instances, storing the context for each one.
Clay_Context* instance1 = Clay_Initialize(arena1, layoutDimensions, errorHandler);
Clay_Context* instance2 = Clay_Initialize(arena2, layoutDimensions, errorHandler);

// In the program's render function, activate each instance before executing clay commands and macros.
Clay_SetCurrentContext(instance1);
Clay_BeginLayout();
// ... declare layout for instance1
Clay_RenderCommandArray renderCommands1 = Clay_EndLayout();
render(renderCommands1);

// Switch to the second instance
Clay_SetCurrentContext(instance2);
Clay_BeginLayout();
// ... declare layout for instance2
Clay_RenderCommandArray renderCommands2 = Clay_EndLayout();
render(renderCommands2);
```

# API

### Naming Conventions

- "**CAPITAL_LETTERS()**" are used for macros.
- "**Clay__**" ("Clay" followed by **double** underscore) is used for internal functions that are not intended for use and are subject to change.
- "**Clay_**" ("Clay" followed by **single** underscore) is used for external functions that can be called by the user.

## Public Functions

### Lifecycle for public functions

**At startup / initialization time, run once**
`Clay_MinMemorySize` -> `Clay_CreateArenaWithCapacityAndMemory` -> `Clay_Initialize` -> `Clay_SetMeasureTextFunction`

**Each Frame**
`Clay_SetLayoutDimensions` -> `Clay_SetPointerState` -> `Clay_UpdateScrollContainers` -> `Clay_BeginLayout` -> `CLAY() etc...` -> `Clay_EndLayout`

---

### Clay_MinMemorySize

`uint32_t Clay_MinMemorySize()`

Returns the minimum amount of memory **in bytes** that clay needs to accommodate the current [CLAY_MAX_ELEMENT_COUNT](#preprocessor-directives).

---

### Clay_CreateArenaWithCapacityAndMemory

`Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset)`

Creates a `Clay_Arena` struct with the given capacity and base memory pointer, which can be passed to [Clay_Initialize](#clay_initialize).

---

### Clay_SetMeasureTextFunction

`void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData), uintptr_t userData)`

Takes a pointer to a function that can be used to measure the `width, height` dimensions of a string. Used by clay during layout to determine [CLAY_TEXT](#clay_text) element sizing and wrapping.

**Note 1: This string is not guaranteed to be null terminated.** Clay saves significant performance overhead by using slices when wrapping text instead of having to clone new null terminated strings. If your renderer does not support **ptr, length** style strings (e.g. Raylib), you will need to clone this to a new C string before rendering.

**Note 2: It is essential that this function is as fast as possible.** For text heavy use-cases this function is called many times, and despite the fact that clay caches text measurements internally, it can easily become the dominant overall layout cost if the provided function is slow. **This is on the hot path!**

---

### Clay_ResetMeasureTextCache

`void Clay_ResetMeasureTextCache(void)`

Clay caches measurements from the provided MeasureTextFunction, and this will be sufficient for the majority of use-cases. However, if the measurements can depend on external factors that clay does not know about, like DPI changes, then the cached values may be incorrect. When one of these external factors changes, Clay_ResetMeasureTextCache can be called to force clay to recalculate all string measurements in the next frame.

---

### Clay_SetMaxElementCount

`void Clay_SetMaxElementCount(uint32_t maxElementCount)`

Sets the internal maximum element count that will be used in subsequent [Clay_Initialize()](#clay_initialize) and [Clay_MinMemorySize()](#clay_minmemorysize) calls, allowing clay to allocate larger UI hierarchies.

**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**

---

### Clay_SetMaxMeasureTextCacheWordCount

`void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount)`

Sets the internal text measurement cache size that will be used in subsequent [Clay_Initialize()](#clay_initialize) and [Clay_MinMemorySize()](#clay_minmemorysize) calls, allowing clay to allocate more text. The value represents how many separate words can be stored in the text measurement cache.

**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**

---

### Clay_Initialize

`Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler)`

Initializes the internal memory mapping, sets the internal dimensions for layout, and binds an error handler for clay to use when something goes wrong. Returns a [Clay_Context*](#clay_context) that can optionally be given to [Clay_SetCurrentContext](#clay_setcurrentcontext) to allow running multiple instances of clay in the same program, and sets it as the current context. See [Running more than one Clay instance](#running-more-than-one-clay-instance).

Reference: [Clay_Arena](#clay_createarenawithcapacityandmemory), [Clay_ErrorHandler](#clay_errorhandler), [Clay_SetCurrentContext](#clay_setcurrentcontext)

---

### Clay_SetCurrentContext

`void Clay_SetCurrentContext(Clay_Context* context)`

Sets the context that subsequent clay commands will operate on. You can get this reference from [Clay_Initialize](#clay_initialize) or [Clay_GetCurrentContext](#clay_getcurrentcontext). See [Running more than one Clay instance](#running-more-than-one-clay-instance).

---

### Clay_GetCurrentContext

`Clay_Context* Clay_GetCurrentContext()`

Returns the context that clay commands are currently operating on, or null if no context has been set. See [Running more than one Clay instance](#running-more-than-one-clay-instance).

---

### Clay_SetLayoutDimensions

`void Clay_SetLayoutDimensions(Clay_Dimensions dimensions)`

Sets the internal layout dimensions. Cheap enough to be called every frame with your screen dimensions to automatically respond to window resizing, etc.

---

### Clay_SetPointerState

`void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)`

Sets the internal pointer position and state (i.e. current mouse / touch position) and recalculates overlap info, which is used for mouseover / click calculation (via [Clay_PointerOver](#clay_pointerover) and updating scroll containers with [Clay_UpdateScrollContainers](#clay_updatescrollcontainers). **isPointerDown should represent the current state this frame, e.g. it should be `true` for the entire duration the left mouse button is held down.** Clay has internal handling for detecting click / touch start & end.

---

### Clay_UpdateScrollContainers

`void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime)`

This function handles scrolling of containers. It responds to both `scrollDelta`, which represents mouse wheel or trackpad scrolling this frame, as well as "touch scrolling" on mobile devices, or "drag scrolling" with a mouse or similar device.

Touch / drag scrolling only occurs if the `enableDragScrolling` parameter is `true`, **and** [Clay_SetPointerState](#clay_setpointerstate) has been called this frame. As a result, you can simply always call it with `false` as the first argument if you want to disable touch scrolling.

`deltaTime` is the time **in seconds** since the last frame (e.g. 0.016 is **16 milliseconds**), and is used to normalize & smooth scrolling across different refresh rates.

---

### Clay_GetScrollOffset

`Clay_Vector2 Clay_GetScrollOffset()`

Returns the internally stored scroll offset for the currently open element.

Generally intended for use with [clip elements](#clay_clipelementconfig) and the `.childOffset` field to create scrolling containers.

See [Scrolling Elements](#scrolling-elements) for more details.

```C
// Create a horizontally scrolling container
CLAY(CLAY_ID("ScrollContainer"), {
    .clip = { .horizontal = true, .childOffset = Clay_GetScrollOffset() }
})
```

---

### Clay_BeginLayout

`void Clay_BeginLayout()`

Prepares clay to calculate a new layout. Called each frame / layout **before** any of the [Element Macros](#element-macros).

---

### Clay_EndLayout

`Clay_RenderCommandArray Clay_EndLayout()`

Ends declaration of element macros and calculates the results of the current layout. Renders a [Clay_RenderCommandArray](#clay_rendercommandarray) containing the results of the layout calculation.

---

### Clay_Hovered

`bool Clay_Hovered()`

Called **during** layout declaration, and returns `true` if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the currently open element. Note: this is based on the element's position from the **last** frame.

---

### Clay_OnHover

`void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData), void *userData)`

Called **during** layout declaration, this function allows you to attach a function pointer to the currently open element that will be called once per layout if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the currently open element. See [Clay_PointerData](#clay_pointerdata) for more information on the `pointerData` argument.

```C
void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData) {
    ButtonData *buttonData = (ButtonData *)userData;
    // Pointer state allows you to detect mouse down / hold / release
    if (pointerData.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
        // Do some click handling
        NavigateTo(buttonData->link);
    }
}

ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };

// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_ID("Button"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    Clay_OnHover(HandleButtonInteraction, &buttonData);
    CLAY_TEXT(CLAY_STRING("Click me!"), &headerTextConfig);
}
```

---

### Clay_PointerOver

`bool Clay_PointerOver(Clay_ElementId id)`

Returns `true` if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the layout element with the provided `id`. Note: this is based on the element's position from the **last** frame. If frame-accurate pointer overlap detection is required, perhaps in the case of significant change in UI layout between frames, you can simply run your layout code twice that frame. The second call to `Clay_PointerOver` will be frame-accurate.

### Clay_GetScrollContainerData

`Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id)`

Returns [Clay_ScrollContainerData](#clay_scrollcontainerdata) for the scroll container matching the provided ID. This function allows imperative manipulation of scroll position, allowing you to build things such as scroll bars, buttons that "jump" to somewhere in a scroll container, etc.

---

### Clay_GetElementData

`Clay_ElementData Clay_GetElementData(Clay_ElementId id)`

Returns [Clay_ElementData](#clay_elementdata) for the element matching the provided ID.
Used to retrieve information about elements such as their final calculated bounding box.

---

### Clay_GetElementId

`Clay_ElementId Clay_GetElementId(Clay_String idString)`

Returns a [Clay_ElementId](#clay_elementid) for the provided id string, used for querying element info such as mouseover state, scroll container data, etc.

## Element Macros

### CLAY()
**Usage**

`CLAY(...configuration) { ...children }`

**Lifecycle**

`Clay_BeginLayout()` -> `CLAY()` -> `Clay_EndLayout()` 

**Notes**

**CLAY** opens a generic empty container, that is configurable and supports nested children.
**CLAY** requires a parameter, so if you want to create an element without any configuration, use `CLAY(0)`.

**Examples**
```C
// Define an element with 16px of x and y padding
CLAY(CLAY_ID("Outer"), { .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
    // A nested child element
    CLAY(CLAY_ID("SideBar"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
        // Children laid out top to bottom with a 16 px gap between them
    }
    // A vertical scrolling container with a colored background
    CLAY(CLAY_ID("ScrollContainer"), {
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
        .backgroundColor = { 200, 200, 100, 255 },
        .cornerRadius = CLAY_CORNER_RADIUS(10),
        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
    }) {
        // child elements
    }
}
```

---

### CLAY_AUTO_ID()

A version of the core [CLAY()](#clay) element creation macro that generates an ID automatically instead of requiring it as the first argument.

Note that under the hood this ID is generated in the same way as [CLAY_ID_LOCAL()](#clay_id_local), which is based on the element's position in the hierarchy, and may chance between layout calls if elements are added / removed from the hierarchy before the element is defined. As a result, for transitions & retained mode backends to work correctly, IDs should be specified.

```C
// Note that CLAY_AUTO_ID only takes one argument: the configuration
CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
    // A nested child element
    CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
        // Children laid out top to bottom with a 16 px gap between them
    }
    // A vertical scrolling container with a colored background
    CLAY_AUTO_ID({
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
        .backgroundColor = { 200, 200, 100, 255 },
        .cornerRadius = CLAY_CORNER_RADIUS(10),
        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
    }) {
        // child elements
    }
}
```

---

### CLAY_TEXT()
**Usage**

`CLAY_TEXT(Clay_String textContents, Clay_TextElementConfig *textConfig);`

**Lifecycle**

`Clay_BeginLayout()` -> `CLAY_TEXT()` -> `Clay_EndLayout()`

**Notes**

**TEXT** is a measured, auto-wrapped text element. It uses `Clay_TextElementConfig` to configure text specific options.

Note that `Clay_TextElementConfig` uses `uint32_t fontId`. Font ID to font asset mapping is managed in user code and passed to render commands.

**Struct API (Pseudocode)**

```C
// CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .member = value })) supports these options
Clay_TextElementConfig {
    Clay_Color textColor {
        float r; float g; float b; float a;
    };
    uint16_t fontId;
    uint16_t fontSize;
    uint16_t letterSpacing;
    uint16_t lineHeight;
    Clay_TextElementConfigWrapMode wrapMode {
        CLAY_TEXT_WRAP_WORDS (default),
        CLAY_TEXT_WRAP_NEWLINES,
        CLAY_TEXT_WRAP_NONE,
    };
};
```

**Fields**

**`.textColor`**

`CLAY_TEXT_CONFIG(.textColor = {120, 120, 120, 255})`

Uses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.

---

**`.fontId`**

`CLAY_TEXT_CONFIG(.fontId = FONT_ID_LATO)`

It's up to the user to load fonts and create a mapping from `fontId` to a font that can be measured and rendered.

---

**`.fontSize`**

`CLAY_TEXT_CONFIG(.fontSize = 16)`

Font size is generally thought of as `x pixels tall`, but interpretation is left up to the user & renderer.

---

**`.letterSpacing`**

`CLAY_TEXT_CONFIG(.letterSpacing = 1)`

`.letterSpacing` results in **horizontal** white space between individual rendered characters.

---

**`.lineHeight`**

`CLAY_TEXT_CONFIG(.lineHeight = 20)`

`.lineHeight` - when non zero - forcibly sets the `height` of each wrapped line of text to `.lineheight` pixels tall. Will affect the layout of both parents and siblings. A value of `0` will use the measured height of the font.

---

**`.wrapMode`**

`CLAY_TEXT_CONFIG(.wrapMode = CLAY_TEXT_WRAP_NONE)`

`.wrapMode` specifies under what conditions text should [wrap](https://en.wikipedia.org/wiki/Line_wrap_and_word_wrap).

Available options are:

- `CLAY_TEXT_WRAP_WORDS` (default) - Text will wrap on whitespace characters as container width shrinks, preserving whole words.
- `CLAY_TEXT_WRAP_NEWLINES` -  will only wrap when encountering newline characters.
- `CLAY_TEXT_WRAP_NONE` - Text will never wrap even if its container is compressed beyond the text measured width.

---

**Examples**

```C
// Define a font somewhere in your code
const uint32_t FONT_ID_LATO = 3;
// ..
CLAY_TEXT(CLAY_STRING("John Smith"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_LATO, .fontSize = 24, .textColor = {255, 0, 0, 255} }));
// Rendering example
Font fontToUse = LoadedFonts[renderCommand->renderData.text->fontId];
```

**Rendering**

Element is subject to [culling](#visibility-culling). Otherwise, multiple `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_TEXT` may be created, one for each wrapped line of text.

`Clay_RenderCommand.textContent` will be populated with a `Clay_String` _slice_ of the original string passed in (i.e. wrapping doesn't reallocate, it just returns a `Clay_String` pointing to the start of the new line with a `length`)

---

### CLAY_ID

`Clay_ElementId CLAY_ID(STRING_LITERAL idString)`

**CLAY_ID()** is used to generate and attach a [Clay_ElementId](#clay_elementid) to a layout element during declaration.

Note this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SID](#clay_sid). 

To regenerate the same ID outside of layout declaration when using utility functions such as [Clay_PointerOver](#clay_pointerover), use the [Clay_GetElementId](#clay_getelementid) function.

**Examples**

```C
// Tag a button with the Id "Button"
CLAY(CLAY_ID("Button"), {
    .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }
}) {
    // ...children
}

// Later on outside of layout code
bool buttonIsHovered = Clay_IsPointerOver(Clay_GetElementId("Button"));
if (buttonIsHovered && leftMouseButtonPressed) {
    // ... do some click handling
}
```

---

### CLAY_SID()

`Clay_ElementId CLAY_SID(Clay_String idString)`

A version of [CLAY_ID](#clay_id) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.

---

### CLAY_IDI()

`Clay_ElementId CLAY_IDI(STRING_LITERAL idString, int32_t index)`

An offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_elementid) string id from the provided `char *label`, combined with the `int index`.

Used for generating ids for sequential elements (such as in a `for` loop) without having to construct dynamic strings at runtime.

Note this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SIDI](#clay_sidi).

---

### CLAY_SIDI()

`Clay_ElementId CLAY_SIDI(Clay_String idString, int32_t index)`

A version of [CLAY_IDI](#clay_idi) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.

---

### CLAY_ID_LOCAL()

**Usage**

`Clay_ElementId CLAY_ID_LOCAL(STRING_LITERAL idString)`

**Lifecycle**

`Clay_BeginLayout()` -> `CLAY(` -> `CLAY_ID_LOCAL()` -> `)` -> `Clay_EndLayout()`

**Notes**

**CLAY_ID_LOCAL()** is used to generate and attach a [Clay_ElementId](#clay_elementid) to a layout element during declaration.

Unlike [CLAY_ID](#clay_id) which needs to be globally unique, a local ID is based on the ID of it's parent and only needs to be unique among its siblings.

As a result, local id is suitable for use in reusable components and loops.

Note this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SID_LOCAL](#clay_sid_local).

**Examples**

```C
void RenderHeaderButton(ButtonData button) {
    CLAY({
        .id = CLAY_ID_LOCAL("HeaderButton"),
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }
    }) {
        // ...children
    }
}

for (int i = 0; i < headerButtons.length; i++) {
    RenderHeaderButton(headerButtons.items[i]);
}
```

---

### CLAY_SID_LOCAL()

`Clay_ElementId CLAY_SID_LOCAL(Clay_String idString)`

A version of [CLAY_ID_LOCAL](#clay_id_local) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.

---

### CLAY_IDI_LOCAL()

`Clay_ElementId CLAY_IDI_LOCAL(STRING_LITERAL idString, int32_t index)`

An offset version of [CLAY_ID_LOCAL](#clay_local_id). Generates a [Clay_ElementId](#clay_elementid) string id from the provided `char *label`, combined with the `int index`.

Used for generating ids for sequential elements (such as in a `for` loop) without having to construct dynamic strings at runtime.

Note this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SIDI_LOCAL](#clay_sidi_local).

---

### CLAY_SIDI_LOCAL()

`Clay_ElementId CLAY_SIDI_LOCAL(Clay_String idString, int32_t index)`

A version of [CLAY_IDI_LOCAL](#clay_idi_local) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.

---

## Data Structures & Definitions

### Clay_ElementDeclaration
The **Clay_ElementDeclaration** struct is the only argument to the `CLAY()` macro and provides configuration options for layout elements.

```C
typedef struct {
    Clay_ElementId id;
    Clay_LayoutConfig layout;
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    Clay_AspectRatioElementConfig aspectRatio;
    Clay_ImageElementConfig image;
    Clay_FloatingElementConfig floating;
    Clay_CustomElementConfig custom;
    Clay_ClipElementConfig clip;
    Clay_BorderElementConfig border;
    void *userData;
} Clay_ElementDeclaration;
```

**Fields**

**`.layout`** - `Clay_LayoutConfig`

`CLAY(CLAY_ID("Element"), { .layout = { .padding = { 16, 16, 12, 12 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } })`

Uses [Clay_LayoutConfig](#clay_layoutconfig). Controls various settings related to _layout_, which can be thought of as "the size and position of this element and its children".

---

**`.backgroundColor`** - `Clay_Color`

`CLAY(CLAY_ID("Element"), { .backgroundColor = {120, 120, 120, 255} } })`

Uses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.

---

**`.cornerRadius`** - `float`

`CLAY(CLAY_ID("Element"), { .cornerRadius = { .topLeft = 16, .topRight = 16, .bottomLeft = 16, .bottomRight = 16 } })`

Defines the radius in pixels for the arc of rectangle corners (`0` is square, `rectangle.width / 2` is circular).

Note that the `CLAY_CORNER_RADIUS(radius)` function-like macro is available to provide short hand for setting all four corner radii to the same value. e.g. `CLAY_BORDER({ .cornerRadius = CLAY_CORNER_RADIUS(10) })`

---

**`.aspectRatio`** - `Clay_AspectRatioElementConfig`

`CLAY(CLAY_ID("Element"), { .aspectRatio = 1 })`

Uses [Clay_AspectRatioElementConfig](#clay_aspectratioelementconfig). Configures the element as an aspect ratio scaling element. Especially useful for rendering images, but can also be used to enforce a fixed width / height ratio of other elements.

---

**`.image`** - `Clay_ImageElementConfig`

`CLAY(CLAY_ID("Element"), { .image = { .imageData = &myImage } })`

Uses [Clay_ImageElementConfig](#clay_imageelementconfig). Configures the element as an image element. Causes a render command with type `IMAGE` to be emitted.

---

**`.floating`** - `Clay_FloatingElementConfig`

`CLAY(CLAY_ID("Element"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } })`

Uses [Clay_FloatingElementConfig](#clay_floatingelementconfig). Configures the element as an floating element, which allows it to stack "in front" and "on top" of other elements without affecting sibling or parent size or position. 

---

**`.custom`** - `Clay_CustomElementConfig`

`CLAY(CLAY_ID("Element"), { .custom = { .customData = &my3DModel } })`

Uses [Clay_CustomElementConfig](#clay_customelementconfig). Configures the element as a custom element, which allows you to pass custom data through to the renderer. Causes a render command with type `CUSTOM` to be emitted.

---

**`.clip`** - `Clay_ClipElementConfig`

`CLAY(CLAY_ID("Element"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })`

Uses [Clay_ClipElementConfig](#clay_scrollelementconfig). Configures the element as a clip element, which causes child elements to be clipped / masked if they overflow, and together with the functions listed in [Scrolling Elements](#scrolling-elements) enables scrolling of child contents.

<img width="580" alt="An image demonstrating the concept of clipping which prevents rendering of a child elements pixels if they fall outside the bounds of the parent element." src="https://github.com/user-attachments/assets/2eb83ff9-e186-4ea4-8a87-d90cbc0838b5">

---

**`.border`** - `Clay_BorderElementConfig`

`CLAY(CLAY_ID("Element"), { .border = { .width = { .left = 5 }, .color = COLOR_BLUE } })`

Uses [Clay_BorderElementConfig](#clay_borderelementconfig). Configures the element as a border element, which instructs the renderer to draw coloured border lines along the perimeter of this element's bounding box. Causes a render command with type `BORDER` to be emitted.

---

**`.userData`** - `void *`

`CLAY(CLAY_ID("Element"), { .userData = &extraData })`

Transparently passes a pointer through to the corresponding [Clay_RenderCommands](#clay_rendercommand)s generated by this element.

---

**Examples**

```C
// Declare a reusable rectangle config, with a purple color and 10px rounded corners
Clay_RectangleElementConfig rectangleConfig = (Clay_RectangleElementConfig) { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) };
// Declare a rectangle element using a reusable config
CLAY(CLAY_ID("Box"), rectangleConfig) {}
// Declare a retangle element using an inline config
CLAY(CLAY_ID("BoxInline"), { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
    // child elements
}
// Declare a scrolling container with a colored background
CLAY(CLAY_ID("ScrollingContainer"), { 
    .backgroundColor = { 200, 200, 100, 255 }, 
    .cornerRadius = CLAY_CORNER_RADIUS(10)
    .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
) {
    // child elements
}
```

Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_RECTANGLE` will be created, with `renderCommand->elementConfig.rectangleElementConfig` containing a pointer to the element's Clay_RectangleElementConfig.

### Clay_LayoutConfig

**Clay_LayoutConfig** is used for configuring _layout_ options (i.e. options that affect the final position and size of an element, its parents, siblings, and children)

**Struct API (Pseudocode)**

```C
// CLAY({ .layout = { ...fields } }) supports these options
Clay_LayoutConfig {
    Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;
    Clay_Padding padding {
        u16 left; u16 right; u16 top; u16 bottom; 
    };
    uint16_t childGap;
    Clay_ChildAlignment childAlignment {
        .x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;
        .y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;
    };
    Clay_Sizing sizing { // Recommended to use the provided macros here - see #sizing for more in depth explanation
        .width = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float width) | CLAY_SIZING_PERCENT(float percent)
        .height = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float height) | CLAY_SIZING_PERCENT(float percent)
    }; // See CLAY_SIZING_GROW() etc for more details
};
```

**Fields**

**`.layoutDirection`** - `Clay_LayoutDirection`

`CLAY(CLAY_ID("Element"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } })`

Controls the axis / direction in which child elements are laid out. Available options are `CLAY_LEFT_TO_RIGHT` (default) and `CLAY_TOP_TO_BOTTOM`.

_Did you know that "left to right" and "top to bottom" both have 13 letters?_

<img width="580" alt="Screenshot 2024-08-22 at 11 10 27 AM" src="https://github.com/user-attachments/assets/7008aa47-8826-4338-9257-8bc83f7813ce">

---

**`.padding`** - `Clay_Padding`

`CLAY(CLAY_ID("Element"), { .layout = { .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } } })`

Controls white-space "padding" around the **outside** of child elements.

<img width="486" alt="Screenshot 2024-08-22 at 10 50 49 AM" src="https://github.com/user-attachments/assets/b454fa36-92d5-4b1d-bf8b-e4c25428e9de">

---

**`.childGap`** - `uint16_t`

`CLAY(CLAY_ID("Element"), { .layout = { .childGap = 16 } })`

Controls the white-space **between** child elements as they are laid out. When `.layoutDirection` is `CLAY_LEFT_TO_RIGHT` (default), this will be horizontal space, whereas for `CLAY_TOP_TO_BOTTOM` it will be vertical space.

<img width="600" alt="Screenshot 2024-08-22 at 11 05 15 AM" src="https://github.com/user-attachments/assets/fa0dae1f-1936-47f6-a299-634bd7d40d58">

---

**`.childAlignment`** - `Clay_ChildAlignment`

`CLAY(CLAY_ID("Element"), { .layout = { .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER } } })`

Controls the alignment of children relative to the height and width of the parent container. Available options are:
```C
.x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;
.y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;
```

<img width="1030" alt="Screenshot 2024-08-22 at 11 25 16 AM" src="https://github.com/user-attachments/assets/be61b4a7-db4f-447c-b6d6-b2d4a91fc664">

---

**`.sizing`** - `Clay_Sizing`

`CLAY(CLAY_ID("Element"), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_PERCENT(0.5) } } })`

Controls how final width and height of element are calculated. The same configurations are available for both the `.width` and `.height` axis. There are several options:

- `CLAY_SIZING_FIT(float min, float max) (default)` - The element will be sized to fit its children (plus padding and gaps), up to `max`. If `max` is left unspecified, it will default to `FLOAT_MAX`. When elements are compressed to fit into a smaller parent, this element will not shrink below `min`.

- `CLAY_SIZING_GROW(float min, float max)` - The element will grow to fill available space in its parent, up to `max`. If `max` is left unspecified, it will default to `FLOAT_MAX`. When elements are compressed to fit into a smaller parent, this element will not shrink below `min`.

- `CLAY_SIZING_FIXED(float fixed)` - The final size will always be exactly the provided `fixed` value. Shorthand for `CLAY_SIZING_FIT(fixed, fixed)`

- `CLAY_SIZING_PERCENT(float percent)` - Final size will be a percentage of parent size, minus padding and child gaps. `percent` is assumed to be a float between `0` and `1`.

<img width="1056" alt="Screenshot 2024-08-22 at 2 10 33 PM" src="https://github.com/user-attachments/assets/1236efb1-77dc-44cd-a207-7944e0f5e500">

<img width="1141" alt="Screenshot 2024-08-22 at 2 19 04 PM" src="https://github.com/user-attachments/assets/a26074ff-f155-4d35-9ca4-9278a64aac00">


**Example Usage**

```C
CLAY(CLAY_ID("Button"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) } }) {
    // Children will be laid out vertically with 16px of padding around and between
}
```

---

### Clay_ImageElementConfig
**Usage**

`CLAY(CLAY_ID("Element"), { .image = { ...image config } }) {}`

**Clay_ImageElementConfig** configures a clay element to render an image as its background.

**Struct API (Pseudocode)**

```C
Clay_ImageElementConfig {
    void * imageData;
};
```

**Fields**

**`.imageData`** - `void *`

`CLAY(CLAY_ID("Image"), { .image = { .imageData = &myImage } }) {}`

`.imageData` is a generic void pointer that can be used to pass through image data to the renderer.

```C
// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage("profilePicture.png");
// Note that when rendering, .imageData will be void* type.
CLAY(CLAY_ID("Image"), { .image = { .imageData = &profilePicture } }) {}
```

**Examples**

```C
// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage("profilePicture.png");
// Declare a reusable image config
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture };
// Declare an image element using a reusable config
CLAY(CLAY_ID("Image"), { .image = imageConfig }) {}
// Declare an image element using an inline config
CLAY(CLAY_ID("ImageInline"), { .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
// Rendering example
YourImage *imageToRender = renderCommand->elementConfig.imageElementConfig->imageData;
```

**Rendering**

Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_IMAGE` will be created. The user will need to access `renderCommand->renderData.image->imageData` to retrieve image data referenced during layout creation. It's also up to the user to decide how / if they wish to blend `renderCommand->renderData.image->backgroundColor` with the image.

---

### Clay_AspectRatioElementConfig

**Usage**

`CLAY(CLAY_ID("Aspect"), { .aspectRatio = 16.0 / 9.0 }) {}`

**Clay_AspectRatioElementConfig** configures a clay element to enforce a fixed width / height ratio in its final dimensions. Mostly used for image elements, but can also be used for non image elements.

**Struct API (Pseudocode)**

```C
Clay_AspectRatioElementConfig {
    float aspectRatio;
};
```

**Fields**

**`.aspectRatio`** - `float`

`CLAY(CLAY_ID("Aspect"), { .aspectRatio = { .aspectRatio = 16.0 / 9.0 } }) {}`

or alternatively, as C will automatically pass the value to the first nested struct field:

`CLAY(CLAY_ID("Aspect"), { .aspectRatio = 16.0 / 9.0 }) {}`

**Examples**

```C
// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage("profilePicture.png");
// Declare an image element that will grow along the X axis while maintaining its original aspect ratio
CLAY(CLAY_ID("ProfilePicture"), {
    .layout = { .width = CLAY_SIZING_GROW() },
    .aspectRatio = profilePicture.width / profilePicture.height,
    .image = { .imageData = &profilePicture },
}) {}
```

---

### Clay_ImageElementConfig
**Usage**

`CLAY(CLAY_ID("Image"), { .image = { ...image config } }) {}`

**Clay_ImageElementConfig** configures a clay element to render an image as its background.

**Struct API (Pseudocode)**

```C
Clay_ImageElementConfig {
    void * imageData;
};
```

**Fields**

**`.imageData`** - `void *`

`CLAY(CLAY_ID("Image"), { .image = { .imageData = &myImage } }) {}`

`.imageData` is a generic void pointer that can be used to pass through image data to the renderer.

```C
// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage("profilePicture.png");
// Note that when rendering, .imageData will be void* type.
CLAY(CLAY_ID("Image"), { .image = { .imageData = &profilePicture } }) {}
```

Note: for an image to maintain its original aspect ratio when using dynamic scaling, the [.aspectRatio](#clay_aspectratioelementconfig) config option must be used.

**Examples**

```C
// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage("profilePicture.png");
// Declare a reusable image config
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture };
// Declare an image element using a reusable config
CLAY(CLAY_ID("Image"), { .image = imageConfig }) {}
// Declare an image element using an inline config
CLAY(CLAY_ID("ImageInline"), { .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
// Rendering example
YourImage *imageToRender = renderCommand->elementConfig.imageElementConfig->imageData;
```

**Rendering**

Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_IMAGE` will be created. The user will need to access `renderCommand->renderData.image->imageData` to retrieve image data referenced during layout creation. It's also up to the user to decide how / if they wish to blend `renderCommand->renderData.image->backgroundColor` with the image.

---

### Clay_ClipElementConfig

**Usage**

`CLAY(CLAY_ID("ScrollBox"), { .clip = { ...clip config } }) {}`

**Notes**

`Clay_ClipElementConfig` configures the element as a clipping container, enabling masking of children that extend beyond its boundaries.

Note: In order to process scrolling based on pointer position and mouse wheel or touch interactions, you must call `Clay_SetPointerState()` and `Clay_UpdateScrollContainers()` _before_ calling `BeginLayout`.

**Struct Definition (Pseudocode)**

```C
Clay_ClipElementConfig {
    bool horizontal;
    bool vertical;
};
```

**Fields**

**`.horizontal`** - `bool`

`CLAY(CLAY_ID("HorizontalScroll"), { .clip = { .horizontal = true } })`

Enables or disables horizontal clipping for this container element.

---

**`.vertical`** - `bool`

`CLAY(LAY_ID("VerticalScroll"), { .clip = { .vertical = true } })`

Enables or disables vertical clipping for this container element.

---

**Rendering**

Enabling clip for an element will result in two additional render commands: 
- `commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_START`, which should create a rectangle mask with its `boundingBox` and is **not** subject to [culling](#visibility-culling)
- `commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_END`, which disables the previous rectangle mask and is **not** subject to [culling](#visibility-culling)

**Examples**

```C
CLAY(CLAY_ID("ScrollOuter"), { .clip = { .vertical = true } }) {
    // Create child content with a fixed height of 5000
    CLAY(CLAY_ID("ScrollInner"), { .layout = { .sizing = { .height = CLAY_SIZING_FIXED(5000) } } }) {}
}
```

---

### Clay_BorderElementConfig

**Usage**

`CLAY(CLAY_ID("Border"), { .border = { ...border config } }) {}`

**Notes**

`Clay_BorderElementConfig` adds borders to the edges or between the children of elements. It uses Clay_BorderElementConfig to configure border specific options.

**Struct Definition (Pseudocode)**

```C
typedef struct Clay_BorderElementConfig
{
    Clay_Color color {
        float r; float g; float b; float a;
    };
    Clay_BorderWidth width {
        uint16_t left;
        uint16_t right;
        uint16_t top;
        uint16_t bottom;
        uint16_t betweenChildren;  
    };
} Clay_BorderElementConfig;
```

**Fields**

**`.color`** - `Clay_Color`

`CLAY(CLAY_ID("Border"), { .border = { .color = { 255, 0, 0, 255 } } })`

Uses [Clay_Color](#clay_color). Specifies the shared color for all borders configured by this element. Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.

---

**`.width`** - `Clay_BorderWidth`

`CLAY(CLAY_ID("Border"), { .border = { .width = { .left = 2, .right = 10 } } })`

Indicates to the renderer that a border of `.color` should be draw at the specified edges of the bounding box, **inset and overlapping the box contents by `.width`**.

This means that border configuration does not affect layout, as the width of the border doesn't contribute to the total container width or layout position. Border containers with zero padding will be drawn over the top of child elements.

Note:

**`.width.betweenChildren`**

`CLAY(CLAY_ID("Border"), { .border = { .width = { .betweenChildren = 2 } }, .color = COLOR_RED })`

Configures the width and color of borders to be drawn between children. These borders will be vertical lines if the parent uses `.layoutDirection = CLAY_LEFT_TO_RIGHT` and horizontal lines if the parent uses `CLAY_TOP_TO_BOTTOM`. Unlike `.left, .top` etc, this option **will generate additional rectangle render commands representing the borders between children.** As a result, the renderer does not need to specifically implement rendering for these border elements.

---

**Examples**

```C
// 300x300 container with a 1px red border around all the edges
CLAY(CLAY_ID("OuterBorder"), {
    .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) } },
    .border = { .width = { 1, 1, 1, 1, 0 }, .color = COLOR_RED }
}) {
    // ...
}

// Container with a 3px yellow bottom border
CLAY(CLAY_ID("OuterBorder"), {
    .border = { .width = { .bottom = 3 }, .color = COLOR_YELLOW }
}) {
    // ...
}

// Container with a 5px curved border around the edges, and a 5px blue border between all children laid out top to bottom
CLAY(CLAY_ID("OuterBorder"), {
    .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM },
    .border = { .width = { 5, 5, 5, 5, 5 }, .color = COLOR_BLUE }
}) {
    // Child
    // -- 5px blue border will be here --
    // Child
    // -- 5px blue border will be here --
    // Child
}
```

**Rendering**

Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand` with `commandType = CLAY_RENDER_COMMAND_TYPE_BORDER` representing the container will be created.
Rendering of borders and rounded corners is left up to the user. See the provided [Raylib Renderer](https://github.com/nicbarker/clay/tree/main/renderers/raylib) for examples of how to draw borders using line and curve primitives.

---

### Clay_FloatingElementConfig

**Usage**

`CLAY(CLAY_ID("Floating"), { .floating = { ...floating config } }) {}`

**Notes**

**Floating Elements** defines an element that "floats" above other content. Typical use-cases include tooltips and modals.

Floating containers:

- With the default configuration, attach to the top left corner of their "parent" 
- Don't affect the width and height of their parent
- Don't affect the positioning of sibling elements
- Depending on their z-index can appear above or below other elements, partially or completely occluding them
- Apart from positioning, function just like standard elements - including expanding to fit their children, etc.

The easiest mental model to use when thinking about floating containers is that they are a completely separate UI hierarchy, attached to a specific x,y point on their "parent".

Floating elements uses `Clay_FloatingElementConfig` to configure specific options.

**Struct Definition (Pseudocode)**

```C
Clay_FloatingElementConfig {
    Clay_Vector2 offset {
        float x, float y
    };
    Clay_Dimensions expand {
        float width, float height
    };
    uint32_t parentId;
    int16_t zIndex;
    Clay_FloatingAttachPoints attachPoint {
        .element = CLAY_ATTACH_POINT_LEFT_TOP (default) | CLAY_ATTACH_POINT_LEFT_CENTER | CLAY_ATTACH_POINT_LEFT_BOTTOM | CLAY_ATTACH_POINT_CENTER_TOP | CLAY_ATTACH_POINT_CENTER_CENTER | CLAY_ATTACH_POINT_CENTER_BOTTOM | CLAY_ATTACH_POINT_RIGHT_TOP | CLAY_ATTACH_POINT_RIGHT_CENTER | CLAY_ATTACH_POINT_RIGHT_BOTTOM
        .parent = CLAY_ATTACH_POINT_LEFT_TOP (default) | CLAY_ATTACH_POINT_LEFT_CENTER | CLAY_ATTACH_POINT_LEFT_BOTTOM | CLAY_ATTACH_POINT_CENTER_TOP | CLAY_ATTACH_POINT_CENTER_CENTER | CLAY_ATTACH_POINT_CENTER_BOTTOM | CLAY_ATTACH_POINT_RIGHT_TOP | CLAY_ATTACH_POINT_RIGHT_CENTER | CLAY_ATTACH_POINT_RIGHT_BOTTOM
    };
    Clay_FloatingAttachToElement attachTo {
        CLAY_POINTER_CAPTURE_MODE_CAPTURE (default),
        CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH
    };
    Clay_FloatingAttachToElement attachTo {
        CLAY_ATTACH_TO_NONE (default),
        CLAY_ATTACH_TO_PARENT,
        CLAY_ATTACH_TO_ELEMENT_WITH_ID,
        CLAY_ATTACH_TO_ROOT,
    };
};
```

**Fields**

**`.offset`** - `Clay_Vector2`

`CLAY(CLAY_ID("Floating"), { .floating = { .offset = { -24, -24 } } })`

Used to apply a position offset to the floating container _after_ all other layout has been calculated. 

---

**`.expand`** - `Clay_Dimensions`

`CLAY(CLAY_ID("Floating"), { .floating = { .expand = { 16, 16 } } })`

Used to expand the width and height of the floating container _before_ laying out child elements.

---

**`.zIndex`** - `float`

`CLAY(CLAY_ID("Floating"), { .floating = { .zIndex = 1 } })`

All floating elements (as well as their entire child hierarchies) will be sorted by `.zIndex` order before being converted to render commands. If render commands are drawn in order, elements with higher `.zIndex` values will be drawn on top.

---

**`.parentId`** - `uint32_t`

`CLAY(CLAY_ID("Floating"), { .floating = { .parentId = Clay_GetElementId("HeaderButton").id } })`

By default, floating containers will "attach" to the parent element that they are declared inside. However, there are cases where this limitation could cause significant performance or ergonomics problems. `.parentId` allows you to specify a `CLAY_ID().id` to attach the floating container to. The parent element with the matching id can be declared anywhere in the hierarchy, it doesn't need to be declared before or after the floating container in particular.  

Consider the following case:
```C
// Load an image somewhere in your code
CLAY(CLAY_IDI("SidebarButton", 1), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 1) {
        CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI("SidebarButton", 2), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 2) {
        CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI("SidebarButton", 3), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 3) {
        CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI("SidebarButton", 4), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 4) {
        CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI("SidebarButton", 5), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 5) {
        CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
    }
}
```

The definition of the above UI is significantly polluted by the need to conditionally render floating tooltips as a child of many possible elements. The alternative, using `parentId`, looks like this:

```C
// Load an image somewhere in your code
CLAY(CLAY_IDI("SidebarButton", 1), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI("SidebarButton", 2), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI("SidebarButton", 3), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI("SidebarButton", 4), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI("SidebarButton", 5), { }) {
    // .. some button contents
}

// Any other point in the hierarchy
CLAY(CLAY_ID("OptionTooltip"), { .floating = { .attachTo = CLAY_ATTACH_TO_ELEMENT_ID, .parentId = CLAY_IDI("SidebarButton", tooltip.attachedButtonIndex).id }) {
    // Tooltip contents...
}
```

---

**`.attachment`** - `Clay_FloatingAttachPoints`

`CLAY(CLAY_ID("Floating"), { .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } }) {}`

In terms of positioning the floating container, `.attachment` specifies 

- The point on the floating container (`.element`)
- The point on the parent element that it "attaches" to (`.parent`)

![Screenshot 2024-08-23 at 11 47 21 AM](https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce)

You can mentally visualise this as finding a point on the floating container, then finding a point on the parent, and lining them up over the top of one another.

For example:

"Attach the LEFT_CENTER of the floating container to the RIGHT_TOP of the parent"

`CLAY(CLAY_ID("Floating"), { .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } });`

![Screenshot 2024-08-23 at 11 53 24 AM](https://github.com/user-attachments/assets/ebe75e0d-1904-46b0-982d-418f929d1516)

**`.pointerCaptureMode`** - `Clay_PointerCaptureMode`

`CLAY({ .floating = { .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_CAPTURE } })`

Controls whether pointer events like hover and click should pass through to content underneath this floating element, or whether the pointer should be "captured" by this floating element. Defaults to `CLAY_POINTER_CAPTURE_MODE_CAPTURE`. 

**Examples**

```C
// Horizontal container with three option buttons
CLAY(CLAY_ID("OptionsList"), { .layout = { childGap = 16 } }) {
    CLAY(CLAY_IDI("Option", 1), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING("Option 1"), CLAY_TEXT_CONFIG());
    }
    CLAY(CLAY_IDI("Option", 2), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING("Option 2"), CLAY_TEXT_CONFIG());
        // Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
        CLAY(CLAY_ID("OptionTooltip"), { .floating = { .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } } }) {
            CLAY_TEXT(CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
        }
    }
    CLAY(CLAY_IDI("Option", 3), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING("Option 3"), CLAY_TEXT_CONFIG());
    }
}

// Floating containers can also be declared elsewhere in a layout, to avoid branching or polluting other UI
for (int i = 0; i < 1000; i++) {
    CLAY(CLAY_IDI("Option", i + 1), { }) {
        // ...
    }
}
// Note the use of "parentId".
// Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
CLAY(CLAY_ID("OptionTooltip"), { .floating = { .parentId = CLAY_IDI("Option", 2).id, .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_TOP_CENTER } } }) {
    CLAY_TEXT(CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
}
```

When using `.parentId`, the floating container can be declared anywhere after `BeginLayout` and before `EndLayout`. The target element matching the `.parentId` doesn't need to exist when `Clay_FloatingElementConfig` is used.

**Rendering**

`Clay_FloatingElementConfig` will not generate any specific render commands.

---

### Clay_CustomElementConfig

**Usage**

`CLAY(CLAY_ID("Custom"), { .custom = { .customData = &something } }) {}`

**Notes**

**Clay_CustomElementConfig** allows the user to pass custom data to the renderer. 

**Struct Definition (Pseudocode)** 

```C
typedef struct
{
    void * customData;
} Clay_CustomElementConfig;
```

**Fields**

`.customData` - `void *`

`CLAY({ .custom = { .customData = &myCustomData } })`

`.customData` is a generic void pointer that can be used to pass through custom data to the renderer.

**Examples**
```C
#include "clay.h"

typedef enum {
    CUSTOM_ELEMENT_TYPE_MODEL,
    CUSTOM_ELEMENT_TYPE_VIDEO
} CustomElementType;

// A rough example of how you could handle laying out 3d models in your UI
typedef struct {
    CustomElementType type;
    union {
        Model model;
        Video video;
        // ...
    };
} CustomElementData;

Model myModel = Load3DModel(filePath);
CustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }

typedef struct {
    void* memory;
    uintptr_t offset;
} Arena;

// During init
Arena frameArena = (Arena) { .memory = malloc(1024) };

// ...
CLAY(0) {
    // Custom elements only take a single pointer, so we need to store the data somewhere
    CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
    *modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
    frameArena.offset += sizeof(CustomElementData);
    CLAY(CLAY_ID("3DModelViewer"), { .custom = { .customData = modelData } }) {}
}

// Later during your rendering
switch (renderCommand->commandType) {
    // ...
    case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
        // Your extended struct is passed through
        CustomElementData *customElement = renderCommand->config.customElementConfig->customData;
        if (!customElement) continue;
        switch (customElement->type) {
            case CUSTOM_ELEMENT_TYPE_MODEL: {
                // Render your 3d model here
                break;
            }
            case CUSTOM_ELEMENT_TYPE_VIDEO: {
                // Render your video here
                break;
            }
            // ...
        }
        break;
    }
}
```

**Rendering**

Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand` with `commandType = CLAY_RENDER_COMMAND_TYPE_CUSTOM` will be created.

### Clay_Color

```C
typedef struct {
    float r, g, b, a;
} Clay_Color;
```

`Clay_Color` is an RGBA color struct used in Clay's declarations and rendering. By convention the channels are represented as 0-255, but this is left up to the renderer.
Note: when using the debug tools, their internal colors are represented as 0-255.

### Clay_String

```C
typedef struct {
    bool isStaticallyAllocated;
    int32_t length;
    const char *chars;
} Clay_String;
```

`Clay_String` is a string container that clay uses internally to represent all strings.

**Fields**

**`.isStaticallyAllocated`** - `bool`

Whether or not the string is statically allocated, or in other words, whether
or not it lives for the entire lifetime of the program.

---

**`.length`** - `int32_t`

The number of characters in the string, _not including an optional null terminator._

---

**`.chars`** - `const char *`

A pointer to the contents of the string. This data is not guaranteed to be null terminated, so if you are passing it to code that expects standard null terminated C strings, you will need to copy the data and append a null terminator.

---

### Clay_ElementId

```C
typedef struct {
    uint32_t id;
    uint32_t offset;
    uint32_t baseId;
    Clay_String stringId;
} Clay_ElementId;
```

Returned by [CLAY_ID](#clay_id) and [CLAY_IDI](#clay_idi), this struct contains a hash id, as well as the source string that was used to generate it.

**Fields**

**`.id`** - `uint32_t`

A unique ID derived from the string passed to [CLAY_ID](#clay_id) or [CLAY_IDI](#clay_idi).

---

**`.offset`** - `uint32_t`

If this id was generated using [CLAY_IDI](#clay_idi), `.offset` is the value passed as the second argument. For [CLAY_ID](#clay_id), this will always be `0`.

---

**`.baseId`** - `uint32_t`

If this id was generated using [CLAY_IDI](#clay_idi), `.baseId` is the hash of the base string passed, **before it is additionally hashed with `.offset`**. For [CLAY_ID](#clay_id), this will always be the same as `.id`.

---

**`.stringId`** - `Clay_String`

Stores the original string that was passed in when [CLAY_ID](#clay_id) or [CLAY_IDI](#clay_idi) were called.

---

### Clay_RenderCommandArray

```C
typedef struct
{
	uint32_t capacity;
	uint32_t length;
	Clay_RenderCommand *internalArray;
} Clay_RenderCommandArray;
```

Returned by [Clay_EndLayout](#clay_endlayout), this array contains the [Clay_RenderCommand](#clay_rendercommand)s representing the calculated layout.

**Fields**

**`.capacity`** - `uint32_t`

Represents the total capacity of the allocated memory in `.internalArray`.

---

**`.length`** - `uint32_t`

Represents the total number of `Clay_RenderCommand` elements stored consecutively at the address `.internalArray`.

---

**`.internalArray`** - `Clay_RenderCommand`

An array of [Clay_RenderCommand](#clay_rendercommand)s representing the calculated layout. If there was at least one render command, this array will contain elements from `.internalArray[0]` to `.internalArray[.length - 1]`.

---

### Clay_RenderCommand

```C
typedef struct {
    Clay_BoundingBox boundingBox;
    Clay_RenderData renderData;
    uintptr_t userData;
    uint32_t id;
    int16_t zIndex;
    Clay_RenderCommandType commandType;
} Clay_RenderCommand;
```

**Fields**

**`.commandType`** - `Clay_RenderCommandType`

An enum indicating how this render command should be handled. Possible values include:

- `CLAY_RENDER_COMMAND_TYPE_NONE` - Should be ignored by the renderer, and never emitted by clay under normal conditions.
- `CLAY_RENDER_COMMAND_TYPE_RECTANGLE` - A rectangle should be drawn, configured with `.config.rectangleElementConfig`
- `CLAY_RENDER_COMMAND_TYPE_BORDER` - A border should be drawn, configured with `.config.borderElementConfig`
- `CLAY_RENDER_COMMAND_TYPE_TEXT` - Text should be drawn, configured with `.config.textElementConfig`
- `CLAY_RENDER_COMMAND_TYPE_IMAGE` - An image should be drawn, configured with `.config.imageElementConfig`
- `CLAY_RENDER_COMMAND_TYPE_SCISSOR_START` - Named after [glScissor](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glScissor.xhtml), this indicates that the renderer should begin culling any subsequent pixels that are drawn outside the `.boundingBox` of this render command.
- `CLAY_RENDER_COMMAND_TYPE_SCISSOR_END` - Only ever appears after a matching `CLAY_RENDER_COMMAND_TYPE_SCISSOR_START` command, and indicates that the scissor has ended.
- `CLAY_RENDER_COMMAND_TYPE_CUSTOM` - A custom render command controlled by the user, configured with `.config.customElementConfig`

---

**`.boundingBox`** - `Clay_BoundingBox`

```C
typedef struct {
    float x, y, width, height;
} Clay_BoundingBox;
```

A rectangle representing the bounding box of this render command, with `.x` and `.y` representing the top left corner of the element.

---

**`.id`** - `uint32_t`

The id that was originally used with the element macro that created this render command. See [CLAY_ID](#clay_id) for details.

---

**`.zIndex`** - `int16_t`

The z index of the element, based on what was passed to the root floating configuration that this element is a child of.
Higher z indexes should be rendered _on top_ of lower z indexes.

---

**`.renderData`** - `Clay_RenderData`

```C
typedef union {
    Clay_RectangleRenderData rectangle;
    Clay_TextRenderData text;
    Clay_ImageRenderData image;
    Clay_CustomRenderData custom;
    Clay_BorderRenderData border;
} Clay_RenderData;
```

A C union containing various structs, with the type dependent on `.commandType`. Possible values include:

- `config.rectangle` - Used when `.commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE`.
- `config.text` - Used when `.commandType == CLAY_RENDER_COMMAND_TYPE_TEXT`. See [Clay_Text](#clay_text) for details.
- `config.image` - Used when `.commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE`. See [Clay_Image](#clay_imageelementconfig) for details.
- `config.border` - Used when `.commandType == CLAY_RENDER_COMMAND_TYPE_BORDER`. See [Clay_Border](#clay_borderelementconfig) for details.
- `config.custom` - Used when `.commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM`. See [Clay_Custom](#clay_customelementconfig) for details.

**Union Structs**

```C
typedef struct {
    Clay_StringSlice stringContents;
    Clay_Color textColor;
    uint16_t fontId;
    uint16_t fontSize;
    uint16_t letterSpacing;
    uint16_t lineHeight;
} Clay_TextRenderData;
```

```C
typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
} Clay_RectangleRenderData;
```

```C
typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    void* imageData;
} Clay_ImageRenderData;
```

```C
typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    void* customData;
} Clay_CustomRenderData;
```

```C
typedef struct {
    Clay_Color color;
    Clay_CornerRadius cornerRadius;
    Clay_BorderWidth width;
} Clay_BorderRenderData;
```

```C
typedef union {
    Clay_RectangleRenderData rectangle;
    Clay_TextRenderData text;
    Clay_ImageRenderData image;
    Clay_CustomRenderData custom;
    Clay_BorderRenderData border;
} Clay_RenderData;
```

### Clay_ScrollContainerData

```C
// Data representing the current internal state of a scrolling element.
typedef struct {
    // Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
    // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
    Clay_Vector2 *scrollPosition;
    // The bounding box of the scroll element.
    Clay_Dimensions scrollContainerDimensions;
    // The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
    Clay_Dimensions contentDimensions;
    // The config that was originally passed to the scroll element.
    Clay_ClipElementConfig config;
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ScrollContainerData;
```

**Fields**

**`.scrollPosition`** - `Clay_Vector2 *`

A pointer to the internal scroll position of this scroll container. Mutating it will result in elements inside the scroll container shifting up / down (`.y`) or left / right (`.x`).

---

**`.scrollContainerDimensions`** - `Clay_Dimensions`

```C
typedef struct {
    float width, height;
} Clay_Dimensions;
```

Dimensions representing the outer width and height of the scroll container itself.

---

**`.contentDimensions`** - `Clay_Dimensions`

```C
typedef struct {
    float width, height;
} Clay_Dimensions;
```

Dimensions representing the inner width and height of the content _inside_ the scroll container. Scrolling is only possible when the `contentDimensions` are larger in at least one dimension than the `scrollContainerDimensions`.

---

**`.config`** - `Clay_ClipElementConfig`

The [Clay_ClipElementConfig](#clay_scroll) for the matching scroll container element.

---

### Clay_ElementData

```C
// Bounding box and other data for a specific UI element.
typedef struct {
    // The rectangle that encloses this UI element, with the position relative to the root of the layout.
    Clay_BoundingBox boundingBox;
    // Indicates whether an actual Element matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ElementData;
```

**Fields**

**`.boundingBox`** - `Clay_BoundingBox`

```C
typedef struct {
    float x, y, width, height;
} Clay_BoundingBox;
```

A rectangle representing the bounding box of this render command, with `.x` and `.y` representing the top left corner of the element.

---

**`.found`** - `bool`

A boolean representing whether or not the ID passed to [Clay_GetElementData](#clay_getelementdata) matched a valid element or not. In the case that `.found` is `false`, `.boundingBox` will be the default value (zeroed).

---

### Clay_PointerData

```C
typedef struct
{
    Clay_Vector2 position;
    Clay_PointerDataInteractionState state;
} Clay_PointerData;
```

**Fields**

**`.position`** - `Clay_Vector2`

A Vector2 containing the current x,y coordinates of the mouse pointer, which were originally passed into [Clay_SetPointerState()](#clay_setpointerstate).

---

**`.state`** - `Clay_PointerDataInteractionState`

```C
typedef enum
{
    CLAY_POINTER_DATA_PRESSED_THIS_FRAME,
    CLAY_POINTER_DATA_PRESSED,
    CLAY_POINTER_DATA_RELEASED_THIS_FRAME,
    CLAY_POINTER_DATA_RELEASED,
} Clay_PointerDataInteractionState;
```

An enum value representing the current "state" of the pointer interaction. As an example, consider the case where a user is on a desktop computer, moves the mouse pointer over a button, clicks and holds the left mouse button for a short time, then releases it:

- While the mouse pointer is over ("hovering") the button, but no mouse button has been pressed: `CLAY_POINTER_DATA_RELEASED`
- First frame that the user presses the left mouse button: `CLAY_POINTER_DATA_PRESSED_THIS_FRAME`
- All subsequent frames where the user is still holding the left mouse button: `CLAY_POINTER_DATA_PRESSED`
- The single frame where the left mouse button goes from pressed -> released: `CLAY_POINTER_DATA_RELEASED_THIS_FRAME`
- All subsequent frames while the mouse pointer is still over the button: `CLAY_POINTER_DATA_RELEASED`

---

### Clay_ErrorHandler

```C
typedef struct
{
    void (*errorHandlerFunction)(Clay_ErrorData errorText);
    uintptr_t userData;
} Clay_ErrorHandler;
```

**Fields**

**`.errorHandlerFunction`** - `void (Clay_ErrorData errorText) {}`

A function pointer to an error handler function, which takes `Clay_ErrorData` as an argument. This function will be called whenever Clay encounters an internal error.

---

**`.userData`** - `uintptr_t`

A generic pointer to extra userdata that is transparently passed through from `Clay_Initialize` to Clay's error handler callback. Defaults to NULL.

---

### Clay_ErrorData

```C
typedef struct
{
    Clay_ErrorType errorType;
    Clay_String errorText;
    uintptr_t userData;
} Clay_ErrorData;
```

**Fields**

**`.errorType`** - `Clay_ErrorType`

```C
typedef enum {
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
    CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_DUPLICATE_ID,
    CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
    CLAY_ERROR_TYPE_INTERNAL_ERROR,
} Clay_ErrorType;
```

An enum representing the type of error Clay encountered. It's up to the user to handle on a case by case basis, but as some general guidance:

- `CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED` - The user is attempting to use `CLAY_TEXT` and either forgot to call [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction) or accidentally passed a null function pointer.
- `CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED` - Clay was initialized with an Arena that was too small for the configured [Clay_SetMaxElementCount](#clay_setmaxelementcount). Try using [Clay_MinMemorySize()](#clay_minmemorysize) to get the exact number of bytes required by the current configuration.
- `CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED` - The declared UI hierarchy has too many elements for the configured max element count. Use [Clay_SetMaxElementCount](#clay_setmaxelementcount) to increase the max, then call [Clay_MinMemorySize()](#clay_minmemorysize) again and reinitialize clay's memory with the required size.
- `CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED` - The declared UI hierarchy has too much text for the configured text measure cache size. Use [Clay_SetMaxMeasureTextCacheWordCount](#clay_setmeasuretextcachesize) to increase the max, then call [Clay_MinMemorySize()](#clay_minmemorysize) again and reinitialize clay's memory with the required size.
- `CLAY_ERROR_TYPE_DUPLICATE_ID` - Two elements in Clays UI Hierarchy have been declared with exactly the same ID. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.
- `CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND` - A `CLAY_FLOATING` element was declared with the `.parentId` property, but no element with that ID was found. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.
- `CLAY_ERROR_TYPE_INTERNAL_ERROR` - Clay has encountered an internal logic or memory error. Please report this as a bug with a stack trace to help us fix these!

---

**`.errorText`** - `Clay_String`

A [Clay_String](#clay_string) that provides a human readable description of the error. May change in future and should not be relied on to detect error types.

---

**`.userData`** - `uintptr_t`

A generic pointer to extra userdata that is transparently passed through from `Clay_Initialize` to Clay's error handler callback. Defaults to NULL.

---


================================================
FILE: bindings/cpp/README.md
================================================
https://github.com/TimothyHoytBSME/ClayMan

================================================
FILE: bindings/csharp/README
================================================
https://github.com/Orcolom/clay-cs


================================================
FILE: bindings/rust/README
================================================
https://github.com/clay-ui-rs/clay
https://crates.io/crates/clay-layout

================================================
FILE: bindings/zig/README
================================================
https://codeberg.org/Zettexe/clay-zig
https://github.com/johan0A/clay-zig-bindings


================================================
FILE: clay.h
================================================
// VERSION: 0.14

/*
    NOTE: In order to use this library you must define
    the following macro in exactly one file, _before_ including clay.h:

    #define CLAY_IMPLEMENTATION
    #include "clay.h"

    See the examples folder for details.
*/

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

// SIMD includes on supported platforms
#if !defined(CLAY_DISABLE_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64))
#include <emmintrin.h>
#elif !defined(CLAY_DISABLE_SIMD) && defined(__aarch64__)
#include <arm_neon.h>
#endif

// -----------------------------------------
// HEADER DECLARATIONS ---------------------
// -----------------------------------------

#ifndef CLAY_HEADER
#define CLAY_HEADER

#if !( \
    (defined(__cplusplus) && __cplusplus >= 202002L) || \
    (defined(__STDC__) && __STDC__ == 1 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
    defined(_MSC_VER) || \
    defined(__OBJC__) \
)
#error "Clay requires C99, C++20, or MSVC"
#endif

#ifdef CLAY_WASM
#define CLAY_WASM_EXPORT(name) __attribute__((export_name(name)))
#else
#define CLAY_WASM_EXPORT(null)
#endif

#ifdef CLAY_DLL
#define CLAY_DLL_EXPORT __declspec(dllexport) __stdcall
#else
#define CLAY_DLL_EXPORT
#endif

// Public Macro API ------------------------

#define CLAY__MAX(x, y) (((x) > (y)) ? (x) : (y))
#define CLAY__MIN(x, y) (((x) < (y)) ? (x) : (y))

#define CLAY_TEXT_CONFIG(...) Clay__StoreTextElementConfig(CLAY__CONFIG_WRAPPER(Clay_TextElementConfig, __VA_ARGS__))

#define CLAY_BORDER_OUTSIDE(widthValue) {widthValue, widthValue, widthValue, widthValue, 0}

#define CLAY_BORDER_ALL(widthValue) {widthValue, widthValue, widthValue, widthValue, widthValue}

#define CLAY_CORNER_RADIUS(radius) (CLAY__INIT(Clay_CornerRadius) { radius, radius, radius, radius })

#define CLAY_PADDING_ALL(padding) CLAY__CONFIG_WRAPPER(Clay_Padding, { padding, padding, padding, padding })

#define CLAY_SIZING_FIT(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_FIT })

#define CLAY_SIZING_GROW(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_GROW })

#define CLAY_SIZING_FIXED(fixedSize) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { fixedSize, fixedSize } }, .type = CLAY__SIZING_TYPE_FIXED })

#define CLAY_SIZING_PERCENT(percentOfParent) (CLAY__INIT(Clay_SizingAxis) { .size = { .percent = (percentOfParent) }, .type = CLAY__SIZING_TYPE_PERCENT })

// Note: If a compile error led you here, you might be trying to use CLAY_ID with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SID instead.
#define CLAY_ID(label) CLAY_SID(CLAY_STRING(label))

#define CLAY_SID(label) Clay__HashString(label, 0)

// Note: If a compile error led you here, you might be trying to use CLAY_IDI with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SIDI instead.
#define CLAY_IDI(label, index) CLAY_SIDI(CLAY_STRING(label), index)

#define CLAY_SIDI(label, index) Clay__HashStringWithOffset(label, index, 0)

// Note: If a compile error led you here, you might be trying to use CLAY_ID_LOCAL with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SID_LOCAL instead.
#define CLAY_ID_LOCAL(label) CLAY_SID_LOCAL(CLAY_STRING(label))

#define CLAY_SID_LOCAL(label) Clay__HashString(label, Clay__GetParentElementId())

// Note: If a compile error led you here, you might be trying to use CLAY_IDI_LOCAL with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SIDI_LOCAL instead.
#define CLAY_IDI_LOCAL(label, index) CLAY_SIDI_LOCAL(CLAY_STRING(label), index)

#define CLAY_SIDI_LOCAL(label, index) Clay__HashStringWithOffset(label, index, Clay__GetParentElementId())

#define CLAY__STRING_LENGTH(s) ((sizeof(s) / sizeof((s)[0])) - sizeof((s)[0]))

#define CLAY__ENSURE_STRING_LITERAL(x) ("" x "")

// Note: If an error led you here, it's because CLAY_STRING can only be used with string literals, i.e. CLAY_STRING("SomeString") and not CLAY_STRING(yourString)
#define CLAY_STRING(string) (CLAY__INIT(Clay_String) { .isStaticallyAllocated = true, .length = CLAY__STRING_LENGTH(CLAY__ENSURE_STRING_LITERAL(string)), .chars = (string) })

#define CLAY_STRING_CONST(string) { .isStaticallyAllocated = true, .length = CLAY__STRING_LENGTH(CLAY__ENSURE_STRING_LITERAL(string)), .chars = (string) }

static uint8_t CLAY__ELEMENT_DEFINITION_LATCH;

// GCC marks the above CLAY__ELEMENT_DEFINITION_LATCH as an unused variable for files that include clay.h but don't declare any layout
// This is to suppress that warning
static inline void Clay__SuppressUnusedLatchDefinitionVariableWarning(void) { (void) CLAY__ELEMENT_DEFINITION_LATCH; }

// Publicly visible layout element macros -----------------------------------------------------

/* This macro looks scary on the surface, but is actually quite simple.
  It turns a macro call like this:

  CLAY({
    .id = CLAY_ID("Container"),
    .backgroundColor = { 255, 200, 200, 255 }
  }) {
      ...children declared here
  }

  Into calls like this:

  Clay__OpenElement();
  Clay__ConfigureOpenElement((Clay_ElementDeclaration) {
    .id = CLAY_ID("Container"),
    .backgroundColor = { 255, 200, 200, 255 }
  });
  ...children declared here
  Clay__CloseElement();

  The for loop will only ever run a single iteration, putting Clay__CloseElement() in the increment of the loop
  means that it will run after the body - where the children are declared. It just exists to make sure you don't forget
  to call Clay_CloseElement().
*/
#define CLAY_AUTO_ID(...)                                                                                                                                   \
    for (                                                                                                                                                   \
        CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0);  \
        CLAY__ELEMENT_DEFINITION_LATCH < 1;                                                                                                                 \
        CLAY__ELEMENT_DEFINITION_LATCH=1, Clay__CloseElement()                                                                                              \
    )

#define CLAY(id, ...)                                                                                                                                               \
    for (                                                                                                                                                           \
        CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElementWithId(id), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0);  \
        CLAY__ELEMENT_DEFINITION_LATCH < 1;                                                                                                                         \
        CLAY__ELEMENT_DEFINITION_LATCH=1, Clay__CloseElement()                                                                                                      \
    )

// These macros exist to allow the CLAY() macro to be called both with an inline struct definition, such as
// CLAY({ .id = something... });
// As well as by passing a predefined declaration struct
// Clay_ElementDeclaration declarationStruct = ...
// CLAY(declarationStruct);
#define CLAY__WRAPPER_TYPE(type) Clay__##type##Wrapper
#define CLAY__WRAPPER_STRUCT(type) typedef struct { type wrapped; } CLAY__WRAPPER_TYPE(type)
#define CLAY__CONFIG_WRAPPER(type, ...) (CLAY__INIT(CLAY__WRAPPER_TYPE(type)) { __VA_ARGS__ }).wrapped

#define CLAY_TEXT(text, textConfig) Clay__OpenTextElement(text, textConfig)

#ifdef __cplusplus

#define CLAY__INIT(type) type

#define CLAY_PACKED_ENUM enum : uint8_t

#define CLAY__DEFAULT_STRUCT {}

#else

#define CLAY__INIT(type) (type)

#if defined(_MSC_VER) && !defined(__clang__)
#define CLAY_PACKED_ENUM __pragma(pack(push, 1)) enum __pragma(pack(pop))
#else
#define CLAY_PACKED_ENUM enum __attribute__((__packed__))
#endif

#if __STDC_VERSION__ >= 202311L
#define CLAY__DEFAULT_STRUCT {}
#else
#define CLAY__DEFAULT_STRUCT {0}
#endif

#endif // __cplusplus

#ifdef __cplusplus
extern "C" {
#endif

// Utility Structs -------------------------

// Note: Clay_String is not guaranteed to be null terminated. It may be if created from a literal C string,
// but it is also used to represent slices.
typedef struct Clay_String {
    // Set this boolean to true if the char* data underlying this string will live for the entire lifetime of the program.
    // This will automatically be set for strings created with CLAY_STRING, as the macro requires a string literal.
    bool isStaticallyAllocated;
    int32_t length;
    // The underlying character memory. Note: this will not be copied and will not extend the lifetime of the underlying memory.
    const char *chars;
} Clay_String;

// Clay_StringSlice is used to represent non owning string slices, and includes
// a baseChars field which points to the string this slice is derived from.
typedef struct Clay_StringSlice {
    int32_t length;
    const char *chars;
    const char *baseChars; // The source string / char* that this slice was derived from
} Clay_StringSlice;

typedef struct Clay_Context Clay_Context;

// Clay_Arena is a memory arena structure that is used by clay to manage its internal allocations.
// Rather than creating it by hand, it's easier to use Clay_CreateArenaWithCapacityAndMemory()
typedef struct Clay_Arena {
    uintptr_t nextAllocation;
    size_t capacity;
    char *memory;
} Clay_Arena;

typedef struct Clay_Dimensions {
    float width, height;
} Clay_Dimensions;

typedef struct Clay_Vector2 {
    float x, y;
} Clay_Vector2;

// Internally clay conventionally represents colors as 0-255, but interpretation is up to the renderer.
typedef struct Clay_Color {
    float r, g, b, a;
} Clay_Color;

typedef struct Clay_BoundingBox {
    float x, y, width, height;
} Clay_BoundingBox;

// Primarily created via the CLAY_ID(), CLAY_IDI(), CLAY_ID_LOCAL() and CLAY_IDI_LOCAL() macros.
// Represents a hashed string ID used for identifying and finding specific clay UI elements, required
// by functions such as Clay_PointerOver() and Clay_GetElementData().
typedef struct Clay_ElementId {
    uint32_t id; // The resulting hash generated from the other fields.
    uint32_t offset; // A numerical offset applied after computing the hash from stringId.
    uint32_t baseId; // A base hash value to start from, for example the parent element ID is used when calculating CLAY_ID_LOCAL().
    Clay_String stringId; // The string id to hash.
} Clay_ElementId;

// A sized array of Clay_ElementId.
typedef struct
{
    int32_t capacity;
    int32_t length;
    Clay_ElementId *internalArray;
} Clay_ElementIdArray;

// Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
typedef struct Clay_CornerRadius {
    float topLeft;
    float topRight;
    float bottomLeft;
    float bottomRight;
} Clay_CornerRadius;

// Element Configs ---------------------------

// Controls the direction in which child elements will be automatically laid out.
typedef CLAY_PACKED_ENUM {
    // (Default) Lays out child elements from left to right with increasing x.
    CLAY_LEFT_TO_RIGHT,
    // Lays out child elements from top to bottom with increasing y.
    CLAY_TOP_TO_BOTTOM,
} Clay_LayoutDirection;

// Controls the alignment along the x axis (horizontal) of child elements.
typedef CLAY_PACKED_ENUM {
    // (Default) Aligns child elements to the left hand side of this element, offset by padding.width.left
    CLAY_ALIGN_X_LEFT,
    // Aligns child elements to the right hand side of this element, offset by padding.width.right
    CLAY_ALIGN_X_RIGHT,
    // Aligns child elements horizontally to the center of this element
    CLAY_ALIGN_X_CENTER,
} Clay_LayoutAlignmentX;

// Controls the alignment along the y axis (vertical) of child elements.
typedef CLAY_PACKED_ENUM {
    // (Default) Aligns child elements to the top of this element, offset by padding.width.top
    CLAY_ALIGN_Y_TOP,
    // Aligns child elements to the bottom of this element, offset by padding.width.bottom
    CLAY_ALIGN_Y_BOTTOM,
    // Aligns child elements vertically to the center of this element
    CLAY_ALIGN_Y_CENTER,
} Clay_LayoutAlignmentY;

// Controls how the element takes up space inside its parent container.
typedef CLAY_PACKED_ENUM {
    // (default) Wraps tightly to the size of the element's contents.
    CLAY__SIZING_TYPE_FIT,
    // Expands along this axis to fill available space in the parent element, sharing it with other GROW elements.
    CLAY__SIZING_TYPE_GROW,
    // Expects 0-1 range. Clamps the axis size to a percent of the parent container's axis size minus padding and child gaps.
    CLAY__SIZING_TYPE_PERCENT,
    // Clamps the axis size to an exact size in pixels.
    CLAY__SIZING_TYPE_FIXED,
} Clay__SizingType;

// Controls how child elements are aligned on each axis.
typedef struct Clay_ChildAlignment {
    Clay_LayoutAlignmentX x; // Controls alignment of children along the x axis.
    Clay_LayoutAlignmentY y; // Controls alignment of children along the y axis.
} Clay_ChildAlignment;

// Controls the minimum and maximum size in pixels that this element is allowed to grow or shrink to,
// overriding sizing types such as FIT or GROW.
typedef struct Clay_SizingMinMax {
    float min; // The smallest final size of the element on this axis will be this value in pixels.
    float max; // The largest final size of the element on this axis will be this value in pixels.
} Clay_SizingMinMax;

// Controls the sizing of this element along one axis inside its parent container.
typedef struct Clay_SizingAxis {
    union {
        Clay_SizingMinMax minMax; // Controls the minimum and maximum size in pixels that this element is allowed to grow or shrink to, overriding sizing types such as FIT or GROW.
        float percent; // Expects 0-1 range. Clamps the axis size to a percent of the parent container's axis size minus padding and child gaps.
    } size;
    Clay__SizingType type; // Controls how the element takes up space inside its parent container.
} Clay_SizingAxis;

// Controls the sizing of this element along one axis inside its parent container.
typedef struct Clay_Sizing {
    Clay_SizingAxis width; // Controls the width sizing of the element, along the x axis.
    Clay_SizingAxis height;  // Controls the height sizing of the element, along the y axis.
} Clay_Sizing;

// Controls "padding" in pixels, which is a gap between the bounding box of this element and where its children
// will be placed.
typedef struct Clay_Padding {
    uint16_t left;
    uint16_t right;
    uint16_t top;
    uint16_t bottom;
} Clay_Padding;

CLAY__WRAPPER_STRUCT(Clay_Padding);

// Controls various settings that affect the size and position of an element, as well as the sizes and positions
// of any child elements.
typedef struct Clay_LayoutConfig {
    Clay_Sizing sizing; // Controls the sizing of this element inside it's parent container, including FIT, GROW, PERCENT and FIXED sizing.
    Clay_Padding padding; // Controls "padding" in pixels, which is a gap between the bounding box of this element and where its children will be placed.
    uint16_t childGap; // Controls the gap in pixels between child elements along the layout axis (horizontal gap for LEFT_TO_RIGHT, vertical gap for TOP_TO_BOTTOM).
    Clay_ChildAlignment childAlignment; // Controls how child elements are aligned on each axis.
    Clay_LayoutDirection layoutDirection; // Controls the direction in which child elements will be automatically laid out.
} Clay_LayoutConfig;

CLAY__WRAPPER_STRUCT(Clay_LayoutConfig);

extern Clay_LayoutConfig CLAY_LAYOUT_DEFAULT;

// Controls how text "wraps", that is how it is broken into multiple lines when there is insufficient horizontal space.
typedef CLAY_PACKED_ENUM {
    // (default) breaks on whitespace characters.
    CLAY_TEXT_WRAP_WORDS,
    // Don't break on space characters, only on newlines.
    CLAY_TEXT_WRAP_NEWLINES,
    // Disable text wrapping entirely.
    CLAY_TEXT_WRAP_NONE,
} Clay_TextElementConfigWrapMode;

// Controls how wrapped lines of text are horizontally aligned within the outer text bounding box.
typedef CLAY_PACKED_ENUM {
    // (default) Horizontally aligns wrapped lines of text to the left hand side of their bounding box.
    CLAY_TEXT_ALIGN_LEFT,
    // Horizontally aligns wrapped lines of text to the center of their bounding box.
    CLAY_TEXT_ALIGN_CENTER,
    // Horizontally aligns wrapped lines of text to the right hand side of their bounding box.
    CLAY_TEXT_ALIGN_RIGHT,
} Clay_TextAlignment;

// Controls various functionality related to text elements.
typedef struct Clay_TextElementConfig {
    // A pointer that will be transparently passed through to the resulting render command.
    void *userData;
    // The RGBA color of the font to render, conventionally specified as 0-255.
    Clay_Color textColor;
    // An integer transparently passed to Clay_MeasureText to identify the font to use.
    // The debug view will pass fontId = 0 for its internal text.
    uint16_t fontId;
    // Controls the size of the font. Handled by the function provided to Clay_MeasureText.
    uint16_t fontSize;
    // Controls extra horizontal spacing between characters. Handled by the function provided to Clay_MeasureText.
    uint16_t letterSpacing;
    // Controls additional vertical space between wrapped lines of text.
    uint16_t lineHeight;
    // Controls how text "wraps", that is how it is broken into multiple lines when there is insufficient horizontal space.
    // CLAY_TEXT_WRAP_WORDS (default) breaks on whitespace characters.
    // CLAY_TEXT_WRAP_NEWLINES doesn't break on space characters, only on newlines.
    // CLAY_TEXT_WRAP_NONE disables wrapping entirely.
    Clay_TextElementConfigWrapMode wrapMode;
    // Controls how wrapped lines of text are horizontally aligned within the outer text bounding box.
    // CLAY_TEXT_ALIGN_LEFT (default) - Horizontally aligns wrapped lines of text to the left hand side of their bounding box.
    // CLAY_TEXT_ALIGN_CENTER - Horizontally aligns wrapped lines of text to the center of their bounding box.
    // CLAY_TEXT_ALIGN_RIGHT - Horizontally aligns wrapped lines of text to the right hand side of their bounding box.
    Clay_TextAlignment textAlignment;
} Clay_TextElementConfig;

CLAY__WRAPPER_STRUCT(Clay_TextElementConfig);

// Aspect Ratio --------------------------------

// Controls various settings related to aspect ratio scaling element.
typedef struct Clay_AspectRatioElementConfig {
    float aspectRatio; // A float representing the target "Aspect ratio" for an element, which is its final width divided by its final height.
} Clay_AspectRatioElementConfig;

CLAY__WRAPPER_STRUCT(Clay_AspectRatioElementConfig);

// Image --------------------------------

// Controls various settings related to image elements.
typedef struct Clay_ImageElementConfig {
    void* imageData; // A transparent pointer used to pass image data through to the renderer.
} Clay_ImageElementConfig;

CLAY__WRAPPER_STRUCT(Clay_ImageElementConfig);

// Floating -----------------------------

// Controls where a floating element is offset relative to its parent element.
// Note: see https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce for a visual explanation.
typedef CLAY_PACKED_ENUM {
    CLAY_ATTACH_POINT_LEFT_TOP,
    CLAY_ATTACH_POINT_LEFT_CENTER,
    CLAY_ATTACH_POINT_LEFT_BOTTOM,
    CLAY_ATTACH_POINT_CENTER_TOP,
    CLAY_ATTACH_POINT_CENTER_CENTER,
    CLAY_ATTACH_POINT_CENTER_BOTTOM,
    CLAY_ATTACH_POINT_RIGHT_TOP,
    CLAY_ATTACH_POINT_RIGHT_CENTER,
    CLAY_ATTACH_POINT_RIGHT_BOTTOM,
} Clay_FloatingAttachPointType;

// Controls where a floating element is offset relative to its parent element.
typedef struct Clay_FloatingAttachPoints {
    Clay_FloatingAttachPointType element; // Controls the origin point on a floating element that attaches to its parent.
    Clay_FloatingAttachPointType parent; // Controls the origin point on the parent element that the floating element attaches to.
} Clay_FloatingAttachPoints;

// Controls how mouse pointer events like hover and click are captured or passed through to elements underneath a floating element.
typedef CLAY_PACKED_ENUM {
    // (default) "Capture" the pointer event and don't allow events like hover and click to pass through to elements underneath.
    CLAY_POINTER_CAPTURE_MODE_CAPTURE,
    //    CLAY_POINTER_CAPTURE_MODE_PARENT, TODO pass pointer through to attached parent

    // Transparently pass through pointer events like hover and click to elements underneath the floating element.
    CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
} Clay_PointerCaptureMode;

// Controls which element a floating element is "attached" to (i.e. relative offset from).
typedef CLAY_PACKED_ENUM {
    // (default) Disables floating for this element.
    CLAY_ATTACH_TO_NONE,
    // Attaches this floating element to its parent, positioned based on the .attachPoints and .offset fields.
    CLAY_ATTACH_TO_PARENT,
    // Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields.
    CLAY_ATTACH_TO_ELEMENT_WITH_ID,
    // Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning".
    CLAY_ATTACH_TO_ROOT,
} Clay_FloatingAttachToElement;

// Controls whether or not a floating element is clipped to the same clipping rectangle as the element it's attached to.
typedef CLAY_PACKED_ENUM {
    // (default) - The floating element does not inherit clipping.
    CLAY_CLIP_TO_NONE,
    // The floating element is clipped to the same clipping rectangle as the element it's attached to.
    CLAY_CLIP_TO_ATTACHED_PARENT
} Clay_FloatingClipToElement;

// Controls various settings related to "floating" elements, which are elements that "float" above other elements, potentially overlapping their boundaries,
// and not affecting the layout of sibling or parent elements.
typedef struct Clay_FloatingElementConfig {
    // Offsets this floating element by the provided x,y coordinates from its attachPoints.
    Clay_Vector2 offset;
    // Expands the boundaries of the outer floating element without affecting its children.
    Clay_Dimensions expand;
    // When used in conjunction with .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, attaches this floating element to the element in the hierarchy with the provided ID.
    // Hint: attach the ID to the other element with .id = CLAY_ID("yourId"), and specify the id the same way, with .parentId = CLAY_ID("yourId").id
    uint32_t parentId;
    // Controls the z index of this floating element and all its children. Floating elements are sorted in ascending z order before output.
    // zIndex is also passed to the renderer for all elements contained within this floating element.
    int16_t zIndex;
    // Controls how mouse pointer events like hover and click are captured or passed through to elements underneath / behind a floating element.
    // Enum is of the form CLAY_ATTACH_POINT_foo_bar. See Clay_FloatingAttachPoints for more details.
    // Note: see <img src="https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce />
    // and <img src="https://github.com/user-attachments/assets/ebe75e0d-1904-46b0-982d-418f929d1516 /> for a visual explanation.
    Clay_FloatingAttachPoints attachPoints;
    // Controls how mouse pointer events like hover and click are captured or passed through to elements underneath a floating element.
    // CLAY_POINTER_CAPTURE_MODE_CAPTURE (default) - "Capture" the pointer event and don't allow events like hover and click to pass through to elements underneath.
    // CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH - Transparently pass through pointer events like hover and click to elements underneath the floating element.
    Clay_PointerCaptureMode pointerCaptureMode;
    // Controls which element a floating element is "attached" to (i.e. relative offset from).
    // CLAY_ATTACH_TO_NONE (default) - Disables floating for this element.
    // CLAY_ATTACH_TO_PARENT - Attaches this floating element to its parent, positioned based on the .attachPoints and .offset fields.
    // CLAY_ATTACH_TO_ELEMENT_WITH_ID - Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields.
    // CLAY_ATTACH_TO_ROOT - Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning".
    Clay_FloatingAttachToElement attachTo;
    // Controls whether or not a floating element is clipped to the same clipping rectangle as the element it's attached to.
    // CLAY_CLIP_TO_NONE (default) - The floating element does not inherit clipping.
    // CLAY_CLIP_TO_ATTACHED_PARENT - The floating element is clipped to the same clipping rectangle as the element it's attached to.
    Clay_FloatingClipToElement clipTo;
} Clay_FloatingElementConfig;

CLAY__WRAPPER_STRUCT(Clay_FloatingElementConfig);

// Custom -----------------------------

// Controls various settings related to custom elements.
typedef struct Clay_CustomElementConfig {
    // A transparent pointer through which you can pass custom data to the renderer.
    // Generates CUSTOM render commands.
    void* customData;
} Clay_CustomElementConfig;

CLAY__WRAPPER_STRUCT(Clay_CustomElementConfig);

// Scroll -----------------------------

// Controls the axis on which an element switches to "scrolling", which clips the contents and allows scrolling in that direction.
typedef struct Clay_ClipElementConfig {
    bool horizontal; // Clip overflowing elements on the X axis.
    bool vertical; // Clip overflowing elements on the Y axis.
    Clay_Vector2 childOffset; // Offsets the x,y positions of all child elements. Used primarily for scrolling containers.
} Clay_ClipElementConfig;

CLAY__WRAPPER_STRUCT(Clay_ClipElementConfig);

// Border -----------------------------

// Controls the widths of individual element borders.
typedef struct Clay_BorderWidth {
    uint16_t left;
    uint16_t right;
    uint16_t top;
    uint16_t bottom;
    // Creates borders between each child element, depending on the .layoutDirection.
    // e.g. for LEFT_TO_RIGHT, borders will be vertical lines, and for TOP_TO_BOTTOM borders will be horizontal lines.
    // .betweenChildren borders will result in individual RECTANGLE render commands being generated.
    uint16_t betweenChildren;
} Clay_BorderWidth;

// Controls settings related to element borders.
typedef struct Clay_BorderElementConfig {
    Clay_Color color; // Controls the color of all borders with width > 0. Conventionally represented as 0-255, but interpretation is up to the renderer.
    Clay_BorderWidth width; // Controls the widths of individual borders. At least one of these should be > 0 for a BORDER render command to be generated.
} Clay_BorderElementConfig;

CLAY__WRAPPER_STRUCT(Clay_BorderElementConfig);

// Render Command Data -----------------------------

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_TEXT
typedef struct Clay_TextRenderData {
    // A string slice containing the text to be rendered.
    // Note: this is not guaranteed to be null terminated.
    Clay_StringSlice stringContents;
    // Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
    Clay_Color textColor;
    // An integer representing the font to use to render this text, transparently passed through from the text declaration.
    uint16_t fontId;
    uint16_t fontSize;
    // Specifies the extra whitespace gap in pixels between each character.
    uint16_t letterSpacing;
    // The height of the bounding box for this line of text.
    uint16_t lineHeight;
} Clay_TextRenderData;

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE
typedef struct Clay_RectangleRenderData {
    // The solid background color to fill this rectangle with. Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
    Clay_Color backgroundColor;
    // Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
    // The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
    Clay_CornerRadius cornerRadius;
} Clay_RectangleRenderData;

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE
typedef struct Clay_ImageRenderData {
    // The tint color for this image. Note that the default value is 0,0,0,0 and should likely be interpreted
    // as "untinted".
    // Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
    Clay_Color backgroundColor;
    // Controls the "radius", or corner rounding of this image.
    // The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
    Clay_CornerRadius cornerRadius;
    // A pointer transparently passed through from the original element definition, typically used to represent image data.
    void* imageData;
} Clay_ImageRenderData;

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM
typedef struct Clay_CustomRenderData {
    // Passed through from .backgroundColor in the original element declaration.
    // Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
    Clay_Color backgroundColor;
    // Controls the "radius", or corner rounding of this custom element.
    // The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
    Clay_CornerRadius cornerRadius;
    // A pointer transparently passed through from the original element definition.
    void* customData;
} Clay_CustomRenderData;

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_START || commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_END
typedef struct Clay_ScrollRenderData {
    bool horizontal;
    bool vertical;
} Clay_ClipRenderData;

// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
typedef struct Clay_BorderRenderData {
    // Controls a shared color for all this element's borders.
    // Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
    Clay_Color color;
    // Specifies the "radius", or corner rounding of this border element.
    // The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
    Clay_CornerRadius cornerRadius;
    // Controls individual border side widths.
    Clay_BorderWidth width;
} Clay_BorderRenderData;

// A struct union containing data specific to this command's .commandType
typedef union Clay_RenderData {
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE
    Clay_RectangleRenderData rectangle;
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_TEXT
    Clay_TextRenderData text;
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE
    Clay_ImageRenderData image;
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM
    Clay_CustomRenderData custom;
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
    Clay_BorderRenderData border;
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_START|END
    Clay_ClipRenderData clip;
} Clay_RenderData;

// Miscellaneous Structs & Enums ---------------------------------

// Data representing the current internal state of a scrolling element.
typedef struct Clay_ScrollContainerData {
    // Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
    // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
    Clay_Vector2 *scrollPosition;
    // The bounding box of the scroll element.
    Clay_Dimensions scrollContainerDimensions;
    // The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
    Clay_Dimensions contentDimensions;
    // The config that was originally passed to the clip element.
    Clay_ClipElementConfig config;
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ScrollContainerData;

// Bounding box and other data for a specific UI element.
typedef struct Clay_ElementData {
    // The rectangle that encloses this UI element, with the position relative to the root of the layout.
    Clay_BoundingBox boundingBox;
    // Indicates whether an actual Element matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ElementData;

// Used by renderers to determine specific handling for each render command.
typedef CLAY_PACKED_ENUM {
    // This command type should be skipped.
    CLAY_RENDER_COMMAND_TYPE_NONE,
    // The renderer should draw a solid color rectangle.
    CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
    // The renderer should draw a colored border inset into the bounding box.
    CLAY_RENDER_COMMAND_TYPE_BORDER,
    // The renderer should draw text.
    CLAY_RENDER_COMMAND_TYPE_TEXT,
    // The renderer should draw an image.
    CLAY_RENDER_COMMAND_TYPE_IMAGE,
    // The renderer should begin clipping all future draw commands, only rendering content that falls within the provided boundingBox.
    CLAY_RENDER_COMMAND_TYPE_SCISSOR_START,
    // The renderer should finish any previously active clipping, and begin rendering elements in full again.
    CLAY_RENDER_COMMAND_TYPE_SCISSOR_END,
    // The renderer should provide a custom implementation for handling this render command based on its .customData
    CLAY_RENDER_COMMAND_TYPE_CUSTOM,
} Clay_RenderCommandType;

typedef struct Clay_RenderCommand {
    // A rectangular box that fully encloses this UI element, with the position relative to the root of the layout.
    Clay_BoundingBox boundingBox;
    // A struct union containing data specific to this command's commandType.
    Clay_RenderData renderData;
    // A pointer transparently passed through from the original element declaration.
    void *userData;
    // The id of this element, transparently passed through from the original element declaration.
    uint32_t id;
    // The z order required for drawing this command correctly.
    // Note: the render command array is already sorted in ascending order, and will produce correct results if drawn in naive order.
    // This field is intended for use in batching renderers for improved performance.
    int16_t zIndex;
    // Specifies how to handle rendering of this command.
    // CLAY_RENDER_COMMAND_TYPE_RECTANGLE - The renderer should draw a solid color rectangle.
    // CLAY_RENDER_COMMAND_TYPE_BORDER - The renderer should draw a colored border inset into the bounding box.
    // CLAY_RENDER_COMMAND_TYPE_TEXT - The renderer should draw text.
    // CLAY_RENDER_COMMAND_TYPE_IMAGE - The renderer should draw an image.
    // CLAY_RENDER_COMMAND_TYPE_SCISSOR_START - The renderer should begin clipping all future draw commands, only rendering content that falls within the provided boundingBox.
    // CLAY_RENDER_COMMAND_TYPE_SCISSOR_END - The renderer should finish any previously active clipping, and begin rendering elements in full again.
    // CLAY_RENDER_COMMAND_TYPE_CUSTOM - The renderer should provide a custom implementation for handling this render command based on its .customData
    Clay_RenderCommandType commandType;
} Clay_RenderCommand;

// A sized array of render commands.
typedef struct Clay_RenderCommandArray {
    // The underlying max capacity of the array, not necessarily all initialized.
    int32_t capacity;
    // The number of initialized elements in this array. Used for loops and iteration.
    int32_t length;
    // A pointer to the first element in the internal array.
    Clay_RenderCommand* internalArray;
} Clay_RenderCommandArray;

// Represents the current state of interaction with clay this frame.
typedef CLAY_PACKED_ENUM {
    // A left mouse click, or touch occurred this frame.
    CLAY_POINTER_DATA_PRESSED_THIS_FRAME,
    // The left mouse button click or touch happened at some point in the past, and is still currently held down this frame.
    CLAY_POINTER_DATA_PRESSED,
    // The left mouse button click or touch was released this frame.
    CLAY_POINTER_DATA_RELEASED_THIS_FRAME,
    // The left mouse button click or touch is not currently down / was released at some point in the past.
    CLAY_POINTER_DATA_RELEASED,
} Clay_PointerDataInteractionState;

// Information on the current state of pointer interactions this frame.
typedef struct Clay_PointerData {
    // The position of the mouse / touch / pointer relative to the root of the layout.
    Clay_Vector2 position;
    // Represents the current state of interaction with clay this frame.
    // CLAY_POINTER_DATA_PRESSED_THIS_FRAME - A left mouse click, or touch occurred this frame.
    // CLAY_POINTER_DATA_PRESSED - The left mouse button click or touch happened at some point in the past, and is still currently held down this frame.
    // CLAY_POINTER_DATA_RELEASED_THIS_FRAME - The left mouse button click or touch was released this frame.
    // CLAY_POINTER_DATA_RELEASED - The left mouse button click or touch is not currently down / was released at some point in the past.
    Clay_PointerDataInteractionState state;
} Clay_PointerData;

typedef struct Clay_ElementDeclaration {
    // Controls various settings that affect the size and position of an element, as well as the sizes and positions of any child elements.
    Clay_LayoutConfig layout;
    // Controls the background color of the resulting element.
    // By convention specified as 0-255, but interpretation is up to the renderer.
    // If no other config is specified, .backgroundColor will generate a RECTANGLE render command, otherwise it will be passed as a property to IMAGE or CUSTOM render commands.
    Clay_Color backgroundColor;
    // Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
    Clay_CornerRadius cornerRadius;
    // Controls settings related to aspect ratio scaling.
    Clay_AspectRatioElementConfig aspectRatio;
    // Controls settings related to image elements.
    Clay_ImageElementConfig image;
    // Controls whether and how an element "floats", which means it layers over the top of other elements in z order, and doesn't affect the position and size of siblings or parent elements.
    // Note: in order to activate floating, .floating.attachTo must be set to something other than the default value.
    Clay_FloatingElementConfig floating;
    // Used to create CUSTOM render commands, usually to render element types not supported by Clay.
    Clay_CustomElementConfig custom;
    // Controls whether an element should clip its contents, as well as providing child x,y offset configuration for scrolling.
    Clay_ClipElementConfig clip;
    // Controls settings related to element borders, and will generate BORDER render commands.
    Clay_BorderElementConfig border;
    // A pointer that will be transparently passed through to resulting render commands.
    void *userData;
} Clay_ElementDeclaration;

CLAY__WRAPPER_STRUCT(Clay_ElementDeclaration);

// Represents the type of error clay encountered while computing layout.
typedef CLAY_PACKED_ENUM {
    // A text measurement function wasn't provided using Clay_SetMeasureTextFunction(), or the provided function was null.
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
    // Clay attempted to allocate its internal data structures but ran out of space.
    // The arena passed to Clay_Initialize was created with a capacity smaller than that required by Clay_MinMemorySize().
    CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
    // Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxElementCount().
    CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
    // Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxMeasureTextCacheWordCount().
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
    // Two elements were declared with exactly the same ID within one layout.
    CLAY_ERROR_TYPE_DUPLICATE_ID,
    // A floating element was declared using CLAY_ATTACH_TO_ELEMENT_ID and either an invalid .parentId was provided or no element with the provided .parentId was found.
    CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
    // An element was declared that using CLAY_SIZING_PERCENT but the percentage value was over 1. Percentage values are expected to be in the 0-1 range.
    CLAY_ERROR_TYPE_PERCENTAGE_OVER_1,
    // Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
    CLAY_ERROR_TYPE_INTERNAL_ERROR,
    // Clay__OpenElement was called more times than Clay__CloseElement, so there were still remaining open elements when the layout ended.
    CLAY_ERROR_TYPE_UNBALANCED_OPEN_CLOSE,
} Clay_ErrorType;

// Data to identify the error that clay has encountered.
typedef struct Clay_ErrorData {
    // Represents the type of error clay encountered while computing layout.
    // CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED - A text measurement function wasn't provided using Clay_SetMeasureTextFunction(), or the provided function was null.
    // CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED - Clay attempted to allocate its internal data structures but ran out of space. The arena passed to Clay_Initialize was created with a capacity smaller than that required by Clay_MinMemorySize().
    // CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED - Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxElementCount().
    // CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED - Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxMeasureTextCacheWordCount().
    // CLAY_ERROR_TYPE_DUPLICATE_ID - Two elements were declared with exactly the same ID within one layout.
    // CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND - A floating element was declared using CLAY_ATTACH_TO_ELEMENT_ID and either an invalid .parentId was provided or no element with the provided .parentId was found.
    // CLAY_ERROR_TYPE_PERCENTAGE_OVER_1 - An element was declared that using CLAY_SIZING_PERCENT but the percentage value was over 1. Percentage values are expected to be in the 0-1 range.
    // CLAY_ERROR_TYPE_INTERNAL_ERROR - Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
    Clay_ErrorType errorType;
    // A string containing human-readable error text that explains the error in more detail.
    Clay_String errorText;
    // A transparent pointer passed through from when the error handler was first provided.
    void *userData;
} Clay_ErrorData;

// A wrapper struct around Clay's error handler function.
typedef struct {
    // A user provided function to call when Clay encounters an error during layout.
    void (*errorHandlerFunction)(Clay_ErrorData errorText);
    // A pointer that will be transparently passed through to the error handler when it is called.
    void *userData;
} Clay_ErrorHandler;

// Function Forward Declarations ---------------------------------

// Public API functions ------------------------------------------

// Returns the size, in bytes, of the minimum amount of memory Clay requires to operate at its current settings.
CLAY_DLL_EXPORT uint32_t Clay_MinMemorySize(void);
// Creates an arena for clay to use for its internal allocations, given a certain capacity in bytes and a pointer to an allocation of at least that size.
// Intended to be used with Clay_MinMemorySize in the following way:
// uint32_t minMemoryRequired = Clay_MinMemorySize();
// Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(minMemoryRequired, malloc(minMemoryRequired));
CLAY_DLL_EXPORT Clay_Arena Clay_CreateArenaWithCapacityAndMemory(size_t capacity, void *memory);
// Sets the state of the "pointer" (i.e. the mouse or touch) in Clay's internal data. Used for detecting and responding to mouse events in the debug view,
// as well as for Clay_Hovered() and scroll element handling.
CLAY_DLL_EXPORT void Clay_SetPointerState(Clay_Vector2 position, bool pointerDown);
// Initialize Clay's internal arena and setup required data before layout can begin. Only needs to be called once.
// - arena can be created using Clay_CreateArenaWithCapacityAndMemory()
// - layoutDimensions are the initial bounding dimensions of the layout (i.e. the screen width and height for a full screen layout)
// - errorHandler is used by Clay to inform you if something has gone wrong in configuration or layout.
CLAY_DLL_EXPORT Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
// Returns the Context that clay is currently using. Used when using multiple instances of clay simultaneously.
CLAY_DLL_EXPORT Clay_Context* Clay_GetCurrentContext(void);
// Sets the context that clay will use to compute the layout.
// Used to restore a context saved from Clay_GetCurrentContext when using multiple instances of clay simultaneously.
CLAY_DLL_EXPORT void Clay_SetCurrentContext(Clay_Context* context);
// Updates the state of Clay's internal scroll data, updating scroll content positions if scrollDelta is non zero, and progressing momentum scrolling.
// - enableDragScrolling when set to true will enable mobile device like "touch drag" scroll of scroll containers, including momentum scrolling after the touch has ended.
// - scrollDelta is the amount to scroll this frame on each axis in pixels.
// - deltaTime is the time in seconds since the last "frame" (scroll update)
CLAY_DLL_EXPORT void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
// Returns the internally stored scroll offset for the currently open element.
// Generally intended for use with clip elements to create scrolling containers.
CLAY_DLL_EXPORT Clay_Vector2 Clay_GetScrollOffset(void);
// Updates the layout dimensions in response to the window or outer container being resized.
CLAY_DLL_EXPORT void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
// Called before starting any layout declarations.
CLAY_DLL_EXPORT void Clay_BeginLayout(void);
// Called when all layout declarations are finished.
// Computes the layout and generates and returns the array of render commands to draw.
CLAY_DLL_EXPORT Clay_RenderCommandArray Clay_EndLayout(void);
// Calculates a hash ID from the given idString.
// Generally only used for dynamic strings when CLAY_ID("stringLiteral") can't be used.
CLAY_DLL_EXPORT Clay_ElementId Clay_GetElementId(Clay_String idString);
// Calculates a hash ID from the given idString and index.
// - index is used to avoid constructing dynamic ID strings in loops.
// Generally only used for dynamic strings when CLAY_IDI("stringLiteral", index) can't be used.
CLAY_DLL_EXPORT Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
// Returns layout data such as the final calculated bounding box for an element with a given ID.
// The returned Clay_ElementData contains a `found` bool that will be true if an element with the provided ID was found.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
CLAY_DLL_EXPORT Clay_ElementData Clay_GetElementData(Clay_ElementId id);
// Returns true if the pointer position provided by Clay_SetPointerState is within the current element's bounding box.
// Works during element declaration, e.g. CLAY({ .backgroundColor = Clay_Hovered() ? BLUE : RED });
CLAY_DLL_EXPORT bool Clay_Hovered(void);
// Bind a callback that will be called when the pointer position provided by Clay_SetPointerState is within the current element's bounding box.
// - onHoverFunction is a function pointer to a user defined function.
// - userData is a pointer that will be transparently passed through when the onHoverFunction is called.
CLAY_DLL_EXPORT void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData), void *userData);
// An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
CLAY_DLL_EXPORT bool Clay_PointerOver(Clay_ElementId elementId);
// Returns the array of element IDs that the pointer is currently over.
CLAY_DLL_EXPORT Clay_ElementIdArray Clay_GetPointerOverIds(void);
// Returns data representing the state of the scrolling element with the provided ID.
// The returned Clay_ScrollContainerData contains a `found` bool that will be true if a scroll element was found with the provided ID.
// An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
CLAY_DLL_EXPORT Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
// Binds a callback function that Clay will call to determine the dimensions of a given string slice.
// - measureTextFunction is a user provided function that adheres to the interface Clay_Dimensions (Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
// - userData is a pointer that will be transparently passed through when the measureTextFunction is called.
CLAY_DLL_EXPORT void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData), void *userData);
// Experimental - Used in cases where Clay needs to integrate with a system that manages its own scrolling containers externally.
// Please reach out if you plan to use this function, as it may be subject to change.
CLAY_DLL_EXPORT void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, void *userData), void *userData);
// A bounds-checked "get" function for the Clay_RenderCommandArray returned from Clay_EndLayout().
CLAY_DLL_EXPORT Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index);
// Enables and disables Clay's internal debug tools.
// This state is retained and does not need to be set each frame.
CLAY_DLL_EXPORT void Clay_SetDebugModeEnabled(bool enabled);
// Returns true if Clay's internal debug tools are currently enabled.
CLAY_DLL_EXPORT bool Clay_IsDebugModeEnabled(void);
// Enables and disables visibility culling. By default, Clay will not generate render commands for elements whose bounding box is entirely outside the screen.
CLAY_DLL_EXPORT void Clay_SetCullingEnabled(bool enabled);
// Returns the maximum number of UI elements supported by Clay's current configuration.
CLAY_DLL_EXPORT int32_t Clay_GetMaxElementCount(void);
// Modifies the maximum number of UI elements supported by Clay's current configuration.
// This may require reallocating additional memory, and re-calling Clay_Initialize();
CLAY_DLL_EXPORT void Clay_SetMaxElementCount(int32_t maxElementCount);
// Returns the maximum number of measured "words" (whitespace seperated runs of characters) that Clay can store in its internal text measurement cache.
CLAY_DLL_EXPORT int32_t Clay_GetMaxMeasureTextCacheWordCount(void);
// Modifies the maximum number of measured "words" (whitespace seperated runs of characters) that Clay can store in its internal text measurement cache.
// This may require reallocating additional memory, and re-calling Clay_Initialize();
CLAY_DLL_EXPORT void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount);
// Resets Clay's internal text measurement cache. Useful if font mappings have changed or fonts have been reloaded.
CLAY_DLL_EXPORT void Clay_ResetMeasureTextCache(void);

// Internal API functions required by macros ----------------------

CLAY_DLL_EXPORT void Clay__OpenElement(void);
CLAY_DLL_EXPORT void Clay__OpenElementWithId(Clay_ElementId elementId);
CLAY_DLL_EXPORT void Clay__ConfigureOpenElement(const Clay_ElementDeclaration config);
CLAY_DLL_EXPORT void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *config);
CLAY_DLL_EXPORT void Clay__CloseElement(void);
CLAY_DLL_EXPORT Clay_ElementId Clay__HashString(Clay_String key, uint32_t seed);
CLAY_DLL_EXPORT Clay_ElementId Clay__HashStringWithOffset(Clay_String key, uint32_t offset, uint32_t seed);
CLAY_DLL_EXPORT void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig);
CLAY_DLL_EXPORT Clay_TextElementConfig *Clay__StoreTextElementConfig(Clay_TextElementConfig config);
CLAY_DLL_EXPORT uint32_t Clay__GetParentElementId(void);

extern Clay_Color Clay__debugViewHighlightColor;
extern uint32_t Clay__debugViewWidth;

#ifdef __cplusplus
}
#endif

#endif // CLAY_HEADER

// -----------------------------------------
// IMPLEMENTATION --------------------------
// -----------------------------------------
#ifdef CLAY_IMPLEMENTATION
#undef CLAY_IMPLEMENTATION

#ifndef CLAY__NULL
#define CLAY__NULL 0
#endif

#ifndef CLAY__MAXFLOAT
#define CLAY__MAXFLOAT 3.40282346638528859812e+38F
#endif

Clay_LayoutConfig CLAY_LAYOUT_DEFAULT = CLAY__DEFAULT_STRUCT;

Clay_Color Clay__Color_DEFAULT = CLAY__DEFAULT_STRUCT;
Clay_CornerRadius Clay__CornerRadius_DEFAULT = CLAY__DEFAULT_STRUCT;
Clay_BorderWidth Clay__BorderWidth_DEFAULT = CLAY__DEFAULT_STRUCT;

// The below functions define array bounds checking and convenience functions for a provided type.
#define CLAY__ARRAY_DEFINE_FUNCTIONS(typeName, arrayName)                                                       \
                                                                                                                \
typedef struct                                                                                                  \
{                                                                                                               \
    int32_t length;                                                                                             \
    typeName *internalArray;                                                                                    \
} arrayName##Slice;                                                                                             \
                                                                                                                \
typeName typeName##_DEFAULT = CLAY__DEFAULT_STRUCT;                                                             \
                                                                                                                \
arrayName arrayName##_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {                                     \
    return CLAY__INIT(arrayName){.capacity = capacity, .length = 0,                                             \
        .internalArray = (typeName *)Clay__Array_Allocate_Arena(capacity, sizeof(typeName), arena)};            \
}                                                                                                               \
                                                                                                                \
typeName *arrayName##_Get(arrayName *array, int32_t index) {                                                    \
    return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &typeName##_DEFAULT;   \
}                                                                                                               \
                                                                                                                \
typeName arrayName##_GetValue(arrayName *array, int32_t index) {                                                \
    return Clay__Array_RangeCheck(index, array->length) ? array->internalArray[index] : typeName##_DEFAULT;     \
}                                                                                                               \
                                                                                                                \
typeName *arrayName##_Add(arrayName *array, typeName item) {                                                    \
    if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {                                         \
        array->internalArray[array->length++] = item;                                                           \
        return &array->internalArray[array->length - 1];                                                        \
    }                                                                                                           \
    return &typeName##_DEFAULT;                                                                                 \
}                                                                                                               \
                                                                                                                \
typeName *arrayName##Slice_Get(arrayName##Slice *slice, int32_t index) {                                        \
    return Clay__Array_RangeCheck(index, slice->length) ? &slice->internalArray[index] : &typeName##_DEFAULT;   \
}                                                                                                               \
                                                                                                                \
typeName arrayName##_RemoveSwapback(arrayName *array, int32_t index) {                                          \
	if (Clay__Array_RangeCheck(index, array->length)) {                                                         \
		array->length--;                                                                                        \
		typeName removed = array->internalArray[index];                                                         \
		array->internalArray[index] = array->internalArray[array->length];                                      \
		return removed;                                                                                         \
	}                                                                                                           \
	return typeName##_DEFAULT;                                                                                  \
}                                                                                                               \
                                                                                                                \
void arrayName##_Set(arrayName *array, int32_t index, typeName value) {                                         \
	if (Clay__Array_RangeCheck(index, array->capacity)) {                                                       \
		array->internalArray[index] = value;                                                                    \
		array->length = index < array->length ? array->length : index + 1;                                      \
	}                                                                                                           \
}                                                                                                               \

#define CLAY__ARRAY_DEFINE(typeName, arrayName)     \
typedef struct                                      \
{                                                   \
    int32_t capacity;                               \
    int32_t length;                                 \
    typeName *internalArray;                        \
} arrayName;                                        \
                                                    \
CLAY__ARRAY_DEFINE_FUNCTIONS(typeName, arrayName)   \

Clay_Context *Clay__currentContext;
int32_t Clay__defaultMaxElementCount = 8192;
int32_t Clay__defaultMaxMeasureTextWordCacheCount = 16384;

void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {
    (void) errorText;
}

Clay_String CLAY__SPACECHAR = { .length = 1, .chars = " " };
Clay_String CLAY__STRING_DEFAULT = { .length = 0, .chars = NULL };

typedef struct {
    bool maxElementsExceeded;
    bool maxRenderCommandsExceeded;
    bool maxTextMeasureCacheExceeded;
    bool textMeasurementFunctionNotSet;
} Clay_BooleanWarnings;

typedef struct {
    Clay_String baseMessage;
    Clay_String dynamicMessage;
} Clay__Warning;

Clay__Warning CLAY__WARNING_DEFAULT = CLAY__DEFAULT_STRUCT;

typedef struct {
    int32_t capacity;
    int32_t length;
    Clay__Warning *internalArray;
} Clay__WarningArray;

typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    void* userData;
} Clay_SharedElementConfig;

CLAY__WRAPPER_STRUCT(Clay_SharedElementConfig);

Clay__WarningArray Clay__WarningArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena);
Clay__Warning *Clay__WarningArray_Add(Clay__WarningArray *array, Clay__Warning item);
void* Clay__Array_Allocate_Arena(int32_t capacity, uint32_t itemSize, Clay_Arena *arena);
bool Clay__Array_RangeCheck(int32_t index, int32_t length);
bool Clay__Array_AddCapacityCheck(int32_t length, int32_t capacity);

CLAY__ARRAY_DEFINE(bool, Clay__boolArray)
CLAY__ARRAY_DEFINE(int32_t, Clay__int32_tArray)
CLAY__ARRAY_DEFINE(char, Clay__charArray)
CLAY__ARRAY_DEFINE_FUNCTIONS(Clay_ElementId, Clay_ElementIdArray)
CLAY__ARRAY_DEFINE(Clay_LayoutConfig, Clay__LayoutConfigArray)
CLAY__ARRAY_DEFINE(Clay_TextElementConfig, Clay__TextElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_AspectRatioElementConfig, Clay__AspectRatioElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_ImageElementConfig, Clay__ImageElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_FloatingElementConfig, Clay__FloatingElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_CustomElementConfig, Clay__CustomElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_ClipElementConfig, Clay__ClipElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_BorderElementConfig, Clay__BorderElementConfigArray)
CLAY__ARRAY_DEFINE(Clay_String, Clay__StringArray)
CLAY__ARRAY_DEFINE(Clay_SharedElementConfig, Clay__SharedElementConfigArray)
CLAY__ARRAY_DEFINE_FUNCTIONS(Clay_RenderCommand, Clay_RenderCommandArray)

typedef CLAY_PACKED_ENUM {
    CLAY__ELEMENT_CONFIG_TYPE_NONE,
    CLAY__ELEMENT_CONFIG_TYPE_BORDER,
    CLAY__ELEMENT_CONFIG_TYPE_FLOATING,
    CLAY__ELEMENT_CONFIG_TYPE_CLIP,
    CLAY__ELEMENT_CONFIG_TYPE_ASPECT,
    CLAY__ELEMENT_CONFIG_TYPE_IMAGE,
    CLAY__ELEMENT_CONFIG_TYPE_TEXT,
    CLAY__ELEMENT_CONFIG_TYPE_CUSTOM,
    CLAY__ELEMENT_CONFIG_TYPE_SHARED,
} Clay__ElementConfigType;

typedef union {
    Clay_TextElementConfig *textElementConfig;
    Clay_AspectRatioElementConfig *aspectRatioElementConfig;
    Clay_ImageElementConfig *imageElementConfig;
    Clay_FloatingElementConfig *floatingElementConfig;
    Clay_CustomElementConfig *customElementConfig;
    Clay_ClipElementConfig *clipElementConfig;
    Clay_BorderElementConfig *borderElementConfig;
    Clay_SharedElementConfig *sharedElementConfig;
} Clay_ElementConfigUnion;

typedef struct {
    Clay__ElementConfigType type;
    Clay_ElementConfigUnion config;
} Clay_ElementConfig;

CLAY__ARRAY_DEFINE(Clay_ElementConfig, Clay__ElementConfigArray)

typedef struct {
    Clay_Dimensions dimensions;
    Clay_String line;
} Clay__WrappedTextLine;

CLAY__ARRAY_DEFINE(Clay__WrappedTextLine, Clay__WrappedTextLineArray)

typedef struct {
    Clay_String text;
    Clay_Dimensions preferredDimensions;
    int32_t elementIndex;
    Clay__WrappedTextLineArraySlice wrappedLines;
} Clay__TextElementData;

CLAY__ARRAY_DEFINE(Clay__TextElementData, Clay__TextElementDataArray)

typedef struct {
    int32_t *elements;
    uint16_t length;
} Clay__LayoutElementChildren;

typedef struct {
    union {
        Clay__LayoutElementChildren children;
        Clay__TextElementData *textElementData;
    } childrenOrTextContent;
    Clay_Dimensions dimensions;
    Clay_Dimensions minDimensions;
    Clay_LayoutConfig *layoutConfig;
    Clay__ElementConfigArraySlice elementConfigs;
    uint32_t id;
    uint16_t floatingChildrenCount;
} Clay_LayoutElement;

CLAY__ARRAY_DEFINE(Clay_LayoutElement, Clay_LayoutElementArray)

typedef struct {
    Clay_LayoutElement *layoutElement;
    Clay_BoundingBox boundingBox;
    Clay_Dimensions contentSize;
    Clay_Vector2 scrollOrigin;
    Clay_Vector2 pointerOrigin;
    Clay_Vector2 scrollMomentum;
    Clay_Vector2 scrollPosition;
    Clay_Vector2 previousDelta;
    float momentumTime;
    uint32_t elementId;
    bool openThisFrame;
    bool pointerScrollActive;
} Clay__ScrollContainerDataInternal;

CLAY__ARRAY_DEFINE(Clay__ScrollContainerDataInternal, Clay__ScrollContainerDataInternalArray)

typedef struct {
    bool collision;
    bool collapsed;
} Clay__DebugElementData;

CLAY__ARRAY_DEFINE(Clay__DebugElementData, Clay__DebugElementDataArray)

typedef struct { // todo get this struct into a single cache line
    Clay_BoundingBox boundingBox;
    Clay_ElementId elementId;
    Clay_LayoutElement* layoutElement;
    void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, void *userData);
    void *hoverFunctionUserData;
    int32_t nextIndex;
    uint32_t generation;
    Clay__DebugElementData *debugData;
} Clay_LayoutElementHashMapItem;

CLAY__ARRAY_DEFINE(Clay_LayoutElementHashMapItem, Clay__LayoutElementHashMapItemArray)

typedef struct {
    int32_t startOffset;
    int32_t length;
    float width;
    int32_t next;
} Clay__MeasuredWord;

CLAY__ARRAY_DEFINE(Clay__MeasuredWord, Clay__MeasuredWordArray)

typedef struct {
    Clay_Dimensions unwrappedDimensions;
    int32_t measuredWordsStartIndex;
    float minWidth;
    bool containsNewlines;
    // Hash map data
    uint32_t id;
    int32_t nextIndex;
    uint32_t generation;
} Clay__MeasureTextCacheItem;

CLAY__ARRAY_DEFINE(Clay__MeasureTextCacheItem, Clay__MeasureTextCacheItemArray)

typedef struct {
    Clay_LayoutElement *layoutElement;
    Clay_Vector2 position;
    Clay_Vector2 nextChildOffset;
} Clay__LayoutElementTreeNode;

CLAY__ARRAY_DEFINE(Clay__LayoutElementTreeNode, Clay__LayoutElementTreeNodeArray)

typedef struct {
    int32_t layoutElementIndex;
    uint32_t parentId; // This can be zero in the case of the root layout tree
    uint32_t clipElementId; // This can be zero if there is no clip element
    int16_t zIndex;
    Clay_Vector2 pointerOffset; // Only used when scroll containers are managed externally
} Clay__LayoutElementTreeRoot;

CLAY__ARRAY_DEFINE(Clay__LayoutElementTreeRoot, Clay__LayoutElementTreeRootArray)

struct Clay_Context {
    int32_t maxElementCount;
    int32_t maxMeasureTextCacheWordCount;
    bool warningsEnabled;
    Clay_ErrorHandler errorHandler;
    Clay_BooleanWarnings booleanWarnings;
    Clay__WarningArray warnings;

    Clay_PointerData pointerInfo;
    Clay_Dimensions layoutDimensions;
    Clay_ElementId dynamicElementIndexBaseHash;
    uint32_t dynamicElementIndex;
    bool debugModeEnabled;
    bool disableCulling;
    bool externalScrollHandlingEnabled;
    uint32_t debugSelectedElementId;
    uint32_t generation;
    uintptr_t arenaResetOffset;
    void *measureTextUserData;
    void *queryScrollOffsetUserData;
    Clay_Arena internalArena;
    // Layout Elements / Render Commands
    Clay_LayoutElementArray layoutElements;
    Clay_RenderCommandArray renderCommands;
    Clay__int32_tArray openLayoutElementStack;
    Clay__int32_tArray layoutElementChildren;
    Clay__int32_tArray layoutElementChildrenBuffer;
    Clay__TextElementDataArray textElementData;
    Clay__int32_tArray aspectRatioElementIndexes;
    Clay__int32_tArray reusableElementIndexBuffer;
    Clay__int32_tArray layoutElementClipElementIds;
    // Configs
    Clay__LayoutConfigArray layoutConfigs;
    Clay__ElementConfigArray elementConfigs;
    Clay__TextElementConfigArray textElementConfigs;
    Clay__AspectRatioElementConfigArray aspectRatioElementConfigs;
    Clay__ImageElementConfigArray imageElementConfigs;
    Clay__FloatingElementConfigArray floatingElementConfigs;
    Clay__ClipElementConfigArray clipElementConfigs;
    Clay__CustomElementConfigArray customElementConfigs;
    Clay__BorderElementConfigArray borderElementConfigs;
    Clay__SharedElementConfigArray sharedElementConfigs;
    // Misc Data Structures
    Clay__StringArray layoutElementIdStrings;
    Clay__WrappedTextLineArray wrappedTextLines;
    Clay__LayoutElementTreeNodeArray layoutElementTreeNodeArray1;
    Clay__LayoutElementTreeRootArray layoutElementTreeRoots;
    Clay__LayoutElementHashMapItemArray layoutElementsHashMapInternal;
    Clay__int32_tArray layoutElementsHashMap;
    Clay__MeasureTextCacheItemArray measureTextHashMapInternal;
    Clay__int32_tArray measureTextHashMapInternalFreeList;
    Clay__int32_tArray measureTextHashMap;
    Clay__MeasuredWordArray measuredWords;
    Clay__int32_tArray measuredWordsFreeList;
    Clay__int32_tArray openClipElementStack;
    Clay_ElementIdArray pointerOverIds;
    Clay__ScrollContainerDataInternalArray scrollContainerDatas;
    Clay__boolArray treeNodeVisited;
    Clay__charArray dynamicStringData;
    Clay__DebugElementDataArray debugElementData;
};

Clay_Context* Clay__Context_Allocate_Arena(Clay_Arena *arena) {
    size_t totalSizeBytes = sizeof(Clay_Context);
    if (totalSizeBytes > arena->capacity)
    {
        return NULL;
    }
    arena->nextAllocation += totalSizeBytes;
    return (Clay_Context*)(arena->memory);
}

Clay_String Clay__WriteStringToCharBuffer(Clay__charArray *buffer, Clay_String string) {
    for (int32_t i = 0; i < string.length; i++) {
        buffer->internalArray[buffer->length + i] = string.chars[i];
    }
    buffer->length += string.length;
    return CLAY__INIT(Clay_String) { .length = string.length, .chars = (const char *)(buffer->internalArray + buffer->length - string.length) };
}

#ifdef CLAY_WASM
    __attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
    __attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId, void *userData);
#else
    Clay_Dimensions (*Clay__MeasureText)(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
    Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId, void *userData);
#endif

Clay_LayoutElement* Clay__GetOpenLayoutElement(void) {
    Clay_Context* context = Clay_GetCurrentContext();
    return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 1));
}

uint32_t Clay__GetParentElementId(void) {
    Clay_Context* context = Clay_GetCurrentContext();
    return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2))->id;
}

Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY_LAYOUT_DEFAULT : Clay__LayoutConfigArray_Add(&Clay_GetCurrentContext()->layoutConfigs, config); }
Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_TextElementConfig_DEFAULT : Clay__TextElementConfigArray_Add(&Clay_GetCurrentContext()->textElementConfigs, config); }
Clay_AspectRatioElementConfig * Clay__StoreAspectRatioElementConfig(Clay_AspectRatioElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_AspectRatioElementConfig_DEFAULT : Clay__AspectRatioElementConfigArray_Add(&Clay_GetCurrentContext()->aspectRatioElementConfigs, config); }
Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_ImageElementConfig_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay_GetCurrentContext()->imageElementConfigs, config); }
Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_FloatingElementConfig_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay_GetCurrentContext()->floatingElementConfigs, config); }
Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_CustomElementConfig_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay_GetCurrentContext()->customElementConfigs, config); }
Clay_ClipElementConfig * Clay__StoreClipElementConfig(Clay_ClipElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_ClipElementConfig_DEFAULT : Clay__ClipElementConfigArray_Add(&Clay_GetCurrentContext()->clipElementConfigs, config); }
Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_BorderElementConfig_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay_GetCurrentContext()->borderElementConfigs, config); }
Clay_SharedElementConfig * Clay__StoreSharedElementConfig(Clay_SharedElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_SharedElementConfig_DEFAULT : Clay__SharedElementConfigArray_Add(&Clay_GetCurrentContext()->sharedElementConfigs, config); }

Clay_ElementConfig Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type) {
    Clay_Context* context = Clay_GetCurrentContext();
    if (context->booleanWarnings.maxElementsExceeded) {
        return CLAY__INIT(Clay_ElementConfig) CLAY__DEFAULT_STRUCT;
    }
    Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
    openLayoutElement->elementConfigs.length++;
    return *Clay__ElementConfigArray_Add(&context->elementConfigs, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
}

Clay_ElementConfigUnion Clay__FindElementConfigWithType(Clay_LayoutElement *element, Clay__ElementConfigType type) {
    for (int32_t i = 0; i < element->elementConfigs.length; i++) {
        Clay_ElementConfig *config = Clay__ElementConfigArraySlice_Get(&element->elementConfigs, i);
        if (config->type == type) {
            return config->config;
        }
    }
    return CLAY__INIT(Clay_ElementConfigUnion) { NULL };
}

Clay_ElementId Clay__HashNumber(const uint32_t offset, const uint32_t seed) {
    uint32_t hash = seed;
    hash += (offset + 48);
    hash += (hash << 10);
    hash ^= (hash >> 6);

    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    return CLAY__INIT(Clay_ElementId) { .id = hash + 1, .offset = offset, .baseId = seed, .stringId = CLAY__STRING_DEFAULT }; // Reserve the hash result of zero as "null id"
}

Clay_ElementId Clay__HashString(Clay_String key, const uint32_t seed) {
    uint32_t hash = seed;

    for (int32_t i = 0; i < key.length; i++) {
        hash += key.chars[i];
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }

    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    return CLAY__INIT(Clay_ElementId) { .id = hash + 1, .offset = 0, .baseId = hash + 1, .stringId = key }; // Reserve the hash result of zero as "null id"
}

Clay_ElementId Clay__HashStringWithOffset(Clay_String key, const uint32_t offset, const uint32_t seed) {
    uint32_t hash = 0;
    uint32_t base = seed;

    for (int32_t i = 0; i < key.length; i++) {
        base += key.chars[i];
        base += (base << 10);
        base ^= (base >> 6);
    }
    hash = base;
    hash += offset;
    hash += (hash << 10);
    hash ^= (hash >> 6);

    hash += (hash << 3);
    base += (base << 3);
    hash ^= (hash >> 11);
    base ^= (base >> 11);
    hash += (hash << 15);
    base += (base << 15);
    return CLAY__INIT(Clay_ElementId) { .id = hash + 1, .offset = offset, .baseId = base + 1, .stringId = key }; // Reserve the hash result of zero as "null id"
}

#if !defined(CLAY_DISABLE_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64))
static inline __m128i Clay__SIMDRotateLeft(__m128i x, int r) {
    return _mm_or_si128(_mm_slli_epi64(x, r), _mm_srli_epi64(x, 64 - r));
}

static inline void Clay__SIMDARXMix(__m128i* a, __m128i* b) {
    *a = _mm_add_epi64(*a, *b);
    *b = _mm_xor_si128(Clay__SIMDRotateLeft(*b, 17), *a);
}

uint64_t Clay__HashData(const uint8_t* data, size_t length) {
    // Pinched these constants from the BLAKE implementation
    __m128i v0 = _mm_set1_epi64x(0x6a09e667f3bcc908ULL);
    __m128i v1 = _mm_set1_epi64x(0xbb67ae8584caa73bULL);
    __m128i v2 = _mm_set1_epi64x(0x3c6ef372fe94f82bULL);
    __m128i v3 = _mm_set1_epi64x(0xa54ff53a5f1d36f1ULL);

    uint8_t overflowBuffer[16] = { 0 };  // Temporary buffer for small inputs

    while (length > 0) {
        __m128i msg;
        if (length >= 16) {
            msg = _mm_loadu_si128((const __m128i*)data);
            data += 16;
            length -= 16;
        }
        else {
            for (size_t i = 0; i < length; i++) {
                overflowBuffer[i] = data[i];
            }
            msg = _mm_loadu_si128((const __m128i*)overflowBuffer);
            length = 0;
        }

        v0 = _mm_xor_si128(v0, msg);
        Clay__SIMDARXMix(&v0, &v1);
        Clay__SIMDARXMix(&v2, &v3);

        v0 = _mm_add_epi64(v0, v2);
        v1 = _mm_add_epi64(v1, v3);
    }

    Clay__SIMDARXMix(&v0, &v1);
    Clay__SIMDARXMix(&v2, &v3);
    v0 = _mm_add_epi64(v0, v2);
    v1 = _mm_add_epi64(v1, v3);
    v0 = _mm_add_epi64(v0, v1);

    uint64_t result[2];
    _mm_storeu_si128((__m128i*)result, v0);

    return result[0] ^ result[1];
}
#elif !defined(CLAY_DISABLE_SIMD) && defined(__aarch64__)
static inline void Clay__SIMDARXMix(uint64x2_t* a, uint64x2_t* b) {
    *a = vaddq_u64(*a, *b);
    *b = veorq_u64(vorrq_u64(vshlq_n_u64(*b, 17), vshrq_n_u64(*b, 64 - 17)), *a);
}

uint64_t Clay__HashData(const uint8_t* data, size_t length) {
    // Pinched these constants from the BLAKE implementation
    uint64x2_t v0 = vdupq_n_u64(0x6a09e667f3bcc908ULL);
    uint64x2_t v1 = vdupq_n_u64(0xbb67ae8584caa73bULL);
    uint64x2_t v2 = vdupq_n_u64(0x3c6ef372fe94f82bULL);
    uint64x2_t v3 = vdupq_n_u64(0xa54ff53a5f1d36f1ULL);

    uint8_t overflowBuffer[8] = { 0 };

    while (length > 0) {
        uint64x2_t msg;
        if (length > 16) {
            msg = vld1q_u64((const uint64_t*)data);
            data += 16;
            length -= 16;
        }
        else if (length > 8) {
            msg = vcombine_u64(vld1_u64((const uint64_t*)data), vdup_n_u64(0));
            data += 8;
            length -= 8;
        }
        else {
            for (size_t i = 0; i < length; i++) {
                overflowBuffer[i] = data[i];
            }
            uint8x8_t lower = vld1_u8(overflowBuffer);
            msg = vreinterpretq_u64_u8(vcombine_u8(lower, vdup_n_u8(0)));
            length = 0;
        }
        v0 = veorq_u64(v0, msg);
        Clay__SIMDARXMix(&v0, &v1);
        Clay__SIMDARXMix(&v2, &v3);

        v0 = vaddq_u64(v0, v2);
        v1 = vaddq_u64(v1, v3);
    }

    Clay__SIMDARXMix(&v0, &v1);
    Clay__SIMDARXMix(&v2, &v3);
    v0 = vaddq_u64(v0, v2);
    v1 = vaddq_u64(v1, v3);
    v0 = vaddq_u64(v0, v1);

    uint64_t result[2];
    vst1q_u64(result, v0);

    return result[0] ^ result[1];
}
#else
uint64_t Clay__HashData(const uint8_t* data, size_t length) {
    uint64_t hash = 0;

    for (size_t i = 0; i < length; i++) {
        hash += data[i];
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }
    return hash;
}
#endif

uint32_t Clay__HashStringContentsWithConfig(Clay_String *text, Clay_TextElementConfig *config) {
    uint32_t hash = 0;
    if (text->isStaticallyAllocated) {
        hash += (uintptr_t)text->chars;
        hash += (hash << 10);
        hash ^= (hash >> 6);
        hash += text->length;
        hash += (hash << 10);
        hash ^= (hash >> 6);
    } else {
        hash = Clay__HashData((const uint8_t *)text->chars, text->length) % UINT32_MAX;
    }

    hash += config->fontId;
    hash += (hash << 10);
    hash ^= (hash >> 6);

    hash += config->fontSize;
    hash += (hash << 10);
    hash ^= (hash >> 6);

    hash += config->letterSpacing;
    hash += (hash << 10);
    hash ^= (hash >> 6);

    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    return hash + 1; // Reserve the hash result of zero as "null id"
}

Clay__MeasuredWord *Clay__AddMeasuredWord(Clay__MeasuredWord word, Clay__MeasuredWord *previousWord) {
    Clay_Context* context = Clay_GetCurrentContext();
    if (context->measuredWordsFreeList.length > 0) {
        uint32_t newItemIndex = Clay__int32_tArray_GetValue(&context->measuredWordsFreeList, (int)context->measuredWordsFreeList.length - 1);
        context->measuredWordsFreeList.length--;
        Clay__MeasuredWordArray_Set(&context->measuredWords, (int)newItemIndex, word);
        previousWord->next = (int32_t)newItemIndex;
        return Clay__MeasuredWordArray_Get(&context->measuredWords, (int)newItemIndex);
    } else {
        previousWord->next = (int32_t)context->measuredWords.length;
        return Clay__MeasuredWordArray_Add(&context->measuredWords, word);
    }
}

Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_TextElementConfig *config) {
    Clay_Context* context = Clay_GetCurrentContext();
    #ifndef CLAY_WASM
    if (!Clay__MeasureText) {
        if (!context->booleanWarnings.textMeasurementFunctionNotSet) {
            context->booleanWarnings.textMeasurementFunctionNotSet = true;
            context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                    .errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
                    .errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."),
                    .userData = context->errorHandler.userData });
        }
        return &Clay__MeasureTextCacheItem_DEFAULT;
    }
    #endif
    uint32_t id = Clay__HashStringContentsWithConfig(text, config);
    uint32_t hashBucket = id % (context->maxMeasureTextCacheWordCount / 32);
    int32_t elementIndexPrevious = 0;
    int32_t elementIndex = context->measureTextHashMap.internalArray[hashBucket];
    while (elementIndex != 0) {
        Clay__MeasureTextCacheItem *hashEntry = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndex);
        if (hashEntry->id == id) {
            hashEntry->generation = context->generation;
            return hashEntry;
        }
        // This element hasn't been seen in a few frames, delete the hash map item
        if (context->generation - hashEntry->generation > 2) {
            // Add all the measured words that were included in this measurement to the freelist
            int32_t nextWordIndex = hashEntry->measuredWordsStartIndex;
            while (nextWordIndex != -1) {
                Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&context->measuredWords, nextWordIndex);
                Clay__int32_tArray_Add(&context->measuredWordsFreeList, nextWordIndex);
                nextWordIndex = measuredWord->next;
            }

            int32_t nextIndex = hashEntry->nextIndex;
            Clay__MeasureTextCacheItemArray_Set(&context->measureTextHashMapInternal, elementIndex, CLAY__INIT(Clay__MeasureTextCacheItem) { .measuredWordsStartIndex = -1 });
            Clay__int32_tArray_Add(&context->measureTextHashMapInternalFreeList, elementIndex);
            if (elementIndexPrevious == 0) {
                context->measureTextHashMap.internalArray[hashBucket] = nextIndex;
            } else {
                Clay__MeasureTextCacheItem *previousHashEntry = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndexPrevious);
                previousHashEntry->nextIndex = nextIndex;
            }
            elementIndex = nextIndex;
        } else {
            elementIndexPrevious = elementIndex;
            elementIndex = hashEntry->nextIndex;
        }
    }

    int32_t newItemIndex = 0;
    Clay__MeasureTextCacheItem newCacheItem = { .measuredWordsStartIndex = -1, .id = id, .generation = context->generation };
    Clay__MeasureTextCacheItem *measured = NULL;
    if (context->measureTextHashMapInternalFreeList.length > 0) {
        newItemIndex = Clay__int32_tArray_GetValue(&context->measureTextHashMapInternalFreeList, context->measureTextHashMapInternalFreeList.length - 1);
        context->measureTextHashMapInternalFreeList.length--;
        Clay__MeasureTextCacheItemArray_Set(&context->measureTextHashMapInternal, newItemIndex, newCacheItem);
        measured = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, newItemIndex);
    } else {
        if (context->measureTextHashMapInternal.length == context->measureTextHashMapInternal.capacity - 1) {
            if (!context->booleanWarnings.maxTextMeasureCacheExceeded) {
                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                        .errorType = CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
                        .errorText = CLAY_STRING("Clay ran out of capacity while attempting to measure text elements. Try using Clay_SetMaxElementCount() with a higher value."),
                        .userData = context->errorHandler.userData });
                context->booleanWarnings.maxTextMeasureCacheExceeded = true;
            }
            return &Clay__MeasureTextCacheItem_DEFAULT;
        }
        measured = Clay__MeasureTextCacheItemArray_Add(&context->measureTextHashMapInternal, newCacheItem);
        newItemIndex = context->measureTextHashMapInternal.length - 1;
    }

    int32_t start = 0;
    int32_t end = 0;
    float lineWidth = 0;
    float measuredWidth = 0;
    float measuredHeight = 0;
    float spaceWidth = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = 1, .chars = CLAY__SPACECHAR.chars, .baseChars = CLAY__SPACECHAR.chars }, config, context->measureTextUserData).width;
    Clay__MeasuredWord tempWord = { .next = -1 };
    Clay__MeasuredWord *previousWord = &tempWord;
    while (end < text->length) {
        if (context->measuredWords.length == context->measuredWords.capacity - 1) {
            if (!context->booleanWarnings.maxTextMeasureCacheExceeded) {
                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                    .errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
                    .errorText = CLAY_STRING("Clay has run out of space in it's internal text measurement cache. Try using Clay_SetMaxMeasureTextCacheWordCount() (default 16384, with 1 unit storing 1 measured word)."),
                    .userData = context->errorHandler.userData });
                context->booleanWarnings.maxTextMeasureCacheExceeded = true;
            }
            return &Clay__MeasureTextCacheItem_DEFAULT;
        }
        char current = text->chars[end];
        if (current == ' ' || current == '\n') {
            int32_t length = end - start;
            Clay_Dimensions dimensions = CLAY__DEFAULT_STRUCT;
            if (length > 0) {
                dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) {.length = length, .chars = &text->chars[start], .baseChars = text->chars}, config, context->measureTextUserData);
            }
            measured->minWidth = CLAY__MAX(dimensions.width, measured->minWidth);
            measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
            if (current == ' ') {
                dimensions.width += spaceWidth;
                previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = length + 1, .width = dimensions.width, .next = -1 }, previousWord);
                lineWidth += dimensions.width;
            }
            if (current == '\n') {
                if (length > 0) {
                    previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = length, .width = dimensions.width, .next = -1 }, previousWord);
                }
                previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = end + 1, .length = 0, .width = 0, .next = -1 }, previousWord);
                lineWidth += dimensions.width;
                measuredWidth = CLAY__MAX(lineWidth, measuredWidth);
                measured->containsNewlines = true;
                lineWidth = 0;
            }
            start = end + 1;
        }
        end++;
    }
    if (end - start > 0) {
        Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = end - start, .chars = &text->chars[start], .baseChars = text->chars }, config, context->measureTextUserData);
        Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = end - start, .width = dimensions.width, .next = -1 }, previousWord);
        lineWidth += dimensions.width;
        measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
        measured->minWidth = CLAY__MAX(dimensions.width, measured->minWidth);
    }
    measuredWidth = CLAY__MAX(lineWidth, measuredWidth) - config->letterSpacing;

    measured->measuredWordsStartIndex = tempWord.next;
    measured->unwrappedDimensions.width = measuredWidth;
    measured->unwrappedDimensions.height = measuredHeight;

    if (elementIndexPrevious != 0) {
        Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndexPrevious)->nextIndex = newItemIndex;
    } else {
        context->measureTextHashMap.internalArray[hashBucket] = newItemIndex;
    }
    return measured;
}

bool Clay__PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
    return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
}

Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
    Clay_Context* context = Clay_GetCurrentContext();
    if (co
Download .txt
gitextract_vqarsh70/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── cmake-multi-platform.yml
│       └── odin-bindings-update.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE.md
├── README.md
├── bindings/
│   ├── cpp/
│   │   └── README.md
│   ├── csharp/
│   │   └── README
│   ├── rust/
│   │   └── README
│   └── zig/
│       └── README
├── clay.h
├── cmake/
│   └── FindCairo.cmake
├── examples/
│   ├── GLES3-GLFW-video-demo/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── GLES3-SDL2-sidebar-scrolling-container/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── GLES3-SDL2-video-demo/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── Makefile.emscripten
│   │   ├── Makefile.macos
│   │   ├── README.md
│   │   └── main.c
│   ├── SDL2-video-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── SDL3-simple-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── cairo-pdf-rendering/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── clay-official-website/
│   │   ├── CMakeLists.txt
│   │   ├── build/
│   │   │   └── clay/
│   │   │       ├── index.html
│   │   │       └── index.wasm
│   │   ├── build.sh
│   │   ├── index.html
│   │   └── main.c
│   ├── cpp-project-example/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── introducing-clay-video-demo/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── playdate-project-example/
│   │   ├── .gitignore
│   │   ├── CmakeLists.txt
│   │   ├── README.md
│   │   ├── Source/
│   │   │   └── pdxinfo
│   │   ├── clay-video-demo-playdate.c
│   │   └── main.c
│   ├── raylib-multi-context/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── raylib-sidebar-scrolling-container/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── multi-compilation-unit.c
│   ├── shared-layouts/
│   │   └── clay-video-demo.c
│   ├── sokol-corner-radius/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   ├── sokol-video-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── sokol.c
│   ├── termbox2-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── readme.md
│   ├── termbox2-image-demo/
│   │   ├── CMakeLists.txt
│   │   ├── main.c
│   │   └── readme.md
│   ├── terminal-example/
│   │   ├── CMakeLists.txt
│   │   └── main.c
│   └── win32_gdi/
│       ├── CMakeLists.txt
│       ├── build.ps1
│       └── main.c
├── renderers/
│   ├── GLES3/
│   │   ├── clay_renderer_gles3.h
│   │   └── clay_renderer_gles3_loader_stb.c
│   ├── SDL2/
│   │   ├── README
│   │   └── clay_renderer_SDL2.c
│   ├── SDL3/
│   │   └── clay_renderer_SDL3.c
│   ├── cairo/
│   │   └── clay_renderer_cairo.c
│   ├── playdate/
│   │   └── clay_renderer_playdate.c
│   ├── raylib/
│   │   ├── clay_renderer_raylib.c
│   │   ├── raylib.h
│   │   └── raymath.h
│   ├── sokol/
│   │   └── sokol_clay.h
│   ├── termbox2/
│   │   ├── clay_renderer_termbox2.c
│   │   └── image_character_masks.h
│   ├── terminal/
│   │   └── clay_renderer_terminal_ansi.c
│   ├── web/
│   │   ├── build-wasm.sh
│   │   ├── canvas2d/
│   │   │   └── clay-canvas2d-renderer.html
│   │   ├── clay.wasm
│   │   └── html/
│   │       └── clay-html-renderer.html
│   └── win32_gdi/
│       ├── README.md
│       └── clay_renderer_gdi.c
└── tests/
    ├── docker-compose.yml
    ├── gcc/
    │   └── 9.4/
    │       └── Dockerfile
    └── run-tests.sh
Download .txt
SYMBOL INDEX (610 symbols across 36 files)

FILE: clay.h
  function Clay__SuppressUnusedLatchDefinitionVariableWarning (line 108) | static inline void Clay__SuppressUnusedLatchDefinitionVariableWarning(vo...
  type Clay_String (line 195) | typedef struct Clay_String {
  type Clay_StringSlice (line 206) | typedef struct Clay_StringSlice {
  type Clay_Context (line 212) | typedef struct Clay_Context Clay_Context;
  type Clay_Arena (line 216) | typedef struct Clay_Arena {
  type Clay_Dimensions (line 222) | typedef struct Clay_Dimensions {
  type Clay_Vector2 (line 226) | typedef struct Clay_Vector2 {
  type Clay_Color (line 231) | typedef struct Clay_Color {
  type Clay_BoundingBox (line 235) | typedef struct Clay_BoundingBox {
  type Clay_ElementId (line 242) | typedef struct Clay_ElementId {
  type Clay_ElementIdArray (line 250) | typedef struct
  type Clay_CornerRadius (line 259) | typedef struct Clay_CornerRadius {
  type CLAY_PACKED_ENUM (line 269) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 277) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 287) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 297) | typedef CLAY_PACKED_ENUM {
  type Clay_ChildAlignment (line 309) | typedef struct Clay_ChildAlignment {
  type Clay_SizingMinMax (line 316) | typedef struct Clay_SizingMinMax {
  type Clay_SizingAxis (line 322) | typedef struct Clay_SizingAxis {
  type Clay_Sizing (line 331) | typedef struct Clay_Sizing {
  type Clay_Padding (line 338) | typedef struct Clay_Padding {
  type Clay_LayoutConfig (line 349) | typedef struct Clay_LayoutConfig {
  type CLAY_PACKED_ENUM (line 362) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 372) | typedef CLAY_PACKED_ENUM {
  type Clay_TextElementConfig (line 382) | typedef struct Clay_TextElementConfig {
  type Clay_AspectRatioElementConfig (line 413) | typedef struct Clay_AspectRatioElementConfig {
  type Clay_ImageElementConfig (line 422) | typedef struct Clay_ImageElementConfig {
  type CLAY_PACKED_ENUM (line 432) | typedef CLAY_PACKED_ENUM {
  type Clay_FloatingAttachPoints (line 445) | typedef struct Clay_FloatingAttachPoints {
  type CLAY_PACKED_ENUM (line 451) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 461) | typedef CLAY_PACKED_ENUM {
  type CLAY_PACKED_ENUM (line 473) | typedef CLAY_PACKED_ENUM {
  type Clay_FloatingElementConfig (line 482) | typedef struct Clay_FloatingElementConfig {
  type Clay_CustomElementConfig (line 519) | typedef struct Clay_CustomElementConfig {
  type Clay_ClipElementConfig (line 530) | typedef struct Clay_ClipElementConfig {
  type Clay_BorderWidth (line 541) | typedef struct Clay_BorderWidth {
  type Clay_BorderElementConfig (line 553) | typedef struct Clay_BorderElementConfig {
  type Clay_TextRenderData (line 563) | typedef struct Clay_TextRenderData {
  type Clay_RectangleRenderData (line 579) | typedef struct Clay_RectangleRenderData {
  type Clay_ImageRenderData (line 588) | typedef struct Clay_ImageRenderData {
  type Clay_CustomRenderData (line 601) | typedef struct Clay_CustomRenderData {
  type Clay_ClipRenderData (line 613) | typedef struct Clay_ScrollRenderData {
  type Clay_BorderRenderData (line 619) | typedef struct Clay_BorderRenderData {
  type Clay_RenderData (line 631) | typedef union Clay_RenderData {
  type Clay_ScrollContainerData (line 649) | typedef struct Clay_ScrollContainerData {
  type Clay_ElementData (line 664) | typedef struct Clay_ElementData {
  type CLAY_PACKED_ENUM (line 672) | typedef CLAY_PACKED_ENUM {
  type Clay_RenderCommand (line 691) | typedef struct Clay_RenderCommand {
  type Clay_RenderCommandArray (line 716) | typedef struct Clay_RenderCommandArray {
  type CLAY_PACKED_ENUM (line 726) | typedef CLAY_PACKED_ENUM {
  type Clay_PointerData (line 738) | typedef struct Clay_PointerData {
  type Clay_ElementDeclaration (line 749) | typedef struct Clay_ElementDeclaration {
  type CLAY_PACKED_ENUM (line 778) | typedef CLAY_PACKED_ENUM {
  type Clay_ErrorData (line 801) | typedef struct Clay_ErrorData {
  type Clay_ErrorHandler (line 819) | typedef struct {
  function Clay__ErrorHandlerFunctionDefault (line 1031) | void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {
  type Clay_BooleanWarnings (line 1038) | typedef struct {
  type Clay__Warning (line 1045) | typedef struct {
  type Clay__WarningArray (line 1052) | typedef struct {
  type Clay_SharedElementConfig (line 1058) | typedef struct {
  type CLAY_PACKED_ENUM (line 1088) | typedef CLAY_PACKED_ENUM {
  type Clay_ElementConfigUnion (line 1100) | typedef union {
  type Clay_ElementConfig (line 1111) | typedef struct {
  type Clay__WrappedTextLine (line 1118) | typedef struct {
  type Clay__TextElementData (line 1125) | typedef struct {
  type Clay__LayoutElementChildren (line 1134) | typedef struct {
  type Clay_LayoutElement (line 1139) | typedef struct {
  type Clay__ScrollContainerDataInternal (line 1154) | typedef struct {
  type Clay__DebugElementData (line 1171) | typedef struct {
  type Clay_LayoutElementHashMapItem (line 1178) | typedef struct { // todo get this struct into a single cache line
  type Clay__MeasuredWord (line 1191) | typedef struct {
  type Clay__MeasureTextCacheItem (line 1200) | typedef struct {
  type Clay__LayoutElementTreeNode (line 1213) | typedef struct {
  type Clay__LayoutElementTreeRoot (line 1221) | typedef struct {
  type Clay_Context (line 1231) | struct Clay_Context {
  function Clay_Context (line 1293) | Clay_Context* Clay__Context_Allocate_Arena(Clay_Arena *arena) {
  function Clay_String (line 1303) | Clay_String Clay__WriteStringToCharBuffer(Clay__charArray *buffer, Clay_...
  function Clay_LayoutElement (line 1319) | Clay_LayoutElement* Clay__GetOpenLayoutElement(void) {
  function Clay__GetParentElementId (line 1324) | uint32_t Clay__GetParentElementId(void) {
  function Clay_LayoutConfig (line 1329) | Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) { ...
  function Clay_TextElementConfig (line 1330) | Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementCo...
  function Clay_AspectRatioElementConfig (line 1331) | Clay_AspectRatioElementConfig * Clay__StoreAspectRatioElementConfig(Clay...
  function Clay_ImageElementConfig (line 1332) | Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElemen...
  function Clay_FloatingElementConfig (line 1333) | Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_Float...
  function Clay_CustomElementConfig (line 1334) | Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomEle...
  function Clay_ClipElementConfig (line 1335) | Clay_ClipElementConfig * Clay__StoreClipElementConfig(Clay_ClipElementCo...
  function Clay_BorderElementConfig (line 1336) | Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderEle...
  function Clay_SharedElementConfig (line 1337) | Clay_SharedElementConfig * Clay__StoreSharedElementConfig(Clay_SharedEle...
  function Clay_ElementConfig (line 1339) | Clay_ElementConfig Clay__AttachElementConfig(Clay_ElementConfigUnion con...
  function Clay_ElementConfigUnion (line 1349) | Clay_ElementConfigUnion Clay__FindElementConfigWithType(Clay_LayoutEleme...
  type Clay__RenderDebugLayoutData (line 3180) | typedef struct {
  function Clay__WarningArray (line 3849) | Clay__WarningArray Clay__WarningArray_Allocate_Arena(int32_t capacity, C...
  function Clay__Warning (line 3866) | Clay__Warning *Clay__WarningArray_Add(Clay__WarningArray *array, Clay__W...
  function Clay__Array_RangeCheck (line 3892) | bool Clay__Array_RangeCheck(int32_t index, int32_t length)
  function Clay__Array_AddCapacityCheck (line 3905) | bool Clay__Array_AddCapacityCheck(int32_t length, int32_t capacity)
  function Clay_MinMemorySize (line 3921) | uint32_t Clay_MinMemorySize(void) {
  function Clay_Arena (line 3943) | Clay_Arena Clay_CreateArenaWithCapacityAndMemory(size_t capacity, void *...
  function Clay_SetMeasureTextFunction (line 3952) | void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(...
  function Clay_SetQueryScrollOffsetFunction (line 3957) | void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetF...
  function Clay_SetLayoutDimensions (line 3965) | void Clay_SetLayoutDimensions(Clay_Dimensions dimensions) {
  function Clay_SetPointerState (line 3970) | void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
  function Clay_Context (line 4041) | Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDi...
  function Clay_RenderCommandArray (line 4236) | Clay_RenderCommandArray Clay_EndLayout(void) {
  function Clay_ElementId (line 4269) | Clay_ElementId Clay_GetElementId(Clay_String idString) {
  function Clay_ElementId (line 4274) | Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t...
  function Clay_Hovered (line 4278) | bool Clay_Hovered(void) {
  function Clay_OnHover (line 4296) | void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay...
  function Clay_PointerOver (line 4311) | bool Clay_PointerOver(Clay_ElementId elementId) { // TODO return priorit...
  function Clay_ScrollContainerData (line 4322) | Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
  function Clay_ElementData (line 4344) | Clay_ElementData Clay_GetElementData(Clay_ElementId id){
  function Clay_SetDebugModeEnabled (line 4357) | void Clay_SetDebugModeEnabled(bool enabled) {
  function Clay_IsDebugModeEnabled (line 4363) | bool Clay_IsDebugModeEnabled(void) {
  function Clay_SetCullingEnabled (line 4369) | void Clay_SetCullingEnabled(bool enabled) {
  function Clay_SetExternalScrollHandlingEnabled (line 4375) | void Clay_SetExternalScrollHandlingEnabled(bool enabled) {
  function Clay_GetMaxElementCount (line 4381) | int32_t Clay_GetMaxElementCount(void) {
  function Clay_SetMaxElementCount (line 4387) | void Clay_SetMaxElementCount(int32_t maxElementCount) {
  function Clay_GetMaxMeasureTextCacheWordCount (line 4398) | int32_t Clay_GetMaxMeasureTextCacheWordCount(void) {
  function Clay_SetMaxMeasureTextCacheWordCount (line 4404) | void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWor...
  function Clay_ResetMeasureTextCache (line 4414) | void Clay_ResetMeasureTextCache(void) {

FILE: examples/GLES3-GLFW-video-demo/main.c
  type VideoCtx (line 16) | typedef struct VideoCtx
  function initVideo (line 25) | static int initVideo(VideoCtx *ctx, const int initialWidth, const int in...
  function My_ErrorHandler (line 74) | void My_ErrorHandler(Clay_ErrorData errorData)
  function scroll_callback (line 85) | static void scroll_callback(GLFWwindow* window, double xoffset, double y...
  function init (line 91) | void init()
  function loop (line 133) | void loop()
  function main (line 193) | int main()

FILE: examples/GLES3-SDL2-sidebar-scrolling-container/main.c
  type VideoCtx (line 15) | typedef struct VideoCtx
  function initVideo (line 25) | static int initVideo(VideoCtx *ctx, const int initialWidth, const int in...
  function My_ErrorHandler (line 78) | void My_ErrorHandler(Clay_ErrorData errorData)
  function init (line 105) | void init()
  function RenderDropdownTextItem (line 217) | void RenderDropdownTextItem(int index)

FILE: examples/GLES3-SDL2-video-demo/main.c
  type VideoCtx (line 14) | typedef struct VideoCtx
  function initVideo (line 24) | static int initVideo(VideoCtx *ctx, const int initialWidth, const int in...
  function My_ErrorHandler (line 78) | void My_ErrorHandler(Clay_ErrorData errorData)
  function init (line 91) | void init()
  function loop (line 129) | void loop()
  function main (line 184) | int main()

FILE: examples/SDL2-video-demo/main.c
  function HandleClayErrors (line 16) | void HandleClayErrors(Clay_ErrorData errorData) {
  type ResizeRenderData_ (line 21) | struct ResizeRenderData_ {
  type ResizeRenderData (line 29) | typedef struct ResizeRenderData_ ResizeRenderData;
  function resizeRendering (line 31) | int resizeRendering(void* userData, SDL_Event* event) {
  function main (line 55) | int main(int argc, char *argv[]) {

FILE: examples/SDL3-simple-demo/main.c
  type AppState (line 20) | typedef struct app_state {
  function Clay_Dimensions (line 29) | static inline Clay_Dimensions SDL_MeasureText(Clay_StringSlice text, Cla...
  function HandleClayErrors (line 43) | void HandleClayErrors(Clay_ErrorData errorData) {
  function Clay_RenderCommandArray (line 48) | Clay_RenderCommandArray ClayImageSample_CreateLayout() {
  function SDL_AppResult (line 79) | SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
  function SDL_AppResult (line 144) | SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
  function SDL_AppResult (line 178) | SDL_AppResult SDL_AppIterate(void *appstate)
  function SDL_AppQuit (line 197) | void SDL_AppQuit(void *appstate, SDL_AppResult result)

FILE: examples/cairo-pdf-rendering/main.c
  function main (line 116) | int main(void) {

FILE: examples/clay-official-website/main.c
  type Arena (line 40) | typedef struct {
  type CustomHTMLData (line 47) | typedef struct d {
  function CustomHTMLData (line 53) | CustomHTMLData* FrameAllocateCustomData(CustomHTMLData data) {
  function Clay_String (line 60) | Clay_String* FrameAllocateString(Clay_String string) {
  function LandingPageBlob (line 67) | void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_Str...
  function LandingPageDesktop (line 74) | void LandingPageDesktop() {
  function LandingPageMobile (line 93) | void LandingPageMobile() {
  function FeatureBlocksDesktop (line 110) | void FeatureBlocksDesktop() {
  function FeatureBlocksMobile (line 130) | void FeatureBlocksMobile() {
  type ScrollbarData (line 331) | typedef struct
  function Clay_RenderCommandArray (line 341) | Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
  function SetScratchMemory (line 434) | void SetScratchMemory(void * memory) {
  function Clay_RenderCommandArray (line 438) | Clay_RenderCommandArray UpdateDrawFrame(float width, float height, float...
  function main (line 508) | int main() {

FILE: examples/cpp-project-example/main.cpp
  function HandleClayErrors (line 7) | void HandleClayErrors(Clay_ErrorData errorData) {
  function main (line 11) | int main(void) {

FILE: examples/introducing-clay-video-demo/main.c
  function HandleClayErrors (line 7) | void HandleClayErrors(Clay_ErrorData errorData) {
  function main (line 11) | int main(void) {

FILE: examples/playdate-project-example/clay-video-demo-playdate.c
  function RenderHeaderButton (line 20) | void RenderHeaderButton(Clay_String text) {
  type Document (line 33) | typedef struct {
  type DocumentArray (line 39) | typedef struct {
  function ClayVideoDemoPlaydate_Initialize (line 49) | void ClayVideoDemoPlaydate_Initialize(PlaydateAPI* pd) {

FILE: examples/playdate-project-example/main.c
  function HandleClayErrors (line 16) | void HandleClayErrors(Clay_ErrorData errorData) {}
  type TextUserData (line 18) | struct TextUserData {
  type TextUserData (line 23) | struct TextUserData
  function Clay_Dimensions (line 25) | static Clay_Dimensions PlayDate_MeasureText(Clay_StringSlice text, Clay_...
  function eventHandler (line 42) | __declspec(dllexport)
  function update (line 81) | static int update(void *userdata) {

FILE: examples/raylib-multi-context/main.c
  function HandleClayErrors (line 6) | void HandleClayErrors(Clay_ErrorData errorData) {
  function Clay_RenderCommandArray (line 10) | Clay_RenderCommandArray CreateLayout(Clay_Context* context, ClayVideoDem...
  function main (line 33) | int main(void) {

FILE: examples/raylib-sidebar-scrolling-container/main.c
  function HandleHeaderButtonInteraction (line 16) | void HandleHeaderButtonInteraction(Clay_ElementId elementId, Clay_Pointe...
  function Clay_ElementDeclaration (line 22) | Clay_ElementDeclaration HeaderButtonStyle(bool hovered) {
  function RenderHeaderButton (line 30) | void RenderHeaderButton(Clay_String text) {
  function RenderDropdownTextItem (line 39) | void RenderDropdownTextItem(int index) {
  function Clay_RenderCommandArray (line 45) | Clay_RenderCommandArray CreateLayout(void) {
  type ScrollbarData (line 145) | typedef struct
  function UpdateDrawFrame (line 156) | void UpdateDrawFrame(Font* fonts)
  function HandleClayErrors (line 214) | void HandleClayErrors(Clay_ErrorData errorData) {
  function main (line 225) | int main(void) {

FILE: examples/raylib-sidebar-scrolling-container/multi-compilation-unit.c
  function SatisfyCompiler (line 5) | void SatisfyCompiler(void) {

FILE: examples/shared-layouts/clay-video-demo.c
  function RenderHeaderButton (line 7) | void RenderHeaderButton(Clay_String text) {
  function RenderDropdownMenuItem (line 21) | void RenderDropdownMenuItem(Clay_String text) {
  type Document (line 31) | typedef struct {
  type DocumentArray (line 36) | typedef struct {
  type ClayVideoDemo_Arena (line 48) | typedef struct {
  type ClayVideoDemo_Data (line 53) | typedef struct {
  type SidebarClickData (line 59) | typedef struct {
  function HandleSidebarInteraction (line 64) | void HandleSidebarInteraction(
  function ClayVideoDemo_Data (line 79) | ClayVideoDemo_Data ClayVideoDemo_Initialize() {
  function Clay_RenderCommandArray (line 92) | Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *d...

FILE: examples/sokol-corner-radius/main.c
  function init (line 15) | static void init() {
  function frame (line 71) | static void frame() {
  function event (line 84) | static void event(const sapp_event *ev) {
  function cleanup (line 92) | static void cleanup() {
  function sapp_desc (line 98) | sapp_desc sokol_main(int argc, char **argv) {

FILE: examples/sokol-video-demo/main.c
  function init (line 20) | static void init() {
  function frame (line 37) | static void frame() {
  function event (line 50) | static void event(const sapp_event *ev) {
  function cleanup (line 58) | static void cleanup() {
  function sapp_desc (line 64) | sapp_desc sokol_main(int argc, char **argv) {

FILE: examples/termbox2-demo/main.c
  function component_image (line 410) | void component_image(clay_tb_image *image, int width)
  function handle_termbox_events (line 575) | void handle_termbox_events(void)
  function main (line 746) | int main(void)

FILE: examples/termbox2-image-demo/main.c
  type img_group (line 49) | struct img_group {
  type img_group (line 57) | typedef struct img_group img_group;
  function img_group (line 73) | img_group img_group_load(const char *filename)
  function img_group_free (line 90) | void img_group_free(img_group *img)
  function component_image (line 312) | void component_image(img_group *img_pair)
  function component_image_small (line 344) | void component_image_small(img_group **img_pairs, int count, int selecte...
  function component_thumbnails (line 385) | void component_thumbnails(img_group **img_pairs, int count, int selected...
  function Clay_RenderCommandArray (line 428) | Clay_RenderCommandArray CreateLayout(struct img_group **imgs)
  function handle_clay_errors (line 456) | void handle_clay_errors(Clay_ErrorData errorData)
  function handle_termbox_events (line 466) | void handle_termbox_events(void)
  function main (line 650) | int main(void)

FILE: examples/terminal-example/main.c
  function HandleClayErrors (line 13) | void HandleClayErrors(Clay_ErrorData errorData) {
  function main (line 17) | int main() {

FILE: examples/win32_gdi/main.c
  function LRESULT (line 37) | LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM ...
  function HandleClayErrors (line 137) | void HandleClayErrors(Clay_ErrorData errorData)
  function WinMain (line 147) | int APIENTRY WinMain(
  function CenterWindow (line 212) | void CenterWindow(HWND hwnd_self)

FILE: renderers/GLES3/clay_renderer_gles3.h
  type RectInstance (line 33) | typedef struct RectInstance
  type GlyphVtx (line 50) | typedef struct GlyphVtx
  type Gles3_GlyphVtxArray (line 59) | typedef struct Gles3_GlyphVtxArray
  type Gles3_QuadInstanceArray (line 66) | typedef struct Gles3_QuadInstanceArray
  type Gles3_ImageConfig (line 73) | typedef struct Gles3_ImageConfig
  type Gles3_Renderer (line 81) | typedef struct Gles3_Renderer Gles3_Renderer;
  type Gles3_Renderer (line 301) | typedef struct Gles3_Renderer
  function GLuint (line 336) | static GLuint Gles3__CompileShader(GLenum type, const char *source)
  function GLuint (line 364) | GLuint Gles3__CreateShaderProgram(
  function Gles3_Initialize (line 384) | void Gles3_Initialize(Gles3_Renderer *renderer, int maxInstances)
  function Gles3_SetRenderTextFunction (line 516) | void Gles3_SetRenderTextFunction(
  function Gles3_Render (line 525) | void Gles3_Render(

FILE: renderers/GLES3/clay_renderer_gles3_loader_stb.c
  type LoadedImage (line 11) | typedef struct LoadedImage
  type LoadedImageInternal (line 19) | typedef struct LoadedImageInternal
  function LoadedImage (line 26) | const LoadedImage *loadImage(const char *path, bool flip)
  function freeImage (line 56) | void freeImage(const LoadedImage *img)
  type Stb_FontData (line 71) | typedef struct Stb_FontData
  function Stb_LoadFont (line 83) | bool Stb_LoadFont(
  function Clay_Dimensions (line 186) | static inline Clay_Dimensions Stb_MeasureText(
  function Stb_RenderText (line 245) | static inline void Stb_RenderText(
  function Stb_LoadImage (line 331) | bool Stb_LoadImage(GLuint *textureOut, const char *path)

FILE: renderers/SDL2/clay_renderer_SDL2.c
  type SDL2_Font (line 14) | typedef struct
  function Clay_Dimensions (line 21) | static Clay_Dimensions SDL2_MeasureText(Clay_StringSlice text, Clay_Text...
  function SDL_RenderFillRoundedRect (line 47) | static void SDL_RenderFillRoundedRect(SDL_Renderer* renderer, const SDL_...
  function SDL_RenderCornerBorder (line 151) | static void SDL_RenderCornerBorder(SDL_Renderer *renderer, Clay_Bounding...
  function Clay_SDL2_Render (line 267) | static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandA...

FILE: renderers/SDL3/clay_renderer_SDL3.c
  type Clay_SDL3RendererData (line 7) | typedef struct {
  function SDL_Clay_RenderFillRoundedRect (line 18) | static void SDL_Clay_RenderFillRoundedRect(Clay_SDL3RendererData *render...
  function SDL_Clay_RenderArc (line 119) | static void SDL_Clay_RenderArc(Clay_SDL3RendererData *rendererData, cons...
  function SDL_Clay_RenderClayCommands (line 146) | static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererD...

FILE: renderers/cairo/clay_renderer_cairo.c
  function Clay_Dimensions (line 78) | static inline Clay_Dimensions Clay_Cairo_MeasureText(Clay_StringSlice st...
  function Clay_Cairo_Initialize (line 153) | void Clay_Cairo_Initialize(cairo_t *cairo) {
  function Clay_Cairo__Blit_Surface (line 158) | void Clay_Cairo__Blit_Surface(cairo_surface_t *src_surface, cairo_surfac...
  function Clay_Cairo_Render (line 185) | void Clay_Cairo_Render(Clay_RenderCommandArray commands, char** fonts) {

FILE: renderers/playdate/clay_renderer_playdate.c
  function Clay_Playdate_CountUtf8Codepoints (line 5) | static size_t Clay_Playdate_CountUtf8Codepoints(const char *str, size_t ...
  function LCDColor (line 20) | static LCDColor clayColorToLCDColor(Clay_Color color) {
  function LCDBitmapDrawMode (line 27) | static LCDBitmapDrawMode clayColorToDrawMode(Clay_Color color) {
  function clampCornerRadius (line 34) | static float clampCornerRadius(float yAxisSize, float radius) {
  function Clay_Playdate_Render (line 46) | static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArra...

FILE: renderers/raylib/clay_renderer_raylib.c
  type CustomLayoutElementType (line 13) | typedef enum
  type CustomLayoutElement_3DModel (line 18) | typedef struct
  type CustomLayoutElement (line 26) | typedef struct
  function Ray (line 35) | Ray GetScreenToWorldPointWithZDistance(Vector2 position, Camera camera, ...
  function Clay_Dimensions (line 84) | static inline Clay_Dimensions Raylib_MeasureText(Clay_StringSlice text, ...
  function Clay_Raylib_Initialize (line 127) | void Clay_Raylib_Initialize(int width, int height, const char *title, un...
  function Clay_Raylib_Close (line 139) | void Clay_Raylib_Close()
  function Clay_Raylib_Render (line 148) | void Clay_Raylib_Render(Clay_RenderCommandArray renderCommands, Font* fo...

FILE: renderers/raylib/raylib.h
  type bool (line 210) | enum bool { false = 0, true = !false }
  type Vector2 (line 215) | typedef struct Vector2 {
  type Vector3 (line 221) | typedef struct Vector3 {
  type Vector4 (line 228) | typedef struct Vector4 {
  type Vector4 (line 236) | typedef Vector4 Quaternion;
  type Matrix (line 239) | typedef struct Matrix {
  type Color (line 247) | typedef struct Color {
  type Rectangle (line 255) | typedef struct Rectangle {
  type Image (line 263) | typedef struct Image {
  type Texture (line 272) | typedef struct Texture {
  type Texture (line 281) | typedef Texture Texture2D;
  type Texture (line 284) | typedef Texture TextureCubemap;
  type RenderTexture (line 287) | typedef struct RenderTexture {
  type RenderTexture (line 294) | typedef RenderTexture RenderTexture2D;
  type NPatchInfo (line 297) | typedef struct NPatchInfo {
  type GlyphInfo (line 307) | typedef struct GlyphInfo {
  type Font (line 316) | typedef struct Font {
  type Camera3D (line 326) | typedef struct Camera3D {
  type Camera3D (line 334) | typedef Camera3D Camera;
  type Camera2D (line 337) | typedef struct Camera2D {
  type Mesh (line 345) | typedef struct Mesh {
  type Shader (line 372) | typedef struct Shader {
  type MaterialMap (line 378) | typedef struct MaterialMap {
  type Material (line 385) | typedef struct Material {
  type Transform (line 392) | typedef struct Transform {
  type BoneInfo (line 399) | typedef struct BoneInfo {
  type Model (line 405) | typedef struct Model {
  type ModelAnimation (line 421) | typedef struct ModelAnimation {
  type Ray (line 430) | typedef struct Ray {
  type RayCollision (line 436) | typedef struct RayCollision {
  type BoundingBox (line 444) | typedef struct BoundingBox {
  type Wave (line 450) | typedef struct Wave {
  type rAudioBuffer (line 460) | typedef struct rAudioBuffer rAudioBuffer;
  type rAudioProcessor (line 461) | typedef struct rAudioProcessor rAudioProcessor;
  type AudioStream (line 464) | typedef struct AudioStream {
  type Sound (line 474) | typedef struct Sound {
  type Music (line 480) | typedef struct Music {
  type VrDeviceInfo (line 490) | typedef struct VrDeviceInfo {
  type VrStereoConfig (line 503) | typedef struct VrStereoConfig {
  type FilePathList (line 515) | typedef struct FilePathList {
  type AutomationEvent (line 522) | typedef struct AutomationEvent {
  type AutomationEventList (line 529) | typedef struct AutomationEventList {
  type ConfigFlags (line 541) | typedef enum {
  type TraceLogLevel (line 562) | typedef enum {
  type KeyboardKey (line 576) | typedef enum {
  type MouseButton (line 699) | typedef enum {
  type MouseCursor (line 710) | typedef enum {
  type GamepadButton (line 725) | typedef enum {
  type GamepadAxis (line 747) | typedef enum {
  type MaterialMapIndex (line 757) | typedef enum {
  type ShaderLocationIndex (line 775) | typedef enum {
  type ShaderUniformDataType (line 811) | typedef enum {
  type ShaderAttributeDataType (line 824) | typedef enum {
  type PixelFormat (line 833) | typedef enum {
  type TextureFilter (line 863) | typedef enum {
  type TextureWrap (line 873) | typedef enum {
  type CubemapLayout (line 881) | typedef enum {
  type FontType (line 890) | typedef enum {
  type BlendMode (line 897) | typedef enum {
  type Gesture (line 910) | typedef enum {
  type CameraMode (line 925) | typedef enum {
  type CameraProjection (line 934) | typedef enum {
  type NPatchLayout (line 940) | typedef enum {

FILE: renderers/raylib/raymath.h
  type Vector2 (line 117) | typedef struct Vector2 {
  type Vector3 (line 126) | typedef struct Vector3 {
  type Vector4 (line 136) | typedef struct Vector4 {
  type Vector4 (line 147) | typedef Vector4 Quaternion;
  type Matrix (line 153) | typedef struct Matrix {
  type float3 (line 163) | typedef struct float3 {
  type float16 (line 167) | typedef struct float16 {
  function RMAPI (line 178) | RMAPI float Clamp(float value, float min, float max)
  function RMAPI (line 188) | RMAPI float Lerp(float start, float end, float amount)
  function RMAPI (line 196) | RMAPI float Normalize(float value, float start, float end)
  function RMAPI (line 204) | RMAPI float Remap(float value, float inputStart, float inputEnd, float o...
  function RMAPI (line 212) | RMAPI float Wrap(float value, float min, float max)
  function RMAPI (line 220) | RMAPI int FloatEquals(float x, float y)
  function RMAPI (line 236) | RMAPI Vector2 Vector2Zero(void)
  function RMAPI (line 244) | RMAPI Vector2 Vector2One(void)
  function RMAPI (line 252) | RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2)
  function RMAPI (line 260) | RMAPI Vector2 Vector2AddValue(Vector2 v, float add)
  function RMAPI (line 268) | RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
  function RMAPI (line 276) | RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub)
  function RMAPI (line 284) | RMAPI float Vector2Length(Vector2 v)
  function RMAPI (line 292) | RMAPI float Vector2LengthSqr(Vector2 v)
  function RMAPI (line 300) | RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2)
  function RMAPI (line 308) | RMAPI float Vector2Distance(Vector2 v1, Vector2 v2)
  function RMAPI (line 316) | RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
  function RMAPI (line 325) | RMAPI float Vector2Angle(Vector2 v1, Vector2 v2)
  function RMAPI (line 340) | RMAPI float Vector2LineAngle(Vector2 start, Vector2 end)
  function RMAPI (line 351) | RMAPI Vector2 Vector2Scale(Vector2 v, float scale)
  function RMAPI (line 359) | RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2)
  function RMAPI (line 367) | RMAPI Vector2 Vector2Negate(Vector2 v)
  function RMAPI (line 375) | RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
  function RMAPI (line 383) | RMAPI Vector2 Vector2Normalize(Vector2 v)
  function RMAPI (line 399) | RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat)
  function RMAPI (line 414) | RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount)
  function RMAPI (line 425) | RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal)
  function RMAPI (line 438) | RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2)
  function RMAPI (line 449) | RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2)
  function RMAPI (line 460) | RMAPI Vector2 Vector2Rotate(Vector2 v, float angle)
  function RMAPI (line 474) | RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDis...
  function RMAPI (line 493) | RMAPI Vector2 Vector2Invert(Vector2 v)
  function RMAPI (line 502) | RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max)
  function RMAPI (line 513) | RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max)
  function RMAPI (line 540) | RMAPI int Vector2Equals(Vector2 p, Vector2 q)
  function RMAPI (line 557) | RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r)
  function RMAPI (line 582) | RMAPI Vector3 Vector3Zero(void)
  function RMAPI (line 590) | RMAPI Vector3 Vector3One(void)
  function RMAPI (line 598) | RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2)
  function RMAPI (line 606) | RMAPI Vector3 Vector3AddValue(Vector3 v, float add)
  function RMAPI (line 614) | RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
  function RMAPI (line 622) | RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub)
  function RMAPI (line 630) | RMAPI Vector3 Vector3Scale(Vector3 v, float scalar)
  function RMAPI (line 638) | RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2)
  function RMAPI (line 646) | RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2)
  function RMAPI (line 654) | RMAPI Vector3 Vector3Perpendicular(Vector3 v)
  function RMAPI (line 683) | RMAPI float Vector3Length(const Vector3 v)
  function RMAPI (line 691) | RMAPI float Vector3LengthSqr(const Vector3 v)
  function RMAPI (line 699) | RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2)
  function RMAPI (line 707) | RMAPI float Vector3Distance(Vector3 v1, Vector3 v2)
  function RMAPI (line 720) | RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2)
  function RMAPI (line 733) | RMAPI float Vector3Angle(Vector3 v1, Vector3 v2)
  function RMAPI (line 746) | RMAPI Vector3 Vector3Negate(Vector3 v)
  function RMAPI (line 754) | RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2)
  function RMAPI (line 762) | RMAPI Vector3 Vector3Normalize(Vector3 v)
  function RMAPI (line 780) | RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2)
  function RMAPI (line 797) | RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2)
  function RMAPI (line 816) | RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2)
  function RMAPI (line 849) | RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat)
  function RMAPI (line 865) | RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
  function RMAPI (line 877) | RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float an...
  function RMAPI (line 929) | RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDis...
  function RMAPI (line 950) | RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
  function RMAPI (line 963) | RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 ...
  function RMAPI (line 978) | RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
  function RMAPI (line 996) | RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2)
  function RMAPI (line 1008) | RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2)
  function RMAPI (line 1021) | RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  function RMAPI (line 1045) | RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix...
  function RMAPI (line 1128) | RMAPI float3 Vector3ToFloatV(Vector3 v)
  function RMAPI (line 1140) | RMAPI Vector3 Vector3Invert(Vector3 v)
  function RMAPI (line 1149) | RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max)
  function RMAPI (line 1161) | RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max)
  function RMAPI (line 1189) | RMAPI int Vector3Equals(Vector3 p, Vector3 q)
  function RMAPI (line 1207) | RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r)
  function RMAPI (line 1232) | RMAPI Vector4 Vector4Zero(void)
  function RMAPI (line 1238) | RMAPI Vector4 Vector4One(void)
  function RMAPI (line 1244) | RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2)
  function RMAPI (line 1255) | RMAPI Vector4 Vector4AddValue(Vector4 v, float add)
  function RMAPI (line 1266) | RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2)
  function RMAPI (line 1277) | RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add)
  function RMAPI (line 1288) | RMAPI float Vector4Length(Vector4 v)
  function RMAPI (line 1294) | RMAPI float Vector4LengthSqr(Vector4 v)
  function RMAPI (line 1300) | RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2)
  function RMAPI (line 1307) | RMAPI float Vector4Distance(Vector4 v1, Vector4 v2)
  function RMAPI (line 1316) | RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2)
  function RMAPI (line 1325) | RMAPI Vector4 Vector4Scale(Vector4 v, float scale)
  function RMAPI (line 1332) | RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2)
  function RMAPI (line 1339) | RMAPI Vector4 Vector4Negate(Vector4 v)
  function RMAPI (line 1346) | RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2)
  function RMAPI (line 1353) | RMAPI Vector4 Vector4Normalize(Vector4 v)
  function RMAPI (line 1371) | RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2)
  function RMAPI (line 1384) | RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2)
  function RMAPI (line 1397) | RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount)
  function RMAPI (line 1410) | RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDis...
  function RMAPI (line 1433) | RMAPI Vector4 Vector4Invert(Vector4 v)
  function RMAPI (line 1440) | RMAPI int Vector4Equals(Vector4 p, Vector4 q)
  function RMAPI (line 1459) | RMAPI float MatrixDeterminant(Matrix mat)
  function RMAPI (line 1480) | RMAPI float MatrixTrace(Matrix mat)
  function RMAPI (line 1488) | RMAPI Matrix MatrixTranspose(Matrix mat)
  function RMAPI (line 1513) | RMAPI Matrix MatrixInvert(Matrix mat)
  function RMAPI (line 1560) | RMAPI Matrix MatrixIdentity(void)
  function RMAPI (line 1571) | RMAPI Matrix MatrixAdd(Matrix left, Matrix right)
  function RMAPI (line 1596) | RMAPI Matrix MatrixSubtract(Matrix left, Matrix right)
  function RMAPI (line 1622) | RMAPI Matrix MatrixMultiply(Matrix left, Matrix right)
  function RMAPI (line 1647) | RMAPI Matrix MatrixTranslate(float x, float y, float z)
  function RMAPI (line 1659) | RMAPI Matrix MatrixRotate(Vector3 axis, float angle)
  function RMAPI (line 1704) | RMAPI Matrix MatrixRotateX(float angle)
  function RMAPI (line 1724) | RMAPI Matrix MatrixRotateY(float angle)
  function RMAPI (line 1744) | RMAPI Matrix MatrixRotateZ(float angle)
  function RMAPI (line 1765) | RMAPI Matrix MatrixRotateXYZ(Vector3 angle)
  function RMAPI (line 1796) | RMAPI Matrix MatrixRotateZYX(Vector3 angle)
  function RMAPI (line 1831) | RMAPI Matrix MatrixScale(float x, float y, float z)
  function RMAPI (line 1842) | RMAPI Matrix MatrixFrustum(double left, double right, double bottom, dou...
  function RMAPI (line 1875) | RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPl...
  function RMAPI (line 1901) | RMAPI Matrix MatrixOrtho(double left, double right, double bottom, doubl...
  function RMAPI (line 1930) | RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
  function RMAPI (line 1985) | RMAPI float16 MatrixToFloatV(Matrix mat)
  function RMAPI (line 2014) | RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2)
  function RMAPI (line 2022) | RMAPI Quaternion QuaternionAddValue(Quaternion q, float add)
  function RMAPI (line 2030) | RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2)
  function RMAPI (line 2038) | RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub)
  function RMAPI (line 2046) | RMAPI Quaternion QuaternionIdentity(void)
  function RMAPI (line 2054) | RMAPI float QuaternionLength(Quaternion q)
  function RMAPI (line 2062) | RMAPI Quaternion QuaternionNormalize(Quaternion q)
  function RMAPI (line 2079) | RMAPI Quaternion QuaternionInvert(Quaternion q)
  function RMAPI (line 2099) | RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
  function RMAPI (line 2115) | RMAPI Quaternion QuaternionScale(Quaternion q, float mul)
  function RMAPI (line 2128) | RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2)
  function RMAPI (line 2136) | RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
  function RMAPI (line 2149) | RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amo...
  function RMAPI (line 2174) | RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amo...
  function RMAPI (line 2221) | RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion ...
  function RMAPI (line 2246) | RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
  function RMAPI (line 2274) | RMAPI Quaternion QuaternionFromMatrix(Matrix mat)
  function RMAPI (line 2338) | RMAPI Matrix QuaternionToMatrix(Quaternion q)
  function RMAPI (line 2372) | RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
  function RMAPI (line 2416) | RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *...
  function RMAPI (line 2454) | RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll)
  function RMAPI (line 2475) | RMAPI Vector3 QuaternionToEuler(Quaternion q)
  function RMAPI (line 2499) | RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat)
  function RMAPI (line 2512) | RMAPI int QuaternionEquals(Quaternion p, Quaternion q)
  function RMAPI (line 2531) | RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion ...
  function Vector2 (line 2602) | inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
  function Vector2 (line 2613) | inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
  function Vector2 (line 2624) | inline Vector2 operator * (const Vector2& lhs, const float& rhs)
  function Vector2 (line 2635) | inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
  function Vector2 (line 2646) | inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
  function Vector2 (line 2657) | inline Vector2 operator / (const Vector2& lhs, const float& rhs)
  function Vector2 (line 2668) | inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
  function operator (line 2679) | inline bool operator == (const Vector2& lhs, const Vector2& rhs)
  function operator (line 2684) | inline bool operator != (const Vector2& lhs, const Vector2& rhs)
  function Vector3 (line 2696) | inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
  function Vector3 (line 2707) | inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
  function Vector3 (line 2718) | inline Vector3 operator * (const Vector3& lhs, const float& rhs)
  function Vector3 (line 2729) | inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
  function Vector3 (line 2740) | inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
  function Vector3 (line 2751) | inline Vector3 operator / (const Vector3& lhs, const float& rhs)
  function Vector3 (line 2762) | inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
  function operator (line 2773) | inline bool operator == (const Vector3& lhs, const Vector3& rhs)
  function operator (line 2778) | inline bool operator != (const Vector3& lhs, const Vector3& rhs)
  function Vector4 (line 2791) | inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
  function Vector4 (line 2802) | inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
  function Vector4 (line 2813) | inline Vector4 operator * (const Vector4& lhs, const float& rhs)
  function Vector4 (line 2824) | inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
  function Vector4 (line 2835) | inline Vector4 operator / (const Vector4& lhs, const float& rhs)
  function Vector4 (line 2846) | inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
  function operator (line 2857) | inline bool operator == (const Vector4& lhs, const Vector4& rhs)
  function operator (line 2862) | inline bool operator != (const Vector4& lhs, const Vector4& rhs)
  function Quaternion (line 2872) | inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
  function Quaternion (line 2883) | inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
  function Quaternion (line 2894) | inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
  function Matrix (line 2906) | inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
  function Matrix (line 2917) | inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
  function Matrix (line 2928) | inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)

FILE: renderers/sokol/sokol_clay.h
  type sclay_font_t (line 111) | typedef int sclay_font_t;
  type sclay_image (line 113) | typedef struct sclay_image {
  type _sclay_state_t (line 155) | typedef struct {
  function sclay_setup (line 167) | void sclay_setup() {
  function sclay_shutdown (line 188) | void sclay_shutdown() {
  function sclay_handle_event (line 194) | void sclay_handle_event(const sapp_event* ev) {
  function sclay_new_frame (line 214) | void sclay_new_frame() {
  function sclay_set_layout_dimensions (line 223) | void sclay_set_layout_dimensions(Clay_Dimensions size, float dpi_scale) {
  function sclay_font_t (line 234) | sclay_font_t sclay_add_font(const char *filename) {
  function sclay_font_t (line 239) | sclay_font_t sclay_add_font_mem(unsigned char *data, int dataLen) {
  function Clay_Dimensions (line 244) | Clay_Dimensions sclay_measure_text(Clay_StringSlice text, Clay_TextEleme...
  function _draw_rect (line 259) | static void _draw_rect(float x, float y, float w, float h){
  function _draw_rect_textured (line 268) | static void _draw_rect_textured(float x, float y, float w, float h, floa...
  function _draw_corner (line 285) | static void _draw_corner(float x, float y, float rx, float ry){
  function _draw_corner_textured (line 296) | static void _draw_corner_textured(float x, float y, float rx, float ry, ...
  function _draw_corner_border (line 314) | static void _draw_corner_border(float x, float y, float rx, float ry, fl...
  function sclay_render (line 325) | void sclay_render(Clay_RenderCommandArray renderCommands, sclay_font_t *...

FILE: renderers/termbox2/clay_renderer_termbox2.c
  type clay_tb_dimensions (line 41) | typedef struct {
  type clay_tb_pixel_dimensions (line 45) | typedef struct {
  type clay_tb_cell_bounding_box (line 49) | typedef struct {
  type clay_tb_color_pair (line 54) | typedef struct {
  type border_mode (line 59) | enum border_mode {
  type border_chars (line 65) | enum border_chars {
  type image_mode (line 73) | enum image_mode {
  type clay_tb_image (line 85) | typedef struct {
  type border_mode (line 173) | enum border_mode
  type border_chars (line 185) | enum border_chars
  type image_mode (line 212) | enum image_mode
  type border_mode (line 344) | enum border_mode
  type border_chars (line 345) | enum border_chars
  type image_mode (line 345) | enum image_mode
  type border_mode (line 373) | enum border_mode
  type border_chars (line 374) | enum border_chars
  type image_mode (line 375) | enum image_mode
  function clay_tb_valid_color (line 413) | static inline bool clay_tb_valid_color(Clay_Color color)
  function clay_tb_rgb_intensity_to_index (line 439) | static int clay_tb_rgb_intensity_to_index(int color)
  function uintattr_t (line 453) | static uintattr_t clay_tb_color_convert(Clay_Color color)
  function clay_tb_roundf (line 590) | static inline int clay_tb_roundf(float f)
  function clay_tb_cell_bounding_box (line 604) | static inline clay_tb_cell_bounding_box cell_snap_bounding_box(Clay_Boun...
  function clay_tb_cell_bounding_box (line 625) | static inline clay_tb_cell_bounding_box cell_snap_pos_ind_bounding_box(C...
  function Clay_Color (line 641) | static inline Clay_Color clay_tb_color_buffer_clay_get(int x, int y)
  function clay_tb_color_buffer_clay_set (line 659) | static inline void clay_tb_color_buffer_clay_set(int x, int y, Clay_Colo...
  function clay_tb_resize_buffer (line 673) | static void clay_tb_resize_buffer(void)
  function clay_tb_color_pair (line 708) | static inline clay_tb_color_pair clay_tb_get_transparency_color(
  function clay_tb_set_cell (line 743) | static int clay_tb_set_cell(
  function clay_tb_image_convert (line 789) | bool clay_tb_image_convert(clay_tb_image *image, int width, int height)
  function Clay_Termbox_Set_Cell_Pixel_Size (line 1102) | void Clay_Termbox_Set_Cell_Pixel_Size(float width, float height)
  function Clay_Termbox_Set_Color_Mode (line 1109) | void Clay_Termbox_Set_Color_Mode(int color_mode)
  function Clay_Termbox_Set_Border_Mode (line 1130) | void Clay_Termbox_Set_Border_Mode(enum border_mode border_mode)
  function Clay_Termbox_Set_Border_Chars (line 1142) | void Clay_Termbox_Set_Border_Chars(enum border_chars border_chars)
  function Clay_Termbox_Set_Image_Mode (line 1154) | void Clay_Termbox_Set_Image_Mode(enum image_mode image_mode)
  function Clay_Termbox_Set_Image_Fuel (line 1166) | void Clay_Termbox_Set_Image_Fuel(int fuel_max, int fuel_per_image)
  function Clay_Termbox_Set_Transparency (line 1174) | void Clay_Termbox_Set_Transparency(bool transparency)
  function Clay_Termbox_Width (line 1182) | float Clay_Termbox_Width(void)
  function Clay_Termbox_Height (line 1189) | float Clay_Termbox_Height(void)
  function Clay_Termbox_Cell_Width (line 1196) | float Clay_Termbox_Cell_Width(void)
  function Clay_Termbox_Cell_Height (line 1201) | float Clay_Termbox_Cell_Height(void)
  function Clay_Dimensions (line 1206) | static inline Clay_Dimensions Clay_Termbox_MeasureText(
  function clay_tb_image (line 1237) | clay_tb_image Clay_Termbox_Image_Load_File(const char *filename)
  function clay_tb_image (line 1261) | clay_tb_image Clay_Termbox_Image_Load_Memory(const void *image, int size)
  function Clay_Termbox_Image_Free (line 1276) | void Clay_Termbox_Image_Free(clay_tb_image *image)
  function Clay_Termbox_Initialize (line 1286) | void Clay_Termbox_Initialize(int color_mode, enum border_mode border_mode,
  function Clay_Termbox_Close (line 1416) | void Clay_Termbox_Close(void)
  function Clay_Termbox_Render (line 1428) | void Clay_Termbox_Render(Clay_RenderCommandArray commands)
  function Clay_Termbox_Waitfor_Event (line 1779) | void Clay_Termbox_Waitfor_Event(void)

FILE: renderers/termbox2/image_character_masks.h
  type clay_tb_character_mask (line 5) | typedef struct {

FILE: renderers/terminal/clay_renderer_terminal_ansi.c
  function Console_MoveCursor (line 10) | static inline void Console_MoveCursor(int x, int y) {
  function Clay_PointIsInsideRect (line 14) | bool Clay_PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
  function Console_DrawRectangle (line 20) | static inline void Console_DrawRectangle(int x0, int y0, int width, int ...
  function Clay_Dimensions (line 45) | static inline Clay_Dimensions
  function Clay_Terminal_Render (line 75) | void Clay_Terminal_Render(Clay_RenderCommandArray renderCommands, int wi...

FILE: renderers/win32_gdi/clay_renderer_gdi.c
  function DWORD (line 27) | inline DWORD Clay_Win32_GetRendererFlags() { return g_dwGdiRenderFlags; }
  function Clay_Win32_SetRendererFlags (line 30) | inline void Clay_Win32_SetRendererFlags(DWORD dwFlags) { g_dwGdiRenderFl...
  function Clay_Win32_ModifyRendererFlags (line 33) | inline bool Clay_Win32_ModifyRendererFlags(DWORD dwRemove, DWORD dwAdd)
  function intrin_sqrtf (line 51) | inline float intrin_sqrtf(const float f)
  function fast_inv_sqrtf (line 61) | float fast_inv_sqrtf(float number)
  function fast_sqrtf (line 80) | float fast_sqrtf(float number)
  function Clay_Color (line 99) | static inline Clay_Color ColorBlend(Clay_Color base, Clay_Color overlay,...
  function RoundedRectPixelCoverage (line 125) | static float RoundedRectPixelCoverage(int x, int y, const Clay_CornerRad...
  type HDCSubstitute (line 177) | typedef struct {
  function CreateHDCSubstitute (line 185) | static void CreateHDCSubstitute(HDCSubstitute* phdcs, HDC hdcSrc, PRECT ...
  function DestroyHDCSubstitute (line 223) | static void DestroyHDCSubstitute(HDCSubstitute* phdcs)
  function __Clay_Win32_FillRoundRect (line 236) | static void __Clay_Win32_FillRoundRect(HDC hdc, PRECT prc, Clay_Color co...
  function Clay_Win32_Render (line 287) | void Clay_Win32_Render(HWND hwnd, Clay_RenderCommandArray renderCommands...
  function Clay_Dimensions (line 523) | static inline Clay_Dimensions Clay_Win32_MeasureText(Clay_StringSlice te...
  function HFONT (line 582) | HFONT Clay_Win32_SimpleCreateFont(const char* filePath, const char* fami...
Condensed preview — 99 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,398K chars).
[
  {
    "path": ".dockerignore",
    "chars": 77,
    "preview": "cmake-build-debug/\ncmake-build-release/\n.DS_Store\n.idea/\nbuild/\nnode_modules/"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 20,
    "preview": "github: [nicbarker]\n"
  },
  {
    "path": ".github/workflows/cmake-multi-platform.yml",
    "chars": 3892,
    "preview": "name: CMake on multiple platforms\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n\njobs:\n"
  },
  {
    "path": ".github/workflows/odin-bindings-update.yml",
    "chars": 3349,
    "preview": "name: Odin Bindings Update\non:\n  push:\n    branches: [main]\njobs:\n  check_changes:\n    runs-on: ubuntu-latest\n    output"
  },
  {
    "path": ".gitignore",
    "chars": 82,
    "preview": "cmake-build-debug/\ncmake-build-release/\n.DS_Store\n.idea/\nnode_modules/\n*.dSYM\n.vs/"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 2389,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay)\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\")\n\n"
  },
  {
    "path": "LICENSE.md",
    "chars": 891,
    "preview": "zlib/libpng license\n\nCopyright (c) 2024 Nic Barker\n\nThis software is provided 'as-is', without any express or implied wa"
  },
  {
    "path": "README.md",
    "chars": 95793,
    "preview": "# Clay, A UI Layout Library\n**_Clay_** (short for **C Layout**) is a high performance 2D UI layout library.\n\n### Major F"
  },
  {
    "path": "bindings/cpp/README.md",
    "chars": 42,
    "preview": "https://github.com/TimothyHoytBSME/ClayMan"
  },
  {
    "path": "bindings/csharp/README",
    "chars": 35,
    "preview": "https://github.com/Orcolom/clay-cs\n"
  },
  {
    "path": "bindings/rust/README",
    "chars": 71,
    "preview": "https://github.com/clay-ui-rs/clay\nhttps://crates.io/crates/clay-layout"
  },
  {
    "path": "bindings/zig/README",
    "chars": 83,
    "preview": "https://codeberg.org/Zettexe/clay-zig\nhttps://github.com/johan0A/clay-zig-bindings\n"
  },
  {
    "path": "clay.h",
    "chars": 269906,
    "preview": "// VERSION: 0.14\n\n/*\n    NOTE: In order to use this library you must define\n    the following macro in exactly one file,"
  },
  {
    "path": "cmake/FindCairo.cmake",
    "chars": 875,
    "preview": "# Defines:\n#  CAIRO_FOUND        - System has Cairo\n#  CAIRO_INCLUDE_DIRS - Cairo include directories\n#  CAIRO_LIBRARY  "
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/.gitignore",
    "chars": 34,
    "preview": "/build/\n/website-demo-macos-glfw*\n"
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/CMakeLists.txt",
    "chars": 2744,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(GLES3_GLFW_video_demo C)\n\nset(CMAKE_C_STANDARD 99)\nset(CMAKE_C_STANDARD_REQ"
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/Makefile.emscripten",
    "chars": 774,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\n#\n# PROGRAM COMPONENTS\n# \n\nCXX = emcc\n\nCXXFLAGS = -std=c99\nCXX"
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/Makefile.macos",
    "chars": 656,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\nCXX = clang\n\nCXXFLAGS = -std=c99\nCXXFLAGS += -g -O0 -fno-omit-"
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/README.md",
    "chars": 1861,
    "preview": "GLES3 Renderer Video Demo (Using GLFW)\n======================================\n\nThis directory contains a standard Video-"
  },
  {
    "path": "examples/GLES3-GLFW-video-demo/main.c",
    "chars": 6228,
    "preview": "#include <stdio.h>\n\n#include <GLFW/glfw3.h>\n\n#define STB_IMAGE_IMPLEMENTATION\n#define STB_TRUETYPE_IMPLEMENTATION\n#defin"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/.gitignore",
    "chars": 70,
    "preview": "/build/\n/website-demo-macos-sdl2*\n/macos-sidebar-scrolling-container*\n"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/CMakeLists.txt",
    "chars": 2530,
    "preview": "cmake_minimum_required(VERSION 3.27)\nset(CMAKE_C_STANDARD 99)\nproject(GLES3_SDL2_sidebar_scrolling_container C)\n\n# -----"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/Makefile.emscripten",
    "chars": 1041,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\n#\n# PROGRAM COMPONENTS\n# \n\nCXX = emcc\n\nCXXFLAGS = -std=c99\nCXX"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/Makefile.macos",
    "chars": 676,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\nCXX = clang\n\nCXXFLAGS = -std=c99\nCXXFLAGS += -g -O0 -fno-omit-"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/README.md",
    "chars": 1436,
    "preview": "GLES3 Renderer Scrolling Container (Using SDL2)\n===============================================\n\nThis directory contains"
  },
  {
    "path": "examples/GLES3-SDL2-sidebar-scrolling-container/main.c",
    "chars": 38956,
    "preview": "#include <SDL.h>\n#include <stdio.h>\n\n#define STB_IMAGE_IMPLEMENTATION\n#define STB_TRUETYPE_IMPLEMENTATION\n#define CLAY_I"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/.gitignore",
    "chars": 34,
    "preview": "/build/\n/website-demo-macos-sdl2*\n"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/CMakeLists.txt",
    "chars": 2412,
    "preview": "cmake_minimum_required(VERSION 3.27)\nset(CMAKE_C_STANDARD 99)\nproject(GLES3_SDL2_video_demo C)\n\n\n# ---------------------"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/Makefile.emscripten",
    "chars": 773,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\n#\n# PROGRAM COMPONENTS\n# \n\nCXX = emcc\n\nCXXFLAGS = -std=c99\nCXX"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/Makefile.macos",
    "chars": 661,
    "preview": "# vim: set tabstop=4 shiftwidth=4 expandtab noexpandtab:\n\nCXX = clang\n\nCXXFLAGS = -std=c99\nCXXFLAGS += -g -O0 -fno-omit-"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/README.md",
    "chars": 1442,
    "preview": "GLES3 Renderer Video Demo (Using SDL2)\n======================================\n\nThis directory contains a standard Video-"
  },
  {
    "path": "examples/GLES3-SDL2-video-demo/main.c",
    "chars": 6056,
    "preview": "#include <SDL.h>\n\n#define STB_IMAGE_IMPLEMENTATION\n#define STB_TRUETYPE_IMPLEMENTATION\n#define CLAY_IMPLEMENTATION\n#defi"
  },
  {
    "path": "examples/SDL2-video-demo/CMakeLists.txt",
    "chars": 1443,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(SDL2_video_demo C)\nset(CMAKE_C_STANDARD 99)\n\ninclude(FetchContent)\nset(FETC"
  },
  {
    "path": "examples/SDL2-video-demo/main.c",
    "chars": 5843,
    "preview": "#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n#include \"../../renderers/SDL2/clay_renderer_SDL2.c\"\n\n#include <SDL."
  },
  {
    "path": "examples/SDL3-simple-demo/CMakeLists.txt",
    "chars": 1622,
    "preview": "cmake_minimum_required(VERSION 3.27)\n\n# Project setup\nproject(clay_examples_sdl3_simple_demo C)\nset(CMAKE_C_STANDARD 99)"
  },
  {
    "path": "examples/SDL3-simple-demo/main.c",
    "chars": 7055,
    "preview": "#define SDL_MAIN_USE_CALLBACKS\n#include <SDL3/SDL_main.h>\n#include <SDL3/SDL.h>\n#include <SDL3_ttf/SDL_ttf.h>\n\n#define C"
  },
  {
    "path": "examples/cairo-pdf-rendering/CMakeLists.txt",
    "chars": 835,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_cairo_pdf_rendering C)\nset(CMAKE_C_STANDARD 99)\n\nlist(APPEND "
  },
  {
    "path": "examples/cairo-pdf-rendering/main.c",
    "chars": 8192,
    "preview": "// Copyright (c) 2024 Justin Andreas Lacoste (@27justin)\n//\n// This software is provided 'as-is', without any express or"
  },
  {
    "path": "examples/clay-official-website/CMakeLists.txt",
    "chars": 255,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_official_website C)\n\nset(CMAKE_C_STANDARD 99)\n\nadd_executable(clay_off"
  },
  {
    "path": "examples/clay-official-website/build/clay/index.html",
    "chars": 47076,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset"
  },
  {
    "path": "examples/clay-official-website/build.sh",
    "chars": 1398,
    "preview": "mkdir -p build/clay                                                       \\\n&& clang                                    "
  },
  {
    "path": "examples/clay-official-website/index.html",
    "chars": 47076,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset"
  },
  {
    "path": "examples/clay-official-website/main.c",
    "chars": 39057,
    "preview": "#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n\ndouble windowWidth = 1024, windowHeight = 768;\nfloat modelPageOneZR"
  },
  {
    "path": "examples/cpp-project-example/CMakeLists.txt",
    "chars": 489,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_cpp_project_example CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nif(NOT M"
  },
  {
    "path": "examples/cpp-project-example/main.cpp",
    "chars": 755,
    "preview": "#include <iostream>\n#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n\nClay_LayoutConfig layoutElement = Clay_LayoutCo"
  },
  {
    "path": "examples/introducing-clay-video-demo/CMakeLists.txt",
    "chars": 1249,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_introducing_clay_video_demo C)\nset(CMAKE_C_STANDARD 99)\n\n# Ad"
  },
  {
    "path": "examples/introducing-clay-video-demo/main.c",
    "chars": 2167,
    "preview": "#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n#include \"../../renderers/raylib/clay_renderer_raylib.c\"\n#include \"."
  },
  {
    "path": "examples/playdate-project-example/.gitignore",
    "chars": 60,
    "preview": "clay_playdate_example.pdx\nSource/pdex.dylib\nSource/pdex.elf\n"
  },
  {
    "path": "examples/playdate-project-example/CmakeLists.txt",
    "chars": 1131,
    "preview": "cmake_minimum_required(VERSION 3.27)\nset(CMAKE_C_STANDARD 99)\n\nset(ENVSDK $ENV{PLAYDATE_SDK_PATH})\n\nif (NOT ${ENVSDK} ST"
  },
  {
    "path": "examples/playdate-project-example/README.md",
    "chars": 1749,
    "preview": "# Playdate console example\n\nThis example uses a modified version of the document viewer application from the Clay video "
  },
  {
    "path": "examples/playdate-project-example/Source/pdxinfo",
    "chars": 153,
    "preview": "name=Clay Playdate Example\nauthor=Matthew Jennings\ndescription=A small demo of Clay running on the Playdate\nbundleID=dev"
  },
  {
    "path": "examples/playdate-project-example/clay-video-demo-playdate.c",
    "chars": 17036,
    "preview": "// This is the video demo with some adjustments so it works on the playdate\n// console The playdate screen is only 400x2"
  },
  {
    "path": "examples/playdate-project-example/main.c",
    "chars": 3553,
    "preview": "#include \"pd_api.h\"\n#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n\n#include \"../../renderers/playdate/clay_rendere"
  },
  {
    "path": "examples/raylib-multi-context/CMakeLists.txt",
    "chars": 1136,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_raylib_multi_context C)\nset(CMAKE_C_STANDARD 99)\n\n# Adding Ra"
  },
  {
    "path": "examples/raylib-multi-context/main.c",
    "chars": 10371,
    "preview": "#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n#include \"../../renderers/raylib/clay_renderer_raylib.c\"\n#include \"."
  },
  {
    "path": "examples/raylib-sidebar-scrolling-container/CMakeLists.txt",
    "chars": 1324,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_raylib_sidebar_scrolling_container C)\nset(CMAKE_C_STANDARD 99"
  },
  {
    "path": "examples/raylib-sidebar-scrolling-container/main.c",
    "chars": 30594,
    "preview": "#define CLAY_IMPLEMENTATION\n#include \"../../clay.h\"\n#include \"../../renderers/raylib/clay_renderer_raylib.c\"\n\nconst uint"
  },
  {
    "path": "examples/raylib-sidebar-scrolling-container/multi-compilation-unit.c",
    "chars": 301,
    "preview": "#include \"../../clay.h\"\n\n// NOTE: This file only exists to make sure that clay works when included in multiple translati"
  },
  {
    "path": "examples/shared-layouts/clay-video-demo.c",
    "chars": 17018,
    "preview": "#include \"../../clay.h\"\n#include <stdlib.h>\n\nconst int FONT_ID_BODY_16 = 0;\nClay_Color COLOR_WHITE = { 255, 255, 255, 25"
  },
  {
    "path": "examples/sokol-corner-radius/CMakeLists.txt",
    "chars": 382,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(sokol_corner_radius C)\n\nif(CMAKE_SYSTEM_NAME STREQUAL Windows)\n    add_exec"
  },
  {
    "path": "examples/sokol-corner-radius/main.c",
    "chars": 3226,
    "preview": "#include \"sokol_app.h\"\n#include \"sokol_gfx.h\"\n#include \"sokol_glue.h\"\n#include \"sokol_log.h\"\n\n#define CLAY_IMPLEMENTATIO"
  },
  {
    "path": "examples/sokol-video-demo/CMakeLists.txt",
    "chars": 2313,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(sokol_video_demo C)\n\ninclude(FetchContent)\nset(FETCHCONTENT_QUIET FALSE)\n\n#"
  },
  {
    "path": "examples/sokol-video-demo/main.c",
    "chars": 2145,
    "preview": "#include \"sokol_app.h\"\n#include \"sokol_gfx.h\"\n#include \"sokol_glue.h\"\n#include \"sokol_log.h\"\n\n#define CLAY_IMPLEMENTATIO"
  },
  {
    "path": "examples/sokol-video-demo/sokol.c",
    "chars": 572,
    "preview": "#define SOKOL_IMPL\n#if defined(_WIN32)\n#define SOKOL_D3D11\n#elif defined(__EMSCRIPTEN__)\n#define SOKOL_GLES2\n#elif defin"
  },
  {
    "path": "examples/termbox2-demo/CMakeLists.txt",
    "chars": 1144,
    "preview": "cmake_minimum_required(VERSION 3.25)\nproject(clay_examples_termbox2_demo C)\nset(CMAKE_C_STANDARD 11)\n\ninclude(FetchConte"
  },
  {
    "path": "examples/termbox2-demo/main.c",
    "chars": 29363,
    "preview": "/*\n    Unlicense\n\n    Copyright (c) 2025 Mivirl\n\n    This is free and unencumbered software released into the public dom"
  },
  {
    "path": "examples/termbox2-demo/readme.md",
    "chars": 1436,
    "preview": "# Termbox2 renderer demo\n\nTerminal-based renderer using [termbox2](https://github.com/termbox/termbox2)\n\nThis demo shows"
  },
  {
    "path": "examples/termbox2-image-demo/CMakeLists.txt",
    "chars": 1243,
    "preview": "cmake_minimum_required(VERSION 3.25)\nproject(clay_examples_termbox2_image_demo C)\nset(CMAKE_C_STANDARD 11)\nset(CMAKE_BUI"
  },
  {
    "path": "examples/termbox2-image-demo/main.c",
    "chars": 25289,
    "preview": "/*\n    Unlicense\n\n    Copyright (c) 2025 Mivirl\n\n    This is free and unencumbered software released into the public dom"
  },
  {
    "path": "examples/termbox2-image-demo/readme.md",
    "chars": 2689,
    "preview": "# Termbox2 renderer demo\n\nTerminal-based renderer using [termbox2](https://github.com/termbox/termbox2)\n\nThis demo shows"
  },
  {
    "path": "examples/terminal-example/CMakeLists.txt",
    "chars": 528,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(clay_examples_terminal C)\nset(CMAKE_C_STANDARD 99)\n\nadd_executable(clay_exa"
  },
  {
    "path": "examples/terminal-example/main.c",
    "chars": 1396,
    "preview": "// Must be defined in one file, _before_ #include \"clay.h\"\n#define CLAY_IMPLEMENTATION\n\n#include <unistd.h>\n#include \".."
  },
  {
    "path": "examples/win32_gdi/CMakeLists.txt",
    "chars": 414,
    "preview": "cmake_minimum_required(VERSION 3.27)\nproject(win32_gdi C)\n\nset(CMAKE_C_STANDARD 99)\n\nadd_executable(win32_gdi WIN32 main"
  },
  {
    "path": "examples/win32_gdi/build.ps1",
    "chars": 132,
    "preview": "\r\n# to build this, install mingw\r\n\r\ngcc main.c -ggdb -omain -lgdi32 -lmingw32 # -mwindows # comment -mwindows out for co"
  },
  {
    "path": "examples/win32_gdi/main.c",
    "chars": 6458,
    "preview": "\r\n#define WIN32_LEAN_AND_MEAN\r\n#include <windows.h>\r\n#include <windowsx.h>\r\n\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n\r"
  },
  {
    "path": "renderers/GLES3/clay_renderer_gles3.h",
    "chars": 28962,
    "preview": "#ifndef CLAY_RENDERER_GLES3_H\n#define CLAY_RENDERER_GLES3_H\n\n// There may be custom header customizations, very client s"
  },
  {
    "path": "renderers/GLES3/clay_renderer_gles3_loader_stb.c",
    "chars": 10361,
    "preview": "#pragma once\n\n#include <stdbool.h>\n#include <clay.h>\n\n#include <stb_image.h>\n#include <stb_truetype.h>\n\n#include \"clay_r"
  },
  {
    "path": "renderers/SDL2/README",
    "chars": 299,
    "preview": "Note: on Mac OSX, SDL2 for some reason decides to automatically disable momentum scrolling on macbook trackpads.\nYou can"
  },
  {
    "path": "renderers/SDL2/clay_renderer_SDL2.c",
    "chars": 20663,
    "preview": "#include \"../../clay.h\"\n#include <SDL.h>\n#include <SDL_ttf.h>\n#include <SDL_image.h>\n#include <stdio.h>\n#include <math.h"
  },
  {
    "path": "renderers/SDL3/clay_renderer_SDL3.c",
    "chars": 14495,
    "preview": "#include \"../../clay.h\"\n#include <SDL3/SDL_main.h>\n#include <SDL3/SDL.h>\n#include <SDL3_ttf/SDL_ttf.h>\n#include <SDL3_im"
  },
  {
    "path": "renderers/cairo/clay_renderer_cairo.c",
    "chars": 12810,
    "preview": "// Copyright (c) 2024 Justin Andreas Lacoste (@27justin)\n//\n// This software is provided 'as-is', without any express or"
  },
  {
    "path": "renderers/playdate/clay_renderer_playdate.c",
    "chars": 12045,
    "preview": "#include \"pd_api.h\"\n#include \"../../clay.h\"\n\n// Playdate drawText function expects the number of codepoints to draw, not"
  },
  {
    "path": "renderers/raylib/clay_renderer_raylib.c",
    "chars": 13431,
    "preview": "#include \"raylib.h\"\n#include \"raymath.h\"\n#include \"stdint.h\"\n#include \"string.h\"\n#include \"stdio.h\"\n#include \"stdlib.h\"\n"
  },
  {
    "path": "renderers/raylib/raylib.h",
    "chars": 130624,
    "preview": "/**********************************************************************************************\n*\n*   raylib v5.5 - A si"
  },
  {
    "path": "renderers/raylib/raymath.h",
    "chars": 82281,
    "preview": "/**********************************************************************************************\n*\n*   raymath v2.0 - Mat"
  },
  {
    "path": "renderers/sokol/sokol_clay.h",
    "chars": 28434,
    "preview": "#ifndef SOKOL_CLAY_INCLUDED\n#define SOKOL_CLAY_INCLUDED (1)\n/*\n    sokol_clay.h -- drop-in Clay renderer for sokol_gfx.h"
  },
  {
    "path": "renderers/termbox2/clay_renderer_termbox2.c",
    "chars": 73540,
    "preview": "/*\n    zlib/libpng license\n\n    Copyright (c) 2025 Mivirl\n\n    altered by Godje (Sep 2025)\n\n    This software is provide"
  },
  {
    "path": "renderers/termbox2/image_character_masks.h",
    "chars": 71059,
    "preview": "#ifndef CLAY_TB_IMAGE_H\n#define CLAY_TB_IMAGE_H\n#include <stdint.h>\n\ntypedef struct {\n    uint32_t character;\n    int da"
  },
  {
    "path": "renderers/terminal/clay_renderer_terminal_ansi.c",
    "chars": 7652,
    "preview": "#include \"stdint.h\"\n#include \"string.h\"\n#include \"stdio.h\"\n#include \"stdlib.h\"\n\n#ifdef CLAY_OVERFLOW_TRAP\n#include \"sign"
  },
  {
    "path": "renderers/web/build-wasm.sh",
    "chars": 300,
    "preview": "cp ../../clay.h clay.c && \t\t\\\nclang \t\t\t\t\t\t\t\\\n-Os \t\t\t\t\t\t\t\\\n-DCLAY_WASM \t\t\t\t\t\\\n-mbulk-memory \t\t\t\t\t\\\n--target=wasm32 \t\t\t\t\\\n"
  },
  {
    "path": "renderers/web/canvas2d/clay-canvas2d-renderer.html",
    "chars": 26548,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charse"
  },
  {
    "path": "renderers/web/html/clay-html-renderer.html",
    "chars": 25142,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charse"
  },
  {
    "path": "renderers/win32_gdi/README.md",
    "chars": 134,
    "preview": "The windows GDI renderer example is missing the following:\n\n- Images\n- Rendering Rounded Rectangle borders\n- Custom Font"
  },
  {
    "path": "renderers/win32_gdi/clay_renderer_gdi.c",
    "chars": 21491,
    "preview": "#include <Windows.h>\r\n\r\n#if !defined(CLAY_DISABLE_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64))"
  },
  {
    "path": "tests/docker-compose.yml",
    "chars": 126,
    "preview": "services:\n  gcc:\n    build:\n      context: ../\n      dockerfile: tests/gcc/9.4/Dockerfile\n    volumes:\n      - /tmp/clay"
  },
  {
    "path": "tests/gcc/9.4/Dockerfile",
    "chars": 785,
    "preview": "FROM --platform=linux/amd64 ubuntu:20.04\n\nRUN apt update -y\nRUN DEBIAN_FRONTEND=noninteractive apt install -y build-esse"
  },
  {
    "path": "tests/run-tests.sh",
    "chars": 67,
    "preview": "docker compose build && docker compose up && echo \"Tests complete.\""
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the nicbarker/clay GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 99 files (1.3 MB), approximately 351.6k tokens, and a symbol index with 610 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!