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

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

#include "geometry/rect2d.hpp"

#include <cstdint>
#include <functional>
#include <list>
#include <map>
#include <queue>
#include <utility>
#include <vector>

namespace m2
{
template <typename pair_t>
struct first_less
{
  bool operator()(pair_t const & first, pair_t const & second)
  {
    return first.first < second.first;
  }
};

/// The simplest row-by-row packer.
/// When there is no free room all the packing
/// rect is cleared and the process is started again.
class Packer
{
public:
  using overflowFn = std::function<void()>;

  using overflowFns =
      std::priority_queue<std::pair<size_t, overflowFn>, std::vector<std::pair<size_t, overflowFn>>,
                          first_less<std::pair<size_t, overflowFn>>>;

  using handle_t = uint32_t;
  using find_result_t = std::pair<bool, m2::RectU>;

  Packer();

  /// create a packer on a rectangular area of (0, 0, width, height) dimensions
  Packer(unsigned width, unsigned height, uint32_t maxHandle = 0xFFFF - 1);

  /// reset the state of the packer
  void reset();

  /// add overflow handler.
  /// @param priority handlers with higher priority value are called first.
  void addOverflowFn(overflowFn fn, int priority);

  /// pack the rect with dimensions width X height on a free area.
  /// when there is no free area - find it somehow(depending on a packer implementation,
  /// the simplest one will just clear the whole rect and start the packing process again).
  handle_t pack(unsigned width, unsigned height);

  /// return free handle
  handle_t freeHandle();

  /// Does we have room to pack another rectangle?
  bool hasRoom(unsigned width, unsigned height) const;

  /// Does we have room to pack a sequence of rectangles?
  bool hasRoom(m2::PointU const * sizes, size_t cnt) const;

  /// is the handle present on the texture.
  bool isPacked(handle_t handle);

  /// find the packed area by the handle.
  find_result_t find(handle_t handle) const;

  /// remove the handle from the list of active handles.
  void remove(handle_t handle);

  /// get an invalid handle
  uint32_t invalidHandle() const;

private:
  using rects_t = std::map<handle_t, m2::RectU>;

  void callOverflowFns();

  unsigned m_currentX;
  unsigned m_currentY;
  unsigned m_yStep;

  unsigned m_width;
  unsigned m_height;

  overflowFns m_overflowFns;

  handle_t m_currentHandle;

  rects_t m_rects;

  uint32_t m_maxHandle;
  uint32_t m_invalidHandle;
};
}  // namespace m2