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

pen_info.hpp « software_renderer - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ab669399c5e6aacbecb3d1b0eefe008b44a35b31 (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
#pragma once

#include "software_renderer/icon_info.hpp"

#include "drape/drape_global.hpp"

#include "base/buffer_vector.hpp"
#include "base/math.hpp"

#include <algorithm>
#include <iterator>

namespace software_renderer
{

struct PenInfo
{
  typedef buffer_vector<double, 16> TPattern;
  dp::Color m_color;
  double m_w;
  TPattern m_pat;
  double m_offset;
  IconInfo m_icon;
  double m_step;
  dp::LineJoin m_join;
  dp::LineCap m_cap;

  bool m_isSolid;

  PenInfo(dp::Color const & color = dp::Color(0, 0, 0, 255),
          double width = 1.0,
          double const * pattern = 0,
          size_t patternSize = 0,
          double offset = 0,
          char const * symbol = 0,
          double step = 0,
          dp::LineJoin join = dp::RoundJoin,
          dp::LineCap cap = dp::RoundCap)
    : m_color(color)
    , m_w(width)
    , m_offset(offset)
    , m_step(step)
    , m_join(join)
    , m_cap(cap)
    , m_isSolid(false)
  {
    if (symbol != nullptr)
      m_icon = IconInfo(symbol);

    if (!m_icon.m_name.empty())
    {
      m_isSolid = false;
    }
    else
    {
      /// if pattern is solid
      if ((pattern == 0 ) || (patternSize == 0))
        m_isSolid = true;
      else
      {
        // hack for Samsung GT-S5570 (GPU floor()'s texture pattern width)
        m_w = std::max(m_w, 1.0);

        buffer_vector<double, 4> tmpV;
        std::copy(pattern, pattern + patternSize, std::back_inserter(tmpV));

        if (tmpV.size() % 2)
          tmpV.push_back(0);

        double length = 0;

        /// ensuring that a minimal element has a length of 2px
        for (size_t i = 0; i < tmpV.size(); ++i)
        {
          if ((tmpV[i] < 2) && (tmpV[i] > 0))
            tmpV[i] = 2;
          length += tmpV[i];
        }

        int i = 0;

        buffer_vector<double, 4> vec;

        if ((offset >= length) || (offset < 0))
          offset -= floor(offset / length) * length;

        double curLen = 0;

        /// shifting pattern
        while (true)
        {
          if (curLen + tmpV[i] > offset)
          {
            //we're inside, let's split the pattern

            if (i % 2 == 1)
              vec.push_back(0);

            vec.push_back(curLen + tmpV[i] - offset);
            std::copy(tmpV.begin() + i + 1, tmpV.end(), std::back_inserter(vec));
            std::copy(tmpV.begin(), tmpV.begin() + i, std::back_inserter(vec));
            vec.push_back(offset - curLen);

            if (i % 2 == 0)
              vec.push_back(0);

            break;
          }
          else
            curLen += tmpV[i++];
        }

        int periods = std::max(int((256 - 4) / length), 1);
        m_pat.reserve(periods * vec.size());
        for (int i = 0; i < periods; ++i)
          std::copy(vec.begin(), vec.end(), std::back_inserter(m_pat));
      }
    }
  }
};

}