Replace GetBaseline with GetLogicalBaseline and use logical coordinates in the line position and baseline getters in nsLayoutUtils. Bug 789096, r=jfkthame

This commit is contained in:
Simon Montagu 2014-06-17 05:19:38 -07:00
parent d28c7a452d
commit 36dfc0d94f
35 changed files with 185 additions and 134 deletions

View File

@ -4595,17 +4595,19 @@ nsLayoutUtils::GetCenteredFontBaseline(nsFontMetrics* aFontMetrics,
/* static */ bool
nsLayoutUtils::GetFirstLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
nsLayoutUtils::GetFirstLineBaseline(WritingMode aWritingMode,
const nsIFrame* aFrame, nscoord* aResult)
{
LinePosition position;
if (!GetFirstLinePosition(aFrame, &position))
if (!GetFirstLinePosition(aWritingMode, aFrame, &position))
return false;
*aResult = position.mBaseline;
return true;
}
/* static */ bool
nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
nsLayoutUtils::GetFirstLinePosition(WritingMode aWM,
const nsIFrame* aFrame,
LinePosition* aResult)
{
const nsBlockFrame* block = nsLayoutUtils::GetAsBlock(const_cast<nsIFrame*>(aFrame));
@ -4614,11 +4616,11 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
// so, use the baseline of its first row.
nsIAtom* fType = aFrame->GetType();
if (fType == nsGkAtoms::tableOuterFrame) {
aResult->mTop = 0;
aResult->mBaseline = aFrame->GetBaseline();
aResult->mBStart = 0;
aResult->mBaseline = aFrame->GetLogicalBaseline(aWM);
// This is what we want for the list bullet caller; not sure if
// other future callers will want the same.
aResult->mBottom = aFrame->GetSize().height;
aResult->mBEnd = aFrame->BSize(aWM);
return true;
}
@ -4629,11 +4631,13 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
NS_NOTREACHED("not scroll frame");
}
LinePosition kidPosition;
if (GetFirstLinePosition(sFrame->GetScrolledFrame(), &kidPosition)) {
if (GetFirstLinePosition(aWM,
sFrame->GetScrolledFrame(), &kidPosition)) {
// Consider only the border and padding that contributes to the
// kid's position, not the scrolling, so we get the initial
// position.
*aResult = kidPosition + aFrame->GetUsedBorderAndPadding().top;
*aResult = kidPosition +
aFrame->GetLogicalUsedBorderAndPadding(aWM).BStart(aWM);
return true;
}
return false;
@ -4643,8 +4647,9 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
LinePosition kidPosition;
nsIFrame* kid = aFrame->GetFirstPrincipalChild();
// kid might be a legend frame here, but that's ok.
if (GetFirstLinePosition(kid, &kidPosition)) {
*aResult = kidPosition + kid->GetNormalPosition().y;
if (GetFirstLinePosition(aWM, kid, &kidPosition)) {
*aResult = kidPosition +
kid->GetLogicalNormalPosition(aWM, aFrame->GetSize().width).B(aWM);
return true;
}
return false;
@ -4660,18 +4665,23 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
if (line->IsBlock()) {
nsIFrame *kid = line->mFirstChild;
LinePosition kidPosition;
if (GetFirstLinePosition(kid, &kidPosition)) {
*aResult = kidPosition + kid->GetNormalPosition().y;
if (GetFirstLinePosition(aWM, kid, &kidPosition)) {
//XXX Not sure if this is the correct value to use for container
// width here. It will only be used in vertical-rl layout,
// which we don't have full support and testing for yet.
nscoord containerWidth = line->mContainerWidth;
*aResult = kidPosition +
kid->GetLogicalNormalPosition(aWM, containerWidth).B(aWM);
return true;
}
} else {
// XXX Is this the right test? We have some bogus empty lines
// floating around, but IsEmpty is perhaps too weak.
if (line->BSize() != 0 || !line->IsEmpty()) {
nscoord top = line->BStart();
aResult->mTop = top;
aResult->mBaseline = top + line->GetAscent();
aResult->mBottom = top + line->BSize();
nscoord bStart = line->BStart();
aResult->mBStart = bStart;
aResult->mBaseline = bStart + line->GetLogicalAscent();
aResult->mBEnd = bStart + line->BSize();
return true;
}
}
@ -4680,7 +4690,8 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
}
/* static */ bool
nsLayoutUtils::GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
nsLayoutUtils::GetLastLineBaseline(WritingMode aWM,
const nsIFrame* aFrame, nscoord* aResult)
{
const nsBlockFrame* block = nsLayoutUtils::GetAsBlock(const_cast<nsIFrame*>(aFrame));
if (!block)
@ -4693,21 +4704,24 @@ nsLayoutUtils::GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
if (line->IsBlock()) {
nsIFrame *kid = line->mFirstChild;
nscoord kidBaseline;
if (GetLastLineBaseline(kid, &kidBaseline)) {
nscoord containerWidth = line->mContainerWidth;
if (GetLastLineBaseline(aWM, kid, &kidBaseline)) {
// Ignore relative positioning for baseline calculations
*aResult = kidBaseline + kid->GetNormalPosition().y;
*aResult = kidBaseline +
kid->GetLogicalNormalPosition(aWM, containerWidth).B(aWM);
return true;
} else if (kid->GetType() == nsGkAtoms::scrollFrame) {
// Use the bottom of the scroll frame.
// XXX CSS2.1 really doesn't say what to do here.
*aResult = kid->GetNormalPosition().y + kid->GetRect().height;
*aResult = kid->GetLogicalNormalPosition(aWM, containerWidth).B(aWM) +
kid->BSize(aWM);
return true;
}
} else {
// XXX Is this the right test? We have some bogus empty lines
// floating around, but IsEmpty is perhaps too weak.
if (line->BSize() != 0 || !line->IsEmpty()) {
*aResult = line->BStart() + line->GetAscent();
*aResult = line->BStart() + line->GetLogicalAscent();
return true;
}
}
@ -4716,45 +4730,49 @@ nsLayoutUtils::GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
}
static nscoord
CalculateBlockContentBottom(nsBlockFrame* aFrame)
CalculateBlockContentBEnd(WritingMode aWM, nsBlockFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null ptr");
nscoord contentBottom = 0;
nscoord contentBEnd = 0;
for (nsBlockFrame::line_iterator line = aFrame->begin_lines(),
line_end = aFrame->end_lines();
line != line_end; ++line) {
if (line->IsBlock()) {
nsIFrame* child = line->mFirstChild;
nscoord offset = child->GetNormalPosition().y;
contentBottom = std::max(contentBottom,
nsLayoutUtils::CalculateContentBottom(child) + offset);
nscoord containerWidth = line->mContainerWidth;
nscoord offset =
child->GetLogicalNormalPosition(aWM, containerWidth).B(aWM);
contentBEnd =
std::max(contentBEnd,
nsLayoutUtils::CalculateContentBEnd(aWM, child) + offset);
}
else {
contentBottom = std::max(contentBottom, line->BEnd());
contentBEnd = std::max(contentBEnd, line->BEnd());
}
}
return contentBottom;
return contentBEnd;
}
/* static */ nscoord
nsLayoutUtils::CalculateContentBottom(nsIFrame* aFrame)
nsLayoutUtils::CalculateContentBEnd(WritingMode aWM, nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null ptr");
nscoord contentBottom = aFrame->GetRect().height;
nscoord contentBEnd = aFrame->BSize(aWM);
// We want scrollable overflow rather than visual because this
// calculation is intended to affect layout.
if (aFrame->GetScrollableOverflowRect().height > contentBottom) {
LogicalSize overflowSize(aWM, aFrame->GetScrollableOverflowRect().Size());
if (overflowSize.BSize(aWM) > contentBEnd) {
nsIFrame::ChildListIDs skip(nsIFrame::kOverflowList |
nsIFrame::kExcessOverflowContainersList |
nsIFrame::kOverflowOutOfFlowList);
nsBlockFrame* blockFrame = GetAsBlock(aFrame);
if (blockFrame) {
contentBottom =
std::max(contentBottom, CalculateBlockContentBottom(blockFrame));
contentBEnd =
std::max(contentBEnd, CalculateBlockContentBEnd(aWM, blockFrame));
skip |= nsIFrame::kPrincipalList;
}
nsIFrame::ChildListIterator lists(aFrame);
@ -4763,14 +4781,16 @@ nsLayoutUtils::CalculateContentBottom(nsIFrame* aFrame)
nsFrameList::Enumerator childFrames(lists.CurrentList());
for (; !childFrames.AtEnd(); childFrames.Next()) {
nsIFrame* child = childFrames.get();
nscoord offset = child->GetNormalPosition().y;
contentBottom = std::max(contentBottom,
CalculateContentBottom(child) + offset);
nscoord offset =
child->GetLogicalNormalPosition(aWM,
aFrame->GetSize().width).B(aWM);
contentBEnd = std::max(contentBEnd,
CalculateContentBEnd(aWM, child) + offset);
}
}
}
}
return contentBottom;
return contentBEnd;
}
/* static */ nsIFrame*

View File

@ -65,6 +65,7 @@ namespace mozilla {
class SVGImageContext;
struct IntrinsicSize;
struct ContainerLayerParameters;
class WritingMode;
namespace dom {
class DOMRectList;
class Element;
@ -1360,7 +1361,8 @@ public:
* Returns true if a baseline was found (and fills in aResult).
* Otherwise returns false.
*/
static bool GetFirstLineBaseline(const nsIFrame* aFrame, nscoord* aResult);
static bool GetFirstLineBaseline(mozilla::WritingMode aWritingMode,
const nsIFrame* aFrame, nscoord* aResult);
/**
* Just like GetFirstLineBaseline, except also returns the top and
@ -1370,17 +1372,18 @@ public:
* Otherwise returns false.
*/
struct LinePosition {
nscoord mTop, mBaseline, mBottom;
nscoord mBStart, mBaseline, mBEnd;
LinePosition operator+(nscoord aOffset) const {
LinePosition result;
result.mTop = mTop + aOffset;
result.mBStart = mBStart + aOffset;
result.mBaseline = mBaseline + aOffset;
result.mBottom = mBottom + aOffset;
result.mBEnd = mBEnd + aOffset;
return result;
}
};
static bool GetFirstLinePosition(const nsIFrame* aFrame,
static bool GetFirstLinePosition(mozilla::WritingMode aWritingMode,
const nsIFrame* aFrame,
LinePosition* aResult);
@ -1392,17 +1395,20 @@ public:
* Returns true if a baseline was found (and fills in aResult).
* Otherwise returns false.
*/
static bool GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult);
static bool GetLastLineBaseline(mozilla::WritingMode aWritingMode,
const nsIFrame* aFrame, nscoord* aResult);
/**
* Returns a y coordinate relative to this frame's origin that represents
* the logical bottom of the frame or its visible content, whichever is lower.
* Returns a block-dir coordinate relative to this frame's origin that
* represents the logical block-end of the frame or its visible content,
* whichever is further from the origin.
* Relative positioning is ignored and margins and glyph bounds are not
* considered.
* This value will be >= mRect.height() and <= overflowRect.YMost() unless
* This value will be >= mRect.BSize() and <= overflowRect.BEnd() unless
* relative positioning is applied.
*/
static nscoord CalculateContentBottom(nsIFrame* aFrame);
static nscoord CalculateContentBEnd(mozilla::WritingMode aWritingMode,
nsIFrame* aFrame);
/**
* Gets the closest frame (the frame passed in or one of its parents) that

View File

@ -585,8 +585,9 @@ nsFieldSetFrame::AccessibleType()
#endif
nscoord
nsFieldSetFrame::GetBaseline() const
nsFieldSetFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
nsIFrame* inner = GetInner();
return inner->GetPosition().y + inner->GetBaseline();
return inner->BStart(aWritingMode, GetParent()->GetSize().width) +
inner->GetLogicalBaseline(aWritingMode);
}

View File

@ -25,7 +25,7 @@ public:
nsSize aCBSize, nscoord aAvailableWidth,
nsSize aMargin, nsSize aBorder, nsSize aPadding,
uint32_t aFlags) MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
/**
* The area to paint box-shadows around. It's the border rect except

View File

@ -63,14 +63,15 @@ nsFormControlFrame::GetIntrinsicHeight()
}
nscoord
nsFormControlFrame::GetBaseline() const
nsFormControlFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
NS_ASSERTION(!NS_SUBTREE_DIRTY(this),
"frame must not be dirty");
// Treat radio buttons and checkboxes as having an intrinsic baseline
// at the bottom of the control (use the bottom content edge rather
// than the bottom margin edge).
return mRect.height - GetUsedBorderAndPadding().bottom;
return BSize(aWritingMode) -
GetLogicalUsedBorderAndPadding(aWritingMode).BEnd(aWritingMode);
}
void

View File

@ -45,7 +45,8 @@ public:
mozilla::WidgetGUIEvent* aEvent,
nsEventStatus* aEventStatus) MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode)
const MOZ_OVERRIDE;
/**
* Respond to the request to resize and/or reflow

View File

@ -333,7 +333,8 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
// Make sure we have a useful 'ascent' value for the child
if (contentsDesiredSize.BlockStartAscent() ==
nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
contentsDesiredSize.SetBlockStartAscent(aFirstKid->GetBaseline());
WritingMode wm = aButtonReflowState.GetWritingMode();
contentsDesiredSize.SetBlockStartAscent(aFirstKid->GetLogicalBaseline(wm));
}
// OK, we're done with the child frame.

View File

@ -714,6 +714,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
if (aCreateLeft) {
DisplayListClipState::AutoSaveRestore clipState(mBuilder);
//XXX Needs vertical text love
nsRect markerRect = nsRect(aInsideMarkersArea.x - mLeft.mIntrinsicWidth,
aLine->BStart(),
mLeft.mIntrinsicWidth, aLine->BSize());
@ -722,7 +723,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
markerRect, clipState);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
aLine->GetAscent(), mLeft.mStyle, 0);
aLine->GetLogicalAscent(), mLeft.mStyle, 0);
mMarkerList.AppendNewToTop(marker);
}
@ -737,7 +738,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
markerRect, clipState);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
aLine->GetAscent(), mRight.mStyle, 1);
aLine->GetLogicalAscent(), mRight.mStyle, 1);
mMarkerList.AppendNewToTop(marker);
}
}

View File

@ -46,7 +46,7 @@ public:
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
{
@ -193,7 +193,7 @@ BRFrame::GetType() const
}
nscoord
BRFrame::GetBaseline() const
BRFrame::GetLogicalBaseline(mozilla::WritingMode aWritingMode) const
{
return mAscent;
}

View File

@ -488,12 +488,12 @@ nsBlockFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItem
}
nscoord
nsBlockFrame::GetBaseline() const
nsBlockFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
nscoord result;
if (nsLayoutUtils::GetLastLineBaseline(this, &result))
if (nsLayoutUtils::GetLastLineBaseline(aWritingMode, this, &result))
return result;
return nsFrame::GetBaseline();
return nsFrame::GetLogicalBaseline(aWritingMode);
}
nscoord
@ -1187,12 +1187,14 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// XXX Use the entire line when we fix bug 25888.
nsLayoutUtils::LinePosition position;
WritingMode wm = aReflowState.GetWritingMode();
bool havePosition = nsLayoutUtils::GetFirstLinePosition(this, &position);
nscoord lineTop = havePosition ? position.mTop
: reflowState->ComputedPhysicalBorderPadding().top;
bool havePosition = nsLayoutUtils::GetFirstLinePosition(wm, this,
&position);
nscoord lineTop = havePosition ?
position.mBStart :
reflowState->ComputedLogicalBorderPadding().BStart(wm);
nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, state, metrics, lineTop);
NS_ASSERTION(!BulletIsEmpty() || metrics.Height() == 0,
NS_ASSERTION(!BulletIsEmpty() || metrics.BSize(wm) == 0,
"empty bullet took up space");
if (havePosition && !BulletIsEmpty()) {
@ -2461,7 +2463,8 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
if (metrics.BlockStartAscent() == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
nscoord ascent;
if (nsLayoutUtils::GetFirstLineBaseline(bullet, &ascent)) {
WritingMode wm = aState.mReflowState.GetWritingMode();
if (nsLayoutUtils::GetFirstLineBaseline(wm, bullet, &ascent)) {
metrics.SetBlockStartAscent(ascent);
} else {
metrics.SetBlockStartAscent(metrics.BSize(wm));

View File

@ -121,7 +121,7 @@ public:
nsIFrame* aOldFrame) MOZ_OVERRIDE;
virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual nscoord GetCaretBaseline() const MOZ_OVERRIDE;
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;

View File

@ -781,11 +781,11 @@ nsBulletFrame::GetImage() const
}
nscoord
nsBulletFrame::GetBaseline() const
nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
nscoord ascent = 0, bottomPadding;
if (GetStateBits() & BULLET_FRAME_IMAGE_LOADING) {
ascent = GetRect().height;
ascent = BSize(aWritingMode);
} else {
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
@ -820,7 +820,8 @@ nsBulletFrame::GetBaseline() const
break;
}
}
return ascent + GetUsedBorderAndPadding().top;
return ascent +
GetLogicalUsedMargin(aWritingMode).BStart(aWritingMode);
}
void

View File

@ -86,7 +86,7 @@ public:
virtual bool IsEmpty() MOZ_OVERRIDE;
virtual bool IsSelfEmpty() MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
float GetFontSizeInflation() const;
bool HasFontSizeInflation() const {

View File

@ -464,7 +464,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
}
}
int columnCount = 0;
int contentBottom = 0;
int contentBEnd = 0;
bool reflowNext = false;
while (child) {
@ -494,7 +494,8 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
bool skipResizeHeightShrink = shrinkingHeightOnly
&& child->GetScrollableOverflowRect().YMost() <= aConfig.mColMaxHeight;
nscoord childContentBottom = 0;
nscoord childContentBEnd = 0;
WritingMode wm = child->GetWritingMode();
if (!reflowNext && (skipIncremental || skipResizeHeightShrink)) {
// This child does not need to be reflowed, but we may need to move it
MoveChildTo(this, child, childOrigin);
@ -508,7 +509,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
} else {
aStatus = mLastFrameStatus;
}
childContentBottom = nsLayoutUtils::CalculateContentBottom(child);
childContentBEnd = nsLayoutUtils::CalculateContentBEnd(wm, child);
#ifdef DEBUG_roc
printf("*** Skipping child #%d %p (incremental %d, resize height shrink %d): status = %d\n",
columnCount, (void*)child, skipIncremental, skipResizeHeightShrink, aStatus);
@ -547,8 +548,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
kidReflowState.mFlags.mNextInFlowUntouched = true;
}
nsHTMLReflowMetrics kidDesiredSize(aReflowState.GetWritingMode(),
aDesiredSize.mFlags);
nsHTMLReflowMetrics kidDesiredSize(wm, aDesiredSize.mFlags);
// XXX it would be cool to consult the float manager for the
// previous block to figure out the region of floats from the
@ -578,12 +578,12 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
FinishReflowChild(child, PresContext(), kidDesiredSize,
&kidReflowState, childOrigin.x, childOrigin.y, 0);
childContentBottom = nsLayoutUtils::CalculateContentBottom(child);
if (childContentBottom > aConfig.mColMaxHeight) {
childContentBEnd = nsLayoutUtils::CalculateContentBEnd(wm, child);
if (childContentBEnd > aConfig.mColMaxHeight) {
allFit = false;
}
if (childContentBottom > availSize.height) {
aColData.mMaxOverflowingHeight = std::max(childContentBottom,
if (childContentBEnd > availSize.height) {
aColData.mMaxOverflowingHeight = std::max(childContentBEnd,
aColData.mMaxOverflowingHeight);
}
}
@ -591,9 +591,9 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
contentRect.UnionRect(contentRect, child->GetRect());
ConsiderChildOverflow(overflowRects, child);
contentBottom = std::max(contentBottom, childContentBottom);
aColData.mLastHeight = childContentBottom;
aColData.mSumHeight += childContentBottom;
contentBEnd = std::max(contentBEnd, childContentBEnd);
aColData.mLastHeight = childContentBEnd;
aColData.mSumHeight += childContentBEnd;
// Build a continuation column if necessary
nsIFrame* kidNextInFlow = child->GetNextInFlow();
@ -637,8 +637,8 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
kidNextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if ((contentBottom > aReflowState.ComputedMaxHeight() ||
contentBottom > aReflowState.ComputedHeight()) &&
if ((contentBEnd > aReflowState.ComputedMaxBSize() ||
contentBEnd > aReflowState.ComputedBSize()) &&
aConfig.mBalanceColCount < INT32_MAX) {
// We overflowed vertically, but have not exceeded the number of
// columns. We're going to go into overflow columns now, so balancing
@ -702,8 +702,8 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
}
}
aColData.mMaxHeight = contentBottom;
contentRect.height = std::max(contentRect.height, contentBottom);
aColData.mMaxHeight = contentBEnd;
contentRect.height = std::max(contentRect.height, contentBEnd);
mLastFrameStatus = aStatus;
// contentRect included the borderPadding.left,borderPadding.top of the child rects

View File

@ -373,7 +373,7 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
}
nscoord
nsFirstLetterFrame::GetBaseline() const
nsFirstLetterFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
return mBaseline;
}

View File

@ -59,7 +59,7 @@ public:
nsReflowStatus& aStatus) MOZ_OVERRIDE;
virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
//override of nsFrame method

View File

@ -2911,14 +2911,15 @@ static void
ResolveReflowedChildAscent(nsIFrame* aFrame,
nsHTMLReflowMetrics& aChildDesiredSize)
{
WritingMode wm = aChildDesiredSize.GetWritingMode();
if (aChildDesiredSize.BlockStartAscent() ==
nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
// Use GetFirstLineBaseline(), or just GetBaseline() if that fails.
nscoord ascent;
if (nsLayoutUtils::GetFirstLineBaseline(aFrame, &ascent)) {
if (nsLayoutUtils::GetFirstLineBaseline(wm, aFrame, &ascent)) {
aChildDesiredSize.SetBlockStartAscent(ascent);
} else {
aChildDesiredSize.SetBlockStartAscent(aFrame->GetBaseline());
aChildDesiredSize.SetBlockStartAscent(aFrame->GetLogicalBaseline(wm));
}
}
}

View File

@ -1353,13 +1353,14 @@ nsFrame::SetAdditionalStyleContext(int32_t aIndex,
}
nscoord
nsFrame::GetBaseline() const
nsFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
NS_ASSERTION(!NS_SUBTREE_DIRTY(this),
"frame must not be dirty");
// Default to the bottom margin edge, per CSS2.1's definition of the
// 'baseline' value of 'vertical-align'.
return mRect.height + GetUsedMargin().bottom;
return BSize(aWritingMode) +
GetLogicalUsedMargin(aWritingMode).BEnd(aWritingMode);
}
const nsFrameList&
@ -7944,8 +7945,9 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState)
if (desiredSize.BlockStartAscent() ==
nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
if (!nsLayoutUtils::GetFirstLineBaseline(this, &metrics->mBlockAscent))
metrics->mBlockAscent = GetBaseline();
if (!nsLayoutUtils::GetFirstLineBaseline(wm, this,
&metrics->mBlockAscent))
metrics->mBlockAscent = GetLogicalBaseline(wm);
} else {
metrics->mBlockAscent = desiredSize.BlockStartAscent();
}
@ -8222,7 +8224,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
needsReflow = true;
}
}
// ok now reflow the child into the spacers calculated space
if (needsReflow) {
@ -8375,8 +8377,9 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
} else {
if (aDesiredSize.BlockStartAscent() ==
nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
if (!nsLayoutUtils::GetFirstLineBaseline(this, &metrics->mAscent))
metrics->mAscent = GetBaseline();
WritingMode wm = aDesiredSize.GetWritingMode();
if (!nsLayoutUtils::GetFirstLineBaseline(wm, this, &metrics->mAscent))
metrics->mAscent = GetLogicalBaseline(wm);
} else
metrics->mAscent = aDesiredSize.BlockStartAscent();
}

View File

@ -148,7 +148,7 @@ public:
virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
virtual void SetAdditionalStyleContext(int32_t aIndex,
nsStyleContext* aStyleContext) MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;

View File

@ -980,7 +980,7 @@ public:
* the frame (its top border edge). Only valid when Reflow is not
* needed.
*/
virtual nscoord GetBaseline() const = 0;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const = 0;
/**
* Get the position of the baseline on which the caret needs to be placed,
@ -989,7 +989,7 @@ public:
* caret positioning.
*/
virtual nscoord GetCaretBaseline() const {
return GetBaseline();
return GetLogicalBaseline(GetWritingMode());
}
/**

View File

@ -939,7 +939,7 @@ nsInlineFrame::GetLogicalSkipSides(const nsHTMLReflowState* aReflowState) const
}
nscoord
nsInlineFrame::GetBaseline() const
nsInlineFrame::GetLogicalBaseline(mozilla::WritingMode aWritingMode) const
{
return mBaseline;
}

View File

@ -81,7 +81,7 @@ public:
virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
virtual void PullOverflowsFromPrevInFlow() MOZ_OVERRIDE;
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual bool DrainSelfOverflowList() MOZ_OVERRIDE;
/**

View File

@ -488,15 +488,15 @@ public:
}
/**
* The ascent (distance from top to baseline) of the linebox is the
* ascent of the anonymous inline box (for which we don't actually
* create a frame) that wraps all the consecutive inline children of a
* block.
* The logical ascent (distance from block-start to baseline) of the
* linebox is the logical ascent of the anonymous inline box (for
* which we don't actually create a frame) that wraps all the
* consecutive inline children of a block.
*
* This is currently unused for block lines.
*/
nscoord GetAscent() const { return mAscent; }
void SetAscent(nscoord aAscent) { mAscent = aAscent; }
nscoord GetLogicalAscent() const { return mAscent; }
void SetLogicalAscent(nscoord aAscent) { mAscent = aAscent; }
nscoord BStart() const {
return mBounds.BStart(mWritingMode);

View File

@ -348,7 +348,7 @@ nsLineLayout::UpdateBand(const nsRect& aNewAvailSpace,
}
}
mBStartEdge = aNewAvailSpace.y;
mBStartEdge = availSpace.BStart(lineWM);
mImpactedByFloats = true;
mLastFloatWasLetterFrame = nsGkAtoms::letterFrame == aFloatFrame->GetType();
@ -1292,7 +1292,7 @@ nsLineLayout::PlaceFrame(PerFrameData* pfd, nsHTMLReflowMetrics& aMetrics)
// Record ascent and update max-ascent and max-descent values
if (aMetrics.BlockStartAscent() == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
pfd->mAscent = pfd->mFrame->GetBaseline();
pfd->mAscent = pfd->mFrame->GetLogicalBaseline(lineWM);
} else {
pfd->mAscent = aMetrics.BlockStartAscent();
}
@ -1333,7 +1333,7 @@ nsLineLayout::AddBulletFrame(nsIFrame* aFrame,
mRootSpan->AppendFrame(pfd);
pfd->SetFlag(PFD_ISBULLET, true);
if (aMetrics.BlockStartAscent() == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
pfd->mAscent = aFrame->GetBaseline();
pfd->mAscent = aFrame->GetLogicalBaseline(lineWM);
} else {
pfd->mAscent = aMetrics.BlockStartAscent();
}
@ -1475,13 +1475,13 @@ nsLineLayout::BlockDirAlignLine()
mContainerWidth);
mFinalLineBSize = lineBSize;
mLineBox->SetAscent(baselineBCoord - mBStartEdge);
mLineBox->SetLogicalAscent(baselineBCoord - mBStartEdge);
#ifdef NOISY_BLOCKDIR_ALIGN
printf(
" [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n",
mLineBox->GetBounds().IStart(lineWM), mLineBox->GetBounds().BStart(lineWM),
mLineBox->GetBounds().ISize(lineWM), mLineBox->GetBounds().BSize(lineWM),
mFinalLineBSize, mLineBox->GetAscent());
mFinalLineBSize, mLineBox->GetLogicalAscent());
#endif
// Undo root-span mFrame pointer to prevent brane damage later on...
@ -1913,6 +1913,8 @@ nsLineLayout::BlockDirAlignFrames(PerSpanData* psd)
{
// The top of the logical box is aligned with the top of
// the parent element's text.
// XXX For vertical text we will need a new API to get the logical
// max-ascent here
nscoord parentAscent = fm->MaxAscent();
if (frameSpan) {
pfd->mBounds.BStart(lineWM) = baselineBCoord - parentAscent -

View File

@ -4669,7 +4669,7 @@ nsTextFrame::GetTextDecorations(
// the CSS 2.1 spec that blocks should propagate decorations down to their
// children (albeit the style should be preserved)
// However, if we're vertically aligned within a block, then we need to
// recover the right baseline from the line by querying the FrameProperty
// recover the correct baseline from the line by querying the FrameProperty
// that should be set (see nsLineLayout::VerticalAlignLine).
if (firstBlock) {
// At this point, fChild can't be null since TextFrames can't be blocks
@ -4684,7 +4684,9 @@ nsTextFrame::GetTextDecorations(
}
}
else if (!nearestBlockFound) {
baselineOffset = frameTopOffset - f->GetBaseline();
// use a dummy WritingMode, because nsTextFrame::GetLogicalBaseLine
// doesn't use it anyway
baselineOffset = frameTopOffset - f->GetLogicalBaseline(WritingMode());
}
nearestBlockFound = nearestBlockFound || firstBlock;
@ -8525,7 +8527,7 @@ nsTextFrame::IsAtEndOfLine() const
}
nscoord
nsTextFrame::GetBaseline() const
nsTextFrame::GetLogicalBaseline(WritingMode aWritingMode ) const
{
return mAscent;
}

View File

@ -171,7 +171,7 @@ public:
virtual bool IsEmpty() MOZ_OVERRIDE;
virtual bool IsSelfEmpty() MOZ_OVERRIDE { return IsEmpty(); }
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual bool HasSignificantTerminalNewline() const MOZ_OVERRIDE;

View File

@ -849,11 +849,11 @@ nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
if (aDesiredSize.BlockStartAscent() == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
// This will be suitable for inline frames, which are wrapped in a block.
nscoord ascent;
if (!nsLayoutUtils::GetLastLineBaseline(aChildFrame, &ascent)) {
WritingMode wm = aReflowState.GetWritingMode();
if (!nsLayoutUtils::GetLastLineBaseline(wm, aChildFrame, &ascent)) {
// We don't expect any other block children so just place the frame on
// the baseline instead of going through DidReflow() and
// GetBaseline(). This is what nsFrame::GetBaseline() will do anyway.
WritingMode wm = aReflowState.GetWritingMode();
aDesiredSize.SetBlockStartAscent(aDesiredSize.BSize(wm));
} else {
aDesiredSize.SetBlockStartAscent(ascent);

View File

@ -335,6 +335,9 @@ GetBaselinePosition(nsTextFrame* aFrame,
gfxTextRun* aTextRun,
uint8_t aDominantBaseline)
{
// use a dummy WritingMode, because nsTextFrame::GetLogicalBaseLine
// doesn't use it anyway
WritingMode writingMode;
switch (aDominantBaseline) {
case NS_STYLE_DOMINANT_BASELINE_HANGING:
case NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE:
@ -348,7 +351,7 @@ GetBaselinePosition(nsTextFrame* aFrame,
// (fall through)
case NS_STYLE_DOMINANT_BASELINE_AUTO:
case NS_STYLE_DOMINANT_BASELINE_ALPHABETIC:
return aFrame->GetBaseline();
return aFrame->GetLogicalBaseline(writingMode);
}
gfxTextRun::Metrics metrics =
@ -366,7 +369,7 @@ GetBaselinePosition(nsTextFrame* aFrame,
}
NS_NOTREACHED("unexpected dominant-baseline value");
return aFrame->GetBaseline();
return aFrame->GetLogicalBaseline(writingMode);
}
/**
@ -1069,7 +1072,7 @@ TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext,
gfxFloat ascent, descent;
GetAscentAndDescentInAppUnits(mFrame, ascent, descent);
gfxFloat topEdge = mFrame->GetBaseline() - ascent;
gfxFloat topEdge = mFrame->GetLogicalBaseline(mFrame->GetWritingMode()) - ascent;
gfxFloat bottomEdge = topEdge + ascent + descent;
if (p.y < aContext->AppUnitsToGfxUnits(topEdge) ||

View File

@ -713,7 +713,7 @@ nsTableCellFrame::GetCellBaseline() const
nsIFrame *inner = mFrames.FirstChild();
nscoord borderPadding = GetUsedBorderAndPadding().top;
nscoord result;
if (nsLayoutUtils::GetFirstLineBaseline(inner, &result))
if (nsLayoutUtils::GetFirstLineBaseline(GetWritingMode(), inner, &result))
return result + borderPadding;
return inner->GetContentRect().YMost() - inner->GetPosition().y +
borderPadding;

View File

@ -3527,22 +3527,26 @@ nscoord nsTableFrame::GetCellSpacingY()
/* virtual */ nscoord
nsTableFrame::GetBaseline() const
nsTableFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
nscoord ascent = 0;
RowGroupArray orderedRowGroups;
OrderRowGroups(orderedRowGroups);
nsTableRowFrame* firstRow = nullptr;
// XXX not sure if this should be the width of the containing block instead.
nscoord containerWidth = mRect.width;
for (uint32_t rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
if (rgFrame->GetRowCount()) {
firstRow = rgFrame->GetFirstRow();
ascent = rgFrame->GetRect().y + firstRow->GetRect().y + firstRow->GetRowBaseline();
ascent = rgFrame->BStart(aWritingMode, containerWidth) +
firstRow->BStart(aWritingMode, containerWidth) +
firstRow->GetRowBaseline(aWritingMode);
break;
}
}
if (!firstRow)
ascent = GetRect().height;
ascent = BSize(aWritingMode);
return ascent;
}
/* ----- global methods ----- */

View File

@ -379,7 +379,7 @@ public:
/** helper to get the cell spacing Y style value */
nscoord GetCellSpacingY();
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table. The row span equals the number of rows spanned by aCell starting at
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row

View File

@ -47,15 +47,16 @@ nsTableCaptionFrame::GetType() const
}
/* virtual */ nscoord
nsTableOuterFrame::GetBaseline() const
nsTableOuterFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
nsIFrame* kid = mFrames.FirstChild();
if (!kid) {
NS_NOTREACHED("no inner table");
return nsContainerFrame::GetBaseline();
return nsContainerFrame::GetLogicalBaseline(aWritingMode);
}
return kid->GetBaseline() + kid->GetPosition().y;
return kid->GetLogicalBaseline(aWritingMode) +
kid->BStart(aWritingMode, mRect.width);
}
/* virtual */ nsSize

View File

@ -97,7 +97,7 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
virtual nscoord GetBaseline() const MOZ_OVERRIDE;
virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;

View File

@ -366,7 +366,7 @@ nscoord nsTableRowFrame::GetMaxCellAscent() const
return mMaxCellAscent;
}
nscoord nsTableRowFrame::GetRowBaseline()
nscoord nsTableRowFrame::GetRowBaseline(WritingMode aWritingMode)
{
if(mMaxCellAscent)
return mMaxCellAscent;

View File

@ -122,7 +122,7 @@ public:
/* return the row ascent
*/
nscoord GetRowBaseline();
nscoord GetRowBaseline(mozilla::WritingMode aWritingMode);
/** returns the ordinal position of this row in its table */
virtual int32_t GetRowIndex() const;