Exemplo n.º 1
0
        protected WpfFontFamilyInfo GetTextFontFamilyInfo(SvgTextContentElement element)
        {
            _actualFontName = null;

            string fontFamily = element.GetPropertyValue("font-family");

            string[] fontNames = fontFamily.Split(new char[1] {
                ','
            });

            FontStyle   fontStyle   = GetTextFontStyle(element);
            FontWeight  fontWeight  = GetTextFontWeight(element);
            FontStretch fontStretch = GetTextFontStretch(element);

            var comparer   = StringComparison.OrdinalIgnoreCase;
            var docElement = element.OwnerDocument;

            ISet <string> svgFontFamilies = docElement.SvgFontFamilies;
            IDictionary <string, string> styledFontIds = docElement.StyledFontIds;

            IList <string> svgFontNames = null;

            if (svgFontFamilies != null && svgFontFamilies.Count != 0)
            {
                svgFontNames = new List <string>();
            }
            //var systemFontFamilies = Fonts.SystemFontFamilies;

            var wpfSettings         = _context.Settings;
            var fontFamilyNames     = wpfSettings.FontFamilyNames;
            var privateFontFamilies = wpfSettings.HasFontFamilies;

            FontFamily family = null;
            // using separate pointer to give less priority to generic font names
            FontFamily genericFamily = null;

            WpfFontFamilyType familyType = WpfFontFamilyType.None;

            foreach (string fn in fontNames)
            {
                try
                {
                    string fontName = fn.Trim(new char[] { ' ', '\'', '"' });
                    if (svgFontFamilies != null && svgFontFamilies.Count != 0)
                    {
                        if (svgFontFamilies.Contains(fontName))
                        {
                            svgFontNames.Add(fontName);
                            continue;
                        }
                        if (styledFontIds.ContainsKey(fontName))
                        {
                            string mappedFontName = styledFontIds[fontName];
                            if (svgFontFamilies.Contains(mappedFontName))
                            {
                                svgFontNames.Add(mappedFontName);
                                continue;
                            }
                        }
                    }

                    if (string.Equals(fontName, "serif", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericSerif;
                    }
                    else if (string.Equals(fontName, "sans-serif", comparer) ||
                             string.Equals(fontName, "sans serif", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericSansSerif;
                    }
                    else if (string.Equals(fontName, "monospace", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericMonospace;
                    }
                    else if (styledFontIds.ContainsKey(fontName))
                    {
                        string mappedFontName = styledFontIds[fontName];
                        family = LookupFontFamily(mappedFontName, fontFamilyNames);
                        if (family != null)
                        {
                            _actualFontName = mappedFontName;
                            familyType      = WpfFontFamilyType.System;
                        }
                    }
                    else
                    {
                        // Try looking up fonts in the system font registry...
                        family = LookupFontFamily(fontName, fontFamilyNames);
                        if (family != null)
                        {
                            _actualFontName = fontName;
                            familyType      = WpfFontFamilyType.System;
                        }

                        // If not found, look through private fonts if available..
                        if (family == null && privateFontFamilies)
                        {
                            family = wpfSettings.LookupFontFamily(fontName);
                            if (family != null)
                            {
                                _actualFontName = fontName;
                                familyType      = WpfFontFamilyType.Private;
                            }
                        }
                    }

                    if (family != null)
                    {
                        return(new WpfFontFamilyInfo(familyType, _actualFontName, family,
                                                     fontWeight, fontStyle, fontStretch));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }

            // If set, use the SVG-Font...
            if (svgFontNames != null && svgFontNames.Count != 0)
            {
                FontFamily altFamily = (genericFamily != null) ? genericFamily : WpfDrawingSettings.DefaultFontFamily;

                IList <SvgFontElement> svgFonts = docElement.GetFonts(svgFontNames);
                if (svgFonts != null && svgFonts.Count != 0)
                {
                    string fontVariant = element.GetPropertyValue("font-variant");

                    // For a single match...
                    if (svgFonts.Count == 1)
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }

                    // For the defined font style...
                    if (fontStyle != FontStyles.Normal)
                    {
                        // Then it is either oblique or italic
                        SvgFontElement closeFont   = null;
                        SvgFontElement closestFont = null;
                        bool           isItalic    = fontStyle.Equals(FontStyles.Italic);
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            var typefaceStyle = GetTextFontStyle(fontFace.FontStyle);
                            if (fontStyle.Equals(typefaceStyle))
                            {
                                closeFont = svgFont;
                                if (closestFont == null)
                                {
                                    closestFont = svgFont;
                                }
                                var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                                if (fontVariant.Equals(fontFace.FontVariant, comparer))
                                {
                                    closestFont = svgFont;
                                    if (fontWeight.Equals(typefaceWeight))
                                    {
                                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                                   fontWeight, fontStyle, fontStretch);

                                        fontFamilyInfo.Variant = fontVariant;
                                        // For rendering that do not support the SVG Fonts...
                                        fontFamilyInfo.Family = altFamily;
                                        return(fontFamilyInfo);
                                    }
                                }
                            }
                            if (closeFont == null)
                            {
                                if (isItalic && typefaceStyle == FontStyles.Oblique)
                                {
                                    closeFont = svgFont;
                                }
                                if (!isItalic && typefaceStyle == FontStyles.Italic)
                                {
                                    closeFont = svgFont;
                                }
                            }
                        }
                        if (closestFont != null)
                        {
                            closeFont = closestFont;
                        }

                        if (closeFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(closeFont.FontFamily, closeFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                    }

                    SvgFontElement variantFont = null;
                    // For multiple matches, we will test the variants...
                    if (!string.IsNullOrWhiteSpace(fontVariant))
                    {
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            if (fontVariant.Equals(fontFace.FontVariant, comparer))
                            {
                                variantFont = svgFont;
                                // Check for more perfect match...
                                var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                                var typefaceStyle  = GetTextFontStyle(fontFace.FontStyle);
                                if (fontStyle.Equals(typefaceStyle) && fontWeight.Equals(typefaceWeight))
                                {
                                    var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                               fontWeight, fontStyle, fontStretch);

                                    fontFamilyInfo.Variant = fontVariant;
                                    // For rendering that do not support the SVG Fonts...
                                    fontFamilyInfo.Family = altFamily;
                                    return(fontFamilyInfo);
                                }
                            }
                        }

                        //if (variantFont != null)
                        //{
                        //    // If there was a matching variant but either style or weight not matched...
                        //    var fontFamilyInfo = new WpfFontFamilyInfo(variantFont.FontFamily, variantFont,
                        //        fontWeight, fontStyle, fontStretch);

                        //    fontFamilyInfo.Variant = fontVariant;
                        //    // For rendering that do not support the SVG Fonts...
                        //    fontFamilyInfo.Family = altFamily;
                        //    return fontFamilyInfo;
                        //}
                    }

                    // For the defined font weights...
                    if (fontWeight != FontWeights.Normal && fontWeight != FontWeights.Regular)
                    {
                        int            weightValue    = fontWeight.ToOpenTypeWeight();
                        int            selectedValue  = int.MaxValue;
                        SvgFontElement sameWeightFont = null;
                        SvgFontElement closestFont    = null;
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                            if (fontWeight.Equals(typefaceWeight))
                            {
                                sameWeightFont = svgFont;
                                var typefaceStyle = GetTextFontStyle(fontFace.FontStyle);
                                if (fontStyle.Equals(typefaceStyle))
                                {
                                    var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                               fontWeight, fontStyle, fontStretch);

                                    fontFamilyInfo.Variant = fontVariant;
                                    // For rendering that do not support the SVG Fonts...
                                    fontFamilyInfo.Family = altFamily;
                                    return(fontFamilyInfo);
                                }
                            }

                            int weightDiff = Math.Abs(weightValue - typefaceWeight.ToOpenTypeWeight());
                            if (weightDiff < selectedValue)
                            {
                                closestFont   = svgFont;
                                selectedValue = weightDiff;
                            }
                        }

                        // If the weights matched, but not the style
                        if (sameWeightFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(sameWeightFont.FontFamily, sameWeightFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                        if (closestFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(closestFont.FontFamily, closestFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                    }

                    if (variantFont != null)
                    {
                        // If there was a matching variant but either style or weight not matched...
                        var fontFamilyInfo = new WpfFontFamilyInfo(variantFont.FontFamily, variantFont,
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }
                    else // If the variant is not found, return the first match...
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }

                    //// For multiple matches, we will test the variants...
                    //if (string.IsNullOrWhiteSpace(fontVariant))
                    //{
                    //    // Not found, return the first match...
                    //    var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                    //        fontWeight, fontStyle, fontStretch);

                    //    fontFamilyInfo.Variant = fontVariant;
                    //    // For rendering that do not support the SVG Fonts...
                    //    fontFamilyInfo.Family = altFamily;
                    //    return fontFamilyInfo;
                    //}
                }
            }

            if (genericFamily != null)
            {
                return(new WpfFontFamilyInfo(WpfFontFamilyType.Generic, _actualFontName, genericFamily,
                                             fontWeight, fontStyle, fontStretch));
            }

            // No known font-family was found => default to "Arial"
            return(new WpfFontFamilyInfo(familyType, _actualFontName,
                                         WpfDrawingSettings.DefaultFontFamily, fontWeight, fontStyle, fontStretch));
        }