public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) {
cropRectangle = Rectangle.Empty;
try {
fixed( byte* bpx = Map.Blocks ) {
fixed( byte* tp = Tiles ) {
fixed( byte* stp = ShadowTiles ) {
bp = bpx;
while( h < Map.Height ) {
block = GetBlock( x, y, h );
if( block != 0 ) {
switch( Rot ) {
case 0: ctp = (h >= Map.Shadows[x, y] ? tp : stp); break;
case 1: ctp = (h >= Map.Shadows[dimX1 - y, x] ? tp : stp); break;
case 2: ctp = (h >= Map.Shadows[dimX1 - x, dimY1 - y] ? tp : stp); break;
case 3: ctp = (h >= Map.Shadows[y, dimY1 - x] ? tp : stp); break;
}
int blockRight, blockLeft, blockUp;
if( x != (Rot == 1 || Rot == 3 ? dimY1 : dimX1) ) blockRight = GetBlock( x + 1, y, h );
else blockRight = 0;
if( y != (Rot == 1 || Rot == 3 ? dimX1 : dimY1) ) blockLeft = GetBlock( x, y + 1, h );
else blockLeft = 0;
if( h != Map.Height - 1 ) blockUp = GetBlock( x, y, h + 1 );
else blockUp = 0;
if( blockUp == 0 || blockLeft == 0 || blockRight == 0 || // air
blockUp == 8 || blockLeft == 8 || blockRight == 8 || // water
blockUp == 9 || blockLeft == 9 || blockRight == 9 || // water
(block != 20 && (blockUp == 20 || blockLeft == 20 || blockRight == 20)) || // glass
blockUp == 18 || blockLeft == 18 || blockRight == 18 || // foliage
blockLeft == 44 || blockRight == 44 || // step
blockUp == 10 || blockLeft == 10 || blockRight == 10 || // lava
blockUp == 11 || blockLeft == 11 || blockRight == 11 || // lava
blockUp == 37 || blockLeft == 37 || blockRight == 37 || // flower
blockUp == 38 || blockLeft == 38 || blockRight == 38 || // flower
blockUp == 6 || blockLeft == 6 || blockRight == 6 || // tree
blockUp == 39 || blockLeft == 39 || blockRight == 39 || // mushroom
blockUp == 40 || blockLeft == 40 || blockRight == 40 ) // mushroom
BlendTile();
}
x++;
if( x == (Rot == 1 || Rot == 3 ? dimY : dimX) ) {
y++;
x = 0;
}
if( y == (Rot == 1 || Rot == 3 ? dimX : dimY) ) {
h++;
y = 0;
if( h % 4 == 0 && worker != null ) {
if( worker.CancellationPending ) return null;
worker.ReportProgress( (h * 100) / Map.Height );
}
}
}
}
}
}
int xMin = 0, xMax = imageWidth - 1, yMin = 0, yMax = imageHeight - 1;
bool cont = true;
int offset;
// find left bound (xMin)
for( x = 0; cont && x < imageWidth; x++ ) {
offset = x * 4 + 3;
for( y = 0; y < imageHeight; y++ ) {
if( image[offset] > 0 ) {
xMin = x;
cont = false;
break;
}
offset += imageStride;
}
}
if( worker != null && worker.CancellationPending ) return null;
// find top bound (yMin)
cont = true;
for( y = 0; cont && y < imageHeight; y++ ) {
offset = imageStride * y + xMin * 4 + 3;
for( x = xMin; x < imageWidth; x++ ) {
if( image[offset] > 0 ) {
yMin = y;
cont = false;
break;
}
offset += 4;
}
}
if( worker != null && worker.CancellationPending ) return null;
// find right bound (xMax)
cont = true;
for( x = imageWidth - 1; cont && x >= xMin; x-- ) {
offset = x * 4 + 3 + yMin * imageStride;
for( y = yMin; y < imageHeight; y++ ) {
if( image[offset] > 0 ) {
xMax = x + 1;
cont = false;
break;
}
offset += imageStride;
}
}
if( worker != null && worker.CancellationPending ) return null;
// find bottom bound (yMax)
cont = true;
for( y = imageHeight - 1; cont && y >= yMin; y-- ) {
offset = imageStride * y + 3 + xMin * 4;
for( x = xMin; x < xMax; x++ ) {
if( image[offset] > 0 ) {
yMax = y + 1;
cont = false;
break;
}
offset += 4;
}
}
cropRectangle = new Rectangle( Math.Max( 0, xMin - 2 ),
Math.Max( 0, yMin - 2 ),
Math.Min( imageBmp.Width, xMax - xMin + 4 ),
Math.Min( imageBmp.Height, yMax - yMin + 4 ) );
return imageBmp;
} finally {
imageBmp.UnlockBits( imageData );
if( worker != null && worker.CancellationPending && imageBmp != null ) {
try {
imageBmp.Dispose();
} catch( ObjectDisposedException ) { }
}
}
}