/// <summary> /// Registers the font face. /// </summary> public static XFontSource RegisterFontFace(byte[] fontBytes) { try { Lock.EnterFontFactory(); ulong key = FontHelper.CalcChecksum(fontBytes); XFontSource fontSource; if (FontSourcesByKey.TryGetValue(key, out fontSource)) { throw new InvalidOperationException("Font face already registered."); } fontSource = XFontSource.GetOrCreateFrom(fontBytes); Debug.Assert(FontSourcesByKey.ContainsKey(key)); Debug.Assert(fontSource.Fontface != null); //fontSource.Fontface = new OpenTypeFontface(fontSource); //FontSourcesByKey.Add(checksum, fontSource); //FontSourcesByFontName.Add(fontSource.FontName, fontSource); XGlyphTypeface glyphTypeface = new XGlyphTypeface(fontSource); FontSourcesByName.Add(glyphTypeface.Key, fontSource); GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface); return(fontSource); } finally { Lock.ExitFontFactory(); } }
internal OpenTypeDescriptor(string fontDescriptorKey, string idName, byte[] fontData) : base(fontDescriptorKey) { try { FontFace = XFontSource.GetOrCreateFrom(fontData).Fontface; // Try to get real name form name table if (idName.Contains("XPS-Font-") && FontFace.name != null && FontFace.name.Name.Length != 0) { string tag = String.Empty; if (idName.IndexOf('+') == 6) { tag = idName.Substring(0, 6); } idName = tag + "+" + FontFace.name.Name; if (FontFace.name.Style.Length != 0) { idName += "," + FontFace.name.Style; } //idName = idName.Replace(" ", ""); } FontName = idName; Initialize(); } catch (Exception) { GetType(); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="OpenTypeFontface"/> class. /// </summary> public OpenTypeFontface(byte[] data, string faceName) { _fullFaceName = faceName; // Always save a copy of the font bytes. FontSource = XFontSource.GetOrCreateFrom(data); Read(); }
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); }
//// 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(); } }
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); }