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
|
#include "graphics/text_element.hpp"
#include "graphics/overlay_renderer.hpp"
#include "graphics/glyph.hpp"
#include "graphics/glyph_layout.hpp"
#include "base/logging.hpp"
namespace graphics
{
TextElement::TextElement(Params const & p)
: OverlayElement(p),
m_fontDesc(p.m_fontDesc),
m_auxFontDesc(p.m_auxFontDesc)
{
}
pair<bool, bool> TextElement::Params::GetVisibleTexts(
strings::UniString & visText, strings::UniString & auxVisText) const
{
if (m_log2vis)
{
visText = m_glyphCache->log2vis(m_logText);
if (!m_auxLogText.empty())
auxVisText = m_glyphCache->log2vis(m_auxLogText);
return make_pair(visText != m_logText, auxVisText != m_auxLogText);
}
else
{
visText = m_logText;
auxVisText = m_auxLogText;
return make_pair(false, false);
}
}
FontDesc const & TextElement::fontDesc() const
{
return m_fontDesc;
}
FontDesc const & TextElement::auxFontDesc() const
{
return m_auxFontDesc;
}
void TextElement::drawTextImpl(GlyphLayout const & layout,
OverlayRenderer * screen,
math::Matrix<double, 3, 3> const & m,
bool doTransformPivotOnly,
bool doAlignPivot,
FontDesc const & fontDesc,
double depth) const
{
if (!fontDesc.IsValid())
return;
m2::PointD pv = layout.pivot();
m2::PointD offs = layout.offset();
double deltaA = 0;
if (doTransformPivotOnly)
pv *= m;
else
{
double k = (sqrt((m(0, 0) * m(0, 0) + m(0, 1) * m(0, 1) + m(1, 0) * m(1, 0) + m(1, 1) * m(1, 1)) / 2));
if ((k > 1.1) || (k < 1 / 1.1))
return;
deltaA = (ang::AngleD(0) * m).val();
}
size_t const cnt = layout.entries().size();
buffer_vector<Glyph::Info, 32> glyphInfos(cnt);
buffer_vector<Resource::Info const *, 32> resInfos(cnt);
buffer_vector<uint32_t, 32> glyphIDs(cnt);
size_t const firstVis = layout.firstVisible();
size_t const lastVis = layout.lastVisible();
/// collecting all glyph infos in one array and packing them as a whole.
for (size_t i = firstVis; i < lastVis; ++i)
{
GlyphKey glyphKey(layout.entries()[i].m_sym,
fontDesc.m_size,
fontDesc.m_isMasked,
fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color);
glyphInfos[i] = Glyph::Info(glyphKey, screen->glyphCache());
resInfos[i] = &glyphInfos[i];
}
if (firstVis != lastVis &&
!screen->mapInfo(&resInfos[firstVis],
&glyphIDs[firstVis],
lastVis - firstVis))
{
LOG(LDEBUG, ("cannot render string", lastVis - firstVis, "characters long"));
return;
}
for (size_t i = firstVis; i < lastVis; ++i)
{
GlyphLayoutElem const & elem = layout.entries()[i];
Glyph const * glyph = static_cast<Glyph const *>(screen->fromID(glyphIDs[i]));
m2::PointD glyphPt;
ang::AngleD glyphAngle;
if (doTransformPivotOnly)
{
m2::PointD offsPt = offs + elem.m_pt;
screen->drawStraightGlyph(pv, offsPt, glyph, depth);
}
else
{
glyphPt = (pv + offs + elem.m_pt) * m;
glyphAngle = ang::AngleD(elem.m_angle.val() + deltaA);
screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyph, depth);
}
}
}
}
|