diff --git a/profile-widget/divecartesianaxis.cpp b/profile-widget/divecartesianaxis.cpp index f90c0b039..1c154bd0d 100644 --- a/profile-widget/divecartesianaxis.cpp +++ b/profile-widget/divecartesianaxis.cpp @@ -18,7 +18,7 @@ void DiveCartesianAxis::setBounds(double minimum, double maximum) max = maximum; } -DiveCartesianAxis::DiveCartesianAxis(Position position, color_index_t gridColor, double dpr, +DiveCartesianAxis::DiveCartesianAxis(Position position, int integralDigits, int fractionalDigits, color_index_t gridColor, double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene) : printMode(printMode), position(position), @@ -45,6 +45,26 @@ DiveCartesianAxis::DiveCartesianAxis(Position position, color_index_t gridColor, pen.setBrush(getColor(gridColor, isGrayscale)); gridPen = pen; + + /* Create the longest expected label, e.g. 999.99. */ + QString label; + label.reserve(integralDigits + fractionalDigits + 1); + for (int i = 0; i < integralDigits; ++i) + label.append('9'); + if (fractionalDigits > 0) { + label.append('.'); + for (int i = 0; i < fractionalDigits; ++i) + label.append('9'); + } + + /* Use the label to estimate size of the labels. + * Round up, because non-integers tend to give abysmal rendering. + */ + QFont fnt = DiveTextItem::getFont(dpr, labelScale); + double outlineSpace = DiveTextItem::outlineSpace(dpr); + QFontMetrics fm(fnt); + labelWidth = ceil(fm.size(Qt::TextSingleLine, label).width() + outlineSpace); + labelHeight = ceil(fm.height() + outlineSpace); } DiveCartesianAxis::~DiveCartesianAxis() @@ -93,23 +113,14 @@ void emptyList(QList &list, int steps, int speed) } } -double DiveCartesianAxis::textWidth(const QString &s) const -{ - QFont fnt = DiveTextItem::getFont(dpr, labelScale); - QFontMetrics fm(fnt); - return fm.size(Qt::TextSingleLine, s).width() + labelSpaceHorizontal * dpr; -} - double DiveCartesianAxis::width() const { - return textWidth("999"); + return labelWidth + labelSpaceHorizontal * dpr; } double DiveCartesianAxis::height() const { - QFont fnt = DiveTextItem::getFont(dpr, labelScale); - QFontMetrics fm(fnt); - return fm.height() + labelSpaceVertical * dpr; + return labelHeight + labelSpaceVertical * dpr; } void DiveCartesianAxis::updateTicks(int animSpeed) @@ -383,9 +394,10 @@ QString TemperatureAxis::textForValue(double value) const return QString::number(mkelvin_to_C((int)value)); } -PartialGasPressureAxis::PartialGasPressureAxis(const DivePlotDataModel &model, Position position, color_index_t gridColor, - double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene) : - DiveCartesianAxis(position, gridColor, dpr, labelScale, printMode, isGrayscale, scene), +PartialGasPressureAxis::PartialGasPressureAxis(const DivePlotDataModel &model, Position position, int integralDigits, int fractionalDigits, + color_index_t gridColor, double dpr, double labelScale, bool printMode, bool isGrayscale, + ProfileScene &scene) : + DiveCartesianAxis(position, integralDigits, fractionalDigits, gridColor, dpr, labelScale, printMode, isGrayscale, scene), model(model) { } @@ -413,8 +425,3 @@ void PartialGasPressureAxis::update(int animSpeed) setTickInterval(pp > 4 ? 0.5 : 0.25); updateTicks(animSpeed); } - -double PartialGasPressureAxis::width() const -{ - return textWidth(textForValue(0.99)); -} diff --git a/profile-widget/divecartesianaxis.h b/profile-widget/divecartesianaxis.h index adfdd16a2..8b4fd3a03 100644 --- a/profile-widget/divecartesianaxis.h +++ b/profile-widget/divecartesianaxis.h @@ -32,7 +32,7 @@ public: enum class Position { Left, Right, Bottom }; - DiveCartesianAxis(Position position, color_index_t gridColor, double dpr, + DiveCartesianAxis(Position position, int integralDigits, int fractionalDigits, color_index_t gridColor, double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene); ~DiveCartesianAxis(); void setBounds(double min, double max); @@ -62,7 +62,6 @@ protected: ProfileScene &scene; virtual QString textForValue(double value) const; virtual QColor colorForValue(double value) const; - double textWidth(const QString &s) const; Orientation orientation; QList labels; QList lines; @@ -74,6 +73,7 @@ protected: double labelScale; bool changed; double dpr; + double labelWidth, labelHeight; // maximum expected sizes of label width and height }; class DepthAxis : public DiveCartesianAxis { @@ -106,10 +106,9 @@ private: class PartialGasPressureAxis : public DiveCartesianAxis { Q_OBJECT public: - PartialGasPressureAxis(const DivePlotDataModel &model, Position position, color_index_t gridColor, - double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene); + PartialGasPressureAxis(const DivePlotDataModel &model, Position position, int integralDigits, int fractionalDigits, + color_index_t gridColor, double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene); void update(int animSpeed); - double width() const; private: const DivePlotDataModel &model; }; diff --git a/profile-widget/divetextitem.cpp b/profile-widget/divetextitem.cpp index 6e6f97e95..1b8580d2a 100644 --- a/profile-widget/divetextitem.cpp +++ b/profile-widget/divetextitem.cpp @@ -82,6 +82,11 @@ QFont DiveTextItem::getFont(double dpr, double scale) return fnt; } +double DiveTextItem::outlineSpace(double dpr) +{ + return 2.0 * outlineSize * dpr; // Double because outline growths to both sides. +} + double DiveTextItem::fontHeight(double dpr, double scale) { QFont fnt = getFont(dpr, scale); diff --git a/profile-widget/divetextitem.h b/profile-widget/divetextitem.h index cb7d054b1..6ce3437af 100644 --- a/profile-widget/divetextitem.h +++ b/profile-widget/divetextitem.h @@ -22,6 +22,7 @@ public: const QString &text(); static QFont getFont(double dpr, double scale); static double fontHeight(double dpr, double scale); + static double outlineSpace(double dpr); // Additional space needed by outline double height() const; private: diff --git a/profile-widget/profilescene.cpp b/profile-widget/profilescene.cpp index 779514a14..020930f17 100644 --- a/profile-widget/profilescene.cpp +++ b/profile-widget/profilescene.cpp @@ -47,13 +47,13 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) : maxtime(-1), maxdepth(-1), dataModel(new DivePlotDataModel(this)), - profileYAxis(new DepthAxis(DiveCartesianAxis::Position::Left, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), - gasYAxis(new PartialGasPressureAxis(*dataModel, DiveCartesianAxis::Position::Right, TIME_GRID, dpr, 0.7, printMode, isGrayscale, *this)), - temperatureAxis(new TemperatureAxis(DiveCartesianAxis::Position::Right, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), - timeAxis(new TimeAxis(DiveCartesianAxis::Position::Bottom, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), - cylinderPressureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), - heartBeatAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, HR_AXIS, dpr, 0.7, printMode, isGrayscale, *this)), - percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, TIME_GRID, dpr, 0.7, printMode, isGrayscale, *this)), + profileYAxis(new DepthAxis(DiveCartesianAxis::Position::Left, 3, 0, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), + gasYAxis(new PartialGasPressureAxis(*dataModel, DiveCartesianAxis::Position::Right, 1, 2, TIME_GRID, dpr, 0.7, printMode, isGrayscale, *this)), + temperatureAxis(new TemperatureAxis(DiveCartesianAxis::Position::Right, 3, 0, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), + timeAxis(new TimeAxis(DiveCartesianAxis::Position::Bottom, 2, 2, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), + cylinderPressureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 2, 2, TIME_GRID, dpr, 1.0, printMode, isGrayscale, *this)), + heartBeatAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, 3, 0, HR_AXIS, dpr, 0.7, printMode, isGrayscale, *this)), + percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 2, 0, TIME_GRID, dpr, 0.7, printMode, isGrayscale, *this)), diveProfileItem(createItem(*profileYAxis, DivePlotDataModel::DEPTH, 0, dpr)), temperatureItem(createItem(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)), meanDepthItem(createItem(*profileYAxis, DivePlotDataModel::INSTANT_MEANDEPTH, 1, dpr)),