Skip to content

A potential bug when propagating effect of text wrapping on height of percentage-based parents #520

@SolidAlloy

Description

@SolidAlloy

Hi Nic,
While reading the post-DFS “propagate height from children” step (the block that updates a parent’s height on its non-layout axis after wrapping / aspect), I noticed it unconditionally clamps with:

currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(value, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);

This reads the minMax member of the sizing union even when sizing.height.type == CLAY__SIZING_TYPE_PERCENT. I couldn’t find a guard earlier (e.g., when pushing nodes into dfsBuffer) that excludes percent-based parents. If I’m overlooking where that guarantee is made, please point me to it. Otherwise, it looks like percent-height parents could read the wrong union member and get clamped incorrectly.

clay/clay.h

Lines 2618 to 2637 in 3767508

// DFS node has been visited, this is on the way back up to the root
Clay_LayoutConfig *layoutConfig = currentElement->layoutConfig;
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
// Resize any parent containers that have grown in height along their non layout axis
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom, currentElement->dimensions.height);
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
}
} else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
// Resizing along the layout axis
float contentHeight = (float)(layoutConfig->padding.top + layoutConfig->padding.bottom);
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
contentHeight += childElement->dimensions.height;
}
contentHeight += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(contentHeight, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions