Welcome to mirror list, hosted at ThFree Co, Russian Federation.

text_path.cpp « graphics - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 465aa8aabc9b260beecfcd412e9e1e2532b2b7b7 (plain)
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
#include "../base/SRC_FIRST.hpp"

#include "text_path.hpp"

#include "../geometry/angles.hpp"

namespace graphics
{
  TextPath::TextPath()
    : m_pv(),
      m_fullLength(0),
      m_pathOffset(0)
  {}

  TextPath::TextPath(TextPath const & src, math::Matrix<double, 3, 3> const & m)
  {
    m_arr.resize(src.m_arr.size());
    for (unsigned i = 0; i < m_arr.size(); ++i)
      m_arr[i] = src.m_arr[i] * m;

    m_fullLength = (m2::PointD(src.m_fullLength, 0) * m).Length(m2::PointD(0, 0) * m);
    m_pathOffset = (m2::PointD(src.m_pathOffset, 0) * m).Length(m2::PointD(0, 0) * m);

    m_pv = PathView(&m_arr[0], m_arr.size());

    /// Fix: Check for reversing only when rotation is active,
    /// otherwise we have some flicker-blit issues for street names on zooming.
    /// @todo Should investigate this stuff.
    if (m(0, 1) != 0.0 && m(1, 0) != 0.0)
      checkReverse();
    else
      setIsReverse(src.isReverse());
  }

  TextPath::TextPath(m2::PointD const * arr, size_t sz, double fullLength, double pathOffset)
    : m_fullLength(fullLength),
      m_pathOffset(pathOffset)
  {
    ASSERT ( sz > 1, () );

    m_arr.resize(sz);
    copy(arr, arr + sz, m_arr.begin());

    m_pv = PathView(&m_arr[0], m_arr.size());

    checkReverse();
  }

  bool TextPath::isReverse() const
  {
    return m_pv.isReverse();
  }

  void TextPath::setIsReverse(bool flag)
  {
    m_pv.setIsReverse(flag);
  }

  void TextPath::checkReverse()
  {
    /* assume, that readable text in path should be ('o' - start draw point):
     *    /   o
     *   /     \
     *  /   or  \
     * o         \
     */

    double const a = ang::AngleTo(m_arr[0], m_arr[m_arr.size() - 1]);

    if (fabs(a) > math::pi / 2.0)
    {
      // if we swap direction, we need to recalculate path offset from the end
      double len = 0.0;
      for (size_t i = 1; i < m_arr.size(); ++i)
        len += m_arr[i-1].Length(m_arr[i]);

      m_pathOffset = m_fullLength - m_pathOffset - len;
      ASSERT ( m_pathOffset >= -1.0E-6, () );
      if (m_pathOffset < 0.0)
        m_pathOffset = 0.0;

      setIsReverse(true);
    }
    else
      setIsReverse(false);
  }

  double TextPath::fullLength() const
  {
    return m_fullLength;
  }

  double TextPath::pathOffset() const
  {
    return m_pathOffset;
  }

  size_t TextPath::size() const
  {
    return m_pv.size();
  }

  m2::PointD TextPath::get(size_t i) const
  {
    return m_pv.get(i);
  }

  m2::PointD TextPath::operator[](size_t i) const
  {
    return get(i);
  }

  PathPoint const TextPath::offsetPoint(PathPoint const & pp, double offset) const
  {
    return m_pv.offsetPoint(pp, offset);
  }

  PivotPoint TextPath::findPivotPoint(PathPoint const & pp, GlyphMetrics const & sym, double kern) const
  {
    return m_pv.findPivotPoint(pp, sym.m_xOffset + sym.m_width / 2.0, kern);
  }

  PathPoint const TextPath::front() const
  {
    return m_pv.front();
  }
}