libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
paintengine.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <promeki/config.h>
11#if PROMEKI_ENABLE_PROAV
12#include <promeki/namespace.h>
13#include <promeki/pixelformat.h>
14#include <promeki/sharedptr.h>
15#include <promeki/array.h>
16#include <promeki/list.h>
17#include <promeki/size2d.h>
18#include <promeki/point.h>
19#include <promeki/line.h>
20#include <promeki/rect.h>
21#include <promeki/color.h>
22
23PROMEKI_NAMESPACE_BEGIN
24
25class Image;
26class UncompressedVideoPayload;
27
42class PaintEngine {
43 public:
45 using Ptr = SharedPtr<PaintEngine>;
46
48 static constexpr size_t MaxPixelBytes = 16;
49
58 struct Pixel {
59 uint8_t _data[MaxPixelBytes] = {};
60 uint8_t _size = 0;
61
63 bool isEmpty() const { return _size == 0; }
64
66 size_t size() const { return _size; }
67
69 const uint8_t *data() const { return _data; }
70
72 uint8_t *data() { return _data; }
73
75 uint8_t &operator[](size_t i) { return _data[i]; }
76 uint8_t operator[](size_t i) const { return _data[i]; }
77
79 void resize(size_t n) { _size = static_cast<uint8_t>(n); }
80 };
81
83 using PointList = ::promeki::List<Point2Di32>;
84
86 using AlphaList = ::promeki::List<float>;
87
95 class Impl {
96 PROMEKI_SHARED_BASE(Impl)
97 public:
99 virtual ~Impl();
100
109 virtual bool blit(const Point2Di32 &destTopLeft, const UncompressedVideoPayload &src,
110 const Point2Di32 &srcTopLeft, const Size2Du32 &srcSize) const;
111
118 virtual Pixel createPixel(const uint16_t *comps, size_t compCount) const;
119
127 virtual size_t drawPoints(const Pixel &pixel, const Point2Di32 *points,
128 size_t pointCount) const;
129
138 virtual size_t compositePoints(const Pixel &pixel, const Point2Di32 *points,
139 const float *alphas, size_t pointCount) const;
140
146 virtual bool fill(const Pixel &pixel) const;
147
155 virtual size_t drawLines(const Pixel &pixel, const Line2Di32 *lines,
156 size_t count) const;
157
164 virtual size_t drawRect(const Pixel &pixel, const Rect<int32_t> &rect) const;
165
172 virtual size_t fillRect(const Pixel &pixel, const Rect<int32_t> &rect) const;
173
181 virtual size_t drawCircle(const Pixel &pixel, const Point2Di32 &center,
182 int radius) const;
183
191 virtual size_t fillCircle(const Pixel &pixel, const Point2Di32 &center,
192 int radius) const;
193
201 virtual size_t drawEllipse(const Pixel &pixel, const Point2Di32 &center,
202 const Size2Du32 &size) const;
203
211 virtual size_t fillEllipse(const Pixel &pixel, const Point2Di32 &center,
212 const Size2Du32 &size) const;
213
218 virtual const PixelFormat &pixelFormat() const;
219
220 protected:
221 };
222
231 static PointList plotLine(int x1, int y1, int x2, int y2);
232
234 PaintEngine() : d(SharedPtr<Impl, false>::create()) {};
235
240 PaintEngine(Impl *impl) : d(SharedPtr<Impl, false>::takeOwnership(impl)) {}
241
246 const PixelFormat &pixelFormat() const { return d->pixelFormat(); }
247
254 Pixel createPixel(const uint16_t *comps, size_t compCount) const {
255 return d->createPixel(comps, compCount);
256 }
257
263 Pixel createPixel(uint16_t c1) const { return d->createPixel(&c1, 1); }
264
271 Pixel createPixel(uint16_t c1, uint16_t c2) const {
272 uint16_t data[] = {c1, c2};
273 return d->createPixel(data, 2);
274 }
275
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);
286 }
287
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);
299 }
300
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);
322 }
323 if (count >= 4) {
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);
328 }
329 return d->createPixel(data, count);
330 }
331
339 size_t drawPoints(const Pixel &pixel, const Point2Di32 *points, size_t pointCount) const {
340 return d->drawPoints(pixel, points, pointCount);
341 }
342
349 size_t drawPoints(const Pixel &pixel, const PointList &points) const {
350 return d->drawPoints(pixel, points.data(), points.size());
351 }
352
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);
364 }
365
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());
375 }
376
384 size_t drawLines(const Pixel &pixel, const Line2Di32 *lines, size_t lineCount) const {
385 return d->drawLines(pixel, lines, lineCount);
386 }
387
394 size_t drawLine(const Pixel &pixel, const Line2Di32 &line) const {
395 return d->drawLines(pixel, &line, 1);
396 }
397
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);
410 }
411
417 bool fill(const Pixel &pixel) { return d->fill(pixel); }
418
425 size_t drawRect(const Pixel &pixel, const Rect<int32_t> &rect) const {
426 return d->drawRect(pixel, rect);
427 }
428
435 size_t fillRect(const Pixel &pixel, const Rect<int32_t> &rect) const {
436 return d->fillRect(pixel, rect);
437 }
438
446 size_t drawCircle(const Pixel &pixel, const Point2Di32 &center, int radius) const {
447 return d->drawCircle(pixel, center, radius);
448 }
449
457 size_t fillCircle(const Pixel &pixel, const Point2Di32 &center, int radius) const {
458 return d->fillCircle(pixel, center, radius);
459 }
460
468 size_t drawEllipse(const Pixel &pixel, const Point2Di32 &center, const Size2Du32 &size) const {
469 return d->drawEllipse(pixel, center, size);
470 }
471
479 size_t fillEllipse(const Pixel &pixel, const Point2Di32 &center, const Size2Du32 &size) const {
480 return d->fillEllipse(pixel, center, size);
481 }
482
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);
495 }
496
497 private:
498 SharedPtr<Impl, false> d;
499};
500
501PROMEKI_NAMESPACE_END
502
503#endif // PROMEKI_ENABLE_PROAV