10#include <promeki/config.h>
11#if PROMEKI_ENABLE_PROAV
23PROMEKI_NAMESPACE_BEGIN
26class UncompressedVideoPayload;
45 using Ptr = SharedPtr<PaintEngine>;
48 static constexpr size_t MaxPixelBytes = 16;
59 uint8_t _data[MaxPixelBytes] = {};
63 bool isEmpty()
const {
return _size == 0; }
66 size_t size()
const {
return _size; }
69 const uint8_t *data()
const {
return _data; }
72 uint8_t *data() {
return _data; }
75 uint8_t &operator[](
size_t i) {
return _data[i]; }
76 uint8_t operator[](
size_t i)
const {
return _data[i]; }
79 void resize(
size_t n) { _size =
static_cast<uint8_t
>(n); }
83 using PointList = ::promeki::List<Point2Di32>;
86 using AlphaList = ::promeki::List<float>;
96 PROMEKI_SHARED_BASE(Impl)
109 virtual bool blit(
const Point2Di32 &destTopLeft,
const UncompressedVideoPayload &src,
110 const Point2Di32 &srcTopLeft,
const Size2Du32 &srcSize)
const;
118 virtual Pixel createPixel(
const uint16_t *comps,
size_t compCount)
const;
127 virtual size_t drawPoints(
const Pixel &pixel,
const Point2Di32 *points,
128 size_t pointCount)
const;
138 virtual size_t compositePoints(
const Pixel &pixel,
const Point2Di32 *points,
139 const float *alphas,
size_t pointCount)
const;
146 virtual bool fill(
const Pixel &pixel)
const;
155 virtual size_t drawLines(
const Pixel &pixel,
const Line2Di32 *lines,
164 virtual size_t drawRect(
const Pixel &pixel,
const Rect<int32_t> &rect)
const;
172 virtual size_t fillRect(
const Pixel &pixel,
const Rect<int32_t> &rect)
const;
181 virtual size_t drawCircle(
const Pixel &pixel,
const Point2Di32 ¢er,
191 virtual size_t fillCircle(
const Pixel &pixel,
const Point2Di32 ¢er,
201 virtual size_t drawEllipse(
const Pixel &pixel,
const Point2Di32 ¢er,
202 const Size2Du32 &size)
const;
211 virtual size_t fillEllipse(
const Pixel &pixel,
const Point2Di32 ¢er,
212 const Size2Du32 &size)
const;
218 virtual const PixelFormat &pixelFormat()
const;
231 static PointList plotLine(
int x1,
int y1,
int x2,
int y2);
234 PaintEngine() : d(SharedPtr<Impl, false>::create()) {};
240 PaintEngine(Impl *impl) : d(SharedPtr<Impl, false>::takeOwnership(impl)) {}
246 const PixelFormat &pixelFormat()
const {
return d->pixelFormat(); }
254 Pixel createPixel(
const uint16_t *comps,
size_t compCount)
const {
255 return d->createPixel(comps, compCount);
263 Pixel createPixel(uint16_t c1)
const {
return d->createPixel(&c1, 1); }
271 Pixel createPixel(uint16_t c1, uint16_t c2)
const {
272 uint16_t data[] = {c1, c2};
273 return d->createPixel(data, 2);
283 Pixel createPixel(uint16_t c1, uint16_t c2, uint16_t c3)
const {
284 uint16_t data[] = {c1, c2, c3};
285 return d->createPixel(data, 3);
296 Pixel createPixel(uint16_t c1, uint16_t c2, uint16_t c3, uint16_t c4)
const {
297 uint16_t data[] = {c1, c2, c3, c4};
298 return d->createPixel(data, 4);
311 Pixel createPixel(
const Color &color)
const {
312 const PixelFormat &pd = d->pixelFormat();
313 const ColorModel &targetModel = pd.isValid() ? pd.colorModel() : ColorModel(ColorModel::sRGB);
314 Color c = (color.model() == targetModel) ? color : color.convert(targetModel);
315 size_t count = pd.isValid() ? pd.compCount() : 4;
316 uint16_t data[PixelMemLayout::MaxComps] = {};
317 for (
size_t i = 0; i < count && i < 3; i++) {
318 float v = c.comp(i) * 65535.0f;
319 if (v < 0.0f) v = 0.0f;
320 if (v > 65535.0f) v = 65535.0f;
321 data[i] =
static_cast<uint16_t
>(v);
324 float a = c.alpha() * 65535.0f;
325 if (a < 0.0f) a = 0.0f;
326 if (a > 65535.0f) a = 65535.0f;
327 data[3] =
static_cast<uint16_t
>(a);
329 return d->createPixel(data, count);
339 size_t drawPoints(
const Pixel &pixel,
const Point2Di32 *points,
size_t pointCount)
const {
340 return d->drawPoints(pixel, points, pointCount);
349 size_t drawPoints(
const Pixel &pixel,
const PointList &points)
const {
350 return d->drawPoints(pixel, points.data(), points.size());
361 size_t compositePoints(
const Pixel &pixel,
const Point2Di32 *points,
const float *alphas,
362 size_t pointCount)
const {
363 return d->compositePoints(pixel, points, alphas, pointCount);
373 size_t compositePoints(
const Pixel &pixel,
const PointList &points,
const AlphaList &alphas)
const {
374 return d->compositePoints(pixel, points.data(), alphas.data(), points.size());
384 size_t drawLines(
const Pixel &pixel,
const Line2Di32 *lines,
size_t lineCount)
const {
385 return d->drawLines(pixel, lines, lineCount);
394 size_t drawLine(
const Pixel &pixel,
const Line2Di32 &line)
const {
395 return d->drawLines(pixel, &line, 1);
407 size_t drawLine(
const Pixel &pixel,
int x1,
int y1,
int x2,
int y2)
const {
408 Line2Di32 line(Point2Di32(x1, y1), Point2Di32(x2, y2));
409 return d->drawLines(pixel, &line, 1);
417 bool fill(
const Pixel &pixel) {
return d->fill(pixel); }
425 size_t drawRect(
const Pixel &pixel,
const Rect<int32_t> &rect)
const {
426 return d->drawRect(pixel, rect);
435 size_t fillRect(
const Pixel &pixel,
const Rect<int32_t> &rect)
const {
436 return d->fillRect(pixel, rect);
446 size_t drawCircle(
const Pixel &pixel,
const Point2Di32 ¢er,
int radius)
const {
447 return d->drawCircle(pixel, center, radius);
457 size_t fillCircle(
const Pixel &pixel,
const Point2Di32 ¢er,
int radius)
const {
458 return d->fillCircle(pixel, center, radius);
468 size_t drawEllipse(
const Pixel &pixel,
const Point2Di32 ¢er,
const Size2Du32 &size)
const {
469 return d->drawEllipse(pixel, center, size);
479 size_t fillEllipse(
const Pixel &pixel,
const Point2Di32 ¢er,
const Size2Du32 &size)
const {
480 return d->fillEllipse(pixel, center, size);
491 bool blit(
const Point2Di32 &destTopLeft,
const UncompressedVideoPayload &src,
492 const Point2Di32 &srcTopLeft = Point2Di32(0, 0),
493 const Size2Du32 &srcSize = Size2Du32())
const {
494 return d->blit(destTopLeft, src, srcTopLeft, srcSize);
498 SharedPtr<Impl, false> d;