11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
24PROMEKI_NAMESPACE_BEGIN
40 bool underline =
false;
41 SubtitleEdgeStyle edgeStyle = SubtitleEdgeStyle::None;
42 SubtitleFontFace fontFace = SubtitleFontFace::Default;
49 SubtitlePenSize penSize = SubtitlePenSize::Standard;
54 SubtitlePenOffset penOffset = SubtitlePenOffset::Normal;
62 SubtitleTextTag textTag = SubtitleTextTag::Dialog;
63 Color foregroundColor;
64 Color backgroundColor;
66 SubtitleOpacity foregroundOpacity = SubtitleOpacity::Solid;
67 SubtitleOpacity backgroundOpacity = SubtitleOpacity::Solid;
68 SubtitleOpacity edgeOpacity = SubtitleOpacity::Solid;
73 bool hasAnyStyle()
const {
74 return italic || underline
75 || edgeStyle != SubtitleEdgeStyle::None
76 || fontFace != SubtitleFontFace::Default
77 || penSize != SubtitlePenSize::Standard
78 || penOffset != SubtitlePenOffset::Normal
79 || textTag != SubtitleTextTag::Dialog
80 || foregroundColor.isValid() || backgroundColor.isValid()
81 || edgeColor.isValid()
82 || foregroundOpacity != SubtitleOpacity::Solid
83 || backgroundOpacity != SubtitleOpacity::Solid
84 || edgeOpacity != SubtitleOpacity::Solid;
87 bool operator==(
const Cea708PenAttr &o)
const {
88 return italic == o.italic && underline == o.underline
89 && edgeStyle.value() == o.edgeStyle.value()
90 && fontFace.value() == o.fontFace.value()
91 && penSize.value() == o.penSize.value()
92 && penOffset.value() == o.penOffset.value()
93 && textTag.value() == o.textTag.value()
94 && foregroundColor == o.foregroundColor
95 && backgroundColor == o.backgroundColor
96 && edgeColor == o.edgeColor
97 && foregroundOpacity.value() == o.foregroundOpacity.value()
98 && backgroundOpacity.value() == o.backgroundOpacity.value()
99 && edgeOpacity.value() == o.edgeOpacity.value();
101 bool operator!=(
const Cea708PenAttr &o)
const {
return !(*
this == o); }
130struct Cea708WindowAttr {
134 SubtitleOpacity fillOpacity = SubtitleOpacity::Solid;
142 uint8_t borderType = 0;
147 uint8_t printDirection = 0;
149 uint8_t scrollDirection = 3;
151 bool wordWrap =
false;
153 uint8_t displayEffect = 0;
155 uint8_t effectDirection = 0;
157 uint8_t effectSpeed = 0;
163 bool hasAnyAttribute()
const {
164 return fillColor.isValid()
165 || fillOpacity != SubtitleOpacity::Solid
166 || borderColor.isValid()
169 || printDirection != 0
170 || scrollDirection != 3
172 || displayEffect != 0
173 || effectDirection != 0
177 bool operator==(
const Cea708WindowAttr &o)
const {
178 return fillColor == o.fillColor
179 && fillOpacity.value() == o.fillOpacity.value()
180 && borderColor == o.borderColor && borderType == o.borderType
181 && justify == o.justify && printDirection == o.printDirection
182 && scrollDirection == o.scrollDirection && wordWrap == o.wordWrap
183 && displayEffect == o.displayEffect && effectDirection == o.effectDirection
184 && effectSpeed == o.effectSpeed;
186 bool operator!=(
const Cea708WindowAttr &o)
const {
return !(*
this == o); }
199 uint32_t codepoint = 0;
202 bool operator==(
const Cea708Cell &o)
const {
203 return codepoint == o.codepoint && pen == o.pen;
205 bool operator!=(
const Cea708Cell &o)
const {
return !(*
this == o); }
242 static constexpr int MaxRows = 15;
245 static constexpr int MaxCols = 42;
247 bool visible =
false;
248 bool defined =
false;
253 bool relativePos =
true;
284 uint8_t lastWindowStyleId = 0;
287 uint8_t lastPenStyleId = 0;
294 Cea708WindowAttr attrs;
318 List<List<Cea708Cell>> grid;
322 void resize(
int rows,
int cols);
334 void putChar(uint32_t cp,
const Cea708PenAttr &pen);
342 void putChar(uint32_t cp) { putChar(cp, Cea708PenAttr{}); }
346 void carriageReturn();
362 SubtitleSpan::List visibleSpans()
const;
365 bool isEmpty()
const;
367 bool operator==(
const Cea708Window &o)
const;
368 bool operator!=(
const Cea708Window &o)
const {
return !(*
this == o); }
438class Cea708WindowState {
441 static constexpr int WindowCount = 8;
462 enum class DisplayAspect {
477 int currentWindowId()
const {
return _currentWindow; }
480 void setCurrentWindowId(
int id) {
481 _currentWindow = (
id < 0) ? 0 : (id > 7) ? 7 : id;
485 const Cea708Window &window(
int id)
const {
return _windows[clampId(
id)]; }
488 Cea708Window &window(
int id) {
return _windows[clampId(
id)]; }
492 const Cea708Window ¤tWindow()
const {
return _windows[_currentWindow]; }
493 Cea708Window ¤tWindow() {
return _windows[_currentWindow]; }
497 DisplayAspect displayAspect()
const {
return _displayAspect; }
506 void setDisplayAspect(DisplayAspect a) { _displayAspect = a; }
519 const Cea708PenAttr ¤tPen()
const {
return _windows[_currentWindow].pen; }
520 Cea708PenAttr ¤tPen() {
return _windows[_currentWindow].pen; }
524 bool anyVisible()
const;
531 String visibleText()
const;
540 SubtitleSpan::List visibleSpans()
const;
546 void processServiceBytes(
const Cea708Service &svc);
555 void processBytes(
const void *data,
size_t size);
559 using WindowArray = Array<Cea708Window, WindowCount>;
561 WindowArray _windows;
562 int _currentWindow = 0;
563 DisplayAspect _displayAspect = DisplayAspect::WideScreen;
575 uint32_t _pendingHighSurrogate = 0;
577 static int clampId(
int id) {
578 if (
id < 0)
return 0;
579 if (
id > 7)
return 7;