1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
#include "drape_frontend/visual_params.hpp"
#include "base/macros.hpp"
#include "base/math.hpp"
#include "base/assert.hpp"
#include "geometry/mercator.hpp"
#include "indexer/scales.hpp"
#include "std/algorithm.hpp"
#include "std/limits.hpp"
#include "std/utility.hpp"
namespace df
{
namespace
{
static VisualParams g_VizParams;
typedef pair<string, double> visual_scale_t;
} // namespace
#ifdef DEBUG
static bool g_isInited = false;
#define RISE_INITED g_isInited = true
#define ASSERT_INITED ASSERT(g_isInited, ())
#else
#define RISE_INITED
#define ASSERT_INITED
#endif
double const VisualParams::kMdpiScale = 1.0;
double const VisualParams::kHdpiScale = 1.5;
double const VisualParams::kXhdpiScale = 2.0;
double const VisualParams::k6plusScale = 2.4;
double const VisualParams::kXxhdpiScale = 3.0;
void VisualParams::Init(double vs, uint32_t tileSize)
{
g_VizParams.m_tileSize = tileSize;
g_VizParams.m_visualScale = vs;
// Here we set up glyphs rendering parameters separately for high-res and low-res screens.
if (vs <= 1.0)
g_VizParams.m_glyphVisualParams = { 0.48f, 0.08f, 0.2f, 0.01f, 0.49f, 0.04f };
else
g_VizParams.m_glyphVisualParams = { 0.5f, 0.06f, 0.2f, 0.01f, 0.49f, 0.04f };
RISE_INITED;
}
uint32_t VisualParams::GetGlyphSdfScale() const
{
return (m_visualScale <= 1.0) ? 3 : 4;
}
uint32_t VisualParams::GetGlyphBaseSize() const
{
return 22;
}
double VisualParams::GetFontScale() const
{
return m_fontScale;
}
void VisualParams::SetFontScale(double fontScale)
{
m_fontScale = fontScale;
}
VisualParams & VisualParams::Instance()
{
ASSERT_INITED;
return g_VizParams;
}
string const & VisualParams::GetResourcePostfix(double visualScale)
{
static visual_scale_t postfixes[] =
{
make_pair("mdpi", kMdpiScale),
make_pair("hdpi", kHdpiScale),
make_pair("xhdpi", kXhdpiScale),
make_pair("xxhdpi", kXxhdpiScale),
make_pair("6plus", k6plusScale),
};
// Looking for the nearest available scale.
int postfixIndex = -1;
double minValue = numeric_limits<double>::max();
for (int i = 0; i < ARRAY_SIZE(postfixes); i++)
{
double val = fabs(postfixes[i].second - visualScale);
if (val < minValue)
{
minValue = val;
postfixIndex = i;
}
}
ASSERT_GREATER_OR_EQUAL(postfixIndex, 0, ());
return postfixes[postfixIndex].first;
}
string const & VisualParams::GetResourcePostfix() const
{
return VisualParams::GetResourcePostfix(m_visualScale);
}
double VisualParams::GetVisualScale() const
{
return m_visualScale;
}
uint32_t VisualParams::GetTileSize() const
{
return m_tileSize;
}
uint32_t VisualParams::GetTouchRectRadius() const
{
float const kRadiusInPixels = 20.0f;
return kRadiusInPixels * GetVisualScale();
}
double VisualParams::GetDragThreshold() const
{
double const kDragThresholdInPixels = 10.0;
return kDragThresholdInPixels * GetVisualScale();
}
double VisualParams::GetScaleThreshold() const
{
double const kScaleThresholdInPixels = 2.0;
return kScaleThresholdInPixels * GetVisualScale();
}
VisualParams::GlyphVisualParams const & VisualParams::GetGlyphVisualParams() const
{
return m_glyphVisualParams;
}
VisualParams::VisualParams()
: m_tileSize(0)
, m_visualScale(0.0)
, m_fontScale(1.0)
{
}
m2::RectD const & GetWorldRect()
{
static m2::RectD const worldRect = MercatorBounds::FullRect();
return worldRect;
}
int GetTileScaleBase(ScreenBase const & s, uint32_t tileSize)
{
ScreenBase tmpS = s;
tmpS.Rotate(-tmpS.GetAngle());
// slightly smaller than original to produce "antialiasing" effect using bilinear filtration.
int const halfSize = static_cast<int>(tileSize / 1.05 / 2.0);
m2::RectD glbRect;
m2::PointD const pxCenter = tmpS.PixelRect().Center();
tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(halfSize, halfSize),
pxCenter + m2::PointD(halfSize, halfSize)),
glbRect);
return GetTileScaleBase(glbRect);
}
int GetTileScaleBase(ScreenBase const & s)
{
return GetTileScaleBase(s, VisualParams::Instance().GetTileSize());
}
int GetTileScaleBase(m2::RectD const & r)
{
double const sz = max(r.SizeX(), r.SizeY());
return max(1, my::rounds(log((MercatorBounds::maxX - MercatorBounds::minX) / sz) / log(2.0)));
}
int GetTileScaleIncrement(uint32_t tileSize, double visualScale)
{
return log(tileSize / 256.0 / visualScale) / log(2.0);
}
int GetTileScaleIncrement()
{
VisualParams const & p = VisualParams::Instance();
return GetTileScaleIncrement(p.GetTileSize(), p.GetVisualScale());
}
m2::RectD GetRectForDrawScale(int drawScale, m2::PointD const & center, uint32_t tileSize, double visualScale)
{
// +1 - we will calculate half length for each side
double const factor = 1 << (max(1, drawScale - GetTileScaleIncrement(tileSize, visualScale)) + 1);
double const len = (MercatorBounds::maxX - MercatorBounds::minX) / factor;
return m2::RectD(MercatorBounds::ClampX(center.x - len),
MercatorBounds::ClampY(center.y - len),
MercatorBounds::ClampX(center.x + len),
MercatorBounds::ClampY(center.y + len));
}
m2::RectD GetRectForDrawScale(int drawScale, m2::PointD const & center)
{
VisualParams const & p = VisualParams::Instance();
return GetRectForDrawScale(drawScale, center, p.GetTileSize(), p.GetVisualScale());
}
m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center, uint32_t tileSize, double visualScale)
{
return GetRectForDrawScale(my::rounds(drawScale), center, tileSize, visualScale);
}
m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center)
{
return GetRectForDrawScale(my::rounds(drawScale), center);
}
int CalculateTileSize(int screenWidth, int screenHeight)
{
int const maxSz = max(screenWidth, screenHeight);
// we're calculating the tileSize based on (maxSz > 1024 ? rounded : ceiled)
// to the nearest power of two value of the maxSz
int const ceiledSz = 1 << static_cast<int>(ceil(log(double(maxSz + 1)) / log(2.0)));
int res = 0;
if (maxSz < 1024)
res = ceiledSz;
else
{
int const flooredSz = ceiledSz / 2;
// rounding to the nearest power of two.
if (ceiledSz - maxSz < maxSz - flooredSz)
res = ceiledSz;
else
res = flooredSz;
}
#ifndef OMIM_OS_DESKTOP
return my::clamp(res / 2, 256, 1024);
#else
return my::clamp(res / 2, 512, 1024);
#endif
}
int GetDrawTileScale(int baseScale, uint32_t tileSize, double visualScale)
{
return max(1, baseScale + GetTileScaleIncrement(tileSize, visualScale));
}
int GetDrawTileScale(ScreenBase const & s, uint32_t tileSize, double visualScale)
{
return GetDrawTileScale(GetTileScaleBase(s, tileSize), tileSize, visualScale);
}
int GetDrawTileScale(m2::RectD const & r, uint32_t tileSize, double visualScale)
{
return GetDrawTileScale(GetTileScaleBase(r), tileSize, visualScale);
}
int GetDrawTileScale(int baseScale)
{
VisualParams const & p = VisualParams::Instance();
return GetDrawTileScale(baseScale, p.GetTileSize(), p.GetVisualScale());
}
int GetDrawTileScale(ScreenBase const & s)
{
VisualParams const & p = VisualParams::Instance();
return GetDrawTileScale(s, p.GetTileSize(), p.GetVisualScale());
}
int GetDrawTileScale(m2::RectD const & r)
{
VisualParams const & p = VisualParams::Instance();
return GetDrawTileScale(r, p.GetTileSize(), p.GetVisualScale());
}
double GetZoomLevel(double scale)
{
static double const kLog2 = log(2.0);
return my::clamp(fabs(log(scale) / kLog2), 1, scales::GetUpperStyleScale() + 1.0);
}
double GetNormalizedZoomLevel(double scale, int minZoom)
{
double const kMaxZoom = scales::GetUpperStyleScale() + 1.0;
return my::clamp((GetZoomLevel(scale) - minZoom) / (kMaxZoom - minZoom), 0.0, 1.0);
}
double GetScale(double zoomLevel)
{
return pow(2.0, -zoomLevel);
}
} // namespace df
|