调色性能优化 + 新增色域方块拾色 + 取值胶囊高对比配色 + 数据点标记修复

1. 修复自定义颜色滑动卡顿(VERY_BIG_DATA 全信号可见时 36ms/步 → 约 12ms/步)
   - 根因:场景缓存的内容指纹把逐信号的颜色/不透明度/线宽/模式都算了进去,
     改一次颜色就整幅失效,于是所有网格的波形都要重新光栅化。
   - 新增"不含外观样式"的几何指纹与样式快照:只有在网格结构、视图几何、信号集合与
     文字都不变、仅外观样式变化时,走"局部重画"快路径 —— 只重画颜色变了的那个网格,
     再把结果写回场景缓存(下一帧回到纯贴图)。
   - 补丁矩形向内对齐到整数像素,避免把属于相邻网格的一行擦掉而留下 1px 接缝;
     底色填充按补丁矩形本身进行(大面积不透明填充会走 GDI 快路径,不受 GDI+ 裁剪约束)。
   - 该优化对调色板点击、线宽/不透明度滑块、绘制模式切换同样生效。

2. 自定义颜色新增"方块色域图"拾色
   - 新增饱和度-明度方块(横轴饱和度、纵轴明度)与纵向色相条,可直接在色域图上取色。
   - 与面板内其它控件完全联动:RGB 滑块、十六进制输入、预览色块同源(RGB 为唯一数据源),
     并记忆色相,消色差时仍可用色相条换回颜色。
   - 色域方块按当前色相预渲染缓存,色相不变时不重复绘制;色域内用十字光标、色相条用纵向光标。

3. 取值胶囊的对比度描边与文本色改为对信号配色线性响应
   - 原实现只有一个亮度阈值,文字/描边只有黑、白两套固定取值。现按底色亮度选定亮/暗一侧,
     再与底色的互补色按固定比例线性混合(互补色亮度恰为 1−底色亮度),
     因此文字与描边的亮度随信号配色线性变化,且任意底色下都保持高对比。

4. 修复光标数据点越界三角的判定与绘制
   - 是否改用三角,以"数据点本身是否超出绘制边界"为准,不再因为数值标注被贴边而改变形状。
   - 三角方向修正为尖端朝外(此前上越界画下三角、左越界画右三角,方向完全相反),
     内三角改按质心收缩,描边不再是歪的;上下越界时三角与显示的数值纵向居中对齐。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-10-10 14:02:37 +08:00
1 parent d3c83237f1
commit 40b12d6e8b
7 files changed
+877 -124

No files matched your search

+65 -4
View File
@@ -835,12 +835,13 @@ namespace jdi
bool IsOnCursorSpanLabel(int x, int y) const;
/**
* @brief 画文字时给底色胶囊加一层与文字反色的细描边,提升与背景/曲线的对比度。
* @brief 画文字时给底色胶囊加一层细描边,提升与背景/曲线的对比度。
* @param [IN] rect 胶囊矩形。
* @param [IN] radius 圆角半径。
* @param [IN] textDark 文字是否用深色。
* @param [IN] outlineColor 描边色(由 `LabelInkFor` 与文字色一并算出的反相色)。
*/
void DrawLabelOutline(gd::Graphics& g, const gd::RectF& rect, float radius, bool textDark);
void DrawLabelOutline(gd::Graphics& g, const gd::RectF& rect, float radius,
std::uint32_t outlineColor);
/**
* @brief 精确检测鼠标位置是否命中某条可见信号曲线。
@@ -1404,9 +1405,65 @@ namespace jdi
* 视图几何以外的任何内容变化(改颜色/线宽/透明度/样式、重命名、增删信号)
* 都会改变该指纹,从而让静态场景缓存自动失效,无需在各处手工调用失效接口。
*
* @param [IN] includeStyles 是否把逐信号外观样式(颜色/不透明度/线宽/模式)计入指纹。
* @return 指纹值。
*/
std::uint64_t SceneContentHash() const;
std::uint64_t SceneContentHash(bool includeStyles = true) const;
/**
* @brief 场景内容中**不含逐信号外观样式**的指纹。
*
* 只包含网格结构、视图几何、网格幅值、信号集合与可见性、图例文案、选中项等
* "变化后必须整幅重建"的内容;逐信号的 `color / opacity / lineWidth / mode`
* 一律不参与。
*
* 用途:外观样式变化时(典型场景是拖动自定义颜色的滑块)波形几何完全不变,
* 只要该指纹一致,就可以只重画"颜色变了的那个网格"再写回缓存,
* 而不必整幅重绘全部网格(VERY_BIG_DATA 实测整幅 30ms+、单网格约 4ms)。
*
* @return 指纹值。
*/
std::uint64_t SceneGeometryHash() const;
/**
* @brief 静态场景缓存中"网格内信号外观样式"的快照条目。
*/
struct SceneStyleEntry
{
std::uint32_t color = 0; /**< 信号色(未叠加不透明度)。 */
float opacity = 1.0f; /**< 不透明度。 */
float lineWidth = 1.0f; /**< 线宽。 */
int mode = 0; /**< 绘制模式。 */
};
/**
* @brief 采集当前各网格内可见信号的外观样式快照。
* @param [OUT] out 采集结果(按网格分组)。
*/
void CollectSceneStyles(std::vector<std::vector<SceneStyleEntry>>& out) const;
/**
* @brief 判断当前相对缓存是否"只有外观样式发生了变化"。
*
* 成立条件:`SceneGeometryHash()` 与缓存一致(网格结构、视图几何、信号集合
* 与文字都没变),且至少有一个网格内信号的外观样式不同。
*
* @param [OUT] lanes 外观发生变化的网格下标(升序)。
* @return 可以走"局部重画"快路径返回 true。
*/
bool FindStyleOnlyLanes(std::vector<int>& lanes) const;
/**
* @brief 只重画指定网格并把结果写回静态场景缓存。
*
* 必须在 `BlitSceneCache()` 之后调用:贴图已经完成,这里把受影响网格的
* "底色 + 网格线 + 波形 + 标尺 + 图例"重画到画布上,再整块拷回缓存位图,
* 使缓存内容与当前样式一致(下一帧即可重新走"完全命中"快路径)。
*
* @param [IN,OUT] g 绘图上下文。
* @param [IN] lanes 需要重画的网格下标。
*/
void RepaintSceneCachePatch(gd::Graphics& g, const std::vector<int>& lanes);
/**
* @brief 当前应当绘入静态场景缓存的信号光晕(仅拖拽中的信号)。
@@ -1485,6 +1542,10 @@ namespace jdi
int m_sceneY = 0; /**< 缓存对应的客户区纵坐标(绘图区上边界)。 */
bool m_sceneValid = false; /**< 缓存内容是否有效。 */
SceneCacheKey m_sceneKey; /**< 缓存对应的场景参数。 */
/** 缓存捕获时"不含逐信号外观样式"的内容指纹(用于识别仅样式变化)。 */
std::uint64_t m_sceneGeometryHash = 0;
/** 缓存捕获时各网格内信号的外观样式快照(按网格分组,与 m_sceneStyles 同序)。 */
std::vector<std::vector<SceneStyleEntry>> m_sceneStyles;
/**
* @brief 查询坐标命中的图例条目。