protected override void OnRender(DrawingContext dc) { Brush bgBrush = Background; dc.DrawRectangle(bgBrush, null, new Rect(RenderSize)); if (Items == null) { return; } try { //long tickStart = DateTime.Now.Ticks; //パフォーマンス計測用 double selfLeft = Canvas.GetLeft(this); // Items 設定時に CreateDrawTextList を行うと、番組表に複数のタブを設定していると // 全てのタブの GlyphRun を一度に生成しようとするので、最初の表示までに多くの時間がかかる。 // 表示しようとするタブのみ GlyphRun を行うことで、最初の応答時間を削減することにする。 CreateDrawTextList(); //long tickGlyphRun = DateTime.Now.Ticks; //パフォーマンス計測用 foreach (ProgramViewItem info in Items) { dc.DrawRectangle(bgBrush, null, new Rect(info.LeftPos - selfLeft, info.TopPos, info.Width, 1)); dc.DrawRectangle(bgBrush, null, new Rect(info.LeftPos - selfLeft, info.TopPos + info.Height, info.Width, 1)); if (info.Height > 1) { dc.DrawRectangle(info.ContentColor, null, new Rect(info.LeftPos - selfLeft, info.TopPos + 0.5, info.Width - 1, info.Height - 0.5)); if (textDrawDict.ContainsKey(info)) { dc.PushClip(new RectangleGeometry(new Rect(info.LeftPos - selfLeft, info.TopPos + 0.5, info.Width - 1, info.Height - 0.5))); foreach (TextDrawItem txtinfo in textDrawDict[info]) { dc.DrawGlyphRun(txtinfo.FontColor, txtinfo.Text); } dc.Pop(); } } } // EpgViewPanel は複数に分けて Render するので、最後のパネルが Render し終わったら // 些細なメモリ節約のために cache をクリアする ItemFontNormal.ClearCache(); ItemFontTitle.ClearCache(); //パフォーマンス計測用 //long tickDraw = DateTime.Now.Ticks; //Console.Write("GlyphRun = " + Math.Round((tickGlyphRun - tickStart)/10000D).ToString() // + ", Draw = " + Math.Round((tickDraw - tickGlyphRun)/10000D).ToString() // + ", Total = " + Math.Round((tickDraw-tickStart)/10000D).ToString() + "\n"); } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); } }
protected void CreateDrawTextList() { LastItemRenderTextHeight = 0; textDrawLists = null; Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice; if (Items == null) { return; } textDrawLists = new List <List <Tuple <Brush, GlyphRun> > >(Items.Count); if (ItemFontNormal == null || ItemFontNormal.GlyphType == null || ItemFontTitle == null || ItemFontTitle.GlyphType == null) { return; } ItemFontNormal.PrepareCache(); ItemFontTitle.PrepareCache(); { double selfLeft = Canvas.GetLeft(this); double sizeTitle = Math.Max(Settings.Instance.FontSizeTitle, 1); double sizeNormal = Math.Max(Settings.Instance.FontSize, 1); double indentTitle = sizeTitle * 1.7; double indentNormal = IsTitleIndent ? indentTitle : 2; SolidColorBrush colorTitle = CommonManager.Instance.CustTitle1Color; SolidColorBrush colorNormal = CommonManager.Instance.CustTitle2Color; foreach (ProgramViewItem info in Items) { var textDrawList = new List <Tuple <Brush, GlyphRun> >(); textDrawLists.Add(textDrawList); double innerLeft = info.LeftPos + BorderLeftSize / 2; //0.26は細枠線での微調整 double innerTop = info.TopPos + BorderTopSize / 2 - 0.26; double innerWidth = info.Width - BorderLeftSize; double innerHeight = info.Height - BorderTopSize; double useHeight; //分 string min = (info.EventInfo.StartTimeFlag == 0 ? "?" : info.EventInfo.start_time.Minute.ToString("d02")); if (RenderText(min, textDrawList, ItemFontTitle, sizeTitle * 0.95, innerWidth - 1, innerHeight, innerLeft + 1, innerTop, out useHeight, colorTitle, m, selfLeft) == false) { info.TitleDrawErr = true; LastItemRenderTextHeight = info.Height; continue; } //タイトル string title = info.EventInfo.ShortInfo == null ? "" : info.EventInfo.ShortInfo.event_name; if (ReplaceDictionaryTitle != null) { title = CommonManager.ReplaceText(title, ReplaceDictionaryTitle); } if (RenderText(title.Length > 0 ? title : " ", textDrawList, ItemFontTitle, sizeTitle, innerWidth - sizeTitle * 0.5 - indentTitle, innerHeight, innerLeft + indentTitle, innerTop, out useHeight, colorTitle, m, selfLeft) == false) { info.TitleDrawErr = true; LastItemRenderTextHeight = info.Height; continue; } if (info.Height < sizeTitle) { //高さ足りない info.TitleDrawErr = true; } LastItemRenderTextHeight = useHeight + sizeNormal * 0.5; if (info.EventInfo.ShortInfo != null) { //説明 string detail = info.EventInfo.ShortInfo.text_char; //詳細 detail += ExtInfoMode == false || info.EventInfo.ExtInfo == null ? "" : "\r\n\r\n" + info.EventInfo.ExtInfo.text_char; if (ReplaceDictionaryNormal != null) { detail = CommonManager.ReplaceText(detail, ReplaceDictionaryNormal); } RenderText(detail, textDrawList, ItemFontNormal, sizeNormal, innerWidth - sizeTitle * 0.5 - indentNormal, innerHeight - LastItemRenderTextHeight, innerLeft + indentNormal, innerTop + LastItemRenderTextHeight, out useHeight, colorNormal, m, selfLeft); LastItemRenderTextHeight += useHeight + sizeNormal * 0.25; } LastItemRenderTextHeight = Math.Floor(LastItemRenderTextHeight + BorderTopSize + sizeNormal * 0.5); LastItemRenderTextHeight = Math.Min(LastItemRenderTextHeight, info.Height); } } }
protected override void OnRender(DrawingContext dc) { dc.DrawRectangle(Background, null, new Rect(RenderSize)); if (Items == null) { return; } if (ItemFontNormal == null || ItemFontNormal.GlyphType == null || ItemFontTitle == null || ItemFontTitle.GlyphType == null) { return; } try { double sizeMin = Settings.Instance.TunerFontSize; double sizeTitle = Settings.Instance.TunerFontSizeService; double sizeNormal = Settings.Instance.TunerFontSize; double indentTitle = sizeMin * 1.7; double indentNormal = Settings.Instance.TunerTitleIndent ? indentTitle : 2; Brush colorTitle = CommonManager.Instance.CustTunerServiceColor; Brush colorNormal = CommonManager.Instance.CustTunerTextColor; double heightMin = Settings.Instance.TunerFontHeight; double heightTitle = Settings.Instance.TunerFontHeightService; double heightNormal = Settings.Instance.TunerFontHeight; double height1stLine = Math.Max(heightMin, heightTitle); // 起点はベースラインになるので、それぞれのベースラインを計算しておく。 // 分とサービス名はフォントが異なることができるのでセンタリングして合うように調整しておく。 // (ベースラインを合わせてみたら XAML と違うので PopupItem の表示との差が大きかった。) double baselineMin = sizeMin * ItemFontNormal.GlyphType.Baseline + (height1stLine - heightMin) / 2; double baselineTitle = sizeTitle * ItemFontTitle.GlyphType.Baseline + (height1stLine - heightTitle) / 2; double baselineNormal = sizeNormal * ItemFontNormal.GlyphType.Baseline; //録画中のものを後で描画する List <ReserveViewItem> postdrawList = Items.Where(info => info.ReserveInfo.IsOnRec()).ToList(); postdrawList.ForEach(info => Items.Remove(info)); Items.AddRange(postdrawList); foreach (ReserveViewItem info in Items) { colorTitle = Settings.Instance.TunerColorModeUse == true ? info.ForeColorPriTuner : colorTitle; double x = info.LeftPos; double y = info.TopPos; double height = Math.Max(info.Height, 0) + 1; double width = info.Width + 1; dc.DrawRectangle(info.BorderBrushTuner, null, new Rect(x, y, width, height)); if (height > 2) { // 枠の内側を計算 x += 1; y += 1; width -= 2; height -= 2; dc.DrawRectangle(info.BackColorTuner, null, new Rect(x, y, width, height)); if (height < height1stLine) // ModifierMinimumHeight してるので足りなくならないハズ。 { //高さ足りない info.TitleDrawErr = true; continue; } // margin 設定 x += 2; width -= 6; double useHeight = 0; //分 string min = info.ReserveInfo.StartTime.Minute.ToString("d02"); if (RenderText(min, dc, ItemFontNormal, colorTitle, sizeMin, width, height, x, y + baselineMin, ref useHeight) == false) { info.TitleDrawErr = true; continue; } //サービス名 if (info.ReserveInfo.StationName.Length > 0) { string serviceName = info.ReserveInfo.StationName + "(" + CommonManager.ConvertNetworkNameText(info.ReserveInfo.OriginalNetworkID) + ")"; if (RenderText(serviceName, dc, ItemFontTitle, colorTitle, sizeTitle, width - indentTitle, height, x + indentTitle, y + baselineTitle, ref useHeight, Settings.Instance.TunerServiceNoWrap) == false) { info.TitleDrawErr = true; continue; } useHeight += 2; // margin: 番組名との間隔は 2px にする } //番組名 if (info.ReserveInfo.Title.Length > 0) { if (RenderText(info.ReserveInfo.Title, dc, ItemFontNormal, colorNormal, sizeNormal, width - indentNormal, height - useHeight, x + indentNormal, y + useHeight + baselineNormal, ref useHeight) == false) { info.TitleDrawErr = true; continue; } } } } ItemFontNormal.ClearCache(); ItemFontTitle.ClearCache(); } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); } }
protected void CreateDrawTextList() { textDrawDict = new Dictionary <ProgramViewItem, List <TextDrawItem> >(); Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice; if (Items == null) { return; } if (ItemFontNormal == null || ItemFontNormal.GlyphType == null || ItemFontTitle == null || ItemFontTitle.GlyphType == null) { return; } ItemFontNormal.PrepareCache(); ItemFontTitle.PrepareCache(); try { double selfLeft = Canvas.GetLeft(this); double sizeMin = Settings.Instance.FontSizeTitle - 1; double sizeTitle = Settings.Instance.FontSizeTitle; double sizeNormal = Settings.Instance.FontSize; double indentTitle = Math.Floor(sizeMin * 1.7); double indentNormal = Math.Floor(Settings.Instance.EpgTitleIndent ? indentTitle : 2); Brush colorTitle = CommonManager.Instance.CustTitle1Color; Brush colorNormal = CommonManager.Instance.CustTitle2Color; double height1stLine = Math.Max(Settings.Instance.FontHeightTitle, Settings.Instance.FontHeightTitle); // あらかじめベースラインをそろえるために計算しておく。 // 今は sizeMin と sizeTitle 同じだけどね… double baselineMin = Math.Max(sizeMin * ItemFontTitle.GlyphType.Baseline, sizeTitle * ItemFontTitle.GlyphType.Baseline); double baselineNormal = sizeNormal * ItemFontNormal.GlyphType.Baseline; foreach (ProgramViewItem info in Items) { List <TextDrawItem> textDrawList = new List <TextDrawItem>(); textDrawDict[info] = textDrawList; if (info.Height > 2) { if (info.Height < height1stLine) // ModifierMinimumHeight してるので足りなくならないハズ。 { //高さ足りない info.TitleDrawErr = true; } double x = info.LeftPos - selfLeft; double y = info.TopPos; double height = info.Height; double width = info.Width; double totalHeight = 0; // offset x += 2; width -= 2; y += 1; height -= 1; // margin 設定 width -= 4; //分 string min = (info.EventInfo.StartTimeFlag != 1 ? "未定 " : info.EventInfo.start_time.Minute.ToString("d02")); double useHeight = 0; if (RenderText(min, ref textDrawList, ItemFontTitle, sizeMin, width, height, x, y + baselineMin, ref useHeight, colorTitle, m) == false) { info.TitleDrawErr = true; continue; } //番組情報 if (info.EventInfo.ShortInfo != null) { //タイトル if (info.EventInfo.ShortInfo.event_name.Length > 0) { if (RenderText(info.EventInfo.ShortInfo.event_name, ref textDrawList, ItemFontTitle, sizeTitle, width - indentTitle, height - totalHeight, x + indentTitle, y + totalHeight + baselineMin, ref useHeight, colorTitle, m) == false) { info.TitleDrawErr = true; continue; } totalHeight += Math.Floor(useHeight + 4); // 説明との間隔は 4px にする } //説明 if (info.EventInfo.ShortInfo.text_char.Length > 0) { if (RenderText(info.EventInfo.ShortInfo.text_char, ref textDrawList, ItemFontNormal, sizeNormal, width - indentNormal, height - totalHeight, x + indentNormal, y + totalHeight + baselineNormal, ref useHeight, colorNormal, m) == false) { continue; } //totalHeight += useHeight + 4; // 詳細との間隔は 4px にする } //詳細 // if (info.EventInfo.ExtInfo != null) // { // if (info.EventInfo.ExtInfo.text_char.Length > 0) // { // if (RenderText(info.EventInfo.ExtInfo.text_char, ref textDrawList, ItemFontNormal, sizeNormal, width - widthOffset, height - totalHeight, x + widthOffset, y + totalHeight + baselineNormal, ref useHeight, colorNormal, m) == false) // { // continue; // } // totalHeight += useHeight; // } // } } } } } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); } }