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: cfeb6d2f5fbddf22e0b74e1653869985cace0a40 (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 "std/list.hpp"
#include "std/map.hpp"
#include "std/function.hpp"
#include "std/queue.hpp"


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:

    typedef function<void()> overflowFn;

    typedef priority_queue<pair<size_t, overflowFn>, vector<pair<size_t, overflowFn> >, first_less<pair<size_t, overflowFn> > > overflowFns;

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

  private:

    unsigned m_currentX;
    unsigned m_currentY;
    unsigned m_yStep;

    unsigned m_width;
    unsigned m_height;

    overflowFns m_overflowFns;

    handle_t m_currentHandle;

    typedef map<handle_t, m2::RectU> rects_t;

    rects_t m_rects;

    void callOverflowFns();

    uint32_t m_maxHandle;
    uint32_t m_invalidHandle;

  public:

    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;
  };
}