MythTV  master
subtitlescreen.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 #ifndef SUBTITLESCREEN_H
4 #define SUBTITLESCREEN_H
5 
6 #include <utility>
7 #ifdef USING_LIBASS
8 extern "C" {
9 #include <ass/ass.h>
10 }
11 #endif
12 
13 // Qt headers
14 #include <QFont>
15 #include <QHash>
16 #include <QRect>
17 #include <QRegExp>
18 #include <QSize>
19 #include <QStringList>
20 #include <QVector>
21 
22 // MythTV headers
23 #include "mythscreentype.h"
24 #include "subtitlereader.h"
25 #include "mythplayer.h"
26 #include "mythuishape.h"
27 #include "mythuisimpletext.h"
28 #include "mythuiimage.h"
29 
30 class SubtitleScreen;
31 
33 {
34 public:
36  CC708CharacterAttribute formatting,
38  : m_text(std::move(t)), m_format(std::move(formatting)), m_parent(p) {}
39  FormattedTextChunk(void) = default;
40 
41  QSize CalcSize(float layoutSpacing = 0.0F) const;
42  void CalcPadding(bool isFirst, bool isLast, int &left, int &right) const;
43  bool Split(FormattedTextChunk &newChunk);
44  QString ToLogString(void) const;
45  bool PreRender(bool isFirst, bool isLast, int &x, int y, int height);
46 
47  QString m_text;
49  const SubtitleScreen *m_parent {nullptr}; // where fonts and sizes are kept
50 
51  // The following are calculated by PreRender().
52  QString m_bgShapeName;
55  QString m_textName;
56  QRect m_textRect;
57 };
58 
60 {
61 public:
62  FormattedTextLine(int x = -1, int y = -1, int o_x = -1, int o_y = -1)
63  : m_xIndent(x), m_yIndent(y), m_origX(o_x), m_origY(o_y) {}
64 
65  QSize CalcSize(float layoutSpacing = 0.0F) const;
66 
67  QList<FormattedTextChunk> chunks;
68  int m_xIndent {-1}; // -1 means TBD i.e. centered
69  int m_yIndent {-1}; // -1 means TBD i.e. relative to bottom
70  int m_origX {-1}; // original, unscaled coordinates
71  int m_origY {-1}; // original, unscaled coordinates
72 };
73 
75 {
76 protected:
77  FormattedTextSubtitle(QString base, const QRect &safearea,
78  uint64_t start, uint64_t duration,
79  SubtitleScreen *p) :
80  m_base(std::move(base)), m_safeArea(safearea),
81  m_start(start), m_duration(duration), m_subScreen(p) {}
82  FormattedTextSubtitle(void) = default;
83 public:
84  virtual ~FormattedTextSubtitle() = default;
85  // These are the steps that can be done outside of the UI thread
86  // and the decoder thread.
87  virtual void WrapLongLines(void) {}
88  virtual void Layout(void);
89  virtual void PreRender(void);
90  // This is the step that can only be done in the UI thread.
91  virtual void Draw(void);
92  virtual int CacheNum(void) const { return -1; }
93  QStringList ToSRT(void) const;
94 
95 protected:
96  QString m_base;
97  QVector<FormattedTextLine> m_lines;
98  const QRect m_safeArea;
99  uint64_t m_start {0};
100  uint64_t m_duration {0};
101  SubtitleScreen *m_subScreen {nullptr}; // where fonts and sizes are kept
102  int m_xAnchorPoint {0}; // 0=left, 1=center, 2=right
103  int m_yAnchorPoint {0}; // 0=top, 1=center, 2=bottom
104  int m_xAnchor {0}; // pixels from left
105  int m_yAnchor {0}; // pixels from top
106  QRect m_bounds;
107 };
108 
110 {
111 public:
112  FormattedTextSubtitleSRT(const QString &base,
113  const QRect &safearea,
114  uint64_t start,
115  uint64_t duration,
116  SubtitleScreen *p,
117  const QStringList &subs) :
118  FormattedTextSubtitle(base, safearea, start, duration, p)
119  {
120  Init(subs);
121  }
122  void WrapLongLines(void) override; // FormattedTextSubtitle
123 private:
124  void Init(const QStringList &subs);
125 };
126 
128 {
129 public:
130  FormattedTextSubtitle608(const vector<CC608Text*> &buffers,
131  const QString &base = "",
132  const QRect &safearea = QRect(),
133  SubtitleScreen *p = nullptr) :
134  FormattedTextSubtitle(base, safearea, 0, 0, p)
135  {
136  Init(buffers);
137  }
138  void Layout(void) override; // FormattedTextSubtitle
139 private:
140  void Init(const vector<CC608Text*> &buffers);
141 };
142 
144 {
145 public:
147  int num,
148  const vector<CC708String*> &list,
149  const QString &base = "",
150  const QRect &safearea = QRect(),
151  SubtitleScreen *p = nullptr,
152  float aspect = 1.77777F) :
153  FormattedTextSubtitle(base, safearea, 0, 0, p),
154  m_num(num),
155  m_bgFillAlpha(win.GetFillAlpha()),
156  m_bgFillColor(win.GetFillColor())
157  {
158  Init(win, list, aspect);
159  }
160  void Draw(void) override; // FormattedTextSubtitle
161  int CacheNum(void) const override // FormattedTextSubtitle
162  { return m_num; }
163 private:
164  void Init(const CC708Window &win,
165  const vector<CC708String*> &list,
166  float aspect);
167  int m_num;
170 };
171 
173 {
174 public:
175  SubtitleScreen(MythPlayer *player, const char * name, int fontStretch);
176  ~SubtitleScreen() override;
177 
178  void EnableSubtitles(int type, bool forced_only = false);
179  void DisableForcedSubtitles(void);
180  int EnabledSubtitleType(void) const { return m_subtitleType; }
181 
182  void ClearAllSubtitles(void);
183  void ClearNonDisplayedSubtitles(void);
184  void ClearDisplayedSubtitles(void);
185  void DisplayDVDButton(AVSubtitle* dvdButton, QRect &buttonPos);
186 
187  void SetZoom(int percent);
188  int GetZoom(void) const;
189  void SetDelay(int ms);
190  int GetDelay(void) const;
191 
192  class SubtitleFormat *GetSubtitleFormat(void) { return m_format; }
193  void Clear708Cache(uint64_t mask);
194  void SetElementAdded(void);
195  void SetElementResized(void);
196  void SetElementDeleted(void);
197 
198  QSize CalcTextSize(const QString &text,
199  const CC708CharacterAttribute &format,
200  float layoutSpacing) const;
201  void CalcPadding(const CC708CharacterAttribute &format,
202  bool isFirst, bool isLast,
203  int &left, int &right) const;
205  void SetFontSize(int pixelSize) { m_fontSize = pixelSize; }
206 
207  // Temporary methods until teletextscreen.cpp is refactored into
208  // subtitlescreen.cpp
209  static QString GetTeletextFontName(void);
210  static int GetTeletextBackgroundAlpha(void);
211 
212  // MythScreenType methods
213  bool Create(void) override; // MythScreenType
214  void Pulse(void) override; // MythUIType
215 
216 private:
217  void ResetElementState(void);
218  void OptimiseDisplayedArea(void);
219  void DisplayAVSubtitles(void);
220  int DisplayScaledAVSubtitles(const AVSubtitleRect *rect, QRect &bbox,
221  bool top, QRect &display, int forced,
222  const QString& imagename,
223  long long displayuntil, long long late);
224  void DisplayTextSubtitles(void);
225  void DisplayRawTextSubtitles(void);
226  void DrawTextSubtitles(const QStringList &subs, uint64_t start,
227  uint64_t duration);
228  void DisplayCC608Subtitles(void);
229  void DisplayCC708Subtitles(void);
230  void AddScaledImage(QImage &img, QRect &pos);
231  void InitializeFonts(bool wasResized);
232 
233  MythPlayer *m_player {nullptr};
237  QRect m_safeArea;
238  QRegExp m_removeHTML {"</?.+>"};
240  int m_fontSize {0};
241  int m_textFontZoom {100}; // valid for 708 & text subs
243  int m_textFontDelayMs {0}; // valid for text subs
245  bool m_refreshModified {false};
246  bool m_refreshDeleted {false};
248  QString m_family; // 608, 708, text, teletext
249  // Subtitles initialized but still to be processed and drawn
250  QList<FormattedTextSubtitle *> m_qInited;
251  class SubtitleFormat *m_format {nullptr};
252 
253 #ifdef USING_LIBASS
254  bool InitialiseAssLibrary(void);
255  void LoadAssFonts(void);
256  void CleanupAssLibrary(void);
257  void InitialiseAssTrack(int tracknum);
258  void CleanupAssTrack(void);
259  void AddAssEvent(char *event);
260  void ResizeAssRenderer(void);
261  void RenderAssTrack(uint64_t timecode);
262 
263  ASS_Library *m_assLibrary {nullptr};
264  ASS_Renderer *m_assRenderer {nullptr};
265  int m_assTrackNum {-1};
266  ASS_Track *m_assTrack {nullptr};
268 #endif // USING_LIBASS
269 };
270 
271 #endif // SUBTITLESCREEN_H
class SubtitleFormat * GetSubtitleFormat(void)
FormattedTextChunk(QString t, CC708CharacterAttribute formatting, SubtitleScreen *p)
int DisplayScaledAVSubtitles(const AVSubtitleRect *rect, QRect &bbox, bool top, QRect &display, int forced, const QString &imagename, long long displayuntil, long long late)
void SetElementResized(void)
void SetZoom(int percent)
CC608Reader * m_cc608reader
bool Split(FormattedTextChunk &newChunk)
FormattedTextSubtitle608(const vector< CC608Text * > &buffers, const QString &base="", const QRect &safearea=QRect(), SubtitleScreen *p=nullptr)
const SubtitleScreen * m_parent
void InitializeFonts(bool wasResized)
void InitialiseAssTrack(int tracknum)
void CleanupAssLibrary(void)
FormattedTextChunk(void)=default
virtual int CacheNum(void) const
void EnableSubtitles(int type, bool forced_only=false)
QList< FormattedTextSubtitle * > m_qInited
MythFontProperties * GetFont(const CC708CharacterAttribute &attr) const
void Clear708Cache(uint64_t mask)
void CalcPadding(bool isFirst, bool isLast, int &left, int &right) const
void DisplayCC608Subtitles(void)
void DrawTextSubtitles(const QStringList &subs, uint64_t start, uint64_t duration)
void CleanupAssTrack(void)
void OptimiseDisplayedArea(void)
FormattedTextSubtitleSRT(const QString &base, const QRect &safearea, uint64_t start, uint64_t duration, SubtitleScreen *p, const QStringList &subs)
FormattedTextSubtitle(void)=default
void SetFontSize(int pixelSize)
int CacheNum(void) const override
MythFontProperties * m_textFont
FormattedTextSubtitle708(const CC708Window &win, int num, const vector< CC708String * > &list, const QString &base="", const QRect &safearea=QRect(), SubtitleScreen *p=nullptr, float aspect=1.77777F)
SubtitleScreen(MythPlayer *player, const char *name, int fontStretch)
int GetZoom(void) const
void ClearNonDisplayedSubtitles(void)
void Init(const QStringList &subs)
void DisableForcedSubtitles(void)
FormattedTextSubtitle(QString base, const QRect &safearea, uint64_t start, uint64_t duration, SubtitleScreen *p)
void Init(const CC708Window &win, const vector< CC708String * > &list, float aspect)
void SetElementDeleted(void)
QSize CalcSize(float layoutSpacing=0.0F) const
bool Create(void) override
FormattedTextLine(int x=-1, int y=-1, int o_x=-1, int o_y=-1)
CC708Reader * m_cc708reader
static int GetTeletextBackgroundAlpha(void)
void RenderAssTrack(uint64_t timecode)
virtual void WrapLongLines(void)
static QString GetTeletextFontName(void)
SubtitleReader * m_subreader
unsigned int uint
Definition: compat.h:140
void Init(const vector< CC608Text * > &buffers)
bool PreRender(bool isFirst, bool isLast, int &x, int y, int height)
void WrapLongLines(void) override
virtual void Layout(void)
void SetElementAdded(void)
void CalcPadding(const CC708CharacterAttribute &format, bool isFirst, bool isLast, int &left, int &right) const
void DisplayDVDButton(AVSubtitle *dvdButton, QRect &buttonPos)
void DisplayCC708Subtitles(void)
~SubtitleScreen() override
QSize CalcTextSize(const QString &text, const CC708CharacterAttribute &format, float layoutSpacing) const
void Pulse(void) override
Pulse is called 70 times a second to trigger a single frame of an animation.
QString ToLogString(void) const
void Layout(void) override
void SetDelay(int ms)
ASS_Track * m_assTrack
QSize CalcSize(float layoutSpacing=0.0F) const
virtual ~FormattedTextSubtitle()=default
QVector< FormattedTextLine > m_lines
void ClearDisplayedSubtitles(void)
void ResizeAssRenderer(void)
CC708CharacterAttribute m_format
QList< FormattedTextChunk > chunks
ASS_Library * m_assLibrary
ASS_Renderer * m_assRenderer
void ClearAllSubtitles(void)
class SubtitleFormat * m_format
void DisplayTextSubtitles(void)
void LoadAssFonts(void)
int EnabledSubtitleType(void) const
QStringList ToSRT(void) const
Screen in which all other widgets are contained and rendered.
SubtitleScreen * m_subScreen
int GetDelay(void) const
void AddAssEvent(char *event)
bool InitialiseAssLibrary(void)
void DisplayRawTextSubtitles(void)
virtual void Draw(void)
void DisplayAVSubtitles(void)
void ResetElementState(void)
void AddScaledImage(QImage &img, QRect &pos)
void Draw(void) override
MythPlayer * m_player
QRegExp m_removeHTML
virtual void PreRender(void)