40package com.jogamp.opengl.util.packrect;
45 private final int width;
47 private final int yPos;
50 private final List<Rect> rects =
new ArrayList<Rect>();
51 private List<Rect> freeList;
54 static class RectXComparator
implements Comparator<Rect> {
56 public int compare(
final Rect r1,
final Rect r2) {
57 return r1.x() - r2.x();
61 public boolean equals(
final Object obj) {
65 private static final Comparator<Rect> rectXComparator =
new RectXComparator();
67 public Level(
final int width,
final int height,
final int yPos,
final LevelSet holder) {
74 public int w() {
return width; }
75 public int h() {
return height; }
84 if (rect.h() > height) {
86 if (nextAddX + rect.w() > width) {
96 holder.
expand(
this, height, rect.h());
101 if (nextAddX + rect.w() <= width) {
104 nextAddX += rect.w();
109 if (freeList !=
null) {
110 Rect candidate =
null;
111 for (
final Iterator<Rect> iter = freeList.iterator(); iter.hasNext(); ) {
112 final Rect cur = iter.next();
119 if (candidate !=
null) {
121 freeList.remove(candidate);
126 if (candidate.w() > rect.w()) {
127 candidate.
setPosition(candidate.x() + rect.w(), candidate.y());
128 candidate.
setSize(candidate.w() - rect.w(), height);
129 freeList.add(candidate);
142 public boolean remove(
final Rect rect) {
143 if (!rects.remove(rect))
148 if (rect.maxX() + 1 == nextAddX) {
149 nextAddX -= rect.w();
151 if (freeList ==
null) {
152 freeList =
new ArrayList<Rect>();
154 freeList.add(
new Rect(rect.x(), rect.y(), rect.w(), height,
null));
163 return rects.isEmpty();
169 if (rect.h() > height)
171 if (freeList ==
null)
173 int freeListWidth = 0;
174 for (
final Iterator<Rect> iter = freeList.iterator(); iter.hasNext(); ) {
175 final Rect cur = iter.next();
176 freeListWidth += cur.w();
179 freeListWidth += (width - nextAddX);
180 return (freeListWidth >= rect.w());
184 Collections.sort(rects, rectXComparator);
185 int nextCompactionDest = 0;
187 for (
final Iterator<Rect> iter = rects.iterator(); iter.hasNext(); ) {
188 final Rect cur = iter.next();
189 if (cur.x() != nextCompactionDest) {
190 manager.
move(backingStore, cur,
191 backingStore,
new Rect(nextCompactionDest, cur.y(), cur.w(), cur.h(),
null));
194 nextCompactionDest += cur.w();
196 nextAddX = nextCompactionDest;
202 return rects.iterator();
207 for (
final Iterator<Rect> iter = rects.iterator(); iter.hasNext(); ) {
208 final Rect rect = iter.next();
218 for (
int i = 0; i < rects.size(); i++) {
219 final Rect cur = rects.get(i);
222 if (cur.w() != next.w() || cur.h() != next.h())
223 throw new RuntimeException(
"Unexpected disparity in rectangle sizes during updateRectangleReferences");
228 private void coalesceFreeList() {
229 if (freeList ==
null)
231 if (freeList.isEmpty())
235 Collections.sort(freeList, rectXComparator);
237 while (i < freeList.size() - 1) {
238 final Rect r1 = freeList.get(i);
239 final Rect r2 = freeList.get(i+1);
240 if (r1.
maxX() + 1 == r2.x()) {
242 freeList.remove(i+1);
243 r1.
setSize(r1.w() + r2.w(), r1.h());
249 final Rect last = freeList.get(freeList.size() - 1);
250 if (last.maxX() + 1 == nextAddX) {
251 nextAddX -= last.w();
252 freeList.remove(freeList.size() - 1);
254 if (freeList.isEmpty()) {
264 int freeListWidth = 0;
265 for (
final Iterator<Rect> iter = freeList.iterator(); iter.hasNext(); ) {
266 final Rect cur = iter.next();
267 System.err.println(
" Free rectangle at " + cur);
268 freeListWidth += cur.w();
271 System.err.println(
" Remaining free space " + (width - nextAddX));
272 freeListWidth += (width - nextAddX);
273 System.err.println(
" Total free space " + freeListWidth);
Manages a list of Levels; this is the core data structure contained within the RectanglePacker and en...
void expand(final Level level, final int oldHeight, final int newHeight)
boolean canExpand(final Level level, final int height)
Indicates whether it's legal to trivially increase the height of the given Level.
void updateRectangleReferences()
Updates the references to the Rect objects in this Level with the "next locations" of those Rects.
void visit(final RectVisitor visitor)
Visits all Rects contained in this Level.
void compact(final Object backingStore, final BackingStoreManager manager)
boolean couldAllocateIfCompacted(final Rect rect)
Indicates whether this Level could satisfy an allocation request if it were compacted.
boolean isEmpty()
Indicates whether this Level contains no rectangles.
Iterator< Rect > iterator()
boolean add(final Rect rect)
Tries to add the given rectangle to this level only allowing non-disruptive changes like trivial expa...
Level(final int width, final int height, final int yPos, final LevelSet holder)
Represents a rectangular region on the backing store.
void setPosition(final int x, final int y)
boolean canContain(final Rect other)
int maxX()
Returns the maximum x-coordinate contained within this rectangle.
void setSize(final int w, final int h)
This interface must be implemented by the end user and is called in response to events like addition ...
void beginMovement(Object oldBackingStore, Object newBackingStore)
Notification that movement is starting.
void endMovement(Object oldBackingStore, Object newBackingStore)
Notification that movement is ending.
void move(Object oldBackingStore, Rect oldLocation, Object newBackingStore, Rect newLocation)
Tells the manager to move the contents of the given rect from the old location on the old backing sto...
Iteration construct without exposing the internals of the RectanglePacker and without implementing a ...