public Font GetOrCreateFont(string fontName, float fontSize, FontWeight fontWeight) { var key = new FontKey(fontName, fontSize, fontWeight); if (!_cachedFonts.TryGetValue(key, out var font)) { var alternatives = _fontFallbackSettings.GetFallbackList(fontName); var fontNameFound = alternatives .Prepend(fontName) .FirstOrDefault(name => SystemFonts.TryFind(name, out _)); if (fontNameFound != fontName) { Logger.Info($"Requesting font {fontName}, actually found {fontNameFound}"); } var fontStyle = fontWeight == FontWeight.Bold ? FontStyle.Bold : FontStyle.Regular; if (fontNameFound != null) { font = SystemFonts.CreateFont(fontNameFound, fontSize, fontStyle); } else { Logger.Info($"Will use embedded font as fallback for font {fontName}"); font = _fallbackFonts.CreateFont(FallbackEmbeddedFont, fontSize, fontStyle); } _cachedFonts.Add(key, font); } return(font); }
public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey) { fontKey = default; return(false); }
/// <summary> /// Returns a new typeface, or an existing one if a matching typeface exists. /// </summary> /// <param name="fontFamily">The font family.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="fontStyle">The font style.</param> /// <returns> /// The typeface. /// </returns> public Typeface GetOrAddTypeface(FontFamily fontFamily, FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal) { while (true) { if (fontFamily.IsDefault) { fontFamily = _defaultFontFamily; } var key = new FontKey(fontFamily.Name, fontWeight, fontStyle); if (_typefaceCache.TryGetValue(key, out var typeface)) { return(typeface); } typeface = new Typeface(fontFamily, fontStyle, fontWeight); if (_typefaceCache.TryAdd(key, typeface)) { return(typeface); } if (fontFamily == _defaultFontFamily) { return(null); } fontFamily = _defaultFontFamily; } }
unsafe static SKTypeface GetTypeface(string name, FontKey key) { if (name == null) { name = "Arial"; } Dictionary<FontKey, SKTypeface> entry; if (!Cache.TryGetValue(name, out entry)) { Cache[name] = entry = new Dictionary<FontKey, SKTypeface>(); } SKTypeface typeface = null; if (!entry.TryGetValue(key, out typeface)) { typeface = SKTypeface.FromFamilyName(name, key.Weight, SKFontStyleWidth.Normal, key.Slant); if (typeface == null) { typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal); } entry[key] = typeface; } return typeface; }
NativeFont ResolveForNativeFont(ActualFont actualFont) { NativeFont nativeFont; FontFace fontface = actualFont.FontFace; FontKey key = new FontKey(fontface.Name, actualFont.SizeInPoints, FontStyle.Regular); if (specificFontSize.TryGetValue(key, out nativeFont)) { return(nativeFont); } //----------------------------- //not native font //if we need to use hardbuzz then //create a native one for use FontFace nativeFontFace; if (!nativeFontFaces.TryGetValue(fontface.Name, out nativeFontFace)) { //create new nativeFontFace = FreeTypeFontLoader.LoadFont(fontface.FontPath, "en", HBDirection.HB_DIRECTION_LTR); nativeFontFaces.Add(fontface.Name, nativeFontFace); } //check if we have native fontface for this font? nativeFont = (NativeFont)nativeFontFace.GetFontAtPointSize(actualFont.SizeInPoints); specificFontSize.Add(key, nativeFont); return(nativeFont); }
public Font GetOrCreateFont(string fontName, float fontSize, FontWeight fontWeight) { var key = new FontKey { FontName = fontName, FontSize = fontSize, FontWeight = fontWeight }; if (!_cachedFonts.TryGetValue(key, out var font)) { if (!SystemFonts.TryFind(fontName, out var fontFamily)) { fontName = "Arial"; } var fontStyle = fontWeight == FontWeight.Bold ? FontStyle.Bold : FontStyle.Regular; _cachedFonts.Add(key, font = SystemFonts.CreateFont( fontName, fontSize, fontStyle)); } return(font); }
public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey) { var familyCount = Direct2D1FontCollectionCache.InstalledFontCollection.FontFamilyCount; for (var i = 0; i < familyCount; i++) { var font = Direct2D1FontCollectionCache.InstalledFontCollection.GetFontFamily(i) .GetMatchingFonts((SharpDX.DirectWrite.FontWeight)fontWeight, FontStretch.Normal, (SharpDX.DirectWrite.FontStyle)fontStyle).GetFont(0); if (!font.HasCharacter(codepoint)) { continue; } var fontFamilyName = font.FontFamily.FamilyNames.GetString(0); fontKey = new FontKey(fontFamilyName, fontWeight, fontStyle); return(true); } fontKey = default; return(false); }
public override bool Equals(object obj) { if (!(obj is FontKey)) { return(false); } FontKey key = (FontKey)obj; return(_hashCode == key._hashCode); }
private SpriteFont getFont(FontKey key, Dictionary<FontKey, SpriteFont> dict) { if (!dict.ContainsKey(key)) { SpriteFont fontToAdd = Game1.content.Load<SpriteFont>(FONT_LOCATION + fontName + key.size); dict.Add(new FontKey(key.size, key.style), fontToAdd); return fontToAdd; } return dict[key]; }
public override bool Equals(object obj) { if (obj.GetType() != this.GetType()) { return(false); } FontKey other = (FontKey)obj; return(this.FontFamily == other.FontFamily && this.FontSize == other.FontSize && this.FontWeight.Weight == other.FontWeight.Weight && this.FontStyle == other.FontStyle); }
private GlyphMetrics GetGlyphMetrics(FontKey fontKey, string glyphLabel) { Dictionary <string, GlyphMetrics> fontCache = null; if (!cache.TryGetValue(fontKey, out fontCache)) { fontCache = new Dictionary <string, GlyphMetrics>(); cache[fontKey] = fontCache; } GlyphMetrics value = null; if (!fontCache.TryGetValue(glyphLabel, out value)) { var typeFace = new Typeface(fontKey.FontFamily, fontKey.FontStyle, fontKey.FontWeight, fontKey.FontStretch); var formattedChar = new FormattedText ( glyphLabel, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeFace, fontKey.FontSize, Brushes.Black ); formattedChar.TextAlignment = TextAlignment.Left; var geometry = formattedChar.BuildGeometry(new System.Windows.Point(0.0f, 0.0f)); var rect = geometry.Bounds; // For glyph without geometry (space) if (rect.IsEmpty) { rect = new Rect(0.0, 0.0, formattedChar.WidthIncludingTrailingWhitespace, formattedChar.Height); } var rectX = (float)rect.X; var rectY = (float)rect.Y; var rectW = (float)rect.Width; var rectH = (float)rect.Height; var leftBearing = -(float)(rect.X); var rightBearing = 0.0f; var glyphX = px2mm(rectX, dpiX); var glyphY = px2mm(rectY, dpiY); var glyphW = px2mm(rectW, dpiX); var glyphH = px2mm(rectH, dpiY); var glyphRect = new Rectangle(glyphX, glyphY, glyphW, glyphH); var glyphLeftBearing = px2mm(leftBearing, dpiX); var glyphRightBearing = px2mm(rightBearing, dpiX); value = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing); fontCache[glyphLabel] = value; } return(new GlyphMetrics(new Rectangle(value.BoundingBox.X, value.BoundingBox.Y, value.BoundingBox.Width, value.BoundingBox.Height), value.LeftSideBearing, value.RightSideBearing)); }
private static Gdi::Font CreateFont(string name, float size, Gdi::FontStyle style) { FontKey k = new FontKey(name, size, style); if (!fonts.ContainsKey(k)) { Gdi::Font f = new Gdi::Font(name, size, style, Gdi::GraphicsUnit.Pixel); fonts[k] = f; return(f); } return(fonts[k]); }
private GlyphMetrics GetGlyphMetrics(FontKey fontKey, string glyphLabel, CanvasDevice canvasDevice) { Dictionary <string, GlyphMetrics> fontCache = null; if (!cache.TryGetValue(fontKey, out fontCache)) { fontCache = new Dictionary <string, GlyphMetrics>(); cache[fontKey] = fontCache; } GlyphMetrics value = null; if (!fontCache.TryGetValue(glyphLabel, out value)) { var textFormat = new CanvasTextFormat() { FontSize = fontKey.FontSize, FontFamily = fontKey.FontFamily, FontStyle = fontKey.FontStyle, FontWeight = fontKey.FontWeight }; using (var canvasCharLayout = new CanvasTextLayout(canvasDevice, glyphLabel, textFormat, 10000, 10000)) { canvasCharLayout.SetFontFamily(0, 1, fontKey.FontFamily); canvasCharLayout.SetFontSize(0, 1, fontKey.FontSize); canvasCharLayout.SetFontWeight(0, 1, fontKey.FontWeight); canvasCharLayout.SetFontStyle(0, 1, fontKey.FontStyle); var charRect = canvasCharLayout.DrawBounds; var charX = (float)charRect.X; var charY = (float)charRect.Y - canvasCharLayout.LineMetrics[0].Baseline; var charLeftBearing = (float)(-charRect.Left); var charAdvance = canvasCharLayout.GetCaretPosition(0, true); var charRightBearing = (float)(charAdvance.X - charRect.Right); var glyphX = px2mm(charX, dpiX); var glyphY = px2mm(charY, dpiY); var glyphW = px2mm((float)charRect.Width, dpiX); var glyphH = px2mm((float)charRect.Height, dpiY); var glyphRect = new Rectangle(glyphX, glyphY, glyphW, glyphH); var glyphLeftBearing = px2mm(charLeftBearing, dpiX); var glyphRightBearing = px2mm(charRightBearing, dpiX); value = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing); fontCache[glyphLabel] = value; } } return(new GlyphMetrics(new Rectangle(value.BoundingBox.X, value.BoundingBox.Y, value.BoundingBox.Width, value.BoundingBox.Height), value.LeftSideBearing, value.RightSideBearing)); }
public static WinGdiFont GetWinGdiFont(RequestFont f) { if (f == null) { throw new NotSupportedException(); } if (f == latestFont) { return(latestWinFont); } WinGdiFont actualFontInside = WinGdiFont.GetCacheFontAsWinGdiFont(f); if (actualFontInside != null) { return(actualFontInside); } //----- //need to create a new one //get register font or create the new one FontKey key = f.FontKey; WinGdiFont found; if (!registerFonts.TryGetValue(key, out found)) { //create the new one and register //create fontface FontFaceKey fontfaceKey = new FontFaceKey(key); WinGdiFontFace fontface; if (!winGdiFonFaces.TryGetValue(fontfaceKey, out fontface)) { //create new fontface = new WinGdiFontFace(f.Name); winGdiFonFaces.Add(fontfaceKey, fontface); } var winGdiFont = new WinGdiFont(fontface, f.SizeInPoints, FontStyle.Regular); found = winGdiFont; registerFonts.Add(key, found);//cache here } latestFont = f; RequestFontImpl reqFont = (RequestFontImpl)f; if (reqFont._platformFont == null) { reqFont._platformFont = found; } //found.AssignToRequestFont(f); return(latestWinFont = found); }
public override bool Equals(object obj) { if (obj.GetType() != this.GetType()) { return(false); } FontKey other = (FontKey)obj; return((this.FontFamily.Equals(other.FontFamily)) && (this.FontSize == other.FontSize) && (this.FontWeight == other.FontWeight) && (this.FontStretch == other.FontStretch) && (this.FontStyle == other.FontStyle)); }
public Font GetOrCreateFont(string fontName, float fontSize, FontWeight fontWeight) { var key = new FontKey { FontName = fontName, FontSize = fontSize, FontWeight = fontWeight }; if (!_cachedFonts.TryGetValue(key, out var font)) { var embeddedFallback = false; if (!SystemFonts.TryFind(fontName, out var fontFamily)) { //First try to load a fallback system font (Arial) if (SystemFonts.TryFind(_fallbackSystemFont, out fontFamily)) { fontName = _fallbackSystemFont; } //If this fails use an embedded fallback font (Roboto) else { embeddedFallback = true; } } var fontStyle = fontWeight == FontWeight.Bold ? FontStyle.Bold : FontStyle.Regular; if (!embeddedFallback) { font = SystemFonts.CreateFont(fontName, fontSize, fontStyle); } else { font = _fallbackFonts.CreateFont(_fallbackEmbeddedFont, fontSize, fontStyle); } _cachedFonts.Add(key, font); } return(font); }
public RequestFont(string facename, float fontSizeInPts, FontStyle style = FontStyle.Regular) { WriteDirection = WriteDirection.LTR; ScriptLang = ScriptLangs.Latin;//default //Lang = "en";//default Name = facename; SizeInPoints = fontSizeInPts; Style = style; fontKey = new FontKey(facename, fontSizeInPts, style); //TODO: review here *** //temp fix //we need font height*** //this.Height = SizeInPixels; }
public ActualFont LoadFont(string fontName, float fontSizeInPoints) { //find install font from fontname InstalledFont found = PixelFarm.Drawing.GLES2.GLES2Platform.GetInstalledFont(fontName, InstalledFontStyle.Regular); if (found == null) { return(null); } FontFace fontFace; if (!fonts.TryGetValue(found, out fontFace)) { throw new NotSupportedException("revisit freetype impl"); //convert to freetype data //TODO: review here //fontFace = FreeTypeFontLoader.LoadFont(found, // GLES2PlatformFontMx.defaultScriptLang // GLES2PlatformFontMx.defaultHbDirection, // GLES2PlatformFontMx.defaultScriptCode); //fontFace = FreeTypeFontLoader.LoadFont(found, // "en", // HBDirection.HB_DIRECTION_RTL); if (fontFace == null) { throw new NotSupportedException(); } fonts.Add(found, fontFace);//register } //----------- //create font at specific size from this fontface FontKey fontKey = new FontKey(fontName, fontSizeInPoints, FontStyle.Regular); ActualFont createdFont; if (!registerFonts.TryGetValue(fontKey, out createdFont)) { createdFont = fontFace.GetFontAtPointSize(fontSizeInPoints); } //----------- return(createdFont); }
public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey) { foreach (var customTypeface in _customTypefaces) { if (customTypeface.GlyphTypeface.GetGlyph((uint)codepoint) == 0) { continue; } fontKey = new FontKey(customTypeface.FontFamily, fontWeight, fontStyle); return(true); } var fallback = SKFontManager.Default.MatchCharacter(codepoint); fontKey = new FontKey(fallback?.FamilyName ?? SKTypeface.Default.FamilyName, fontWeight, fontStyle); return(true); }
public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey) { foreach (var customTypeface in _customTypefaces) { if (customTypeface.GlyphTypeface.GetGlyph((uint)codepoint) == 0) { continue; } fontKey = new FontKey(customTypeface.FontFamily.Name, fontStyle, fontWeight); return(true); } var fallback = SKFontManager.Default.MatchCharacter(fontFamily?.Name, (SKFontStyleWeight)fontWeight, SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, _bcp47, codepoint); fontKey = new FontKey(fallback?.FamilyName ?? _defaultFamilyName, fontStyle, fontWeight); return(true); }
internal static UIFont BestFont(string family, nfloat size, bool bold = false, bool italic = false, Assembly assembly = null) { if (family == null) { family = "sans-serif"; } if (family.ToLower() == "monospace") { family = "Menlo"; } if (family.ToLower() == "serif") { family = "Times New Roman"; } if (family.ToLower() == "sans-serif") { family = "Arial"; } if (size < 0) { size = (nfloat)(UIFont.LabelFontSize * Math.Abs(size)); } // is it in the cache? var key = new FontKey(family, size, bold, italic); Dictionary <FontKey, UIFont> dictionary = UiFontCache; lock (dictionary) { if (dictionary.TryGetValue(key, out UIFont storedUiFont)) { return(storedUiFont); } } UIFont bestAttemptFont = null; if (UIFont.FamilyNames.Contains(family)) { // a system font var fontNames = FontFamilies.FontsForFamily(family); string baseFontName = null; string reqFontName = null; //string fallbackFontName = null; if (fontNames != null && fontNames.Count > 0) { if (fontNames.Count == 1) { baseFontName = fontNames[0]; if (!bold && !italic) { reqFontName = fontNames[0]; } } else { int shortestMatchLength = int.MaxValue; int shortestBaseLength = int.MaxValue; foreach (var fontName in fontNames) { var lowerName = fontName.ToLower(); bool nameHasBold = lowerName.Contains("bold") || lowerName == "avenir-black"; bool nameHasItalic = lowerName.Contains("italic") || lowerName.Contains("oblique"); // assume the shortest name is the base font name if (lowerName.Length < shortestBaseLength) { baseFontName = fontName; shortestBaseLength = lowerName.Length; } // assume the shortest name with matching attributes is a match if (nameHasBold == bold && nameHasItalic == italic && lowerName.Length < shortestMatchLength) { reqFontName = fontName; shortestMatchLength = lowerName.Length; } if (lowerName.Contains("-regular")) { baseFontName = fontName; shortestBaseLength = -1; if (!bold && !italic) { reqFontName = fontName; shortestMatchLength = -1; break; } } } } } if (reqFontName != null) { bestAttemptFont = UIFont.FromName(reqFontName, size); } if (bestAttemptFont == null && baseFontName != null && !bold && !italic) { bestAttemptFont = UIFont.FromName(baseFontName, size); } } else { // an embedded font or a explicitly named system font? bestAttemptFont = EmbeddedFont(family, size, assembly); if (bestAttemptFont == null) { bestAttemptFont = UIFont.FromName(family, size); } } if (bestAttemptFont != null) { // we have a match but is wasn't cached - so let's cache it for future reference lock (dictionary) { if (!dictionary.TryGetValue(key, out UIFont storedUiFont)) { // It could have been added by another thread so only add if we're really sure it's no there! dictionary.Add(key, bestAttemptFont); } } return(bestAttemptFont); } // fall back to a system font if (bold && italic) { UIFont systemFont = UIFont.SystemFontOfSize(size); var descriptor = systemFont.FontDescriptor.CreateWithTraits(UIFontDescriptorSymbolicTraits.Bold | UIFontDescriptorSymbolicTraits.Italic); bestAttemptFont = UIFont.FromDescriptor(descriptor, size); } if (bestAttemptFont == null && italic) { bestAttemptFont = UIFont.ItalicSystemFontOfSize(size); } if (bestAttemptFont == null && bold) { bestAttemptFont = UIFont.BoldSystemFontOfSize(size); } if (bestAttemptFont == null) { bestAttemptFont = UIFont.SystemFontOfSize(size); } return(bestAttemptFont); }
public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey) { fontKey = new FontKey("Arial", fontWeight, fontStyle); return(true); }
internal static UIFont BestFont(string family, nfloat size, bool bold = false, bool italic = false, Assembly assembly = null) { if (family == null) { family = ".AppleSystemUIFont"; } if (family.ToLower() == "monospace") { family = "Menlo"; } if (family.ToLower() == "serif") { family = "Times New Roman"; } if (family.ToLower() == "sans-serif") { family = ".AppleSystemUIFont"; } if (size < 0) { size = (nfloat)(UIFont.LabelFontSize * Math.Abs(size)); } // is it in the cache? var key = new FontKey(family, size, bold, italic); Dictionary <FontKey, UIFont> dictionary = UiFontCache; lock (dictionary) { if (dictionary.TryGetValue(key, out UIFont storedUiFont)) { return(storedUiFont); } } UIFont bestAttemptFont = null; if (UIFont.FamilyNames.Contains(family)) { // a system font var fontNames = FontFamilies.FontsForFamily(family); string baseFontName = null; string reqFontName = null; //string fallbackFontName = null; if (fontNames != null && fontNames.Count > 0) { if (fontNames.Count == 1) { baseFontName = fontNames[0]; if (!bold && !italic) { reqFontName = fontNames[0]; } } else { int shortestMatchLength = int.MaxValue; int shortestBaseLength = int.MaxValue; foreach (var fontName in fontNames) { var lowerName = fontName.ToLower(); bool nameHasBold = lowerName.Contains("bold") || lowerName == "avenir-black"; bool nameHasItalic = lowerName.Contains("italic") || lowerName.Contains("oblique"); // assume the shortest name is the base font name if (lowerName.Length < shortestBaseLength) { baseFontName = fontName; shortestBaseLength = lowerName.Length; } // assume the shortest name with matching attributes is a match if (nameHasBold == bold && nameHasItalic == italic && lowerName.Length < shortestMatchLength) { reqFontName = fontName; shortestMatchLength = lowerName.Length; } if (lowerName.Contains("-regular")) { baseFontName = fontName; shortestBaseLength = -1; if (!bold && !italic) { reqFontName = fontName; shortestMatchLength = -1; break; } } } } } if (reqFontName != null) { bestAttemptFont = UIFont.FromName(reqFontName, size); } if (bestAttemptFont == null && baseFontName != null && !bold && !italic) { bestAttemptFont = UIFont.FromName(baseFontName, size); } } else { // an embedded font or a explicitly named system font? bestAttemptFont = EmbeddedFont(family, size, assembly); if (bestAttemptFont == null && !family.StartsWith(".SFUI")) { bestAttemptFont = UIFont.FromName(family, size); } } if (bestAttemptFont != null) { if (bold || italic) { if (bestAttemptFont.FontDescriptor.CreateWithTraits( (bold ? UIFontDescriptorSymbolicTraits.Bold : UIFontDescriptorSymbolicTraits.ClassUnknown) | (italic ? UIFontDescriptorSymbolicTraits.Italic : UIFontDescriptorSymbolicTraits.ClassUnknown) ) is UIFontDescriptor descriptor) { bestAttemptFont = UIFont.FromDescriptor(descriptor, size); } } // we have a match but is wasn't cached - so let's cache it for future reference lock (dictionary) { if (!dictionary.TryGetValue(key, out UIFont storedUiFont)) { // It could have been added by another thread so only add if we're really sure it's no there! dictionary.Add(key, bestAttemptFont); } } return(bestAttemptFont); } UIFontWeight fontWeight = UIFontWeight.Regular; if (family.StartsWith(".SFUI")) { var parts = family.Split("-"); if (parts.Length > 1) { var weightText = parts[1]; switch (weightText) { case nameof(UIFontWeight.Black): fontWeight = UIFontWeight.Black; break; case nameof(UIFontWeight.Bold): fontWeight = UIFontWeight.Bold; break; case nameof(UIFontWeight.Heavy): fontWeight = UIFontWeight.Heavy; break; case nameof(UIFontWeight.Light): fontWeight = UIFontWeight.Light; break; case nameof(UIFontWeight.Medium): fontWeight = UIFontWeight.Medium; break; case nameof(UIFontWeight.Regular): fontWeight = UIFontWeight.Medium; break; case nameof(UIFontWeight.Semibold): fontWeight = UIFontWeight.Semibold; break; case nameof(UIFontWeight.Thin): fontWeight = UIFontWeight.Thin; break; case nameof(UIFontWeight.UltraLight): fontWeight = UIFontWeight.UltraLight; break; default: fontWeight = UIFontWeight.Regular; break; } } // fall back to a system font } // fall back to a system font if (bold && italic || (fontWeight != UIFontWeight.Regular && (bold || italic))) { UIFont systemFont = UIFont.SystemFontOfSize(size, fontWeight); UIFontDescriptorSymbolicTraits traits = (bold ? UIFontDescriptorSymbolicTraits.Bold : (UIFontDescriptorSymbolicTraits)0) | (italic ? UIFontDescriptorSymbolicTraits.Italic : (UIFontDescriptorSymbolicTraits)0); var descriptor = systemFont.FontDescriptor.CreateWithTraits(traits); bestAttemptFont = UIFont.FromDescriptor(descriptor, size); } if (bestAttemptFont == null && italic) { bestAttemptFont = UIFont.ItalicSystemFontOfSize(size); } if (bestAttemptFont == null && bold) { bestAttemptFont = UIFont.BoldSystemFontOfSize(size); } if (bestAttemptFont == null) { bestAttemptFont = UIFont.SystemFontOfSize(size, fontWeight); } return(bestAttemptFont); }
public bool Equals(FontKey other) { return Slant == other.Slant && Weight == other.Weight; }
public GlyphMetrics[] GetGlyphMetrics(MyScript.IInk.Text.Text text, TextSpan[] spans) { CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice(); GlyphMetrics[] glyphMetrics = new GlyphMetrics[text.GlyphCount]; var firstStyle = spans[0].Style; var firstFontKey = FontKeyFromStyle(firstStyle); if (text.GlyphCount == 1) { glyphMetrics[0] = GetGlyphMetrics(firstFontKey, text.Label, canvasDevice); } else { var textFormat = new CanvasTextFormat() { FontSize = firstFontKey.FontSize, FontFamily = firstFontKey.FontFamily, FontStyle = firstFontKey.FontStyle, FontWeight = firstFontKey.FontWeight, WordWrapping = CanvasWordWrapping.NoWrap, Options = UseColorFont ? CanvasDrawTextOptions.EnableColorFont : CanvasDrawTextOptions.Default }; using (var canvasTextLayout = new CanvasTextLayout(canvasDevice, text.Label, textFormat, 0.0f, 0.0f)) { for (int i = 0; i < spans.Length; ++i) { var charIndex = text.GetGlyphBeginAt(spans[i].BeginPosition); var charCount = text.GetGlyphEndAt(spans[i].EndPosition - 1) - charIndex; var style = spans[i].Style; var fontKey = FontKeyFromStyle(style); canvasTextLayout.SetFontFamily(charIndex, charCount, fontKey.FontFamily); canvasTextLayout.SetFontSize(charIndex, charCount, fontKey.FontSize); canvasTextLayout.SetFontWeight(charIndex, charCount, fontKey.FontWeight); canvasTextLayout.SetFontStyle(charIndex, charCount, fontKey.FontStyle); } for (int i = 0; i < text.GlyphCount; ++i) { var glyphLabel = text.GetGlyphLabelAt(i); var glyphCharStart = text.GetGlyphBeginAt(i); var glyphCharEnd = text.GetGlyphEndAt(i); var glyphFontKey = new FontKey(canvasTextLayout.GetFontFamily(glyphCharStart) , canvasTextLayout.GetFontSize(glyphCharStart) , canvasTextLayout.GetFontWeight(glyphCharStart) , canvasTextLayout.GetFontStyle(glyphCharStart)); var glyphMetrics_ = GetGlyphMetrics(glyphFontKey, glyphLabel, canvasDevice); // Find cluster associated to element // (Use of ClusterMetrics to identify ligatures in the CanvasTextLayout) int cluster = -1; int clusterCharStart = 0; if (canvasTextLayout.ClusterMetrics != null) { for (int c = 0; c < canvasTextLayout.ClusterMetrics.Length; ++c) { var clusterCharCount = canvasTextLayout.ClusterMetrics[c].CharacterCount; if ((glyphCharStart >= clusterCharStart) && (glyphCharStart < (clusterCharStart + clusterCharCount))) { cluster = c; break; } clusterCharStart += clusterCharCount; } } if ((i > 0) && (cluster >= 0) && (glyphCharStart > clusterCharStart)) { // Ligature with the previous glyph // The position is not accurate because of glyphs substitution at rendering // but it makes the illusion. var prevGlyphMetrics = glyphMetrics[i - 1]; glyphMetrics_.BoundingBox.X = prevGlyphMetrics.BoundingBox.X + prevGlyphMetrics.BoundingBox.Width + prevGlyphMetrics.RightSideBearing + glyphMetrics_.LeftSideBearing; } else { float glyphX = 0.0f; var charRegions = canvasTextLayout.GetCharacterRegions(glyphCharStart, glyphCharEnd - glyphCharStart); if ((charRegions != null) && (charRegions.Length > 0)) { glyphX = (float)charRegions[0].LayoutBounds.X; } else { var glyphPos = canvasTextLayout.GetCaretPosition(glyphCharStart, false); glyphX = (float)glyphPos.X; } glyphMetrics_.BoundingBox.X += px2mm(glyphX, dpiX); } glyphMetrics[i] = glyphMetrics_; } } } return(glyphMetrics); }
private GlyphMetrics GetGlyphMetrics(FontKey fontKey, string glyphLabel, CanvasDevice canvasDevice) { Dictionary <string, GlyphMetrics> fontCache = null; if (!cache.TryGetValue(fontKey, out fontCache)) { fontCache = new Dictionary <string, GlyphMetrics>(); cache[fontKey] = fontCache; } GlyphMetrics value = null; if (!fontCache.TryGetValue(glyphLabel, out value)) { var textFormat = new CanvasTextFormat() { FontSize = fontKey.FontSize, FontFamily = fontKey.FontFamily, FontStyle = fontKey.FontStyle, FontWeight = fontKey.FontWeight, WordWrapping = CanvasWordWrapping.NoWrap, Options = UseColorFont ? CanvasDrawTextOptions.EnableColorFont : CanvasDrawTextOptions.Default }; using (var canvasCharLayout = new CanvasTextLayout(canvasDevice, glyphLabel, textFormat, 0.0f, 0.0f)) { int charCount = 0; if (canvasCharLayout.ClusterMetrics != null) { foreach (var c in canvasCharLayout.ClusterMetrics) { charCount += c.CharacterCount; } } var rect = canvasCharLayout.DrawBounds; var left = (float)rect.Left; var top = (float)rect.Top - canvasCharLayout.LineMetrics[0].Baseline; var leftBearing = (float)(-rect.Left); var height = (float)rect.Height; var charEnd = (charCount > 0) ? (charCount - 1) : 0; var advance = canvasCharLayout.GetCaretPosition(charEnd, true); var width = (float)rect.Width; var right = (float)rect.Right; var rightBearing = (float)advance.X - right; var glyphX = px2mm(left, dpiX); var glyphY = px2mm(top, dpiY); var glyphW = px2mm(width, dpiX); var glyphH = px2mm(height, dpiY); var glyphRect = new Rectangle(glyphX, glyphY, glyphW, glyphH); var glyphLeftBearing = px2mm(leftBearing, dpiX); var glyphRightBearing = px2mm(rightBearing, dpiX); value = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing); fontCache[glyphLabel] = value; } } return(new GlyphMetrics(new Rectangle(value.BoundingBox.X, value.BoundingBox.Y, value.BoundingBox.Width, value.BoundingBox.Height), value.LeftSideBearing, value.RightSideBearing)); }
public GlyphMetrics[] GetGlyphMetrics(MyScript.IInk.Text.Text text, TextSpan[] spans) { CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice(); GlyphMetrics[] glyphMetrics = new GlyphMetrics[text.GlyphCount]; var firstStyle = spans[0].Style; var firstFontKey = FontKeyFromStyle(firstStyle); if (text.GlyphCount == 1) { glyphMetrics[0] = GetGlyphMetrics(firstFontKey, text.Label, canvasDevice); } else { var textFormat = new CanvasTextFormat() { FontSize = mm2px(firstStyle.FontSize, dpiY), FontFamily = firstStyle.FontFamily, FontStyle = firstFontKey.FontStyle, FontWeight = firstFontKey.FontWeight }; using (var canvasTextLayout = new CanvasTextLayout(canvasDevice, text.Label, textFormat, 10000, 10000)) { for (int i = 0; i < spans.Length; ++i) { var charIndex = spans[i].BeginPosition; var charCount = spans[i].EndPosition - spans[i].BeginPosition; var style = spans[i].Style; var fontKey = FontKeyFromStyle(style); canvasTextLayout.SetFontFamily(charIndex, charCount, fontKey.FontFamily); canvasTextLayout.SetFontSize(charIndex, charCount, fontKey.FontSize); canvasTextLayout.SetFontWeight(charIndex, charCount, fontKey.FontWeight); canvasTextLayout.SetFontStyle(charIndex, charCount, fontKey.FontStyle); } // Use of TextElementEnumerator to get character indices as in the CanvasTextLayout var tee = StringInfo.GetTextElementEnumerator(text.Label); // Use of ClusterMetrics to identify ligatures in the CanvasTextLayout int cluster = 0; int clusterStartChar = 0; var clusterCharCount = canvasTextLayout.ClusterMetrics[cluster].CharacterCount; for (int i = 0, g = 0; i < text.GlyphCount; ++i) { var fontKey = new FontKey(canvasTextLayout.GetFontFamily(i) , canvasTextLayout.GetFontSize(i) , canvasTextLayout.GetFontWeight(i) , canvasTextLayout.GetFontStyle(i)); var glyphLabel = text.GetGlyphLabelAt(i); var glyphMetrics_ = GetGlyphMetrics(fontKey, glyphLabel, canvasDevice); // Find cluster associated to element if (tee.MoveNext()) { g = tee.ElementIndex; } while ((g < clusterStartChar) || (g >= (clusterStartChar + clusterCharCount))) { ++cluster; clusterStartChar += clusterCharCount; clusterCharCount = canvasTextLayout.ClusterMetrics[cluster].CharacterCount; } if (g > clusterStartChar) { // Ligature with the previous glyph // The position is not accurate because of glyphs substitution at rendering // but it makes the illusion. var prevGlyphMetrics = glyphMetrics[i - 1]; glyphMetrics_.BoundingBox.X = prevGlyphMetrics.BoundingBox.X + prevGlyphMetrics.BoundingBox.Width + prevGlyphMetrics.RightSideBearing + glyphMetrics_.LeftSideBearing; } else { var charPos = canvasTextLayout.GetCaretPosition(g, false); glyphMetrics_.BoundingBox.X += px2mm(charPos.X, dpiX); } glyphMetrics[i] = glyphMetrics_; } } } return(glyphMetrics); }
public FontFaceKey(FontKey fontKey) { this.FontNameIndex = fontKey.FontNameIndex; this.FontStyle = fontKey.FontStyle; }
public GdiFont(Font font) { _font = font; _nativeFont = font.ToHfont(); _key = new FontKey(font); }
public int GetStyleIndex(SpreadsheetStyle style) { var styleIdentifier = style.GetIdentifier(); if (_styles.ContainsKey(styleIdentifier)) { return(_styles[styleIdentifier]); } var fontIndex = 0; if (style.Font != null) { var key = new FontKey(style.Font, style.ForegroundColor); if (_fonts.ContainsKey(key)) { fontIndex = _fonts[key]; } else { var newFont = new Font(); newFont.FontName = new FontName() { Val = style.Font.Name }; newFont.FontSize = new FontSize() { Val = style.Font.Size }; if (style.Font.Bold) { newFont.Bold = new Bold(); } if (style.Font.Italic) { newFont.Italic = new Italic(); } if (style.ForegroundColor != null) { newFont.Color = new Color() { Rgb = String.Format("{0:X2}{1:X2}{2:X2}{3:X2}", style.ForegroundColor.Value.A, style.ForegroundColor.Value.R, style.ForegroundColor.Value.G, style.ForegroundColor.Value.B) }; } _stylesheet.Fonts.AppendChild(newFont); fontIndex = _fonts[key] = (int)((UInt32)_stylesheet.Fonts.Count); _stylesheet.Fonts.Count++; } } var fillIndex = 0; if (style.BackgroundColor != null) { if (_fills.ContainsKey(style.BackgroundColor.Value)) { fillIndex = _fills[style.BackgroundColor.Value]; } else { var newFill = new PatternFill() { PatternType = PatternValues.Solid }; newFill.ForegroundColor = new ForegroundColor() { Rgb = String.Format("{0:X2}{1:X2}{2:X2}{3:X2}", style.BackgroundColor.Value.A, style.BackgroundColor.Value.R, style.BackgroundColor.Value.G, style.BackgroundColor.Value.B) }; newFill.BackgroundColor = new BackgroundColor() { Indexed = 64U }; fillIndex = (int)(UInt32)_stylesheet.Fills.Count; _fills[style.BackgroundColor.Value] = fillIndex; _stylesheet.Fills.AppendChild(new Fill() { PatternFill = newFill }); _stylesheet.Fills.Count++; } } var numberingId = 0; if (style.IsDate) { numberingId = 164; } var cellFormat = new CellFormat() { FormatId = 0, FontId = (UInt32)fontIndex, FillId = (UInt32)fillIndex, BorderId = 0, NumberFormatId = (UInt32)numberingId, ApplyFill = true }; if (style.Alignment != null || style.VerticalAlignment != null || style.Indent != 0 || style.WrapText) { var aligment = new Alignment(); if (style.Alignment != null) { aligment.Horizontal = style.Alignment.Value; } if (style.VerticalAlignment != null) { aligment.Vertical = style.VerticalAlignment.Value; } if (style.Indent != 0) { aligment.Indent = (UInt32)style.Indent; } if (style.WrapText) { aligment.WrapText = true; } cellFormat.AppendChild(aligment); } var styleIndex = _styles[styleIdentifier] = (int)(UInt32)_stylesheet.CellFormats.Count; _stylesheet.CellFormats.AppendChild(cellFormat); _stylesheet.CellFormats.Count++; return(styleIndex); }