Skip to content

fix(reader): adapt sidebar thumbnails and night mode to dark theme - #375

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:master
Sep 9, 2026
Merged

fix(reader): adapt sidebar thumbnails and night mode to dark theme#375
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:master

Conversation

@add-uos

@add-uos add-uos commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Invert bookmark/thumbnail pixmaps via HSL lightness in dark theme, with min-clamp 37 (#252525) and >=192 boost to white for contrast; cache the inverted pixmap by source cacheKey. Darken unselected borders with windowText@0.2 alpha in dark theme only. Night mode now converts to non-premultiplied ARGB32 and clamps lightness both ends.

深色主题下书签/缩略图按 HSL 亮度反色并做两端收敛,反色结果按源图缓存;
未选中卡片外框淡化仅作用于深色主题;夜间模式统一转非预乘 ARGB32。

Log: 深色主题缩略图反色与夜间模式对比度优化
Influence: 深色主题下侧边栏缩略图变为黑底白字、卡片边框可见,浅色主题
显示保持不变;不改变缩略图数据与缓存结构。

Summary by Sourcery

Improve dark-theme sidebar readability and night-mode image contrast without changing stored thumbnail data.

New Features:

  • Improve bookmark and thumbnail rendering in dark themes by inverting image lightness while preserving color characteristics and transparency.
  • Make unselected sidebar card borders more visible in dark themes.

Bug Fixes:

  • Improve night-mode contrast by clamping inverted lightness extremes and consistently processing images as non-premultiplied ARGB32.

Enhancements:

  • Cache dark-theme bookmark pixmap transformations without modifying the original thumbnail data.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @add-uos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 3 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR improves dark-theme sidebar contrast by applying bounded HSL lightness inversion to thumbnails and night-mode images, standardizing image writes on non-premultiplied ARGB32, caching bookmark inversion results, and adjusting unselected card borders only in dark themes.

Sequence diagram for dark-theme thumbnail rendering

sequenceDiagram
    participant View as SidebarView
    participant Delegate as ThumbnailDelegate
    participant Theme as DGuiApplicationHelper
    participant Image as ThumbnailPixmap
    participant Painter as QPainter

    View->>Delegate: paint(painter, option, index)
    Delegate->>Theme: themeType()
    alt DarkType
        Delegate->>Image: toImage()
        Delegate->>Image: convertToFormat(Format_ARGB32)
        loop Each pixel
            Delegate->>Image: getHsl()
            Delegate->>Image: setHsl()
        end
        Delegate->>Painter: drawPixmap(inverted image)
        Delegate->>Painter: drawRoundedRect(windowText alpha 0.2)
    else Light theme
        Delegate->>Painter: drawPixmap(original image)
        Delegate->>Painter: drawRoundedRect(frameShadowBorder)
    end
Loading

Sequence diagram for cached bookmark inversion

sequenceDiagram
    participant View as SidebarView
    participant Delegate as BookMarkDelegate
    participant Cache as m_darkPixmapCache
    participant Painter as QPainter

    View->>Delegate: paint(painter, option, index)
    Delegate->>Cache: object(pixmap.cacheKey())
    alt Cached inverted pixmap
        Cache-->>Delegate: QPixmap
    else Cache miss
        Delegate->>Delegate: apply HSL lightness inversion
        Delegate->>Cache: insert(cacheKey, invertedPixmap)
    end
    Delegate->>Painter: drawPixmap(invertedPixmap)
Loading

Flow diagram for bounded HSL lightness inversion

flowchart TD
    A[Source pixel] --> B[Convert to HSL]
    B --> C[light = 255 - light]
    C --> D{light >= 192?}
    D -- Yes --> E[Set lightness to 255]
    D -- No --> F[Keep inverted lightness]
    E --> G[Clamp lightness to minimum 37 or 30]
    F --> G
    G --> H[Preserve hue saturation and alpha]
    H --> I[Write non-premultiplied ARGB32 pixel]
Loading

File-Level Changes

Change Details Files
Apply consistent HSL lightness inversion and contrast clamping for night mode and dark-theme thumbnails.
  • Convert source images to non-premultiplied ARGB32 before per-pixel edits.
  • Invert HSL lightness while preserving hue, saturation, and alpha.
  • Clamp inverted lightness to a dark minimum and promote high values to white.
reader/browser/BrowserPage.cpp
reader/sidebar/ThumbnailDelegate.cpp
Add dark-theme thumbnail inversion caching without modifying source thumbnail data.
  • Cache rendered inverted bookmark pixmaps by source pixmap cache key.
  • Limit cache cost to 8 MB using ARGB32 pixel-size accounting.
  • Preserve device pixel ratio and fall back to the original pixmap if conversion fails.
reader/sidebar/BookMarkDelegate.cpp
reader/sidebar/BookMarkDelegate.h
Improve visibility of unselected sidebar card borders in dark themes while preserving light-theme styling.
  • Use windowText with 20% alpha for unselected borders in dark mode.
  • Keep the existing frame-shadow border and other border behavior for light mode and selected items.
reader/sidebar/BookMarkDelegate.cpp
reader/sidebar/ThumbnailDelegate.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 91 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 91 分,大于 70 分通过阈值,代码质量符合要求。本次提交实现了深色主题下侧边栏缩略图反色与夜间模式对比度优化,逻辑清晰,无安全漏洞,仅存在少量代码质量和性能优化建议。

🔍 详细分析

1. 语法逻辑 ✅

评价: 良好 ✅ 通过

潜在问题:

  1. reader/sidebar/BookMarkDelegate.cpp:55 - 缓存键使用 pixmap.cacheKey()(源图 cacheKey),但实际反色处理对象为 scalePix(pixmap.scaled(pageSize) 后的新 pixmap)。当 devicePixelRatio 变化(如窗口移动到不同 DPI 显示器)导致同一源图缩放尺寸不同时,缓存命中会返回错误尺寸的反色 pixmap,造成绘制错误

建议: 建议将缓存键改为 scalePix.cacheKey(),或在缓存键中包含缩放尺寸信息(如 pixmap.cacheKey() ^ qHash(scalePix.size())),以确保不同缩放尺寸的反色结果不会互相覆盖


2. 代码质量 ✅

评价: 良好 ✅ 通过

潜在问题:

  1. reader/sidebar/BookMarkDelegate.cpp:64 - HSL 亮度反色算法(含 kMinLightAfterInvert/kMaxLightBoostThreshold 两端收敛逻辑)在 BookMarkDelegate.cpp:64-81、ThumbnailDelegate.cpp:83-97、BrowserPage.cpp:1299-1319 三处重复实现,约30行代码重复

建议: 建议将 HSL 亮度反色算法提取为独立工具函数(如 QImage invertImageLightness(const QImage &img, int minLight, int maxBoostThreshold)),在三个调用处复用,减少维护成本


3. 代码性能 ✅

评价: 良好 ✅ 通过

潜在问题:

  1. reader/sidebar/BookMarkDelegate.cpp:56 - 缓存命中时执行 invertedPixmap = *cached 完整 QPixmap 深拷贝,可直接使用缓存指针绘制以避免拷贝开销

建议: 建议直接使用缓存指针绘制:将 if-else 分支改为直接从 cached 指针调用 painter->drawPixmap(),避免不必要的 QPixmap 深拷贝。示例:if (QPixmap *cached = m_darkPixmapCache.object(pixmap.cacheKey())) { painter->drawPixmap(rect.x(), rect.y(), *cached); } else { ... }


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 代码安全合规,无安全漏洞。reinterpret_cast<QRgb *>(img.scanLine(y)) 的使用是 Qt 图像处理的标准模式,在确保格式为 ARGB32 后操作安全。缓存操作不涉及用户输入,无注入风险。


💡 改进建议代码示例

// 建议提取共享工具函数,减少代码重复
// utils/ImageUtils.h
#pragma once
#include <QImage>

namespace ImageUtils {
/// HSL 亮度反色,两端收敛
/// \param img 非预乘 ARGB32 图像(调用前确保格式)
/// \param minLight 反色后亮度下限(如 37 = #252525)
/// \param boostThreshold 提亮阈值(如 192 = 0xC0)
inline void invertLightness(QImage &img, int minLight, int boostThreshold)
{
    const int w = img.width();
    const int h = img.height();
    for (int y = 0; y < h; ++y) {
        QRgb *line = reinterpret_cast<QRgb *>(img.scanLine(y));
        for (int x = 0; x < w; ++x) {
            const QRgb px = line[x];
            const int alpha = qAlpha(px);
            QColor c = QColor::fromRgb(qRed(px), qGreen(px), qBlue(px));
            int hue, sat, light, dummy;
            c.getHsl(&hue, &sat, &light, &dummy);
            light = 255 - light;
            if (light >= boostThreshold)
                light = 255;
            light = qMax(light, minLight);
            c.setHsl(hue, sat, light);
            line[x] = qRgba(c.red(), c.green(), c.blue(), alpha);
        }
    }
}
} // namespace ImageUtils

// BookMarkDelegate.cpp - 缓存命中时直接使用指针绘制,避免拷贝
if (QPixmap *cached = m_darkPixmapCache.object(pixmap.cacheKey())) {
    painter->drawPixmap(rect.x(), rect.y(), *cached);
} else {
    QImage img = scalePix.toImage();
    if (!img.isNull()) {
        if (img.format() != QImage::Format_ARGB32)
            img = img.convertToFormat(QImage::Format_ARGB32);
        ImageUtils::invertLightness(img, 37, 192);
        QPixmap invertedPixmap = QPixmap::fromImage(img);
        invertedPixmap.setDevicePixelRatio(scalePix.devicePixelRatio());
        m_darkPixmapCache.insert(pixmap.cacheKey(),
            new QPixmap(invertedPixmap),
            img.width() * img.height() * 4);
        painter->drawPixmap(rect.x(), rect.y(), invertedPixmap);
    } else {
        painter->drawPixmap(rect.x(), rect.y(), scalePix);
    }
}

本报告由 AI 代码审查工具自动生成

Invert bookmark/thumbnail pixmaps via HSL lightness in dark theme, with
min-clamp 37 (#252525) and >=192 boost to white for contrast; cache the
inverted pixmap by source cacheKey. Darken unselected borders with
windowText@0.2 alpha in dark theme only. Night mode now converts to
non-premultiplied ARGB32 and clamps lightness both ends.

深色主题下书签/缩略图按 HSL 亮度反色并做两端收敛,反色结果按源图缓存;
未选中卡片外框淡化仅作用于深色主题;夜间模式统一转非预乘 ARGB32。

Log: 深色主题缩略图反色与夜间模式对比度优化
Influence: 深色主题下侧边栏缩略图变为黑底白字、卡片边框可见,浅色主题
显示保持不变;不改变缩略图数据与缓存结构。
@add-uos

add-uos commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: unstable)

@deepin-bot
deepin-bot Bot merged commit f204a41 into linuxdeepin:master Sep 9, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants