#ifndef __UI_DEBUG_BOUNDS_HPP__ #define __UI_DEBUG_BOUNDS_HPP__ #include #include #include #include #include "Theme.hpp" #include "UiBox.hpp" namespace jdi { // ⚠️ 这个头文件只负责"把几何 box 画成彩色的布局边界线"(调试专用)。 // 几何本身(`UiBox` / `UiBoxTable`)在 `UiBox.hpp` 里,与绘制无关。 /** * @brief 布局边界描边颜色(按层级取色)。 * * 层级只用于**区分归属**,不代表重要性:层级越深说明越靠近叶子控件。 * * @param [IN] depth 层级(0 = 顶层组件区域,≥1 = 内部控件)。 * @return ARGB 颜色(不透明)。 */ std::uint32_t UiDebugBoundsColor(int depth); /** * @brief 绘制一个矩形的布局边界(**四角粗、四边细**,粗细随矩形尺寸自适应,受 `clip` 裁剪)。 * * 视觉规则: * * 四条边固定 1 设备像素; * * 四个角额外加粗成 `⌜ ⌝ ⌞ ⌟` —— 这是"一眼定位元素边界"的关键, * 即使多个矩形共边也能靠角的形状分辨层次; * * **包角粗细与长度都随矩形短边自适应**:元素越小越细(小方框不会被描成"粗边框"), * 短边 ≤ 12px 时只画四个角块、不画边,短边 ≤ 5px 时完全不画(否则就盖住元素本身了); * * **不做任何内缩**:框必须与"可见形状的外接矩形"完全重合。 * 曾经为"父子共边不叠粗"内缩 1px,结果把胶囊/圆角元素(GX 徽标、色块、✕) * 的圆弧留在框外 —— 那是错误的取舍。重叠时让"后画的那个"覆盖即可; * * **只描边、不填充、不写字** —— 填充会糊住内容。 * * ⚠️ 线宽按**设备像素**固定(不乘 `scale`)并临时 `PixelOffsetModeNone` + 关抗锯齿, * 否则 1px 线会被抗锯齿摊成 2px 灰边,无法判断真实边界。 * * @param [IN,OUT] g 绘图上下文。 * @param [IN] rect 目标矩形(客户区坐标)。 * @param [IN] clip 裁剪矩形(空 = 不裁剪)。 * @param [IN] depth 层级(决定配色与包角基础粗细)。 */ void UiDebugPaintBoundsClipped(gd::Graphics& g, const gd::RectF& rect, const gd::RectF& clip, int depth); /** * @brief 一次性画完整个 box 表(在宿主绘制的最后一步调用)。 * * 按 `(layer, depth)` 稳定排序后绘制:后收集的层压住先收集的层,同层内父先子后。 * `layer` 比某个遮挡矩形低的 box 会被该矩形挖洞裁掉(见 `UiBoxTable::AddOccluder`)。 * * @param [IN,OUT] g 绘图上下文。 * @param [IN] boxes 几何 box 表。 */ void UiDebugPaintBoxList(gd::Graphics& g, const UiBoxTable& boxes); } // namespace jdi #endif // __UI_DEBUG_BOUNDS_HPP__