roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
raw_streamable_overlay.h
Go to the documentation of this file.
1#pragma once
2
5
6namespace roo_display {
7
8namespace internal {
9
10// Expands the 'rectangle size' of the specified stream, generating
11// empty (fully transparent) pixels in the extended area surrounding the
12// specified stream.
13template <typename RawPixelStream>
15 public:
16 // width: the width of the surrounding rectangle
17 // inner: the bounding box of the delegate stream in the surrounding rectangle
18 SuperRectangleStream(std::unique_ptr<RawPixelStream> delegate, int16_t width,
19 const Box &inner)
20 : delegate_(std::move(delegate)),
21 count_(0),
22 skip_(inner.xMin() + (int32_t)width * inner.yMin()),
23 remaining_lines_(
24 inner.empty() || inner.width() == width ? 0 : inner.height() - 1),
25 width_(inner.empty()
26 ? 0
27 : (inner.width() == width ? (int32_t)width * inner.height()
28 : inner.width())),
29 width_skip_(width - inner.width()),
30 transparency_(delegate_->transparency() != TransparencyMode::kNone
31 ? delegate_->transparency()
32 : width == inner.width() && inner.xMin() == 0 &&
33 inner.yMin() == 0
36
38
40 if (skip_ > 0) {
41 --skip_;
42 return color::Transparent;
43 }
44 if (count_ < width_) {
45 count_++;
46 return delegate_->next();
47 }
48 if (remaining_lines_ == 0) {
49 return color::Transparent;
50 } else {
51 count_ = 0;
52 skip_ = width_skip_ - 1;
53 --remaining_lines_;
54 return color::Transparent;
55 }
56 }
57
58 void skip(uint32_t count) {
59 for (uint32_t i = 0; i < count; ++i) {
60 next();
61 }
62 }
63
64 TransparencyMode transparency() const { return transparency_; }
65
66 private:
68
69 std::unique_ptr<RawPixelStream> delegate_;
70 int32_t count_;
71 int32_t skip_;
72 int16_t remaining_lines_;
73 const int32_t width_;
74 const int16_t width_skip_;
75 TransparencyMode transparency_;
76};
77
78template <typename RawPixelStream>
79std::unique_ptr<SuperRectangleStream<RawPixelStream>> Realign(
80 const Box &outer_extents, const Box &inner_extents,
81 std::unique_ptr<RawPixelStream> stream) {
82 return std::unique_ptr<SuperRectangleStream<RawPixelStream>>(
84 std::move(stream), outer_extents.width(),
85 inner_extents.translate(-outer_extents.xMin(),
86 -outer_extents.yMin())));
87}
88
89// The streams MUST be aligned first.
90template <typename Bg, typename Fg>
92 public:
93 UnionStream(std::unique_ptr<Bg> bg, std::unique_ptr<Fg> fg)
94 : bg_(std::move(bg)),
95 fg_(std::move(fg)),
96 transparency_(bg_->transparency() == TransparencyMode::kNone &&
99 : bg_->transparency() == TransparencyMode::kFull ||
103
105
107 Color bg = bg_->next();
108 Color fg = fg_->next();
109 return AlphaBlend(bg, fg);
110 }
111
112 void skip(uint32_t count) {
113 bg_->skip(count);
114 fg_->skip(count);
115 }
116
117 TransparencyMode transparency() const { return transparency_; }
118
119 private:
120 UnionStream(const UnionStream &) = delete;
121
122 std::unique_ptr<Bg> bg_;
123 std::unique_ptr<Fg> fg_;
124 TransparencyMode transparency_;
125};
126
127template <typename Bg, typename Fg>
128std::unique_ptr<UnionStream<Bg, Fg>> MakeUnionStream(std::unique_ptr<Bg> bg,
129 std::unique_ptr<Fg> fg) {
130 return std::unique_ptr<UnionStream<Bg, Fg>>(
131 new UnionStream<Bg, Fg>(std::move(bg), std::move(fg)));
132}
133
134// Takes two streamables, and super-imposes one over another.
135// Does not use any additional memory buffer.
136template <typename Bg, typename Fg>
138 public:
141 : anchor_extents_(anchor_extents),
142 bg_(std::move(bg)),
143 bg_x_(bg_x),
144 bg_y_(bg_y),
145 fg_(std::move(fg)),
146 fg_x_(fg_x),
147 fg_y_(fg_y),
148 // bg_bounds_(bg_.bounds().translate(bg_x, bg_y)),
149 // fg_bounds_(fg_.bounds().translate(fg_x, fg_y)),
150 extents_(Box::Extent(bg_extents(), fg_extents())) {}
151
153
157 return MakeUnionStream(
158 Realign(extents_, bg_extents(), bg_.createRawStream()),
159 Realign(extents_, fg_extents(), fg_.createRawStream()));
160 }
161
162 auto CreateClippedStream(const Box &clip_box) const
163 -> std::unique_ptr<internal::UnionStream<
166 Box bounds = Box::Intersect(extents_, clip_box);
167 return MakeUnionStream(
168 Realign(bounds, Box::Intersect(bounds, bg_extents()),
169 CreateClippedStreamFor(bg_, bounds.translate(-bg_x_, -bg_y_))),
170 Realign(bounds, Box::Intersect(bounds, fg_extents()),
171 CreateClippedStreamFor(fg_, bounds.translate(-fg_x_, -fg_y_))));
172 }
173
174 const Box &extents() const { return extents_; }
175 const Box &anchorExtents() const { return anchor_extents_; }
176
177 private:
178 Superposition(const Superposition &) = delete;
179
180 Box anchor_extents_;
181 Bg bg_;
182 int16_t bg_x_;
183 int16_t bg_y_;
184 Fg fg_;
185 int16_t fg_x_;
186 int16_t fg_y_;
187
188 Box bg_extents() const { return bg_.extents().translate(bg_x_, bg_y_); }
189
190 Box fg_extents() const { return fg_.extents().translate(fg_x_, fg_y_); }
191
192 // Rect bg_bounds_;
193 // Rect fg_bounds_;
194 Box extents_;
195};
196
197template <typename RawStreamable>
199 public:
201 const Box extents() const { return ref_.extents(); }
202 decltype(std::declval<const RawStreamable &>().createRawStream())
204 return ref_.createRawStream();
205 }
206
207 private:
208 const RawStreamable &ref_;
209};
210
211} // namespace internal
212
213template <typename Bg, typename Fg>
215 Fg fg, int16_t fg_x, int16_t fg_y) {
216 Box anchor_extents = bg.anchorExtents();
218 bg_y, std::move(fg), fg_x, fg_y);
219}
220
221template <typename Bg, typename Fg>
225 Offset bg_offset = bg_align.resolveOffset(anchor_extents, bg.anchorExtents());
226 Offset fg_offset = fg_align.resolveOffset(anchor_extents, fg.anchorExtents());
228 anchor_extents, std::move(bg), bg_offset.dx, bg_offset.dy, std::move(fg),
229 fg_offset.dx, fg_offset.dy);
230}
231
232template <typename RawStreamable>
236
237} // namespace roo_display
Combines horizontal and vertical alignment.
Definition alignment.h:172
Axis-aligned integer rectangle.
Definition box.h:12
Box translate(int16_t x_offset, int16_t y_offset) const
Return a translated copy of this box.
Definition box.h:127
static Box Intersect(const Box &a, const Box &b)
Return the intersection of two boxes (may be empty).
Definition box.h:25
ARGB8888 color stored as a 32-bit unsigned integer.
Definition color.h:16
Filter functor that alpha-blends a fixed overlay color.
decltype(std::declval< const RawStreamable & >().createRawStream()) createRawStream() const
SuperRectangleStream(std::unique_ptr< RawPixelStream > delegate, int16_t width, const Box &inner)
SuperRectangleStream(SuperRectangleStream &&)=default
Superposition(Superposition &&)=default
Superposition(Box anchor_extents, Bg bg, int16_t bg_x, int16_t bg_y, Fg fg, int16_t fg_x, int16_t fg_y)
auto createRawStream() const -> std::unique_ptr< internal::UnionStream< SuperRectangleStream< RawStreamTypeOf< Bg > >, SuperRectangleStream< RawStreamTypeOf< Fg > > > >
auto CreateClippedStream(const Box &clip_box) const -> std::unique_ptr< internal::UnionStream< SuperRectangleStream< ClipperedRawStreamTypeOf< Bg > >, SuperRectangleStream< ClipperedRawStreamTypeOf< Fg > > > >
UnionStream(UnionStream &&)=default
UnionStream(std::unique_ptr< Bg > bg, std::unique_ptr< Fg > fg)
std::unique_ptr< UnionStream< Bg, Fg > > MakeUnionStream(std::unique_ptr< Bg > bg, std::unique_ptr< Fg > fg)
std::unique_ptr< SuperRectangleStream< RawPixelStream > > Realign(const Box &outer_extents, const Box &inner_extents, std::unique_ptr< RawPixelStream > stream)
Defines 140 opaque HTML named colors.
Color AlphaBlend(Color bgc, Color fgc)
Definition blending.h:598
TransparencyMode
Transparency information for a stream or color mode.
Definition blending.h:103
@ kNone
All colors are fully opaque.
@ kCrude
Colors are either fully opaque or fully transparent.
@ kFull
Colors may include partial transparency (alpha channel).
typename decltype(std::declval< const RawStreamable >() .createRawStream())::element_type RawStreamTypeOf
internal::RawStreamableRef< RawStreamable > Ref(const RawStreamable &ref)
#define const
Definition zconf.h:230