2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
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.
11 #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
12 #define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
17 #include "webrtc/base/constructormagic.h"
18 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
19 #include "webrtc/typedefs.h"
23 // DesktopRegion represents a region of the screen or window.
25 // Internally each region is stored as a set of rows where each row contains one
26 // or more rectangles aligned vertically.
29 // The following private types need to be declared first because they are used
30 // in the public Iterator.
32 // RowSpan represents a horizontal span withing a single row.
34 RowSpan(int32_t left, int32_t right);
36 // Used by std::vector<>.
37 bool operator==(const RowSpan& that) const {
38 return left == that.left && right == that.right;
45 typedef std::vector<RowSpan> RowSpanSet;
47 // Row represents a single row of a region. A row is set of rectangles that
48 // have the same vertical position.
50 Row(int32_t top, int32_t bottom);
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;
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.
69 explicit Iterator(const DesktopRegion& target);
74 const DesktopRect& rect() const { return rect_; }
77 const DesktopRegion& region_;
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();
84 Rows::const_iterator row_;
85 Rows::const_iterator previous_row_;
86 RowSpanSet::const_iterator row_span_;
91 explicit DesktopRegion(const DesktopRect& rect);
92 DesktopRegion(const DesktopRect* rects, int count);
93 DesktopRegion(const DesktopRegion& other);
96 DesktopRegion& operator=(const DesktopRegion& other);
98 bool is_empty() const { return rows_.empty(); }
100 bool Equals(const DesktopRegion& region) const;
102 // Reset the region to be empty.
105 // Reset region to contain just |rect|.
106 void SetRect(const DesktopRect& rect);
108 // Adds specified rect(s) or region to the region.
109 void AddRect(const DesktopRect& rect);
110 void AddRects(const DesktopRect* rects, int count);
111 void AddRegion(const DesktopRegion& region);
113 // Finds intersection of two regions and stores them in the current region.
114 void Intersect(const DesktopRegion& region1, const DesktopRegion& region2);
116 // Same as above but intersects content of the current region with |region|.
117 void IntersectWith(const DesktopRegion& region);
119 // Clips the region by the |rect|.
120 void IntersectWith(const DesktopRect& rect);
122 // Subtracts |region| from the current content of the region.
123 void Subtract(const DesktopRegion& region);
125 // Subtracts |rect| from the current content of the region.
126 void Subtract(const DesktopRect& rect);
128 // Adds (dx, dy) to the position of the region.
129 void Translate(int32_t dx, int32_t dy);
131 void Swap(DesktopRegion* region);
134 // 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);
139 // Adds a new span to the row, coalescing spans if necessary.
140 static void AddSpanToRow(Row* row, int32_t left, int32_t right);
142 // Returns true if the |span| exists in the given |row|.
143 static bool IsSpanInRow(const Row& row, const RowSpan& rect);
145 // Calculates the intersection of two sets of spans.
146 static void IntersectRows(const RowSpanSet& set1,
147 const RowSpanSet& set2,
150 static void SubtractRows(const RowSpanSet& set_a,
151 const RowSpanSet& set_b,
154 // 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
158 void MergeWithPrecedingRow(Rows::iterator row);
163 } // namespace webrtc
165 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_