/// <summary> /// Reset the selected caption to parse it with the new settings. /// </summary> /// <param name="settings">the updated caption settings</param> public override void OnApplyCaptionSettings(CustomCaptionSettings settings) { if (settings == null) { var selectedCaptions = this.MediaPlayer.SelectedCaption; this.MediaPlayer.SelectedCaption = null; this.MediaPlayer.SelectedCaption = selectedCaptions; } }
/// <summary> /// Gets the Windows Phone 8 font family from the user settings Font Family /// </summary> /// <param name="userSettings">the user settings</param> /// <returns>the font family</returns> /// <remarks>See /// <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/cc189010(v=vs.105).aspx#silverlight_fonts">Text and fonts for Windows Phone</a> /// for more details on the fonts available for Windows Phone 8. /// </remarks> public static FF.FontFamily GetFontFamily(CustomCaptionSettings userSettings) { if (fontMap == null) { fontMap = new Dictionary<Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily, FF.FontFamily>(); fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.Default] = null; fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.MonospaceSerif] = new FF.FontFamily("Courier New"); fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.ProportionalSerif] = new FF.FontFamily("Times New Roman"); fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.MonospaceSansSerif] = new FF.FontFamily("Calibri"); fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.ProportionalSansSerif] = new FF.FontFamily("Tahoma"); fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.Casual] = new FF.FontFamily("Comic Sans MS"); // Since Windows Phone 8 does not ship with a cursive font, we use this. fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.Cursive] = new FF.FontFamily("Calibri Italic Light"); // _Smallcaps is a unique keyword that will trigger the usage of Typography.SetCapitals(textblock, FontCapitals.SmallCaps) // and the default font. fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.Smallcaps] = new FF.FontFamily("_Smallcaps"); } var fontName = fontMap[userSettings.FontFamily]; return fontName; }
/// <summary> /// Recursively apply the settings to the UI elements /// </summary> /// <param name="element">a UI Element</param> /// <param name="settings">the custom caption settings</param> /// <param name="parent">the parent element</param> /// <param name="isRoot">true if this is the root node</param> public void ApplySettings(UIElement element, CustomCaptionSettings settings, UIElement parent, bool isRoot = false) { if (settings == null) { return; } var panel = element as StackPanel; var border = element as Border; var textBlock = element as TextBlock; var grid = element as Grid; if (panel != null) { this.ApplyPanel(settings, isRoot, panel); } else if (border != null) { this.ApplyBorder(settings, border); } else if (textBlock != null) { this.ApplyText(settings, textBlock, parent); } else if (grid != null) { foreach (var item in grid.Children) { this.ApplySettings(item, settings, grid, true); } } else { System.Diagnostics.Debugger.Break(); } }
/// <summary> /// update the capitals for all of the TextBlock elements in a panel. /// </summary> /// <param name="customCaptionSettings">the custom caption settings /// </param> /// <param name="panel">the panel</param> /// <exception cref="ArgumentNullException">if customCaptionSettings /// or panel are null.</exception> private static void UpdateCaptials( CustomCaptionSettings customCaptionSettings, Panel panel) { if (customCaptionSettings == null) { throw new ArgumentNullException( "customCaptionSettings", "customCaptionSettings cannot be null."); } if (panel == null) { return; } var children = panel.Children.OfType<TextBlock>(); foreach (var item in children) { if (customCaptionSettings.FontFamily == Model.FontFamily.Smallcaps) { Typography.SetCapitals(item, FontCapitals.SmallCaps); } else { Typography.SetCapitals(item, FontCapitals.Normal); } } }
/// <summary> /// update the capitals for all of the TextBlock elements in a panel. /// </summary> /// <param name="customCaptionSettings">the custom caption settings /// </param> /// <param name="panel">the panel</param> /// <exception cref="ArgumentNullException">if customCaptionSettings /// or panel are null.</exception> private static void UpdateCaptials( CustomCaptionSettings customCaptionSettings, Panel panel) { if (customCaptionSettings == null) { throw new ArgumentNullException( "customCaptionSettings", "customCaptionSettings cannot be null."); } if (panel == null) { throw new ArgumentNullException( "panel", "panel cannot be null."); } var children = panel.Children.OfType<TextBlock>(); foreach (var item in children) { if (customCaptionSettings.FontFamily == Model.FontFamily.Smallcaps) { Typography.SetCapitals(item, FontCapitals.SmallCaps); } else { Typography.SetCapitals(item, FontCapitals.Normal); } ////System.Diagnostics.Debug.WriteLine("Captials for {0} are {1}", item.Name, Typography.GetCapitals(item)); } }
/// <summary> /// Gets the font family from the user settings Font /// </summary> /// <param name="userSettings">the user settings</param> /// <returns>the font family</returns> private static FF.FontFamily GetFontFamily(CustomCaptionSettings userSettings) { if (fontMap == null) { fontMap = new Dictionary<Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily, FF.FontFamily>(); // _Smallcaps is a unique keyword that will trigger the usage of Typography.SetCapitals(textblock, FontCapitals.SmallCaps) // and the default font. fontMap[Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily.Smallcaps] = new FF.FontFamily("_Smallcaps"); } FF.FontFamily fontFamily; if (fontMap.TryGetValue(userSettings.FontFamily, out fontFamily)) { return fontFamily; } var name = GetFontFamilyName(userSettings.FontFamily); if (name == null) { return null; } fontFamily = new FF.FontFamily(name); fontMap[userSettings.FontFamily] = fontFamily; return fontFamily; }
/// <summary> /// Apply the font style /// </summary> /// <param name="captionElement">the caption element</param> /// <param name="userSettings">the user settings</param> private static void ApplyFontStyle(TimedTextElement captionElement, CustomCaptionSettings userSettings) { var outlineWidth = 1.0; if (userSettings.FontSize.HasValue) { outlineWidth = System.Convert.ToDouble(userSettings.FontSize.Value) / 100.0; } var outlineColor = Media.Colors.Black; if (userSettings.FontColor != null) { outlineColor = Media.Color.FromArgb(255, 0, 0, 0); } switch (userSettings.FontStyle) { case FontStyle.Default: captionElement.Style.TextStyle = TextStyle.Default; // Todo: look at code for calculation of OutlineWidth and OutlineBlur captionElement.Style.OutlineWidth = new Length { Value = outlineWidth, Unit = LengthUnit.Pixel }; captionElement.Style.OutlineColor = outlineColor; break; case FontStyle.DepressedEdge: captionElement.Style.TextStyle = TextStyle.DepressedEdge; captionElement.Style.OutlineColor = outlineColor; captionElement.Style.OutlineWidth = new Length { Value = outlineWidth, Unit = LengthUnit.Pixel }; break; case FontStyle.DropShadow: captionElement.Style.TextStyle = TextStyle.DropShadow; // Todo: look at code for calculation of OutlineWidth and OutlineBlur captionElement.Style.OutlineColor = outlineColor; captionElement.Style.OutlineWidth = new Length { Value = outlineWidth, Unit = LengthUnit.Pixel }; break; case FontStyle.None: captionElement.Style.TextStyle = TextStyle.None; break; case FontStyle.Outline: captionElement.Style.TextStyle = TextStyle.Outline; captionElement.Style.OutlineWidth = new Length { Value = outlineWidth, Unit = LengthUnit.Pixel }; captionElement.Style.OutlineColor = outlineColor; break; case FontStyle.RaisedEdge: captionElement.Style.TextStyle = TextStyle.RaisedEdge; captionElement.Style.OutlineWidth = new Length { Value = outlineWidth, Unit = LengthUnit.Pixel }; captionElement.Style.OutlineColor = outlineColor; break; } }
/// <summary> /// Recursively update the caption elements /// </summary> /// <param name="captionElement">the caption element</param> /// <param name="userSettings">the user settings</param> /// <param name="level">the 0-based level of the caption element</param> private static void UpdateElement( TimedTextElement captionElement, CustomCaptionSettings userSettings, uint level) { if (level == 0) { if (userSettings.WindowColor != null) { captionElement.Style.BackgroundColor = userSettings.WindowColor.ToColor(); } } else if (level == 1) { if (userSettings.BackgroundColor != null) { captionElement.Style.BackgroundColor = userSettings.BackgroundColor.ToColor(); } } if (userSettings.FontColor != null) { captionElement.Style.Color = userSettings.FontColor.ToColor(); } if (userSettings.FontSize.HasValue) { captionElement.Style.FontSize = new Length { Unit = captionElement.Style.FontSize.Unit, Value = System.Convert.ToDouble(userSettings.FontSize.Value) * captionElement.Style.FontSize.Value / 100.0 }; } var fontFamily = GetFontFamily(userSettings); if (fontFamily != null) { captionElement.Style.FontFamily = fontFamily; #if WINDOWS_PHONE if (userSettings.FontFamily == FontFamily.Cursive) { captionElement.Style.FontStyle = System.Windows.FontStyles.Italic; } #endif } ApplyFontStyle(captionElement, userSettings); var children = captionElement.Children as MediaMarkerCollection<TimedTextElement>; if (children != null) { foreach (var child in children) { UpdateElement(child, userSettings, level + 1); } } }
/// <summary> /// Gets the Windows or Windows Phone font family from the user /// settings Font /// </summary> /// <param name="settings">the custom caption settings</param> /// <returns>the font family</returns> private Media.FontFamily GetFontFamily(CustomCaptionSettings settings) { if (this.fontMap == null) { this.fontMap = new Dictionary<Microsoft.PlayerFramework.CaptionSettings.Model.FontFamily, Media.FontFamily>(); } Media.FontFamily fontFamily; if (this.fontMap.TryGetValue(settings.FontFamily, out fontFamily)) { return fontFamily; } string fontName = CC608CaptionSettingsPlugin.GetFontFamilyName(settings.FontFamily); if (fontName == null) { return null; } fontFamily = new Media.FontFamily(fontName); this.fontMap[settings.FontFamily] = fontFamily; return fontFamily; }
/// <summary> /// Apply a depressed edge /// </summary> /// <param name="textBlock">the text block</param> /// <param name="parent">the parent</param> /// <param name="settings">the settings</param> private void ApplyDepressedEdge(TextBlock textBlock, UIElement parent, CustomCaptionSettings settings) { var offset = 1.5; if (settings.FontSize.HasValue) { offset = offset * settings.FontSize.Value / 100; } var newTextBlocks = new TextBlock[] { new TextBlock { Name = "TopLeft", RenderTransform = new Media.TranslateTransform { X = -offset, Y = -offset }, }, new TextBlock { Name = "Top", RenderTransform = new Media.TranslateTransform { Y = -offset }, }, new TextBlock { Name = "Left", RenderTransform = new Media.TranslateTransform { X = -offset, }, }, }; CopyAttributes(textBlock, newTextBlocks, parent, 0.25, 1); }
/// <summary> /// Apply an outline /// </summary> /// <param name="textBlock">the text block</param> /// <param name="parent">the parent</param> /// <param name="settings">the settings</param> private void ApplyOutline(TextBlock textBlock, UIElement parent, CustomCaptionSettings settings) { var offset = 1.0; if (settings.FontSize.HasValue) { offset = settings.FontSize.Value / 100; } var newTextBlocks = new TextBlock[] { new TextBlock { RenderTransform = new Media.TranslateTransform { X = -offset, Y = -offset }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { Y = -offset }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = offset, Y = -offset }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = -offset, }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = offset, }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = -offset, Y = offset }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { Y = offset }, }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = offset, Y = offset } }, }; CopyAttributes(textBlock, newTextBlocks, parent, textBlock.Opacity, -1); }
/// <summary> /// Apply the font style /// </summary> /// <param name="settings">the caption settings</param> /// <param name="textBlock">the text block</param> /// <param name="parent">the text block's parent</param> private void ApplyFontStyle(CustomCaptionSettings settings, TextBlock textBlock, UIElement parent) { switch (settings.FontStyle) { case Model.FontStyle.Default: // default style is Outline this.ApplyOutline(textBlock, parent, settings); break; case Model.FontStyle.DepressedEdge: this.ApplyDepressedEdge(textBlock, parent, settings); break; case Model.FontStyle.DropShadow: this.ApplyDropShadow(textBlock, parent, settings); break; case Model.FontStyle.Outline: this.ApplyOutline(textBlock, parent, settings); break; case Model.FontStyle.RaisedEdge: this.ApplyRaisedEdge(textBlock, parent, settings); break; case Model.FontStyle.None: break; } }
/// <summary> /// Apply setting to a TextBlock /// </summary> /// <param name="settings">the custom caption settings</param> /// <param name="textBlock">the text block</param> /// <param name="parent">the parent</param> private void ApplyText(CustomCaptionSettings settings, TextBlock textBlock, UIElement parent) { if (string.IsNullOrWhiteSpace(textBlock.Text)) { return; } this.ApplyFontStyle(settings, textBlock, parent); }
/// <summary> /// Apply settings to a panel /// </summary> /// <param name="settings">the custom caption settings</param> /// <param name="isRoot">is this the root panel</param> /// <param name="panel">the panel</param> private void ApplyPanel(CustomCaptionSettings settings, bool isRoot, StackPanel panel) { var children = System.Convert.ToDouble(panel.Children.Count); var startIndex = -1; var endIndex = -1; var index = 0; foreach (var item in panel.Children) { bool empty = IsRowEmpty(item); if (!empty && startIndex == -1) { startIndex = index; } if (!empty) { endIndex = index + 1; } this.ApplySettings(item, settings, panel); index++; } if (isRoot && settings.WindowColor != null) { if (startIndex >= 0 && endIndex >= 0) { var startPercentage = Math.Max(0.0, (System.Convert.ToDouble(startIndex) / children) - 0.01); var endPercentage = Math.Min(1.0, (System.Convert.ToDouble(endIndex) / children) + 0.01); var gradientStops = new Media.GradientStopCollection(); var color = settings.WindowColor.ToColor(); gradientStops.Add(new Media.GradientStop { Color = Colors.Transparent, Offset = startPercentage }); gradientStops.Add(new Media.GradientStop { Color = color, Offset = startPercentage }); gradientStops.Add(new Media.GradientStop { Color = color, Offset = endPercentage }); gradientStops.Add(new Media.GradientStop { Color = Colors.Transparent, Offset = endPercentage }); panel.Background = new Media.LinearGradientBrush(gradientStops, 90); } } }
/// <summary> /// Apply settings to a border /// </summary> /// <param name="settings">the custom caption settings</param> /// <param name="border">a border</param> private void ApplyBorder(CustomCaptionSettings settings, Border border) { this.ApplySettings(border.Child, settings, border); }
/// <summary> /// Apply a drop shadow /// </summary> /// <param name="textBlock">the text block</param> /// <param name="parent">the parent</param> /// <param name="settings">the settings</param> private void ApplyDropShadow(TextBlock textBlock, UIElement parent, CustomCaptionSettings settings) { var offset = this.DropShadowOffset; if (settings.FontSize.HasValue) { offset = offset * settings.FontSize.Value / 100; } var newTextBlocks = new TextBlock[] { new TextBlock { RenderTransform = new Media.TranslateTransform { X = offset } }, new TextBlock { RenderTransform = new Media.TranslateTransform { Y = offset } }, new TextBlock { RenderTransform = new Media.TranslateTransform { X = offset, Y = offset } }, }; CopyAttributes(textBlock, newTextBlocks, parent, 0.5, -1); }