Skip to content

Commit

Permalink
Improve text drawing performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
stakira committed Jun 1, 2015
1 parent 405e2f5 commit 4c5752c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 22 deletions.
2 changes: 1 addition & 1 deletion OpenUtau.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenUtau", "OpenUtau\OpenUtau.csproj", "{D951492F-0901-4296-AE7F-831430C07FA9}"
Expand Down
20 changes: 14 additions & 6 deletions OpenUtau/UI/Controls/BackgroundElements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ protected override void OnRender(DrawingContext drawingContext)

class TimelineBackground : TickBackground
{
Dictionary<int, FormattedText> fTextPool = new Dictionary<int, FormattedText>();

protected override void OnRender(DrawingContext drawingContext)
{
double zoomRatio = MusicMath.getZoomRatio(QuarterWidth, BeatPerBar, BeatUnit, MinTickWidth);
Expand All @@ -244,15 +246,21 @@ protected override void OnRender(DrawingContext drawingContext)
if ((tick * zoomRatio * BeatUnit) % (BeatPerBar * 4) == 0)
{
if (!first_tick) drawingContext.DrawLine(darkPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
drawingContext.DrawText(
new FormattedText(
((tick * zoomRatio * BeatUnit) / BeatPerBar / 4 + 1).ToString(),
int barNumber = (int)((tick * zoomRatio * BeatUnit) / BeatPerBar / 4 + 1);

FormattedText fText;
if (!fTextPool.ContainsKey(barNumber))
{
fText = new FormattedText(
barNumber.ToString(),
System.Threading.Thread.CurrentThread.CurrentUICulture,
FlowDirection.LeftToRight, SystemFonts.CaptionFontFamily.GetTypefaces().First(),
12,
darkPen.Brush),
new Point(snappedLeft + 3, 3)
);
darkPen.Brush);
fTextPool.Add(barNumber, fText);
}
else fText = fTextPool[barNumber];
drawingContext.DrawText(fText, new Point(snappedLeft + 3, 3));
}
left += interval;
tick++;
Expand Down
57 changes: 42 additions & 15 deletions OpenUtau/UI/Controls/ExpElements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ExpElement : FrameworkElement
protected override Visual GetVisualChild(int index) { return visual; }

protected UVoicePart _part;
public UVoicePart Part { set { _part = value; MarkUpdate(); } get { return _part; } }
public virtual UVoicePart Part { set { _part = value; MarkUpdate(); } get { return _part; } }

public string Key;
protected TranslateTransform tTrans;
Expand Down Expand Up @@ -130,10 +130,16 @@ class PitchExpElement : ExpElement
double _quarterWidth;
public double QuarterWidth { set { if (_quarterWidth != value) { _quarterWidth = value; MarkUpdate(); } } get { return _quarterWidth; } }

public override UVoicePart Part { set { _part = value; ClearFormattedTextPool(); MarkUpdate(); } get { return _part; } }

public OpenUtau.UI.Models.MidiViewModel midiVM;

Pen penPit;
Pen penEnv;

Dictionary<string, FormattedText> fTextPool = new Dictionary<string, FormattedText>();
Dictionary<string, double> fTextWidths = new Dictionary<string, double>();
Dictionary<string, double> fTextHeights = new Dictionary<string, double>();

public PitchExpElement()
{
Expand Down Expand Up @@ -171,6 +177,13 @@ public override void RedrawIfUpdated()
_updated = false;
}

private void ClearFormattedTextPool()
{
fTextPool.Clear();
fTextWidths.Clear();
fTextHeights.Clear();
}

private void DrawNote(UNote note, DrawingContext cxt)
{
DrawNoteBody(note, cxt);
Expand All @@ -195,23 +208,37 @@ private void DrawNoteBody(UNote note, DrawingContext cxt)
null, new Rect(new Point(left, top), new Size(width, height)), 2, 2);
if (height >= 10)
{
var text = new FormattedText(
note.Lyric,
System.Threading.Thread.CurrentThread.CurrentUICulture,
FlowDirection.LeftToRight, SystemFonts.CaptionFontFamily.GetTypefaces().First(),
12,
Brushes.White);
if (text.Width + 5 > width && note.Lyric.Length > 0)
text = new FormattedText(
note.Lyric[0] + "..",
System.Threading.Thread.CurrentThread.CurrentUICulture,
FlowDirection.LeftToRight, SystemFonts.CaptionFontFamily.GetTypefaces().First(),
12,
Brushes.White);
if (text.Width + 5 <= width) cxt.DrawText(text, new Point((int)left + 5, Math.Round(top + (height - text.Height) / 2)));
if (note.Lyric.Length == 0) return;
string displayLyric = note.Lyric;

if (!fTextPool.ContainsKey(displayLyric)) AddToFormattedTextPool(displayLyric);
var fText = fTextPool[displayLyric];

if (fTextWidths[displayLyric] + 5 > width)
{
displayLyric = note.Lyric[0] + "..";
if (!fTextPool.ContainsKey(displayLyric)) AddToFormattedTextPool(displayLyric);
fText = fTextPool[displayLyric];
if (fTextWidths[displayLyric] + 5 > width) return;
}

cxt.DrawText(fText, new Point((int)left + 5, Math.Round(top + (height - fTextHeights[displayLyric]) / 2)));
}
}

private void AddToFormattedTextPool(string text)
{
var fText = new FormattedText(
text,
System.Threading.Thread.CurrentThread.CurrentUICulture,
FlowDirection.LeftToRight, SystemFonts.CaptionFontFamily.GetTypefaces().First(),
12,
Brushes.White);
fTextPool.Add(text, fText);
fTextWidths.Add(text, fText.Width);
fTextHeights.Add(text, fText.Height);
}

private void DrawEnvelope(UNote note, DrawingContext cxt)
{
double y = midiVM.TrackHeight * ((double)UIConstants.MaxNoteNum - 1 - note.NoteNum) + 1.5;
Expand Down

0 comments on commit 4c5752c

Please sign in to comment.