libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
cea708windowstate.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <cstdint>
14#include <promeki/array.h>
15#include <promeki/buffer.h>
17#include <promeki/color.h>
18#include <promeki/enums.h>
19#include <promeki/list.h>
20#include <promeki/namespace.h>
21#include <promeki/string.h>
22#include <promeki/subtitle.h>
23
24PROMEKI_NAMESPACE_BEGIN
25
38struct Cea708PenAttr {
39 bool italic = false;
40 bool underline = false;
41 SubtitleEdgeStyle edgeStyle = SubtitleEdgeStyle::None;
42 SubtitleFontFace fontFace = SubtitleFontFace::Default;
43 Color foregroundColor;
44 Color backgroundColor;
45 Color edgeColor;
46 SubtitleOpacity foregroundOpacity = SubtitleOpacity::Solid;
47 SubtitleOpacity backgroundOpacity = SubtitleOpacity::Solid;
48 SubtitleOpacity edgeOpacity = SubtitleOpacity::Solid;
49
53 bool hasAnyStyle() const {
54 return italic || underline
55 || edgeStyle.value() != SubtitleEdgeStyle::None.value()
56 || fontFace.value() != SubtitleFontFace::Default.value()
57 || foregroundColor.isValid() || backgroundColor.isValid()
58 || edgeColor.isValid()
59 || foregroundOpacity.value() != SubtitleOpacity::Solid.value()
60 || backgroundOpacity.value() != SubtitleOpacity::Solid.value()
61 || edgeOpacity.value() != SubtitleOpacity::Solid.value();
62 }
63
64 bool operator==(const Cea708PenAttr &o) const {
65 return italic == o.italic && underline == o.underline
66 && edgeStyle.value() == o.edgeStyle.value()
67 && fontFace.value() == o.fontFace.value()
68 && foregroundColor == o.foregroundColor
69 && backgroundColor == o.backgroundColor
70 && edgeColor == o.edgeColor
71 && foregroundOpacity.value() == o.foregroundOpacity.value()
72 && backgroundOpacity.value() == o.backgroundOpacity.value()
73 && edgeOpacity.value() == o.edgeOpacity.value();
74 }
75 bool operator!=(const Cea708PenAttr &o) const { return !(*this == o); }
76};
77
104struct Cea708WindowAttr {
107 Color fillColor;
108 SubtitleOpacity fillOpacity = SubtitleOpacity::Solid;
109
112 Color borderColor;
116 uint8_t borderType = 0;
117
119 uint8_t justify = 0;
121 uint8_t printDirection = 0;
123 uint8_t scrollDirection = 3; // BtT — caption convention
125 bool wordWrap = false;
127 uint8_t displayEffect = 0;
129 uint8_t effectDirection = 0;
131 uint8_t effectSpeed = 0;
132
137 bool hasAnyAttribute() const {
138 return fillColor.isValid()
139 || fillOpacity.value() != SubtitleOpacity::Solid.value()
140 || borderColor.isValid()
141 || borderType != 0
142 || justify != 0
143 || printDirection != 0
144 || scrollDirection != 3
145 || wordWrap
146 || displayEffect != 0
147 || effectDirection != 0
148 || effectSpeed != 0;
149 }
150
151 bool operator==(const Cea708WindowAttr &o) const {
152 return fillColor == o.fillColor
153 && fillOpacity.value() == o.fillOpacity.value()
154 && borderColor == o.borderColor && borderType == o.borderType
155 && justify == o.justify && printDirection == o.printDirection
156 && scrollDirection == o.scrollDirection && wordWrap == o.wordWrap
157 && displayEffect == o.displayEffect && effectDirection == o.effectDirection
158 && effectSpeed == o.effectSpeed;
159 }
160 bool operator!=(const Cea708WindowAttr &o) const { return !(*this == o); }
161};
162
172struct Cea708Cell {
173 uint32_t codepoint = 0;
174 Cea708PenAttr pen;
175
176 bool operator==(const Cea708Cell &o) const {
177 return codepoint == o.codepoint && pen == o.pen;
178 }
179 bool operator!=(const Cea708Cell &o) const { return !(*this == o); }
180};
181
213struct Cea708Window {
216 static constexpr int MaxRows = 15;
219 static constexpr int MaxCols = 42;
220
221 bool visible = false;
222 bool defined = false;
223 int priority = 0;
224 int anchorPoint = 1;
225 int anchorV = 0;
226 int anchorH = 0;
227 bool relativePos = true;
228 int rowCount = 15;
229 int colCount = 32;
230 bool rowLock = true;
231 bool colLock = true;
232 int penRow = 0;
233 int penCol = 0;
234
240 Cea708WindowAttr attrs;
241
247 List<List<Cea708Cell>> grid;
248
251 void resize(int rows, int cols);
252
255 void clearGrid();
256
263 void putChar(uint32_t cp, const Cea708PenAttr &pen);
264
271 void putChar(uint32_t cp) { putChar(cp, Cea708PenAttr{}); }
272
275 void carriageReturn();
276
282 String text() const;
283
291 SubtitleSpan::List visibleSpans() const;
292
294 bool isEmpty() const;
295
296 bool operator==(const Cea708Window &o) const;
297 bool operator!=(const Cea708Window &o) const { return !(*this == o); }
298};
299
358class Cea708WindowState {
359 public:
361 static constexpr int WindowCount = 8;
362
363 Cea708WindowState();
364
369 void reset();
370
373 int currentWindowId() const { return _currentWindow; }
376 void setCurrentWindowId(int id) {
377 _currentWindow = (id < 0) ? 0 : (id > 7) ? 7 : id;
378 }
379
381 const Cea708Window &window(int id) const { return _windows[clampId(id)]; }
382
384 Cea708Window &window(int id) { return _windows[clampId(id)]; }
385
388 const Cea708Window &currentWindow() const { return _windows[_currentWindow]; }
389 Cea708Window &currentWindow() { return _windows[_currentWindow]; }
390
394 const Cea708PenAttr &currentPen() const { return _pen; }
395 Cea708PenAttr &currentPen() { return _pen; }
396
399 bool anyVisible() const;
400
406 String visibleText() const;
407
415 SubtitleSpan::List visibleSpans() const;
416
421 void processServiceBytes(const Cea708Service &svc);
422
430 void processBytes(const void *data, size_t size);
431
432 private:
434 using WindowArray = Array<Cea708Window, WindowCount>;
435
436 WindowArray _windows;
437 int _currentWindow = 0;
438 Cea708PenAttr _pen;
439
450 uint32_t _pendingHighSurrogate = 0;
451
452 static int clampId(int id) {
453 if (id < 0) return 0;
454 if (id > 7) return 7;
455 return id;
456 }
457};
458
459PROMEKI_NAMESPACE_END
460
461#endif // PROMEKI_ENABLE_PROAV