blob: fc7c6ed9e2d8e2c4f7c1d67338e46caa11319f0f [file] [log] [blame]
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
12#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
13
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000014#include <map>
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000015#include <vector>
16
17#include "webrtc/modules/desktop_capture/desktop_geometry.h"
18#include "webrtc/system_wrappers/interface/constructor_magic.h"
19#include "webrtc/typedefs.h"
20
21namespace webrtc {
22
23// DesktopRegion represents a region of the screen or window.
24//
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000025// Internally each region is stored as a set of rows where each row contains one
26// or more rectangles aligned vertically.
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000027class DesktopRegion {
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000028 private:
29 // The following private types need to be declared first because they are used
30 // in the public Iterator.
31
32 // RowSpan represents a horizontal span withing a single row.
33 struct RowSpan {
34 RowSpan(int32_t left, int32_t right);
35
36 // Used by std::vector<>.
37 bool operator==(const RowSpan& that) const {
38 return left == that.left && right == that.right;
39 }
40
41 int32_t left;
42 int32_t right;
43 };
44
45 typedef std::vector<RowSpan> RowSpanSet;
46
47 // Row represents a single row of a region. A row is set of rectangles that
48 // have the same vertical position.
49 struct Row {
50 Row(int32_t top, int32_t bottom);
pbos@webrtc.org10b36642013-07-31 15:32:43 +000051 ~Row();
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000052
53 int32_t top;
54 int32_t bottom;
55
56 RowSpanSet spans;
57 };
58
59 // Type used to store list of rows in the region. The bottom position of row
60 // is used as the key so that rows are always ordered by their position. The
61 // map stores pointers to make Translate() more efficient.
62 typedef std::map<int, Row*> Rows;
63
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000064 public:
65 // Iterator that can be used to iterate over rectangles of a DesktopRegion.
66 // The region must not be mutated while the iterator is used.
67 class Iterator {
68 public:
69 explicit Iterator(const DesktopRegion& target);
70
71 bool IsAtEnd() const;
72 void Advance();
73
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000074 const DesktopRect& rect() const { return rect_; }
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000075
76 private:
77 const DesktopRegion& region_;
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000078
79 // Updates |rect_| based on the current |row_| and |row_span_|. If
80 // |row_span_| matches spans on consecutive rows then they are also merged
81 // into |rect_|, to generate more efficient output.
82 void UpdateCurrentRect();
83
84 Rows::const_iterator row_;
85 Rows::const_iterator previous_row_;
86 RowSpanSet::const_iterator row_span_;
87 DesktopRect rect_;
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000088 };
89
90 DesktopRegion();
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000091 explicit DesktopRegion(const DesktopRect& rect);
92 DesktopRegion(const DesktopRect* rects, int count);
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000093 DesktopRegion(const DesktopRegion& other);
94 ~DesktopRegion();
95
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000096 DesktopRegion& operator=(const DesktopRegion& other);
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +000097
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +000098 bool is_empty() const { return rows_.empty(); }
99
100 bool Equals(const DesktopRegion& region) const;
101
102 // Reset the region to be empty.
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000103 void Clear();
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000104
105 // Reset region to contain just |rect|.
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000106 void SetRect(const DesktopRect& rect);
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000107
108 // Adds specified rect(s) or region to the region.
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000109 void AddRect(const DesktopRect& rect);
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000110 void AddRects(const DesktopRect* rects, int count);
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000111 void AddRegion(const DesktopRegion& region);
112
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000113 // Finds intersection of two regions and stores them in the current region.
114 void Intersect(const DesktopRegion& region1, const DesktopRegion& region2);
115
116 // Same as above but intersects content of the current region with |region|.
117 void IntersectWith(const DesktopRegion& region);
118
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000119 // Clips the region by the |rect|.
120 void IntersectWith(const DesktopRect& rect);
121
sergeyu@chromium.org26251da2013-09-13 19:53:16 +0000122 // Subtracts |region| from the current content of the region.
123 void Subtract(const DesktopRegion& region);
124
125 // Subtracts |rect| from the current content of the region.
126 void Subtract(const DesktopRect& rect);
127
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000128 // Adds (dx, dy) to the position of the region.
129 void Translate(int32_t dx, int32_t dy);
130
131 void Swap(DesktopRegion* region);
132
133 private:
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000134 // Comparison functions used for std::lower_bound(). Compare left or right
135 // edges withs a given |value|.
136 static bool CompareSpanLeft(const RowSpan& r, int32_t value);
137 static bool CompareSpanRight(const RowSpan& r, int32_t value);
138
139 // Adds a new span to the row, coalescing spans if necessary.
140 static void AddSpanToRow(Row* row, int32_t left, int32_t right);
141
142 // Returns true if the |span| exists in the given |row|.
143 static bool IsSpanInRow(const Row& row, const RowSpan& rect);
144
145 // Calculates the intersection of two sets of spans.
146 static void IntersectRows(const RowSpanSet& set1,
147 const RowSpanSet& set2,
148 RowSpanSet* output);
149
sergeyu@chromium.org26251da2013-09-13 19:53:16 +0000150 static void SubtractRows(const RowSpanSet& set_a,
151 const RowSpanSet& set_b,
152 RowSpanSet* output);
153
sergeyu@chromium.orgaec1bc82013-06-04 00:38:39 +0000154 // Merges |row| with the row above it if they contain the same spans. Doesn't
155 // do anything if called with |row| set to rows_.begin() (i.e. first row of
156 // the region). If the rows were merged |row| remains a valid iterator to the
157 // merged row.
158 void MergeWithPrecedingRow(Rows::iterator row);
159
160 Rows rows_;
sergeyu@chromium.org85a1dab2013-04-29 20:10:57 +0000161};
162
163} // namespace webrtc
164
165#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
166