예제 #1
0
        /// <summary>
        /// Caches a font source under its face name and its key.
        /// </summary>
        public static XFontSource CacheFontSource(XFontSource fontSource)
        {
            try
            {
                Lock.EnterFontFactory();
                // Check whether an identical font source with a different face name already exists.
                XFontSource existingFontSource;
                if (FontSourcesByKey.TryGetValue(fontSource.Key, out existingFontSource))
                {
#if DEBUG
                    // Fonts have same length and check sum. Now check byte by byte identity.
                    int length = fontSource.Bytes.Length;
                    for (int idx = 0; idx < length; idx++)
                    {
                        if (existingFontSource.Bytes[idx] != fontSource.Bytes[idx])
                        {
                            //Debug.Assert(false,"Two fonts with identical checksum found.");
                            break;
                            //goto FontsAreNotIdentical;
                        }
                    }
                    Debug.Assert(existingFontSource.Fontface != null);
#endif
                    return(existingFontSource);

                    //FontsAreNotIdentical:
                    //// Incredible rare case: Two different fonts have the same size and check sum.
                    //// Give the new one a new key until it do not clash with an existing one.
                    //while (FontSourcesByKey.ContainsKey(fontSource.Key))
                    //    fontSource.IncrementKey();
                }

                OpenTypeFontface fontface = fontSource.Fontface;
                if (fontface == null)
                {
                    // Create OpenType fontface for this font source.
                    fontSource.Fontface = new OpenTypeFontface(fontSource);
                }
                FontSourcesByKey.Add(fontSource.Key, fontSource);
                if (FontSourcesByName.ContainsKey(fontSource.FontName))
                {
                    // TODO: merge font faces?..
                }
                else
                {
                    FontSourcesByName.Add(fontSource.FontName, fontSource);
                }

                return(fontSource);
            }
            finally { Lock.ExitFontFactory(); }
        }
예제 #2
0
        //// Suffix for internal face names to indicate that the font data comes from the platform
        //// and not from the users font resolver.
        //public const string PlatformTag = "platform:";

        /// <summary>
        /// Converts specified information about a required typeface into a specific font.
        /// </summary>
        /// <param name="familyName">Name of the font family.</param>
        /// <param name="fontResolvingOptions">The font resolving options.</param>
        /// <param name="typefaceKey">Typeface key if already known by caller, null otherwise.</param>
        /// <returns>
        /// Information about the typeface, or null if no typeface can be found.
        /// </returns>
        public static FontResolverInfo ResolveTypeface(string familyName, FontResolvingOptions fontResolvingOptions, string typefaceKey)
        {
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }

            try
            {
                Lock.EnterFontFactory();
                // Was this typeface requested before?
                FontResolverInfo fontResolverInfo;
                if (FontResolverInfosByName.TryGetValue(typefaceKey, out fontResolverInfo))
                {
                    return(fontResolverInfo);
                }

                // Case: This typeface was not resolved before.

                // Is there a custom font resolver available?
                IFontResolver customFontResolver = GlobalFontSettings.FontResolver;
                if (customFontResolver != null)
                {
                    // Case: Use custom font resolver.
                    fontResolverInfo = customFontResolver.ResolveTypeface(familyName, fontResolvingOptions.IsBold, fontResolvingOptions.IsItalic);

                    // If resolved by custom font resolver register info and font source.
                    if (fontResolverInfo != null && !(fontResolverInfo is PlatformFontResolverInfo))
                    {
                        string           resolverInfoKey = fontResolverInfo.Key;
                        FontResolverInfo existingFontResolverInfo;
                        if (FontResolverInfosByName.TryGetValue(resolverInfoKey, out existingFontResolverInfo))
                        {
                            // Case: A new typeface was resolved with the same info as a previous one.
                            // Discard new object an reuse previous one.
                            fontResolverInfo = existingFontResolverInfo;
                            // Associate with typeface key.
                            FontResolverInfosByName.Add(typefaceKey, fontResolverInfo);
#if DEBUG
                            // The font source should exist.
                            Debug.Assert(FontSourcesByName.ContainsKey(fontResolverInfo.FaceName));
#endif
                        }
                        else
                        {
                            // Case: No such font resolver info exists.
                            // Add to both dictionaries.
                            FontResolverInfosByName.Add(typefaceKey, fontResolverInfo);
                            Debug.Assert(resolverInfoKey == fontResolverInfo.Key);
                            FontResolverInfosByName.Add(resolverInfoKey, fontResolverInfo);

                            // Create font source if not yet exists.
                            XFontSource previousFontSource;
                            if (FontSourcesByName.TryGetValue(fontResolverInfo.FaceName, out previousFontSource))
                            {
                                // Case: The font source exists, because a previous font resolver info comes
                                // with the same face name, but was different in style simulation flags.
                                // Nothing to do.
                            }
                            else
                            {
                                // Case: Get font from custom font resolver and create font source.
                                byte[]      bytes      = customFontResolver.GetFont(fontResolverInfo.FaceName);
                                XFontSource fontSource = XFontSource.GetOrCreateFrom(bytes);

                                // Add font source's font resolver name if it is different to the face name.
                                if (string.Compare(fontResolverInfo.FaceName, fontSource.FontName, StringComparison.OrdinalIgnoreCase) != 0)
                                {
                                    FontSourcesByName.Add(fontResolverInfo.FaceName, fontSource);
                                }
                            }
                        }
                    }
                }
                else
                {
                    // Case: There was no custom font resolver set.
                    // Use platform font resolver.
                    // If it was successful resolver info and font source are cached
                    // automatically by PlatformFontResolver.ResolveTypeface.
                    fontResolverInfo = PlatformFontResolver.ResolveTypeface(familyName, fontResolvingOptions, typefaceKey);
                }

                // Return value is null if the typeface could not be resolved.
                // In this case PDFsharp stops.
                return(fontResolverInfo);
            }
            finally { Lock.ExitFontFactory(); }
        }