2511-eiger-mask #2

Merged
leonarski_f merged 69 commits from 2511-eiger-mask into main 2025-11-09 12:42:28 +01:00
2 changed files with 152 additions and 0 deletions
Showing only changes of commit b694c03e85 - Show all commits

View File

@@ -0,0 +1,5 @@
//
// Created by jungfrau on 11/7/25.
//
#include "JFJochPixelOverlayClass.h"

View File

@@ -0,0 +1,147 @@
//
// Created by jungfrau on 11/7/25.
//
#ifndef JFJOCH_JFJOCHPIXELOVERLAYCLASS_H
#define JFJOCH_JFJOCHPIXELOVERLAYCLASS_H
#include <QGraphicsItem>
#include <QPainter>
#include <QStaticText>
#include <QHash>
#include <QFont>
static constexpr int32_t SATURATED_PXL_VALUE = 0x7FFFFFFF; // adjust to your constants
static constexpr int32_t GAP_PXL_VALUE = 0x7FFFFFFE;
static constexpr int32_t ERROR_PXL_VALUE = 0x7FFFFFFD;
inline qreal luminance(QRgb c) {
// sRGB luma approximation
return 0.2126 * qRed(c) + 0.7152 * qGreen(c) + 0.0722 * qBlue(c);
}
class PixelTextOverlayItem : public QGraphicsItem {
public:
PixelTextOverlayItem(const int32_t* values, const QRgb* rgb, int width, int height)
: m_values(values), m_rgb(rgb), m_w(width), m_h(height) {
setFlag(ItemUsesExtendedStyleOption, true);
// Choose a legible monospaced font; adjust as needed
m_font.setFamily("DejaVu Sans Mono");
m_font.setStyleHint(QFont::TypeWriter);
m_font.setPixelSize(10); // base size; tune with zoom externally if desired
}
// Item covers the whole image in item coordinates
QRectF boundingRect() const override {
return QRectF(0, 0, m_w, m_h);
}
// Call when viewport/zoom changes
void setView(int startX, int startY, int endX, int endY, double scaleFactor) {
m_sx = std::clamp(startX, 0, m_w);
m_sy = std::clamp(startY, 0, m_h);
m_ex = std::clamp(endX, 0, m_w);
m_ey = std::clamp(endY, 0, m_h);
m_scale = scaleFactor;
update();
}
// Optional: keep text a constant on-screen size by adjusting pixel size with zoom
void setFontPixelSize(int px) {
if (px <= 0) return;
if (m_font.pixelSize() != px) {
m_font.setPixelSize(px);
m_staticCache.clear(); // font size change invalidates cached layout
update();
}
}
// Optional: tweak font or color policy externally
void setFont(const QFont& f) {
m_font = f;
m_staticCache.clear();
update();
}
void setMinScaleToShow(double s) { m_minScale = s; }
protected:
void paint(QPainter* p, const QStyleOptionGraphicsItem*, QWidget*) override {
if (!m_values || !m_rgb) return;
// Gate: only draw when zoomed in enough and area small enough
const int w = m_ex - m_sx;
const int h = m_ey - m_sy;
if (m_scale < m_minScale || w <= 0 || h <= 0) return;
if (1LL * w * h > 500) return; // keep fast; same idea as your original guard
p->setRenderHint(QPainter::TextAntialiasing, false);
p->setFont(m_font);
for (int y = m_sy; y < m_ey; ++y) {
const int rowOff = y * m_w;
for (int x = m_sx; x < m_ex; ++x) {
const int idx = rowOff + x;
const int32_t v = m_values[idx];
const QString& label = toLabel(v);
const QStaticText& st = cachedStaticText(label);
// Contrast-aware text color
const qreal lum = luminance(m_rgb[idx]);
p->setPen(lum > 128.0 ? Qt::black : Qt::white);
// Offsets so text sits within/near the pixel; tune as you like
// If you want exact pixel center, use QPointF(x + 0.5, y + 0.5) and align text.
p->drawStaticText(QPointF(x - 0.7, y - 0.8), st);
}
}
}
private:
const QString& toLabel(int32_t v) {
if (v == SATURATED_PXL_VALUE) return m_cachedSat;
if (v == GAP_PXL_VALUE) return m_cachedGap;
if (v == ERROR_PXL_VALUE) return m_cachedErr;
// Cache numeric strings by value to avoid reformatting
auto it = m_valueToString.find(v);
if (it != m_valueToString.end()) return it.value();
return m_valueToString.insert(v, QString::number(v)).value();
}
const QStaticText& cachedStaticText(const QString& s) {
auto it = m_staticCache.find(s);
if (it != m_staticCache.end()) return it.value();
QStaticText st(s);
st.setTextFormat(Qt::PlainText);
st.setPerformanceHint(QStaticText::AggressiveCaching);
// No width wrapping; tiny labels
st.setTextWidth(-1);
return m_staticCache.insert(s, st).value();
}
const int32_t* m_values = nullptr; // image values (x + y*w)
const QRgb* m_rgb = nullptr; // RGB image for luminance
int m_w = 0, m_h = 0;
int m_sx = 0, m_sy = 0, m_ex = 0, m_ey = 0;
double m_scale = 1.0;
double m_minScale = 20.0; // match your logic
QFont m_font;
// Caches
QHash<int32_t, QString> m_valueToString;
QHash<QString, QStaticText> m_staticCache;
const QString m_cachedSat = QStringLiteral("Sat");
const QString m_cachedGap = QStringLiteral("Gap");
const QString m_cachedErr = QStringLiteral("Err");
};
#endif //JFJOCH_JFJOCHPIXELOVERLAYCLASS_H