mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

Bug: webrtc:12338 Change-Id: I300ba78fc4423db7030e555d7e51d2cb2246e9a4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227162 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34678}
169 lines
5.3 KiB
C++
169 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_
|