/// <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. if (FontFactory.TryGetFontResolverInfoByTypefaceKey(typefaceKey, out FontResolverInfo 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 XFontSource fontSource = CreateFontSource(familyName, fontResolvingOptions, out GdiFont 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 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 simulation. if (infoBold != null && infoBold.StyleSimulations == XStyleSimulations.None) { // Use existing bold typeface and simulate 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 FontFactory.CacheFontResolverInfo(typefaceKey, fontResolverInfo); // Register font data under the platform specific face name. // Already done in CreateFontSource. // FontFactory.CacheNewFontSource(typefaceKey, fontSource); return(fontResolverInfo); }
/// <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. font = FontHelper.CreateFont(familyName, 10, gdiStyle, out XFontSource fontSource); if (fontSource != null) { Debug.Assert(font != null); // Case: Font was created by a GDI+ private font collection. #if true #if DEBUG Debug.Assert(FontFactory.TryGetFontSourceByTypefaceKey(typefaceKey, out XFontSource 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 under the specified typeface key. fontSource = XFontSource.GetOrCreateFromGdi(typefaceKey, font); } return(fontSource); }