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 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); } }