Fix System.Drawing.Tests.SystemFontsTests.SystemFont_Get_ReturnsExpected_WindowsNames...
authorGanbarukamo41 <ganbarukamo@gmail.com>
Tue, 2 Apr 2019 17:43:34 +0000 (18:43 +0100)
committerSantiago Fernandez Madero <safern@microsoft.com>
Tue, 2 Apr 2019 17:43:34 +0000 (10:43 -0700)
* Add another native function, change SetLastError to false

* Fixed so it tests with appropriate test data according to user locale, tests for DefaultFont/DialogFont removed

* Remove unused native function

* Change non-ASCII characters to escape sequences

* Add a single space after the comment header

* Use nameof() instead of string literals for systemFontName

* Remove a using statement that has been added accidentally

* Include more detailed message when throwing an exception

Commit migrated from https://github.com/dotnet/corefx/commit/158cd903a64aa14b85d06b90ed2e8804c2f2eb11

src/libraries/System.Drawing.Common/tests/SystemFontsTests.cs

index effc04c..126e71c 100644 (file)
@@ -37,22 +37,72 @@ namespace System.Drawing.Tests
 
         public static IEnumerable<object[]> SystemFonts_WindowsNames_TestData()
         {
-            yield return Font(() => SystemFonts.CaptionFont, "CaptionFont", "Segoe UI");
-            yield return Font(() => SystemFonts.IconTitleFont, "IconTitleFont", "Segoe UI");
-            yield return Font(() => SystemFonts.MenuFont, "MenuFont", "Segoe UI");
-            yield return Font(() => SystemFonts.MessageBoxFont, "MessageBoxFont", "Segoe UI");
-            yield return Font(() => SystemFonts.SmallCaptionFont, "SmallCaptionFont", "Segoe UI");
-            yield return Font(() => SystemFonts.StatusFont, "StatusFont", "Segoe UI");
+            int userLangId = GetUserDefaultLCID();
+            SystemFontList fonts;
 
-            bool isArabic = (GetSystemDefaultLCID() & 0x3ff) == 0x0001;
-            yield return Font(() => SystemFonts.DefaultFont, "DefaultFont", isArabic ? "Tahoma" : "Microsoft Sans Serif");
+            switch (userLangId & 0x3ff)
+            {
+                case 0x11: // ja-JP (Japanese)
+                    fonts = new SystemFontList("Yu Gothic UI");
+                    break;
+                case 0x5C: // chr-Cher-US (Cherokee)
+                    fonts = new SystemFontList("Gadugi");
+                    break;
+                case 0x12: // ko-KR (Korean)
+                    fonts = new SystemFontList("\ub9d1\uc740\x20\uace0\ub515");
+                    break;
+                case 0x4: // zh-TW (Traditional Chinese, Taiwan) or zh-CN (Simplified Chinese, PRC)
+                    // Although the primary language ID is the same, the fonts are different
+                    // So we have to determine by the full language ID
+                    // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f
+                    // Assuming this doc is correct AND the font only differs by whether it's traditional or not it should work
+                    switch (userLangId & 0xFFFF)
+                    {
+                        case 0x0004: // zh-Hans
+                        case 0x7804: // zh
+                        case 0x0804: // zh-CN
+                        case 0x1004: // zh-SG
+                            fonts = new SystemFontList("Microsoft JhengHei UI");
+                            break;
+                        case 0x7C04: // zh-Hant
+                        case 0x0C04: // zh-HK
+                        case 0x1404: // zh-MO
+                        case 0x0404: // zh-TW
+                            fonts = new SystemFontList("Microsoft YaHei UI");
+                            break;
+                        default:
+                            throw new InvalidOperationException("The primary language ID is Chinese, however it was not able to" +
+                                                                $" determine the user locale from the LCID with value: {userLangId & 0xFFFF:X4}.");
+                    }
+                    break;
+                case 0x1E: // th-TH
+                case 0x54: // lo-LA
+                case 0x53: // km-KH 
+                    fonts = new SystemFontList("Leelawadee UI");
+                    break;
+                case 0x4A: // te-IN
+                case 0x49: // ta-IN
+                case 0x5B: // si-LK
+                case 0x48: // or-IN
+                case 0x4E: // mr-IN
+                case 0x4C: // ml-IN
+                case 0x57: // kok-IN
+                case 0x45: // bn-BD
+                case 0x4D: // as-IN
+                    fonts = new SystemFontList("Nirmala UI");
+                    break;
+                case 0x5E: // am-ET
+                    fonts = new SystemFontList("Ebrima");
+                    break;
+                default: // For now we assume everything else uses Segoe UI
+                    // If there's other failure reported we can add it
+                    fonts = new SystemFontList("Segoe UI");
+                    break;
+            }
 
-            bool isJapanese = (GetSystemDefaultLCID() & 0x3ff) == 0x0011;
-            yield return Font(() => SystemFonts.DialogFont, "DialogFont", isJapanese ? "Microsoft Sans Serif" : "Tahoma");
+            return fonts.ToTestData();
         }
 
-        public static object[] Font(Func<Font> getFont, string systemFontName, string windowsFontName) => new object[] { getFont, systemFontName, windowsFontName };
-
         [PlatformSpecific(TestPlatforms.Windows)]
         [ConditionalTheory(Helpers.IsDrawingSupported)]
         [MemberData(nameof(SystemFonts_WindowsNames_TestData))]
@@ -85,7 +135,42 @@ namespace System.Drawing.Tests
             Assert.Null(SystemFonts.GetFontByName(systemFontName));
         }
 
-        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
-        public static extern int GetSystemDefaultLCID();
+        [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
+        public static extern int GetUserDefaultLCID();
+
+        // Do not test DefaultFont and DialogFont, as we can't reliably determine from LCID
+        // https://github.com/dotnet/corefx/issues/35664#issuecomment-473556522
+        class SystemFontList
+        {
+            public SystemFontList(string c_it_m_mb_scFonts)
+            {
+                CaptionFont = c_it_m_mb_scFonts;
+                IconTitleFont = c_it_m_mb_scFonts;
+                MenuFont = c_it_m_mb_scFonts;
+                MessageBoxFont = c_it_m_mb_scFonts;
+                SmallCaptionFont = c_it_m_mb_scFonts;
+                StatusFont = c_it_m_mb_scFonts;
+            }
+
+            public string CaptionFont { get; set; }
+            public string IconTitleFont { get; set; }
+            public string MenuFont { get; set; }
+            public string MessageBoxFont { get; set; }
+            public string SmallCaptionFont { get; set; }
+            public string StatusFont { get; set; }
+
+            public IEnumerable<object[]> ToTestData()
+            {
+                return new []
+                {
+                new object[] {(Func<Font>)(() => SystemFonts.CaptionFont), nameof(CaptionFont), CaptionFont},
+                new object[] {(Func<Font>)(() => SystemFonts.IconTitleFont), nameof(IconTitleFont), IconTitleFont},
+                new object[] {(Func<Font>)(() => SystemFonts.MenuFont), nameof(MenuFont), MenuFont},
+                new object[] {(Func<Font>)(() => SystemFonts.MessageBoxFont), nameof(MessageBoxFont), MessageBoxFont},
+                new object[] {(Func<Font>)(() => SystemFonts.SmallCaptionFont), nameof(SmallCaptionFont), SmallCaptionFont},
+                new object[] {(Func<Font>)(() => SystemFonts.StatusFont), nameof(StatusFont), StatusFont}
+                };
+            }
+        }
     }
 }