зеркало из https://github.com/mozilla/pjs.git
b=494901 textbox misaligned when using align=baseline r=dbaron
--HG-- extra : rebase_source : 6322f30a5eabd9c4662a1cc817dde8abaecacaaa
This commit is contained in:
Родитель
1207213155
Коммит
790c69b995
|
@ -10,6 +10,7 @@ HTTP(..) == input-text-baseline-1.html input-text-baseline-1-ref.html
|
|||
HTTP(..) == input-text-centering-1.xul input-text-centering-1-ref.xul
|
||||
HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html
|
||||
== input-text-dynamic-height-1.xul input-text-dynamic-height-1-ref.xul
|
||||
== textbox-align-baseline-1.xul textbox-align-baseline-1-ref.xul # bug 494901
|
||||
|
||||
== radio-label-dynamic.html radio-label-dynamic-ref.html
|
||||
== out-of-bounds-selectedindex.html out-of-bounds-selectedindex-ref.html # bug 471741
|
||||
|
|
|
@ -934,8 +934,10 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& aState)
|
|||
aState.SetLayoutFlags(0);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (mLayoutManager)
|
||||
if (mLayoutManager) {
|
||||
CoordNeedsRecalc(mAscent);
|
||||
rv = mLayoutManager->Layout(this, aState);
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(oldFlags);
|
||||
|
||||
|
|
|
@ -241,8 +241,6 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
nsBoxSize* boxSizes = nsnull;
|
||||
nsComputedBoxSize* computedBoxSizes = nsnull;
|
||||
|
||||
nscoord maxAscent = aBox->GetBoxAscent(aState);
|
||||
|
||||
nscoord min = 0;
|
||||
nscoord max = 0;
|
||||
PRInt32 flexes = 0;
|
||||
|
@ -415,33 +413,26 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
if (childRect.height > clientRect.height)
|
||||
clientRect.height = childRect.height;
|
||||
|
||||
// |x|, |y|, |nextX|, and |nextY| are updated by this function call. This call
|
||||
// also deals with box ALIGNMENT (when stretching is not turned on).
|
||||
ComputeChildsNextPosition(aBox,
|
||||
x,
|
||||
y,
|
||||
nextX,
|
||||
nextY,
|
||||
childRect,
|
||||
originalClientRect,
|
||||
childBoxSize->ascent,
|
||||
maxAscent);
|
||||
// Either |nextX| or |nextY| is updated by this function call, according
|
||||
// to our axis.
|
||||
ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect);
|
||||
|
||||
// Now we update our nextX/Y along our axis and we update our x/y along the opposite
|
||||
// axis (since a non-stretching alignment could have caused an adjustment).
|
||||
// Now we further update our nextX/Y along our axis.
|
||||
// We also set childRect.y/x along the opposite axis appropriately for a
|
||||
// stretch alignment. (Non-stretch alignment is handled below.)
|
||||
if (frameState & NS_STATE_IS_HORIZONTAL) {
|
||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||
nextX += (childBoxSize->right);
|
||||
else
|
||||
nextX -= (childBoxSize->left);
|
||||
childRect.y = y;
|
||||
childRect.y = originalClientRect.y;
|
||||
}
|
||||
else {
|
||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||
nextY += (childBoxSize->right);
|
||||
else
|
||||
nextY -= (childBoxSize->left);
|
||||
childRect.x = x;
|
||||
childRect.x = originalClientRect.x;
|
||||
}
|
||||
|
||||
// If we encounter a completely bogus box size, we just leave this child completely
|
||||
|
@ -478,14 +469,25 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
layout = PR_FALSE;
|
||||
}
|
||||
|
||||
nsRect oldRect(child->GetRect());
|
||||
|
||||
// Non-stretch alignment will be handled in AlignChildren(), so don't
|
||||
// change child out-of-axis positions yet.
|
||||
if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
if (frameState & NS_STATE_IS_HORIZONTAL) {
|
||||
childRect.y = oldRect.y;
|
||||
} else {
|
||||
childRect.x = oldRect.x;
|
||||
}
|
||||
}
|
||||
|
||||
// We computed a childRect. Now we want to set the bounds of the child to be that rect.
|
||||
// If our old rect is different, then we know our size changed and we cache that fact
|
||||
// in the |sizeChanged| variable.
|
||||
nsRect oldRect(child->GetRect());
|
||||
PRBool sizeChanged = PR_FALSE;
|
||||
|
||||
child->SetBounds(aState, childRect);
|
||||
sizeChanged = (childRect.width != oldRect.width || childRect.height != oldRect.height);
|
||||
PRBool sizeChanged = (childRect.width != oldRect.width ||
|
||||
childRect.height != oldRect.height);
|
||||
|
||||
if (sizeChanged) {
|
||||
// Our size is different. Sanity check against our maximum allowed size to ensure
|
||||
|
@ -570,23 +572,8 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
}
|
||||
|
||||
// If the child resized then recompute its position.
|
||||
ComputeChildsNextPosition(aBox,
|
||||
x,
|
||||
y,
|
||||
nextX,
|
||||
nextY,
|
||||
newChildRect,
|
||||
originalClientRect,
|
||||
childBoxSize->ascent,
|
||||
maxAscent);
|
||||
ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect);
|
||||
|
||||
// Only update the variable in the opposite axis (since this is only here to deal with
|
||||
// a non-stretching ALIGNMENT)
|
||||
if (frameState & NS_STATE_IS_HORIZONTAL)
|
||||
newChildRect.y = y;
|
||||
else
|
||||
newChildRect.x = x;
|
||||
|
||||
if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom)
|
||||
newChildRect.Deflate(margin);
|
||||
|
||||
|
@ -676,6 +663,11 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
}
|
||||
}
|
||||
|
||||
// Perform out-of-axis alignment for non-stretch alignments
|
||||
if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
AlignChildren(aBox, aState, &needsRedraw);
|
||||
}
|
||||
|
||||
// Now do our redraw.
|
||||
if (needsRedraw)
|
||||
aBox->Redraw(aState);
|
||||
|
@ -879,7 +871,6 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
|||
aMaxSize = maxSize.height;
|
||||
}
|
||||
|
||||
currentBox->ascent = ascent;
|
||||
currentBox->collapsed = collapsed;
|
||||
aFlexes += currentBox->flex;
|
||||
|
||||
|
@ -934,77 +925,126 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
|||
|
||||
void
|
||||
nsSprocketLayout::ComputeChildsNextPosition(nsIBox* aBox,
|
||||
nscoord& aCurX,
|
||||
nscoord& aCurY,
|
||||
const nscoord& aCurX,
|
||||
const nscoord& aCurY,
|
||||
nscoord& aNextX,
|
||||
nscoord& aNextY,
|
||||
const nsRect& aCurrentChildSize,
|
||||
const nsRect& aBoxRect,
|
||||
nscoord childAscent,
|
||||
nscoord aMaxAscent)
|
||||
const nsRect& aCurrentChildSize)
|
||||
{
|
||||
// Get the position along the box axis for the child.
|
||||
// The out-of-axis position is not set.
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
|
||||
nsIBox::Halignment halign = aBox->GetHAlign();
|
||||
nsIBox::Valignment valign = aBox->GetVAlign();
|
||||
|
||||
if (IsHorizontal(aBox)) {
|
||||
// Handle alignment of a horizontal box's children.
|
||||
// horizontal box's children.
|
||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||
aNextX = aCurX + aCurrentChildSize.width;
|
||||
else aNextX = aCurX - aCurrentChildSize.width;
|
||||
else
|
||||
aNextX = aCurX - aCurrentChildSize.width;
|
||||
|
||||
if (frameState & NS_STATE_AUTO_STRETCH)
|
||||
aCurY = aBoxRect.y;
|
||||
else {
|
||||
switch (valign)
|
||||
{
|
||||
case nsBoxFrame::vAlign_BaseLine:
|
||||
aCurY = aBoxRect.y + (aMaxAscent - childAscent);
|
||||
break;
|
||||
|
||||
case nsBoxFrame::vAlign_Top:
|
||||
aCurY = aBoxRect.y;
|
||||
break;
|
||||
case nsBoxFrame::vAlign_Middle:
|
||||
aCurY = aBoxRect.y + (aBoxRect.height/2 - aCurrentChildSize.height/2);
|
||||
break;
|
||||
case nsBoxFrame::vAlign_Bottom:
|
||||
aCurY = aBoxRect.y + aBoxRect.height - aCurrentChildSize.height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle alignment of a vertical box's children.
|
||||
// vertical box's children.
|
||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||
aNextY = aCurY + aCurrentChildSize.height;
|
||||
else
|
||||
aNextY = aCurY - aCurrentChildSize.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (frameState & NS_STATE_AUTO_STRETCH)
|
||||
aCurX = aBoxRect.x;
|
||||
else {
|
||||
PRUint8 frameDirection = GetFrameDirection(aBox);
|
||||
switch (halign)
|
||||
{
|
||||
case nsBoxFrame::hAlign_Left:
|
||||
if (frameDirection == NS_STYLE_DIRECTION_LTR)
|
||||
aCurX = aBoxRect.x;
|
||||
else
|
||||
aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
|
||||
break;
|
||||
case nsBoxFrame::hAlign_Center:
|
||||
aCurX = aBoxRect.x + (aBoxRect.width/2 - aCurrentChildSize.width/2);
|
||||
break;
|
||||
case nsBoxFrame::hAlign_Right:
|
||||
if (frameDirection == NS_STYLE_DIRECTION_LTR)
|
||||
aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
|
||||
else
|
||||
aCurX = aBoxRect.x;
|
||||
break;
|
||||
}
|
||||
void
|
||||
nsSprocketLayout::AlignChildren(nsIBox* aBox,
|
||||
nsBoxLayoutState& aState,
|
||||
PRBool* aNeedsRedraw)
|
||||
{
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
PRBool isHorizontal = (frameState & NS_STATE_IS_HORIZONTAL) != 0;
|
||||
nsRect clientRect;
|
||||
aBox->GetClientRect(clientRect);
|
||||
|
||||
NS_PRECONDITION(!(frameState & NS_STATE_AUTO_STRETCH),
|
||||
"Only AlignChildren() with non-stretch alignment");
|
||||
|
||||
// These are only calculated if needed
|
||||
nsIBox::Halignment halign;
|
||||
nsIBox::Valignment valign;
|
||||
nscoord maxAscent;
|
||||
PRBool isLTR;
|
||||
|
||||
if (isHorizontal) {
|
||||
valign = aBox->GetVAlign();
|
||||
if (valign == nsBoxFrame::vAlign_BaseLine) {
|
||||
maxAscent = aBox->GetBoxAscent(aState);
|
||||
}
|
||||
} else {
|
||||
isLTR = GetFrameDirection(aBox) == NS_STYLE_DIRECTION_LTR;
|
||||
halign = aBox->GetHAlign();
|
||||
}
|
||||
|
||||
nsIBox* child = aBox->GetChildBox();
|
||||
while (child) {
|
||||
|
||||
nsMargin margin;
|
||||
child->GetMargin(margin);
|
||||
nsRect childRect = child->GetRect();
|
||||
|
||||
if (isHorizontal) {
|
||||
const nscoord startAlign = clientRect.y + margin.top;
|
||||
const nscoord endAlign =
|
||||
clientRect.YMost() - margin.bottom - childRect.height;
|
||||
|
||||
nscoord y;
|
||||
switch (valign) {
|
||||
case nsBoxFrame::vAlign_Top:
|
||||
y = startAlign;
|
||||
break;
|
||||
case nsBoxFrame::vAlign_Middle:
|
||||
// Should this center the border box?
|
||||
// This centers the margin box, the historical behavior.
|
||||
y = (startAlign + endAlign) / 2;
|
||||
break;
|
||||
case nsBoxFrame::vAlign_Bottom:
|
||||
y = endAlign;
|
||||
break;
|
||||
case nsBoxFrame::vAlign_BaseLine:
|
||||
// Alignments don't force the box to grow (only sizes do),
|
||||
// so keep the children within the box.
|
||||
y = maxAscent - child->GetBoxAscent(aState);
|
||||
y = NS_MAX(startAlign, y);
|
||||
y = NS_MIN(y, endAlign);
|
||||
break;
|
||||
}
|
||||
|
||||
childRect.y = y;
|
||||
|
||||
} else { // vertical box
|
||||
const nscoord leftAlign = clientRect.x + margin.left;
|
||||
const nscoord rightAlign =
|
||||
clientRect.XMost() - margin.right - childRect.width;
|
||||
|
||||
nscoord x;
|
||||
switch (halign) {
|
||||
case nsBoxFrame::hAlign_Left: // start
|
||||
x = isLTR ? leftAlign : rightAlign;
|
||||
break;
|
||||
case nsBoxFrame::hAlign_Center:
|
||||
x = (leftAlign + rightAlign) / 2;
|
||||
break;
|
||||
case nsBoxFrame::hAlign_Right: // end
|
||||
x = isLTR ? rightAlign : leftAlign;
|
||||
break;
|
||||
}
|
||||
|
||||
childRect.x = x;
|
||||
}
|
||||
|
||||
if (childRect.TopLeft() != child->GetPosition()) {
|
||||
*aNeedsRedraw = PR_TRUE;
|
||||
child->SetBounds(aState, childRect);
|
||||
}
|
||||
|
||||
child = child->GetNextBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1530,7 +1570,10 @@ nsSprocketLayout::GetAscent(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
child = child->GetNextBox();
|
||||
}
|
||||
|
||||
return vAscent;
|
||||
nsMargin borderPadding;
|
||||
aBox->GetBorderAndPadding(borderPadding);
|
||||
|
||||
return vAscent + borderPadding.top;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1614,7 +1657,6 @@ nsBoxSize::nsBoxSize()
|
|||
min = 0;
|
||||
max = NS_INTRINSICSIZE;
|
||||
collapsed = PR_FALSE;
|
||||
ascent = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
flex = 0;
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
nscoord pref;
|
||||
nscoord min;
|
||||
nscoord max;
|
||||
nscoord ascent;
|
||||
nscoord flex;
|
||||
nscoord left;
|
||||
nscoord right;
|
||||
|
@ -121,14 +120,11 @@ protected:
|
|||
|
||||
|
||||
void ComputeChildsNextPosition(nsIBox* aBox,
|
||||
nscoord& aCurX,
|
||||
nscoord& aCurY,
|
||||
const nscoord& aCurX,
|
||||
const nscoord& aCurY,
|
||||
nscoord& aNextX,
|
||||
nscoord& aNextY,
|
||||
const nsRect& aChildSize,
|
||||
const nsRect& aContainingRect,
|
||||
nscoord childAscent,
|
||||
nscoord aMaxAscent);
|
||||
const nsRect& aChildSize);
|
||||
|
||||
void ChildResized(nsIBox* aBox,
|
||||
nsBoxLayoutState& aState,
|
||||
|
@ -143,6 +139,10 @@ protected:
|
|||
PRInt32 aFlexes,
|
||||
PRBool& aFinished);
|
||||
|
||||
void AlignChildren(nsIBox* aBox,
|
||||
nsBoxLayoutState& aState,
|
||||
PRBool* aNeedsRedraw);
|
||||
|
||||
virtual void ComputeChildSizes(nsIBox* aBox,
|
||||
nsBoxLayoutState& aState,
|
||||
nscoord& aGivenSize,
|
||||
|
|
Загрузка…
Ссылка в новой задаче