@@ -303,17 +303,26 @@ static void render_text(struct Clayterm *ct, int x0, int y0,
303303static void render_border (struct Clayterm * ct , int x0 , int y0 , int x1 , int y1 ,
304304 Clay_RenderCommand * cmd ) {
305305 Clay_BorderRenderData * b = & cmd -> renderData .border ;
306- /* userData points at eight words in the command buffer carrying resolved
307- * per-side attributes as fg/bg pairs in top, right, bottom, left order.
308- * Fallback resolution (shared color/bg vs side overrides) happens on the
309- * TypeScript side; this renderer consumes explicit values only. The
310- * command buffer outlives the render pass within reduce(). */
306+ /* Must match border packing in ops.ts.
307+ * userData points at eight required words in the command buffer: resolved
308+ * fg/bg pairs in top, right, bottom, left order. Fallback resolution
309+ * (shared color/bg vs side overrides) happens on the TypeScript side; this
310+ * renderer consumes explicit values only. The command buffer outlives the
311+ * render pass within reduce(). Missing userData is a wire-format violation.
312+ */
311313 const uint32_t * s = (const uint32_t * )cmd -> userData ;
312- uint32_t deffg = color (b -> color );
313- uint32_t top_fg = s ? s [0 ] : deffg , top_bg = s ? s [1 ] : ATTR_DEFAULT ;
314- uint32_t right_fg = s ? s [2 ] : deffg , right_bg = s ? s [3 ] : ATTR_DEFAULT ;
315- uint32_t bot_fg = s ? s [4 ] : deffg , bot_bg = s ? s [5 ] : ATTR_DEFAULT ;
316- uint32_t left_fg = s ? s [6 ] : deffg , left_bg = s ? s [7 ] : ATTR_DEFAULT ;
314+ if (s == NULL ) {
315+ __builtin_trap ();
316+ }
317+
318+ uint32_t top_fg = s [0 ];
319+ uint32_t top_bg = s [1 ];
320+ uint32_t right_fg = s [2 ];
321+ uint32_t right_bg = s [3 ];
322+ uint32_t bot_fg = s [4 ];
323+ uint32_t bot_bg = s [5 ];
324+ uint32_t left_fg = s [6 ];
325+ uint32_t left_bg = s [7 ];
317326 int top = b -> width .top > 0 ;
318327 int bot = b -> width .bottom > 0 ;
319328 int left = b -> width .left > 0 ;
0 commit comments