Пример #1
0
        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);
        }
Пример #2
0
        public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily,
                                      CultureInfo culture, out FontKey fontKey)
        {
            fontKey = default;

            return(false);
        }
Пример #3
0
        /// <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;
            }
        }
Пример #4
0
        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;
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
            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));
        }
Пример #12
0
        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));
        }
Пример #14
0
        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));
            }
Пример #16
0
        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);
        }
Пример #17
0
        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;
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
        }
Пример #20
0
        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);
        }
Пример #21
0
        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);
        }
Пример #22
0
 public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle, FontFamily fontFamily, CultureInfo culture, out FontKey fontKey)
 {
     fontKey = new FontKey("Arial", fontWeight, fontStyle);
     return(true);
 }
Пример #23
0
        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);
        }
Пример #24
0
 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);
        }
Пример #28
0
 public FontFaceKey(FontKey fontKey)
 {
     this.FontNameIndex = fontKey.FontNameIndex;
     this.FontStyle     = fontKey.FontStyle;
 }
Пример #29
0
 public GdiFont(Font font)
 {
     _font       = font;
     _nativeFont = font.ToHfont();
     _key        = new FontKey(font);
 }
Пример #30
0
        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);
        }