зеркало из 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 "nsIDOMHTMLDocument.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
|
#include "nsBlockFrame.h"
|
||||||
|
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ enum ePathTypes{
|
||||||
struct InlineBackgroundData
|
struct InlineBackgroundData
|
||||||
{
|
{
|
||||||
InlineBackgroundData()
|
InlineBackgroundData()
|
||||||
: mFrame(nsnull)
|
: mFrame(nsnull), mBlockFrame(nsnull)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,18 +118,64 @@ struct InlineBackgroundData
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
mBoundingBox.SetRect(0,0,0,0);
|
mBoundingBox.SetRect(0,0,0,0);
|
||||||
mContinuationPoint = mUnbrokenWidth = 0;
|
mContinuationPoint = mLineContinuationPoint = mUnbrokenWidth = 0;
|
||||||
mFrame = nsnull;
|
mFrame = mBlockFrame = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect GetContinuousRect(nsIFrame* aFrame)
|
nsRect GetContinuousRect(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
SetFrame(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
|
// Assume background-origin: border and return a rect with offsets
|
||||||
// relative to (0,0). If we have a different background-origin,
|
// relative to (0,0). If we have a different background-origin,
|
||||||
// then our rect should be deflated appropriately by our caller.
|
// 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)
|
nsRect GetBoundingRect(nsIFrame* aFrame)
|
||||||
|
@ -153,6 +200,10 @@ protected:
|
||||||
nscoord mUnbrokenWidth;
|
nscoord mUnbrokenWidth;
|
||||||
nsRect mBoundingBox;
|
nsRect mBoundingBox;
|
||||||
|
|
||||||
|
PRBool mBidiEnabled;
|
||||||
|
nsBlockFrame* mBlockFrame;
|
||||||
|
nscoord mLineContinuationPoint;
|
||||||
|
|
||||||
void SetFrame(nsIFrame* aFrame)
|
void SetFrame(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aFrame, "Need a frame");
|
NS_PRECONDITION(aFrame, "Need a frame");
|
||||||
|
@ -170,6 +221,12 @@ protected:
|
||||||
// point before we cache the new frame.
|
// point before we cache the new frame.
|
||||||
mContinuationPoint += mFrame->GetSize().width;
|
mContinuationPoint += mFrame->GetSize().width;
|
||||||
|
|
||||||
|
// If this a new line, update mLineContinuationPoint.
|
||||||
|
if (mBidiEnabled &&
|
||||||
|
(aFrame->GetPrevInFlow() || !AreOnSameLine(mFrame, aFrame))) {
|
||||||
|
mLineContinuationPoint = mContinuationPoint;
|
||||||
|
}
|
||||||
|
|
||||||
mFrame = aFrame;
|
mFrame = aFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +255,29 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
mFrame = aFrame;
|
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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче