From 11fd096a3d2c6db5e2a6e88526cf135b6ce5080e Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Thu, 23 Jan 2020 14:40:10 +0100 Subject: [PATCH 1/2] [Ide] Dynamically add ~contrast~dark~sel resource mappings to avoid adding duplicate EmbeddedResource entries to project files. --- .../MonoDevelop.Ide/ImageService.cs | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs index cd1b75f4979..7bdc877de10 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs @@ -929,12 +929,45 @@ public IEnumerable GetAlternativeFiles (string fileName, string baseName resourceList.Sort (); // sort resources by name } - return resourceList.Where (r => r.StartsWith (baseName) && r.EndsWith (ext)); + return GetFinalFilelist (resourceList, baseName, ext); } + IEnumerable GetFinalFilelist (IEnumerable source, string baseName, string ext) + { + foreach (var name in source) { + if (name.StartsWith (baseName) && name.EndsWith (ext)) { + yield return name; + + var tagPortion = name.Substring (baseName.Length, name.Length - baseName.Length - ext.Length); + // to avoid duplicate resource entries in project files, add virtual file mappings for + // high contrast icons in selected state + if (tagPortion == "~dark~sel" || tagPortion == "~dark~sel@2x") { + var map = name.Replace ("~dark~sel", "~contrast~dark~sel"); + if (virtualMappings == null) { + virtualMappings = new Dictionary (); + } + if (!virtualMappings.ContainsKey (map)) { + virtualMappings.Add (map, name); + } + yield return map; + } else { + // remove existing mapping if a resource with the same name exists. + // note: we know that the source is sorted + virtualMappings?.Remove (name); + } + } + } + } + + Dictionary virtualMappings; + public Stream LoadImage (string fileName) { - return addin.GetResource (fileName, true); + // load original resource if a mapping exists + if (virtualMappings != null && virtualMappings.TryGetValue (fileName, out var mapsTo)) + return addin.GetResource (mapsTo, true); + else + return addin.GetResource (fileName, true); } } } From f5db8837d0a1edaa84d7915e3745266482990b3f Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Thu, 23 Jan 2020 16:11:55 +0100 Subject: [PATCH 2/2] [Ide] Avoid one string allocation in CustomImageLoader --- .../MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs index 7bdc877de10..88f9c7d9cea 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs @@ -938,10 +938,14 @@ IEnumerable GetFinalFilelist (IEnumerable source, string baseNam if (name.StartsWith (baseName) && name.EndsWith (ext)) { yield return name; - var tagPortion = name.Substring (baseName.Length, name.Length - baseName.Length - ext.Length); // to avoid duplicate resource entries in project files, add virtual file mappings for - // high contrast icons in selected state - if (tagPortion == "~dark~sel" || tagPortion == "~dark~sel@2x") { + // high contrast icons in selected state. + // note: we include the "." to ensure that we match "~dark~sel" exactly and not "~dark~sel~xyz". + int start = baseName.Length; + int length = name.Length - baseName.Length - ext.Length + 1; + if (name.IndexOf ("~dark~sel.", start, length, StringComparison.Ordinal) == start || + name.IndexOf ("~dark~sel@2x.", start, length, StringComparison.Ordinal) == start) + { var map = name.Replace ("~dark~sel", "~contrast~dark~sel"); if (virtualMappings == null) { virtualMappings = new Dictionary ();