[.NET源码学习]实例化Font,遭遇字体不存在的情况。

  实例化Font类时,当传入参数为不存在或未安装的字体时,Windows系统会用Microsoft Sans Serif字体替代该字体。

  Msdn:

    "For more information about how to construct fonts, see How to: Construct Font Families and Fonts. Windows Forms applications support TrueType fonts and have limited support for OpenType fonts. If you attempt to use a font that is not supported, or the font is not installed on the machine that is running the application, the Microsoft Sans Serif font will be substituted."

  

  情景

    利用 New Font("字体",.....) ,当该字体不存在时,我本以为会用系统默认的输入法代替之,后来查看了MSDN,发现事实似乎并非如此。决定查找一下源代码。

  

  源码

   System.Drawing.Font类

1 private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
2 {
3     this.originalFontName = familyName;
4     this.SetFontFamily(new FontFamily(Font.StripVerticalName(familyName), true));
5     this.Initialize(this.fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont);
6 }

System.Drawing.FontFamily类

1 internal FontFamily(string name, bool createDefaultOnFail)
2 {
3     this.createDefaultOnFail = createDefaultOnFail;
4     this.CreateFontFamily(name, null);
5 }
 1 private void CreateFontFamily(string name, FontCollection fontCollection)
 2 {
 3     IntPtr intPtr = IntPtr.Zero;
 4     IntPtr handle = (fontCollection == null) ? IntPtr.Zero : fontCollection.nativeFontCollection;
 5     int num = SafeNativeMethods.Gdip.GdipCreateFontFamilyFromName(name, new HandleRef(fontCollection, handle), out intPtr);
 6     if (num != 0)
 7     {
 8         if (this.createDefaultOnFail)
 9         {
10             intPtr = FontFamily.GetGdipGenericSansSerif();
11         }
12         else
13         {
14             if (num == 14)
15             {
16                 throw new ArgumentException(SR.GetString("GdiplusFontFamilyNotFound", new object[]
17                 {
18                     name
19                 }));
20             }
21             if (num == 16)
22             {
23                 throw new ArgumentException(SR.GetString("GdiplusNotTrueTypeFont", new object[]
24                 {
25                     name
26                 }));
27             }
28             throw SafeNativeMethods.Gdip.StatusException(num);
29         }
30     }
31     this.SetNativeFamily(intPtr);
32 }    
 1 private static IntPtr GetGdipGenericSansSerif()
 2 {
 3     IntPtr zero = IntPtr.Zero;
 4     int num = SafeNativeMethods.Gdip.GdipGetGenericFontFamilySansSerif(out zero);
 5     if (num != 0)
 6     {
 7         throw SafeNativeMethods.Gdip.StatusException(num);
 8     }
 9     return zero;
10 }
结论:【SafeNativeMethods.Gdip.GdipGetGenericFontFamilySansSerif】方法,Windows系统下返回Microsoft Sans Serif字体。

由此可见,当实例化字体不存在时,Windows下固定返回Microsoft Sans Serif字体,与系统默认字体无关。
            

[.NET源码学习]实例化Font,遭遇字体不存在的情况。

时间: 2024-11-29 07:10:33

[.NET源码学习]实例化Font,遭遇字体不存在的情况。的相关文章

FireMonkey 源码学习(5)

(5)UpdateCharRec 该函数的源码分析如下: procedure TTextLayoutNG.UpdateCharRec(const ACanvas: TCanvas; NeedBitmap: Boolean; var NewRec: PCharRec; HasItem: Boolean; const CharDic: TCharDic; const AFont: TFont; const Ch: UCS4Char; const NeedPath: Boolean = False);

FireMonkey 源码学习(4)

(4)DoDrawLayout DoDrawLayout函数的源代码分析如下: procedure TTextLayoutNG.DoDrawLayout(const ACanvas: TCanvas); var CharDic: TCharDic; Rec: PCharRec; Pos: TPointF; R, SrcR, ClipBounds: TRectF; LLine: TGPULine; LRun: TGPURun; I, J, K: Integer; VerticalAligned,

tomcat源码学习(2)  关于apache digest

好久不写博文,罪过罪过.因为最近公司比较忙加上琐事有点多,所以隔了好久才来更新博文. apache digest本来是struts2框架中来加载xml文件并实例化对象的一个jar包,后来使用的越来越多. 我们都知道tomcat的conf文件夹下有一个server.xml配置文件,我们经常会其中的来进行配置以来运行一个java web项目,也经常修改中的port属性以来实现修改tomcat监听的端口.其实每个标签基本上都对应着一个对象,那tomcat是如何将这些对象实例化到java 虚拟机的运行内

Hadoop源码学习笔记(4) ——Socket到RPC调用

Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要学的就是Socket编程,这是网络编程中最底层的程序接口,分为服务器端和客户端,服务器负责监听某个端口,客户端负责连接服务器上的某个端口,一旦连接通过后,服务器和客户端就可以双向通讯了,我们看下示例代码: ServerSocket server = new ServerSocket(8111); S

Spring源码学习笔记(6)

Spring源码学习笔记(六) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. 上一篇中我们梳理到 Spring 加载 XML 配置文件, 完成 XML 的解析工作,接下来我们将进入 Spring 加载 bean 的逻辑. 我们使用 Spring 获取 XML

Spring源码学习笔记(3)

Spring源码学习笔记(三) 前言----     最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. DispatcherServlet 实现核心功能 和普通的 Servelt 类一样, DispatcherServlet 中的 doGet() 和 doPost() 方法

FireMonkey 源码学习(3)

五.TTextLayoutNG 在FMX.TextLayout.GPU.pas文件中,实现了几个基础功能,其中: (1)渲染单元 在TextLayout中,每一批同字体和颜色的1~n个字符,组成一个最基本的渲染单元TGPURun,1~n个渲染单元构成一行(TGPULine),1~n行构成一帧(Frame).如下图: 行和帧只是一个组织方式,其中没有太多的内容.主要的实现还是在渲染单元(TGPURun)中. (2)TCharDic和TFamilyDic TextLayout的实现思路是: 每个渲染

API源码学习之集合(2)--LinkedList

继续集合源码学习--LinkedList 1.该类主要成员变量及构造方法有如下几个: 1 transient int size = 0; 2 3 /** 4 * Pointer to first node. 5 * Invariant: (first == null && last == null) || 6 * (first.prev == null && first.item != null) 7 */ 8 transient Node<E> first;

Spring源码学习笔记(7)

Spring源码学习笔记(七) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门 写前说句话, 开篇不尴尬 ---- 接下的这一篇当中, 我们将来回顾 Spring 中 AOP 功能的实现流程.  早上精力充沛, 开始新一天的学习 \(^o^)/~ 接触过 Spri