Properly dispose of all GDI+ entities used in VectorRenderModule for dynamic textures.

The convention is that if an object implements IDiposable() the code must explicitly call Dispose() or call it via the using statement.
This may be particularly important for GDI+ objects since they encapsulate native code entities.
0.7.3-extended
Justin Clark-Casey (justincc) 2012-08-03 00:00:54 +01:00
parent 0e9e60d55a
commit f35e94f168
1 changed files with 322 additions and 259 deletions

View File

@ -98,15 +98,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize)
{
Font myFont = new Font(fontName, fontSize);
using (Font myFont = new Font(fontName, fontSize))
{
SizeF stringSize = new SizeF();
lock (m_graph) {
lock (m_graph)
{
stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
}
}
}
#endregion
@ -121,6 +123,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
if (m_graph == null)
{
// We won't dispose of these explicitly since this module is only removed when the entire simulator
// is shut down.
Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
m_graph = Graphics.FromImage(bitmap);
}
@ -299,24 +303,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
Bitmap bitmap;
Bitmap bitmap = null;
Graphics graph = null;
try
{
if (alpha == 256)
{
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
}
else
{
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
}
Graphics graph = Graphics.FromImage(bitmap);
graph = Graphics.FromImage(bitmap);
// this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
{
graph.FillRectangle(new SolidBrush(bgColor), 0, 0, width, height);
using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
{
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
}
}
for (int w = 0; w < bitmap.Width; w++)
@ -347,6 +353,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
m_textureManager.ReturnData(id, imageJ2000);
}
finally
{
if (graph != null)
graph.Dispose();
if (bitmap != null)
bitmap.Dispose();
}
}
private int parseIntParam(string strInt)
{
@ -407,11 +422,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0);
Pen drawPen = new Pen(Color.Black, 7);
Pen drawPen = null;
Font myFont = null;
SolidBrush myBrush = null;
try
{
drawPen = new Pen(Color.Black, 7);
string fontName = m_fontName;
float fontSize = 14;
Font myFont = new Font(fontName, fontSize);
SolidBrush myBrush = new SolidBrush(Color.Black);
myFont = new Font(fontName, fontSize);
myBrush = new SolidBrush(Color.Black);
char[] lineDelimiter = {dataDelim};
char[] partsDelimiter = {','};
@ -453,19 +474,27 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
endPoint.X = (int) x;
endPoint.Y = (int) y;
Image image = ImageHttpRequest(nextLine);
using (Image image = ImageHttpRequest(nextLine))
{
if (image != null)
{
graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
}
else
{
graph.DrawString("URL couldn't be resolved or is", new Font(m_fontName,6),
using (Font errorFont = new Font(m_fontName,6))
{
graph.DrawString("URL couldn't be resolved or is", errorFont,
myBrush, startPoint);
graph.DrawString("not an image. Please check URL.", new Font(m_fontName, 6),
graph.DrawString("not an image. Please check URL.", errorFont,
myBrush, new Point(startPoint.X, 12 + startPoint.Y));
}
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
}
}
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
}
@ -519,6 +548,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
nextLine = nextLine.Remove(0, 8);
nextLine = nextLine.Trim();
fontSize = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
myFont.Dispose();
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("FontProp"))
@ -534,22 +565,40 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
case "B":
if (!(myFont.Bold))
myFont = new Font(myFont, myFont.Style | FontStyle.Bold);
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Bold);
myFont.Dispose();
myFont = newFont;
}
break;
case "I":
if (!(myFont.Italic))
myFont = new Font(myFont, myFont.Style | FontStyle.Italic);
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Italic);
myFont.Dispose();
myFont = newFont;
}
break;
case "U":
if (!(myFont.Underline))
myFont = new Font(myFont, myFont.Style | FontStyle.Underline);
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Underline);
myFont.Dispose();
myFont = newFont;
}
break;
case "S":
if (!(myFont.Strikeout))
myFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
{
Font newFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
myFont.Dispose();
myFont = newFont;
}
break;
case "R":
myFont = new Font(myFont, FontStyle.Regular);
Font newFont = new Font(myFont, FontStyle.Regular);
myFont.Dispose();
myFont = newFont;
break;
}
}
@ -558,6 +607,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
nextLine = nextLine.Remove(0, 8);
fontName = nextLine.Trim();
myFont.Dispose();
myFont = new Font(fontName, fontSize);
}
else if (nextLine.StartsWith("PenSize"))
@ -640,6 +690,18 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
}
finally
{
if (drawPen != null)
drawPen.Dispose();
if (myFont != null)
myFont.Dispose();
if (myBrush != null)
myBrush.Dispose();
}
}
private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
{
@ -702,6 +764,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
catch { }
return null;
}
}