Hi guys :-)
I am currently writing an image packer utility that uses freeimage for loading/saving graphic files.

see screenshots of current version




I have incorporated in my code an updated version of the TPartition class that Nitrogen wrote for his Font Studio (http://www.nitrogen.za.org/projectinfo.asp?id=12) (Thanks Nitrogen!!).

I thought I'd share the updated TPartition unit here.

I have replaced the corner constants with an enumerated type for specifying how to pack the rectangles, added a new option for packing rectangles as horizontal strips, made the Insert method return true or false and the rect as a var parameter, altered variable names, and altered the code formatting (easier to read in my opinion, no offense intended to Nitrogen).

When my image packer is done, I will share it as well

Again, lots of thanks to Nitrogen for sharing the original partition code :-)

You can download the unit from here

http://fpc4gp2x.eonclash.com/downloads/Partitions.pas

I tried pasting it here but using the code and pascal both screwed up the formatting and some of the code

This is how I use the unit:

[pascal]
Type
{................................................. .............................}
TRectangle = Class
Rect : TRect;
Name : AnsiString;
FileName : AnsiString;
Width,Height : Integer;
Index : Integer;
WasInserted : Boolean;
End;
{................................................. .............................}

{................................................. .............................}
<SNIP>
{................................................. .............................}

{................................................. .............................}
Function CompareRectanglesByArea(a,b: Pointer): Integer;
Begin
Result := -1 * ((TRectangle(a).Width * TRectangle(a).Height) - (TRectangle(b).Width * TRectangle(b).Height));
End;
{................................................. .............................}

{................................................. .............................}
Function CompareRectanglesByIndex(a,b: Pointer): Integer;
Begin
Result := TRectangle(a).Index - TRectangle(b).Index;
End;
{................................................. .............................}

{................................................. .............................}
Procedure TForm_MainForm.PackRectangles(x,y,x2,y2: Integer; PackingMode: TPackingMode);
Var
Rectangle : TRectangle;
i : Integer;
Partition : TPartition;
r : TRect;
Begin
If FRectangles.Count <= 0 Then Exit;
Partition := TPartition.Create(x,y,x2,y2,PackingMode);

If PackingMode <> ePackingMode_HorizontalStrips Then
FRectangles.Sort(@CompareRectanglesByArea);
For i := 0 To FRectangles.Count - 1 Do
Begin
Rectangle := TRectangle(FRectangles.Items[i]);
Rectangle.WasInserted := False;
If Partition.Insert(Rectangle.Width,Rectangle.Height, r) Then
Begin
Rectangle.WasInserted := True;
Rectangle.Rect := r;
End;
End;

If PackingMode <> ePackingMode_HorizontalStrips Then
FRectangles.Sort(@CompareRectanglesByIndex);
Partition.Free;
For i := 0 To FRectangles.Count - 1 Do
Begin
Rectangle := TRectangle(FRectangles.Items[i]);
If Rectangle.WasInserted Then
StringGrid_ImagesToPack.Cells[1,i + 1] := ''
Else
StringGrid_ImagesToPack.Cells[1,i + 1] := 'X';
End;
End;
{................................................. .............................}

{................................................. .............................}
[/pascal]

FRectangles is a TList holding a number of the TRectangle classes that I want to pack.

TRectangle.Rect is the rectangle where it was inserted, and TRectangle.WasInserted can be checked for to see if the rectangle was actually inserted.

TRectangle.Index allows me to sort the list by area and then back to the original order.

TRectangle.Width and TRectangle.Height is the width and height of this rectangle to be inserted.

After packing the rectangles I am going through the list and updating a stringgrid showing if the rectangle was inserted or not, but you can do whatever you want with this information of course.

I call the PackRectangles like so:
[pascal]PackRectangles(0,0,FPackedImage.GetWidth,FPackedIm age.GetHeight,PackingMode);[/pascal]

the first 4 parameters are the rectangle (top,left, bottom,right) where I want to attempt to pack the rectangles into; in this case the whole of the specified image dimensions, and the PackingMode is just one of the TPackingMode enums from the TPartition unit.

cheers,
Paul.