WorkspacesIcon.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Drawing; 7 using System.Drawing.Drawing2D; 8 using System.Drawing.Imaging; 9 using System.IO; 10 using System.Linq; 11 12 using ManagedCommon; 13 14 namespace WorkspacesEditor.Utils 15 { 16 public class WorkspacesIcon : IDisposable 17 { 18 private const int IconSize = 128; 19 20 public static readonly Brush LightThemeIconBackground = new SolidBrush(Color.FromArgb(255, 239, 243, 251)); 21 public static readonly Brush LightThemeIconForeground = new SolidBrush(Color.FromArgb(255, 47, 50, 56)); 22 public static readonly Brush DarkThemeIconBackground = new SolidBrush(Color.FromArgb(255, 55, 55, 55)); 23 public static readonly Brush DarkThemeIconForeground = new SolidBrush(Color.FromArgb(255, 228, 228, 228)); 24 25 public static readonly Font IconFont = new("Aptos", 24, FontStyle.Bold); 26 27 public static string IconTextFromProjectName(string projectName) 28 { 29 string result = string.Empty; 30 char[] delimiterChars = { ' ', ',', '.', ':', '-', '\t' }; 31 string[] words = projectName.Split(delimiterChars); 32 33 foreach (string word in words) 34 { 35 if (string.IsNullOrEmpty(word)) 36 { 37 continue; 38 } 39 40 if (word.All(char.IsDigit)) 41 { 42 result += word; 43 } 44 else 45 { 46 result += word.ToUpper(System.Globalization.CultureInfo.CurrentCulture).ToCharArray()[0]; 47 } 48 } 49 50 return result; 51 } 52 53 public static Bitmap DrawIcon(string text, Theme currentTheme) 54 { 55 Brush background = currentTheme == Theme.Dark ? DarkThemeIconBackground : LightThemeIconBackground; 56 Brush foreground = currentTheme == Theme.Dark ? DarkThemeIconForeground : LightThemeIconForeground; 57 Bitmap bitmap = new Bitmap(IconSize, IconSize); 58 59 using (Graphics graphics = Graphics.FromImage(bitmap)) 60 { 61 graphics.SmoothingMode = SmoothingMode.AntiAlias; 62 graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 63 graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 64 graphics.FillEllipse(background, 0, 0, IconSize, IconSize); 65 66 var textSize = graphics.MeasureString(text, IconFont); 67 var state = graphics.Save(); 68 69 // Calculate scaling factors 70 float scaleX = (float)IconSize / textSize.Width; 71 float scaleY = (float)IconSize / textSize.Height; 72 float scale = Math.Min(scaleX, scaleY) * 0.8f; // Use the smaller scale factor to maintain aspect ratio 73 74 // Calculate the position to center the text 75 float textX = (IconSize - (textSize.Width * scale)) / 2; 76 float textY = ((IconSize - (textSize.Height * scale)) / 2) + 6; 77 78 graphics.TranslateTransform(textX, textY); 79 graphics.ScaleTransform(scale, scale); 80 graphics.DrawString(text, IconFont, foreground, 0, 0); 81 graphics.Restore(state); 82 } 83 84 return bitmap; 85 } 86 87 public static void SaveIcon(Bitmap icon, string path) 88 { 89 if (Path.Exists(path)) 90 { 91 File.Delete(path); 92 } 93 94 FileStream fileStream = new FileStream(path, FileMode.CreateNew); 95 using (var memoryStream = new MemoryStream()) 96 { 97 WorkspacesCsharpLibrary.DrawHelper.SaveBitmap(icon, memoryStream); 98 99 BinaryWriter iconWriter = new BinaryWriter(fileStream); 100 if (fileStream != null && iconWriter != null) 101 { 102 // 0-1 reserved, 0 103 iconWriter.Write((byte)0); 104 iconWriter.Write((byte)0); 105 106 // 2-3 image type, 1 = icon, 2 = cursor 107 iconWriter.Write((short)1); 108 109 // 4-5 number of images 110 iconWriter.Write((short)1); 111 112 // image entry 1 113 // 0 image width 114 iconWriter.Write((byte)IconSize); 115 116 // 1 image height 117 iconWriter.Write((byte)IconSize); 118 119 // 2 number of colors 120 iconWriter.Write((byte)0); 121 122 // 3 reserved 123 iconWriter.Write((byte)0); 124 125 // 4-5 color planes 126 iconWriter.Write((short)0); 127 128 // 6-7 bits per pixel 129 iconWriter.Write((short)32); 130 131 // 8-11 size of image data 132 iconWriter.Write((int)memoryStream.Length); 133 134 // 12-15 offset of image data 135 iconWriter.Write((int)(6 + 16)); 136 137 // write image data 138 // png data must contain the whole png data file 139 iconWriter.Write(memoryStream.ToArray()); 140 141 iconWriter.Flush(); 142 } 143 } 144 145 fileStream.Flush(); 146 fileStream.Close(); 147 } 148 149 public void Dispose() 150 { 151 GC.SuppressFinalize(this); 152 } 153 } 154 }