Line data Source code
1 : /*
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 :
14 : #include <map>
15 : #include <vector>
16 :
17 : #include "webrtc/base/constructormagic.h"
18 : #include "webrtc/modules/desktop_capture/desktop_geometry.h"
19 : #include "webrtc/typedefs.h"
20 :
21 : namespace webrtc {
22 :
23 : // DesktopRegion represents a region of the screen or window.
24 : //
25 : // Internally each region is stored as a set of rows where each row contains one
26 : // or more rectangles aligned vertically.
27 : class DesktopRegion {
28 : 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 0 : bool operator==(const RowSpan& that) const {
38 0 : 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 0 : struct Row {
50 : Row(const Row&);
51 : Row(Row&&);
52 : Row(int32_t top, int32_t bottom);
53 : ~Row();
54 :
55 : int32_t top;
56 : int32_t bottom;
57 :
58 : RowSpanSet spans;
59 : };
60 :
61 : // Type used to store list of rows in the region. The bottom position of row
62 : // is used as the key so that rows are always ordered by their position. The
63 : // map stores pointers to make Translate() more efficient.
64 : typedef std::map<int, Row*> Rows;
65 :
66 : public:
67 : // Iterator that can be used to iterate over rectangles of a DesktopRegion.
68 : // The region must not be mutated while the iterator is used.
69 : class Iterator {
70 : public:
71 : explicit Iterator(const DesktopRegion& target);
72 : ~Iterator();
73 :
74 : bool IsAtEnd() const;
75 : void Advance();
76 :
77 0 : const DesktopRect& rect() const { return rect_; }
78 :
79 : private:
80 : const DesktopRegion& region_;
81 :
82 : // Updates |rect_| based on the current |row_| and |row_span_|. If
83 : // |row_span_| matches spans on consecutive rows then they are also merged
84 : // into |rect_|, to generate more efficient output.
85 : void UpdateCurrentRect();
86 :
87 : Rows::const_iterator row_;
88 : Rows::const_iterator previous_row_;
89 : RowSpanSet::const_iterator row_span_;
90 : DesktopRect rect_;
91 : };
92 :
93 : DesktopRegion();
94 : explicit DesktopRegion(const DesktopRect& rect);
95 : DesktopRegion(const DesktopRect* rects, int count);
96 : DesktopRegion(const DesktopRegion& other);
97 : ~DesktopRegion();
98 :
99 : DesktopRegion& operator=(const DesktopRegion& other);
100 :
101 : bool is_empty() const { return rows_.empty(); }
102 :
103 : bool Equals(const DesktopRegion& region) const;
104 :
105 : // Reset the region to be empty.
106 : void Clear();
107 :
108 : // Reset region to contain just |rect|.
109 : void SetRect(const DesktopRect& rect);
110 :
111 : // Adds specified rect(s) or region to the region.
112 : void AddRect(const DesktopRect& rect);
113 : void AddRects(const DesktopRect* rects, int count);
114 : void AddRegion(const DesktopRegion& region);
115 :
116 : // Finds intersection of two regions and stores them in the current region.
117 : void Intersect(const DesktopRegion& region1, const DesktopRegion& region2);
118 :
119 : // Same as above but intersects content of the current region with |region|.
120 : void IntersectWith(const DesktopRegion& region);
121 :
122 : // Clips the region by the |rect|.
123 : void IntersectWith(const DesktopRect& rect);
124 :
125 : // Subtracts |region| from the current content of the region.
126 : void Subtract(const DesktopRegion& region);
127 :
128 : // Subtracts |rect| from the current content of the region.
129 : void Subtract(const DesktopRect& rect);
130 :
131 : // Adds (dx, dy) to the position of the region.
132 : void Translate(int32_t dx, int32_t dy);
133 :
134 : void Swap(DesktopRegion* region);
135 :
136 : private:
137 : // Comparison functions used for std::lower_bound(). Compare left or right
138 : // edges withs a given |value|.
139 : static bool CompareSpanLeft(const RowSpan& r, int32_t value);
140 : static bool CompareSpanRight(const RowSpan& r, int32_t value);
141 :
142 : // Adds a new span to the row, coalescing spans if necessary.
143 : static void AddSpanToRow(Row* row, int32_t left, int32_t right);
144 :
145 : // Returns true if the |span| exists in the given |row|.
146 : static bool IsSpanInRow(const Row& row, const RowSpan& rect);
147 :
148 : // Calculates the intersection of two sets of spans.
149 : static void IntersectRows(const RowSpanSet& set1,
150 : const RowSpanSet& set2,
151 : RowSpanSet* output);
152 :
153 : static void SubtractRows(const RowSpanSet& set_a,
154 : const RowSpanSet& set_b,
155 : RowSpanSet* output);
156 :
157 : // Merges |row| with the row above it if they contain the same spans. Doesn't
158 : // do anything if called with |row| set to rows_.begin() (i.e. first row of
159 : // the region). If the rows were merged |row| remains a valid iterator to the
160 : // merged row.
161 : void MergeWithPrecedingRow(Rows::iterator row);
162 :
163 : Rows rows_;
164 : };
165 :
166 : } // namespace webrtc
167 :
168 : #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
169 :
|