1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ 12*d9f75844SAndroid Build Coastguard Worker #define MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <map> 17*d9f75844SAndroid Build Coastguard Worker #include <vector> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "modules/desktop_capture/desktop_geometry.h" 20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker // DesktopRegion represents a region of the screen or window. 25*d9f75844SAndroid Build Coastguard Worker // 26*d9f75844SAndroid Build Coastguard Worker // Internally each region is stored as a set of rows where each row contains one 27*d9f75844SAndroid Build Coastguard Worker // or more rectangles aligned vertically. 28*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT DesktopRegion { 29*d9f75844SAndroid Build Coastguard Worker private: 30*d9f75844SAndroid Build Coastguard Worker // The following private types need to be declared first because they are used 31*d9f75844SAndroid Build Coastguard Worker // in the public Iterator. 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker // RowSpan represents a horizontal span withing a single row. 34*d9f75844SAndroid Build Coastguard Worker struct RowSpan { 35*d9f75844SAndroid Build Coastguard Worker RowSpan(int32_t left, int32_t right); 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker // Used by std::vector<>. 38*d9f75844SAndroid Build Coastguard Worker bool operator==(const RowSpan& that) const { 39*d9f75844SAndroid Build Coastguard Worker return left == that.left && right == that.right; 40*d9f75844SAndroid Build Coastguard Worker } 41*d9f75844SAndroid Build Coastguard Worker 42*d9f75844SAndroid Build Coastguard Worker int32_t left; 43*d9f75844SAndroid Build Coastguard Worker int32_t right; 44*d9f75844SAndroid Build Coastguard Worker }; 45*d9f75844SAndroid Build Coastguard Worker 46*d9f75844SAndroid Build Coastguard Worker typedef std::vector<RowSpan> RowSpanSet; 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker // Row represents a single row of a region. A row is set of rectangles that 49*d9f75844SAndroid Build Coastguard Worker // have the same vertical position. 50*d9f75844SAndroid Build Coastguard Worker struct Row { 51*d9f75844SAndroid Build Coastguard Worker Row(const Row&); 52*d9f75844SAndroid Build Coastguard Worker Row(Row&&); 53*d9f75844SAndroid Build Coastguard Worker Row(int32_t top, int32_t bottom); 54*d9f75844SAndroid Build Coastguard Worker ~Row(); 55*d9f75844SAndroid Build Coastguard Worker 56*d9f75844SAndroid Build Coastguard Worker int32_t top; 57*d9f75844SAndroid Build Coastguard Worker int32_t bottom; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker RowSpanSet spans; 60*d9f75844SAndroid Build Coastguard Worker }; 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Worker // Type used to store list of rows in the region. The bottom position of row 63*d9f75844SAndroid Build Coastguard Worker // is used as the key so that rows are always ordered by their position. The 64*d9f75844SAndroid Build Coastguard Worker // map stores pointers to make Translate() more efficient. 65*d9f75844SAndroid Build Coastguard Worker typedef std::map<int, Row*> Rows; 66*d9f75844SAndroid Build Coastguard Worker 67*d9f75844SAndroid Build Coastguard Worker public: 68*d9f75844SAndroid Build Coastguard Worker // Iterator that can be used to iterate over rectangles of a DesktopRegion. 69*d9f75844SAndroid Build Coastguard Worker // The region must not be mutated while the iterator is used. 70*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT Iterator { 71*d9f75844SAndroid Build Coastguard Worker public: 72*d9f75844SAndroid Build Coastguard Worker explicit Iterator(const DesktopRegion& target); 73*d9f75844SAndroid Build Coastguard Worker ~Iterator(); 74*d9f75844SAndroid Build Coastguard Worker 75*d9f75844SAndroid Build Coastguard Worker bool IsAtEnd() const; 76*d9f75844SAndroid Build Coastguard Worker void Advance(); 77*d9f75844SAndroid Build Coastguard Worker rect()78*d9f75844SAndroid Build Coastguard Worker const DesktopRect& rect() const { return rect_; } 79*d9f75844SAndroid Build Coastguard Worker 80*d9f75844SAndroid Build Coastguard Worker private: 81*d9f75844SAndroid Build Coastguard Worker const DesktopRegion& region_; 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard Worker // Updates `rect_` based on the current `row_` and `row_span_`. If 84*d9f75844SAndroid Build Coastguard Worker // `row_span_` matches spans on consecutive rows then they are also merged 85*d9f75844SAndroid Build Coastguard Worker // into `rect_`, to generate more efficient output. 86*d9f75844SAndroid Build Coastguard Worker void UpdateCurrentRect(); 87*d9f75844SAndroid Build Coastguard Worker 88*d9f75844SAndroid Build Coastguard Worker Rows::const_iterator row_; 89*d9f75844SAndroid Build Coastguard Worker Rows::const_iterator previous_row_; 90*d9f75844SAndroid Build Coastguard Worker RowSpanSet::const_iterator row_span_; 91*d9f75844SAndroid Build Coastguard Worker DesktopRect rect_; 92*d9f75844SAndroid Build Coastguard Worker }; 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker DesktopRegion(); 95*d9f75844SAndroid Build Coastguard Worker explicit DesktopRegion(const DesktopRect& rect); 96*d9f75844SAndroid Build Coastguard Worker DesktopRegion(const DesktopRect* rects, int count); 97*d9f75844SAndroid Build Coastguard Worker DesktopRegion(const DesktopRegion& other); 98*d9f75844SAndroid Build Coastguard Worker ~DesktopRegion(); 99*d9f75844SAndroid Build Coastguard Worker 100*d9f75844SAndroid Build Coastguard Worker DesktopRegion& operator=(const DesktopRegion& other); 101*d9f75844SAndroid Build Coastguard Worker is_empty()102*d9f75844SAndroid Build Coastguard Worker bool is_empty() const { return rows_.empty(); } 103*d9f75844SAndroid Build Coastguard Worker 104*d9f75844SAndroid Build Coastguard Worker bool Equals(const DesktopRegion& region) const; 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker // Reset the region to be empty. 107*d9f75844SAndroid Build Coastguard Worker void Clear(); 108*d9f75844SAndroid Build Coastguard Worker 109*d9f75844SAndroid Build Coastguard Worker // Reset region to contain just `rect`. 110*d9f75844SAndroid Build Coastguard Worker void SetRect(const DesktopRect& rect); 111*d9f75844SAndroid Build Coastguard Worker 112*d9f75844SAndroid Build Coastguard Worker // Adds specified rect(s) or region to the region. 113*d9f75844SAndroid Build Coastguard Worker void AddRect(const DesktopRect& rect); 114*d9f75844SAndroid Build Coastguard Worker void AddRects(const DesktopRect* rects, int count); 115*d9f75844SAndroid Build Coastguard Worker void AddRegion(const DesktopRegion& region); 116*d9f75844SAndroid Build Coastguard Worker 117*d9f75844SAndroid Build Coastguard Worker // Finds intersection of two regions and stores them in the current region. 118*d9f75844SAndroid Build Coastguard Worker void Intersect(const DesktopRegion& region1, const DesktopRegion& region2); 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker // Same as above but intersects content of the current region with `region`. 121*d9f75844SAndroid Build Coastguard Worker void IntersectWith(const DesktopRegion& region); 122*d9f75844SAndroid Build Coastguard Worker 123*d9f75844SAndroid Build Coastguard Worker // Clips the region by the `rect`. 124*d9f75844SAndroid Build Coastguard Worker void IntersectWith(const DesktopRect& rect); 125*d9f75844SAndroid Build Coastguard Worker 126*d9f75844SAndroid Build Coastguard Worker // Subtracts `region` from the current content of the region. 127*d9f75844SAndroid Build Coastguard Worker void Subtract(const DesktopRegion& region); 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker // Subtracts `rect` from the current content of the region. 130*d9f75844SAndroid Build Coastguard Worker void Subtract(const DesktopRect& rect); 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Worker // Adds (dx, dy) to the position of the region. 133*d9f75844SAndroid Build Coastguard Worker void Translate(int32_t dx, int32_t dy); 134*d9f75844SAndroid Build Coastguard Worker 135*d9f75844SAndroid Build Coastguard Worker void Swap(DesktopRegion* region); 136*d9f75844SAndroid Build Coastguard Worker 137*d9f75844SAndroid Build Coastguard Worker private: 138*d9f75844SAndroid Build Coastguard Worker // Comparison functions used for std::lower_bound(). Compare left or right 139*d9f75844SAndroid Build Coastguard Worker // edges withs a given `value`. 140*d9f75844SAndroid Build Coastguard Worker static bool CompareSpanLeft(const RowSpan& r, int32_t value); 141*d9f75844SAndroid Build Coastguard Worker static bool CompareSpanRight(const RowSpan& r, int32_t value); 142*d9f75844SAndroid Build Coastguard Worker 143*d9f75844SAndroid Build Coastguard Worker // Adds a new span to the row, coalescing spans if necessary. 144*d9f75844SAndroid Build Coastguard Worker static void AddSpanToRow(Row* row, int32_t left, int32_t right); 145*d9f75844SAndroid Build Coastguard Worker 146*d9f75844SAndroid Build Coastguard Worker // Returns true if the `span` exists in the given `row`. 147*d9f75844SAndroid Build Coastguard Worker static bool IsSpanInRow(const Row& row, const RowSpan& rect); 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker // Calculates the intersection of two sets of spans. 150*d9f75844SAndroid Build Coastguard Worker static void IntersectRows(const RowSpanSet& set1, 151*d9f75844SAndroid Build Coastguard Worker const RowSpanSet& set2, 152*d9f75844SAndroid Build Coastguard Worker RowSpanSet* output); 153*d9f75844SAndroid Build Coastguard Worker 154*d9f75844SAndroid Build Coastguard Worker static void SubtractRows(const RowSpanSet& set_a, 155*d9f75844SAndroid Build Coastguard Worker const RowSpanSet& set_b, 156*d9f75844SAndroid Build Coastguard Worker RowSpanSet* output); 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker // Merges `row` with the row above it if they contain the same spans. Doesn't 159*d9f75844SAndroid Build Coastguard Worker // do anything if called with `row` set to rows_.begin() (i.e. first row of 160*d9f75844SAndroid Build Coastguard Worker // the region). If the rows were merged `row` remains a valid iterator to the 161*d9f75844SAndroid Build Coastguard Worker // merged row. 162*d9f75844SAndroid Build Coastguard Worker void MergeWithPrecedingRow(Rows::iterator row); 163*d9f75844SAndroid Build Coastguard Worker 164*d9f75844SAndroid Build Coastguard Worker Rows rows_; 165*d9f75844SAndroid Build Coastguard Worker }; 166*d9f75844SAndroid Build Coastguard Worker 167*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 168*d9f75844SAndroid Build Coastguard Worker 169*d9f75844SAndroid Build Coastguard Worker #endif // MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ 170