170 lines
5.3 KiB
C
170 lines
5.3 KiB
C
|
/*
|
||
|
* 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_
|