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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
#define MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
#include <stdint.h>
#include <map>
#include <vector>
#include "modules/desktop_capture/desktop_geometry.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// DesktopRegion represents a region of the screen or window.
//
// Internally each region is stored as a set of rows where each row contains one
// or more rectangles aligned vertically.
class RTC_EXPORT DesktopRegion {
private:
// The following private types need to be declared first because they are used
// in the public Iterator.
// RowSpan represents a horizontal span withing a single row.
struct RowSpan {
RowSpan(int32_t left, int32_t right);
// Used by std::vector<>.
bool operator==(const RowSpan& that) const {
return left == that.left && right == that.right;
}
int32_t left;
int32_t right;
};
typedef std::vector<RowSpan> RowSpanSet;
// Row represents a single row of a region. A row is set of rectangles that
// have the same vertical position.
struct Row {
Row(const Row&);
Row(Row&&);
Row(int32_t top, int32_t bottom);
~Row();
int32_t top;
int32_t bottom;
RowSpanSet spans;
};
// Type used to store list of rows in the region. The bottom position of row
// is used as the key so that rows are always ordered by their position. The
// map stores pointers to make Translate() more efficient.
typedef std::map<int, Row*> Rows;
public:
// Iterator that can be used to iterate over rectangles of a DesktopRegion.
// The region must not be mutated while the iterator is used.
class RTC_EXPORT Iterator {
public:
explicit Iterator(const DesktopRegion& target);
~Iterator();
bool IsAtEnd() const;
void Advance();
const DesktopRect& rect() const { return rect_; }
private:
const DesktopRegion& region_;
// Updates `rect_` based on the current `row_` and `row_span_`. If
// `row_span_` matches spans on consecutive rows then they are also merged
// into `rect_`, to generate more efficient output.
void UpdateCurrentRect();
Rows::const_iterator row_;
Rows::const_iterator previous_row_;
RowSpanSet::const_iterator row_span_;
DesktopRect rect_;
};
DesktopRegion();
explicit DesktopRegion(const DesktopRect& rect);
DesktopRegion(const DesktopRect* rects, int count);
DesktopRegion(const DesktopRegion& other);
~DesktopRegion();
DesktopRegion& operator=(const DesktopRegion& other);
bool is_empty() const { return rows_.empty(); }
bool Equals(const DesktopRegion& region) const;
// Reset the region to be empty.
void Clear();
// Reset region to contain just `rect`.
void SetRect(const DesktopRect& rect);
// Adds specified rect(s) or region to the region.
void AddRect(const DesktopRect& rect);
void AddRects(const DesktopRect* rects, int count);
void AddRegion(const DesktopRegion& region);
// Finds intersection of two regions and stores them in the current region.
void Intersect(const DesktopRegion& region1, const DesktopRegion& region2);
// Same as above but intersects content of the current region with `region`.
void IntersectWith(const DesktopRegion& region);
// Clips the region by the `rect`.
void IntersectWith(const DesktopRect& rect);
// Subtracts `region` from the current content of the region.
void Subtract(const DesktopRegion& region);
// Subtracts `rect` from the current content of the region.
void Subtract(const DesktopRect& rect);
// Adds (dx, dy) to the position of the region.
void Translate(int32_t dx, int32_t dy);
void Swap(DesktopRegion* region);
private:
// Comparison functions used for std::lower_bound(). Compare left or right
// edges withs a given `value`.
static bool CompareSpanLeft(const RowSpan& r, int32_t value);
static bool CompareSpanRight(const RowSpan& r, int32_t value);
// Adds a new span to the row, coalescing spans if necessary.
static void AddSpanToRow(Row* row, int32_t left, int32_t right);
// Returns true if the `span` exists in the given `row`.
static bool IsSpanInRow(const Row& row, const RowSpan& rect);
// Calculates the intersection of two sets of spans.
static void IntersectRows(const RowSpanSet& set1,
const RowSpanSet& set2,
RowSpanSet* output);
static void SubtractRows(const RowSpanSet& set_a,
const RowSpanSet& set_b,
RowSpanSet* output);
// Merges `row` with the row above it if they contain the same spans. Doesn't
// do anything if called with `row` set to rows_.begin() (i.e. first row of
// the region). If the rows were merged `row` remains a valid iterator to the
// merged row.
void MergeWithPrecedingRow(Rows::iterator row);
Rows rows_;
};
} // namespace webrtc
#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
|