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

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

#include "software_renderer/path_info.hpp"
#include "software_renderer/area_info.hpp"
#include "software_renderer/frame_image.hpp"
#include "software_renderer/text_engine.h"
#include "software_renderer/glyph_cache.hpp"
#include "software_renderer/icon_info.hpp"
#include "software_renderer/circle_info.hpp"
#include "software_renderer/pen_info.hpp"
#include "software_renderer/brush_info.hpp"

#include "drape/drape_global.hpp"

#include "geometry/point2d.hpp"

#include "base/string_utils.hpp"

#include "3party/agg/agg_rendering_buffer.h"
#include "3party/agg/agg_pixfmt_rgba.h"
#include "3party/agg/agg_renderer_scanline.h"
#include "3party/agg/agg_renderer_primitives.h"
#include "3party/agg/agg_path_storage.h"

#include <cstdint>
#include <map>
#include <memory>
#include <vector>

namespace software_renderer
{
class PathWrapper;

class SoftwareRenderer
{
public:
  SoftwareRenderer(GlyphCache::Params const & glyphCacheParams, std::string const & resourcesPostfix);

  void BeginFrame(uint32_t width, uint32_t height, dp::Color const & bgColor);

  void DrawSymbol(m2::PointD const & pt, dp::Anchor anchor, IconInfo const & info);
  void DrawCircle(m2::PointD const & pt, dp::Anchor anchor, CircleInfo const & info);
  void DrawPath(PathInfo const & geometry, PenInfo const & info);
  void DrawPath(PathWrapper & path, math::Matrix<double, 3, 3> const & m);
  void DrawArea(AreaInfo const & geometry, BrushInfo const & info);
  void DrawText(m2::PointD const & pt, dp::Anchor anchor,
                dp::FontDecl const & primFont, strings::UniString const & primText);
  void DrawText(m2::PointD const & pt, dp::Anchor anchor,
                dp::FontDecl const & primFont, dp::FontDecl const & secFont,
                strings::UniString const & primText, strings::UniString const & secText);
  void DrawPathText(PathInfo const & geometry, dp::FontDecl const & font,
                    strings::UniString const & text);

  void CalculateSymbolMetric(m2::PointD const & pt, dp::Anchor anchor,
                             IconInfo const & info, m2::RectD & rect);

  void CalculateCircleMetric(m2::PointD const & pt, dp::Anchor anchor,
                             CircleInfo const & info, m2::RectD & rect);

  void CalculateTextMetric(m2::PointD const & pt, dp::Anchor anchor,
                           dp::FontDecl const & font, strings::UniString const & text,
                           m2::RectD & result);
  /// Result must be bound box contains both texts
  void CalculateTextMetric(m2::PointD const & pt, dp::Anchor anchor,
                           dp::FontDecl const & primFont, dp::FontDecl const & secFont,
                           strings::UniString const & primText, strings::UniString const & secText,
                           m2::RectD & result);
  /// rects - rect for each glyph
  void CalculateTextMetric(PathInfo const & geometry, dp::FontDecl const & font,
                           strings::UniString const & text,
                           std::vector<m2::RectD> & rects);

  void EndFrame(FrameImage & image);
  m2::RectD FrameRect() const;

  GlyphCache * GetGlyphCache() const { return m_glyphCache.get(); }

private:
  template <class TColor, class TOrder>
  struct TBlendAdaptor
  {
    using order_type = TOrder;
    using color_type = TColor;
    using TValueType = typename color_type::value_type;
    using TCalcType = typename color_type::calc_type;

    enum EBaseScale
    {
      SCALE_SHIFT = color_type::base_shift,
      SCALE_MASK = color_type::base_mask
    };

    static AGG_INLINE void blend_pix(unsigned op, TValueType * p, unsigned cr, unsigned cg,
                                     unsigned cb, unsigned ca, unsigned cover)
    {
      using TBlendTable = agg::comp_op_table_rgba<TColor, TOrder>;
      if (p[TOrder::A])
      {
        TBlendTable::g_comp_op_func[op](p, (cr * ca + SCALE_MASK) >> SCALE_SHIFT, (cg * ca + SCALE_MASK) >> SCALE_SHIFT,
                                        (cb * ca + SCALE_MASK) >> SCALE_SHIFT, ca, cover);
      }
      else
        TBlendTable::g_comp_op_func[op](p, cr, cg, cb, ca, cover);
    }
  };

public:
  using TBlender = TBlendAdaptor<agg::rgba8, agg::order_rgba>;
  using TPixelFormat = agg::pixfmt_custom_blend_rgba<TBlender, agg::rendering_buffer>;

  using TBaseRenderer = agg::renderer_base<TPixelFormat>;
  using TPrimitivesRenderer = agg::renderer_primitives<TBaseRenderer>;
  using TSolidRenderer = agg::renderer_scanline_aa_solid<TBaseRenderer>;

private:
  std::unique_ptr<GlyphCache> m_glyphCache;
  std::map<string, m2::RectU> m_symbolsIndex;
  std::vector<uint8_t> m_symbolsSkin;
  uint32_t m_skinWidth, m_skinHeight;

  std::vector<unsigned char> m_frameBuffer;
  uint32_t m_frameWidth, m_frameHeight;

  agg::rendering_buffer m_renderBuffer;
  TPixelFormat m_pixelFormat;
  TBaseRenderer m_baseRenderer;

  TSolidRenderer m_solidRenderer;

  ml::text_engine m_textEngine;
};

struct PathParams
{
  agg::rgba8 m_fillColor;
  agg::rgba8 m_strokeColor;
  bool m_isFill;
  bool m_isStroke;
  bool m_isEventOdd;
  double m_strokeWidth;

  PathParams()
    : m_fillColor(agg::rgba(0, 0, 0))
    , m_strokeColor(agg::rgba(0, 0, 0))
    , m_isFill(false)
    , m_isStroke(false)
    , m_isEventOdd(false)
    , m_strokeWidth(1.0)
  {
  }
};

class PathWrapper
{
public:
  void AddParams(PathParams const & params);
  void MoveTo(m2::PointD const & pt);
  void LineTo(m2::PointD const & pt);
  void CurveTo(m2::PointD const & pt1,
               m2::PointD const & pt2,
                m2::PointD const & ptTo);
  void ClosePath();
  void BoundingRect(m2::RectD & rect);

  void Render(SoftwareRenderer::TSolidRenderer & renderer,
              agg::trans_affine const & mtx,
              m2::RectD const & clipBox);

private:
  agg::path_storage  m_storage;
  std::vector<PathParams> m_params;
};
}  // namespace software_renderer