Expand description
塗りつぶし矩形のクリップ計算(純粋ロジック)。
ハードウェアにもグローバル状態にも依存しないため、ホスト側の
ユニットテスト(tests/src/test_draw_clip.rs)から直接検証できる。
§座標の約束
- 入力
(x0, y0, x1, y1): 呼び出し側の塗り矩形。x1/y1はcrate::kernel::draw::Screen::boxfillの従来仕様どおり両端を含む。 clip:(kx0, ky0, kx1, ky1)で、kx1/ky1は右下を含まない (draw_pixelがx >= cx1で捨てているのと同じ約束)。- 戻り値: 両端を含む
(x0, y0, x1, y1)。1 ピクセルも描かないならNone。
§【2026-09-08 カーネルパニックの原因】
以前は boxfill 内に直接、
if cx1 >= kx1 { cx1 = kx1 - 1; }と書かれていた。kx1 == 0(幅ゼロのクリップ矩形)のとき 0 - 1 が
u32 で 4294967295 へラップし、続く cx0 > cx1 の空判定も素通りする。
結果 rect_w が約 43 億となり、dma_fill_rect が RAM 全域を塗り色で
埋めてヒープのフリーリストを破壊していた。
実際のパニックログでは Tlsf::allocate が 0xffc7c8daffc7c8da を
ポインタとして辿って落ちており、この 0xffc7c8da は
ARGB(255,199,200,218) という塗り色そのものだった。
別のフレームでは boxfill がフレームバッファを走り抜けて
ペリフェラル領域 0x3f007008 へ書き込み、外部アボートで落ちている。
kx1 == 0 は絵空事ではなく、render.rs の
push_clip(x0, y0, x1.saturating_sub(18), y1)(<select> の
ドロップダウン矢印ぶんを削る処理)が、幅 18px 未満の要素で
そのまま 0 を渡す。push_clip の交差計算 cx1.min(x1) からも 0 は出る。
Functions§
- clip_
fill_ rect - 塗り矩形を描画先サイズとクリップ矩形で切り詰める。