public static bool ContainsEmojiSymbols(FontVariant v) { return(ContainsRange(v, UnicodeRange.SymbolsExtended) || ContainsRange(v, UnicodeRange.MiscSymbols) || ContainsRange(v, UnicodeRange.SupplementalSymbols) || ContainsRange(v, UnicodeRange.TransportSymbols)); }
public HtmlFont(FontStyle style, FontVariant variant, FontWeight weight, Unit size, FontFamily family) { this.style = style; this.variant = variant; this.family = family; this.weight = weight; this.size = size; }
public static void CreateMenu( MenuFlyout menu, InstalledFont font, FontVariant variant, bool standalone, bool showAdvanced = false) { MainViewModel main = ResourceHelper.Get <ViewModelLocator>("Locator").Main;
public HtmlFont(FontStyle style, FontVariant variant, FontWeight weight, Unit size, string family) { this.style = style; this.variant = variant; this.family = family; this.weight = weight; this.size = size; }
internal static string GetCharacterDescription(int unicodeIndex, FontVariant variant) { if (variant == null || _provider == null) { return(null); } return(_provider.GetCharacterDescription(unicodeIndex, variant)); }
/// <summary> /// Creates the context menu for the Font List or the "..." button. /// Both of these have a font as their main target. /// </summary> /// <param name="menu"></param> /// <param name="font"></param> /// <param name="variant"></param> /// <param name="headerContent"></param> /// <param name="standalone"></param> /// <param name="showAdvanced"></param> public static void CreateMenu( MenuFlyout menu, InstalledFont font, FontVariant variant, FrameworkElement headerContent, bool standalone, bool showAdvanced = false) { MainViewModel main = Ioc.Default.GetService <MainViewModel>();
internal static Task <IReadOnlyList <IGlyphData> > SearchAsync(string query, FontVariant variant) { if (variant == null) { return(Task.FromResult(EMPTY_SEARCH)); } return(_provider.SearchAsync(query, variant)); }
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); }
internal TextRun(string text, FontStyle fontStyle, FontVariant fontVariant, FontWeight fontWeight, TextDecoration textDecoration, VerticalAlign verticalAlign) : base(string.IsNullOrEmpty(text)) { // init this.Text = text; this.FontStyle = fontStyle; this.FontVariant = fontVariant; this.FontWeight = fontWeight; this.TextDecoration = textDecoration; this.VerticalAlign = verticalAlign; }
public TextRun(string text, FontStyle fontStyle, FontVariant fontVariant, FontWeight fontWeight, TextDecoration textDecoration, VerticalAlign verticalAlign) : base(string.IsNullOrEmpty(text)) { // init Text = text; FontStyle = fontStyle; FontVariant = fontVariant; FontWeight = fontWeight; TextDecoration = textDecoration; VerticalAlign = verticalAlign; }
/// <summary> /// Determines if the given value represents a valid state of this property. /// </summary> /// <param name="value">The state that should be used.</param> /// <returns>True if the state is valid, otherwise false.</returns> protected override Boolean IsValid(CSSValue value) { var variant = value.ToFontVariant(); if (variant.HasValue) { _variant = variant.Value; return(true); } return(false); }
public void WriteXml(XmlWriter writer) { writer.WriteStartElement(FontElementName); writer.WriteAttributeString(StyleAttributeName, FontStyle.ToString()); writer.WriteAttributeString(VariantAttributeName, FontVariant.ToString()); writer.WriteAttributeString(WidthAttributeName, FontWidth.ToString()); writer.WriteAttributeString(StretchAttributeName, FontStretch.ToString()); foreach (var fontSource in _sources) { fontSource.WriteXml(writer); } writer.WriteEndElement(); }
public override string GetStepParameters() { var parameters = new List <string>(); parameters.Add(Name != null ? Name.ToStepValue() : "$"); parameters.Add(FontFamily != null ? FontFamily.ToStepValue() : "$"); parameters.Add(FontStyle != null ? FontStyle.ToStepValue() : "$"); parameters.Add(FontVariant != null ? FontVariant.ToStepValue() : "$"); parameters.Add(FontWeight != null ? FontWeight.ToStepValue() : "$"); parameters.Add(FontSize != null ? FontSize.ToStepValue() : "$"); return(string.Join(", ", parameters.ToArray())); }
private CiteProc.Formatting.FontVariant Map(FontVariant variant) { switch (variant) { case v10.FontVariant.Normal: return(CiteProc.Formatting.FontVariant.Normal); case v10.FontVariant.SmallCaps: return(CiteProc.Formatting.FontVariant.SmallCaps); default: throw new NotSupportedException(); } }
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); }
protected override Boolean IsValid(CSSValue value) { if (value.Is("normal")) { _style = FontVariant.Normal; } else if (value.Is("small-caps")) { _style = FontVariant.SmallCaps; } else if (value != CSSValue.Inherit) { return(false); } return(true); }
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); }
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)); }
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)); }
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.First && hex <= range.Last) { string hexsql = $"SELECT * FROM {table} WHERE Ix == {hex} LIMIT 1"; var hexresults = _connection.Query <GlyphDescription>(hexsql, query)?.Cast <IGlyphData>()?.ToList(); if (hexresults == null || hexresults.Count == 0) { var label = hex.ToString("x4"); 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; } } // 2. If we're performing SQL, create the base query filter StringBuilder sb = new StringBuilder(); bool next = false; /// Note: SQLite only supports expression trees up to 1000 items, so we need to limit the range /// of Unicode ranges we search through. Very rare for any font to hit this - especially one with /// any useful search results. MS Office Symbol is an example of such a font (with no useful search /// results anyway). Certain complex Asian script fonts **may** theoretically hit this limit. /// We don't want to throw an exception if we ever hit this case, we'll just do our best. foreach (var range in variant.UnicodeRanges.Take(995)) { if (next) { sb.AppendFormat(" OR Ix BETWEEN {0} AND {1}", range.First, range.Last); } else { next = true; sb.AppendFormat("WHERE (Ix BETWEEN {0} AND {1}", range.First, range.Last); } } 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; } List <IGlyphData> results = null; // 3. Otherwise, perform a multi-step text search. First perform an FTS4 search string sql = $"SELECT * FROM {ftsTable} {sb.ToString()} AND Description MATCH ? LIMIT {SEARCH_LIMIT}"; 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 Ix 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 ? 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); } })); }
public virtual T WithFontVariant(FontVariant fontVariant) { return(SetAttr(new { fontVariant = fontVariant.ToString().ToLower() })); }
private bool IsFontAwesome(FontVariant variant) { return(variant.FamilyName.StartsWith("Font Awesome")); }
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); } })); }
private Task <IReadOnlyList <IGlyphData> > SearchFontAwesomeAsync(string query, FontVariant variant) { return(InternalSearchAsync(FONTAWESOME_SEARCH_TABLE, nameof(FontAwesomeGlyph), query, variant)); }
private Task <IReadOnlyList <IGlyphData> > SearchMDL2Async(string query, FontVariant variant) { return(InternalSearchAsync(MDL2_SEARCH_TABLE, nameof(MDL2Glyph), query, variant)); }
private Task <IReadOnlyList <IGlyphData> > SearchUnicodeAsync(string query, FontVariant variant) { return(InternalSearchAsync(UNICODE_SEARCH_TABLE, nameof(UnicodeGlyphData), query, variant)); }
/// <summary> /// Changes the font variant /// </summary> /// <param name="value">The new font variant</param> /// <returns>A reference to the same RichString instance</returns> public RichString FontVariant(FontVariant value) => Append(new FontVariantItem(value));
public static bool ContainsRange(FontVariant v, UnicodeRange range) { return(v.UnicodeRanges.Any(r => r.First <= range.End && range.Start <= r.Last)); }
public static bool SupportsScript(FontVariant v, UnicodeRange range) { // Filters out fonts that support just a singular symbol (like currency symbol) return(v.UnicodeRanges.Any(r => r.First <= range.End && range.Start <= r.Last && ((r.Last - r.First) > 0))); }
public static bool ContainsEmoji(FontVariant v) { return(ContainsRange(v, UnicodeRange.Emoticons) || ContainsRange(v, UnicodeRange.Dingbats) || ContainsEmojiSymbols(v)); }