public void put(double w,double h,T data){
  if (LOG.isDebuggingFinest()) {
    LOG.finest("Add: " + w + "x"+ h);
  }
  final int cols=widths.size();
  final int rows=heights.size();
  int bestsx=-1;
  int bestsy=-1;
  int bestex=cols - 1;
  int bestey=-1;
  double bestwi;
  double besthi;
  double bestinc;
{
    double i1=computeIncreaseArea(w,Math.max(0,h - theight));
    double i2=computeIncreaseArea(Math.max(0,w - twidth),h);
    if (i1 < i2) {
      bestwi=w;
      besthi=Math.max(0,h - theight);
      bestinc=i1;
    }
 else {
      bestwi=Math.max(0,w - twidth);
      besthi=h;
      bestinc=i2;
    }
  }
  for (int sy=0; sy < rows; sy++) {
    for (int sx=0; sx < cols; sx++) {
      if (usage.get(sy).get(sx) != null) {
        continue;
      }
      double avw=widths.get(sx);
      double avh=heights.get(sy);
      int ex=sx;
      int ey=sy;
      while (avw < w || avh < h) {
        if (avw / avh < w / h) {
          if (avw < w && ex + 1 < cols) {
            boolean ok=true;
            for (int y=sy; y <= ey; y++) {
              if (usage.get(y).get(ex + 1) != null) {
                ok=false;
              }
            }
            if (ok) {
              ex+=1;
              avw+=widths.get(ex);
              continue;
            }
          }
          if (avh < h && ey + 1 < rows) {
            boolean ok=true;
            for (int x=sx; x <= ex; x++) {
              if (usage.get(ey + 1).get(x) != null) {
                ok=false;
              }
            }
            if (ok) {
              ey+=1;
              avh+=heights.get(ey);
              continue;
            }
          }
        }
 else {
          if (avh < h && ey + 1 < rows) {
            boolean ok=true;
            for (int x=sx; x <= ex; x++) {
              if (usage.get(ey + 1).get(x) != null) {
                ok=false;
              }
            }
            if (ok) {
              ey+=1;
              avh+=heights.get(ey);
              continue;
            }
          }
          if (avw < w && ex + 1 < cols) {
            boolean ok=true;
            for (int y=sy; y <= ey; y++) {
              if (usage.get(y).get(ex + 1) != null) {
                ok=false;
              }
            }
            if (ok) {
              ex+=1;
              avw+=widths.get(ex);
              continue;
            }
          }
        }
        break;
      }
      if (avw < w && ex < cols - 1) {
        continue;
      }
      if (avh < h && ey < rows - 1) {
        continue;
      }
      double winc=Math.max(0.0,w - avw);
      double hinc=Math.max(0.0,h - avh);
      double inc=computeIncreaseArea(winc,hinc);
      if (LOG.isDebuggingFinest()) {
        LOG.debugFinest("Candidate: " + sx + ","+ sy+ " - "+ ex+ ","+ ey+ ": "+ avw+ "x"+ avh+ " "+ inc);
      }
      if (inc < bestinc) {
        bestinc=inc;
        bestsx=sx;
        bestsy=sy;
        bestex=ex;
        bestey=ey;
        bestwi=w - avw;
        besthi=h - avh;
      }
      if (inc == 0) {
        break;
      }
    }
    assert assertConsistent();
  }
  if (LOG.isDebuggingFinest()) {
    LOG.debugFinest("Best: " + bestsx + ","+ bestsy+ " - "+ bestex+ ","+ bestey+ " inc: "+ bestwi+ "x"+ besthi+ " "+ bestinc);
  }
  if (bestinc > 0) {
    assert (bestex == cols - 1 || bestey == rows - 1);
    double inc=Math.max(bestwi,besthi * ratio);
    resize(inc);
    put(w,h,data);
    return;
  }
  if (bestwi < 0.0) {
    splitCol(bestex,-bestwi);
    bestwi=0.0;
  }
  if (besthi < 0.0) {
    splitRow(bestey,-besthi);
    besthi=0.0;
  }
  for (int x=bestsx; x <= bestex; x++) {
    for (int y=bestsy; y <= bestey; y++) {
      usage.get(y).set(x,data);
    }
  }
  double xpos=0.0;
  double ypos=0.0;
{
    for (int x=0; x < bestsx; x++) {
      xpos+=widths.get(x);
    }
    for (int y=0; y < bestsy; y++) {
      ypos+=heights.get(y);
    }
  }
  map.put(data,new double[]{xpos,ypos,w,h});
  if (LOG.isDebuggingFinest()) {
    logSizes();
  }
}

public void put ( double w , double h , T data ) { if ( LOG . isDebuggingFinest ( ) ) { LOG . finest ( "Add: " + w + "x" + h ) ; } final int cols = widths . size ( ) ; final int rows = heights . size ( ) ; int bestsx = - 1 ; int bestsy = - 1 ; int bestex = cols - 1 ; int bestey = - 1 ; double bestwi ; double besthi ; double bestinc ; { double i1 = computeIncreaseArea ( w , Math . max ( 0 , h - theight ) ) ; double i2 = computeIncreaseArea ( Math . max ( 0 , w - twidth ) , h ) ; if ( i1 < i2 ) { bestwi = w ; besthi = Math . max ( 0 , h - theight ) ; bestinc = i1 ; } else { bestwi = Math . max ( 0 , w - twidth ) ; besthi = h ; bestinc = i2 ; } } for ( int sy = 0 ; sy < rows ; sy ++ ) { for ( int sx = 0 ; sx < cols ; sx ++ ) { if ( usage . get ( sy ) . get ( sx ) != null ) { continue ; } double avw = widths . get ( sx ) ; double avh = heights . get ( sy ) ; int ex = sx ; int ey = sy ; while ( avw < w || avh < h ) { if ( avw / avh < w / h ) { if ( avw < w && ex + 1 < cols ) { boolean ok = true ; for ( int y = sy ; y <= ey ; y ++ ) { if ( usage . get ( y ) . get ( ex + 1 ) != null ) { ok = false ; } } if ( ok ) { ex += 1 ; avw += widths . get ( ex ) ; continue ; } } if ( avh < h && ey + 1 < rows ) { boolean ok = true ; for ( int x = sx ; x <= ex ; x ++ ) { if ( usage . get ( ey + 1 ) . get ( x ) != null ) { ok = false ; } } if ( ok ) { ey += 1 ; avh += heights . get ( ey ) ; continue ; } } } else { if ( avh < h && ey + 1 < rows ) { boolean ok = true ; for ( int x = sx ; x <= ex ; x ++ ) { if ( usage . get ( ey + 1 ) . get ( x ) != null ) { ok = false ; } } if ( ok ) { ey += 1 ; avh += heights . get ( ey ) ; continue ; } } if ( avw < w && ex + 1 < cols ) { boolean ok = true ; for ( int y = sy ; y <= ey ; y ++ ) { if ( usage . get ( y ) . get ( ex + 1 ) != null ) { ok = false ; } } if ( ok ) { ex += 1 ; avw += widths . get ( ex ) ; continue ; } } } break ; } if ( avw < w && ex < cols - 1 ) { continue ; } if ( avh < h && ey < rows - 1 ) { continue ; } double winc = Math . max ( 0.0 , w - avw ) ; double hinc = Math . max ( 0.0 , h - avh ) ; double inc = computeIncreaseArea ( winc , hinc ) ; if ( LOG . isDebuggingFinest ( ) ) { LOG . debugFinest ( "Candidate: " + sx + "," + sy + " - " + ex + "," + ey + ": " + avw + "x" + avh + " " + inc ) ; } if ( inc < bestinc ) { bestinc = inc ; bestsx = sx ; bestsy = sy ; bestex = ex ; bestey = ey ; bestwi = w - avw ; besthi = h - avh ; } if ( inc == 0 ) { break ; } } assert assertConsistent ( ) ; } if ( LOG . isDebuggingFinest ( ) ) { LOG . debugFinest ( "Best: " + bestsx + "," + bestsy + " - " + bestex + "," + bestey + " inc: " + bestwi + "x" + besthi + " " + bestinc ) ; } if ( bestinc > 0 ) { assert ( bestex == cols - 1 || bestey == rows - 1 ) ; double inc = Math . max ( bestwi , besthi * ratio ) ; resize ( inc ) ; put ( w , h , data ) ; return ; } if ( bestwi < 0.0 ) { splitCol ( bestex , - bestwi ) ; bestwi = 0.0 ; } if ( besthi < 0.0 ) { splitRow ( bestey , - besthi ) ; besthi = 0.0 ; } for ( int x = bestsx ; x <= bestex ; x ++ ) { for ( int y = bestsy ; y <= bestey ; y ++ ) { usage . get ( y ) . set ( x , data ) ; } } double xpos = 0.0 ; double ypos = 0.0 ; { for ( int x = 0 ; x < bestsx ; x ++ ) { xpos += widths . get ( x ) ; } for ( int y = 0 ; y < bestsy ; y ++ ) { ypos += heights . get ( y ) ; } } map . put ( data , new double [ ] { xpos , ypos , w , h } ) ; if ( LOG . isDebuggingFinest ( ) ) { logSizes ( ) ; } }
add a new recangle .
