struct AdjustData { nsIFrame* frame; PRBool splittable; nsRect bounds; };
nsInlineFrame::AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace){  if (0 >= aExtraSpace) {    aUsedSpace = 0;    return NS_OK;  }  struct AdjustData {    nsIFrame* frame;    PRBool splittable;    nsRect bounds;  };  const int NUM_AD = 50;  AdjustData adjustMem[NUM_AD];  AdjustData* ad0 = adjustMem;  AdjustData* end = ad0 + NUM_AD;  AdjustData* ad = ad0;  PRInt32 numAD = NUM_AD;  // Gather up raw data for justification  nsIFrame* frame = mFirstChild;  PRInt32 fixed = 0;  PRInt32 total = 0;  nscoord fixedWidth = 0;  for (; nsnull != frame; ad++, total++) {    // Grow temporary storage if we have to    if (ad == end) {      AdjustData* newAD = new AdjustData[numAD + numAD];      if (nsnull == newAD) {        if (ad0 != adjustMem) {          delete [] ad0;        }        aUsedSpace = 0;        return NS_OK;      }      nsCRT::memcpy(newAD, ad0, sizeof(AdjustData) * numAD);      ad = newAD + (ad - ad0);      if (ad0 != adjustMem) {        delete [] ad0;      }      ad0 = newAD;      end = ad0 + numAD;      numAD = numAD + numAD;    }    // Record info about the frame    ad->frame = frame;    frame->GetRect(ad->bounds);    nsSplittableType isSplittable = NS_FRAME_NOT_SPLITTABLE;    frame->IsSplittable(isSplittable);    if ((0 == ad->bounds.width) ||        NS_FRAME_IS_NOT_SPLITTABLE(isSplittable)) {      ad->splittable = PR_FALSE;      fixed++;      fixedWidth += ad->bounds.width;    }    else {      ad->splittable = PR_TRUE;    }    // Advance to the next frame    frame->GetNextSibling(frame);  }  nscoord totalUsed = 0;  nscoord variableWidth = mRect.width - fixedWidth;  if (variableWidth > 0) {    // Each variable width frame gets a portion of the available extra    // space that is proportional to the space it takes in the    // line. The extra space is given to the frame by updating its    // position and size. The frame is responsible for adjusting the    // position of its contents on its own (during rendering).    PRInt32 i, splittable = total - fixed;    nscoord extraSpace = aExtraSpace;    nscoord remainingExtra = extraSpace;    nscoord dx = 0;    float lineWidth = float(mRect.width);    ad = ad0;    for (i = 0; i < total; i++, ad++) {      nsIFrame* frame = ad->frame;      nsIHTMLReflow* ihr;      if (NS_OK == frame->QueryInterface(kIHTMLReflowIID, (void**)&ihr)) {        nsRect r;        if (ad->splittable && (ad->bounds.width > 0)) {          float pctOfLine = float(ad->bounds.width) / lineWidth;          nscoord extra = nscoord(pctOfLine * extraSpace);          if (--splittable == 0) {            extra = remainingExtra;          }          if (0 != extra) {            nscoord used;            ihr->AdjustFrameSize(extra, used);            if (used < extra) {//              frame->ListTag(); printf(": extra=%d used=%d\n", extra, used);            }            totalUsed += used;            frame->GetRect(r);            r.x += dx;            frame->SetRect(r);            dx += used;            remainingExtra -= used;          }          else if (0 != dx) {            frame->GetRect(r);            r.x += dx;            frame->SetRect(r);          }        }        else if (0 != dx) {          frame->GetRect(r);          r.x += dx;          frame->SetRect(r);        }      }    }  }  mRect.width += totalUsed;  aUsedSpace = totalUsed;  if (ad0 != adjustMem) {    delete [] ad0;  }  return NS_OK;}