From 1e09fe06b129fc134711d43724d6e7caf3ce9b50 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Tue, 27 Aug 2019 16:07:16 +0200 Subject: [PATCH 1/2] Introduced consistent load/render API, removed width configuration from settings --- .../AlphaTab.Samples.PngDump/Program.cs | 4 +- .../CSharp/ManagedThreadScoreRenderer.cs | 36 ++- .../Platform/CSharp/ManagedUiFacade.cs | 7 +- .../CSharp/WinForms/AlphaTabControl.cs | 2 +- .../Platform/CSharp/Wpf/AlphaTab.cs | 4 +- .../Platform/JavaScript/AlphaTabApi.cs | 28 +- .../Platform/JavaScript/AlphaTabWebWorker.cs | 13 +- .../JavaScript/AlphaTabWorkerScoreRenderer.cs | 30 +- .../Platform/JavaScript/JQueryAlphaTab.cs | 28 +- Source/AlphaTab.JavaScript/Settings.cs | 10 - .../AlphaTab.JavaScript/UI/BrowserUiFacade.cs | 35 +-- .../Importer/AlphaTexImporterTest.cs | 24 +- .../Importer/GpImporterTestBase.cs | 2 +- .../Importer/MusicXmlImporterTestBase.cs | 4 +- .../VisualTests/VisualTestBase.cs | 8 +- Source/AlphaTab/AlphaTabApi.cs | 261 ++++++++---------- Source/AlphaTab/Rendering/IScoreRenderer.cs | 50 ++-- .../Rendering/Layout/PageViewLayout.cs | 22 +- Source/AlphaTab/Rendering/ScoreRenderer.cs | 25 +- Source/AlphaTab/Settings.cs | 52 ++-- 20 files changed, 334 insertions(+), 311 deletions(-) diff --git a/Samples/CSharp/AlphaTab.Samples.PngDump/Program.cs b/Samples/CSharp/AlphaTab.Samples.PngDump/Program.cs index e912c4e1a..1cac59557 100644 --- a/Samples/CSharp/AlphaTab.Samples.PngDump/Program.cs +++ b/Samples/CSharp/AlphaTab.Samples.PngDump/Program.cs @@ -24,8 +24,8 @@ private static void Main(string[] args) // render score with svg engine and desired rendering width var settings = Settings.Defaults; settings.Engine = "skia"; - settings.Width = 970; var renderer = new ScoreRenderer(settings); + renderer.Width = 970; // iterate tracks for (int i = 0, j = score.Tracks.Count; i < j; i++) @@ -46,7 +46,7 @@ private static void Main(string[] args) totalWidth = (int)r.TotalWidth; totalHeight = (int)r.TotalHeight; }; - renderer.Render(score, new[] { track.Index }); + renderer.RenderScore(score, new[] { track.Index }); // write png var info = new FileInfo(args[0]); diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/ManagedThreadScoreRenderer.cs b/Source/AlphaTab.CSharp/Platform/CSharp/ManagedThreadScoreRenderer.cs index d2af8d5ba..b8ffe8a5f 100644 --- a/Source/AlphaTab.CSharp/Platform/CSharp/ManagedThreadScoreRenderer.cs +++ b/Source/AlphaTab.CSharp/Platform/CSharp/ManagedThreadScoreRenderer.cs @@ -16,6 +16,7 @@ internal class ManagedThreadScoreRenderer : IScoreRenderer private ManualResetEventSlim _threadStartedEvent; private CancellationTokenSource _workerCancellationToken; private ScoreRenderer _renderer; + private int _width; public BoundsLookup BoundsLookup { get; private set; } @@ -91,39 +92,56 @@ private bool CheckAccess() return Thread.CurrentThread == _workerThread; } - public void Invalidate() + public void Render() { if (CheckAccess()) { - _renderer.Invalidate(); + _renderer.Render(); } else { - _workerQueue.Add(() => Invalidate()); + _workerQueue.Add(Render); } } - public void Resize(int width) + public int Width + { + get => _width; + set + { + _width = value; + if (CheckAccess()) + { + _renderer.Width = value; + } + else + { + _workerQueue.Add(() => _renderer.Width = value); + } + } + } + + public void ResizeRender() { if (CheckAccess()) { - _renderer.Resize(width); + _renderer.ResizeRender(); } else { - _workerQueue.Add(() => Resize(width)); + _workerQueue.Add(ResizeRender); } } - public void Render(Score score, int[] trackIndexes) + public void RenderScore(Score score, int[] trackIndexes) { if (CheckAccess()) { - _renderer.Render(score, trackIndexes); + _renderer.RenderScore(score, trackIndexes); } else { - _workerQueue.Add(() => Render(score, trackIndexes)); + _workerQueue.Add(() => RenderScore(score, trackIndexes)); } } diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/ManagedUiFacade.cs b/Source/AlphaTab.CSharp/Platform/CSharp/ManagedUiFacade.cs index cbf4a9011..a7adc889f 100644 --- a/Source/AlphaTab.CSharp/Platform/CSharp/ManagedUiFacade.cs +++ b/Source/AlphaTab.CSharp/Platform/CSharp/ManagedUiFacade.cs @@ -75,11 +75,8 @@ public virtual void InitialRender() { // rendering was possibly delayed due to invisible element // in this case we need the correct width for autosize - if (Api.AutoSize) - { - Api.Settings.Width = (int)RootContainer.Width; - Api.Renderer.UpdateSettings(Api.Settings); - } + Api.Renderer.Width = (int)RootContainer.Width; + Api.Renderer.UpdateSettings(Api.Settings); RenderTracks(); }; diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs index bb2f3ec71..d8027e785 100644 --- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs +++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs @@ -135,7 +135,7 @@ public void RenderTracks() if (score != null) { - Api.RenderTracks(score, trackIndexes.ToArray()); + Api.RenderScore(score, trackIndexes.ToArray()); } } diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs index 1f5334f87..87fa723c7 100644 --- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs +++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs @@ -171,11 +171,11 @@ public void RenderTracks() if (score != null) { - Api.RenderTracks(score, trackIndexes.ToArray()); + Api.RenderScore(score, trackIndexes.ToArray()); } } public event Action SettingsChanged; } } -#endif \ No newline at end of file +#endif diff --git a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabApi.cs b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabApi.cs index f66590f69..ea5ff8c8b 100644 --- a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabApi.cs +++ b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabApi.cs @@ -1,7 +1,9 @@ using System; +using System.Diagnostics.Contracts; using AlphaTab.Audio.Generator; using AlphaTab.Audio.Synth; using AlphaTab.Audio.Synth.Midi; +using AlphaTab.Collections; using AlphaTab.Haxe.Js; using AlphaTab.Haxe.Js.Html; using AlphaTab.Importer; @@ -100,7 +102,7 @@ public void Print(string width) alphaTab.CanvasElement.Height = -1; preview.Print(); }; - alphaTab.RenderTracks(Score, TrackIndexes); + alphaTab.RenderTracks(Tracks); } public override void UpdateLayout(LayoutSettings layoutSettings) @@ -109,6 +111,7 @@ public override void UpdateLayout(LayoutSettings layoutSettings) { layoutSettings = Settings.LayoutFromJson(layoutSettings); } + base.UpdateLayout(layoutSettings); } @@ -147,6 +150,7 @@ public override void ChangeTrackMute(Track[] tracks, bool mute) base.ChangeTrackMute(trackList, mute); } + public override void ChangeTrackSolo(Track[] tracks, bool solo) { var trackList = TrackIndexesToTracks(((BrowserUiFacade)UiFacade).ParseTracks(tracks)); @@ -159,10 +163,30 @@ public override void ChangeTrackVolume(Track[] tracks, float volume) base.ChangeTrackVolume(trackList, volume); } + private Track[] TrackIndexesToTracks(int[] trackIndexes) + { + if (Score == null) + { + return new Track[0]; + } + + var tracks = new FastList(); + foreach (var index in trackIndexes) + { + if (index >= 0 && index < Score.Tracks.Count) + { + tracks.Add(Score.Tracks[index]); + } + } + + return tracks.ToArray(); + } + /// /// This event is fired during the sound font loading from an external source. /// public event Action SoundFontLoad; + internal void OnSoundFontLoad(ProgressEventArgs e) { var handler = SoundFontLoad; @@ -170,6 +194,7 @@ internal void OnSoundFontLoad(ProgressEventArgs e) { handler(e); } + UiFacade.TriggerEvent(Container, "soundFontLoad", e); } @@ -179,6 +204,7 @@ internal void LoadSoundFontFromUrl(string url) { return; } + ((AlphaSynthWebWorkerApi)Player).LoadSoundFontFromUrl(url, OnSoundFontLoad); } } diff --git a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWebWorker.cs b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWebWorker.cs index dad5466dc..6500213cb 100644 --- a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWebWorker.cs +++ b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWebWorker.cs @@ -56,12 +56,15 @@ private void HandleMessage(Event e) _renderer.Error += Error; break; case "alphaTab.invalidate": - _renderer.Invalidate(); + _renderer.Render(); break; - case "alphaTab.resize": - _renderer.Resize(data.width); + case "alphaTab.resizeRender": + _renderer.ResizeRender(); break; - case "alphaTab.render": + case "alphaTab.setWidth": + _renderer.Width = data.width; + break; + case "alphaTab.renderScore": var score = JsonConverter.JsObjectToScore(data.score, _renderer.Settings); RenderMultiple(score, data.trackIndexes); break; @@ -80,7 +83,7 @@ private void RenderMultiple(Score score, int[] trackIndexes) { try { - _renderer.Render(score, trackIndexes); + _renderer.RenderScore(score, trackIndexes); } catch (Exception e) { diff --git a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWorkerScoreRenderer.cs b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWorkerScoreRenderer.cs index 13ee240c3..38b0f3ab6 100644 --- a/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWorkerScoreRenderer.cs +++ b/Source/AlphaTab.JavaScript/Platform/JavaScript/AlphaTabWorkerScoreRenderer.cs @@ -12,6 +12,7 @@ internal class AlphaTabWorkerScoreRenderer : IScoreRenderer { private readonly AlphaTabApi _api; private readonly Worker _worker; + private int _width; public BoundsLookup BoundsLookup { get; private set; } @@ -24,7 +25,7 @@ public AlphaTabWorkerScoreRenderer(AlphaTabApi api, Settings settings) } catch { - // fallback to blob worker + // fallback to blob worker try { HaxeString script = "importScripts('" + settings.ScriptFile + "')"; @@ -63,23 +64,36 @@ public void UpdateSettings(Settings settings) }); } - public void Invalidate() + public void Render() { _worker.PostMessage(new { - cmd = "alphaTab.invalidate" + cmd = "alphaTab.render" }); } - public void Resize(int width) + public void ResizeRender() { _worker.PostMessage(new { - cmd = "alphaTab.resize", - width = width + cmd = "alphaTab.resizeRender" }); } + public int Width + { + get => _width; + set + { + _width = value; + _worker.PostMessage(new + { + cmd = "alphaTab.setWidth", + width = value + }); + } + } + private void HandleWorkerMessage(Event e) { var data = ((MessageEvent)e).Data; @@ -105,12 +119,12 @@ private void HandleWorkerMessage(Event e) } } - public void Render(Score score, int[] trackIndexes) + public void RenderScore(Score score, int[] trackIndexes) { var jsObject = JsonConverter.ScoreToJsObject(score); _worker.PostMessage(new { - cmd = "alphaTab.render", + cmd = "alphaTab.renderScore", score = jsObject, trackIndexes = trackIndexes }); diff --git a/Source/AlphaTab.JavaScript/Platform/JavaScript/JQueryAlphaTab.cs b/Source/AlphaTab.JavaScript/Platform/JavaScript/JQueryAlphaTab.cs index 9ffa75587..495e4890a 100644 --- a/Source/AlphaTab.JavaScript/Platform/JavaScript/JQueryAlphaTab.cs +++ b/Source/AlphaTab.JavaScript/Platform/JavaScript/JQueryAlphaTab.cs @@ -86,16 +86,34 @@ public void Print(JQuery element, AlphaTabApi context, string width) context.Print(width); } + [Name("load")] + public bool Load(JQuery element, AlphaTabApi context, object data, int[] tracks = null) + { + return context.Load(data, tracks); + } + [Name("render")] public void Render(JQuery element, AlphaTabApi context) { context.Render(); } + [Name("renderScore")] + public void Render(JQuery element, AlphaTabApi context, Score score, int[] tracks = null) + { + context.RenderScore(score, tracks); + } + [Name("renderTracks")] - public void RenderTracks(JQuery element, AlphaTabApi context, Score score, int[] tracks, bool invalidate = true) + public void RenderTracks(JQuery element, AlphaTabApi context, Track[] tracks) { - context.RenderTracks(score, tracks, invalidate); + context.RenderTracks(tracks); + } + + [Name("invalidate")] + public void Invalidate(JQuery element, AlphaTabApi context) + { + context.Render(); } [Name("tex")] @@ -116,12 +134,6 @@ public void UpdateLayout(JQuery element, AlphaTabApi context) context.UpdateSettings(); } - [Name("load")] - public bool Load(JQuery element, AlphaTabApi context, object data) - { - return context.Load(data); - } - #endregion diff --git a/Source/AlphaTab.JavaScript/Settings.cs b/Source/AlphaTab.JavaScript/Settings.cs index 060d43b1d..f7aeffe78 100644 --- a/Source/AlphaTab.JavaScript/Settings.cs +++ b/Source/AlphaTab.JavaScript/Settings.cs @@ -128,7 +128,6 @@ public dynamic ToJson() json.useWorker = UseWorkers; json.scale = Scale; json.slurHeight = SlurHeight; - json.width = Width; json.engine = Engine; json.stretchForce = StretchForce; json.forcePianoFingering = ForcePianoFingering; @@ -327,15 +326,6 @@ public static void FillFromJson(Settings settings, dynamic json, FastDictionary< settings.SlurHeight = dataAttributes["slurHeight"].As(); } - if (Platform.Platform.JsonExists(json, "width")) - { - settings.Width = json.width; - } - else if (dataAttributes != null && dataAttributes.ContainsKey("width")) - { - settings.Width = dataAttributes["width"].As(); - } - if (Platform.Platform.JsonExists(json, "engine")) { settings.Engine = json.engine; diff --git a/Source/AlphaTab.JavaScript/UI/BrowserUiFacade.cs b/Source/AlphaTab.JavaScript/UI/BrowserUiFacade.cs index 3c7ba71b9..dc58156d6 100644 --- a/Source/AlphaTab.JavaScript/UI/BrowserUiFacade.cs +++ b/Source/AlphaTab.JavaScript/UI/BrowserUiFacade.cs @@ -27,6 +27,7 @@ internal class BrowserUiFacade : IUiFacade private int _visibilityCheckIntervalId; private int _visibilityCheckInterval; private int _totalResultCount; + private int[] _initialTrackIndexes; public int ResizeThrottle => 10; @@ -108,7 +109,7 @@ public void Initialize(AlphaTabApi api, object raw) #region build tracks array // get track data to parse - dynamic tracksData; + object tracksData; if (options != null && options.tracks) { tracksData = options.tracks; @@ -125,7 +126,7 @@ public void Initialize(AlphaTabApi api, object raw) } } - SetTracks(tracksData, false); + _initialTrackIndexes = ParseTracks(tracksData); #endregion @@ -250,11 +251,8 @@ public void InitialRender() { // rendering was possibly delayed due to invisible element // in this case we need the correct width for autosize - if (_api.AutoSize) - { - _api.Settings.Width = (int)RootContainer.Width; - _api.Renderer.UpdateSettings(_api.Settings); - } + _api.Renderer.Width = (int)RootContainer.Width; + _api.Renderer.UpdateSettings(_api.Settings); if (!string.IsNullOrEmpty(_contents)) { @@ -263,7 +261,11 @@ public void InitialRender() else if (!string.IsNullOrEmpty(_file)) { ScoreLoader.LoadScoreAsync(_file, - s => _api.ScoreLoaded(s), + s => + { + _api.RenderScore(s, _initialTrackIndexes); + _initialTrackIndexes = null; + }, e => { _api.OnError("import", e); }, _api.Settings); } @@ -337,23 +339,12 @@ private void CreateStyleElement(Settings settings) } } - public void SetTracks(dynamic tracksData, bool render = true) + public int[] ParseTracks(object tracksData) { - Score score = null; - if (tracksData.length && Platform.Platform.TypeOf(tracksData[0].Index) == "number") - { - score = tracksData[0].Score; - } - else if (Platform.Platform.TypeOf(tracksData.Index) == "number") + if (tracksData == null) { - score = tracksData.Score; + return new int[0]; } - - _api.RenderTracks(score, ParseTracks(tracksData), render); - } - - public int[] ParseTracks(object tracksData) - { var tracks = new FastList(); // decode string diff --git a/Source/AlphaTab.Test/Importer/AlphaTexImporterTest.cs b/Source/AlphaTab.Test/Importer/AlphaTexImporterTest.cs index 5f2d55efa..39e8c364a 100644 --- a/Source/AlphaTab.Test/Importer/AlphaTexImporterTest.cs +++ b/Source/AlphaTab.Test/Importer/AlphaTexImporterTest.cs @@ -230,12 +230,13 @@ public void HamonicsRenderingText_Issue79() settings.Staves = new StaveSettings("harmonics"); var renderer = new ScoreRenderer(settings); + renderer.Width = 970; var svg = ""; renderer.PartialRenderFinished += r => { svg += r.RenderResult.ToString(); }; - renderer.Render(score, new[] { 0 }); + renderer.RenderScore(score, new[] { 0 }); var regexTemplate = @"]+>\s*{0}\s*"; @@ -278,6 +279,7 @@ public void BendRendering_Issue79() settings.UseWorkers = false; var renderer = new ScoreRenderer(settings); + renderer.Width = 970; var partials = new FastList(); renderer.Error += (o, e) => { @@ -287,7 +289,7 @@ public void BendRendering_Issue79() { partials.Add(r.RenderResult.ToString()); }; - renderer.Render(score, new[] { 0 }); + renderer.RenderScore(score, new[] { 0 }); var tab = new XmlDocument(partials[0]); @@ -474,7 +476,7 @@ public void TestSingleStaffWithSetting() [TestMethod] public void TestMultiStaffWithSettings() { - var tex = @"\staff{score} 1.1 | 1.1 | + var tex = @"\staff{score} 1.1 | 1.1 | \staff{tabs} \capo 2 2.1 | 2.1 | \staff{score tabs} \tuning A1 D2 A2 D3 G3 B3 E4 3.1 | 3.1"; var score = ParseTex(tex); @@ -565,17 +567,17 @@ public void TestMultiTrackNames() public void TestMultiTrackMultiStaff() { var tex = - @"\track ""Piano"" - \staff{score} \tuning piano \instrument acousticgrandpiano + @"\track ""Piano"" + \staff{score} \tuning piano \instrument acousticgrandpiano c4 d4 e4 f4 | - + \staff{score} \tuning piano \clef F4 c2 c2 c2 c2 | \track ""Guitar"" \staff{tabs} 1.2 3.2 0.1 1.1 | - + \track ""Second Guitar"" 1.2 3.2 0.1 1.1 "; @@ -652,17 +654,17 @@ 1.2 3.2 0.1 1.1 public void TestMultiTrackMultiStaffInconsistentBars() { var tex = - @"\track ""Piano"" - \staff{score} \tuning piano \instrument acousticgrandpiano + @"\track ""Piano"" + \staff{score} \tuning piano \instrument acousticgrandpiano c4 d4 e4 f4 | - + \staff{score} \tuning piano \clef F4 c2 c2 c2 c2 | c2 c2 c2 c2 | c2 c2 c2 c2 | \track ""Guitar"" \staff{tabs} 1.2 3.2 0.1 1.1 | 1.2 3.2 0.1 1.1 | - + \track ""Second Guitar"" 1.2 3.2 0.1 1.1 "; diff --git a/Source/AlphaTab.Test/Importer/GpImporterTestBase.cs b/Source/AlphaTab.Test/Importer/GpImporterTestBase.cs index d82d50bfd..736b2ff8c 100644 --- a/Source/AlphaTab.Test/Importer/GpImporterTestBase.cs +++ b/Source/AlphaTab.Test/Importer/GpImporterTestBase.cs @@ -556,7 +556,7 @@ protected void Render(Score score, [CallerFilePath] string callerFile = null, [C totalWidth = (int)r.TotalWidth; totalHeight = (int)r.TotalHeight; }; - renderer.Render(score, new[] { track.Index }); + renderer.RenderScore(score, new[] { track.Index }); var final = new StringBuilder(); final.Append(""); diff --git a/Source/AlphaTab.Test/Importer/MusicXmlImporterTestBase.cs b/Source/AlphaTab.Test/Importer/MusicXmlImporterTestBase.cs index f0dba3d0c..4f706ef45 100644 --- a/Source/AlphaTab.Test/Importer/MusicXmlImporterTestBase.cs +++ b/Source/AlphaTab.Test/Importer/MusicXmlImporterTestBase.cs @@ -393,8 +393,8 @@ protected void Render(Track[] tracks, string path, string renderLayout) { Mode = renderLayout }; - settings.Width = 800; var renderer = new ScoreRenderer(settings); + renderer.Width = 800; var images = new FastList(); var totalWidth = 0; var totalHeight = 0; @@ -418,7 +418,7 @@ protected void Render(Track[] tracks, string path, string renderLayout) totalWidth = (int)r.TotalWidth; totalHeight = (int)r.TotalHeight; }; - renderer.Render(tracks[0].Score, tracks.Select(t => t.Index).ToArray()); + renderer.RenderScore(tracks[0].Score, tracks.Select(t => t.Index).ToArray()); using (var bmp = new Bitmap(totalWidth, totalHeight)) { var y = 0; diff --git a/Source/AlphaTab.Test/VisualTests/VisualTestBase.cs b/Source/AlphaTab.Test/VisualTests/VisualTestBase.cs index 36d2e160c..075b29457 100644 --- a/Source/AlphaTab.Test/VisualTests/VisualTestBase.cs +++ b/Source/AlphaTab.Test/VisualTests/VisualTestBase.cs @@ -11,13 +11,13 @@ public class VisualTestBase { protected void RunVisualTest(Settings settings, int[] tracks, string inputFileName, string referenceImage) { - settings.Width = 1300; TestPlatform.LoadFile(inputFileName, inputFileData => { TestPlatform.LoadFile(referenceImage, referenceFileData => { var score = ScoreLoader.LoadScoreFromBytes(inputFileData, settings); var renderer = new ScoreRenderer(settings); + renderer.Width = 1300; var result = new FastList(); @@ -37,7 +37,7 @@ protected void RunVisualTest(Settings settings, int[] tracks, string inputFileNa Assert.Fail("Failed to render image: " + s + "," + e); }; - renderer.Render(score, tracks); + renderer.RenderScore(score, tracks); TestPlatform.CompareVisualResult(totalWidth, totalHeight, result, referenceImage, referenceFileData); TestPlatform.Done(); @@ -47,13 +47,13 @@ protected void RunVisualTest(Settings settings, int[] tracks, string inputFileNa } protected void RunVisualTestTex(Settings settings, int[] tracks, string alphaTex, string referenceImage) { - settings.Width = 1300; TestPlatform.LoadFile(referenceImage, referenceFileData => { var importer = new AlphaTexImporter(); importer.Init(TestPlatform.CreateStringReader(alphaTex), settings); var score = importer.ReadScore(); var renderer = new ScoreRenderer(settings); + renderer.Width = 1300; var result = new FastList(); @@ -73,7 +73,7 @@ protected void RunVisualTestTex(Settings settings, int[] tracks, string alphaTex Assert.Fail("Failed to render image: " + s + "," + e); }; - renderer.Render(score, tracks); + renderer.RenderScore(score, tracks); TestPlatform.CompareVisualResult(totalWidth, totalHeight, result, referenceImage, referenceFileData); }); diff --git a/Source/AlphaTab/AlphaTabApi.cs b/Source/AlphaTab/AlphaTabApi.cs index 7cdbc5b15..144e97dc4 100644 --- a/Source/AlphaTab/AlphaTabApi.cs +++ b/Source/AlphaTab/AlphaTabApi.cs @@ -23,6 +23,7 @@ namespace AlphaTab public class AlphaTabApi { private long _startTime; + private FastList _trackIndexes; /// /// Gets the UI facade to use for interacting with the user interface. @@ -50,41 +51,15 @@ public class AlphaTabApi public Settings Settings { get; internal set; } /// - /// Gets a list of the tracks that should be rendered based on and + /// Gets a list of the tracks that are currently rendered; /// - public Track[] Tracks - { - get - { - var tracks = TrackIndexesToTracks(TrackIndexes); - - if (tracks.Length == 0 && Score.Tracks.Count > 0) - { - return new[] - { - Score.Tracks[0] - }; - } - - return tracks; - } - } - - /// - /// Gets a value indicating whether auto-sizing is active and the music sheet will be re-rendered on resize. - /// - internal bool AutoSize => Settings.Width < 0; + public Track[] Tracks { get; private set; } /// /// Gets the UI container that will hold all rendered results. /// internal IContainer CanvasElement { get; } - /// - /// Gets the indexes of the tracks that should be rendered of the currently set score. - /// - internal int[] TrackIndexes { get; private set; } - /// /// Initializes a new instance of the class. /// @@ -101,30 +76,15 @@ public AlphaTabApi(IUiFacade uiFacade, TSettings settings) CanvasElement = uiFacade.CreateCanvasElement(); Container.AppendChild(CanvasElement); - #region Auto Sizing - - if (AutoSize) - { - Settings.Width = (int)Container.Width; - Container.Resize += Platform.Platform.Throttle(() => + Container.Resize += Platform.Platform.Throttle(() => + { + if (Container.Width != Renderer.Width) { - if (Container.Width != Settings.Width) - { - TriggerResize(); - } - }, - uiFacade.ResizeThrottle); - - var initialResizeEventInfo = new ResizeEventArgs(); - initialResizeEventInfo.OldWidth = 0; - initialResizeEventInfo.NewWidth = (int)Container.Width; - initialResizeEventInfo.Settings = Settings; - OnResize(initialResizeEventInfo); - Settings.Width = initialResizeEventInfo.NewWidth; - } - - #endregion + TriggerResize(); + } + }, + uiFacade.ResizeThrottle); if (Settings.UseWorkers && UiFacade.AreWorkersSupported && Environment.GetRenderEngineFactory(Settings).SupportsWorkers) @@ -136,6 +96,12 @@ public AlphaTabApi(IUiFacade uiFacade, TSettings settings) Renderer = new ScoreRenderer(Settings); } + var initialResizeEventInfo = new ResizeEventArgs(); + initialResizeEventInfo.OldWidth = Renderer.Width; + initialResizeEventInfo.NewWidth = (int)Container.Width; + initialResizeEventInfo.Settings = Settings; + OnResize(initialResizeEventInfo); + Renderer.RenderFinished += e => OnRenderFinished(); Renderer.PostRenderFinished += () => { @@ -177,39 +143,111 @@ public virtual void Destroy() Renderer.Destroy(); } + #region Rendering + /// - /// Maps the given list of track indexes to tracks using the current + /// Applies any changes that were done to the settings object and informs the about any new values to consider. /// - /// The indexes of the tracks. - /// A list of Tracks that are available in the current . - protected Track[] TrackIndexesToTracks(int[] trackIndexes) + public void UpdateSettings() { - var tracks = new FastList(); + Renderer.UpdateSettings(Settings); + } - if (trackIndexes == null) + /// + /// Attempts a load of the score represented by the given data object. + /// + /// The data container supported by + /// + /// The indexes of the tracks from the song that should be rendered. If not provided, the first track of the + /// song will be shown. + /// + /// true if the data object is supported and a load was initiated, otherwise false + public bool Load(object scoreData, int[] trackIndexes = null) + { + try + { + return UiFacade.Load(scoreData, + score => + { + RenderScore(score, trackIndexes); + }, + error => + { + OnError("import", error); + }); + } + catch (Exception e) { - return Score.Tracks.Clone().ToArray(); + OnError("import", e); + return false; } + } - foreach (var track in trackIndexes) + /// + /// Initiates a rendering of the given score. + /// + /// The score containing the tracks to be rendered. + /// + /// The indexes of the tracks from the song that should be rendered. If not provided, the first track of the + /// song will be shown. + /// + public void RenderScore(Score score, int[] trackIndexes = null) + { + var tracks = new FastList(); + if (trackIndexes == null) { - if (track >= 0 && track < Score.Tracks.Count) + if (score.Tracks.Count > 0) { - tracks.Add(Score.Tracks[track]); + tracks.Add(score.Tracks[0]); } } - - return tracks.ToArray(); + else + { + foreach (var index in trackIndexes) + { + if (index >= 0 && index <= score.Tracks.Count) + { + tracks.Add(score.Tracks[index]); + } + } + } + InternalRenderTracks(score, tracks.ToArray()); } - #region Rendering + public void RenderTracks(Track[] tracks) + { + if (tracks.Length > 0) + { + var score = tracks[0].Score; + foreach (var track in tracks) + { + if (track.Score != score) + { + OnError("load", new AlphaTabException("All rendered tracks must belong to the same score.")); + return; + } + } - /// - /// Applies any changes that were done to the settings object and informs the about any new values to consider. - /// - public void UpdateSettings() + InternalRenderTracks(score, tracks); + } + } + + private void InternalRenderTracks(Score score, Track[] tracks) { - Renderer.UpdateSettings(Settings); + ModelUtils.ApplyPitchOffsets(Settings, score); + + Score = score; + Tracks = tracks; + _trackIndexes = new FastList(); + foreach (var track in tracks) + { + _trackIndexes.Add(track.Index); + } + + OnLoaded(score); + LoadMidiForScore(); + + Render(); } private void TriggerResize() @@ -228,14 +266,14 @@ private void TriggerResize() { var resizeEventInfo = new ResizeEventArgs { - OldWidth = Settings.Width, + OldWidth = Renderer.Width, NewWidth = (int)Container.Width, Settings = Settings }; OnResize(resizeEventInfo); - Settings.Width = resizeEventInfo.NewWidth; Renderer.UpdateSettings(Settings); - Renderer.Resize(Settings.Width); + Renderer.Width = (int)Container.Width; + Renderer.ResizeRender(); } } @@ -258,27 +296,6 @@ private void AppendRenderResult(RenderFinishedEventArgs result) } } - /// - /// Initiates a rendering of the given tracks. - /// - /// The data model holding the song information. - /// The indexes of the tracks to render. - /// If set to true, a redrawing will be done as part of this call. - public void RenderTracks(Score score, int[] tracks, bool invalidate = true) - { - if (score != null && score != Score) - { - ScoreLoaded(score, false); - } - - TrackIndexes = tracks; - - if (invalidate) - { - Render(); - } - } - /// /// Tells alphaTab to render the given alphaTex. /// @@ -292,15 +309,7 @@ public virtual void Tex(string tex, int[] tracks = null) var data = ByteBuffer.FromBuffer(Platform.Platform.StringToByteArray(tex)); parser.Init(data, Settings); var score = parser.ReadScore(); - if (tracks != null) - { - tracks = new int[] - { - 0 - }; - } - - RenderTracks(score, tracks, true); + RenderScore(score, tracks); } catch (Exception e) { @@ -308,32 +317,6 @@ public virtual void Tex(string tex, int[] tracks = null) } } - /// - /// Attempts a load of the score represented by the given data object. - /// - /// The data container supported by - /// true if the data object is supported and a load was initiated, otherwise false - public bool Load(object data) - { - try - { - return UiFacade.Load(data, - score => - { - ScoreLoaded(score); - }, - error => - { - OnError("import", error); - }); - } - catch (Exception e) - { - OnError("import", e); - return false; - } - } - /// /// Attempts a load of the score represented by the given data object. /// @@ -349,25 +332,6 @@ public bool LoadSoundFont(object data) return UiFacade.LoadSoundFont(data); } - /// - /// Performs any necessary steps that are needed after a new score was loaded/set. - /// - /// The score that was loaded. - /// If set to true, a rerendering will be initiated as part of this call. - protected internal void ScoreLoaded(Score score, bool render = true) - { - ModelUtils.ApplyPitchOffsets(Settings, score); - - Score = score; - OnLoaded(score); - LoadMidiForScore(); - - if (render) - { - Render(); - } - } - /// /// Initiates a re-rendering of the current setup. If rendering is not yet possible, it will be deferred until the UI changes to be ready for rendering. /// @@ -384,7 +348,8 @@ public void Render() if (UiFacade.CanRender) { // when font is finally loaded, start rendering - Renderer.Render(Score, TrackIndexes); + Renderer.Width = (int)Container.Width; + Renderer.RenderScore(Score, _trackIndexes.ToArray()); } else { @@ -1171,7 +1136,7 @@ public virtual void UpdateLayout(LayoutSettings layoutSettings) { Settings.Layout = layoutSettings; Renderer.UpdateSettings(Settings); - Renderer.Invalidate(); + Renderer.Render(); } diff --git a/Source/AlphaTab/Rendering/IScoreRenderer.cs b/Source/AlphaTab/Rendering/IScoreRenderer.cs index 945c0bd6d..d920fb04c 100644 --- a/Source/AlphaTab/Rendering/IScoreRenderer.cs +++ b/Source/AlphaTab/Rendering/IScoreRenderer.cs @@ -5,32 +5,36 @@ namespace AlphaTab.Rendering { /// - /// Represents the public interface of the component that can render scores. + /// Represents the public interface of the component that can render scores. /// public interface IScoreRenderer { /// - /// Gets or sets the lookup which allows fast access to beats at a given position. + /// Gets or sets the lookup which allows fast access to beats at a given position. /// BoundsLookup BoundsLookup { get; } /// - /// Invalidates the drawn music sheet and initiates a redraw. + /// Gets or sets the width of the score to be rendered. /// - void Invalidate(); + int Width { get; set; } /// - /// Triggers a relayout to the given size including redrawing. + /// Initiates a full re-rendering of the score using the current settings. /// - /// - void Resize(int width); + void Render(); /// - /// Initiates the rendering of the specified tracks of the given score. + /// Initiates a resize-optimized re-rendering of the score using the current settings. + /// + void ResizeRender(); + + /// + /// Initiates the rendering of the specified tracks of the given score. /// /// The score defining the tracks. /// The indexes of the tracks to draw. - void Render(Score score, int[] trackIndexes); + void RenderScore(Score score, int[] trackIndexes); /// /// Occurs before the rendering of the tracks starts. @@ -38,75 +42,75 @@ public interface IScoreRenderer event Action PreRender; /// - /// Occurs after the rendering of the tracks finished. + /// Occurs after the rendering of the tracks finished. /// event Action RenderFinished; /// - /// Occurs whenever a part of the whole music sheet is rendered and can be displayed. + /// Occurs whenever a part of the whole music sheet is rendered and can be displayed. /// event Action PartialRenderFinished; /// - /// Occurs when the whole rendering and layout process finished. + /// Occurs when the whole rendering and layout process finished. /// event Action PostRenderFinished; /// - /// Occurs whenever an error happens. + /// Occurs whenever an error happens. /// event Action Error; /// - /// Updates the settings to the given object. + /// Updates the settings to the given object. /// /// void UpdateSettings(Settings settings); /// - /// Destroys the renderer. + /// Destroys the renderer. /// void Destroy(); } /// /// This eventargs define the details about the rendering and layouting process and are - /// provided whenever a part of of the music sheet is rendered. + /// provided whenever a part of of the music sheet is rendered. /// public class RenderFinishedEventArgs { /// - /// Gets or sets the width of the current rendering result. + /// Gets or sets the width of the current rendering result. /// public float Width { get; set; } /// - /// Gets or sets the height of the current rendering result. + /// Gets or sets the height of the current rendering result. /// public float Height { get; set; } /// - /// Gets or sets the currently known total width of the final music sheet. + /// Gets or sets the currently known total width of the final music sheet. /// public float TotalWidth { get; set; } /// - /// Gets or sets the currently known total height of the final music sheet. + /// Gets or sets the currently known total height of the final music sheet. /// public float TotalHeight { get; set; } /// - /// Gets or sets the index of the first masterbar that was rendered in this result. + /// Gets or sets the index of the first masterbar that was rendered in this result. /// public int FirstMasterBarIndex { get; set; } /// - /// Gets or sets the index of the last masterbar that was rendered in this result. + /// Gets or sets the index of the last masterbar that was rendered in this result. /// public int LastMasterBarIndex { get; set; } /// - /// Gets or sets the render engine specific result object which contains the rendered music sheet. + /// Gets or sets the render engine specific result object which contains the rendered music sheet. /// public object RenderResult { get; set; } } diff --git a/Source/AlphaTab/Rendering/Layout/PageViewLayout.cs b/Source/AlphaTab/Rendering/Layout/PageViewLayout.cs index 5654bd9da..624062e44 100644 --- a/Source/AlphaTab/Rendering/Layout/PageViewLayout.cs +++ b/Source/AlphaTab/Rendering/Layout/PageViewLayout.cs @@ -8,7 +8,7 @@ namespace AlphaTab.Rendering.Layout { /// - /// This layout arranges the bars into a fixed width and dynamic height region. + /// This layout arranges the bars into a fixed width and dynamic height region. /// internal class PageViewLayout : ScoreLayout { @@ -53,14 +53,14 @@ protected override void DoLayoutAndRender() var x = _pagePadding[0]; var y = _pagePadding[1]; - Width = Renderer.Settings.Width; + Width = Renderer.Width; _allMasterBarRenderers = new FastList(); - // + // // 1. Score Info y = LayoutAndRenderScoreInfo(x, y); - // + // // 2. Chord Diagrms y = LayoutAndRenderChordDiagrams(y); @@ -77,14 +77,14 @@ public override void Resize() { var x = _pagePadding[0]; var y = _pagePadding[1]; - Width = Renderer.Settings.Width; + Width = Renderer.Width; var oldHeight = Height; - // + // // 1. Score Info y = LayoutAndRenderScoreInfo(x, y, oldHeight); - // + // // 2. Chord Digrams y = LayoutAndRenderChordDiagrams(y, oldHeight); @@ -225,7 +225,7 @@ private float ResizeAndRenderScore(float x, float y, float oldHeight) { var canvas = Renderer.Canvas; - // if we have a fixed number of bars per row, we only need to refit them. + // if we have a fixed number of bars per row, we only need to refit them. if (Renderer.Settings.Layout.Get("barsPerRow", -1) != -1) { for (var i = 0; i < _groups.Count; i++) @@ -237,7 +237,7 @@ private float ResizeAndRenderScore(float x, float y, float oldHeight) y += PaintGroup(group, oldHeight, canvas); } } - // if the bars per row are flexible, we need to recreate the stave groups + // if the bars per row are flexible, we need to recreate the stave groups // by readding the existing groups else { @@ -337,7 +337,7 @@ private float PaintGroup(StaveGroup group, float totalHeight, ICanvas canvas) canvas.BeginRender(Width, height); Renderer.Canvas.Color = Renderer.Settings.RenderingResources.MainGlyphColor; Renderer.Canvas.TextAlign = TextAlign.Left; - // NOTE: we use this negation trick to make the group paint itself to 0/0 coordinates + // NOTE: we use this negation trick to make the group paint itself to 0/0 coordinates // since we use partial drawing group.Paint(0, -group.Y, canvas); @@ -439,6 +439,6 @@ private StaveGroup CreateStaveGroup(int currentBarIndex, int endIndex) return group; } - private float MaxWidth => Renderer.Settings.Width - _pagePadding[0] - _pagePadding[2]; + private float MaxWidth => Renderer.Width - _pagePadding[0] - _pagePadding[2]; } } diff --git a/Source/AlphaTab/Rendering/ScoreRenderer.cs b/Source/AlphaTab/Rendering/ScoreRenderer.cs index 17feaa35e..f46b086b0 100644 --- a/Source/AlphaTab/Rendering/ScoreRenderer.cs +++ b/Source/AlphaTab/Rendering/ScoreRenderer.cs @@ -9,7 +9,7 @@ namespace AlphaTab.Rendering { /// - /// This is the main wrapper of the rendering engine which + /// This is the main wrapper of the rendering engine which /// can render a single track of a score object into a notation sheet. /// public class ScoreRenderer : IScoreRenderer @@ -76,7 +76,7 @@ private bool RecreateLayout() } /// - public void Render(Score score, int[] trackIndexes) + public void RenderScore(Score score, int[] trackIndexes) { try { @@ -104,7 +104,7 @@ public void Render(Score score, int[] trackIndexes) } Tracks = tracks.ToArray(); - Invalidate(); + Render(); } catch (Exception e) { @@ -128,7 +128,7 @@ public void RenderTracks(Track[] tracks) } Tracks = tracks; - Invalidate(); + Render(); } @@ -139,9 +139,9 @@ public void UpdateSettings(Settings settings) } /// - public void Invalidate() + public void Render() { - if (Settings.Width == 0) + if (Width == 0) { Logger.Warning("Rendering", "AlphaTab skipped rendering because of width=0 (element invisible)"); return; @@ -172,19 +172,26 @@ public void Invalidate() } /// - public void Resize(int width) + public int Width + { + get; + set; + } + + + /// + public void ResizeRender() { if (RecreateLayout() || RecreateCanvas() || _renderedTracks != Tracks || Tracks == null) { Logger.Info("Rendering", "Starting full rerendering due to layout or canvas change"); - Invalidate(); + Render(); } else if (Layout.SupportsResize) { Logger.Info("Rendering", "Starting optimized rerendering for resize"); BoundsLookup = new BoundsLookup(); OnPreRender(); - Settings.Width = width; Canvas.Settings = Settings; Layout.Resize(); Layout.RenderAnnotation(); diff --git a/Source/AlphaTab/Settings.cs b/Source/AlphaTab/Settings.cs index 110804b1f..9c1e60cf8 100644 --- a/Source/AlphaTab/Settings.cs +++ b/Source/AlphaTab/Settings.cs @@ -16,12 +16,7 @@ public partial class Settings public float Scale { get; set; } /// - /// The initial size of the canvas during loading or the width for particular layouts (e.g. page layout). - /// - public int Width { get; set; } - - /// - /// The engine which should be used to render the the tablature. + /// The engine which should be used to render the the tablature. ///
    ///
  • default - Platform specific default engine
  • ///
  • html5 - HTML5 Canvas
  • @@ -36,7 +31,7 @@ public partial class Settings public LayoutSettings Layout { get; set; } /// - /// Specific settings for importers. Keys are specific for the importers. + /// Specific settings for importers. Keys are specific for the importers. /// General ///
      ///
    • encoding - The text encoding to use when decoding strings (string, default:utf-8)
    • @@ -49,30 +44,30 @@ public partial class Settings public FastDictionary ImporterSettings { get; set; } /// - /// The default stretch force to use for layouting. + /// The default stretch force to use for layouting. /// public float StretchForce { get; set; } /// - /// Forces the fingering rendering to use always the piano finger stýle where + /// Forces the fingering rendering to use always the piano finger stýle where /// fingers are rendered as 1-5 instead of p,i,m,a,c and T,1,2,3,4. /// public bool ForcePianoFingering { get; set; } /// - /// The staves that should be shown in the music sheet. + /// The staves that should be shown in the music sheet. /// This is one of the profiles registered in the /// public StaveSettings Staves { get; set; } /// - /// The transposition pitch offsets for the individual tracks. + /// The transposition pitch offsets for the individual tracks. /// They apply to rendering and playback. /// public int[] TranspositionPitches { get; set; } /// - /// The transposition pitch offsets for the individual tracks. + /// The transposition pitch offsets for the individual tracks. /// They apply to rendering only. /// public int[] DisplayTranspositionPitches { get; set; } @@ -89,19 +84,19 @@ public partial class Settings /// /// If set to true bend arrows expand to the end of the last tied note - /// of the string. Otherwise they end on the next beat. + /// of the string. Otherwise they end on the next beat. /// public bool ExtendBendArrowsOnTiedNotes { get; set; } /// /// If set to true the note heads on tied notes - /// will have parenthesis if they are preceeded by bends. + /// will have parenthesis if they are preceeded by bends. /// public bool ShowParenthesisForTiedBends { get; set; } /// /// If set to true a tab number will be shown in case - /// a bend is increased on a tied note. + /// a bend is increased on a tied note. /// public bool ShowTabNoteOnTiedBend { get; set; } @@ -111,23 +106,23 @@ public partial class Settings public DisplayMode DisplayMode { get; set; } /// - /// Gets or sets the fingering mode to use. + /// Gets or sets the fingering mode to use. /// public FingeringMode FingeringMode { get; set; } /// - /// If set to true, 0 is shown on dive whammy bars. + /// If set to true, 0 is shown on dive whammy bars. /// public bool ShowZeroOnDiveWhammy { get; set; } /// /// If set to true, line effects (like w/bar, let-ring etc) - /// are drawn until the end of the beat instead of the start. + /// are drawn until the end of the beat instead of the start. /// public bool ExtendLineEffectsToBeatEnd { get; set; } /// - /// Gets or sets the settings on how the vibrato audio is generated. + /// Gets or sets the settings on how the vibrato audio is generated. /// public VibratoPlaybackSettings Vibrato { get; set; } @@ -138,18 +133,18 @@ public partial class Settings public float SlurHeight { get; set; } /// - /// Gets or sets the bend duration in milliseconds for songbook bends. + /// Gets or sets the bend duration in milliseconds for songbook bends. /// public int SongBookBendDuration { get; set; } /// - /// Gets or sets the duration of whammy dips in milliseconds for songbook whammys. + /// Gets or sets the duration of whammy dips in milliseconds for songbook whammys. /// public int SongBookDipDuration { get; set; } /// /// Gets or sets whether in the also the - /// position and area of each individual note is provided. + /// position and area of each individual note is provided. /// public bool IncludeNoteBounds { get; set; } @@ -164,17 +159,17 @@ public partial class Settings public bool EnablePlayer { get; set; } /// - /// Gets or sets whether playback cursors should be displayed. + /// Gets or sets whether playback cursors should be displayed. /// public bool EnableCursor { get; set; } /// - /// Gets or sets the width of the beat cursor in pixels. + /// Gets or sets the width of the beat cursor in pixels. /// public int BeatCursorWidth { get; set; } /// - /// Gets or sets the X-offset to add when scrolling. + /// Gets or sets the X-offset to add when scrolling. /// public int ScrollOffsetX { @@ -192,7 +187,7 @@ public int ScrollOffsetY } /// - /// Gets or sets the mode how to scroll. + /// Gets or sets the mode how to scroll. /// public ScrollMode ScrollMode { @@ -210,12 +205,12 @@ public int ScrollSpeed } /// - /// Gets or sets the resources used during rendering. This defines all fonts and colors used. + /// Gets or sets the resources used during rendering. This defines all fonts and colors used. /// public RenderingResources RenderingResources { get; set; } /// - /// Gets the default settings for the songbook display mode. + /// Gets the default settings for the songbook display mode. /// public static Settings SongBook { @@ -249,7 +244,6 @@ public static Settings Defaults settings.Scale = 1.0f; settings.StretchForce = 1; - settings.Width = -1; settings.Engine = "default"; settings.TranspositionPitches = new int[0]; settings.DisplayTranspositionPitches = new int[0]; From 5c9449d23550cecadb2edf4a85b79dd71dad3dc7 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Tue, 27 Aug 2019 16:07:34 +0200 Subject: [PATCH 2/2] Updated documentation --- .../examples/render-customization/size.cshtml | 9 +- Documentation/input/reference/api/load.cshtml | 32 +++++++ .../input/reference/api/renderscore.cshtml | 95 +++++++++++++++++++ .../input/reference/api/rendertracks.cshtml | 41 ++++---- .../input/reference/api/tracks.cshtml | 2 +- .../input/reference/property/width.cshtml | 68 ------------- 6 files changed, 152 insertions(+), 95 deletions(-) create mode 100644 Documentation/input/reference/api/renderscore.cshtml delete mode 100644 Documentation/input/reference/property/width.cshtml diff --git a/Documentation/input/examples/render-customization/size.cshtml b/Documentation/input/examples/render-customization/size.cshtml index ff31191f2..7a7ca676d 100644 --- a/Documentation/input/examples/render-customization/size.cshtml +++ b/Documentation/input/examples/render-customization/size.cshtml @@ -4,7 +4,7 @@ Order: 1
      Normally the page layout scales automatically to the available width. If you - want to have a fixed width (e.g. for printing) the size can be specified via width: 800 or data-width="800" + want to have a fixed width (e.g. for printing) the size of the parent container should be set accordingly.
      @@ -15,20 +15,19 @@ Order: 1
      -
      +
      -
      +