зеркало из https://github.com/mozilla/pjs.git
For continuous background inlines, apply the background image to bidi continuations in visual order, and for RTL blocks, in RTL order. bug=412093 r+sr+a1.9=roc
This commit is contained in:
Родитель
134ef9c98c
Коммит
aee0c8874b
|
@ -69,6 +69,7 @@
|
|||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsBlockFrame.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
|
||||
|
@ -106,7 +107,7 @@ enum ePathTypes{
|
|||
struct InlineBackgroundData
|
||||
{
|
||||
InlineBackgroundData()
|
||||
: mFrame(nsnull)
|
||||
: mFrame(nsnull), mBlockFrame(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -117,18 +118,64 @@ struct InlineBackgroundData
|
|||
void Reset()
|
||||
{
|
||||
mBoundingBox.SetRect(0,0,0,0);
|
||||
mContinuationPoint = mUnbrokenWidth = 0;
|
||||
mFrame = nsnull;
|
||||
mContinuationPoint = mLineContinuationPoint = mUnbrokenWidth = 0;
|
||||
mFrame = mBlockFrame = nsnull;
|
||||
}
|
||||
|
||||
nsRect GetContinuousRect(nsIFrame* aFrame)
|
||||
{
|
||||
SetFrame(aFrame);
|
||||
|
||||
nscoord x;
|
||||
if (mBidiEnabled) {
|
||||
x = mLineContinuationPoint;
|
||||
|
||||
// Scan continuations on the same line as aFrame and accumulate the widths
|
||||
// of frames that are to the left (if this is an LTR block) or right
|
||||
// (if it's RTL) of the current one.
|
||||
PRBool isRtlBlock = (mBlockFrame->GetStyleVisibility()->mDirection ==
|
||||
NS_STYLE_DIRECTION_RTL);
|
||||
nscoord curOffset = aFrame->GetOffsetTo(mBlockFrame).x;
|
||||
|
||||
nsIFrame* inlineFrame = aFrame->GetPrevContinuation();
|
||||
// If the continuation is fluid we know inlineFrame is not on the same line.
|
||||
// If it's not fluid, we need to test furhter to be sure.
|
||||
while (inlineFrame && !inlineFrame->GetNextInFlow() &&
|
||||
AreOnSameLine(aFrame, inlineFrame)) {
|
||||
nscoord frameXOffset = inlineFrame->GetOffsetTo(mBlockFrame).x;
|
||||
if((isRtlBlock && frameXOffset >= curOffset) ||
|
||||
(!isRtlBlock && frameXOffset < curOffset)) {
|
||||
x += inlineFrame->GetSize().width;
|
||||
}
|
||||
inlineFrame = inlineFrame->GetPrevContinuation();
|
||||
}
|
||||
|
||||
inlineFrame = aFrame->GetNextContinuation();
|
||||
while (inlineFrame && !inlineFrame->GetPrevInFlow() &&
|
||||
AreOnSameLine(aFrame, inlineFrame)) {
|
||||
nscoord frameXOffset = inlineFrame->GetOffsetTo(mBlockFrame).x;
|
||||
if((isRtlBlock && frameXOffset >= curOffset) ||
|
||||
(!isRtlBlock && frameXOffset < curOffset)) {
|
||||
x += inlineFrame->GetSize().width;
|
||||
}
|
||||
inlineFrame = inlineFrame->GetNextContinuation();
|
||||
}
|
||||
if (isRtlBlock) {
|
||||
// aFrame itself is also to the right of its left edge, so add its width.
|
||||
x += aFrame->GetSize().width;
|
||||
// x is now the distance from the left edge of aFrame to the right edge
|
||||
// of the unbroken content. Change it to indicate the distance from the
|
||||
// left edge of the unbroken content to the left edge of aFrame.
|
||||
x = mUnbrokenWidth - x;
|
||||
}
|
||||
} else {
|
||||
x = mContinuationPoint;
|
||||
}
|
||||
|
||||
// Assume background-origin: border and return a rect with offsets
|
||||
// relative to (0,0). If we have a different background-origin,
|
||||
// then our rect should be deflated appropriately by our caller.
|
||||
return nsRect(-mContinuationPoint, 0, mUnbrokenWidth, mFrame->GetSize().height);
|
||||
return nsRect(-x, 0, mUnbrokenWidth, mFrame->GetSize().height);
|
||||
}
|
||||
|
||||
nsRect GetBoundingRect(nsIFrame* aFrame)
|
||||
|
@ -153,6 +200,10 @@ protected:
|
|||
nscoord mUnbrokenWidth;
|
||||
nsRect mBoundingBox;
|
||||
|
||||
PRBool mBidiEnabled;
|
||||
nsBlockFrame* mBlockFrame;
|
||||
nscoord mLineContinuationPoint;
|
||||
|
||||
void SetFrame(nsIFrame* aFrame)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Need a frame");
|
||||
|
@ -170,6 +221,12 @@ protected:
|
|||
// point before we cache the new frame.
|
||||
mContinuationPoint += mFrame->GetSize().width;
|
||||
|
||||
// If this a new line, update mLineContinuationPoint.
|
||||
if (mBidiEnabled &&
|
||||
(aFrame->GetPrevInFlow() || !AreOnSameLine(mFrame, aFrame))) {
|
||||
mLineContinuationPoint = mContinuationPoint;
|
||||
}
|
||||
|
||||
mFrame = aFrame;
|
||||
}
|
||||
|
||||
|
@ -198,6 +255,29 @@ protected:
|
|||
}
|
||||
|
||||
mFrame = aFrame;
|
||||
|
||||
mBidiEnabled = aFrame->PresContext()->BidiEnabled();
|
||||
if (mBidiEnabled) {
|
||||
// Find the containing block frame
|
||||
nsIFrame* frame = aFrame;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
while (frame &&
|
||||
frame->IsFrameOfType(nsIFrame::eLineParticipant) &&
|
||||
NS_FAILED(rv)) {
|
||||
frame = frame->GetParent();
|
||||
rv = frame->QueryInterface(kBlockFrameCID, (void**)&mBlockFrame);
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && mBlockFrame, "Cannot find containing block.");
|
||||
|
||||
mLineContinuationPoint = mContinuationPoint;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool AreOnSameLine(nsIFrame* aFrame1, nsIFrame* aFrame2) {
|
||||
// Assumes that aFrame1 and aFrame2 are both decsendants of mBlockFrame.
|
||||
nsBlockInFlowLineIterator it1(mBlockFrame, aFrame1);
|
||||
nsBlockInFlowLineIterator it2(mBlockFrame, aFrame2);
|
||||
return it1.GetLine() == it2.GetLine();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче