Audacity 3.2.0
LogarithmicUpdater.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 LogarithmicUpdater.cpp
6
7 Dominic Mazzoni
8 Michael Papadopoulos split from Ruler.cpp
9
10**********************************************************************/
11
12#include "LogarithmicUpdater.h"
13#include "IntFormat.h"
14
16{
17 static LogarithmicUpdater instance;
18 return instance;
19}
20
22 wxDC& dc, const Envelope* envelope,
23 UpdateOutputs& allOutputs, const RulerStruct& context) const
24{
25 TickOutputs majorOutputs{
26 allOutputs.majorLabels, allOutputs.bits, allOutputs.box };
27
28 const int mLength = context.mLength;
29
30 const int mOrientation = context.mOrientation;
31
32 const double mMin = context.mMin;
33 const double mMax = context.mMax;
34 const double mHiddenMin = context.mHiddenMin;
35 const double mHiddenMax = context.mHiddenMax;
36
37 const RulerStruct::Fonts& mFonts = *context.mpFonts;
38 const NumberScale mNumberScale = context.mNumberScale;
39
40 auto numberScale = (mNumberScale == NumberScale{})
41 ? NumberScale(nstLogarithmic, mMin, mMax)
42 : mNumberScale;
43
44 double UPP = (mHiddenMax - mHiddenMin) / mLength; // Units per pixel
45 TickSizes tickSizes{ UPP, mOrientation, context.mpRulerFormat, true };
46
47 tickSizes.mDigits = 2; //TODO: implement dynamic digit computation
48
49 double loLog = log10(mMin);
50 double hiLog = log10(mMax);
51 int loDecade = (int)floor(loLog);
52
53 double val;
54 double startDecade = pow(10., (double)loDecade);
55
56 // Major ticks are the decades
57 double decade = startDecade;
58 double delta = hiLog - loLog, steps = fabs(delta);
59 double step = delta >= 0 ? 10 : 0.1;
60 double rMin = std::min(mMin, mMax), rMax = std::max(mMin, mMax);
61 for (int i = 0; i <= steps; i++)
62 { // if(i!=0)
63 { val = decade;
64 if (val >= rMin && val < rMax) {
65 const int pos(0.5 + mLength * numberScale.ValueToPosition(val));
66 Tick(dc, pos, val, tickSizes, mFonts.major, majorOutputs, context);
67 }
68 }
69 decade *= step;
70 }
71
72 // Minor ticks are multiples of decades
73 decade = startDecade;
74 float start, end, mstep;
75 if (delta > 0)
76 {
77 start = 2; end = 10; mstep = 1;
78 }
79 else
80 {
81 start = 9; end = 1; mstep = -1;
82 }
83 steps++;
84 tickSizes.tickType = RulerFormat::t_minor;
85 TickOutputs minorOutputs{
86 allOutputs.minorLabels, allOutputs.bits, allOutputs.box };
87 for (int i = 0; i <= steps; i++) {
88 for (int j = start; j != end; j += mstep) {
89 val = decade * j;
90 if (val >= rMin && val < rMax) {
91 const int pos(0.5 + mLength * numberScale.ValueToPosition(val));
92 Tick(dc, pos, val, tickSizes, mFonts.minor, minorOutputs, context);
93 }
94 }
95 decade *= step;
96 }
97
98 // MinorMinor ticks are multiples of decades
99 decade = startDecade;
100 if (delta > 0)
101 {
102 start = 10; end = 100; mstep = 1;
103 }
104 else
105 {
106 start = 100; end = 10; mstep = -1;
107 }
108 steps++;
109 tickSizes.tickType = RulerFormat::t_minorMinor;
110 TickOutputs minorMinorOutputs{
111 allOutputs.minorMinorLabels, allOutputs.bits, allOutputs.box };
112 for (int i = 0; i <= steps; i++) {
113 // PRL: Bug1038. Don't label 1.6, rounded, as a duplicate tick for "2"
114 if (!(context.mpRulerFormat == &IntFormat::Instance() && decade < 10.0)) {
115 for (int f = start; f != (int)(end); f += mstep) {
116 if ((int)(f / 10) != f / 10.0f) {
117 val = decade * f / 10;
118 if (val >= rMin && val < rMax) {
119 const int pos(0.5 + mLength * numberScale.ValueToPosition(val));
120 Tick(dc, pos, val, tickSizes,
121 mFonts.minorMinor, minorMinorOutputs, context);
122 }
123 }
124 }
125 }
126 decade *= step;
127 }
128
129 BoxAdjust(allOutputs, context);
130}
131
int min(int a, int b)
@ nstLogarithmic
Definition: NumberScale.h:20
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
bool Tick(wxDC &dc, int pos, double d, const TickSizes &tickSizes, wxFont font, TickOutputs outputs, const RulerStruct &context) const
static const IntFormat & Instance()
Definition: IntFormat.cpp:14
static const LogarithmicUpdater & Instance()
~LogarithmicUpdater() override
void Update(wxDC &dc, const Envelope *envelope, UpdateOutputs &allOutputs, const RulerStruct &context) const override
void BoxAdjust(UpdateOutputs &allOutputs, const RulerStruct &context) const
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
std::unique_ptr< Fonts > mpFonts
Definition: RulerUpdater.h:52
double mMax
Definition: RulerUpdater.h:34
double mHiddenMax
Definition: RulerUpdater.h:35
int mOrientation
Definition: RulerUpdater.h:37
NumberScale mNumberScale
Definition: RulerUpdater.h:55
const RulerFormat * mpRulerFormat
Definition: RulerUpdater.h:41
double mMin
Definition: RulerUpdater.h:32
double mHiddenMin
Definition: RulerUpdater.h:33