GraphicsPathを指定してPathGradientBrushのインスタンスを作成する際、GraphicsPathに設定されているパスの内容次第ではPathGradientBrushのコンストラクタが例外OutOfMemoryExceptionをスローする。
扇型のパス (GraphicsPath.AddPie)
GraphicsPath.AddPieでsweepAngleに0
などの微小な角度を指定したパスを追加すると、OutOfMemoryExceptionとなる。
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
class Sample {
static void Main(string[] args)
{
var bounds = new RectangleF(0.0f, 0.0f, 64.0f, 64.0f);
const float startAngle = 0.0f;
const float sweepAngle = 0.0f;
using (var gp = new GraphicsPath()) {
// GraphicsPathにsweepAngleが0の扇型パスを追加する
gp.AddPie(bounds.X, bounds.Y, bounds.Width, bounds.Height, startAngle, sweepAngle);
// PathGradientBrushのコンストラクタがOutOfMemoryExceptionをスローする
using (var pgb = new PathGradientBrush(gp)) {
Console.WriteLine(pgb);
}
}
}
}
扇形が正円(外接するRectangleが正方形)の場合は、sweepAngleに指定する値が1.611493E-43
以上(後述の検証結果参照)であればOutOfMemoryExceptionとならない模様。 この値は扇形(外接するRectangle)の大きさによらず一定。 扇型が楕円(外接するRectangleが長方形)の場合は、その縦横比に応じてOutOfMemoryExceptionとなるsweepAngleの値も変わる。
以下は、GraphicsPath.AddPieに指定するsweepAngleの値を変えて正円の扇型パスを追加し、PathGradientBrushがOutOfMemoryExceptionをスローするかどうかを検証した結果。
1.401298E-45: OutOfMemoryException 9.809089E-45: OutOfMemoryException 9.949219E-44: OutOfMemoryException 1.000527E-42: OK 9.999666E-42: OK 9.999946E-41: OK 1E-39: OK 9.999999E-39: OK 1E-37: OK 1E-36: OK 1E-35: OK 1E-34: OK 1E-33: OK 1E-32: OK 1E-31: OK 1E-30: OK 1E-29: OK 1E-28: OK 1E-27: OK 1E-26: OK 1E-25: OK 1E-24: OK 1E-23: OK 1E-22: OK 1E-21: OK 1E-20: OK 1E-19: OK 1E-18: OK 1E-17: OK 1E-16: OK 1E-15: OK 1E-14: OK 1E-13: OK 1E-12: OK 1E-11: OK 1E-10: OK 1E-09: OK 1E-08: OK 1E-07: OK 1E-06: OK 1E-05: OK 0.0001: OK 0.001: OK 0.01: OK 0.1: OK
0: OutOfMemoryException 1.401298E-45: OutOfMemoryException 2.802597E-45: OutOfMemoryException 4.203895E-45: OutOfMemoryException : (中略) : 1.569454E-43: OutOfMemoryException 1.583467E-43: OutOfMemoryException 1.59748E-43: OutOfMemoryException 1.611493E-43: OK 1.625506E-43: OK 1.639519E-43: OK : (後略) :
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
class Sample {
static void Main(string[] args)
{
var bounds = new RectangleF(0.0f, 0.0f, 64.0f, 64.0f);
const float startAngle = 0.0f;
//for (var sweepAngle = 0.0f; sweepAngle <= 1.0f; sweepAngle += float.Epsilon) {
for (var exp = -45; exp < 0; exp++) {
var sweepAngle = (float)Math.Pow(10.0, exp);
Console.Write("{0}: ", sweepAngle);
using (var gp = new GraphicsPath()) {
gp.AddPie(bounds.X, bounds.Y, bounds.Width, bounds.Height, startAngle, sweepAngle);
try {
using (var pgb = new PathGradientBrush(gp)) {
Console.WriteLine("OK");
}
}
catch (OutOfMemoryException) {
Console.WriteLine("OutOfMemoryException");
}
}
}
}
}
Graphics.FillPie/DrawPie
Graphics.FillPieメソッドやGraphics.DrawPieメソッドでは、sweepAngleが0
や微小な値であってもOutOfMemoryExceptionやArgumentOutOfRangeExceptionはスローされない。
libgdiplus(Mono)の場合
libgdiplusでは、AddPieメソッドに指定するsweepAngleが0
や微小な値であってもOutOfMemoryExceptionやArgumentOutOfRangeExceptionはスローされない。
それ以外のパス
未検証。