зеркало из 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(..) == input-text-centering-1.xul input-text-centering-1-ref.xul
|
||||||
HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html
|
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
|
== 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
|
== radio-label-dynamic.html radio-label-dynamic-ref.html
|
||||||
== out-of-bounds-selectedindex.html out-of-bounds-selectedindex-ref.html # bug 471741
|
== out-of-bounds-selectedindex.html out-of-bounds-selectedindex-ref.html # bug 471741
|
||||||
|
|
|
@ -934,8 +934,10 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& aState)
|
||||||
aState.SetLayoutFlags(0);
|
aState.SetLayoutFlags(0);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mLayoutManager)
|
if (mLayoutManager) {
|
||||||
|
CoordNeedsRecalc(mAscent);
|
||||||
rv = mLayoutManager->Layout(this, aState);
|
rv = mLayoutManager->Layout(this, aState);
|
||||||
|
}
|
||||||
|
|
||||||
aState.SetLayoutFlags(oldFlags);
|
aState.SetLayoutFlags(oldFlags);
|
||||||
|
|
||||||
|
|
|
@ -241,8 +241,6 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
||||||
nsBoxSize* boxSizes = nsnull;
|
nsBoxSize* boxSizes = nsnull;
|
||||||
nsComputedBoxSize* computedBoxSizes = nsnull;
|
nsComputedBoxSize* computedBoxSizes = nsnull;
|
||||||
|
|
||||||
nscoord maxAscent = aBox->GetBoxAscent(aState);
|
|
||||||
|
|
||||||
nscoord min = 0;
|
nscoord min = 0;
|
||||||
nscoord max = 0;
|
nscoord max = 0;
|
||||||
PRInt32 flexes = 0;
|
PRInt32 flexes = 0;
|
||||||
|
@ -415,33 +413,26 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
||||||
if (childRect.height > clientRect.height)
|
if (childRect.height > clientRect.height)
|
||||||
clientRect.height = childRect.height;
|
clientRect.height = childRect.height;
|
||||||
|
|
||||||
// |x|, |y|, |nextX|, and |nextY| are updated by this function call. This call
|
// Either |nextX| or |nextY| is updated by this function call, according
|
||||||
// also deals with box ALIGNMENT (when stretching is not turned on).
|
// to our axis.
|
||||||
ComputeChildsNextPosition(aBox,
|
ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect);
|
||||||
x,
|
|
||||||
y,
|
|
||||||
nextX,
|
|
||||||
nextY,
|
|
||||||
childRect,
|
|
||||||
originalClientRect,
|
|
||||||
childBoxSize->ascent,
|
|
||||||
maxAscent);
|
|
||||||
|
|
||||||
// Now we update our nextX/Y along our axis and we update our x/y along the opposite
|
// Now we further update our nextX/Y along our axis.
|
||||||
// axis (since a non-stretching alignment could have caused an adjustment).
|
// 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_HORIZONTAL) {
|
||||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||||
nextX += (childBoxSize->right);
|
nextX += (childBoxSize->right);
|
||||||
else
|
else
|
||||||
nextX -= (childBoxSize->left);
|
nextX -= (childBoxSize->left);
|
||||||
childRect.y = y;
|
childRect.y = originalClientRect.y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||||
nextY += (childBoxSize->right);
|
nextY += (childBoxSize->right);
|
||||||
else
|
else
|
||||||
nextY -= (childBoxSize->left);
|
nextY -= (childBoxSize->left);
|
||||||
childRect.x = x;
|
childRect.x = originalClientRect.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we encounter a completely bogus box size, we just leave this child completely
|
// 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;
|
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.
|
// 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
|
// If our old rect is different, then we know our size changed and we cache that fact
|
||||||
// in the |sizeChanged| variable.
|
// in the |sizeChanged| variable.
|
||||||
nsRect oldRect(child->GetRect());
|
|
||||||
PRBool sizeChanged = PR_FALSE;
|
|
||||||
|
|
||||||
child->SetBounds(aState, childRect);
|
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) {
|
if (sizeChanged) {
|
||||||
// Our size is different. Sanity check against our maximum allowed size to ensure
|
// 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.
|
// If the child resized then recompute its position.
|
||||||
ComputeChildsNextPosition(aBox,
|
ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect);
|
||||||
x,
|
|
||||||
y,
|
|
||||||
nextX,
|
|
||||||
nextY,
|
|
||||||
newChildRect,
|
|
||||||
originalClientRect,
|
|
||||||
childBoxSize->ascent,
|
|
||||||
maxAscent);
|
|
||||||
|
|
||||||
// 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)
|
if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom)
|
||||||
newChildRect.Deflate(margin);
|
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.
|
// Now do our redraw.
|
||||||
if (needsRedraw)
|
if (needsRedraw)
|
||||||
aBox->Redraw(aState);
|
aBox->Redraw(aState);
|
||||||
|
@ -879,7 +871,6 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
||||||
aMaxSize = maxSize.height;
|
aMaxSize = maxSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBox->ascent = ascent;
|
|
||||||
currentBox->collapsed = collapsed;
|
currentBox->collapsed = collapsed;
|
||||||
aFlexes += currentBox->flex;
|
aFlexes += currentBox->flex;
|
||||||
|
|
||||||
|
@ -934,77 +925,126 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
||||||
|
|
||||||
void
|
void
|
||||||
nsSprocketLayout::ComputeChildsNextPosition(nsIBox* aBox,
|
nsSprocketLayout::ComputeChildsNextPosition(nsIBox* aBox,
|
||||||
nscoord& aCurX,
|
const nscoord& aCurX,
|
||||||
nscoord& aCurY,
|
const nscoord& aCurY,
|
||||||
nscoord& aNextX,
|
nscoord& aNextX,
|
||||||
nscoord& aNextY,
|
nscoord& aNextY,
|
||||||
const nsRect& aCurrentChildSize,
|
const nsRect& aCurrentChildSize)
|
||||||
const nsRect& aBoxRect,
|
|
||||||
nscoord childAscent,
|
|
||||||
nscoord aMaxAscent)
|
|
||||||
{
|
{
|
||||||
|
// Get the position along the box axis for the child.
|
||||||
|
// The out-of-axis position is not set.
|
||||||
nsFrameState frameState = 0;
|
nsFrameState frameState = 0;
|
||||||
GetFrameState(aBox, frameState);
|
GetFrameState(aBox, frameState);
|
||||||
|
|
||||||
nsIBox::Halignment halign = aBox->GetHAlign();
|
|
||||||
nsIBox::Valignment valign = aBox->GetVAlign();
|
|
||||||
|
|
||||||
if (IsHorizontal(aBox)) {
|
if (IsHorizontal(aBox)) {
|
||||||
// Handle alignment of a horizontal box's children.
|
// horizontal box's children.
|
||||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||||
aNextX = aCurX + aCurrentChildSize.width;
|
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 {
|
} else {
|
||||||
// Handle alignment of a vertical box's children.
|
// vertical box's children.
|
||||||
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
|
||||||
aNextY = aCurY + aCurrentChildSize.height;
|
aNextY = aCurY + aCurrentChildSize.height;
|
||||||
else
|
else
|
||||||
aNextY = aCurY - aCurrentChildSize.height;
|
aNextY = aCurY - aCurrentChildSize.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (frameState & NS_STATE_AUTO_STRETCH)
|
void
|
||||||
aCurX = aBoxRect.x;
|
nsSprocketLayout::AlignChildren(nsIBox* aBox,
|
||||||
else {
|
nsBoxLayoutState& aState,
|
||||||
PRUint8 frameDirection = GetFrameDirection(aBox);
|
PRBool* aNeedsRedraw)
|
||||||
switch (halign)
|
{
|
||||||
{
|
nsFrameState frameState = 0;
|
||||||
case nsBoxFrame::hAlign_Left:
|
GetFrameState(aBox, frameState);
|
||||||
if (frameDirection == NS_STYLE_DIRECTION_LTR)
|
PRBool isHorizontal = (frameState & NS_STATE_IS_HORIZONTAL) != 0;
|
||||||
aCurX = aBoxRect.x;
|
nsRect clientRect;
|
||||||
else
|
aBox->GetClientRect(clientRect);
|
||||||
aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
|
|
||||||
break;
|
NS_PRECONDITION(!(frameState & NS_STATE_AUTO_STRETCH),
|
||||||
case nsBoxFrame::hAlign_Center:
|
"Only AlignChildren() with non-stretch alignment");
|
||||||
aCurX = aBoxRect.x + (aBoxRect.width/2 - aCurrentChildSize.width/2);
|
|
||||||
break;
|
// These are only calculated if needed
|
||||||
case nsBoxFrame::hAlign_Right:
|
nsIBox::Halignment halign;
|
||||||
if (frameDirection == NS_STYLE_DIRECTION_LTR)
|
nsIBox::Valignment valign;
|
||||||
aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width;
|
nscoord maxAscent;
|
||||||
else
|
PRBool isLTR;
|
||||||
aCurX = aBoxRect.x;
|
|
||||||
break;
|
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();
|
child = child->GetNextBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
return vAscent;
|
nsMargin borderPadding;
|
||||||
|
aBox->GetBorderAndPadding(borderPadding);
|
||||||
|
|
||||||
|
return vAscent + borderPadding.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1614,7 +1657,6 @@ nsBoxSize::nsBoxSize()
|
||||||
min = 0;
|
min = 0;
|
||||||
max = NS_INTRINSICSIZE;
|
max = NS_INTRINSICSIZE;
|
||||||
collapsed = PR_FALSE;
|
collapsed = PR_FALSE;
|
||||||
ascent = 0;
|
|
||||||
left = 0;
|
left = 0;
|
||||||
right = 0;
|
right = 0;
|
||||||
flex = 0;
|
flex = 0;
|
||||||
|
|
|
@ -50,7 +50,6 @@ public:
|
||||||
nscoord pref;
|
nscoord pref;
|
||||||
nscoord min;
|
nscoord min;
|
||||||
nscoord max;
|
nscoord max;
|
||||||
nscoord ascent;
|
|
||||||
nscoord flex;
|
nscoord flex;
|
||||||
nscoord left;
|
nscoord left;
|
||||||
nscoord right;
|
nscoord right;
|
||||||
|
@ -121,14 +120,11 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
void ComputeChildsNextPosition(nsIBox* aBox,
|
void ComputeChildsNextPosition(nsIBox* aBox,
|
||||||
nscoord& aCurX,
|
const nscoord& aCurX,
|
||||||
nscoord& aCurY,
|
const nscoord& aCurY,
|
||||||
nscoord& aNextX,
|
nscoord& aNextX,
|
||||||
nscoord& aNextY,
|
nscoord& aNextY,
|
||||||
const nsRect& aChildSize,
|
const nsRect& aChildSize);
|
||||||
const nsRect& aContainingRect,
|
|
||||||
nscoord childAscent,
|
|
||||||
nscoord aMaxAscent);
|
|
||||||
|
|
||||||
void ChildResized(nsIBox* aBox,
|
void ChildResized(nsIBox* aBox,
|
||||||
nsBoxLayoutState& aState,
|
nsBoxLayoutState& aState,
|
||||||
|
@ -143,6 +139,10 @@ protected:
|
||||||
PRInt32 aFlexes,
|
PRInt32 aFlexes,
|
||||||
PRBool& aFinished);
|
PRBool& aFinished);
|
||||||
|
|
||||||
|
void AlignChildren(nsIBox* aBox,
|
||||||
|
nsBoxLayoutState& aState,
|
||||||
|
PRBool* aNeedsRedraw);
|
||||||
|
|
||||||
virtual void ComputeChildSizes(nsIBox* aBox,
|
virtual void ComputeChildSizes(nsIBox* aBox,
|
||||||
nsBoxLayoutState& aState,
|
nsBoxLayoutState& aState,
|
||||||
nscoord& aGivenSize,
|
nscoord& aGivenSize,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче