desktop_region.h 5.3 KB

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