Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / CommonUI / System / Drawing / Advanced / Font.cs / 6 / Font.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Drawing {
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System;
using System.Drawing.Design;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.ComponentModel;
using Microsoft.Win32;
using System.Drawing;
using System.Drawing.Internal;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
/*
* Represent a font object
*/
///
///
/// Defines a particular format for text,
/// including font face, size, and style attributes.
///
[
TypeConverterAttribute(typeof(FontConverter)),
EditorAttribute("System.Drawing.Design.FontEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor)),
]
[Serializable]
[ComVisible(true)]
public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable {
const int LogFontCharSetOffset = 23;
const int LogFontNameOffset = 28;
IntPtr nativeFont;
float fontSize;
FontStyle fontStyle;
FontFamily fontFamily;
GraphicsUnit fontUnit;
byte gdiCharSet = SafeNativeMethods.DEFAULT_CHARSET;
bool gdiVerticalFont;
string systemFontName = "";
string originalFontName;
///
/// Creates the GDI+ native font object.
///
private void CreateNativeFont()
{
Debug.Assert(this.nativeFont == IntPtr.Zero, "nativeFont already initialized, this will generate a handle leak.");
Debug.Assert(this.fontFamily != null, "fontFamily not initialized.");
// Note: GDI+ creates singleton font family objects (from the corresponding font file) and reference count them so
// if creating the font object from an external FontFamily, this object's FontFamily will share the same native object.
int status = SafeNativeMethods.Gdip.GdipCreateFont(
new HandleRef(this, this.fontFamily.NativeFamily),
this.fontSize,
this.fontStyle,
this.fontUnit,
out this.nativeFont );
// Special case this common error message to give more information
if (status == SafeNativeMethods.Gdip.FontStyleNotFound)
{
throw new ArgumentException(SR.GetString(SR.GdiplusFontStyleNotFound, this.fontFamily.Name, this.fontStyle.ToString()));
}
else if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
}
/**
* Constructor used in deserialization
*/
[SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")]
private Font(SerializationInfo info, StreamingContext context) {
Debug.Assert(info != null, "Didn't expect a null parameter");
string name = null;
float size = -1f;
FontStyle style = FontStyle.Regular;
GraphicsUnit unit = GraphicsUnit.Point;
SingleConverter sc = new SingleConverter();
SerializationInfoEnumerator sie = info.GetEnumerator();
for (; sie.MoveNext();) {
if (String.Equals(sie.Name, "Name", StringComparison.OrdinalIgnoreCase))
name = (string) sie.Value;
else if (String.Equals(sie.Name, "Size", StringComparison.OrdinalIgnoreCase))
{
if (sie.Value is System.String)
{
size = (float) sc.ConvertFrom(sie.Value);
}
else
{
size = (float) sie.Value;
}
}
else if (String.Compare(sie.Name, "Style", true, CultureInfo.InvariantCulture) == 0)
style = (FontStyle) sie.Value;
else if (String.Compare(sie.Name, "Unit", true, CultureInfo.InvariantCulture) == 0)
unit = (GraphicsUnit) sie.Value;
else {
Debug.Fail("Unknown serialization item for font: " + sie.Name);
}
}
Initialize(name, size, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(name));
}
///
///
/// ISerializable private implementation
///
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
// Serialize the original Font name rather than the fallback font name if we have one
// See VSWhidbey 602074
si.AddValue("Name", String.IsNullOrEmpty(OriginalFontName) ? Name : OriginalFontName);
si.AddValue("Size", Size);
si.AddValue("Style", Style);
si.AddValue("Unit", Unit);
}
///
///
///
/// Initializes a new instance of the class from
/// the specified existing and .
///
///
public Font(Font prototype, FontStyle newStyle)
{
// Copy over the originalFontName because it won't get initialized
this.originalFontName = prototype.OriginalFontName;
Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) {
Initialize(family, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
Initialize(family, emSize, style, unit, gdiCharSet, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
Initialize(familyName, emSize, style, unit, gdiCharSet, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) {
throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize");
}
Initialize(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style) {
Initialize(family, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, GraphicsUnit unit) {
Initialize(family, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize) {
Initialize(family, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) {
Initialize(familyName, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
///
/// Initializes a new instance of the class with
/// the specified
/// attributes.
///
///
public Font(string familyName, float emSize, FontStyle style) {
Initialize(familyName, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, GraphicsUnit unit) {
Initialize(familyName, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize) {
Initialize(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
/// Constructor to initialize fields from an exisiting native GDI+ object reference.
/// Used by ToLogFont.
///
private Font(IntPtr nativeFont, byte gdiCharSet, bool gdiVerticalFont)
{
Debug.Assert(this.nativeFont == IntPtr.Zero, "GDI+ native font already initialized, this will generate a handle leak" );
Debug.Assert(nativeFont != IntPtr.Zero, "nativeFont is null");
int status = 0;
float size = 0;
GraphicsUnit unit = GraphicsUnit.Point;
FontStyle style = FontStyle.Regular;
IntPtr nativeFamily = IntPtr.Zero;
this.nativeFont = nativeFont;
status = SafeNativeMethods.Gdip.GdipGetFontUnit(new HandleRef(this, nativeFont), out unit);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, nativeFont), out size);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFontStyle(new HandleRef(this, nativeFont), out style);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFamily(new HandleRef(this, nativeFont), out nativeFamily);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
SetFontFamily(new FontFamily(nativeFamily));
Initialize(this.fontFamily, size, style, unit, gdiCharSet, gdiVerticalFont);
}
///
/// Initializes this object's fields.
///
private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
{
this.originalFontName = familyName;
SetFontFamily(new FontFamily(StripVerticalName(familyName), true /* createDefaultOnFail */ ));
Initialize( this.fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont );
}
///
/// Initializes this object's fields.
///
private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
{
if (family == null)
{
throw new ArgumentNullException("family");
}
if ( float.IsNaN( emSize ) || float.IsInfinity(emSize) || emSize <= 0 )
{
throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize");
}
int status;
this.fontSize = emSize;
this.fontStyle = style;
this.fontUnit = unit;
this.gdiCharSet = gdiCharSet;
this.gdiVerticalFont = gdiVerticalFont;
if (this.fontFamily == null)
{
// GDI+ FontFamily is a singleton object.
SetFontFamily(new FontFamily(family.NativeFamily));
}
if( this.nativeFont == IntPtr.Zero )
{
CreateNativeFont();
}
// Get actual size.
status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, this.nativeFont), out this.fontSize);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
}
///
///
/// Creates a from the specified Windows
/// handle.
///
public static Font FromHfont(IntPtr hfont) {
IntSecurity.ObjectFromWin32Handle.Demand();
SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT();
SafeNativeMethods.GetObject(new HandleRef(null, hfont), lf);
Font result;
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
result = Font.FromLogFont(lf, screenDC);
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return result;
}
///
///
/// [To be supplied.]
///
public static Font FromLogFont(object lf) {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
Font result;
try {
result = Font.FromLogFont(lf, screenDC);
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return result;
}
///
///
/// [To be supplied.]
///
public static Font FromLogFont(object lf, IntPtr hdc) {
IntSecurity.ObjectFromWin32Handle.Demand();
IntPtr font = IntPtr.Zero;
int status;
if (Marshal.SystemDefaultCharSize == 1)
status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontA(new HandleRef(null, hdc), lf, out font);
else
status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontW(new HandleRef(null, hdc), lf, out font);
// Special case this incredibly common error message to give more information
if (status == SafeNativeMethods.Gdip.NotTrueTypeFont)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName));
else if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
// GDI+ returns font = 0 even though the status is Ok.
if (font == IntPtr.Zero)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont, lf.ToString()));
bool gdiVerticalFont;
if (Marshal.SystemDefaultCharSize == 1) {
gdiVerticalFont = (Marshal.ReadByte(lf, LogFontNameOffset) == (byte)(short)'@');
}
else {
gdiVerticalFont = (Marshal.ReadInt16(lf, LogFontNameOffset) == (short)'@');
}
return new Font(font, Marshal.ReadByte(lf, LogFontCharSetOffset), gdiVerticalFont);
}
///
///
/// Creates a Font from the specified Windows
/// handle to a device context.
///
public static Font FromHdc(IntPtr hdc) {
IntSecurity.ObjectFromWin32Handle.Demand();
IntPtr font = IntPtr.Zero;
int status = SafeNativeMethods.Gdip.GdipCreateFontFromDC(new HandleRef(null, hdc), ref font);
// Special case this incredibly common error message to give more information
if (status == SafeNativeMethods.Gdip.NotTrueTypeFont)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName));
else if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return new Font(font, 0, false);
}
///
///
/// Creates an exact copy of this .
///
public object Clone()
{
IntPtr cloneFont = IntPtr.Zero;
int status = SafeNativeMethods.Gdip.GdipCloneFont(new HandleRef(this, nativeFont), out cloneFont);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
Font newCloneFont = new Font(cloneFont, this.gdiCharSet, this.gdiVerticalFont);
return newCloneFont;
}
///
/// Get native GDI+ object pointer.
/// This property triggers the creation of the GDI+ native object if not initialized yet.
///
internal IntPtr NativeFont
{
get
{
Debug.Assert( this.nativeFont != IntPtr.Zero, "this.nativeFont == IntPtr.Zero." );
return this.nativeFont;
}
}
///
///
/// Gets the of this .
///
[
Browsable(false)
]
public FontFamily FontFamily
{
get
{
Debug.Assert(this.fontFamily != null, "fontFamily should never be null");
return this.fontFamily;
}
}
[SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")]
private void SetFontFamily(FontFamily family) {
this.fontFamily = family;
// GDI+ creates ref-counted singleton FontFamily objects based on the family name so all managed
// objects with same family name share the underlying GDI+ native pointer. The unmanged object is
// destroyed when its ref-count gets to zero.
// Make sure this.fontFamily is not finalized so the underlying singleton object is kept alive.
// SECREVIEW : This security assert here is safe.
//
new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode).Assert();
GC.SuppressFinalize(this.fontFamily);
}
///
///
/// Cleans up Windows resources for this .
///
~Font()
{
Dispose(false);
}
///
///
/// Cleans up Windows resources for this .
///
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
[SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")]
void Dispose(bool disposing) {
if (this.nativeFont != IntPtr.Zero) {
try {
#if DEBUG
int status =
#endif
SafeNativeMethods.Gdip.GdipDeleteFont(new HandleRef(this, this.nativeFont));
#if DEBUG
Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif
}
catch( Exception ex ) {
if( ClientUtils.IsCriticalException( ex ) ) {
throw;
}
Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
}
finally {
this.nativeFont = IntPtr.Zero;
}
}
}
private static bool IsVerticalName(string familyName)
{
return familyName != null && familyName.Length > 0 && familyName[0] == '@';
}
///
///
///
/// Gets a value indicating whether this is bold.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Bold {
get {
return(Style & FontStyle.Bold) != 0;
}
}
///
///
/// Returns the GDI char set for this instance of a font. This will only
/// be valid if this font was created from a classic GDI font definition,
/// like a LOGFONT or HFONT, or it was passed into the constructor.
///
/// This is here for compatability with native Win32 intrinsic controls
/// on non-Unicode platforms.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public byte GdiCharSet {
get {
return gdiCharSet;
}
}
///
///
/// Determines if this font was created to represt a GDI vertical font.
/// his will only be valid if this font was created from a classic GDI
/// font definition, like a LOGFONT or HFONT, or it was passed into the
/// constructor.
///
/// This is here for compatability with native Win32 intrinsic controls
/// on non-Unicode platforms.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool GdiVerticalFont {
get {
return gdiVerticalFont;
}
}
///
///
///
/// Gets a value indicating whether this is Italic.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Italic {
get {
return(Style & FontStyle.Italic) != 0;
}
}
///
///
///
/// Gets the face name of this .
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Editor("System.Drawing.Design.FontNameEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor))]
[TypeConverterAttribute(typeof(FontConverter.FontNameConverter))]
public string Name {
get { return this.FontFamily.Name;}
}
///
///
///
/// This property is required by the framework and not intended to be used directly.
///
///
[Browsable(false)]
public string OriginalFontName
{
get { return this.originalFontName; }
}
///
///
///
/// Gets a value indicating whether this is strikeout (has a line
/// through it).
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Strikeout {
get {
return(Style & FontStyle.Strikeout) != 0;
}
}
///
///
///
/// Gets a value indicating whether this is underlined.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Underline {
get {
return(Style & FontStyle.Underline) != 0;
}
}
///
///
/// Returns a value indicating whether the
/// specified object is a equivalent to this .
///
public override bool Equals(object obj)
{
if (obj == this)
{
return true;
}
Font font = obj as Font;
if (font == null)
{
return false;
}
// Note: If this and/or the passed-in font are disposed, this method can still return true since we check for cached properties
// here - We cannot fix this, see VSW#484721.
// We need to call properties on the passed-in object since it could be a proxy in a remoting scenario and proxies don't
// have access to private/internal fields - See VSW#464151.
return font.FontFamily.Equals(this.FontFamily) &&
font.GdiVerticalFont == this.GdiVerticalFont &&
font.GdiCharSet == this.GdiCharSet &&
font.Style == this.Style &&
font.Size == this.Size &&
font.Unit == this.Unit;
}
///
///
/// Gets the hash code for this .
///
public override int GetHashCode()
{
return (int)((((UInt32)fontStyle << 13) | ((UInt32)fontStyle >> 19)) ^
(((UInt32)fontUnit << 26) | ((UInt32)fontUnit >> 6)) ^
(((UInt32)fontSize << 7) | ((UInt32)fontSize >> 25)));
}
private static string StripVerticalName(string familyName) {
if (familyName != null && familyName.Length > 1 && familyName[0] == '@') {
return familyName.Substring(1);
}
return familyName;
}
///
///
/// Returns a human-readable string
/// representation of this .
///
public override string ToString()
{
return string.Format( CultureInfo.CurrentCulture, "[{0}: Name={1}, Size={2}, Units={3}, GdiCharSet={4}, GdiVerticalFont={5}]",
GetType().Name,
this.FontFamily.Name,
this.fontSize,
(int) this.fontUnit,
this.gdiCharSet,
this.gdiVerticalFont );
}
// Operations
///
///
/// [To be supplied.]
///
public void ToLogFont(object logFont) {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
Graphics graphics = Graphics.FromHdcInternal(screenDC);
try {
this.ToLogFont(logFont, graphics);
}
finally {
graphics.Dispose();
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
}
///
///
/// [To be supplied.]
///
public unsafe void ToLogFont(object logFont, Graphics graphics) {
IntSecurity.ObjectFromWin32Handle.Demand();
if (graphics == null)
throw new ArgumentNullException("graphics");
int status;
// handle proper marshalling of LogFontName as Unicode or ANSI
if (Marshal.SystemDefaultCharSize == 1)
status = SafeNativeMethods.Gdip.GdipGetLogFontA(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont);
else
status = SafeNativeMethods.Gdip.GdipGetLogFontW(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont);
// append "@" to the begining of the string if we are
// a gdiVerticalFont.
//
if (gdiVerticalFont) {
if (Marshal.SystemDefaultCharSize == 1) {
// copy contents of name, over 1 byte
//
for (int i=30; i>=0; i--) {
Marshal.WriteByte(logFont,
LogFontNameOffset + i + 1,
Marshal.ReadByte(logFont, LogFontNameOffset + i));
}
// write ANSI '@' sign at begining of name
//
Marshal.WriteByte(logFont, LogFontNameOffset, (byte)(int)'@');
}
else {
// copy contents of name, over 2 bytes (UNICODE)
//
for (int i=60; i>=0; i-=2) {
Marshal.WriteInt16(logFont,
LogFontNameOffset + i + 2,
Marshal.ReadInt16(logFont, LogFontNameOffset + i));
}
// write UNICODE '@' sign at begining of name
//
Marshal.WriteInt16(logFont, LogFontNameOffset, (short)'@');
}
}
if (Marshal.ReadByte(logFont, LogFontCharSetOffset) == 0) {
Marshal.WriteByte(logFont, LogFontCharSetOffset, gdiCharSet);
}
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
}
///
///
/// Returns a handle to this .
///
public IntPtr ToHfont() {
SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT();
IntSecurity.ObjectFromWin32Handle.Assert();
try {
this.ToLogFont(lf);
}
finally {
System.Security.CodeAccessPermission.RevertAssert();
}
IntPtr handle = IntUnsafeNativeMethods.IntCreateFontIndirect(lf);
if (handle == IntPtr.Zero) {
throw new Win32Exception();
}
return handle;
}
///
///
/// Returns the height of this Font in the
/// specified graphics context.
///
public float GetHeight(Graphics graphics) {
if (graphics == null)
throw new ArgumentNullException("graphics");
float ht;
int status = SafeNativeMethods.Gdip.GdipGetFontHeight(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), out ht);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return ht;
}
///
///
///
public float GetHeight() {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
float height = 0.0f;
try {
using (Graphics graphics = Graphics.FromHdcInternal(screenDC)) {
height = GetHeight(graphics);
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return height;
}
///
///
///
public float GetHeight(float dpi) {
float ht;
int status = SafeNativeMethods.Gdip.GdipGetFontHeightGivenDPI(new HandleRef(this, this.NativeFont), dpi, out ht);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return ht;
}
///
///
/// Gets style information for this .
///
[
Browsable(false)
]
public FontStyle Style {
get {
return fontStyle;
}
}
// Return value is in Unit (the unit the font was created in)
///
///
/// Gets the size of this .
///
public float Size {
get {
return fontSize;
}
}
///
///
/// Gets the size, in points, of this .
///
[Browsable(false)]
public float SizeInPoints {
get {
if (Unit == GraphicsUnit.Point)
return Size;
else {
float emHeightInPoints;
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
using( Graphics graphics = Graphics.FromHdcInternal(screenDC)){
float pixelsPerPoint = (float) (graphics.DpiY / 72.0);
float lineSpacingInPixels = this.GetHeight(graphics);
float emHeightInPixels = lineSpacingInPixels * FontFamily.GetEmHeight(Style) / FontFamily.GetLineSpacing(Style);
emHeightInPoints = emHeightInPixels / pixelsPerPoint;
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return emHeightInPoints;
}
}
}
///
///
/// Gets the unit of measure for this .
///
[TypeConverterAttribute(typeof(FontConverter.FontUnitConverter))]
public GraphicsUnit Unit {
get {
return fontUnit;
}
}
///
///
/// Gets the height of this .
///
[
Browsable(false)
]
public int Height {
get {
return(int) Math.Ceiling(GetHeight());
}
}
///
///
/// Returns true if this is a SystemFont.
///
[
Browsable(false)
]
public bool IsSystemFont {
get {
return !String.IsNullOrEmpty(this.systemFontName);
}
}
///
///
/// Gets the name of this .
///
[
Browsable(false)
]
public string SystemFontName {
get {
return this.systemFontName;
}
}
// This is used by SystemFonts when constructing a system Font objects.
internal void SetSystemFontName(string systemFontName) {
this.systemFontName = systemFontName;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Drawing {
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System;
using System.Drawing.Design;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.ComponentModel;
using Microsoft.Win32;
using System.Drawing;
using System.Drawing.Internal;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
/*
* Represent a font object
*/
///
///
/// Defines a particular format for text,
/// including font face, size, and style attributes.
///
[
TypeConverterAttribute(typeof(FontConverter)),
EditorAttribute("System.Drawing.Design.FontEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor)),
]
[Serializable]
[ComVisible(true)]
public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable {
const int LogFontCharSetOffset = 23;
const int LogFontNameOffset = 28;
IntPtr nativeFont;
float fontSize;
FontStyle fontStyle;
FontFamily fontFamily;
GraphicsUnit fontUnit;
byte gdiCharSet = SafeNativeMethods.DEFAULT_CHARSET;
bool gdiVerticalFont;
string systemFontName = "";
string originalFontName;
///
/// Creates the GDI+ native font object.
///
private void CreateNativeFont()
{
Debug.Assert(this.nativeFont == IntPtr.Zero, "nativeFont already initialized, this will generate a handle leak.");
Debug.Assert(this.fontFamily != null, "fontFamily not initialized.");
// Note: GDI+ creates singleton font family objects (from the corresponding font file) and reference count them so
// if creating the font object from an external FontFamily, this object's FontFamily will share the same native object.
int status = SafeNativeMethods.Gdip.GdipCreateFont(
new HandleRef(this, this.fontFamily.NativeFamily),
this.fontSize,
this.fontStyle,
this.fontUnit,
out this.nativeFont );
// Special case this common error message to give more information
if (status == SafeNativeMethods.Gdip.FontStyleNotFound)
{
throw new ArgumentException(SR.GetString(SR.GdiplusFontStyleNotFound, this.fontFamily.Name, this.fontStyle.ToString()));
}
else if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
}
/**
* Constructor used in deserialization
*/
[SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")]
private Font(SerializationInfo info, StreamingContext context) {
Debug.Assert(info != null, "Didn't expect a null parameter");
string name = null;
float size = -1f;
FontStyle style = FontStyle.Regular;
GraphicsUnit unit = GraphicsUnit.Point;
SingleConverter sc = new SingleConverter();
SerializationInfoEnumerator sie = info.GetEnumerator();
for (; sie.MoveNext();) {
if (String.Equals(sie.Name, "Name", StringComparison.OrdinalIgnoreCase))
name = (string) sie.Value;
else if (String.Equals(sie.Name, "Size", StringComparison.OrdinalIgnoreCase))
{
if (sie.Value is System.String)
{
size = (float) sc.ConvertFrom(sie.Value);
}
else
{
size = (float) sie.Value;
}
}
else if (String.Compare(sie.Name, "Style", true, CultureInfo.InvariantCulture) == 0)
style = (FontStyle) sie.Value;
else if (String.Compare(sie.Name, "Unit", true, CultureInfo.InvariantCulture) == 0)
unit = (GraphicsUnit) sie.Value;
else {
Debug.Fail("Unknown serialization item for font: " + sie.Name);
}
}
Initialize(name, size, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(name));
}
///
///
/// ISerializable private implementation
///
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
// Serialize the original Font name rather than the fallback font name if we have one
// See VSWhidbey 602074
si.AddValue("Name", String.IsNullOrEmpty(OriginalFontName) ? Name : OriginalFontName);
si.AddValue("Size", Size);
si.AddValue("Style", Style);
si.AddValue("Unit", Unit);
}
///
///
///
/// Initializes a new instance of the class from
/// the specified existing and .
///
///
public Font(Font prototype, FontStyle newStyle)
{
// Copy over the originalFontName because it won't get initialized
this.originalFontName = prototype.OriginalFontName;
Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) {
Initialize(family, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
Initialize(family, emSize, style, unit, gdiCharSet, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
Initialize(familyName, emSize, style, unit, gdiCharSet, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) {
throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize");
}
Initialize(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, FontStyle style) {
Initialize(family, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize, GraphicsUnit unit) {
Initialize(family, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(FontFamily family, float emSize) {
Initialize(family, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) {
Initialize(familyName, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
///
/// Initializes a new instance of the class with
/// the specified
/// attributes.
///
///
public Font(string familyName, float emSize, FontStyle style) {
Initialize(familyName, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize, GraphicsUnit unit) {
Initialize(familyName, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
///
/// Initializes a new instance of the class with
/// the specified attributes.
///
public Font(string familyName, float emSize) {
Initialize(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
}
///
/// Constructor to initialize fields from an exisiting native GDI+ object reference.
/// Used by ToLogFont.
///
private Font(IntPtr nativeFont, byte gdiCharSet, bool gdiVerticalFont)
{
Debug.Assert(this.nativeFont == IntPtr.Zero, "GDI+ native font already initialized, this will generate a handle leak" );
Debug.Assert(nativeFont != IntPtr.Zero, "nativeFont is null");
int status = 0;
float size = 0;
GraphicsUnit unit = GraphicsUnit.Point;
FontStyle style = FontStyle.Regular;
IntPtr nativeFamily = IntPtr.Zero;
this.nativeFont = nativeFont;
status = SafeNativeMethods.Gdip.GdipGetFontUnit(new HandleRef(this, nativeFont), out unit);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, nativeFont), out size);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFontStyle(new HandleRef(this, nativeFont), out style);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
status = SafeNativeMethods.Gdip.GdipGetFamily(new HandleRef(this, nativeFont), out nativeFamily);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
SetFontFamily(new FontFamily(nativeFamily));
Initialize(this.fontFamily, size, style, unit, gdiCharSet, gdiVerticalFont);
}
///
/// Initializes this object's fields.
///
private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
{
this.originalFontName = familyName;
SetFontFamily(new FontFamily(StripVerticalName(familyName), true /* createDefaultOnFail */ ));
Initialize( this.fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont );
}
///
/// Initializes this object's fields.
///
private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
{
if (family == null)
{
throw new ArgumentNullException("family");
}
if ( float.IsNaN( emSize ) || float.IsInfinity(emSize) || emSize <= 0 )
{
throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize");
}
int status;
this.fontSize = emSize;
this.fontStyle = style;
this.fontUnit = unit;
this.gdiCharSet = gdiCharSet;
this.gdiVerticalFont = gdiVerticalFont;
if (this.fontFamily == null)
{
// GDI+ FontFamily is a singleton object.
SetFontFamily(new FontFamily(family.NativeFamily));
}
if( this.nativeFont == IntPtr.Zero )
{
CreateNativeFont();
}
// Get actual size.
status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, this.nativeFont), out this.fontSize);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
}
///
///
/// Creates a from the specified Windows
/// handle.
///
public static Font FromHfont(IntPtr hfont) {
IntSecurity.ObjectFromWin32Handle.Demand();
SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT();
SafeNativeMethods.GetObject(new HandleRef(null, hfont), lf);
Font result;
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
result = Font.FromLogFont(lf, screenDC);
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return result;
}
///
///
/// [To be supplied.]
///
public static Font FromLogFont(object lf) {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
Font result;
try {
result = Font.FromLogFont(lf, screenDC);
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return result;
}
///
///
/// [To be supplied.]
///
public static Font FromLogFont(object lf, IntPtr hdc) {
IntSecurity.ObjectFromWin32Handle.Demand();
IntPtr font = IntPtr.Zero;
int status;
if (Marshal.SystemDefaultCharSize == 1)
status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontA(new HandleRef(null, hdc), lf, out font);
else
status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontW(new HandleRef(null, hdc), lf, out font);
// Special case this incredibly common error message to give more information
if (status == SafeNativeMethods.Gdip.NotTrueTypeFont)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName));
else if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
// GDI+ returns font = 0 even though the status is Ok.
if (font == IntPtr.Zero)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont, lf.ToString()));
bool gdiVerticalFont;
if (Marshal.SystemDefaultCharSize == 1) {
gdiVerticalFont = (Marshal.ReadByte(lf, LogFontNameOffset) == (byte)(short)'@');
}
else {
gdiVerticalFont = (Marshal.ReadInt16(lf, LogFontNameOffset) == (short)'@');
}
return new Font(font, Marshal.ReadByte(lf, LogFontCharSetOffset), gdiVerticalFont);
}
///
///
/// Creates a Font from the specified Windows
/// handle to a device context.
///
public static Font FromHdc(IntPtr hdc) {
IntSecurity.ObjectFromWin32Handle.Demand();
IntPtr font = IntPtr.Zero;
int status = SafeNativeMethods.Gdip.GdipCreateFontFromDC(new HandleRef(null, hdc), ref font);
// Special case this incredibly common error message to give more information
if (status == SafeNativeMethods.Gdip.NotTrueTypeFont)
throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName));
else if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return new Font(font, 0, false);
}
///
///
/// Creates an exact copy of this .
///
public object Clone()
{
IntPtr cloneFont = IntPtr.Zero;
int status = SafeNativeMethods.Gdip.GdipCloneFont(new HandleRef(this, nativeFont), out cloneFont);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
Font newCloneFont = new Font(cloneFont, this.gdiCharSet, this.gdiVerticalFont);
return newCloneFont;
}
///
/// Get native GDI+ object pointer.
/// This property triggers the creation of the GDI+ native object if not initialized yet.
///
internal IntPtr NativeFont
{
get
{
Debug.Assert( this.nativeFont != IntPtr.Zero, "this.nativeFont == IntPtr.Zero." );
return this.nativeFont;
}
}
///
///
/// Gets the of this .
///
[
Browsable(false)
]
public FontFamily FontFamily
{
get
{
Debug.Assert(this.fontFamily != null, "fontFamily should never be null");
return this.fontFamily;
}
}
[SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")]
private void SetFontFamily(FontFamily family) {
this.fontFamily = family;
// GDI+ creates ref-counted singleton FontFamily objects based on the family name so all managed
// objects with same family name share the underlying GDI+ native pointer. The unmanged object is
// destroyed when its ref-count gets to zero.
// Make sure this.fontFamily is not finalized so the underlying singleton object is kept alive.
// SECREVIEW : This security assert here is safe.
//
new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode).Assert();
GC.SuppressFinalize(this.fontFamily);
}
///
///
/// Cleans up Windows resources for this .
///
~Font()
{
Dispose(false);
}
///
///
/// Cleans up Windows resources for this .
///
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
[SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")]
void Dispose(bool disposing) {
if (this.nativeFont != IntPtr.Zero) {
try {
#if DEBUG
int status =
#endif
SafeNativeMethods.Gdip.GdipDeleteFont(new HandleRef(this, this.nativeFont));
#if DEBUG
Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif
}
catch( Exception ex ) {
if( ClientUtils.IsCriticalException( ex ) ) {
throw;
}
Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
}
finally {
this.nativeFont = IntPtr.Zero;
}
}
}
private static bool IsVerticalName(string familyName)
{
return familyName != null && familyName.Length > 0 && familyName[0] == '@';
}
///
///
///
/// Gets a value indicating whether this is bold.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Bold {
get {
return(Style & FontStyle.Bold) != 0;
}
}
///
///
/// Returns the GDI char set for this instance of a font. This will only
/// be valid if this font was created from a classic GDI font definition,
/// like a LOGFONT or HFONT, or it was passed into the constructor.
///
/// This is here for compatability with native Win32 intrinsic controls
/// on non-Unicode platforms.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public byte GdiCharSet {
get {
return gdiCharSet;
}
}
///
///
/// Determines if this font was created to represt a GDI vertical font.
/// his will only be valid if this font was created from a classic GDI
/// font definition, like a LOGFONT or HFONT, or it was passed into the
/// constructor.
///
/// This is here for compatability with native Win32 intrinsic controls
/// on non-Unicode platforms.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool GdiVerticalFont {
get {
return gdiVerticalFont;
}
}
///
///
///
/// Gets a value indicating whether this is Italic.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Italic {
get {
return(Style & FontStyle.Italic) != 0;
}
}
///
///
///
/// Gets the face name of this .
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Editor("System.Drawing.Design.FontNameEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor))]
[TypeConverterAttribute(typeof(FontConverter.FontNameConverter))]
public string Name {
get { return this.FontFamily.Name;}
}
///
///
///
/// This property is required by the framework and not intended to be used directly.
///
///
[Browsable(false)]
public string OriginalFontName
{
get { return this.originalFontName; }
}
///
///
///
/// Gets a value indicating whether this is strikeout (has a line
/// through it).
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Strikeout {
get {
return(Style & FontStyle.Strikeout) != 0;
}
}
///
///
///
/// Gets a value indicating whether this is underlined.
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Underline {
get {
return(Style & FontStyle.Underline) != 0;
}
}
///
///
/// Returns a value indicating whether the
/// specified object is a equivalent to this .
///
public override bool Equals(object obj)
{
if (obj == this)
{
return true;
}
Font font = obj as Font;
if (font == null)
{
return false;
}
// Note: If this and/or the passed-in font are disposed, this method can still return true since we check for cached properties
// here - We cannot fix this, see VSW#484721.
// We need to call properties on the passed-in object since it could be a proxy in a remoting scenario and proxies don't
// have access to private/internal fields - See VSW#464151.
return font.FontFamily.Equals(this.FontFamily) &&
font.GdiVerticalFont == this.GdiVerticalFont &&
font.GdiCharSet == this.GdiCharSet &&
font.Style == this.Style &&
font.Size == this.Size &&
font.Unit == this.Unit;
}
///
///
/// Gets the hash code for this .
///
public override int GetHashCode()
{
return (int)((((UInt32)fontStyle << 13) | ((UInt32)fontStyle >> 19)) ^
(((UInt32)fontUnit << 26) | ((UInt32)fontUnit >> 6)) ^
(((UInt32)fontSize << 7) | ((UInt32)fontSize >> 25)));
}
private static string StripVerticalName(string familyName) {
if (familyName != null && familyName.Length > 1 && familyName[0] == '@') {
return familyName.Substring(1);
}
return familyName;
}
///
///
/// Returns a human-readable string
/// representation of this .
///
public override string ToString()
{
return string.Format( CultureInfo.CurrentCulture, "[{0}: Name={1}, Size={2}, Units={3}, GdiCharSet={4}, GdiVerticalFont={5}]",
GetType().Name,
this.FontFamily.Name,
this.fontSize,
(int) this.fontUnit,
this.gdiCharSet,
this.gdiVerticalFont );
}
// Operations
///
///
/// [To be supplied.]
///
public void ToLogFont(object logFont) {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
Graphics graphics = Graphics.FromHdcInternal(screenDC);
try {
this.ToLogFont(logFont, graphics);
}
finally {
graphics.Dispose();
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
}
///
///
/// [To be supplied.]
///
public unsafe void ToLogFont(object logFont, Graphics graphics) {
IntSecurity.ObjectFromWin32Handle.Demand();
if (graphics == null)
throw new ArgumentNullException("graphics");
int status;
// handle proper marshalling of LogFontName as Unicode or ANSI
if (Marshal.SystemDefaultCharSize == 1)
status = SafeNativeMethods.Gdip.GdipGetLogFontA(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont);
else
status = SafeNativeMethods.Gdip.GdipGetLogFontW(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont);
// append "@" to the begining of the string if we are
// a gdiVerticalFont.
//
if (gdiVerticalFont) {
if (Marshal.SystemDefaultCharSize == 1) {
// copy contents of name, over 1 byte
//
for (int i=30; i>=0; i--) {
Marshal.WriteByte(logFont,
LogFontNameOffset + i + 1,
Marshal.ReadByte(logFont, LogFontNameOffset + i));
}
// write ANSI '@' sign at begining of name
//
Marshal.WriteByte(logFont, LogFontNameOffset, (byte)(int)'@');
}
else {
// copy contents of name, over 2 bytes (UNICODE)
//
for (int i=60; i>=0; i-=2) {
Marshal.WriteInt16(logFont,
LogFontNameOffset + i + 2,
Marshal.ReadInt16(logFont, LogFontNameOffset + i));
}
// write UNICODE '@' sign at begining of name
//
Marshal.WriteInt16(logFont, LogFontNameOffset, (short)'@');
}
}
if (Marshal.ReadByte(logFont, LogFontCharSetOffset) == 0) {
Marshal.WriteByte(logFont, LogFontCharSetOffset, gdiCharSet);
}
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
}
///
///
/// Returns a handle to this .
///
public IntPtr ToHfont() {
SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT();
IntSecurity.ObjectFromWin32Handle.Assert();
try {
this.ToLogFont(lf);
}
finally {
System.Security.CodeAccessPermission.RevertAssert();
}
IntPtr handle = IntUnsafeNativeMethods.IntCreateFontIndirect(lf);
if (handle == IntPtr.Zero) {
throw new Win32Exception();
}
return handle;
}
///
///
/// Returns the height of this Font in the
/// specified graphics context.
///
public float GetHeight(Graphics graphics) {
if (graphics == null)
throw new ArgumentNullException("graphics");
float ht;
int status = SafeNativeMethods.Gdip.GdipGetFontHeight(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), out ht);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return ht;
}
///
///
///
public float GetHeight() {
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
float height = 0.0f;
try {
using (Graphics graphics = Graphics.FromHdcInternal(screenDC)) {
height = GetHeight(graphics);
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return height;
}
///
///
///
public float GetHeight(float dpi) {
float ht;
int status = SafeNativeMethods.Gdip.GdipGetFontHeightGivenDPI(new HandleRef(this, this.NativeFont), dpi, out ht);
if (status != SafeNativeMethods.Gdip.Ok)
throw SafeNativeMethods.Gdip.StatusException(status);
return ht;
}
///
///
/// Gets style information for this .
///
[
Browsable(false)
]
public FontStyle Style {
get {
return fontStyle;
}
}
// Return value is in Unit (the unit the font was created in)
///
///
/// Gets the size of this .
///
public float Size {
get {
return fontSize;
}
}
///
///
/// Gets the size, in points, of this .
///
[Browsable(false)]
public float SizeInPoints {
get {
if (Unit == GraphicsUnit.Point)
return Size;
else {
float emHeightInPoints;
IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
try {
using( Graphics graphics = Graphics.FromHdcInternal(screenDC)){
float pixelsPerPoint = (float) (graphics.DpiY / 72.0);
float lineSpacingInPixels = this.GetHeight(graphics);
float emHeightInPixels = lineSpacingInPixels * FontFamily.GetEmHeight(Style) / FontFamily.GetLineSpacing(Style);
emHeightInPoints = emHeightInPixels / pixelsPerPoint;
}
}
finally {
UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
}
return emHeightInPoints;
}
}
}
///
///
/// Gets the unit of measure for this .
///
[TypeConverterAttribute(typeof(FontConverter.FontUnitConverter))]
public GraphicsUnit Unit {
get {
return fontUnit;
}
}
///
///
/// Gets the height of this .
///
[
Browsable(false)
]
public int Height {
get {
return(int) Math.Ceiling(GetHeight());
}
}
///
///
/// Returns true if this is a SystemFont.
///
[
Browsable(false)
]
public bool IsSystemFont {
get {
return !String.IsNullOrEmpty(this.systemFontName);
}
}
///
///
/// Gets the name of this .
///
[
Browsable(false)
]
public string SystemFontName {
get {
return this.systemFontName;
}
}
// This is used by SystemFonts when constructing a system Font objects.
internal void SetSystemFontName(string systemFontName) {
this.systemFontName = systemFontName;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlDomTextWriter.cs
- ClientConfigPaths.cs
- DATA_BLOB.cs
- ApplicationGesture.cs
- EntityDataSourceSelectedEventArgs.cs
- WebEventCodes.cs
- MetaType.cs
- DrawingContextDrawingContextWalker.cs
- ExceptionWrapper.cs
- ActivityExecutionContext.cs
- DecimalAnimationBase.cs
- DataGridTablesFactory.cs
- DataListCommandEventArgs.cs
- ObjectDataSource.cs
- ElementProxy.cs
- SystemIPAddressInformation.cs
- SiteMapSection.cs
- SpecialFolderEnumConverter.cs
- RuleSetCollection.cs
- ThreadExceptionEvent.cs
- SocketPermission.cs
- HttpProfileGroupBase.cs
- PropertyValueUIItem.cs
- ComponentResourceManager.cs
- MenuItemCollection.cs
- UndirectedGraph.cs
- AttachedProperty.cs
- CollectionBuilder.cs
- SqlServices.cs
- XmlSchemaComplexContentExtension.cs
- ContainerParaClient.cs
- WebBrowserNavigatedEventHandler.cs
- XmlSchemaObjectTable.cs
- WebPartConnectionsConnectVerb.cs
- CompilationPass2Task.cs
- ProxyElement.cs
- BuildManager.cs
- MissingFieldException.cs
- ExpandoClass.cs
- GenericArgumentsUpdater.cs
- ReferenceService.cs
- TextBoxAutomationPeer.cs
- FamilyTypeface.cs
- DataAdapter.cs
- InfoCardSymmetricAlgorithm.cs
- TableRowsCollectionEditor.cs
- DataGridViewCellPaintingEventArgs.cs
- ToolStripEditorManager.cs
- KeyInfo.cs
- MaterialGroup.cs
- FileIOPermission.cs
- DynamicMethod.cs
- SpotLight.cs
- CellCreator.cs
- XmlTextReaderImpl.cs
- ArrayListCollectionBase.cs
- FloaterParagraph.cs
- backend.cs
- OutOfMemoryException.cs
- _CacheStreams.cs
- InternalConfigSettingsFactory.cs
- NameSpaceExtractor.cs
- HttpStreamMessage.cs
- InputLangChangeEvent.cs
- ContextStaticAttribute.cs
- DispatcherHookEventArgs.cs
- ForceCopyBuildProvider.cs
- CommandField.cs
- TraceContextEventArgs.cs
- DesignerLoader.cs
- ProcessInfo.cs
- QueryCacheManager.cs
- DateTimeValueSerializer.cs
- ConnectionModeReader.cs
- CuspData.cs
- DataErrorValidationRule.cs
- _ListenerRequestStream.cs
- PointLightBase.cs
- SoapObjectWriter.cs
- XamlToRtfWriter.cs
- HeaderedContentControl.cs
- CountdownEvent.cs
- validation.cs
- IPGlobalProperties.cs
- CustomTokenProvider.cs
- CacheOutputQuery.cs
- PartitionResolver.cs
- TimelineCollection.cs
- StrokeCollectionConverter.cs
- AutomationEventArgs.cs
- NullableConverter.cs
- RegisteredArrayDeclaration.cs
- FixedFindEngine.cs
- TextServicesCompartmentEventSink.cs
- PropertyEmitterBase.cs
- GeneratedContractType.cs
- UnicastIPAddressInformationCollection.cs
- PropertyValidationContext.cs
- FileSystemInfo.cs
- embossbitmapeffect.cs