private async void PickFonts()
        {
            var picker = new FileOpenPicker();

            foreach (var format in FontFinder.SupportedFormats)
            {
                picker.FileTypeFilter.Add(format);
            }

            picker.CommitButtonText = Localization.Get("FilePickerConfirm");
            var files = await picker.PickMultipleFilesAsync();

            if (files.Any())
            {
                ViewModel.IsLoadingFonts = true;
                try
                {
                    if (await FontFinder.ImportFontsAsync(files.ToList()) is FontImportResult result &&
                        result.Imported.Count > 0)
                    {
                        ViewModel.RefreshFontList();
                        ViewModel.TrySetSelectionFromImport(result);
                    }
                }
                finally
                {
                    ViewModel.IsLoadingFonts = false;
                }
            }
        }
        IReadOnlyList <DevOption> Inflate()
        {
            var v = Options.Variant;
            var c = Character;

            bool hasSymbol = FontFinder.IsSegoeMDL2(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);
            var  hex       = c.UnicodeIndex.ToString("x4").ToUpper();

            string pathIconData = GetOutlineGeometry(c, Options);

            var ops = new List <DevOption>()
            {
                new ("TxtXamlCode/Header", c.UnicodeIndex > 0xFFFF ? $"\\U{c.UnicodeIndex:x8}".ToUpper() : $"\\u{hex}"),
                new ("TxtFontIcon/Header", $"new FontIcon {{ FontFamily = new Windows.UI.Xaml.Media.FontFamily(\"{v?.XamlFontSource}\") , Glyph = \"\\u{hex}\" }};"),
            };

            if (!string.IsNullOrWhiteSpace(pathIconData))
            {
                ops.Add(new DevOption("TxtPathIcon/Text", $"new PathIcon {{ Data = (Windows.UI.Xaml.Media.Geometry)Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(Windows.UI.Xaml.Media.Geometry), \"{pathIconData}\"), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }};",
                                      supportsTypography: true));
            }

            if (hasSymbol)
            {
                ops.Add(new DevOption("TxtSymbolIcon/Header", $"new SymbolIcon {{ Symbol = Symbol.{(Symbol)c.UnicodeIndex} }};"));
            }

            return(ops);
        }
        IReadOnlyList <DevOption> Inflate()
        {
            var v = Options.Variant;
            var c = Character;

            bool   hasSymbol    = FontFinder.IsSystemSymbolFamily(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);
            string hex          = c.UnicodeIndex.ToString("x4").ToUpper();
            string pathIconData = GetOutlineGeometry(c, Options);
            string fontIcon     = $"auto f = ref new FontIcon();\n" +
                                  $"f->FontFamily = ref new Media::FontFamily(L\"{v?.XamlFontSource}\");\n" +
                                  $"f->Glyph = L\"\\u{hex}\";";

            var ops = new List <DevOption>()
            {
                new ("TxtXamlCode/Header", c.UnicodeIndex > 0xFFFF ? $"\\U{c.UnicodeIndex:x8}".ToUpper() : $"\\u{hex}"),
                new ("TxtFontIcon/Header", fontIcon, true),
            };

            if (!string.IsNullOrWhiteSpace(pathIconData))
            {
                var data = $"auto p = ref new PathIcon();\n" +
                           "p->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;\n" +
                           "p->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;\n" +
                           $"p->Data = (Geometry^)Markup::XamlBindingHelper::ConvertValue(Geometry::typeid, L\"{pathIconData}\");";

                ops.Add(new DevOption("TxtPathIcon/Text", data, true, true));
            }

            if (hasSymbol)
            {
                ops.Add(new DevOption("TxtSymbolIcon/Header", $"ref new SymbolIcon(Symbol::{(Symbol)c.UnicodeIndex});"));
            }

            return(ops);
        }
        private async void Grid_Drop(object sender, DragEventArgs e)
        {
            if (e.DataView.Contains(StandardDataFormats.StorageItems))
            {
                ViewModel.IsLoadingFonts = true;
                try
                {
                    var items = await e.DataView.GetStorageItemsAsync();

                    if (await FontFinder.ImportFontsAsync(items) is FontImportResult result)
                    {
                        if (result.Imported.Count > 0)
                        {
                            ViewModel.RefreshFontList();
                            ViewModel.TrySetSelectionFromImport(result);
                        }

                        ShowImportResult(result);
                    }
                }
                finally
                {
                    ViewModel.IsLoadingFonts = false;
                }
            }
        }
示例#5
0
        IReadOnlyList <DevOption> Inflate()
        {
            var v = Options.Variant;
            var c = Character;

            bool hasSymbol = FontFinder.IsSystemSymbolFamily(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);
            var  hex       = c.UnicodeIndex.ToString("x4").ToUpper();

            string pathIconData = GetOutlineGeometry(c, Options);

            var ops = new List <DevOption>()
            {
                new ("TxtXamlCode/Header", $"&#x{hex};"),
                new ("TxtFontIcon/Header", $@"<FontIcon FontFamily=""{GetFontSource(v?.XamlFontSource)}"" Glyph=""&#x{hex};"" />", supportsTypography : true),
            };

            if (!string.IsNullOrWhiteSpace(pathIconData))
            {
                ops.Add(new DevOption("TxtPathIcon/Text", $"<PathIcon Data=\"{pathIconData}\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" />", supportsTypography: true));
            }

            if (hasSymbol)
            {
                ops.Add(new DevOption("TxtSymbolIcon/Header", $@"<SymbolIcon Symbol=""{(Symbol)c.UnicodeIndex}"" />"));
            }

            return(ops);
        }
        IReadOnlyList <DevOption> Inflate()
        {
            var v = Options.Variant;
            var c = Character;

            bool hasSymbol = FontFinder.IsSystemSymbolFamily(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);
            var  hex       = c.UnicodeIndex.ToString("x4").ToUpper();

            string pathIconData = GetOutlineGeometry(c, Options);
            string glyph        = c.UnicodeIndex > 0xFFFF ? $"ChrW(&H{$"{c.UnicodeIndex:x8}".ToUpper()})" : $"ChrW(&H{hex})";

            var ops = new List <DevOption>()
            {
                new ("TxtXamlCode/Header", glyph),
                new ("TxtFontIcon/Header", $"New FontIcon With {{ .FontFamily = New Windows.UI.Xaml.Media.FontFamily(\"{v?.XamlFontSource}\"), .Glyph = {glyph} }}"),
            };

            if (!string.IsNullOrWhiteSpace(pathIconData))
            {
                ops.Add(new DevOption("TxtPathIcon/Text", $"New PathIcon With {{.Data = TryCast(Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(GetType(Windows.UI.Xaml.Media.Geometry), \"{pathIconData}\"), Windows.UI.Xaml.Media.Geometry), .HorizontalAlignment = HorizontalAlignment.Center, .VerticalAlignment = VerticalAlignment.Center}}",
                                      supportsTypography: true));
            }

            if (hasSymbol)
            {
                ops.Add(new DevOption("TxtSymbolIcon/Header", $"New SymbolIcon With {{ .Symbol = Symbol.{(Symbol)c.UnicodeIndex} }}"));
            }

            return(ops);
        }
示例#7
0
        static void Main(string[] args)
        {
            var finder = new FontFinder();

            Console.Write("Search for Truetype (*.TTF) fonts? [y/n]");
            var ttf = "y" == Console.ReadLine().ToLower();

            Console.Write("Search for Opentype (*.OTF) fonts? [y/n]");
            var otf = "y" == Console.ReadLine().ToLower();

            Console.Write("Search for Woff2 (*.WOFF2) webfonts? [y/n]");
            var woff2 = "y" == Console.ReadLine().ToLower();

            Console.Write("What font would you like to get?");
            var fontName = Console.ReadLine();

            Console.WriteLine("Getting results from Github, please wait...");

            var results = finder.SearchForFont(fontName, ttf, otf, woff2);

            foreach (var result in results)
            {
                Console.WriteLine(result);
            }
        }
        private async void OpenFont()
        {
            var picker = new FileOpenPicker();

            foreach (var format in FontFinder.SupportedFormats)
            {
                picker.FileTypeFilter.Add(format);
            }

            picker.CommitButtonText = Localization.Get("OpenFontPickerConfirm");
            var file = await picker.PickSingleFileAsync();

            if (file != null)
            {
                try
                {
                    ViewModel.IsLoadingFonts = true;

                    if (await FontFinder.LoadFromFileAsync(file) is InstalledFont font)
                    {
                        await FontMapView.CreateNewViewForFontAsync(font);
                    }
                }
                finally
                {
                    ViewModel.IsLoadingFonts = false;
                }
            }
        }
        public static (string Hex, string FontIcon, string Path, string Symbol) GetDevValues(
            Character c, FontVariant v, CanvasTextLayoutAnalysis a, CanvasTypography t, bool isXaml)
        {
            if (v == FontFinder.DefaultFont.DefaultVariant)
            {
                return(string.Empty, string.Empty, string.Empty, string.Empty);
            }

            NativeInterop interop = Utils.GetInterop();

            string h, f, p, s = null;
            bool   hasSymbol = FontFinder.IsSegoeMDL2(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);

            // Add back in future build
            //string pathData;
            //using (var geom = ExportManager.CreateGeometry(ResourceHelper.AppSettings.GridSize, v, c, a, t))
            //{
            //    pathData = interop.GetPathData(geom).Path;
            //}

            // Creating geometry is expensive. It may be worth delaying this.
            string pathIconData = null;

            if (v != null)
            {
                using var geom = ExportManager.CreateGeometry(20, v, c, a, t);
                pathIconData   = interop.GetPathData(geom).Path;
            }

            var hex = c.UnicodeIndex.ToString("x4").ToUpper();

            if (isXaml)
            {
                h = $"&#x{hex};";
                f = $@"<FontIcon FontFamily=""{v?.XamlFontSource}"" Glyph=""&#x{hex};"" />";
                p = $"<PathIcon Data=\"{pathIconData}\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" />";

                if (hasSymbol)
                {
                    s = $@"<SymbolIcon Symbol=""{(Symbol)c.UnicodeIndex}"" />";
                }
            }
            else
            {
                h = c.UnicodeIndex > 0xFFFF ? $"\\U{c.UnicodeIndex:x8}".ToUpper() : $"\\u{hex}";
                f = $"new FontIcon {{ FontFamily = new Windows.UI.Xaml.Media.FontFamily(\"{v?.XamlFontSource}\") , Glyph = \"\\u{hex}\" }};";
                p = $"new PathIcon {{ Data = (Windows.UI.Xaml.Media.Geometry)Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(Geometry), \"{pathIconData}\"), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }};";

                if (hasSymbol)
                {
                    s = $"new SymbolIcon {{ Symbol = Symbol.{(Symbol)c.UnicodeIndex} }};";
                }
            }

            return(h, f, p, s);
        }
示例#10
0
        protected override async void OnLaunched(LaunchActivatedEventArgs e)
        {
            if (!e.PrelaunchActivated)
            {
                await ActivationService.ActivateAsync(e);
            }
            else
            {
                await FontFinder.LoadFontsAsync();

                await Ioc.Default.GetService <UserCollectionsService>().LoadCollectionsAsync();
            }
        }
示例#11
0
        public static (string Hex, string FontIcon, string Path, string Symbol) GetDevValues(
            Character c, FontVariant v, CanvasTextLayoutAnalysis a, CanvasTypography t, bool isXaml)
        {
            if (v == FontFinder.DefaultFont.DefaultVariant)
            {
                return(string.Empty, string.Empty, string.Empty, string.Empty);
            }

            Interop interop = SimpleIoc.Default.GetInstance <Interop>();

            string h, f, p, s = null;
            bool   hasSymbol = FontFinder.IsMDL2(v) && Enum.IsDefined(typeof(Symbol), c.UnicodeIndex);

            string pathData;

            using (var geom = ExportManager.CreateGeometry(ResourceHelper.AppSettings.GridSize, v, c, a, t))
            {
                pathData = interop.GetPathData(geom).Path;
            }

            var hex = c.UnicodeIndex.ToString("x4").ToUpper();

            if (isXaml)
            {
                h = $"&#x{hex};";
                f = $@"<FontIcon FontFamily=""{v.XamlFontSource}"" Glyph=""&#x{hex};"" />";
                p = $"<Path Data=\"{pathData}\" Fill=\"{{ThemeResource SystemControlForegroundBaseHighBrush}}\" Stretch=\"Uniform\" />";

                if (hasSymbol)
                {
                    s = $@"<SymbolIcon Symbol=""{(Symbol)c.UnicodeIndex}"" />";
                }
            }
            else
            {
                h = $"\\u{hex}";
                f = $"new FontIcon {{ FontFamily = new Windows.UI.Xaml.Media.FontFamily(\"{v.XamlFontSource}\") , Glyph = \"\\u{hex}\" }};";
                p = $"new Windows.UI.Xaml.Shapes.Path {{ Data = (Windows.UI.Xaml.Media.Geometry)Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(Geometry), \"{pathData}\"), Fill = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Black), Stretch = Windows.UI.Xaml.Media.Stretch.Uniform }};";

                if (hasSymbol)
                {
                    s = $"new SymbolIcon {{ Symbol = Symbol.{(Symbol)c.UnicodeIndex} }};";
                }
            }

            return(h, f, p, s);
        }
        public string GetCharacterDescription(int unicodeIndex, FontVariant variant)
        {
            if (FontFinder.IsMDL2(variant))
            {
                return(_connection.Get <MDL2Glyph>(g => g.UnicodeIndex == unicodeIndex)?.Description);
            }

            if (IsFontAwesome(variant))
            {
                return(_connection.Get <FontAwesomeGlyph>(g => g.UnicodeIndex == unicodeIndex)?.Description);
            }

            if (variant.FontFace.IsSymbolFont)
            {
                return(null);
            }

            return(_connection.Get <UnicodeGlyphData>(u => u.UnicodeIndex == unicodeIndex)?.Description);
        }
        IReadOnlyList <DevOption> Inflate()
        {
            var v = Options.Variant;
            var c = Character;

            bool   hasSymbol    = FontFinder.IsSystemSymbolFamily(v) && Enum.IsDefined(typeof(Symbol), (int)c.UnicodeIndex);
            string hex          = c.UnicodeIndex.ToString("x4").ToUpper();
            string pathIconData = GetOutlineGeometry(c, Options);

            string fontIcon =
                "// Add \"#include <winrt/Windows.UI.Xaml.Media.h>\" to pch.h\n" +
                "auto f = FontIcon();\n" +
                $"f.Glyph(L\"\\u{hex}\");\n" +
                $"f.FontFamily(Media::FontFamily(L\"{v?.XamlFontSource}\"));";

            var ops = new List <DevOption>()
            {
                new ("TxtXamlCode/Header", c.UnicodeIndex > 0xFFFF ? $"\\U{c.UnicodeIndex:x8}".ToUpper() : $"\\u{hex}"),
                new ("TxtFontIcon/Header", fontIcon, true),
            };

            if (!string.IsNullOrWhiteSpace(pathIconData))
            {
                var data =
                    $"// Add \"#include <winrt/Windows.UI.Xaml.Media.h>\" to pch.h\n" +
                    $"auto p = PathIcon();\n" +
                    $"p.VerticalAlignment(VerticalAlignment::Center);\n" +
                    $"p.HorizontalAlignment(HorizontalAlignment::Center);\n" +
                    $"p.Data(Markup::XamlBindingHelper::ConvertValue(winrt::xaml_typename<Geometry>(), box_value(L\"{pathIconData}\")).try_as<Geometry>());";

                ops.Add(new DevOption("TxtPathIcon/Text", data, true, true));
            }

            if (hasSymbol)
            {
                ops.Add(new DevOption("TxtSymbolIcon/Header", $"SymbolIcon(Symbol::{(Symbol)c.UnicodeIndex});"));
            }

            return(ops);
        }
        public Task <IReadOnlyList <IGlyphData> > SearchAsync(string query, FontVariant variant)
        {
            if (string.IsNullOrWhiteSpace(query))
            {
                return(Task.FromResult(GlyphService.EMPTY_SEARCH));
            }

            /* MDL2 has special dataset */
            if (FontFinder.IsMDL2(variant))
            {
                return(SearchMDL2Async(query, variant));
            }

            /* FontAwesome has special dataset */
            if (IsFontAwesome(variant))
            {
                return(SearchFontAwesomeAsync(query, variant));
            }

            /* Generic Unicode Search */
            return(SearchUnicodeAsync(query, variant));
        }
示例#15
0
        public Task <IReadOnlyList <IGlyphData> > SearchAsync(string query, FontVariant variant)
        {
            if (string.IsNullOrWhiteSpace(query))
            {
                return(Task.FromResult(GlyphService.EMPTY_SEARCH));
            }

            /* MDL2 has special dataset */
            if (FontFinder.IsMDL2(variant))
            {
                return(SearchMDL2Async(query, variant));
            }

            foreach (SearchTarget target in SearchTarget.KnownTargets)
            {
                if (target.IsTarget(variant))
                {
                    return(InternalSearchAsync(target.SearchTable, target.TargetType.Name, query, variant));
                }
            }

            /* Generic Unicode Search */
            return(SearchUnicodeAsync(query, variant));
        }
示例#16
0
        public string GetCharacterDescription(int unicodeIndex, FontVariant variant)
        {
            string desc = null;

            // MDL2 has it's own special logic
            if (FontFinder.IsMDL2(variant))
            {
                desc = _connection.Get <MDL2Glyph>(g => g.UnicodeIndex == unicodeIndex)?.Description;
                if (string.IsNullOrWhiteSpace(desc) && Enum.IsDefined(typeof(Symbol), unicodeIndex))
                {
                    return(((Symbol)unicodeIndex).ToString().Humanize(LetterCasing.Title));
                }
                return(desc);
            }

            // Otherwise check if we have a search table for this font
            foreach (var target in SearchTarget.KnownTargets)
            {
                if (target.IsTarget(variant))
                {
                    var map   = _connection.GetMapping(target.TargetType);
                    var items = _connection.Query(map, $"SELECT * FROM {target.SearchTable} WHERE Ix = ? LIMIT 1", unicodeIndex);
                    desc = (items.FirstOrDefault() as GlyphDescription)?.Description;

                    break;
                }
            }

            // Otherwise get a fallback value
            if (string.IsNullOrEmpty(desc))
            {
                desc = _connection.Get <UnicodeGlyphData>(u => u.UnicodeIndex == unicodeIndex)?.Description;
            }

            return(desc);
        }
        private Task <IReadOnlyList <IGlyphData> > InternalSearchAsync(string ftsTable, string table, string query, FontVariant variant)
        {
            return(Task.Run <IReadOnlyList <IGlyphData> >(() =>
            {
                /*
                 * Step 1: Perform single-result Hex Search if hex
                 * Step 2: Perform FTS search if not hex or ambiguous
                 * Step 3: Perform LIKE search if still space for results
                 */

                // 1. Decide if hex or FTS4 search
                // 1.1. If hex, search the main table (UnicodeIndex column is indexed)
                GlyphDescription hexResult = null;
                bool ambiguous = !variant.FontFace.IsSymbolFont && IsAmbiguousQuery(query);
                if (Utils.TryParseHexString(query, out int hex))
                {
                    // 1.2. To be more efficient, first check if the font actually contains the UnicodeIndex.
                    //      If it does then we ask the database, otherwise we can return without query.
                    foreach (var range in variant.UnicodeRanges)
                    {
                        if (hex >= range.Item1 && hex <= range.Item2)
                        {
                            string hexsql = $"SELECT * FROM {table} WHERE UnicodeIndex == {hex} LIMIT 1";
                            var hexresults = _connection.Query <GlyphDescription>(hexsql, query)?.Cast <IGlyphData>()?.ToList();
                            if (hexresults == null || hexresults.Count == 0)
                            {
                                var label = hex.ToString("X");
                                hexresults = new List <IGlyphData>()
                                {
                                    new GlyphDescription
                                    {
                                        UnicodeIndex = hex,
                                        UnicodeHex = label,
                                        Description = label
                                    }
                                };
                            }

                            // 1.3. If the search is ambiguous we should still search for description matches,
                            //      otherwise we can return right now
                            if (!ambiguous)
                            {
                                return hexresults;
                            }
                            else
                            {
                                hexResult = hexresults.Cast <GlyphDescription>().FirstOrDefault();
                                break;
                            }
                        }
                    }

                    // 1.4. If the search is ambiguous we should still search for description matches,
                    //      otherwise we can return right now with no hex results
                    //      If we are a generic symbol font, that's all folks. Time to leave.
                    if (!ambiguous)
                    {
                        return GlyphService.EMPTY_SEARCH;
                    }
                }

                // 1.5. If we are a generic symbol font, we don't match by character name so time to go home.
                if (!FontFinder.IsMDL2(variant) && !IsFontAwesome(variant) && variant.FontFace.IsSymbolFont)
                {
                    return GlyphService.EMPTY_SEARCH;
                }

                // 2. If we're performing SQL, create the base query filter
                StringBuilder sb = new StringBuilder();
                bool next = false;
                foreach ((int, int)range in variant.UnicodeRanges)
                {
                    if (next)
                    {
                        sb.AppendFormat(" OR UnicodeIndex BETWEEN {0} AND {1}", range.Item1, range.Item2);
                    }
                    else
                    {
                        next = true;
                        sb.AppendFormat("WHERE (UnicodeIndex BETWEEN {0} AND {1}", range.Item1, range.Item2);
                    }
                }
                sb.Append(")");

                // 2.1. A helper method to inject the hex result for ambiguous searches
                List <IGlyphData> InsertHex(List <IGlyphData> list)
                {
                    if (hexResult != null)
                    {
                        list.Insert(0, hexResult);
                    }
                    return list;
                }

                // 3. Otherwise, perform a multi-step text search. First perform an FTS4 search
                string sql = $"SELECT * FROM {ftsTable} {sb.ToString()} AND Description MATCH '{query}' LIMIT {SEARCH_LIMIT}";
                var results = _connection.Query <GlyphDescription>(sql, query)?.Cast <IGlyphData>()?.ToList();

                // 4. If we have SEARCH_LIMIT matches, we don't need to perform a partial search and can go home early
                if (results != null && results.Count == SEARCH_LIMIT)
                {
                    return InsertHex(results);
                }

                // 5. Perform a partial search on non-FTS table. Only search for what we need.
                //    This means limit the amount of results, and exclude anything we've already matched.
                int limit = results == null ? SEARCH_LIMIT : SEARCH_LIMIT - results.Count;
                if (limit != SEARCH_LIMIT)
                {
                    // 5.1. We need to exclude anything already found above
                    sb.AppendFormat("AND UnicodeIndex NOT IN ({0})",
                                    string.Join(", ", results.Select(r => r.UnicodeIndex)));
                }

                // 6. Execute on the non FTS tables
                string sql2 = $"SELECT * FROM {table} {sb.ToString()} AND Description LIKE '%{query}%' LIMIT {limit}";
                var results2 = _connection.Query <GlyphDescription>(sql2, query)?.Cast <IGlyphData>()?.ToList();

                if (results != null)
                {
                    results.AddRange(results2);
                    return InsertHex(results);
                }
                else
                {
                    return InsertHex(results2);
                }
            }));
        }