using System.Runtime.Serialization;
using System.Runtime.InteropServices;
+using System.Security.Permissions;
using System.ComponentModel;
namespace System.Drawing
private string systemFontName;
private float _size;
- private void CreateFont(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) {
- Status status;
- FontFamily family;
+ private const byte DefaultCharSet = 1;
+ private static int CharSetOffset = -1;
+ private static int FaceNameOffset = -1;
+ private void CreateFont (string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical)
+ {
+#if ONLY_1_1
+ if (familyName == null)
+ throw new ArgumentNullException ("familyName");
+#endif
+ FontFamily family;
// NOTE: If family name is null, empty or invalid,
// MS creates Microsoft Sans Serif font.
try {
}
setProperties (family, emSize, style, unit, charSet, isVertical);
- status = GDIPlus.GdipCreateFont (family.NativeObject, emSize, style, unit, out fontObject);
+ Status status = GDIPlus.GdipCreateFont (family.NativeObject, emSize, style, unit, out fontObject);
GDIPlus.CheckStatus (status);
}
style = (FontStyle)info.GetValue("Style", typeof(FontStyle));
unit = (GraphicsUnit)info.GetValue("Unit", typeof(GraphicsUnit));
- CreateFont(name, size, style, unit, (byte)0, false);
+ CreateFont(name, size, style, unit, DefaultCharSet, false);
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
public void Dispose ()
{
if (fontObject != IntPtr.Zero) {
- GDIPlus.CheckStatus (GDIPlus.GdipDeleteFont (fontObject));
+ Status status = GDIPlus.GdipDeleteFont (fontObject);
fontObject = IntPtr.Zero;
GC.SuppressFinalize (this);
+ // check the status code (throw) at the last step
+ GDIPlus.CheckStatus (status);
}
}
public IntPtr ToHfont ()
{
+ if (fontObject == IntPtr.Zero)
+ throw new ArgumentException (Locale.GetText ("Object has been disposed."));
+
IntPtr Hfont;
OperatingSystem osInfo = Environment.OSVersion;
-
- // Sanity. Should we throw an exception?
- if (fontObject == IntPtr.Zero) {
- return IntPtr.Zero;
- }
-
if ((int) osInfo.Platform == 128 || (int) osInfo.Platform == 4) {
return fontObject;
} else {
- LOGFONT lf = new LOGFONT ();
- ToLogFont(lf);
+ object olf = new LOGFONT ();
+ ToLogFont(olf);
+ LOGFONT lf = (LOGFONT)olf;
Hfont = GDIPlus.CreateFontIndirect (ref lf);
}
return Hfont;
}
public Font (FontFamily family, float emSize, GraphicsUnit unit)
- : this (family, emSize, FontStyle.Regular, unit, (byte)0, false)
+ : this (family, emSize, FontStyle.Regular, unit, DefaultCharSet, false)
{
}
public Font (string familyName, float emSize, GraphicsUnit unit)
- : this (new FontFamily (familyName), emSize, FontStyle.Regular, unit, (byte)0, false)
+ : this (new FontFamily (familyName), emSize, FontStyle.Regular, unit, DefaultCharSet, false)
{
}
public Font (FontFamily family, float emSize)
- : this (family, emSize, FontStyle.Regular, GraphicsUnit.Point, (byte)0, false)
+ : this (family, emSize, FontStyle.Regular, GraphicsUnit.Point, DefaultCharSet, false)
{
}
public Font (FontFamily family, float emSize, FontStyle style)
- : this (family, emSize, style, GraphicsUnit.Point, (byte)0, false)
+ : this (family, emSize, style, GraphicsUnit.Point, DefaultCharSet, false)
{
}
public Font (FontFamily family, float emSize, FontStyle style, GraphicsUnit unit)
- : this (family, emSize, style, unit, (byte)0, false)
+ : this (family, emSize, style, unit, DefaultCharSet, false)
{
}
public Font (FontFamily family, float emSize, FontStyle style,
GraphicsUnit unit, byte charSet, bool isVertical)
{
- // MS does not accept null family
+ if (family == null)
+ throw new ArgumentNullException ("family");
+
Status status;
setProperties (family, emSize, style, unit, charSet, isVertical);
status = GDIPlus.GdipCreateFont (family.NativeObject, emSize, style, unit, out fontObject);
}
public Font (string familyName, float emSize)
- : this (familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, (byte)0, false)
+ : this (familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, DefaultCharSet, false)
{
}
public Font (string familyName, float emSize, FontStyle style)
- : this (familyName, emSize, style, GraphicsUnit.Point, (byte)0, false)
+ : this (familyName, emSize, style, GraphicsUnit.Point, DefaultCharSet, false)
{
}
public Font (string familyName, float emSize, FontStyle style, GraphicsUnit unit)
- : this (familyName, emSize, style, unit, (byte)0, false)
+ : this (familyName, emSize, style, unit, DefaultCharSet, false)
{
}
internal IntPtr NativeObject {
get {
- return fontObject;
- }
- set {
- fontObject = value;
+ return fontObject;
}
}
public override bool Equals (object obj)
{
- if (! (obj is Font))
+ Font fnt = (obj as Font);
+ if (fnt == null)
return false;
-
- Font fnt = (Font) obj;
-
+
if (fnt.FontFamily.Equals (FontFamily) && fnt.Size == Size &&
fnt.Style == Style && fnt.Unit == Unit &&
fnt.GdiCharSet == GdiCharSet &&
{
IntPtr newObject;
LOGFONT o = (LOGFONT)lf;
- GDIPlus.GdipCreateFontFromLogfont (hdc, ref o, out newObject);
+ Status status = GDIPlus.GdipCreateFontFromLogfont (hdc, ref o, out newObject);
+ GDIPlus.CheckStatus (status);
return new Font (newObject, "Microsoft Sans Serif", FontStyle.Regular, 10);
}
}
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
public void ToLogFont (object logFont)
{
Graphics g;
}
}
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
public void ToLogFont (object logFont, Graphics graphics)
{
- if (graphics == null) {
+ if (graphics == null)
throw new ArgumentNullException ("graphics");
+
+ if (logFont == null) {
+#if NET_2_0
+ throw new AccessViolationException ("logFont");
+#else
+ throw new NullReferenceException ("logFont");
+#endif
}
- if (Marshal.SizeOf(logFont) >= Marshal.SizeOf(typeof(LOGFONT))) {
- GDIPlus.CheckStatus (GDIPlus.GdipGetLogFont(NativeObject, graphics.NativeObject, logFont));
+ Type st = logFont.GetType ();
+ if (!st.IsLayoutSequential)
+ throw new ArgumentException ("logFont", Locale.GetText ("Layout must be sequential."));
+
+ // note: there is no exception if 'logFont' isn't big enough
+ Type lf = typeof (LOGFONT);
+ int size = Marshal.SizeOf (lf);
+ if (Marshal.SizeOf (logFont) >= size) {
+ Status status;
+ IntPtr copy = Marshal.AllocHGlobal (size);
+ try {
+ Marshal.StructureToPtr (logFont, copy, false);
+
+ status = GDIPlus.GdipGetLogFont (NativeObject, graphics.NativeObject, logFont);
+ if (status != Status.Ok) {
+ // reset to original values
+ Marshal.PtrToStructure (copy, logFont);
+ }
+ }
+ finally {
+ Marshal.FreeHGlobal (copy);
+ }
+
+ if (CharSetOffset == -1) {
+ CharSetOffset = (int) Marshal.OffsetOf (lf, "lfCharSet");
+ FaceNameOffset = (int) Marshal.OffsetOf (lf, "lfFaceName");
+ }
+
+ // note: Marshal.WriteByte(object,*) methods are unimplemented on Mono
+ GCHandle gch = GCHandle.Alloc (logFont, GCHandleType.Pinned);
+ try {
+ IntPtr ptr = gch.AddrOfPinnedObject ();
+ // if GDI+ lfCharSet is 0, then we return (S.D.) 1, otherwise the value is unchanged
+ if (Marshal.ReadByte (ptr, CharSetOffset) == 0) {
+ // set lfCharSet to 1
+ Marshal.WriteByte (ptr, CharSetOffset, 1);
+ }
+ }
+ finally {
+ gch.Free ();
+ }
+
+ // now we can throw, if required
+ GDIPlus.CheckStatus (status);
}
}
public float GetHeight (Graphics graphics)
{
float size;
-
- GDIPlus.GdipGetFontHeight (fontObject, graphics.NativeObject, out size);
+ Status status = GDIPlus.GdipGetFontHeight (fontObject, graphics.NativeObject, out size);
+ GDIPlus.CheckStatus (status);
return size;
}
public float GetHeight (float dpi)
{
float size;
- GDIPlus.GdipGetFontHeightGivenDPI (fontObject, dpi, out size);
+ Status status = GDIPlus.GdipGetFontHeightGivenDPI (fontObject, dpi, out size);
+ GDIPlus.CheckStatus (status);
return size;
}