mirror of
https://github.com/nicbarker/clay.git
synced 2025-09-18 04:26:18 +00:00
fix: text measurement/rendering width mismatch in sokol_clay
The text bounding box width was incorrect because the measurement function was using logical pixels while the rendering function was using physical pixels (scaled by DPI). This caused a mismatch where: - sclay_measure_text() set font size and letter spacing without DPI scaling - sclay_render() applied DPI scaling to both font size and letter spacing - fontstash's fonsTextBounds() returned physical pixel measurements even when given logical pixel sizes, leading to incorrect width calculations The fix ensures consistent DPI scaling by: 1. Scaling font size and letter spacing by dpi_scale during measurement 2. Dividing the returned bounds by dpi_scale to convert back to logical pixels 3. This ensures Clay receives measurements in logical pixels that match what will actually be rendered This was particularly noticeable with long continuous text where the discrepancy accumulated across many characters. The issue was font-size dependent because different font sizes have different rounding behaviors in the underlying font rendering system. Also adds text alignment support to properly measure and render centered/right-aligned text.
This commit is contained in:
parent
91c6d05774
commit
2b46565a2e
3
clay.h
3
clay.h
|
@ -566,6 +566,8 @@ typedef struct Clay_TextRenderData {
|
|||
uint16_t letterSpacing;
|
||||
// The height of the bounding box for this line of text.
|
||||
uint16_t lineHeight;
|
||||
// Specifies the alignment of the text within its container.
|
||||
Clay_TextAlignment textAlignment;
|
||||
} Clay_TextRenderData;
|
||||
|
||||
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE
|
||||
|
@ -2898,6 +2900,7 @@ void Clay__CalculateFinalLayout(void) {
|
|||
.fontSize = textElementConfig->fontSize,
|
||||
.letterSpacing = textElementConfig->letterSpacing,
|
||||
.lineHeight = textElementConfig->lineHeight,
|
||||
.textAlignment = textElementConfig->textAlignment,
|
||||
}},
|
||||
.userData = textElementConfig->userData,
|
||||
.id = Clay__HashNumber(lineIndex, currentElement->id).id,
|
||||
|
|
|
@ -227,13 +227,26 @@ Clay_Dimensions sclay_measure_text(Clay_StringSlice text, Clay_TextElementConfig
|
|||
sclay_font_t *fonts = (sclay_font_t *)userData;
|
||||
if(!fonts) return (Clay_Dimensions){ 0 };
|
||||
fonsSetFont(_sclay.fonts, fonts[config->fontId]);
|
||||
fonsSetSize(_sclay.fonts, config->fontSize);
|
||||
fonsSetSpacing(_sclay.fonts, config->letterSpacing);
|
||||
fonsSetSize(_sclay.fonts, config->fontSize * _sclay.dpi_scale);
|
||||
fonsSetSpacing(_sclay.fonts, config->letterSpacing * _sclay.dpi_scale);
|
||||
switch (config->textAlignment) {
|
||||
case CLAY_TEXT_ALIGN_LEFT:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
break;
|
||||
case CLAY_TEXT_ALIGN_CENTER:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_CENTER | FONS_ALIGN_TOP);
|
||||
break;
|
||||
case CLAY_TEXT_ALIGN_RIGHT:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_RIGHT | FONS_ALIGN_TOP);
|
||||
break;
|
||||
default:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
}
|
||||
float ascent, descent, lineh;
|
||||
fonsVertMetrics(_sclay.fonts, &ascent, &descent, &lineh);
|
||||
return (Clay_Dimensions) {
|
||||
.width = fonsTextBounds(_sclay.fonts, 0, 0, text.chars, text.chars + text.length, NULL),
|
||||
.height = ascent - descent
|
||||
.width = fonsTextBounds(_sclay.fonts, 0, 0, text.chars, text.chars + text.length, NULL) / _sclay.dpi_scale,
|
||||
.height = (ascent - descent) / _sclay.dpi_scale
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -366,6 +379,19 @@ void sclay_render(Clay_RenderCommandArray renderCommands, sclay_font_t *fonts) {
|
|||
config->textColor.a);
|
||||
fonsSetColor(_sclay.fonts, color);
|
||||
fonsSetSpacing(_sclay.fonts, config->letterSpacing * _sclay.dpi_scale);
|
||||
switch (config->textAlignment) {
|
||||
case CLAY_TEXT_ALIGN_LEFT:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
break;
|
||||
case CLAY_TEXT_ALIGN_CENTER:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_CENTER | FONS_ALIGN_TOP);
|
||||
break;
|
||||
case CLAY_TEXT_ALIGN_RIGHT:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_RIGHT | FONS_ALIGN_TOP);
|
||||
break;
|
||||
default:
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
}
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
fonsSetSize(_sclay.fonts, config->fontSize * _sclay.dpi_scale);
|
||||
sgl_matrix_mode_modelview();
|
||||
|
|
Loading…
Reference in a new issue