Compare commits

...

12 Commits

Author SHA1 Message Date
Shivam7-1
e32cf65728
Merge 63a74a92a8 into 9e7595b873 2025-01-11 09:06:08 -06:00
Nic Barker
9e7595b873 Fixed a bug where minMemorySize could cause a memory overwrite
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Waiting to run
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Failing after 12s
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Failing after 11s
2025-01-11 21:37:21 +13:00
Nic Barker
32d1a31dfe Fix uint64 usage for wasm 2025-01-11 21:35:45 +13:00
Nic Barker
b2b50724e2 Fix bug in html renderer debug tools 2025-01-11 20:45:20 +13:00
Nic Barker
12b3280dab update odin bindings
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Waiting to run
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Failing after 15s
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Failing after 11s
2025-01-11 14:22:52 +13:00
Nic Barker
d81c9e1de5 fix C++ compile issues 2025-01-11 14:21:47 +13:00
Nic Barker
7142a427bb Update odin bindings 2025-01-11 14:19:31 +13:00
Nic Barker
d7ee448ed5 Add EXTEND_CONFIG_BORDER 2025-01-11 14:15:24 +13:00
Nic Barker
7ecd5adbce Update debug view to have correct z indexing 2025-01-11 14:15:02 +13:00
Nic Barker
2fcb4cc76e Fix z index sorting of tree roots 2025-01-11 14:08:02 +13:00
Shivam7-1
63a74a92a8
Rename fuzzing_target.cc to fuzzing_target.c 2024-12-22 21:10:58 +05:30
Shivam7-1
8d3cadc52e
initial fuzzing support 2024-12-21 17:04:07 +05:30
9 changed files with 63 additions and 11 deletions

1
.gitignore vendored
View File

@ -1,6 +1,5 @@
cmake-build-debug/ cmake-build-debug/
cmake-build-release/ cmake-build-release/
build/
.DS_Store .DS_Store
.idea/ .idea/
node_modules/ node_modules/

Binary file not shown.

Binary file not shown.

Binary file not shown.

49
clay.h
View File

@ -406,6 +406,9 @@ CLAY__TYPEDEF(Clay_BorderElementConfig, struct {
Clay_Border bottom; Clay_Border bottom;
Clay_Border betweenChildren; Clay_Border betweenChildren;
Clay_CornerRadius cornerRadius; Clay_CornerRadius cornerRadius;
#ifdef CLAY_EXTEND_CONFIG_BORDER
CLAY_EXTEND_CONFIG_BORDER
#endif
}); });
CLAY__TYPEDEF(Clay_ElementConfigUnion, union { CLAY__TYPEDEF(Clay_ElementConfigUnion, union {
@ -1326,7 +1329,7 @@ CLAY__TYPEDEF(Clay__LayoutElementTreeRoot, struct {
Clay__LayoutElementTreeRoot CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT = CLAY__DEFAULT_STRUCT; Clay__LayoutElementTreeRoot CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT = CLAY__DEFAULT_STRUCT;
// __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__LayoutElementTreeRoot NAME=Clay__LayoutElementTreeRootArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT // __GENERATED__ template array_define,array_allocate,array_add,array_get,array_set TYPE=Clay__LayoutElementTreeRoot NAME=Clay__LayoutElementTreeRootArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT
#pragma region generated #pragma region generated
CLAY__TYPEDEF(Clay__LayoutElementTreeRootArray, struct CLAY__TYPEDEF(Clay__LayoutElementTreeRootArray, struct
{ {
@ -1347,6 +1350,12 @@ Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Add(Clay__LayoutEl
Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Get(Clay__LayoutElementTreeRootArray *array, int32_t index) { Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Get(Clay__LayoutElementTreeRootArray *array, int32_t index) {
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT; return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT;
} }
void Clay__LayoutElementTreeRootArray_Set(Clay__LayoutElementTreeRootArray *array, int32_t index, Clay__LayoutElementTreeRoot value) {
if (Clay__Array_RangeCheck(index, array->capacity)) {
array->internalArray[index] = value;
array->length = index < array->length ? array->length : index + 1;
}
}
#pragma endregion #pragma endregion
// __GENERATED__ template // __GENERATED__ template
@ -1381,7 +1390,7 @@ struct Clay_Context {
bool externalScrollHandlingEnabled; bool externalScrollHandlingEnabled;
uint32_t debugSelectedElementId; uint32_t debugSelectedElementId;
uint32_t generation; uint32_t generation;
uint64_t arenaResetOffset; uintptr_t arenaResetOffset;
Clay_Arena internalArena; Clay_Arena internalArena;
// Layout Elements / Render Commands // Layout Elements / Render Commands
Clay_LayoutElementArray layoutElements; Clay_LayoutElementArray layoutElements;
@ -2093,6 +2102,9 @@ void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Cl
float targetSize = 0; float targetSize = 0;
for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) { for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
if (!xAxis && Clay__ElementHasConfig(childElement, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {
continue;
}
float childSize = xAxis ? childElement->dimensions.width : childElement->dimensions.height; float childSize = xAxis ? childElement->dimensions.width : childElement->dimensions.height;
if ((childSize - largestSize) < 0.1 && (childSize - largestSize) > -0.1) { if ((childSize - largestSize) < 0.1 && (childSize - largestSize) > -0.1) {
Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
@ -2457,6 +2469,20 @@ void Clay__CalculateFinalLayout() {
// Calculate sizing along the Y axis // Calculate sizing along the Y axis
Clay__SizeContainersAlongAxis(false); Clay__SizeContainersAlongAxis(false);
// Sort tree roots by z-index
int32_t sortMax = context->layoutElementTreeRoots.length - 1;
while (sortMax > 0) { // todo dumb bubble sort
for (int32_t i = 0; i < sortMax; ++i) {
Clay__LayoutElementTreeRoot current = *Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, i);
Clay__LayoutElementTreeRoot next = *Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, i + 1);
if (next.zIndex < current.zIndex) {
Clay__LayoutElementTreeRootArray_Set(&context->layoutElementTreeRoots, i, next);
Clay__LayoutElementTreeRootArray_Set(&context->layoutElementTreeRoots, i + 1, current);
}
}
sortMax--;
}
// Calculate final positions and generate render commands // Calculate final positions and generate render commands
context->renderCommands.length = 0; context->renderCommands.length = 0;
dfsBuffer.length = 0; dfsBuffer.length = 0;
@ -2606,7 +2632,7 @@ void Clay__CalculateFinalLayout() {
for (int32_t elementConfigIndex = 0; elementConfigIndex < currentElement->elementConfigs.length; ++elementConfigIndex) { for (int32_t elementConfigIndex = 0; elementConfigIndex < currentElement->elementConfigs.length; ++elementConfigIndex) {
sortedConfigIndexes[elementConfigIndex] = elementConfigIndex; sortedConfigIndexes[elementConfigIndex] = elementConfigIndex;
} }
int32_t sortMax = currentElement->elementConfigs.length - 1; sortMax = currentElement->elementConfigs.length - 1;
while (sortMax > 0) { // todo dumb bubble sort while (sortMax > 0) { // todo dumb bubble sort
for (int32_t i = 0; i < sortMax; ++i) { for (int32_t i = 0; i < sortMax; ++i) {
int32_t current = sortedConfigIndexes[i]; int32_t current = sortedConfigIndexes[i];
@ -3199,16 +3225,19 @@ void Clay__RenderDebugView() {
Clay_TextElementConfig *infoTitleConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE }); Clay_TextElementConfig *infoTitleConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0, 0); Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0, 0);
float scrollYOffset = 0; float scrollYOffset = 0;
bool pointerInDebugView = context->pointerInfo.position.y < context->layoutDimensions.height - 300;
for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) { for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i); Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
if (scrollContainerData->elementId == scrollId.id) { if (scrollContainerData->elementId == scrollId.id) {
if (!context->externalScrollHandlingEnabled) { if (!context->externalScrollHandlingEnabled) {
scrollYOffset = scrollContainerData->scrollPosition.y; scrollYOffset = scrollContainerData->scrollPosition.y;
} else {
pointerInDebugView = context->pointerInfo.position.y + scrollContainerData->scrollPosition.y < context->layoutDimensions.height - 300;
} }
break; break;
} }
} }
int32_t highlightedRow = context->pointerInfo.position.y < context->layoutDimensions.height - 300 int32_t highlightedRow = pointerInDebugView
? (int32_t)((context->pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1 ? (int32_t)((context->pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1
: -1; : -1;
if (context->pointerInfo.position.x < context->layoutDimensions.width - (float)Clay__debugViewWidth) { if (context->pointerInfo.position.x < context->layoutDimensions.width - (float)Clay__debugViewWidth) {
@ -3216,13 +3245,13 @@ void Clay__RenderDebugView() {
} }
Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT; Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
CLAY(CLAY_ID("Clay__DebugView"), CLAY(CLAY_ID("Clay__DebugView"),
CLAY_FLOATING({ .parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id, .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }}), CLAY_FLOATING({ .zIndex = 65000, .parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id, .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }}),
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }}) CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
) { ) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig); CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig);
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), {0} } })) {} CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
// Close button // Close button
CLAY(CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){217,91,67,255}), 4), CLAY(CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){217,91,67,255}), 4),
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10)}, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10)}, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }),
@ -3237,7 +3266,7 @@ void Clay__RenderDebugView() {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = ((initialElementsLength + initialRootsLength) & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1 })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = ((initialElementsLength + initialRootsLength) & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1 })) {
Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0); Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0);
// Element list // Element list
CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) { CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .zIndex = 65001, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = {.x = CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = {.x = CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow); layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
} }
@ -3269,7 +3298,7 @@ void Clay__RenderDebugView() {
) { ) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig); CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig);
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), {0} } })) {} CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
if (selectedItem->elementId.stringId.length != 0) { if (selectedItem->elementId.stringId.length != 0) {
CLAY_TEXT(selectedItem->elementId.stringId, infoTitleConfig); CLAY_TEXT(selectedItem->elementId.stringId, infoTitleConfig);
if (selectedItem->elementId.offset != 0) { if (selectedItem->elementId.offset != 0) {
@ -3402,7 +3431,7 @@ void Clay__RenderDebugView() {
} }
// Image Preview // Image Preview
CLAY_TEXT(CLAY_STRING("Preview"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Preview"), infoTitleConfig);
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0, imageConfig->sourceDimensions.width), {0} }}), Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .imageElementConfig = imageConfig }, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {} CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0, imageConfig->sourceDimensions.width) }}), Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .imageElementConfig = imageConfig }, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {}
} }
break; break;
} }
@ -3586,7 +3615,7 @@ uint32_t Clay_MinMemorySize(void) {
.maxMeasureTextCacheWordCount = Clay__defaultMaxMeasureTextWordCacheCount, .maxMeasureTextCacheWordCount = Clay__defaultMaxMeasureTextWordCacheCount,
.internalArena = { .internalArena = {
.capacity = SIZE_MAX, .capacity = SIZE_MAX,
.memory = (char*)&fakeContext, .memory = NULL,
} }
}; };
Clay_Context* currentContext = Clay_GetCurrentContext(); Clay_Context* currentContext = Clay_GetCurrentContext();

24
fuzz/fuzzing_target.c Normal file
View File

@ -0,0 +1,24 @@
#include "clay.h"
#include <stdint.h>
#include <stddef.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < sizeof(Clay_String)) return 0;
Clay_String testString = { .length = size, .chars = (const char *)data };
Clay_Dimensions dimensions = MeasureText(&testString, NULL);
// Call other critical functions
Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(1024, (void*)data);
Clay_Initialize(arena, (Clay_Dimensions){1024, 768});
Clay_SetPointerState((Clay_Vector2){0, 0}, false);
Clay_BeginLayout();
Clay_EndLayout();
// Handle pointer state changes
Clay_SetPointerState((Clay_Vector2){1, 1}, true);
Clay_SetPointerState((Clay_Vector2){2, 2}, false);
return 0;
}