/ src / modules / Workspaces / WorkspacesEditor / Utils / WorkspacesIcon.cs
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  }