Shapeクラス(設計)
ShapeクラスはImageUtilsのBmpProcを拡張した単純な作図クラスとする。最初はBmpProcを派生しようかとも考えたのだが、privateメンバーが多くて派生しても恩恵に授かれそうにないのでBmpProcをメンバーに持つ形で作ることにした。だいたいの雰囲気はこんな感じ。
ShapeBase +SetPixel() ...仮想関数にしておく +DrawLine() +DrawRectangle() +FillRectangle() +DrawEllipse() +FillEllipse() Shape1 : ShapeBase, IDisposable -BmpProc1 proc +SetPixel() ...基底の関数にoverride Shape8 : ShapeBase, IDisposable -BmpProc8 proc +SetPixel() ...基底の関数にoverride Shape24 : ShapeBase, IDisposable -BmpProc24 proc +SetPixel() ...基底の関数にoverride Shape32 : ShapeBase, IDisposable -BmpProc32 proc +SetPixel() ...基底の関数にoverride
まず作図関数群はShapeBaseという仮想クラスへ作成していく。これらはすべてSetPixel()という仮想関数を呼び出すことで動作するように仕掛けておく。
次にこのShapeBaseからBmpProcの種類数分のShapeXXを派生させる。これらはそれぞれに1つのBmpProcをメンバーに持ち、そのBmpProc特有のSetPixel()をoverrideで実装しておく。
実際に使う側のコードはこうなる予定。
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); int w = ClientSize.Width; int h = ClientSize.Height; if (w >= 2 && h >= 2) { Bitmap bmp = new Bitmap(w, h, PixelFormat.Format24bppRgb); Shape24 sh = new Shape24(bmp); Random r = new Random(); for (int i = 0; i < 100; i++) { Color cl = Color.FromArgb(r.Next(256), r.Next(256), r.Next(256)); int xx = r.Next(-100, w + 100); int yy = r.Next(-100, h + 100); int ww = r.Next(500); int hh = r.Next(500); sh.Color = cl; switch (r.Next(2)) { case 0: sh.DrawEllipse(xx, yy, ww, hh); break; case 1: sh.FillEllipse(xx, yy, ww, hh); break; } } sh.Dispose(); e.Graphics.DrawImage(bmp, 0, 0); bmp.Dispose(); } }
本当はBitmap作成からBmpProcを作成してそのBmpProcからShapeを作るような流れにしたかったのだが、BmpProcはビットマップの情報(Width、Height)などを公開していないのでShapeから描画範囲のクリップをするためには、BmpProcの作成はShape内部で行うように考えてこの形になった。