// This method does some trickery type stuff where we perform the TestPackingImages method over and over, // trying to reduce the image size until we have found the smallest possible image we can fit. private bool PackImageRectangles() { // create a dictionary for our test image placements Dictionary <string, Rectangle> testImagePlacement = new Dictionary <string, Rectangle>(); // get the size of our smallest image int smallestWidth = int.MaxValue; int smallestHeight = int.MaxValue; foreach (var size in imageSizes) { smallestWidth = Math.Min(smallestWidth, size.Value.Width); smallestHeight = Math.Min(smallestHeight, size.Value.Height); } // we need a couple values for testing int testWidth = outputWidth; int testHeight = outputHeight; bool shrinkVertical = false; // just keep looping... while (true) { // make sure our test dictionary is empty testImagePlacement.Clear(); // try to pack the images into our current test size if (!TestPackingImages(testWidth, testHeight, testImagePlacement)) { // if that failed... // if we have no images in imagePlacement, i.e. we've never succeeded at PackImages, // show an error and return false since there is no way to fit the images into our // maximum size texture if (imagePlacement.Count == 0) { return(false); } // otherwise return true to use our last good results if (shrinkVertical) { return(true); } shrinkVertical = true; testWidth += smallestWidth + padding + padding; testHeight += smallestHeight + padding + padding; continue; } // clear the imagePlacement dictionary and add our test results in imagePlacement.Clear(); foreach (var pair in testImagePlacement) { imagePlacement.Add(pair.Key, pair.Value); } // figure out the smallest bitmap that will hold all the images testWidth = testHeight = 0; foreach (var pair in imagePlacement) { testWidth = Math.Max(testWidth, pair.Value.Right); testHeight = Math.Max(testHeight, pair.Value.Bottom); } // subtract the extra padding on the right and bottom if (!shrinkVertical) { testWidth -= padding; } testHeight -= padding; // if we require a power of two texture, find the next power of two that can fit this image if (requirePow2) { testWidth = MiscHelper.FindNextPowerOfTwo(testWidth); testHeight = MiscHelper.FindNextPowerOfTwo(testHeight); } // if we require a square texture, set the width and height to the larger of the two if (requireSquare) { int max = Math.Max(testWidth, testHeight); testWidth = testHeight = max; } // if the test results are the same as our last output results, we've reached an optimal size, // so we can just be done if (testWidth == outputWidth && testHeight == outputHeight) { if (shrinkVertical) { return(true); } shrinkVertical = true; } // save the test results as our last known good results outputWidth = testWidth; outputHeight = testHeight; // subtract the smallest image size out for the next test iteration if (!shrinkVertical) { testWidth -= smallestWidth; } testHeight -= smallestHeight; } }