diff --git a/mythtv/libs/libmythtv/cc708window.h b/mythtv/libs/libmythtv/cc708window.h
index c5657db8d52..12fc066e0bf 100644
--- a/mythtv/libs/libmythtv/cc708window.h
+++ b/mythtv/libs/libmythtv/cc708window.h
@@ -90,7 +90,7 @@ class CC708CharacterAttribute
QColor actual_fg_color;
CC708CharacterAttribute(bool isItalic, bool isBold, bool isUnderline,
- QColor fgColor, bool hasBackground) :
+ QColor fgColor) :
pen_size(k708AttrSizeStandard),
offset(k708AttrOffsetNormal),
text_tag(0), // "dialog", ignored
@@ -102,8 +102,7 @@ class CC708CharacterAttribute
fg_color(k708AttrColorWhite), // will be overridden
fg_opacity(k708AttrOpacitySolid), // solid
bg_color(k708AttrColorBlack),
- bg_opacity(hasBackground ? k708AttrOpacitySolid :
- k708AttrOpacityTransparent),
+ bg_opacity(k708AttrOpacitySolid),
edge_color(k708AttrColorBlack),
override_fg_color(true),
actual_fg_color(fgColor)
diff --git a/mythtv/libs/libmythtv/subtitlescreen.cpp b/mythtv/libs/libmythtv/subtitlescreen.cpp
index e92a8b55003..f3c8914d22d 100644
--- a/mythtv/libs/libmythtv/subtitlescreen.cpp
+++ b/mythtv/libs/libmythtv/subtitlescreen.cpp
@@ -11,6 +11,507 @@
#define LOC QString("Subtitles: ")
#define LOC_WARN QString("Subtitles Warning: ")
+
+// Class SubtitleFormat manages fonts and backgrounds for subtitles.
+//
+// Formatting is specified by the theme in the new file
+// osd_subtitle.xml, in the osd_subtitle window. Subtitle types are
+// text, teletext, 608, 708_0, 708_1, ..., 708_7. Each subtitle type
+// has a fontdef component for the text and a shape component for the
+// background. By default, the attributes of a subtitle type come
+// from either the provider (e.g. font color, italics) or the system
+// default (e.g. font family). These attributes can be overridden by
+// the xml file.
+//
+// The fontdef name and the background shape name are both simply the
+// name of the subtitle type. The fontdef and shape should ultimately
+// inherit from the special value "provider", otherwise all provider
+// values will be ignored.
+//
+// The following example forces .srt subtitles to be rendered in
+// yellow text, FreeSans font, black shadow, with a translucent black
+// background. The fontdef and shape names are "text" since the
+// subtitles come from a .srt file. Note that in this example, color
+// formatting controls in the .srt file will be ignored due to the
+// explicit setting of yellow text.
+//
+//
+//
+//
+//
+//
+// #FFFF00
+// 2,2
+// #000000
+//
+//
+//
+//
+//
+//
+//
+// All elements/attributes of fontdef and shape can be used. Note
+// however that area and position are explicitly ignored, as these are
+// dictated by the subtitle layout.
+//
+// This is implemented with almost no MythUI changes. Two copies of a
+// "provider" object are created, with default/representative provider
+// attributes. One copy is then "complemented" to have a different
+// value for each attribute that a provider might change. The
+// osd_subtitle.xml file is loaded twice, once with respect to each
+// provider object, and the desired fontdef or shape is looked up.
+// The two fontdefs or shapes are compared attribute by attribute, and
+// each attribute that is different is an attribute that the provider
+// may modify, whereas each identical attribute represents one that is
+// fixed by the theme.
+class SubtitleFormat
+{
+public:
+ SubtitleFormat(void) {}
+ ~SubtitleFormat(void);
+ MythFontProperties *GetFont(const QString &family,
+ const CC708CharacterAttribute &attr,
+ int pixelSize, bool isTeletext,
+ int zoom, int stretch);
+ MythUIShape *GetBackground(MythUIType *parent, const QString &name,
+ const QString &family,
+ const CC708CharacterAttribute &attr);
+ static QString MakePrefix(const QString &family,
+ const CC708CharacterAttribute &attr);
+ bool IsUnlocked(const QString &prefix, const QString &property) const
+ {
+ return m_changeMap[prefix].contains(property);
+ }
+private:
+ void Load(const QString &family,
+ const CC708CharacterAttribute &attr);
+ static void CreateProviderDefault(const QString &family,
+ const CC708CharacterAttribute &attr,
+ MythUIType *parent,
+ bool isComplement,
+ MythFontProperties **font,
+ MythUIShape **bg);
+ static void Complement(MythFontProperties *font, MythUIShape *bg);
+ static QSet Diff(const QString &family,
+ const CC708CharacterAttribute &attr,
+ MythFontProperties *font1,
+ MythFontProperties *font2,
+ MythUIShape *bg1,
+ MythUIShape *bg2);
+
+ QHash m_fontMap;
+ QHash m_shapeMap;
+ QHash > m_changeMap;
+ QHash m_pixelSizeMap;
+ QVector m_cleanup;
+};
+
+static const QString kSubProvider("provider");
+static const QString kSubFileName ("osd_subtitle.xml");
+static const QString kSubWindowName("osd_subtitle");
+static const QString kSubFamily608 ("608");
+static const QString kSubFamily708 ("708");
+static const QString kSubFamilyText ("text");
+static const QString kSubFamilyTeletext("teletext");
+
+static const QString kSubAttrItalics ("italics");
+static const QString kSubAttrBold ("bold");
+static const QString kSubAttrUnderline("underline");
+static const QString kSubAttrPixelsize("pixelsize");
+static const QString kSubAttrColor ("color");
+static const QString kSubAttrBGfill ("bgfill");
+static const QString kSubAttrShadow ("shadow");
+static const QString kSubAttrShadowoffset("shadowoffset");
+static const QString kSubAttrShadowcolor ("shadowcolor");
+static const QString kSubAttrShadowalpha ("shadowalpha");
+static const QString kSubAttrOutline ("outline");
+static const QString kSubAttrOutlinecolor("outlinecolor");
+static const QString kSubAttrOutlinesize ("outlinesize");
+static const QString kSubAttrOutlinealpha("outlinealpha");
+
+static QString srtColorString(QColor color);
+static QString fontToString(MythFontProperties *f)
+{
+ QString result;
+ result = QString("face=%1 pixelsize=%2 color=%3 "
+ "italics=%4 weight=%5 underline=%6")
+ .arg(f->GetFace()->family())
+ .arg(f->GetFace()->pixelSize())
+ .arg(srtColorString(f->color()))
+ .arg(f->GetFace()->italic())
+ .arg(f->GetFace()->weight())
+ .arg(f->GetFace()->underline());
+ QPoint offset;
+ QColor color;
+ int alpha;
+ int size;
+ f->GetShadow(offset, color, alpha);
+ result += QString(" shadow=%1 shadowoffset=%2 "
+ "shadowcolor=%3 shadowalpha=%4")
+ .arg(f->hasShadow())
+ .arg(QString("(%1,%2)").arg(offset.x()).arg(offset.y()))
+ .arg(srtColorString(color))
+ .arg(alpha);
+ f->GetOutline(color, size, alpha);
+ result += QString(" outline=%1 outlinecolor=%2 "
+ "outlinesize=%3 outlinealpha=%4")
+ .arg(f->hasOutline())
+ .arg(srtColorString(color))
+ .arg(size)
+ .arg(alpha);
+ return result;
+}
+
+SubtitleFormat::~SubtitleFormat(void)
+{
+ for (int i = 0; i < m_cleanup.size(); ++i)
+ {
+ m_cleanup[i]->DeleteAllChildren();
+ delete m_cleanup[i];
+ m_cleanup[i] = NULL; // just to be safe
+ }
+}
+
+QString SubtitleFormat::MakePrefix(const QString &family,
+ const CC708CharacterAttribute &attr)
+{
+ if (family == kSubFamily708)
+ return family + "_" + QString::number(attr.font_tag & 0x7);
+ else
+ return family;
+}
+
+void SubtitleFormat::CreateProviderDefault(const QString &family,
+ const CC708CharacterAttribute &attr,
+ MythUIType *parent,
+ bool isComplement,
+ MythFontProperties **returnFont,
+ MythUIShape **returnBg)
+{
+ MythFontProperties *font = new MythFontProperties();
+ MythUIShape *bg = new MythUIShape(parent, kSubProvider);
+ if (family == kSubFamily608)
+ {
+ font->GetFace()->setFamily("FreeMono");
+ bg->SetFillBrush(QBrush(Qt::black));
+ }
+ else if (family == kSubFamily708)
+ {
+ static const char *cc708Fonts[] = {
+ "FreeMono", // default
+ "FreeMono", // mono serif
+ "DejaVu Serif", // prop serif
+ "Droid Sans Mono", // mono sans
+ "Liberation Sans", // prop sans
+ "Purisa", // casual
+ "URW Chancery L", // cursive
+ "Impact" // capitals
+ };
+ font->GetFace()->setFamily(cc708Fonts[attr.font_tag & 0x7]);
+ }
+ else if (family == kSubFamilyText)
+ {
+ font->GetFace()->setFamily("Droid Sans");
+ bg->SetFillBrush(QBrush(Qt::black));
+ }
+ else if (family == kSubFamilyTeletext)
+ {
+ font->GetFace()->setFamily("FreeMono");
+ }
+ font->GetFace()->setPixelSize(10);
+
+ if (isComplement)
+ Complement(font, bg);
+ parent->AddFont(kSubProvider, font);
+
+ *returnFont = font;
+ *returnBg = bg;
+}
+
+static QColor differentColor(const QColor &color)
+{
+ return color == Qt::white ? Qt::black : Qt::white;
+}
+
+// Change everything (with respect to the == operator) that the
+// provider might define or override.
+void SubtitleFormat::Complement(MythFontProperties *font, MythUIShape *bg)
+{
+ QPoint offset;
+ QColor color;
+ int alpha;
+ int size;
+ QFont *face = font->GetFace();
+ face->setItalic(!face->italic());
+ face->setPixelSize(face->pixelSize() + 1);
+ face->setUnderline(!face->underline());
+ face->setWeight((face->weight() + 1) % 32);
+ font->SetColor(differentColor(font->color()));
+
+ font->GetShadow(offset, color, alpha);
+ offset.setX(offset.x() + 1);
+ font->SetShadow(!font->hasShadow(), offset, differentColor(color),
+ 255 - alpha);
+
+ font->GetOutline(color, size, alpha);
+ font->SetOutline(!font->hasOutline(), differentColor(color),
+ size + 1, 255 - alpha);
+
+ bg->SetFillBrush(bg->m_fillBrush == Qt::NoBrush ?
+ Qt::SolidPattern : Qt::NoBrush);
+}
+
+void SubtitleFormat::Load(const QString &family,
+ const CC708CharacterAttribute &attr)
+{
+ // Widgets for the actual values
+ MythUIType *baseParent = new MythUIType(NULL, "base");
+ m_cleanup += baseParent;
+ MythFontProperties *providerBaseFont;
+ MythUIShape *providerBaseShape;
+ CreateProviderDefault(family, attr, baseParent, false,
+ &providerBaseFont, &providerBaseShape);
+
+ // Widgets for the "negative" values
+ MythUIType *negParent = new MythUIType(NULL, "base");
+ m_cleanup += negParent;
+ MythFontProperties *negFont;
+ MythUIShape *negBG;
+ CreateProviderDefault(family, attr, negParent, true, &negFont, &negBG);
+
+ bool posResult =
+ XMLParseBase::LoadWindowFromXML(kSubFileName, kSubWindowName,
+ baseParent);
+ bool negResult =
+ XMLParseBase::LoadWindowFromXML(kSubFileName, kSubWindowName,
+ negParent);
+ if (!posResult || !negResult)
+ LOG(VB_VBI, LOG_INFO,
+ QString("Couldn't load theme file %1").arg(kSubFileName));
+ QString prefix = MakePrefix(family, attr);
+ MythFontProperties *resultFont = baseParent->GetFont(prefix);
+ if (!resultFont)
+ resultFont = providerBaseFont;
+ MythUIShape *resultBG =
+ dynamic_cast(baseParent->GetChild(prefix));
+ if (!resultBG)
+ resultBG = providerBaseShape;
+ MythFontProperties *testFont = negParent->GetFont(prefix);
+ if (!testFont)
+ testFont = negFont;
+ MythUIShape *testBG =
+ dynamic_cast(negParent->GetChild(prefix));
+ if (!testBG)
+ testBG = negBG;
+ m_fontMap[prefix] = resultFont;
+ m_shapeMap[prefix] = resultBG;
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("providerBaseFont = %1").arg(fontToString(providerBaseFont)));
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("negFont = %1").arg(fontToString(negFont)));
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("resultFont = %1").arg(fontToString(resultFont)));
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("testFont = %1").arg(fontToString(testFont)));
+ m_changeMap[prefix] = Diff(family, attr, resultFont, testFont,
+ resultBG, testBG);
+ if (!IsUnlocked(prefix, kSubAttrPixelsize))
+ m_pixelSizeMap[prefix] = resultFont->GetFace()->pixelSize();
+}
+
+QSet SubtitleFormat::Diff(const QString &family,
+ const CC708CharacterAttribute &attr,
+ MythFontProperties *font1,
+ MythFontProperties *font2,
+ MythUIShape *bg1,
+ MythUIShape *bg2)
+{
+ bool is708 = (family == kSubFamily708);
+ QSet result;
+ QFont *face1 = font1->GetFace();
+ QFont *face2 = font2->GetFace();
+ if (face1->italic() != face2->italic())
+ result << kSubAttrItalics;
+ if (face1->weight() != face2->weight())
+ result << kSubAttrBold;
+ if (face1->underline() != face2->underline())
+ result << kSubAttrUnderline;
+ if (face1->pixelSize() != face2->pixelSize())
+ result << kSubAttrPixelsize;
+ if (font1->color() != font2->color())
+ result << kSubAttrColor;
+ if (is708 && font1->hasShadow() != font2->hasShadow())
+ {
+ result << kSubAttrShadow;
+ QPoint offset1, offset2;
+ QColor color1, color2;
+ int alpha1, alpha2;
+ font1->GetShadow(offset1, color1, alpha1);
+ font2->GetShadow(offset2, color2, alpha2);
+ if (offset1 != offset2)
+ result << kSubAttrShadowoffset;
+ if (color1 != color2)
+ result << kSubAttrShadowcolor;
+ if (alpha1 != alpha2)
+ result << kSubAttrShadowalpha;
+ }
+ if (is708 && font1->hasOutline() != font2->hasOutline())
+ {
+ result << kSubAttrOutline;
+ QColor color1, color2;
+ int size1, size2;
+ int alpha1, alpha2;
+ font1->GetOutline(color1, size1, alpha1);
+ font2->GetOutline(color2, size2, alpha2);
+ if (color1 != color2)
+ result << kSubAttrOutlinecolor;
+ if (size1 != size2)
+ result << kSubAttrOutlinesize;
+ if (alpha1 != alpha2)
+ result << kSubAttrOutlinealpha;
+ }
+ if (bg1->m_fillBrush != bg2->m_fillBrush)
+ result << kSubAttrBGfill;
+
+ QString values = "";
+ QSet::const_iterator i = result.constBegin();
+ for (; i != result.constEnd(); ++i)
+ values += " " + (*i);
+ LOG(VB_VBI, LOG_INFO,
+ QString("Subtitle family %1 allows provider to change:%2")
+ .arg(MakePrefix(family, attr)).arg(values));
+
+ return result;
+}
+
+MythFontProperties *
+SubtitleFormat::GetFont(const QString &family,
+ const CC708CharacterAttribute &attr,
+ int pixelSize, bool isTeletext,
+ int zoom, int stretch)
+{
+ int origPixelSize = pixelSize;
+ float scale = zoom / 100.0;
+ if (isTeletext)
+ scale = scale * 17 / 25;
+ if ((attr.pen_size & 0x3) == k708AttrSizeSmall)
+ scale = scale * 32 / 42;
+ else if ((attr.pen_size & 0x3) == k708AttrSizeLarge)
+ scale = scale * 42 / 32;
+
+ QString prefix = MakePrefix(family, attr);
+ if (!m_fontMap.contains(prefix))
+ Load(family, attr);
+ MythFontProperties *result = m_fontMap[prefix];
+
+ // Apply the scaling factor to pixelSize even if the theme
+ // explicitly sets pixelSize.
+ if (!IsUnlocked(prefix, kSubAttrPixelsize))
+ pixelSize = m_pixelSizeMap[prefix];
+ pixelSize *= scale;
+ result->GetFace()->setPixelSize(pixelSize);
+
+ result->GetFace()->setStretch(stretch);
+ if (IsUnlocked(prefix, kSubAttrItalics))
+ result->GetFace()->setItalic(attr.italics);
+ if (IsUnlocked(prefix, kSubAttrUnderline))
+ result->GetFace()->setUnderline(attr.underline);
+ if (IsUnlocked(prefix, kSubAttrBold))
+ result->GetFace()->setBold(attr.boldface);
+ if (IsUnlocked(prefix, kSubAttrColor))
+ result->SetColor(attr.GetFGColor());
+ if (IsUnlocked(prefix, kSubAttrShadow))
+ {
+ QPoint offset;
+ QColor color;
+ int alpha;
+ bool shadow = result->hasShadow();
+ result->GetShadow(offset, color, alpha);
+ if (IsUnlocked(prefix, kSubAttrShadowcolor))
+ color = attr.GetEdgeColor();
+ if (IsUnlocked(prefix, kSubAttrShadowalpha))
+ alpha = attr.GetFGAlpha();
+ if (IsUnlocked(prefix, kSubAttrShadowoffset))
+ {
+ int off = pixelSize / 20;
+ offset = QPoint(off, off);
+ if (attr.edge_type == k708AttrEdgeLeftDropShadow)
+ {
+ shadow = true;
+ offset.setX(-off);
+ }
+ else if (attr.edge_type == k708AttrEdgeRightDropShadow)
+ shadow = true;
+ else
+ shadow = false;
+ }
+ result->SetShadow(shadow, offset, color, alpha);
+ }
+ if (IsUnlocked(prefix, kSubAttrOutline))
+ {
+ QColor color;
+ int off;
+ int alpha;
+ bool outline = result->hasOutline();
+ result->GetOutline(color, off, alpha);
+ if (IsUnlocked(prefix, kSubAttrOutlinecolor))
+ color = attr.GetEdgeColor();
+ if (IsUnlocked(prefix, kSubAttrOutlinealpha))
+ alpha = attr.GetFGAlpha();
+ if (IsUnlocked(prefix, kSubAttrOutlinesize))
+ {
+ if (attr.edge_type == k708AttrEdgeUniform ||
+ attr.edge_type == k708AttrEdgeRaised ||
+ attr.edge_type == k708AttrEdgeDepressed)
+ {
+ outline = true;
+ off = pixelSize / 20;
+ }
+ else
+ outline = false;
+ }
+ result->SetOutline(outline, color, off, alpha);
+ }
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("GetFont(family=%1, prefix=%2, orig pixelSize=%3, "
+ "new pixelSize=%4 zoom=%5) = %6")
+ .arg(family).arg(prefix).arg(origPixelSize).arg(pixelSize)
+ .arg(zoom).arg(fontToString(result)));
+ return result;
+}
+
+MythUIShape *
+SubtitleFormat::GetBackground(MythUIType *parent, const QString &name,
+ const QString &family,
+ const CC708CharacterAttribute &attr)
+{
+ QString prefix = MakePrefix(family, attr);
+ if (!m_shapeMap.contains(prefix))
+ Load(family, attr);
+ MythUIShape *result = new MythUIShape(parent, name);
+ result->CopyFrom(m_shapeMap[prefix]);
+ if (family == kSubFamily708)
+ {
+ if (IsUnlocked(prefix, kSubAttrBGfill))
+ {
+ result->SetFillBrush(QBrush(attr.GetBGColor()));
+ }
+ }
+ else if (family == kSubFamilyTeletext)
+ {
+ // add code here when teletextscreen.cpp is refactored
+ }
+ LOG(VB_VBI, LOG_DEBUG,
+ QString("GetBackground(prefix=%1) = "
+ "{type=%2 alpha=%3 brushstyle=%4 brushcolor=%5}")
+ .arg(prefix).arg(result->m_type).arg(result->GetAlpha())
+ .arg(result->m_fillBrush.style())
+ .arg(srtColorString(result->m_fillBrush.color())));
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
static const float PAD_WIDTH = 0.5;
static const float PAD_HEIGHT = 0.04;
@@ -23,11 +524,11 @@ SubtitleScreen::SubtitleScreen(MythPlayer *player, const char * name,
int fontStretch) :
MythScreenType((MythScreenType*)NULL, name),
m_player(player), m_subreader(NULL), m_608reader(NULL),
- m_708reader(NULL), m_safeArea(QRect()), m_useBackground(false),
+ m_708reader(NULL), m_safeArea(QRect()),
m_removeHTML(QRegExp("?.+>")), m_subtitleType(kDisplayNone),
m_textFontZoom(100), m_refreshArea(false),
m_fontStretch(fontStretch),
- m_fontsAreInitialized(false)
+ m_format(new SubtitleFormat)
{
m_removeHTML.setMinimal(true);
@@ -43,6 +544,7 @@ SubtitleScreen::SubtitleScreen(MythPlayer *player, const char * name,
SubtitleScreen::~SubtitleScreen(void)
{
ClearAllSubtitles();
+ delete m_format;
#ifdef USING_LIBASS
CleanupAssLibrary();
#endif
@@ -71,6 +573,19 @@ void SubtitleScreen::EnableSubtitles(int type, bool forced_only)
ClearAllSubtitles();
SetVisible(m_subtitleType != kDisplayNone);
SetArea(MythRect());
+ switch (m_subtitleType)
+ {
+ case kDisplayTextSubtitle:
+ case kDisplayRawTextSubtitle:
+ m_family = kSubFamilyText;
+ break;
+ case kDisplayCC608:
+ m_family = kSubFamily608;
+ break;
+ case kDisplayCC708:
+ m_family = kSubFamily708;
+ break;
+ }
}
void SubtitleScreen::DisableForcedSubtitles(void)
@@ -96,20 +611,8 @@ bool SubtitleScreen::Create(void)
LOG(VB_GENERAL, LOG_WARNING, LOC + "Failed to get CEA-608 reader.");
if (!m_708reader)
LOG(VB_GENERAL, LOG_WARNING, LOC + "Failed to get CEA-708 reader.");
- m_useBackground = (bool)gCoreContext->GetNumSetting("CCBackground", 0);
m_textFontZoom = gCoreContext->GetNumSetting("OSDCC708TextZoom", 100);
- QString defaultFont =
- gCoreContext->GetSetting("DefaultSubtitleFont", "FreeMono");
- m_fontNames.append(defaultFont); // default
- m_fontNames.append("FreeMono"); // mono serif
- m_fontNames.append("DejaVu Serif"); // prop serif
- m_fontNames.append("Droid Sans Mono"); // mono sans
- m_fontNames.append("Liberation Sans"); // prop sans
- m_fontNames.append("Purisa"); // casual
- m_fontNames.append("URW Chancery L"); // cursive
- m_fontNames.append("Impact"); // capitals
-
return true;
}
@@ -363,17 +866,9 @@ void SubtitleScreen::DisplayTextSubtitles(void)
bool changed = false;
VideoOutput *vo = m_player->GetVideoOutput();
- if (vo)
- {
- QRect oldsafe = m_safeArea;
- m_safeArea = vo->GetSafeRect();
- changed = (oldsafe != m_safeArea);
- InitializeFonts(changed);
- }
- else
- {
+ if (!vo)
return;
- }
+ m_safeArea = vo->GetSafeRect();
VideoFrame *currentFrame = vo->GetLastShownFrame();
if (!currentFrame)
@@ -450,11 +945,7 @@ void SubtitleScreen::DisplayRawTextSubtitles(void)
if (!currentFrame)
return;
- bool changed = false;
- QRect oldsafe = m_safeArea;
m_safeArea = vo->GetSafeRect();
- changed = (oldsafe != m_safeArea);
- InitializeFonts(changed);
// delete old subs that may still be on screen
DeleteAllChildren();
@@ -464,11 +955,11 @@ void SubtitleScreen::DisplayRawTextSubtitles(void)
void SubtitleScreen::DrawTextSubtitles(QStringList &wrappedsubs,
uint64_t start, uint64_t duration)
{
- FormattedTextSubtitle fsub(m_safeArea, m_useBackground, this);
+ FormattedTextSubtitle fsub(m_safeArea, this);
fsub.InitFromSRT(wrappedsubs, m_textFontZoom);
fsub.WrapLongLines();
fsub.Layout();
- m_refreshArea = fsub.Draw(0, start, duration) || m_refreshArea;
+ m_refreshArea = fsub.Draw(m_family, NULL, start, duration) || m_refreshArea;
}
void SubtitleScreen::DisplayDVDButton(AVSubtitle* dvdButton, QRect &buttonPos)
@@ -607,18 +1098,9 @@ void SubtitleScreen::DisplayCC608Subtitles(void)
bool changed = false;
- if (m_player && m_player->GetVideoOutput())
- {
- QRect oldsafe = m_safeArea;
- m_safeArea = m_player->GetVideoOutput()->GetSafeRect();
- if (oldsafe != m_safeArea)
- changed = true;
- }
- else
- {
+ if (!m_player || !m_player->GetVideoOutput())
return;
- }
- InitializeFonts(changed);
+ m_safeArea = m_player->GetVideoOutput()->GetSafeRect();
CC608Buffer* textlist = m_608reader->GetOutputText(changed);
if (!changed)
@@ -639,11 +1121,11 @@ void SubtitleScreen::DisplayCC608Subtitles(void)
return;
}
- FormattedTextSubtitle fsub(m_safeArea, m_useBackground, this);
+ FormattedTextSubtitle fsub(m_safeArea, this);
fsub.InitFromCC608(textlist->buffers, m_textFontZoom);
fsub.Layout608();
fsub.Layout();
- m_refreshArea = fsub.Draw() || m_refreshArea;
+ m_refreshArea = fsub.Draw(m_family) || m_refreshArea;
textlist->lock.unlock();
}
@@ -672,8 +1154,6 @@ void SubtitleScreen::DisplayCC708Subtitles(void)
return;
}
- InitializeFonts(changed);
-
for (uint i = 0; i < 8; i++)
{
CC708Window &win = cc708service->windows[i];
@@ -688,7 +1168,7 @@ void SubtitleScreen::DisplayCC708Subtitles(void)
vector list = win.GetStrings();
if (!list.empty())
{
- FormattedTextSubtitle fsub(m_safeArea, m_useBackground, this);
+ FormattedTextSubtitle fsub(m_safeArea, this);
fsub.InitFromCC708(win, i, list, video_aspect, m_textFontZoom);
fsub.Layout();
// Draw the window background after calculating bounding
@@ -704,7 +1184,7 @@ void SubtitleScreen::DisplayCC708Subtitles(void)
m_refreshArea = true;
}
m_refreshArea =
- fsub.Draw(&m_708imageCache[i]) || m_refreshArea;
+ fsub.Draw(m_family, &m_708imageCache[i]) || m_refreshArea;
}
for (uint j = 0; j < list.size(); j++)
delete list[j];
@@ -753,73 +1233,11 @@ void SubtitleScreen::AddScaledImage(QImage &img, QRect &pos)
}
}
-void SubtitleScreen::InitializeFonts(bool wasResized)
+MythFontProperties* SubtitleScreen::GetFont(CC708CharacterAttribute attr,
+ bool teletext) const
{
- if (!m_fontsAreInitialized)
- {
- int count = 0;
- foreach(QString font, m_fontNames)
- {
- MythFontProperties *mythfont = new MythFontProperties();
- QFont newfont(font);
- newfont.setStretch(m_fontStretch);
- font.detach();
- mythfont->SetFace(newfont);
- m_fontSet.insert(count, mythfont);
- count++;
- }
- }
-
- if (wasResized || !m_fontsAreInitialized)
- {
- foreach(MythFontProperties* font, m_fontSet)
- font->face().setStretch(m_fontStretch);
- // XXX reset font sizes
- }
-
- m_fontsAreInitialized = true;
-}
-
-MythFontProperties* SubtitleScreen::Get708Font(CC708CharacterAttribute attr)
- const
-{
- MythFontProperties *mythfont = m_fontSet[attr.font_tag & 0x7];
- if (!mythfont)
- return NULL;
-
- mythfont->GetFace()->setItalic(attr.italics);
- mythfont->GetFace()->setPixelSize(m_708fontSizes[attr.pen_size & 0x3]);
- mythfont->GetFace()->setUnderline(attr.underline);
- mythfont->GetFace()->setBold(attr.boldface);
- mythfont->SetColor(attr.GetFGColor());
-
- int off = m_708fontSizes[attr.pen_size & 0x3] / 20;
- QPoint shadowsz(off, off);
- QColor colour = attr.GetEdgeColor();
- int alpha = attr.GetFGAlpha();
- bool outline = false;
- bool shadow = false;
-
- if (attr.edge_type == k708AttrEdgeLeftDropShadow)
- {
- shadow = true;
- shadowsz.setX(-off);
- }
- else if (attr.edge_type == k708AttrEdgeRightDropShadow)
- {
- shadow = true;
- }
- else if (attr.edge_type == k708AttrEdgeUniform ||
- attr.edge_type == k708AttrEdgeRaised ||
- attr.edge_type == k708AttrEdgeDepressed)
- {
- outline = true;
- }
-
- mythfont->SetOutline(outline, colour, off, alpha);
- mythfont->SetShadow(shadow, shadowsz, colour, alpha);
-
- return mythfont;
+ return m_format->GetFont(m_family, attr, m_fontSize,
+ teletext, m_textFontZoom, m_fontStretch);
}
static QString srtColorString(QColor color)
@@ -843,20 +1261,21 @@ void FormattedTextSubtitle::InitFromCC608(vector &buffers,
return;
vector::iterator i = buffers.begin();
bool teletextmode = (*i)->teletextmode;
- bool useBackground = m_useBackground && !teletextmode;
int xscale = teletextmode ? 40 : 36;
int yscale = teletextmode ? 25 : 17;
- int pixelSize = m_safeArea.height() * textFontZoom
- / (yscale * LINE_SPACING * 100);
+ // For the purpose of pixel size calculation, use a normalized
+ // size based on 17 non-teletext rows rather than 25. The
+ // shrinking is done in GetFont so that the theme can supply a
+ // uniform normalized pixelsize value.
+ int pixelSize = m_safeArea.height() / (/*yscale*/17 * LINE_SPACING);
int fontwidth = 0;
int xmid = 0;
if (parent)
{
- parent->SetFontSizes(pixelSize, pixelSize, pixelSize);
- CC708CharacterAttribute def_attr(false, false, false, clr[0],
- useBackground);
- QFont *font = parent->Get708Font(def_attr)->GetFace();
+ parent->SetFontSize(pixelSize);
+ CC708CharacterAttribute def_attr(false, false, false, clr[0]);
+ QFont *font = parent->GetFont(def_attr, teletextmode)->GetFace();
QFontMetrics fm(*font);
fontwidth = fm.averageCharWidth();
xmid = m_safeArea.width() / 2;
@@ -903,9 +1322,9 @@ void FormattedTextSubtitle::InitFromCC608(vector &buffers,
extract_cc608(text, cc->teletextmode,
color, isItalic, isUnderline);
CC708CharacterAttribute attr(isItalic, isBold, isUnderline,
- clr[min(max(0, color), 7)],
- useBackground);
- FormattedTextChunk chunk(captionText, attr, parent);
+ clr[min(max(0, color), 7)]);
+ FormattedTextChunk chunk(captionText, attr, parent,
+ cc->teletextmode);
line.chunks += chunk;
LOG(VB_VBI, LOG_INFO,
QString("Adding cc608 chunk (%1,%2): %3")
@@ -925,9 +1344,9 @@ void FormattedTextSubtitle::InitFromCC708(const CC708Window &win, int num,
"relative %5")
.arg(num).arg(win.anchor_point).arg(win.anchor_horizontal)
.arg(win.anchor_vertical).arg(win.relative_pos));
- int pixelSize = (m_safeArea.height() * textFontZoom) / 2000;
+ int pixelSize = m_safeArea.height() / 20;
if (parent)
- parent->SetFontSizes(pixelSize * 32 / 42, pixelSize, pixelSize * 42 / 32);
+ parent->SetFontSize(pixelSize);
float xrange = win.relative_pos ? 100.0f :
(aspect > 1.4f) ? 210.0f : 160.0f;
@@ -945,11 +1364,6 @@ void FormattedTextSubtitle::InitFromCC708(const CC708Window &win, int num,
{
if (list[i]->y >= (uint)m_lines.size())
m_lines.resize(list[i]->y + 1);
- if (m_useBackground)
- {
- list[i]->attr.bg_color = k708AttrColorBlack;
- list[i]->attr.bg_opacity = k708AttrOpacitySolid;
- }
FormattedTextChunk chunk(list[i]->str, list[i]->attr, parent);
m_lines[list[i]->y].chunks += chunk;
LOG(VB_VBI, LOG_INFO, QString("Adding cc708 chunk: win %1 row %2: %3")
@@ -973,9 +1387,9 @@ void FormattedTextSubtitle::InitFromSRT(QStringList &subs, int textFontZoom)
// - change font color
// - reset font color to white
- int pixelSize = (m_safeArea.height() * textFontZoom) / 2000;
+ int pixelSize = m_safeArea.height() / 20;
if (parent)
- parent->SetFontSizes(pixelSize, pixelSize, pixelSize);
+ parent->SetFontSize(pixelSize);
m_xAnchorPoint = 1; // center
m_yAnchorPoint = 2; // bottom
m_xAnchor = m_safeArea.width() / 2;
@@ -998,7 +1412,7 @@ void FormattedTextSubtitle::InitFromSRT(QStringList &subs, int textFontZoom)
if (pos != 0) // don't add a zero-length string
{
CC708CharacterAttribute attr(isItalic, isBold, isUnderline,
- color, m_useBackground);
+ color);
FormattedTextChunk chunk(text.left(pos), attr, parent);
line.chunks += chunk;
text = (pos < 0 ? "" : text.mid(pos));
@@ -1072,6 +1486,7 @@ bool FormattedTextChunk::Split(FormattedTextChunk &newChunk)
QString("Failed to split chunk '%1'").arg(text));
return false;
}
+ newChunk.isTeletext = isTeletext;
newChunk.parent = parent;
newChunk.format = format;
newChunk.text = text.mid(lastSpace + 1).trimmed() + ' ';
@@ -1268,7 +1683,8 @@ void FormattedTextSubtitle::Layout(void)
// Returns true if anything new was drawn, false if not. The caller
// should call SubtitleScreen::OptimiseDisplayedArea() if true is
// returned.
-bool FormattedTextSubtitle::Draw(QList *imageCache,
+bool FormattedTextSubtitle::Draw(const QString &base,
+ QList *imageCache,
uint64_t start, uint64_t duration) const
{
bool result = false;
@@ -1285,7 +1701,8 @@ bool FormattedTextSubtitle::Draw(QList *imageCache,
chunk != m_lines[i].chunks.constEnd();
++chunk)
{
- MythFontProperties *mythfont = parent->Get708Font((*chunk).format);
+ MythFontProperties *mythfont =
+ parent->GetFont((*chunk).format, (*chunk).isTeletext);
if (!mythfont)
continue;
QFontMetrics font(*(mythfont->GetFace()));
@@ -1301,37 +1718,36 @@ bool FormattedTextSubtitle::Draw(QList *imageCache,
++count;
}
int x_adjust = count * font.width(" ");
- int padding = (*chunk).CalcPadding();
+ int leftPadding = (*chunk).CalcPadding(true);
+ int rightPadding = (*chunk).CalcPadding(false);
// Account for extra padding before the first chunk.
if (first)
- x += padding;
+ x += leftPadding;
QSize chunk_sz = (*chunk).CalcSize();
- if ((*chunk).format.GetBGAlpha())
- {
- QBrush bgfill = QBrush((*chunk).format.GetBGColor());
- QRect bgrect(x - padding, y,
- chunk_sz.width() + 2 * padding, height);
- // Don't draw a background behind leading spaces.
- if (first)
- bgrect.setLeft(bgrect.left() + x_adjust);
- MythUIShape *bgshape = new MythUIShape(parent,
- QString("subbg%1x%2@%3,%4")
- .arg(chunk_sz.width())
- .arg(height)
- .arg(x).arg(y));
- bgshape->SetFillBrush(bgfill);
- bgshape->SetArea(MythRect(bgrect));
- if (imageCache)
- imageCache->append(bgshape);
- if (duration > 0)
- parent->RegisterExpiration(bgshape, start + duration);
- result = true;
- }
+ QRect bgrect(x - leftPadding, y,
+ chunk_sz.width() + leftPadding + rightPadding,
+ height);
+ // Don't draw a background behind leading spaces.
+ if (first)
+ bgrect.setLeft(bgrect.left() + x_adjust);
+ MythUIShape *bgshape =
+ parent->m_format->
+ GetBackground(parent,
+ QString("subbg%1x%2@%3,%4")
+ .arg(chunk_sz.width()).arg(height)
+ .arg(x).arg(y),
+ base, (*chunk).format);
+ bgshape->SetArea(MythRect(bgrect));
+ if (imageCache)
+ imageCache->append(bgshape);
+ if (duration > 0)
+ parent->RegisterExpiration(bgshape, start + duration);
+ result = true;
// Shift to the right to account for leading spaces that
// are removed by the MythUISimpleText constructor. Also
// add in padding at the end to avoid clipping.
QRect rect(x + x_adjust, y,
- chunk_sz.width() - x_adjust + padding, height);
+ chunk_sz.width() - x_adjust + rightPadding, height);
MythUISimpleText *text =
new MythUISimpleText((*chunk).text, *mythfont, rect,
@@ -1409,31 +1825,71 @@ QStringList FormattedTextSubtitle::ToSRT(void) const
return result;
}
-void SubtitleScreen::SetFontSizes(int nSmall, int nMedium, int nLarge)
+// The QFontMetrics class does not account for the MythFontProperties
+// shadow and offset properties. This method calculates the
+// additional padding to the right and below that is needed for proper
+// bounding box computation.
+static QSize CalcShadowOffsetPadding(MythFontProperties *mythfont)
{
- m_708fontSizes[k708AttrSizeSmall] = nSmall;
- m_708fontSizes[k708AttrSizeStandard] = nMedium;
- m_708fontSizes[k708AttrSizeLarge] = nLarge;
+ QColor color;
+ int alpha;
+ int outlineSize = 0;
+ int shadowWidth = 0, shadowHeight = 0;
+ if (mythfont->hasOutline())
+ {
+ mythfont->GetOutline(color, outlineSize, alpha);
+ }
+ if (mythfont->hasShadow())
+ {
+ QPoint shadowOffset;
+ mythfont->GetShadow(shadowOffset, color, alpha);
+ shadowWidth = abs(shadowOffset.x());
+ shadowHeight = abs(shadowOffset.y());
+ // Shadow and outline overlap, so don't just add them.
+ shadowWidth = max(shadowWidth, outlineSize);
+ shadowHeight = max(shadowHeight, outlineSize);
+ }
+ return QSize(shadowWidth + outlineSize, shadowHeight + outlineSize);
}
QSize SubtitleScreen::CalcTextSize(const QString &text,
const CC708CharacterAttribute &format,
+ bool teletext,
float layoutSpacing) const
{
- QFont *font = Get708Font(format)->GetFace();
+ MythFontProperties *mythfont = GetFont(format, teletext);
+ QFont *font = mythfont->GetFace();
QFontMetrics fm(*font);
int width = fm.width(text);
int height = fm.height() * (1 + PAD_HEIGHT);
if (layoutSpacing > 0 && !text.trimmed().isEmpty())
height = max(height, (int)(font->pixelSize() * layoutSpacing));
+ height += CalcShadowOffsetPadding(mythfont).height();
return QSize(width, height);
}
-int SubtitleScreen::CalcPadding(const CC708CharacterAttribute &format) const
+// Padding calculation is different depending on whether the padding
+// is on the left side or the right side of the text. Padding on the
+// right needs to add the shadow and offset padding.
+int SubtitleScreen::CalcPadding(const CC708CharacterAttribute &format,
+ bool teletext, bool isLeft) const
{
- QFont *font = Get708Font(format)->GetFace();
+ MythFontProperties *mythfont = GetFont(format, teletext);
+ QFont *font = mythfont->GetFace();
QFontMetrics fm(*font);
- return fm.maxWidth() * PAD_WIDTH;
+ int result = fm.maxWidth() * PAD_WIDTH;
+ if (!isLeft)
+ result += CalcShadowOffsetPadding(mythfont).width();
+ return result;
+}
+
+QString SubtitleScreen::GetTeletextFontName(void)
+{
+ SubtitleFormat format;
+ CC708CharacterAttribute attr(false, false, false, Qt::white);
+ MythFontProperties *mythfont =
+ format.GetFont(kSubFamilyTeletext, attr, 20, false, 100, 100);
+ return mythfont->face().family();
}
#ifdef USING_LIBASS
diff --git a/mythtv/libs/libmythtv/subtitlescreen.h b/mythtv/libs/libmythtv/subtitlescreen.h
index 30c8e660300..1fe310eaddb 100644
--- a/mythtv/libs/libmythtv/subtitlescreen.h
+++ b/mythtv/libs/libmythtv/subtitlescreen.h
@@ -41,15 +41,19 @@ class SubtitleScreen : public MythScreenType
QSize CalcTextSize(const QString &text,
const CC708CharacterAttribute &format,
+ bool teletext,
float layoutSpacing) const;
- int CalcPadding(const CC708CharacterAttribute &format) const;
+ int CalcPadding(const CC708CharacterAttribute &format,
+ bool teletext, bool isLeft) const;
void RegisterExpiration(MythUIType *shape, long long endTime)
{
m_expireTimes.insert(shape, endTime);
}
- bool GetUseBackground(void) { return m_useBackground; }
+ // Temporary method until teletextscreen.cpp is refactored into
+ // subtitlescreen.cpp
+ static QString GetTeletextFontName(void);
// MythScreenType methods
virtual bool Create(void);
@@ -67,26 +71,25 @@ class SubtitleScreen : public MythScreenType
void AddScaledImage(QImage &img, QRect &pos);
void Clear708Cache(int num);
void InitializeFonts(bool wasResized);
- MythFontProperties* Get708Font(CC708CharacterAttribute attr) const;
- void SetFontSizes(int nSmall, int nMedium, int nLarge);
+ MythFontProperties* GetFont(CC708CharacterAttribute attr,
+ bool teletext) const;
+ void SetFontSize(int pixelSize) { m_fontSize = pixelSize; }
MythPlayer *m_player;
SubtitleReader *m_subreader;
CC608Reader *m_608reader;
CC708Reader *m_708reader;
QRect m_safeArea;
- bool m_useBackground;
QRegExp m_removeHTML;
int m_subtitleType;
QHash m_expireTimes;
- int m_708fontSizes[4];
+ int m_fontSize;
int m_textFontZoom; // valid for 708 & text subs
bool m_refreshArea;
QHash > m_708imageCache;
int m_fontStretch;
- bool m_fontsAreInitialized;
- QStringList m_fontNames;
- QHash m_fontSet;
+ QString m_family; // 608, 708, text, teletext
+ class SubtitleFormat *m_format;
#ifdef USING_LIBASS
bool InitialiseAssLibrary(void);
@@ -110,19 +113,19 @@ class FormattedTextChunk
{
public:
FormattedTextChunk(const QString &t, CC708CharacterAttribute formatting,
- SubtitleScreen *p)
- : text(t), format(formatting), parent(p)
+ SubtitleScreen *p, bool teletext = false)
+ : text(t), format(formatting), parent(p), isTeletext(teletext)
{
}
FormattedTextChunk(void) : parent(NULL) {}
QSize CalcSize(float layoutSpacing = 0.0f) const
{
- return parent->CalcTextSize(text, format, layoutSpacing);
+ return parent->CalcTextSize(text, format, isTeletext, layoutSpacing);
}
- int CalcPadding(void) const
+ int CalcPadding(bool isLeft) const
{
- return parent->CalcPadding(format);
+ return parent->CalcPadding(format, isTeletext, isLeft);
}
bool Split(FormattedTextChunk &newChunk);
QString ToLogString(void) const;
@@ -130,6 +133,7 @@ class FormattedTextChunk
QString text;
CC708CharacterAttribute format;
SubtitleScreen *parent; // where fonts and sizes are kept
+ bool isTeletext;
};
class FormattedTextLine
@@ -141,18 +145,19 @@ class FormattedTextLine
QSize CalcSize(float layoutSpacing = 0.0f) const
{
int height = 0, width = 0;
- int padding = 0;
+ int leftPadding = 0, rightPadding = 0;
QList::const_iterator it;
for (it = chunks.constBegin(); it != chunks.constEnd(); ++it)
{
QSize tmp = (*it).CalcSize(layoutSpacing);
height = max(height, tmp.height());
width += tmp.width();
- padding = (*it).CalcPadding();
+ leftPadding = (*it).CalcPadding(true);
+ rightPadding = (*it).CalcPadding(false);
if (it == chunks.constBegin())
- width += padding;
+ width += leftPadding;
}
- return QSize(width + padding, height);
+ return QSize(width + rightPadding, height);
}
QList chunks;
@@ -164,10 +169,8 @@ class FormattedTextLine
class FormattedTextSubtitle
{
public:
- FormattedTextSubtitle(const QRect &safearea, bool useBackground,
- SubtitleScreen *p)
- : m_safeArea(safearea), m_useBackground(useBackground),
- parent(p)
+ FormattedTextSubtitle(const QRect &safearea, SubtitleScreen *p)
+ : m_safeArea(safearea), parent(p)
{
// make cppcheck happy
m_xAnchorPoint = 0;
@@ -176,7 +179,7 @@ class FormattedTextSubtitle
m_yAnchor = 0;
}
FormattedTextSubtitle(void)
- : m_safeArea(QRect()), m_useBackground(false), parent(NULL)
+ : m_safeArea(QRect()), parent(NULL)
{
// make cppcheck happy
m_xAnchorPoint = 0;
@@ -193,7 +196,7 @@ class FormattedTextSubtitle
void WrapLongLines(void);
void Layout(void);
void Layout608(void);
- bool Draw(QList *imageCache = 0,
+ bool Draw(const QString &base, QList *imageCache = NULL,
uint64_t start = 0, uint64_t duration = 0) const;
QStringList ToSRT(void) const;
QRect m_bounds;
@@ -201,7 +204,6 @@ class FormattedTextSubtitle
private:
QVector m_lines;
const QRect m_safeArea;
- const bool m_useBackground;
SubtitleScreen *parent; // where fonts and sizes are kept
int m_xAnchorPoint; // 0=left, 1=center, 2=right
int m_yAnchorPoint; // 0=top, 1=center, 2=bottom
diff --git a/mythtv/libs/libmythtv/teletextscreen.cpp b/mythtv/libs/libmythtv/teletextscreen.cpp
index 6bb0e137c11..69dd8101dfe 100644
--- a/mythtv/libs/libmythtv/teletextscreen.cpp
+++ b/mythtv/libs/libmythtv/teletextscreen.cpp
@@ -10,6 +10,7 @@
#include "mythuiimage.h"
#include "mythpainter.h"
#include "teletextscreen.h"
+#include "subtitlescreen.h"
#define LOC QString("TeletextScreen: ")
@@ -678,15 +679,19 @@ void TeletextScreen::DrawStatus(void)
bool TeletextScreen::InitialiseFont()
{
static bool initialised = false;
- QString font = gCoreContext->GetSetting("DefaultSubtitleFont", "FreeMono");
+ //QString font = gCoreContext->GetSetting("DefaultSubtitleFont", "FreeMono");
if (initialised)
{
+ return true;
+#if 0
if (gTTFont->face().family() == font)
return true;
delete gTTFont;
+#endif // 0
}
MythFontProperties *mythfont = new MythFontProperties();
+ QString font = SubtitleScreen::GetTeletextFontName();
if (mythfont)
{
QFont newfont(font);
diff --git a/mythtv/libs/libmythui/mythuishape.h b/mythtv/libs/libmythui/mythuishape.h
index b078e463618..15c363fb91e 100644
--- a/mythtv/libs/libmythui/mythuishape.h
+++ b/mythtv/libs/libmythui/mythuishape.h
@@ -46,6 +46,7 @@ class MUI_PUBLIC MythUIShape : public MythUIType
friend class MythUIProgressBar;
friend class MythUIEditBar;
+ friend class SubtitleFormat;
};
#endif
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp
index 806ad7eb154..9f9ee5a695d 100644
--- a/mythtv/programs/mythfrontend/globalsettings.cpp
+++ b/mythtv/programs/mythfrontend/globalsettings.cpp
@@ -1405,23 +1405,6 @@ static HostSpinBox *OSDCC708TextZoomPercentage(void)
return gs;
}
-static HostComboBox *SubtitleFont()
-{
- HostComboBox *hcb = new HostComboBox("DefaultSubtitleFont");
- QFontDatabase db;
- QStringList fonts = db.families();
- QStringList hide = db.families(QFontDatabase::Symbol);
-
- hcb->setLabel(QObject::tr("Subtitle Font"));
- hcb->setHelpText(QObject::tr("The font to use for text based subtitles."));
- foreach (QString font, fonts)
- {
- if (!hide.contains(font))
- hcb->addSelection(font, font, font.toLower() == "freemono");
- }
- return hcb;
-}
-
static HostComboBox *SubtitleCodec()
{
HostComboBox *gc = new HostComboBox("SubtitleCodec");
@@ -1486,18 +1469,6 @@ static HostSpinBox *YScanDisplacement()
return gs;
};
-static HostCheckBox *CCBackground()
-{
- HostCheckBox *gc = new HostCheckBox("CCBackground");
- gc->setLabel(QObject::tr("Black background for closed captioning"));
- gc->setValue(false);
- gc->setHelpText(QObject::tr(
- "If enabled, captions will be displayed "
- "over a black background "
- "for better contrast."));
- return gc;
-}
-
static HostCheckBox *DefaultCCMode()
{
HostCheckBox *gc = new HostCheckBox("DefaultCCMode");
@@ -3530,9 +3501,7 @@ OSDSettings::OSDSettings()
osd->addChild(EnableMHEG());
osd->addChild(PersistentBrowseMode());
osd->addChild(BrowseAllTuners());
- osd->addChild(CCBackground());
osd->addChild(DefaultCCMode());
- osd->addChild(SubtitleFont());
osd->addChild(OSDCC708TextZoomPercentage());
osd->addChild(SubtitleCodec());
addChild(osd);
diff --git a/mythtv/themes/default/osd_subtitle.xml b/mythtv/themes/default/osd_subtitle.xml
new file mode 100644
index 00000000000..7c45f0f4098
--- /dev/null
+++ b/mythtv/themes/default/osd_subtitle.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+ box
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+