6template <
typename HLineFiller>
9 int16_t dx = x1 - x0, dy = y1 - y0;
14 for (; x0 <= x1; x0++) {
28template <
typename VLineFiller>
31 int16_t dy = y1 - y0, dx = x1 - x0;
36 for (; y0 <= y1; y0++) {
52 if (x0 > clip_box.
xMax() || x1 < clip_box.
xMin() || y0 > clip_box.
yMax() ||
53 y0 < clip_box.
yMin() || x1 < x0) {
57 if (x0 < clip_box.
xMin()) x0 = clip_box.
xMin();
58 if (x1 > clip_box.
xMax()) x1 = clip_box.
xMax();
65 if (x0 > clip_box.
xMax() || x0 < clip_box.
xMin() || y0 > clip_box.
yMax() ||
66 y1 < clip_box.
yMin() || y1 < y0) {
70 if (y0 < clip_box.
yMin()) y0 = clip_box.
yMin();
71 if (y1 > clip_box.
yMax()) y1 = clip_box.
yMax();
76void Line::drawTo(
const Surface &s)
const {
77 int16_t x0 = x0_ + s.dx(), y0 = y0_ + s.dy();
78 int16_t x1 = x1_ + s.dx(), y1 = y1_ + s.dy();
81 drawVLine(s.out(), x0, y0, y1,
color, s.clip_box(), s.blending_mode());
82 }
else if (y0_ == y1_) {
83 drawHLine(s.out(), x0, y0, x1,
color, s.clip_box(), s.blending_mode());
85 bool preclipped = s.clip_box().contains(Box(x0, y0, x1, y1));
88 BufferedVLineFiller drawer(s.out(),
color, s.blending_mode());
91 ClippingBufferedVLineFiller drawer(s.out(),
color, s.clip_box(),
97 BufferedHLineFiller drawer(s.out(),
color, s.blending_mode());
100 ClippingBufferedHLineFiller drawer(s.out(),
color, s.clip_box(),
108void Rect::drawTo(
const Surface &s)
const {
110 int16_t x0 =
x0_ + s.dx();
111 int16_t y0 =
y0_ + s.dy();
112 int16_t x1 =
x1_ + s.dx();
113 int16_t y1 =
y1_ + s.dy();
115 ClippingBufferedRectFiller filler(s.out(), color, s.clip_box(),
117 filler.fillHLine(x0, y0, x1);
118 filler.fillHLine(x0, y1, x1);
119 filler.fillVLine(x0, y0 + 1, y1 - 1);
120 filler.fillVLine(x1, y0 + 1, y1 - 1);
127void Border::drawTo(
const Surface &s)
const {
129 int16_t x0 =
x0_ + s.dx();
130 int16_t y0 =
y0_ + s.dy();
131 int16_t x1 =
x1_ + s.dx();
132 int16_t y1 =
y1_ + s.dy();
134 ClippingBufferedRectFiller filler(s.out(), color, s.clip_box(),
137 filler.fillRect(x0, y0, x0 + left_ - 1, y1);
141 filler.fillRect(x0, y0, x1, y0 + top_ - 1);
145 filler.fillRect(x1 - right_ + 1, y0, x1, y1);
149 filler.fillRect(x0, y1 - bottom_ + 1, x1, y1);
153void FilledRect::drawTo(
const Surface &s)
const {
155 int16_t x0 =
x0_ + s.dx();
156 int16_t y0 =
y0_ + s.dy();
157 int16_t x1 =
x1_ + s.dx();
158 int16_t y1 =
y1_ + s.dy();
160 Box box(x0, y0, x1, y1);
162 s.out().fillRect(s.blending_mode(), box, color);
189template <
typename RectFiller>
227template <
typename HlineFiller>
249 filler->fillHLine(x0 - y, y1 + x, x1 + y);
250 filler->fillHLine(x0 - y, y0 - x, x1 + y);
251 if (
p >= 0 && x + 1 < y) {
252 filler->fillHLine(x0 - x, y1 + y, x1 + x);
253 filler->fillHLine(x0 - x, y0 - y, x1 + x);
258template <
typename HlineFiller>
280 filler->fillHLine(x0 -
r, y1 + x, x0 - y - 1);
281 filler->fillHLine(x1 + y + 1, y1 + x, x1 +
r);
282 filler->fillHLine(x0 -
r, y0 - x, x0 - y - 1);
283 filler->fillHLine(x1 + y + 1, y0 - x, x1 +
r);
285 if (
p >= 0 && x + 1 < y) {
286 filler->fillHLine(x0 -
r, y1 + y, x0 - x - 1);
287 filler->fillHLine(x1 + x + 1, y1 + y, x1 +
r);
288 filler->fillHLine(x0 -
r, y0 - y, x0 - x - 1);
289 filler->fillHLine(x1 + x + 1, y0 - y, x1 +
r);
312void RoundRect::drawInteriorTo(
const Surface &s)
const {
315 AlphaBlend(s.bgcolor(), this->color()), s.blending_mode());
318void Circle::drawInteriorTo(
const Surface &s)
const {
322 AlphaBlend(s.bgcolor(), this->color()), s.blending_mode());
361void FilledRoundRect::drawTo(
const Surface &s)
const {
364 AlphaBlend(s.bgcolor(), this->color()), s.blending_mode());
371void FilledCircle::drawTo(
const Surface &s)
const {
375 AlphaBlend(s.bgcolor(), this->color()), s.blending_mode());
382template <
typename PixelFiller>
396 drawer->fillPixel(x0 + x, y0 + y);
397 drawer->fillPixel(x0 - x, y0 + y);
398 drawer->fillPixel(x0 - x, y0 - y);
399 drawer->fillPixel(x0 + x, y0 - y);
404 s +=
ry2 * ((4 * x) + 6);
411 drawer->fillPixel(x0 + x, y0 + y);
412 drawer->fillPixel(x0 - x, y0 + y);
413 drawer->fillPixel(x0 - x, y0 - y);
414 drawer->fillPixel(x0 + x, y0 - y);
419 s +=
rx2 * ((4 * y) + 6);
424template <
typename HLineFiller>
441 drawer->fillHLine(a, y0, b);
446 dx12 = x2 - x1, dy12 = y2 - y1;
461 for (y = y0; y <= last; y++) {
470 if (a > b) std::swap(a, b);
471 drawer->fillHLine(a, y, b);
478 for (; y <= y2; y++) {
487 if (a > b) std::swap(a, b);
488 drawer->fillHLine(a, y, b);
492void Triangle::drawInteriorTo(
const Surface &s)
const {
499void FilledTriangle::drawInteriorTo(
const Surface &s)
const {
502 int16_t x0 =
x0_ + s.dx();
503 int16_t y0 =
y0_ + s.dy();
504 int16_t x1 =
x1_ + s.dx();
505 int16_t y1 =
y1_ + s.dy();
506 int16_t x2 =
x2_ + s.dx();
507 int16_t y2 =
y2_ + s.dy();
508 if (s.clip_box().contains(box)) {
509 BufferedHLineFiller drawer(s.out(), color, s.blending_mode());
512 ClippingBufferedHLineFiller drawer(s.out(), color, s.clip_box(),
Color color() const
Return the shape color.
Axis-aligned integer rectangle.
int16_t xMin() const
Minimum x (inclusive).
int16_t xMax() const
Maximum x (inclusive).
Box translate(int16_t x_offset, int16_t y_offset) const
Return a translated copy of this box.
bool contains(int16_t x, int16_t y) const
Return whether the point (x, y) lies within the box.
int16_t yMax() const
Maximum y (inclusive).
static Box Intersect(const Box &a, const Box &b)
Return the intersection of two boxes (may be empty).
int16_t yMin() const
Minimum y (inclusive).
Box extents() const override
Return the bounding box encompassing all pixels that need to be drawn.
ARGB8888 color stored as a 32-bit unsigned integer.
The abstraction for drawing to a display.
virtual void fillRects(BlendingMode blending_mode, Color color, int16_t *x0, int16_t *y0, int16_t *x1, int16_t *y1, uint16_t count)=0
Draw the specified rectangles using the same color. Invalidates the address window.
FilledRectStream(Color color)
void Read(Color *buf, uint16_t count) override
Read up to size pixels into buf.
void Skip(uint32_t count) override
Skip count pixels.
std::unique_ptr< PixelStream > createStream() const override
Create a stream covering the full extents().
Stream of pixels in row-major order.
Box extents() const override
Return the bounding box encompassing all pixels that need to be drawn.
Box extents() const override
Return the bounding box encompassing all pixels that need to be drawn.
Defines 140 opaque HTML named colors.
void fillRoundRectCorners(HlineFiller *filler, int16_t x0, int16_t y0, int x1, int y1, int16_t r)
void fillRoundRect(DisplayOutput &output, const Box &bbox, int16_t radius, const Box &clip_box, Color color, BlendingMode mode)
BlendingMode
Porter-Duff style blending modes.
@ kSource
The new ARGB8888 value completely replaces the old one.
void drawRoundRect(DisplayOutput &output, const Box &bbox, int16_t radius, const Box &clip_box, Color color, BlendingMode mode)
void drawEllipse(PixelFiller *drawer, int16_t x0, int16_t y0, int16_t rx, int16_t ry)
void drawSteepLine(VLineFiller *drawer, int16_t x0, int16_t y0, int16_t x1, int16_t y1, bool flip_diag)
Color AlphaBlend(Color bgc, Color fgc)
void drawHLine(DisplayOutput &device, int16_t x0, int16_t y0, int16_t x1, Color color, const Box &clip_box, BlendingMode mode)
void drawVLine(DisplayOutput &device, int16_t x0, int16_t y0, int16_t y1, Color color, const Box &clip_box, BlendingMode mode)
void drawRoundRectTmpl(RectFiller &filler, int16_t x0, int16_t y0, int x1, int y1, int16_t r)
void FillColor(Color *buf, uint32_t count, Color color)
Fill an array with a single color.
void drawNonSteepLine(HLineFiller *drawer, int16_t x0, int16_t y0, int16_t x1, int16_t y1, bool flip_diag)
@ kExtents
Fill the entire extents box (possibly with fully transparent pixels).
void fillRoundRectOutsideCorners(HlineFiller *filler, int16_t x0, int16_t y0, int x1, int y1, int16_t r)
void fillRoundRectBg(DisplayOutput &output, const Box &bbox, int16_t radius, const Box &clip_box, Color bgcolor, BlendingMode mode)
void fillTriangle(HLineFiller *drawer, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)