public static PixelBitmapContent<Color> packSprites( IList<BitmapContent> sourceSprites, ICollection<Rectangle> outputSprites, bool isCompressed, ContentProcessorContext context )
{
if( sourceSprites.Count == 0 )
throw new InvalidContentException( "There are no sprites to pack" );
// Build up a list of all the sprites needing to be arranged.
var sprites = new List<ArrangedSprite>();
for( var i = 0; i < sourceSprites.Count; i++ )
{
var sprite = new ArrangedSprite();
// Include a single pixel padding around each sprite, to avoid filtering problems if the sprite is scaled or rotated.
sprite.width = sourceSprites[i].Width + 2;
sprite.height = sourceSprites[i].Height + 2;
sprite.index = i;
sprites.Add( sprite );
}
// Sort so the largest sprites get arranged first.
sprites.Sort( compareSpriteSizes );
// Work out how big the output bitmap should be.
var outputWidth = guessOutputWidth( sprites );
var outputHeight = 0;
var totalSpriteSize = 0;
// Choose positions for each sprite, one at a time.
for( var i = 0; i < sprites.Count; i++ )
{
positionSprite( sprites, i, outputWidth );
outputHeight = Math.Max( outputHeight, sprites[i].y + sprites[i].height );
totalSpriteSize += sprites[i].width * sprites[i].height;
}
// DXT compression requires texture sizes to be a multiple of 4
if( isCompressed )
outputHeight = (outputHeight + 3) & ~3;
// sort the sprites back into index order.
sprites.Sort( compareSpriteIndices );
context.Logger.LogImportantMessage(
"\nPacked {0} sprites into a {1}x{2} sheet, {3}% efficiency",
sprites.Count, outputWidth, outputHeight,
totalSpriteSize * 100 / outputWidth / outputHeight );
return copySpritesToOutput( sprites, sourceSprites, outputSprites, outputWidth, outputHeight );
}