Compare commits

...

5 Commits

Author SHA1 Message Date
Piggybank Studios
bb0b619402
Merge fbf8251996 into 08e4c5b198 2025-03-26 11:03:53 +00:00
Nic Barker
08e4c5b198 [Core] Fix a bug where ID aliases werent copied on hash collision
Some checks are pending
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) Waiting to run
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Waiting to run
2025-03-26 09:35:15 +13:00
ellie-but-backwards
b1c72a0647
[Bindings/Odin] Remove field hashStringContents in odin bindings (#350) 2025-03-26 09:21:35 +13:00
Igor Karatayev
aee4baee1c
[Core] Guard against hashmap item null dereference (#338) 2025-03-26 09:19:50 +13:00
Taylor Robbins (Piggybank Studios)
fbf8251996 Adds CLAY_TEXT_ALIGN_SHRINK option to Clay_TextAlignment which tells the TEXT command producing code it is allowed to pass a boundingBox that is horizontally smaller than the result of the MeasureText call for that string. The Renderer is then able to choose how it wants to fit a piece of text in a smaller space (often this involves removing some number of characters and replacing them with "..." characters) 2025-03-05 13:04:57 -08:00
2 changed files with 17 additions and 5 deletions

View File

@ -111,7 +111,6 @@ TextElementConfig :: struct {
lineHeight: u16,
wrapMode: TextWrapMode,
textAlignment: TextAlignment,
hashStringContents: bool,
}
ImageElementConfig :: struct {

21
clay.h
View File

@ -360,6 +360,8 @@ typedef CLAY_PACKED_ENUM {
CLAY_TEXT_ALIGN_CENTER,
// Horizontally aligns wrapped lines of text to the right hand side of their bounding box.
CLAY_TEXT_ALIGN_RIGHT,
// The boundingBox passed to the TEXT render command may be smaller than the measured text size. The renderer must then decide how to shorten the text to make it fit
CLAY_TEXT_ALIGN_SHRINK,
} Clay_TextAlignment;
// Controls various functionality related to text elements.
@ -1670,6 +1672,7 @@ Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Cl
item.nextIndex = hashItem->nextIndex;
if (hashItem->generation <= context->generation) { // First collision - assume this is the "same" element
hashItem->elementId = elementId; // Make sure to copy this across. If the stringId reference has changed, we should update the hash item to use the new one.
hashItem->idAlias = idAlias;
hashItem->generation = context->generation + 1;
hashItem->layoutElement = layoutElement;
hashItem->debugData->collision = false;
@ -2804,14 +2807,24 @@ void Clay__CalculateFinalLayout(void) {
continue;
}
float offset = (currentElementBoundingBox.width - wrappedLine->dimensions.width);
if (textElementConfig->textAlignment == CLAY_TEXT_ALIGN_LEFT) {
if (textElementConfig->textAlignment == CLAY_TEXT_ALIGN_LEFT || textElementConfig->textAlignment == CLAY_TEXT_ALIGN_SHRINK) {
offset = 0;
}
if (textElementConfig->textAlignment == CLAY_TEXT_ALIGN_CENTER) {
offset /= 2;
}
Clay_BoundingBox textBoundingBox = {
currentElementBoundingBox.x + offset,
currentElementBoundingBox.y + yPosition,
wrappedLine->dimensions.width,
wrappedLine->dimensions.height
};
if (textElementConfig->textAlignment == CLAY_TEXT_ALIGN_SHRINK && boundingBox.width > currentElementBoundingBox.width) {
boundingBox.width = currentElementBoundingBox.width;
}
Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
.boundingBox = { currentElementBoundingBox.x + offset, currentElementBoundingBox.y + yPosition, wrappedLine->dimensions.width, wrappedLine->dimensions.height },
.boundingBox = textBoundingBox,
.renderData = { .text = {
.stringContents = CLAY__INIT(Clay_StringSlice) { .length = wrappedLine->line.length, .chars = wrappedLine->line.chars, .baseChars = currentElement->childrenOrTextContent.textElementData->text.chars },
.textColor = textElementConfig->textColor,
@ -3810,10 +3823,10 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
Clay_LayoutElementHashMapItem *mapItem = Clay__GetHashMapItem(currentElement->id); // TODO think of a way around this, maybe the fact that it's essentially a binary tree limits the cost, but the worst case is not great
int32_t clipElementId = Clay__int32_tArray_GetValue(&context->layoutElementClipElementIds, (int32_t)(currentElement - context->layoutElements.internalArray));
Clay_LayoutElementHashMapItem *clipItem = Clay__GetHashMapItem(clipElementId);
Clay_BoundingBox elementBox = mapItem->boundingBox;
elementBox.x -= root->pointerOffset.x;
elementBox.y -= root->pointerOffset.y;
if (mapItem) {
Clay_BoundingBox elementBox = mapItem->boundingBox;
elementBox.x -= root->pointerOffset.x;
elementBox.y -= root->pointerOffset.y;
if ((Clay__PointIsInsideRect(position, elementBox)) && (clipElementId == 0 || (Clay__PointIsInsideRect(position, clipItem->boundingBox)))) {
if (mapItem->onHoverFunction) {
mapItem->onHoverFunction(mapItem->elementId, context->pointerInfo, mapItem->hoverFunctionUserData);