public static BitmapContent PackSprites(IList<BitmapContent> p_sourceSprites, ICollection<Rectangle> p_outputSprites, ContentProcessorContext p_context)
{
if (p_sourceSprites.Count == 0) {
throw new InvalidContentException("There are no sprites to arrange");
}
// Build up a list of all the sprites needing to be arranged.
List<ArrangedSprite> l_sprites = new List<ArrangedSprite>();
for (int i = 0; i < p_sourceSprites.Count; i++) {
ArrangedSprite l_sprite = new ArrangedSprite();
// Include a single pixel padding around each sprite, to avoid
// filtering problems if the sprite is scaled or rotated.
l_sprite.Width = p_sourceSprites[i].Width + 2;
l_sprite.Height = p_sourceSprites[i].Height + 2;
l_sprite.Index = i;
l_sprites.Add(l_sprite);
}
// Sort so the largest sprites get arranged first.
l_sprites.Sort(CompareSpriteSizes);
// Work out how big the output bitmap should be.
int l_outputWidth = GuessOutputWidth(l_sprites);
int l_outputHeight = 0;
int l_totalSpriteSize = 0;
// Choose positions for each sprite, one at a time.
for (int i = 0; i < l_sprites.Count; i++) {
PositionSprite(l_sprites, i, l_outputWidth);
l_outputHeight = Math.Max(l_outputHeight, l_sprites[i].Y + l_sprites[i].Height);
l_totalSpriteSize += l_sprites[i].Width * l_sprites[i].Height;
}
// Sort the sprites back into index order.
l_sprites.Sort(CompareSpriteIndices);
p_context.Logger.LogImportantMessage(
"Packed {0} sprites into a {1}x{2} sheet, {3}% efficiency",
l_sprites.Count, l_outputWidth, l_outputHeight,
l_totalSpriteSize * 100 / l_outputWidth / l_outputHeight);
return CopySpritesToOutput(l_sprites, p_sourceSprites, p_outputSprites, l_outputWidth, l_outputHeight);
}