/// <summary>
        /// Create a WPF GlyphTypeface and retrieve font data from it.
        /// </summary>
        internal static XFontSource CreateFontSource(string familyName, FontResolvingOptions fontResolvingOptions,
                                                     out WpfFontFamily wpfFontFamily, out WpfTypeface wpfTypeface, out WpfGlyphTypeface wpfGlyphTypeface, string typefaceKey)
        {
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }
            XFontStyle style = fontResolvingOptions.FontStyle;

#if DEBUG
            if (StringComparer.OrdinalIgnoreCase.Compare(familyName, "Segoe UI Semilight") == 0 &&
                (style & XFontStyle.BoldItalic) == XFontStyle.Italic)
            {
                familyName.GetType();
            }
#endif

            // Use WPF technique to create font data.
            wpfTypeface = XPrivateFontCollection.TryCreateTypeface(familyName, style, out wpfFontFamily);
#if DEBUG__
            if (wpfTypeface != null)
            {
                WpfGlyphTypeface          glyphTypeface;
                ICollection <WpfTypeface> list = wpfFontFamily.GetTypefaces();
                foreach (WpfTypeface tf in list)
                {
                    if (!tf.TryGetGlyphTypeface(out glyphTypeface))
                    {
                        Debug - Break.Break();
                    }
                }

                //if (!WpfTypeface.TryGetGlyphTypeface(out glyphTypeface))
                //    throw new InvalidOperationException(PSSR.CannotGetGlyphTypeface(familyName));
            }
#endif
            if (wpfFontFamily == null)
            {
                wpfFontFamily = new WpfFontFamily(familyName);
            }

            if (wpfTypeface == null)
            {
                wpfTypeface = FontHelper.CreateTypeface(wpfFontFamily, style);
            }

            // Let WPF choose the right glyph typeface.
            if (!wpfTypeface.TryGetGlyphTypeface(out wpfGlyphTypeface))
            {
                throw new InvalidOperationException(PSSR.CannotGetGlyphTypeface(familyName));
            }

            // Get or create the font source and cache it unter the specified typeface key.
            XFontSource fontSource = XFontSource.GetOrCreateFromWpf(typefaceKey, wpfGlyphTypeface);
            return(fontSource);
        }
        internal static XFontSource CreateFontSource(string familyName, FontResolvingOptions fontResolvingOptions, string typefaceKey)
        {
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }

            if (fonts == null)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load("/system/etc/fonts.xml");

                fonts = new Dictionary <AndroidFontInfo, string>();

                var familyset = xmlDoc.DocumentElement;
                foreach (XmlNode family in familyset.ChildNodes)
                {
                    if (family.Attributes != null && family.Attributes["name"] != null)
                    {
                        foreach (XmlNode font in family.ChildNodes)
                        {
                            if (font.Attributes["style"] != null && font.Attributes["weight"] != null)
                            {
                                var id = new AndroidFontInfo
                                {
                                    FamilyName = family.Attributes["name"].Value,
                                    Italic     = font.Attributes["style"].Value == "italic",
                                    Bold       = int.Parse(font.Attributes["weight"].Value) > 500,
                                };

                                fonts[id] = font.ChildNodes[0].Value;
                            }
                        }
                    }
                }
            }

            XFontSource fontSource = null;

            string path;

            var searchId = new AndroidFontInfo
            {
                FamilyName = familyName,
                Italic     = fontResolvingOptions.IsItalic,
                Bold       = fontResolvingOptions.IsBold,
            };

            if (fonts.TryGetValue(searchId, out path))
            {
                fontSource = XFontSource.GetOrCreateFrom(typefaceKey, File.ReadAllBytes(Path.Combine("/system/fonts/", path)));
            }

            return(fontSource);
        }
Esempio n. 3
0
        /// <summary>
        /// Internal implementation.
        /// </summary>
        internal static FontResolverInfo ResolveTypeface(string familyName, FontResolvingOptions fontResolvingOptions, string typefaceKey)
        {
            // Internally we often have the typeface key already.
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }

            // The user may call ResolveTypeface anytime from anywhere, so check cache in FontFactory in the first place.
            FontResolverInfo fontResolverInfo;

            if (FontFactory.TryGetFontResolverInfoByTypefaceKey(typefaceKey, out fontResolverInfo))
            {
                return(fontResolverInfo);
            }

            // Let the platform create the requested font source and save both PlattformResolverInfo
            // and XFontSource in FontFactory cache.
            // It is possible that we already have the correct font source. E.g. we already have the regular typeface in cache
            // and looking now for the italic typeface, but no such font exists. In this case we get the regular font source
            // and cache again it with the italic typeface key. Furthermore in glyph typeface style simulation for italic is set.
            XFontSource fontSource = null;

            // If no such font exists return null. PDFsharp will fail.
            if (fontSource == null)
            {
                return(null);
            }

            //#if (CORE || GDI) && !WPF
            //            // TODO: Support style simulation for GDI+ platform fonts.
            //            fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, false, false, gdiFont);
            //#endif
            if (fontResolvingOptions.OverrideStyleSimulations)
            {
            }
            else
            {
            }
            FontFactory.CacheFontResolverInfo(typefaceKey, fontResolverInfo);

            // Register font data under the platform specific face name.
            // Already done in CreateFontSource.
            // FontFactory.CacheNewFontSource(typefaceKey, fontSource);

            return(fontResolverInfo);
        }
Esempio n. 4
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(); }
        }
        /// <summary>
        /// Internal implementation.
        /// </summary>
        internal static FontResolverInfo ResolveTypeface(string familyName, FontResolvingOptions fontResolvingOptions, string typefaceKey)
        {
            // Internally we often have the typeface key already.
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }

            // The user may call ResolveTypeface anytime from anywhere, so check cache in FontFactory in the first place.
            FontResolverInfo fontResolverInfo;

            if (FontFactory.TryGetFontResolverInfoByTypefaceKey(typefaceKey, out fontResolverInfo))
            {
                return(fontResolverInfo);
            }

            // Let the platform create the requested font source and save both PlattformResolverInfo
            // and XFontSource in FontFactory cache.
            // It is possible that we already have the correct font source. E.g. we already have the regular typeface in cache
            // and looking now for the italic typeface, but no such font exists. In this case we get the regular font source
            // and cache again it with the italic typeface key. Furthermore in glyph typeface style simulation for italic is set.
#if (CORE || GDI) && !WPF
            GdiFont     gdiFont;
            XFontSource fontSource = CreateFontSource(familyName, fontResolvingOptions, out gdiFont, typefaceKey);
#endif
#if WPF && !SILVERLIGHT
            WpfFontFamily    wpfFontFamily;
            WpfTypeface      wpfTypeface;
            WpfGlyphTypeface wpfGlyphTypeface;
            XFontSource      fontSource = CreateFontSource(familyName, fontResolvingOptions, out wpfFontFamily, out wpfTypeface, out wpfGlyphTypeface, typefaceKey);
#endif
#if SILVERLIGHT
            //GlyphTypeface wpfGlyphTypeface;
            XFontSource fontSource = null;//CreateFontSource(familyName, isBold, isItalic, out wpfGlyphTypeface, typefaceKey);
#endif
#if NETFX_CORE || UWP
            //GlyphTypeface wpfGlyphTypeface;
            XFontSource fontSource = null;//CreateFontSource(familyName, isBold, isItalic, out wpfGlyphTypeface, typefaceKey);
#endif
#if __IOS__
            XFontSource fontSource = CreateFontSource(familyName, fontResolvingOptions, typefaceKey);
#endif
#if __ANDROID__
            XFontSource fontSource = CreateFontSource(familyName, fontResolvingOptions, typefaceKey);
#endif
#if PORTABLE
            XFontSource fontSource = null;
#endif
            // If no such font exists return null. PDFsharp will fail.
            if (fontSource == null)
            {
                return(null);
            }

            //#if (CORE || GDI) && !WPF
            //            // TODO: Support style simulation for GDI+ platform fonts.
            //            fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, false, false, gdiFont);
            //#endif
            if (fontResolvingOptions.OverrideStyleSimulations)
            {
#if (CORE || GDI) && !WPF
                // TODO: Support style simulation for GDI+ platform fonts.
                fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, fontResolvingOptions.MustSimulateBold, fontResolvingOptions.MustSimulateItalic, gdiFont);
#endif
#if WPF && !SILVERLIGHT
                fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, fontResolvingOptions.MustSimulateBold, fontResolvingOptions.MustSimulateItalic,
                                                                wpfFontFamily, wpfTypeface, wpfGlyphTypeface);
#endif
            }
            else
            {
#if (CORE || GDI) && !WPF
                bool mustSimulateBold   = gdiFont.Bold && !fontSource.Fontface.os2.IsBold;
                bool mustSimulateItalic = gdiFont.Italic && !fontSource.Fontface.os2.IsItalic;
                fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, mustSimulateBold, mustSimulateItalic, gdiFont);
#endif
#if WPF && !SILVERLIGHT
                // WPF knows what styles have to be simulated.
                bool mustSimulateBold   = (wpfGlyphTypeface.StyleSimulations & WpfStyleSimulations.BoldSimulation) == WpfStyleSimulations.BoldSimulation;
                bool mustSimulateItalic = (wpfGlyphTypeface.StyleSimulations & WpfStyleSimulations.ItalicSimulation) == WpfStyleSimulations.ItalicSimulation;

                // Weird behavior of WPF is fixed here in case we request a bold italic typeface.
                // If only italic is available, bold is simulated based on italic.
                // If only bold is available, italic is simulated based on bold.
                // But if both bold and italic is available, italic face is used and bold is simulated.
                // The latter case is reversed here, i.e. bold face is used and italic is simulated.
                if (fontResolvingOptions.IsBoldItalic && mustSimulateBold && !mustSimulateItalic)
                {
                    // Try to get the bold typeface.
                    string           typefaceKeyBold = XGlyphTypeface.ComputeKey(familyName, true, false);
                    FontResolverInfo infoBold        = ResolveTypeface(familyName,
                                                                       new FontResolvingOptions(FontHelper.CreateStyle(true, false)), typefaceKeyBold);
                    // Use it if it does not base on simulateion.
                    if (infoBold != null && infoBold.StyleSimulations == XStyleSimulations.None)
                    {
                        // Use existing bold typeface and simualte italic.
                        fontResolverInfo = new PlatformFontResolverInfo(typefaceKeyBold, false, true,
                                                                        wpfFontFamily, wpfTypeface, wpfGlyphTypeface);
                    }
                    else
                    {
                        // Simulate both.
                        fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, true, true,
                                                                        wpfFontFamily, wpfTypeface, wpfGlyphTypeface);
                    }
                }
                else
                {
                    fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, mustSimulateBold, mustSimulateItalic,
                                                                    wpfFontFamily, wpfTypeface, wpfGlyphTypeface);
                }
#endif
            }

#if SILVERLIGHT
            fontResolverInfo = null; //new PlattformResolverInfo(typefaceKey, false, false, wpfGlyphTypeface);
#endif

#if __IOS__
            fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, false, false);
#endif

#if __ANDROID__
            fontResolverInfo = new PlatformFontResolverInfo(typefaceKey, false, false);
#endif
            FontFactory.CacheFontResolverInfo(typefaceKey, fontResolverInfo);

            // Register font data under the platform specific face name.
            // Already done in CreateFontSource.
            // FontFactory.CacheNewFontSource(typefaceKey, fontSource);

            return(fontResolverInfo);
        }
        /// <summary>
        /// Resolves the typeface by generating a font resolver info.
        /// </summary>
        /// <param name="familyName">Name of the font family.</param>
        /// <param name="isBold">Indicates whether a bold font is requested.</param>
        /// <param name="isItalic">Indicates whether an italic font is requested.</param>
        public static FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
        {
            FontResolvingOptions fontResolvingOptions = new FontResolvingOptions(FontHelper.CreateStyle(isBold, isItalic));

            return(ResolveTypeface(familyName, fontResolvingOptions, XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions)));
        }
        internal unsafe static XFontSource CreateFontSource(string familyName, FontResolvingOptions fontResolvingOptions, string typefaceKey)
        {
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }

            var descriptor = UIFont.FromName(familyName, 20.0f).FontDescriptor;

            UIFontDescriptorSymbolicTraits traits = 0;

            if (fontResolvingOptions.IsItalic)
            {
                traits |= UIFontDescriptorSymbolicTraits.Italic;
            }

            if (fontResolvingOptions.IsBold)
            {
                traits |= UIFontDescriptorSymbolicTraits.Bold;
            }

            var uifont = UIFont.FromDescriptor(descriptor.CreateWithTraits(traits), 20.0f);
            var cgFont = CGFont.CreateWithFontName(uifont.Name);

            IntPtr tags       = CGFontCopyTableTags(cgFont.Handle);
            nint   tableCount = CFArrayGetCount(tags);
            nint   totalSize  = sizeof(FontHeader) + sizeof(TableEntry) * tableCount;

            for (int index = 0; index < tableCount; ++index)
            {
                nint tableSize = 0;

                int aTag = (int)CFArrayGetValueAtIndex(tags, index);

                IntPtr tableDataRef = CGFontCopyTableForTag(cgFont.Handle, aTag);

                if (tableDataRef != IntPtr.Zero)
                {
                    tableSize = CFDataGetLength(tableDataRef);
                    CFRelease(tableDataRef);
                }

                totalSize += (tableSize + 3) & ~3;
            }

            var data = new byte[totalSize];

            fixed(byte *dataStart = data)
            {
                byte *dataPtr = dataStart;

                UInt16 entrySelector = 0;
                UInt16 searchRange   = 1;

                while (searchRange < tableCount >> 1)
                {
                    entrySelector++;
                    searchRange <<= 1;
                }
                searchRange <<= 4;

                UInt16 rangeShift = (UInt16)((tableCount << 4) - searchRange);

                FontHeader *offsetTable = (FontHeader *)dataPtr;

                offsetTable->fVersion       = (Int32)SwapBytes((UInt16)1);
                offsetTable->fNumTables     = SwapBytes((UInt16)tableCount);
                offsetTable->fSearchRange   = SwapBytes((UInt16)searchRange);
                offsetTable->fEntrySelector = SwapBytes((UInt16)entrySelector);
                offsetTable->fRangeShift    = SwapBytes((UInt16)rangeShift);
                dataPtr += sizeof(FontHeader);

                TableEntry *entry = (TableEntry *)dataPtr;

                dataPtr += sizeof(TableEntry) * tableCount;

                for (int index = 0; index < tableCount; ++index)
                {
                    int aTag = (int)CFArrayGetValueAtIndex(tags, index);

                    IntPtr tableDataRef = CGFontCopyTableForTag(cgFont.Handle, aTag);

                    nint tableSize = 0;

                    if (tableDataRef != IntPtr.Zero)
                    {
                        tableSize = CFDataGetLength(tableDataRef);
                        Buffer.MemoryCopy((byte *)CFDataGetBytePtr(tableDataRef), dataPtr, tableSize, tableSize);
                        entry->fTag      = SwapBytes((UInt32)aTag);
                        entry->fCheckSum = SwapBytes(CalcTableCheckSum((UInt32 *)dataPtr, tableSize));
                        UInt32 offset = (UInt32)(dataPtr - dataStart);
                        entry->fOffset = SwapBytes((UInt32)offset);
                        entry->fLength = SwapBytes((UInt32)tableSize);
                        CFRelease(tableDataRef);
                    }

                    dataPtr += (tableSize + 3) & ~3;
                    ++entry;
                }
            }

            var fontSource = XFontSource.GetOrCreateFrom(typefaceKey, data);

            return(fontSource);
        }
        /// <summary>
        /// Create a GDI+ font and use its handle to retrieve font data using native calls.
        /// </summary>
        internal static XFontSource CreateFontSource(string familyName, FontResolvingOptions fontResolvingOptions, out GdiFont font, string typefaceKey)
        {
            if (string.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }
#if true_
            if (familyName == "Cambria")
            {
                Debug - Break.Break();
            }
#endif
            GdiFontStyle gdiStyle = (GdiFontStyle)(fontResolvingOptions.FontStyle & XFontStyle.BoldItalic);

            // Create a 10 point GDI+ font as an exemplar.
            XFontSource fontSource;
            font = FontHelper.CreateFont(familyName, 10, gdiStyle, out fontSource);

            if (fontSource != null)
            {
                Debug.Assert(font != null);
                // Case: Font was created by a GDI+ private font collection.
#if true
#if DEBUG
                XFontSource existingFontSource;
                Debug.Assert(FontFactory.TryGetFontSourceByTypefaceKey(typefaceKey, out existingFontSource) &&
                             ReferenceEquals(fontSource, existingFontSource));
#endif
#else
                // Win32 API cannot get font data from fonts created by private font collection,
                // because this is handled internally in GDI+.
                // Therefore the font source was created when the private font is added to the private font collection.
                if (!FontFactory.TryGetFontSourceByTypefaceKey(typefaceKey, out fontSource))
                {
                    // Simplify styles.
                    // (The code is written for clarity - do not rearrange for optimization)
                    if (font.Bold && font.Italic)
                    {
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, true, false), out fontSource))
                        {
                            // Use bold font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                        else if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, true), out fontSource))
                        {
                            // Use italic font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                        else if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            // Use regular font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                    else if (font.Bold || font.Italic)
                    {
                        // Use regular font.
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                    else
                    {
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            // Should never come here...
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                }
#endif
            }
            else
            {
                // Get or create the font source and cache it unter the specified typeface key.
                fontSource = XFontSource.GetOrCreateFromGdi(typefaceKey, font);
            }
            return(fontSource);
        }