#include "helpers.h"
#include "logger.h"
#include "signaldrawer.h"
+#include <QApplication>
+#include <QDesktopWidget>
#include <QFontMetrics>
const int SignalDrawer::AXIS_LABEL_BORDER_OFFSET(2);
const int SignalDrawer::AXIS_LABEL_SCALE_OFFSET(3);
-const int SignalDrawer::MAXIMAL_AXIS_BIGTICK_STEP(150);
-const int SignalDrawer::MINIMAL_AXIS_BIGTICK_STEP(25);
+const int SignalDrawer::DEFAULT_BIGTICK_LENGTH(8);
+const double SignalDrawer::DEFAULT_DPI(96);
+const int SignalDrawer::DEFAULT_MAXIMAL_AXIS_BIGTICK_STEP(150);
+const int SignalDrawer::DEFAULT_MINIMAL_AXIS_BIGTICK_STEP(25);
+const int SignalDrawer::DEFAULT_SCALE_TEXT_VERTICAL_OFFSET(15);
+const int SignalDrawer::DEFAULT_SUBTICK_LENGTH(4);
+const int SignalDrawer::LABEL_FONT_SIZE(10);
const int SignalDrawer::SCALE_MARGIN_TIME(16);
const int SignalDrawer::SCALE_MARGIN_VALUE(12);
-SignalDrawer::SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints) :
+SignalDrawer::SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints,
+ const int dpiX, const int dpiY) :
m_controller(controller),
m_background(nullptr),
m_pixmap(nullptr),
m_relYMin(constraints.fromY),
m_leftGraphOffset(0),
m_validConstraints(false),
- m_axisLabelFont(QFont("arial", 10)),
- m_axisLabelFM(QFontMetrics(m_axisLabelFont)),
m_xAxisLabelText("[" + controller->signal()->xunitAsString() + "]"),
m_yAxisLabelText("[" + controller->signal()->yunitAsString() + "]")
{
+ if (dpiX > 0 && dpiY > 0) {
+ m_dpiX = dpiX;
+ m_dpiY = dpiY;
+ } else {
+ m_dpiX = qApp->desktop()->logicalDpiX();
+ m_dpiY = qApp->desktop()->logicalDpiY();
+ }
+
+ m_axisLabelFont = new QFont("arial", scaleToDpiX(LABEL_FONT_SIZE));
+ m_axisLabelFM = new QFontMetrics(*m_axisLabelFont);
+ m_bigTickLength = scaleToDpiX(DEFAULT_BIGTICK_LENGTH);
+ m_subTickLength = scaleToDpiX(DEFAULT_SUBTICK_LENGTH);
+ m_maximalBigtickStep = scaleToDpiX(DEFAULT_MAXIMAL_AXIS_BIGTICK_STEP);
+ m_minimalBigtickStep = scaleToDpiX(DEFAULT_MINIMAL_AXIS_BIGTICK_STEP);
+ m_scaleTextVerticalOffset = scaleToDpiY(DEFAULT_SCALE_TEXT_VERTICAL_OFFSET);
+
+ Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, QString("DPI X: %1, DPI Y: %2").arg(m_dpiX).arg(m_dpiY));
}
/** Public methods **/
Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw scales");
goto error_out;
}
- m_xAxisLabelRect = m_axisLabelFM.boundingRect(m_xAxisLabelText);
- m_yAxisLabelRect = m_axisLabelFM.boundingRect(m_yAxisLabelText);
- m_xAxisLabelRect.moveTo(m_width - m_axisLabelFM.width(m_xAxisLabelText) - AXIS_LABEL_BORDER_OFFSET, m_gHeight - AXIS_LABEL_SCALE_OFFSET);
- m_yAxisLabelRect.moveTo(m_leftGraphOffset + AXIS_LABEL_SCALE_OFFSET, m_axisLabelFM.height() - m_axisLabelFM.underlinePos());
+ m_xAxisLabelRect = m_axisLabelFM->boundingRect(m_xAxisLabelText);
+ m_yAxisLabelRect = m_axisLabelFM->boundingRect(m_yAxisLabelText);
+ m_xAxisLabelRect.moveTo(m_width - m_axisLabelFM->width(m_xAxisLabelText) - AXIS_LABEL_BORDER_OFFSET, m_gHeight - AXIS_LABEL_SCALE_OFFSET);
+ m_yAxisLabelRect.moveTo(m_leftGraphOffset + AXIS_LABEL_SCALE_OFFSET, m_axisLabelFM->height() - m_axisLabelFM->underlinePos());
} else {
m_gWidth = m_width;
m_leftGraphOffset = 0;
m_height = height;
m_width = width;
- m_gHeight = height - SCALE_MARGIN_TIME;
+ m_gHeight = height - scaleToDpiY(SCALE_MARGIN_TIME);
//qDebug() << __QFUNC__ << width << height << m_width << m_height;
}
painter->setPen(QColor(Qt::black));
- painter->setFont(m_axisLabelFont);
+ painter->setFont(*m_axisLabelFont);
painter->drawText(xPix, yPix, text);
return true;
tickDrawFunc = std::bind(&SignalDrawer::renderTimeScaleTick, this, p, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
RulerDrawData rd = m_controller->getRulerDrawData(m_relXMin, m_relXMax, SignalController::Axis::TIME, m_gWidth,
- MINIMAL_AXIS_BIGTICK_STEP, maxBigTickStep);
+ m_minimalBigtickStep, maxBigTickStep);
if (!rd.valid)
return;
tickDrawFunc = std::bind(&SignalDrawer::renderValueScaleTick, this, p, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
RulerDrawData rd = m_controller->getRulerDrawData(m_relYMin, m_relYMax, SignalController::Axis::VALUE, m_gHeight,
- MINIMAL_AXIS_BIGTICK_STEP, maxBigTickStep);
+ m_minimalBigtickStep, maxBigTickStep);
if (!rd.valid)
return;
drawScaleByTicks(rd, textDrawFunc, m_relYMax, false);
/* Maximum width of numeric cues is now known - calculate offset from the left */
- m_leftGraphOffset = maxCueWidth + SCALE_MARGIN_VALUE;
+ m_leftGraphOffset = maxCueWidth + scaleToDpiX(SCALE_MARGIN_VALUE);
m_gWidth = m_width - m_leftGraphOffset;
/* Draw subticks before first big tick */
return false;
}
- painter->setFont(m_axisLabelFont);
+ painter->setFont(*m_axisLabelFont);
/* VALUE scale must be drawn first - left offset of the graph depends on it */
drawValueScale(painter);
drawTimeScale(painter);
QRect br = p->fontMetrics().boundingRect(text);
if (xPix + br.width() > m_gWidth)
return;
- p->drawText(xPix + 2, m_gHeight + 15, m_locale.toString(value, 'f', 3));
+ p->drawText(xPix + 2, m_gHeight + m_scaleTextVerticalOffset, m_locale.toString(value, 'f', 3));
}
void SignalDrawer::renderValueScaleText(QPainter* const p, int& maxCueWidth, const double rel, const double value, const TickType tt)
switch (tt) {
case TickType::BIGTICK:
- p->drawLine(xPix, m_gHeight + 2, xPix, m_gHeight + 8);
+ p->drawLine(xPix, m_gHeight + 2, xPix, m_gHeight + m_bigTickLength);
break;
case TickType::SUBTICK:
- p->drawLine(xPix, m_gHeight + 2, xPix , m_gHeight + 4);
+ p->drawLine(xPix, m_gHeight + 2, xPix , m_gHeight + m_subTickLength);
break;
}
}
switch (tt) {
case TickType::BIGTICK:
- p->drawLine(m_leftGraphOffset - 8, yPix, m_leftGraphOffset - 1, yPix);
+ p->drawLine(m_leftGraphOffset - m_bigTickLength, yPix, m_leftGraphOffset - 1, yPix);
break;
case TickType::SUBTICK:
- p->drawLine(m_leftGraphOffset - 4, yPix, m_leftGraphOffset - 1, yPix);
+ p->drawLine(m_leftGraphOffset - m_subTickLength, yPix, m_leftGraphOffset - 1, yPix);
break;
}
}
int SignalDrawer::calculateMaximalTickStep(const int dimension)
{
- if (dimension < MAXIMAL_AXIS_BIGTICK_STEP) {
+ if (dimension < m_maximalBigtickStep) {
/* The viewport is just too small for the ticks to fit in */
- if (dimension < MINIMAL_AXIS_BIGTICK_STEP) {
- return MINIMAL_AXIS_BIGTICK_STEP + 1;
+ if (dimension < m_minimalBigtickStep) {
+ return m_minimalBigtickStep + 1;
} else {
- return ((dimension - MINIMAL_AXIS_BIGTICK_STEP) / 2) + MINIMAL_AXIS_BIGTICK_STEP + 1;
+ return ((dimension - m_minimalBigtickStep) / 2) + m_minimalBigtickStep + 1;
}
}
- return MAXIMAL_AXIS_BIGTICK_STEP;
+ return m_maximalBigtickStep;
}
double SignalDrawer::linesIntersection(const double k1, const double q1, const double k2, const double q2)
m_relYMax = m_oldRelYMax;
}
+template<typename T>
+T SignalDrawer::scaleToDpiX(const T value)
+{
+ return static_cast<double>(value) * m_dpiX / DEFAULT_DPI;
+}
+
+template<typename T>
+T SignalDrawer::scaleToDpiY(const T value)
+{
+ return static_cast<double>(value) * m_dpiY / DEFAULT_DPI;
+}
+
void SignalDrawer::setNewRelativeConstraints(const double fromX, const double fromY, const double toX, const double toY)
{
m_oldRelXMin = m_relXMin;
{
delete m_pixmap;
delete m_background;
+ delete m_axisLabelFM;
+ delete m_axisLabelFont;
}
class SignalDrawer
{
public:
- SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints = Constraints());
+ SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints = Constraints(),
+ const int dpiX = 0, const int dpiY = 0);
~SignalDrawer();
Constraints currentConstraints();
int dheight() const { return m_height; }
static const int AXIS_LABEL_BORDER_OFFSET;
static const int AXIS_LABEL_SCALE_OFFSET;
- static const int MAXIMAL_AXIS_BIGTICK_STEP;
- static const int MINIMAL_AXIS_BIGTICK_STEP;
+ static const int DEFAULT_BIGTICK_LENGTH;
+ static const double DEFAULT_DPI;
+ static const int DEFAULT_MAXIMAL_AXIS_BIGTICK_STEP;
+ static const int DEFAULT_MINIMAL_AXIS_BIGTICK_STEP;
+ static const int DEFAULT_SCALE_TEXT_VERTICAL_OFFSET;
+ static const int DEFAULT_SUBTICK_LENGTH;
+ static const int LABEL_FONT_SIZE;
static const int SCALE_MARGIN_TIME;
static const int SCALE_MARGIN_VALUE;
int calculateMaximalTickStep(const int dimension);
double linesIntersection(const double k1, const double q1, const double k2, const double q2);
void restoreRelativeConstraints();
+ template<typename T> T scaleToDpiX(const T value);
+ template<typename T> T scaleToDpiY(const T value);
void setNewRelativeConstraints(const double fromX, const double fromY, const double toX, const double toY);
double subStep(const double step);
int m_leftGraphOffset;
bool m_validConstraints;
+ int m_bigTickLength;
+ int m_subTickLength;
+ int m_maximalBigtickStep;
+ int m_minimalBigtickStep;
+ int m_scaleTextVerticalOffset;
+ double m_dpiX;
+ double m_dpiY;
+
double m_oldRelXMax;
double m_oldRelXMin;
double m_oldRelYMax;
double m_oldRelYMin;
- const QFont m_axisLabelFont;
- const QFontMetrics m_axisLabelFM;
+ const QFont* m_axisLabelFont;
+ const QFontMetrics* m_axisLabelFM;
QRect m_xAxisLabelRect;
QRect m_yAxisLabelRect;
const QString m_xAxisLabelText;