bug 71370; author=simon@softel.co.il; r=attinasi; sr=erik; implement bidi

(bidirectional text) for languages such as Arabic and Hebrew; from IBM bidi
project; not part of build yet (due to #ifdef IBMBIDI)
This commit is contained in:
erik%netscape.com 2001-03-09 03:29:00 +00:00
parent ed5898feca
commit 06d55ad850
26 changed files with 2044 additions and 42 deletions

View File

@ -805,6 +805,20 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext,
return rv;
}
#ifdef IBMBIDI
if (aPrevFrame) {
// Insert aFrameList after the last bidi continuation of aPrevFrame.
nsIFrame* nextBidi;
for (; ;) {
GetFrameProperty(aPrevFrame, nsLayoutAtoms::nextBidi, 0, (void**) &nextBidi);
if (!nextBidi) {
break;
}
aPrevFrame = nextBidi;
}
}
#endif // IBMBIDI
return aParentFrame->InsertFrames(aPresContext, aPresShell, aListName,
aPrevFrame, aFrameList);
}
@ -822,6 +836,15 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext,
if (insertionPoint)
return insertionPoint->RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
#ifdef IBMBIDI
// Don't let the parent remove next bidi. In the other cases the it should NOT be removed.
nsIFrame* nextBidi;
GetFrameProperty(aOldFrame, nsLayoutAtoms::nextBidi, 0, (void**) &nextBidi);
if (nextBidi) {
RemoveFrame(aPresContext, aPresShell, aParentFrame, aListName, nextBidi);
}
#endif // IBMBIDI
return aParentFrame->RemoveFrame(aPresContext, aPresShell, aListName,
aOldFrame);
}

View File

@ -135,6 +135,10 @@
// SubShell map
#include "nsDST.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
#endif // IBMBIDI
#include "nsContentCID.h"
static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID);
@ -886,6 +890,12 @@ public:
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
NS_IMETHOD IsReflowLocked(PRBool* aIsLocked);
#ifdef IBMBIDI
NS_IMETHOD SetCursorBidiLevel(PRUint8 aLevel);
NS_IMETHOD GetCursorBidiLevel(PRUint8 *aOutLevel);
NS_IMETHOD UndefineCursorBidiLevel();
NS_IMETHOD BidiStyleChangeReflow();
#endif
//nsIViewObserver interface
@ -1022,6 +1032,10 @@ protected:
PRBool IsDragInProgress ( ) const ;
PRBool mCaretEnabled;
#ifdef IBMBIDI
PRUint8 mBidiLevel; // The Bidi level of the cursor
nsCOMPtr<nsIBidiKeyboard> mBidiKeyboard;
#endif // IBMBIDI
#ifdef NS_DEBUG
PRBool VerifyIncrementalReflow();
PRBool mInVerifyReflow;
@ -1246,6 +1260,9 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
mReflowCountMgr->SetPresContext(mPresContext);
mReflowCountMgr->SetPresShell(this);
#endif
#ifdef IBMBIDI
mBidiLevel = BIDI_LEVEL_UNDEFINED;
#endif
}
NS_IMPL_ADDREF(PresShell)
@ -1479,6 +1496,9 @@ PresShell::Init(nsIDocument* aDocument,
// cache the drag service so we can check it during reflows
mDragService = do_GetService("@mozilla.org/widget/dragservice;1");
#ifdef IBMBIDI
mBidiKeyboard = do_GetService("@mozilla.org/widget/bidikeyboard;1");
#endif
// setup the preference style rules up (no forced reflow)
SetPreferenceStyleRules(PR_FALSE);
@ -4535,6 +4555,55 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
return rv;
}
#ifdef IBMBIDI
NS_IMETHODIMP
PresShell::SetCursorBidiLevel(PRUint8 aLevel)
{
// If the current level is undefined, we have just inserted new text.
// In this case, we don't want to reset the keyboard language
PRBool afterInsert = mBidiLevel & BIDI_LEVEL_UNDEFINED;
mBidiLevel = aLevel;
// PRBool parityChange = ((mBidiLevel ^ aLevel) & 1); // is the parity of the new level different from the current level?
// if (parityChange) // if so, change the keyboard language
if (mBidiKeyboard && !afterInsert)
mBidiKeyboard->SetLangFromBidiLevel(aLevel);
return NS_OK;
}
NS_IMETHODIMP
PresShell::GetCursorBidiLevel(PRUint8 *aOutLevel)
{
if (!aOutLevel) { return NS_ERROR_INVALID_ARG; }
*aOutLevel = mBidiLevel;
return NS_OK;
}
NS_IMETHODIMP
PresShell::UndefineCursorBidiLevel()
{
mBidiLevel |= BIDI_LEVEL_UNDEFINED;
return NS_OK;
}
NS_IMETHODIMP
PresShell::BidiStyleChangeReflow()
{
// Have the root frame's style context remap its style
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
if (rootFrame) {
nsIStyleContext* rootStyleContext;
rootFrame->GetStyleContext(&rootStyleContext);
rootStyleContext->RemapStyle(mPresContext.get() );
NS_RELEASE(rootStyleContext);
ReconstructFrames();
}
return NS_OK;
}
#endif // IBMBIDI
//nsIViewObserver

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -37,6 +37,9 @@
#include "nsLayoutAtoms.h"
#include "prprf.h"
#include "nsIImage.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
nsBulletFrame::nsBulletFrame()
{
@ -145,6 +148,14 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.SetColor(myColor->mColor);
#ifdef IBMBIDI
nsCharType charType = eCharType_LeftToRight;
PRUint8 level = 0;
PRBool isBidiSystem = PR_FALSE;
const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
PRUint32 hints = 0;
#endif // IBMBIDI
nsAutoString text;
switch (listStyleType) {
case NS_STYLE_LIST_STYLE_NONE:
@ -173,6 +184,33 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_DECIMAL:
case NS_STYLE_LIST_STYLE_OLD_DECIMAL:
case NS_STYLE_LIST_STYLE_DECIMAL_LEADING_ZERO:
#ifdef IBMBIDI
GetListItemText(aCX, *myList, text);
charType = eCharType_EuropeanNumber;
break;
case NS_STYLE_LIST_STYLE_ARABIC_INDIC:
GetListItemText(aCX, *myList, text);
charType = eCharType_ArabicNumber;
break;
case NS_STYLE_LIST_STYLE_HEBREW:
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
if (!isBidiSystem) {
charType = eCharType_RightToLeft;
level = 1;
GetListItemText(aCX, *myList, text);
if (NS_STYLE_DIRECTION_RTL == disp->mDirection) {
nsStr::Delete(text, 0, 1);
text.AppendWithConversion(".");
}
break;
}
// else fall through
#endif // IBMBIDI
case NS_STYLE_LIST_STYLE_LOWER_ROMAN:
case NS_STYLE_LIST_STYLE_UPPER_ROMAN:
case NS_STYLE_LIST_STYLE_LOWER_ALPHA:
@ -182,7 +220,9 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_OLD_LOWER_ALPHA:
case NS_STYLE_LIST_STYLE_OLD_UPPER_ALPHA:
case NS_STYLE_LIST_STYLE_LOWER_GREEK:
#ifndef IBMBIDI
case NS_STYLE_LIST_STYLE_HEBREW:
#endif
case NS_STYLE_LIST_STYLE_ARMENIAN:
case NS_STYLE_LIST_STYLE_GEORGIAN:
case NS_STYLE_LIST_STYLE_CJK_IDEOGRAPHIC:
@ -198,7 +238,9 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_JAPANESE_FORMAL:
case NS_STYLE_LIST_STYLE_CJK_HEAVENLY_STEM:
case NS_STYLE_LIST_STYLE_CJK_EARTHLY_BRANCH:
#ifndef IBMBIDI
case NS_STYLE_LIST_STYLE_ARABIC_INDIC:
#endif
case NS_STYLE_LIST_STYLE_PERSIAN:
case NS_STYLE_LIST_STYLE_URDU:
case NS_STYLE_LIST_STYLE_DEVANAGARI:
@ -220,6 +262,31 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
aRenderingContext.DrawString(text, mPadding.left, mPadding.top);
break;
}
#ifdef IBMBIDI
if (charType != eCharType_LeftToRight) {
aCX->GetMetricsFor(myFont->mFont, getter_AddRefs(fm));
aRenderingContext.SetFont(fm);
nsBidiPresUtils* bidiUtils;
aCX->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
const PRUnichar* buffer = text.GetUnicode();
PRInt32 textLength = text.Length();
if (eCharType_RightToLeft == charType) {
bidiUtils->FormatUnicodeText(aCX, (PRUnichar*)buffer, textLength,
charType, level, PR_FALSE);
}
else {
//Mohamed
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_ARABIC_SHAPING);
bidiUtils->FormatUnicodeText(aCX, (PRUnichar*)buffer, textLength,
charType, level, isBidiSystem);//Mohamed
}
}
aRenderingContext.DrawString(text, mPadding.left, mPadding.top);
}
#endif // IBMBIDI
}
return NS_OK;
}
@ -590,12 +657,21 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
{
PRBool outputSep = PR_FALSE;
PRUnichar buf[NUM_BUF_SIZE];
#ifdef IBMBIDI
// Changes: 1) don't reverse the text; 2) don't insert geresh/gershayim.
PRInt32 idx = 0;
#else
PRInt32 idx = NUM_BUF_SIZE;
#endif // IBMBIDI
PRUnichar digit;
do {
PRInt32 n3 = ordinal % 1000;
if(outputSep)
#ifdef IBMBIDI
buf[idx++] = HEBREW_THROSAND_SEP; // output thousand seperator
#else
buf[--idx] = HEBREW_THROSAND_SEP; // output thousand seperator
#endif // IBMBIDI
outputSep = ( n3 > 0); // request to output thousand seperator next time.
PRInt32 d = 0; // we need to keep track of digit got output per 3 digits,
@ -611,10 +687,17 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
digit = gHebrewDigit[(n1/100)-1+18];
if( n3 > 0)
{
#ifdef IBMBIDI
buf[idx++] = digit;
#else
buf[--idx] = digit;
#endif // IBMBIDI
d++;
} else {
// if this is the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -623,6 +706,7 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
} else {
n1 -= 100;
@ -648,10 +732,17 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
n3 -= n2;
if( n3 > 0) {
#ifdef IBMBIDI
buf[idx++] = digit;
#else
buf[--idx] = digit;
#endif // IBMBIDI
d++;
} else {
// if this is the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -660,6 +751,7 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
} // if
@ -668,6 +760,9 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
{
digit = gHebrewDigit[n3-1];
// must be the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -676,10 +771,15 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
ordinal /= 1000;
} while (ordinal >= 1);
#ifdef IBMBIDI
result.Append(buf, idx);
#else
result.Append(buf+idx,NUM_BUF_SIZE-idx);
#endif // IBMBIDI
}
@ -747,6 +847,14 @@ nsBulletFrame::GetListItemText(nsIPresContext* aCX,
const nsStyleList& aListStyle,
nsString& result)
{
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
result.AppendWithConversion(".");
}
#endif // IBMBIDI
switch (aListStyle.mListStyleType) {
case NS_STYLE_LIST_STYLE_DECIMAL:
case NS_STYLE_LIST_STYLE_OLD_DECIMAL:
@ -904,6 +1012,9 @@ nsBulletFrame::GetListItemText(nsIPresContext* aCX,
CharListToText(mOrdinal, result, gCJKEarthlyBranchChars, CJK_EARTHLY_BRANCH_CHARS_SIZE);
break;
}
#ifdef IBMBIDI
if (NS_STYLE_DIRECTION_RTL != display->mDirection)
#endif // IBMBIDI
result.AppendWithConversion(".");
}

View File

@ -851,6 +851,15 @@ nsContainerFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
parent->DeleteChildsNextInFlow(aPresContext, nextInFlow);
}
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi == nextInFlow) {
return;
}
#endif // IBMBIDI
// Disconnect the next-in-flow from the flow list
nsSplittableFrame::BreakFromPrevFlow(nextInFlow);

View File

@ -2633,6 +2633,18 @@ nsFrame::SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange, PRBool a
}
}
#endif
#ifdef IBMBIDI
PRInt32 start, end;
nsIFrame* frame;
GetNextSibling(&frame);
if (frame){
GetFirstLeaf(aPresContext, &frame);
GetOffsets(start, end);
if (start && end) {
frame->SetSelected(aPresContext, aRange, aSelected, aSpread);
}
}
#endif // IBMBIDI
return NS_OK;
}
@ -2776,7 +2788,13 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
nsIView * view; //used for call of get offset from view
aBlockFrame->GetOffsetFromView(aPresContext, offset,&view);
nscoord newDesiredX = aPos->mDesiredX - offset.x;//get desired x into blockframe coordinates!
#ifdef IBMBIDI
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
result = it->FindFrameAt(searchingLine, newDesiredX, bidiEnabled, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
#else
result = it->FindFrameAt(searchingLine, newDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
#endif // IBMBIDI
if(NS_FAILED(result))
continue;
}
@ -3463,6 +3481,26 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
PRInt32 lineFrameCount;
PRUint32 lineFlags;
#ifdef IBMBIDI
/* Check whether the visual and logical order of the frames are different */
PRBool lineIsReordered = PR_FALSE;
nsIFrame *firstVisual;
nsIFrame *lastVisual;
PRBool lineIsRTL;
PRBool lineJump = PR_FALSE;
it->GetDirection(&lineIsRTL);
result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual);
if (NS_FAILED(result))
return result;
if (lineIsReordered) {
firstFrame = firstVisual;
lastFrame = lastVisual;
}
else
#endif
{
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
@ -3476,15 +3514,30 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
return NS_ERROR_FAILURE;
}
}
}
GetFirstLeaf(aPresContext, &firstFrame);
GetLastLeaf(aPresContext, &lastFrame);
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
if
#ifndef IBMBIDI // jumping lines in RTL paragraphs
((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
#else
(((lineIsRTL) &&
((aPos->mDirection == eDirNext && firstFrame == this)
||(aPos->mDirection == eDirPrevious && lastFrame == this)))
||
((!lineIsRTL) &&
((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))))
#endif
{
if (aPos->mJumpLines != PR_TRUE)
return NS_ERROR_FAILURE;//we are done. cannot jump lines
#ifdef IBMBIDI
lineJump = PR_TRUE;
#endif
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
@ -3504,10 +3557,30 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
#ifdef IBMBIDI
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
(lineIsReordered) ? VISUAL : LEAF,
aPresContext,
(lineJump && lineIsRTL)
? (aPos->mDirection == eDirNext) ? lastFrame : firstFrame
: this);
#else
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF, aPresContext, this);
#endif
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
#ifdef IBMBIDI
nsIFrame *newFrame;
nsRect testRect;
while (testRect.IsEmpty()) {
if (lineIsRTL && lineJump)
if (aPos->mDirection == eDirPrevious)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
else
#endif
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
@ -3522,7 +3595,80 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
#ifndef IBMBIDI
nsIFrame *newFrame = (nsIFrame *)isupports;
#else
newFrame = (nsIFrame *)isupports;
newFrame->GetRect(testRect);
if (testRect.IsEmpty()) { // this must be a non-renderable frame creatd at the end of the line by Bidi reordering
lineJump = PR_TRUE;
aPos->mAmount = eSelectNoAmount;
}
}
PRBool newLineIsRTL = PR_FALSE;
if (lineJump) {
blockFrame = newFrame;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
it->GetDirection(&newLineIsRTL);
result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual);
if (NS_FAILED(result))
return result;
if (lineIsReordered)
{
firstFrame = firstVisual;
lastFrame = lastVisual;
}
else
{
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
}
GetFirstLeaf(aPresContext, &firstFrame);
GetLastLeaf(aPresContext, &lastFrame);
if (newLineIsRTL) {
if (aPos->mDirection == eDirPrevious)
newFrame = firstFrame;
else
newFrame = lastFrame;
}
else {
if (aPos->mDirection == eDirNext)
newFrame = firstFrame;
else
newFrame = lastFrame;
}
}
#endif // IBMBIDI
PRBool selectable;
newFrame->IsSelectable(&selectable, nsnull);
if (!selectable)
@ -3531,6 +3677,18 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
#ifdef IBMBIDI
long oldLevel, newLevel, baseLevel;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&oldLevel);
newFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&newLevel);
newFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, (void**)&baseLevel);
if (newLevel & 1) // The new frame is RTL, go to the other end
aPos->mStartOffset = -1 - aPos->mStartOffset;
if ((aPos->mAmount == eSelectNoAmount) && ((newLevel & 1) != (oldLevel & 1))) {
aPos->mPreferLeft = !(aPos->mPreferLeft);
}
#endif
aPos->mResultFrame = newFrame;
return NS_OK;
}
@ -3771,6 +3929,63 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
return PR_FALSE;
}
#ifdef IBMBIDI
/**
* retrieve Bidi property of this frame
* @lina 5/1/2000
*/
nsresult nsFrame::GetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void** aPropertyValue,
long aSize) const
{
if (!aPropertyValue || !aPropertyName) {
return NS_ERROR_NULL_POINTER;
}
if ( (aSize < 1) || (aSize > sizeof(void*) ) ) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsCRT::zero(aPropertyValue, aSize);
void* val = nsnull;
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell) );
if (presShell) {
nsCOMPtr<nsIFrameManager> frameManager;
presShell->GetFrameManager(getter_AddRefs(frameManager) );
if (frameManager) {
frameManager->GetFrameProperty( (nsIFrame*)this, aPropertyName, 0, &val);
if (val) {
nsCRT::memcpy(aPropertyValue, &val, aSize);
}
}
}
return NS_OK;
}
nsresult nsFrame::SetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void* aPropertyValue) const
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell) );
if (shell) {
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager) );
if (frameManager) {
rv = frameManager->SetFrameProperty( (nsIFrame*) this, aPropertyName, aPropertyValue, nsnull);
}
}
return rv;
}
#endif // IBMBIDI
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,

View File

@ -368,6 +368,15 @@ public:
//Mouse Capturing code used by the frames to tell the view to capture all the following events
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
#ifdef IBMBIDI
NS_IMETHOD GetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void** aPropertyValue,
long aSize = sizeof(void*) ) const;
NS_IMETHOD SetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void* aPropertyValue) const ;
#endif // IBMBIDI
#ifdef NS_DEBUG
/**

View File

@ -66,6 +66,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mLineLayout = nsnull;
isTopOfPage = PR_FALSE;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = NS_UNCONSTRAINEDSIZE;
#endif
}
// Initialize a <b>root</b> reflow state for an <b>incremental</b>
@ -90,6 +93,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mLineLayout = nsnull;
isTopOfPage = PR_FALSE;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = NS_UNCONSTRAINEDSIZE;
#endif // IBMBIDI
}
// Initialize a reflow state for a child frames reflow. Some state
@ -117,6 +123,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
// Same as the previous except that the reason is taken from the
@ -140,6 +150,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
// Version that species the containing block width and height
@ -164,6 +178,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
void
@ -1833,6 +1851,18 @@ nsHTMLReflowState::ComputeBlockBoxData(nsIPresContext* aPresContext,
AdjustComputedWidth();
#ifdef IBMBIDI
// See what edge the width applies to (the default is the content
// edge)
if (mComputedWidth != NS_UNCONSTRAINEDSIZE) {
if (mStylePosition->mBoxSizing == NS_STYLE_BOX_SIZING_PADDING) {
mComputedWidth -= mComputedPadding.left + mComputedPadding.right;
} else if (mStylePosition->mBoxSizing == NS_STYLE_BOX_SIZING_BORDER) {
mComputedWidth -= mComputedBorderPadding.left + mComputedBorderPadding.right;
}
}
#endif // IBMBIDI
// Now that we have the computed-width, compute the side margins
CalculateBlockSideMargins(cbrs->mComputedWidth, mComputedWidth);
}

View File

@ -122,12 +122,18 @@ nsInlineFrame::InsertFrames(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
if (nsnull != aListName) {
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif
return NS_ERROR_INVALID_ARG;
}
if (aFrameList) {
// Insert frames after aPrevFrame
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
#ifdef IBMBIDI
if (nsnull == aListName)
#endif
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
}
@ -141,6 +147,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIFrame* aOldFrame)
{
if (nsnull != aListName) {
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif
return NS_ERROR_INVALID_ARG;
}
@ -151,6 +160,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
aOldFrame->GetParent(&oldFrameParent);
nsInlineFrame* parent = (nsInlineFrame*) oldFrameParent;
while (nsnull != aOldFrame) {
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName) {
#endif
// If the frame being removed has zero size then don't bother
// generating a reflow command, otherwise make sure we do.
nsRect bbox;
@ -158,6 +170,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
if (bbox.width || bbox.height) {
generateReflowCommand = PR_TRUE;
}
#ifdef IBMBIDI
}
#endif
// When the parent is an inline frame we have a simple task - just
// remove the frame from its parents list and generate a reflow

View File

@ -653,9 +653,125 @@ nsLineIterator::FindLineAt(nscoord aY,
return NS_OK;
}
#ifdef IBMBIDI
NS_IMETHODIMP
nsLineIterator::CheckLineOrder(PRInt32 aLine,
PRBool *aIsReordered,
nsIFrame **aFirstVisual,
nsIFrame **aLastVisual)
{
nsRect checkRect;
PRInt32 currentLine, saveLine, testLine;
nscoord saveX;
nsIFrame *checkFrame;
nsIFrame *firstFrame;
nsIFrame *leftmostFrame;
nsIFrame *rightmostFrame;
nscoord minX, maxX;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
nsresult result;
// an RTL paragraph is always considered as reordered
// in an LTR paragraph, find out by examining the coordinates of each frame in the line
if (mRightToLeft)
*aIsReordered = PR_TRUE;
else {
*aIsReordered = PR_FALSE;
// Check the preceding and following line, since we might be moving into them
for (currentLine = PR_MAX(0, aLine-1); currentLine < aLine+1; currentLine++) {
nsLineBox* line = mLines[currentLine];
if (!line)
break;
checkFrame = line->mFirstChild;
checkFrame->GetRect(checkRect);
result = FindLineContaining(checkFrame, &saveLine);
if (NS_FAILED(result))
return result;
saveX = checkRect.x;
lineFrameCount = line->GetChildCount();
for (; checkFrame; result = checkFrame->GetNextSibling(&checkFrame)) {
if (NS_FAILED(result))
break;
result = FindLineContaining(checkFrame, &testLine);
if (NS_FAILED(result))
return result;
if (testLine != saveLine) {
*aIsReordered = PR_TRUE;
break;
}
checkFrame->GetRect(checkRect);
// If the origin of any frame is less than the previous frame, the line is reordered
if (checkRect.x < saveX) {
*aIsReordered = PR_TRUE;
break;
}
saveX = checkRect.x;
lineFrameCount--;
if (0 == lineFrameCount)
break;
}
if (*aIsReordered)
break;
}
}
// If the line is reordered, identify the first and last frames on the line
if (*aIsReordered) {
nsRect nonUsedRect;
result = GetLine(aLine, &firstFrame, &lineFrameCount, nonUsedRect, &lineFlags);
if (NS_FAILED(result))
return result;
leftmostFrame = rightmostFrame = firstFrame;
firstFrame->GetRect(checkRect);
maxX = checkRect.x;
minX = checkRect.x;
for (;lineFrameCount > 1;lineFrameCount--) {
result = firstFrame->GetNextSibling(&firstFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsLineBox\n");
return NS_ERROR_FAILURE;
}
firstFrame->GetRect(checkRect);
if (checkRect.x > maxX) {
maxX = checkRect.x;
rightmostFrame = firstFrame;
}
if (checkRect.x < minX) {
minX = checkRect.x;
leftmostFrame = firstFrame;
}
}
if (mRightToLeft) {
*aFirstVisual = rightmostFrame;
*aLastVisual = leftmostFrame;
}
else {
*aFirstVisual = leftmostFrame;
*aLastVisual = rightmostFrame;
}
}
return result;
}
#endif // IBMBIDI
NS_IMETHODIMP
nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
#ifdef IBMBIDI
PRBool aCouldBeReordered,
#endif // IBMBIDI
nsIFrame** aFrameFound,
PRBool* aXIsBeforeFirstFrame,
PRBool* aXIsAfterLastFrame)
@ -709,12 +825,50 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
// when checking.
*aXIsBeforeFirstFrame = PR_FALSE;
*aXIsAfterLastFrame = PR_FALSE;
#ifdef IBMBIDI
PRBool isReordered = PR_FALSE;
nsIFrame *firstVisual, *lastVisual;
if (aCouldBeReordered)
CheckLineOrder(aLineNumber, &isReordered, &firstVisual, &lastVisual);
#endif
nsRect r1, r2;
nsIFrame* frame = line->mFirstChild;
#ifdef IBMBIDI
if (isReordered)
frame = firstVisual;
#endif // IBMBIDI
PRInt32 n = line->GetChildCount();
if (mRightToLeft) {
while (--n >= 0) {
nsIFrame* nextFrame;
#ifdef IBMBIDI
if (isReordered) {
nscoord maxX, limX;
PRInt32 testLine;
nsRect tempRect;
nsIFrame* tempFrame;
maxX = -0x7fffffff;
frame->GetRect(tempRect);
limX = tempRect.x;
tempFrame = line->mFirstChild;
nextFrame = nsnull;
while (tempFrame) {
if (NS_SUCCEEDED(FindLineContaining(tempFrame, &testLine))
&& testLine == aLineNumber) {
tempFrame->GetRect(tempRect);
if (tempRect.x > maxX && tempRect.x < limX) { // we are looking for the highest value less than the current one
maxX = tempRect.x;
nextFrame = tempFrame;
}
}
tempFrame->GetNextSibling(&tempFrame);
}
}
else
#endif // IBMBIDI
frame->GetNextSibling(&nextFrame);
frame->GetRect(r1);
if (aX > r1.x) {
@ -740,6 +894,34 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
else {
while (--n >= 0) {
nsIFrame* nextFrame;
#ifdef IBMBIDI
if (isReordered) {
nsRect tempRect;
nsIFrame* tempFrame;
PRInt64 minX, limX;
PRInt32 testLine;
minX = 0x7fffffff;
frame->GetRect(tempRect);
limX = tempRect.x;
tempFrame = line->mFirstChild;
nextFrame = nsnull;
while (tempFrame) {
if (NS_SUCCEEDED(FindLineContaining(tempFrame, &testLine))
&& testLine == aLineNumber) {
tempFrame->GetRect(tempRect);
if (tempRect.x < minX && tempRect.x > limX) { // we are looking for the lowest value greater than the current one
minX = tempRect.x;
nextFrame = tempFrame;
}
}
tempFrame->GetNextSibling(&tempFrame);
}
}
else
#endif // IBMBIDI
frame->GetNextSibling(&nextFrame);
frame->GetRect(r1);
if (aX < r1.XMost()) {

View File

@ -412,12 +412,20 @@ public:
PRInt32* aLineNumberResult);
NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
#ifdef IBMBIDI
PRBool aCouldBeReordered,
#endif
nsIFrame** aFrameFound,
PRBool* aXIsBeforeFirstFrame,
PRBool* aXIsAfterLastFrame);
NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, PRInt32 aLineNumber);
#ifdef IBMBIDI
NS_IMETHOD CheckLineOrder(PRInt32 aLine,
PRBool *aIsReordered,
nsIFrame **aFirstVisual,
nsIFrame **aLastVisual);
#endif
nsresult Init(nsLineBox* aLines, PRBool aRightToLeft);
protected:

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -58,6 +58,10 @@
#include "prenv.h"
#include "plstr.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
@ -1619,6 +1623,27 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
NS_BLOCK_MARGIN_ROOT & mState);
if (eReflowReason_Resize != aReflowState.reason) {
#ifdef IBMBIDI
if (mLines) {
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
PRBool forceReflow;
nsresult rc = bidiUtils->Resolve(aPresContext, this,
mLines->mFirstChild, forceReflow);
if (NS_SUCCEEDED(rc) && forceReflow) {
// Mark everything dirty
for (nsLineBox* line = mLines; line; line = line->mNext) {
line->MarkDirty();
}
}
}
}
}
#endif // IBMBIDI
RenumberLists(aPresContext);
}
@ -4247,6 +4272,15 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (aUpdateMaximumWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
#ifdef IBMBIDI
else {
nscoord rightEdge = aState.mReflowState.mRightEdge;
if ( (rightEdge != NS_UNCONSTRAINEDSIZE)
&& (availWidth < rightEdge) ) {
availWidth = rightEdge;
}
}
#endif // IBMBIDI
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloaters,
@ -4735,14 +4769,55 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
mStyleContext->GetStyleData(eStyleStruct_Text);
PRBool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign
&& !aLineLayout.GetLineEndsInBR() && ShouldJustifyLine(aState, aLine);
#ifdef IBMBIDI
nsRect bounds(aLine->mBounds);
if (mRect.x) {
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
bounds.x += mRect.x;
}
}
PRBool successful = aLineLayout.HorizontalAlignFrames(bounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
// XXX: not only bidi: right alignment can be broken after RelativePositionFrames!!!
#else
PRBool successful = aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify,
aState.GetFlag(BRS_SHRINKWRAPWIDTH));
#endif // IBMBIDI
if (!successful) {
// Mark the line dirty and then later once we've determined the width
// we can do the horizontal alignment
aLine->MarkDirty();
aState.SetFlag(BRS_NEEDRESIZEREFLOW, PR_TRUE);
}
#ifdef IBMBIDI
else {
PRBool bidiEnabled;
aState.mPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PRBool isVisual;
aState.mPresContext->IsVisualMode(isVisual);
if (!isVisual) {
nsBidiPresUtils* bidiUtils;
aState.mPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils && bidiUtils->IsSuccessful() ) {
nsIFrame* nextInFlow = (aLine->mNext)
? aLine->mNext->mFirstChild : nsnull;
bidiUtils->ReorderFrames(aState.mPresContext,
aState.mReflowState.rendContext,
aLine->mFirstChild, nextInFlow,
aLine->GetChildCount() );
} // bidiUtils
} // not visual mode
} // bidi enabled
} // successful
#endif // IBMBIDI
nsRect combinedArea;
aLineLayout.RelativePositionFrames(combinedArea);
@ -5263,6 +5338,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
mFloaters.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
}
@ -5278,6 +5356,9 @@ nsBlockFrame::InsertFrames(nsIPresContext* aPresContext,
printf("\n");
#endif
nsresult rv = AddFrames(aPresContext, aFrameList, aPrevFrame);
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5441,6 +5522,11 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
line = line->mNext;
}
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#endif // IBMBIDI
else if (nsnull != aListName) {
rv = NS_ERROR_INVALID_ARG;
}
@ -5448,6 +5534,9 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext,
rv = DoRemoveFrame(aPresContext, aOldFrame);
}
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif // IBMBIDI
if (NS_SUCCEEDED(rv)) {
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
@ -5628,12 +5717,21 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
nsIFrame* nextInFlow;
aChild->GetNextInFlow(&nextInFlow);
NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi != nextInFlow) {
#endif // IBMBIDI
nsBlockFrame* parent;
nextInFlow->GetParent((nsIFrame**)&parent);
NS_PRECONDITION(nsnull != parent, "next-in-flow with no parent");
NS_PRECONDITION(nsnull != parent->mLines, "next-in-flow with weird parent");
// NS_PRECONDITION(nsnull == parent->mOverflowLines, "parent with overflow");
parent->DoRemoveFrame(aPresContext, nextInFlow);
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
////////////////////////////////////////////////////////////////////////
@ -7206,9 +7304,21 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
mBullet->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
#endif // IBMBIDI
// Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line
nscoord x = - reflowState.mComputedMargin.right - aMetrics.width;
nscoord x =
#ifdef IBMBIDI
// For direction RTL: set x to the right margin for now.
// This value will be used to indent the bullet from the right most
// egde of the previous frame in nsLineLayout::HorizontalAlignFrames.
(NS_STYLE_DIRECTION_RTL == display->mDirection)
? reflowState.mComputedMargin.right :
#endif // IBMBIDI
- reflowState.mComputedMargin.right - aMetrics.width;
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.

View File

@ -37,6 +37,9 @@
#include "nsLayoutAtoms.h"
#include "prprf.h"
#include "nsIImage.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
nsBulletFrame::nsBulletFrame()
{
@ -145,6 +148,14 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.SetColor(myColor->mColor);
#ifdef IBMBIDI
nsCharType charType = eCharType_LeftToRight;
PRUint8 level = 0;
PRBool isBidiSystem = PR_FALSE;
const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
PRUint32 hints = 0;
#endif // IBMBIDI
nsAutoString text;
switch (listStyleType) {
case NS_STYLE_LIST_STYLE_NONE:
@ -173,6 +184,33 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_DECIMAL:
case NS_STYLE_LIST_STYLE_OLD_DECIMAL:
case NS_STYLE_LIST_STYLE_DECIMAL_LEADING_ZERO:
#ifdef IBMBIDI
GetListItemText(aCX, *myList, text);
charType = eCharType_EuropeanNumber;
break;
case NS_STYLE_LIST_STYLE_ARABIC_INDIC:
GetListItemText(aCX, *myList, text);
charType = eCharType_ArabicNumber;
break;
case NS_STYLE_LIST_STYLE_HEBREW:
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
if (!isBidiSystem) {
charType = eCharType_RightToLeft;
level = 1;
GetListItemText(aCX, *myList, text);
if (NS_STYLE_DIRECTION_RTL == disp->mDirection) {
nsStr::Delete(text, 0, 1);
text.AppendWithConversion(".");
}
break;
}
// else fall through
#endif // IBMBIDI
case NS_STYLE_LIST_STYLE_LOWER_ROMAN:
case NS_STYLE_LIST_STYLE_UPPER_ROMAN:
case NS_STYLE_LIST_STYLE_LOWER_ALPHA:
@ -182,7 +220,9 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_OLD_LOWER_ALPHA:
case NS_STYLE_LIST_STYLE_OLD_UPPER_ALPHA:
case NS_STYLE_LIST_STYLE_LOWER_GREEK:
#ifndef IBMBIDI
case NS_STYLE_LIST_STYLE_HEBREW:
#endif
case NS_STYLE_LIST_STYLE_ARMENIAN:
case NS_STYLE_LIST_STYLE_GEORGIAN:
case NS_STYLE_LIST_STYLE_CJK_IDEOGRAPHIC:
@ -198,7 +238,9 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
case NS_STYLE_LIST_STYLE_JAPANESE_FORMAL:
case NS_STYLE_LIST_STYLE_CJK_HEAVENLY_STEM:
case NS_STYLE_LIST_STYLE_CJK_EARTHLY_BRANCH:
#ifndef IBMBIDI
case NS_STYLE_LIST_STYLE_ARABIC_INDIC:
#endif
case NS_STYLE_LIST_STYLE_PERSIAN:
case NS_STYLE_LIST_STYLE_URDU:
case NS_STYLE_LIST_STYLE_DEVANAGARI:
@ -220,6 +262,31 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
aRenderingContext.DrawString(text, mPadding.left, mPadding.top);
break;
}
#ifdef IBMBIDI
if (charType != eCharType_LeftToRight) {
aCX->GetMetricsFor(myFont->mFont, getter_AddRefs(fm));
aRenderingContext.SetFont(fm);
nsBidiPresUtils* bidiUtils;
aCX->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
const PRUnichar* buffer = text.GetUnicode();
PRInt32 textLength = text.Length();
if (eCharType_RightToLeft == charType) {
bidiUtils->FormatUnicodeText(aCX, (PRUnichar*)buffer, textLength,
charType, level, PR_FALSE);
}
else {
//Mohamed
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_ARABIC_SHAPING);
bidiUtils->FormatUnicodeText(aCX, (PRUnichar*)buffer, textLength,
charType, level, isBidiSystem);//Mohamed
}
}
aRenderingContext.DrawString(text, mPadding.left, mPadding.top);
}
#endif // IBMBIDI
}
return NS_OK;
}
@ -590,12 +657,21 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
{
PRBool outputSep = PR_FALSE;
PRUnichar buf[NUM_BUF_SIZE];
#ifdef IBMBIDI
// Changes: 1) don't reverse the text; 2) don't insert geresh/gershayim.
PRInt32 idx = 0;
#else
PRInt32 idx = NUM_BUF_SIZE;
#endif // IBMBIDI
PRUnichar digit;
do {
PRInt32 n3 = ordinal % 1000;
if(outputSep)
#ifdef IBMBIDI
buf[idx++] = HEBREW_THROSAND_SEP; // output thousand seperator
#else
buf[--idx] = HEBREW_THROSAND_SEP; // output thousand seperator
#endif // IBMBIDI
outputSep = ( n3 > 0); // request to output thousand seperator next time.
PRInt32 d = 0; // we need to keep track of digit got output per 3 digits,
@ -611,10 +687,17 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
digit = gHebrewDigit[(n1/100)-1+18];
if( n3 > 0)
{
#ifdef IBMBIDI
buf[idx++] = digit;
#else
buf[--idx] = digit;
#endif // IBMBIDI
d++;
} else {
// if this is the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -623,6 +706,7 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
} else {
n1 -= 100;
@ -648,10 +732,17 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
n3 -= n2;
if( n3 > 0) {
#ifdef IBMBIDI
buf[idx++] = digit;
#else
buf[--idx] = digit;
#endif // IBMBIDI
d++;
} else {
// if this is the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -660,6 +751,7 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
} // if
@ -668,6 +760,9 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
{
digit = gHebrewDigit[n3-1];
// must be the last digit
#ifdef IBMBIDI
buf[idx++] = digit;
#else
if (d > 0)
{
buf[--idx] = HEBREW_GERSHAYIM;
@ -676,10 +771,15 @@ static void HebrewToText(PRInt32 ordinal, nsString& result)
buf[--idx] = digit;
buf[--idx] = HEBREW_GERESH;
} // if
#endif // IBMBIDI
} // if
ordinal /= 1000;
} while (ordinal >= 1);
#ifdef IBMBIDI
result.Append(buf, idx);
#else
result.Append(buf+idx,NUM_BUF_SIZE-idx);
#endif // IBMBIDI
}
@ -747,6 +847,14 @@ nsBulletFrame::GetListItemText(nsIPresContext* aCX,
const nsStyleList& aListStyle,
nsString& result)
{
#ifdef IBMBIDI
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
result.AppendWithConversion(".");
}
#endif // IBMBIDI
switch (aListStyle.mListStyleType) {
case NS_STYLE_LIST_STYLE_DECIMAL:
case NS_STYLE_LIST_STYLE_OLD_DECIMAL:
@ -904,6 +1012,9 @@ nsBulletFrame::GetListItemText(nsIPresContext* aCX,
CharListToText(mOrdinal, result, gCJKEarthlyBranchChars, CJK_EARTHLY_BRANCH_CHARS_SIZE);
break;
}
#ifdef IBMBIDI
if (NS_STYLE_DIRECTION_RTL != display->mDirection)
#endif // IBMBIDI
result.AppendWithConversion(".");
}

View File

@ -851,6 +851,15 @@ nsContainerFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
parent->DeleteChildsNextInFlow(aPresContext, nextInFlow);
}
#ifdef IBMBIDI
nsIFrame* nextBidi;
aChild->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
if (nextBidi == nextInFlow) {
return;
}
#endif // IBMBIDI
// Disconnect the next-in-flow from the flow list
nsSplittableFrame::BreakFromPrevFlow(nextInFlow);

View File

@ -2633,6 +2633,18 @@ nsFrame::SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange, PRBool a
}
}
#endif
#ifdef IBMBIDI
PRInt32 start, end;
nsIFrame* frame;
GetNextSibling(&frame);
if (frame){
GetFirstLeaf(aPresContext, &frame);
GetOffsets(start, end);
if (start && end) {
frame->SetSelected(aPresContext, aRange, aSelected, aSpread);
}
}
#endif // IBMBIDI
return NS_OK;
}
@ -2776,7 +2788,13 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
nsIView * view; //used for call of get offset from view
aBlockFrame->GetOffsetFromView(aPresContext, offset,&view);
nscoord newDesiredX = aPos->mDesiredX - offset.x;//get desired x into blockframe coordinates!
#ifdef IBMBIDI
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
result = it->FindFrameAt(searchingLine, newDesiredX, bidiEnabled, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
#else
result = it->FindFrameAt(searchingLine, newDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
#endif // IBMBIDI
if(NS_FAILED(result))
continue;
}
@ -3463,6 +3481,26 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
PRInt32 lineFrameCount;
PRUint32 lineFlags;
#ifdef IBMBIDI
/* Check whether the visual and logical order of the frames are different */
PRBool lineIsReordered = PR_FALSE;
nsIFrame *firstVisual;
nsIFrame *lastVisual;
PRBool lineIsRTL;
PRBool lineJump = PR_FALSE;
it->GetDirection(&lineIsRTL);
result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual);
if (NS_FAILED(result))
return result;
if (lineIsReordered) {
firstFrame = firstVisual;
lastFrame = lastVisual;
}
else
#endif
{
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
@ -3476,15 +3514,30 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
return NS_ERROR_FAILURE;
}
}
}
GetFirstLeaf(aPresContext, &firstFrame);
GetLastLeaf(aPresContext, &lastFrame);
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
if
#ifndef IBMBIDI // jumping lines in RTL paragraphs
((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
#else
(((lineIsRTL) &&
((aPos->mDirection == eDirNext && firstFrame == this)
||(aPos->mDirection == eDirPrevious && lastFrame == this)))
||
((!lineIsRTL) &&
((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))))
#endif
{
if (aPos->mJumpLines != PR_TRUE)
return NS_ERROR_FAILURE;//we are done. cannot jump lines
#ifdef IBMBIDI
lineJump = PR_TRUE;
#endif
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
@ -3504,10 +3557,30 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
#ifdef IBMBIDI
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
(lineIsReordered) ? VISUAL : LEAF,
aPresContext,
(lineJump && lineIsRTL)
? (aPos->mDirection == eDirNext) ? lastFrame : firstFrame
: this);
#else
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF, aPresContext, this);
#endif
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
#ifdef IBMBIDI
nsIFrame *newFrame;
nsRect testRect;
while (testRect.IsEmpty()) {
if (lineIsRTL && lineJump)
if (aPos->mDirection == eDirPrevious)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
else
#endif
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
@ -3522,7 +3595,80 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
#ifndef IBMBIDI
nsIFrame *newFrame = (nsIFrame *)isupports;
#else
newFrame = (nsIFrame *)isupports;
newFrame->GetRect(testRect);
if (testRect.IsEmpty()) { // this must be a non-renderable frame creatd at the end of the line by Bidi reordering
lineJump = PR_TRUE;
aPos->mAmount = eSelectNoAmount;
}
}
PRBool newLineIsRTL = PR_FALSE;
if (lineJump) {
blockFrame = newFrame;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
it->GetDirection(&newLineIsRTL);
result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual);
if (NS_FAILED(result))
return result;
if (lineIsReordered)
{
firstFrame = firstVisual;
lastFrame = lastVisual;
}
else
{
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
}
GetFirstLeaf(aPresContext, &firstFrame);
GetLastLeaf(aPresContext, &lastFrame);
if (newLineIsRTL) {
if (aPos->mDirection == eDirPrevious)
newFrame = firstFrame;
else
newFrame = lastFrame;
}
else {
if (aPos->mDirection == eDirNext)
newFrame = firstFrame;
else
newFrame = lastFrame;
}
}
#endif // IBMBIDI
PRBool selectable;
newFrame->IsSelectable(&selectable, nsnull);
if (!selectable)
@ -3531,6 +3677,18 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
#ifdef IBMBIDI
long oldLevel, newLevel, baseLevel;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&oldLevel);
newFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&newLevel);
newFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, (void**)&baseLevel);
if (newLevel & 1) // The new frame is RTL, go to the other end
aPos->mStartOffset = -1 - aPos->mStartOffset;
if ((aPos->mAmount == eSelectNoAmount) && ((newLevel & 1) != (oldLevel & 1))) {
aPos->mPreferLeft = !(aPos->mPreferLeft);
}
#endif
aPos->mResultFrame = newFrame;
return NS_OK;
}
@ -3771,6 +3929,63 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
return PR_FALSE;
}
#ifdef IBMBIDI
/**
* retrieve Bidi property of this frame
* @lina 5/1/2000
*/
nsresult nsFrame::GetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void** aPropertyValue,
long aSize) const
{
if (!aPropertyValue || !aPropertyName) {
return NS_ERROR_NULL_POINTER;
}
if ( (aSize < 1) || (aSize > sizeof(void*) ) ) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsCRT::zero(aPropertyValue, aSize);
void* val = nsnull;
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell) );
if (presShell) {
nsCOMPtr<nsIFrameManager> frameManager;
presShell->GetFrameManager(getter_AddRefs(frameManager) );
if (frameManager) {
frameManager->GetFrameProperty( (nsIFrame*)this, aPropertyName, 0, &val);
if (val) {
nsCRT::memcpy(aPropertyValue, &val, aSize);
}
}
}
return NS_OK;
}
nsresult nsFrame::SetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void* aPropertyValue) const
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell) );
if (shell) {
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager) );
if (frameManager) {
rv = frameManager->SetFrameProperty( (nsIFrame*) this, aPropertyName, aPropertyValue, nsnull);
}
}
return rv;
}
#endif // IBMBIDI
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,

View File

@ -368,6 +368,15 @@ public:
//Mouse Capturing code used by the frames to tell the view to capture all the following events
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
#ifdef IBMBIDI
NS_IMETHOD GetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void** aPropertyValue,
long aSize = sizeof(void*) ) const;
NS_IMETHOD SetBidiProperty(nsIPresContext* aPresContext,
nsIAtom* aPropertyName,
void* aPropertyValue) const ;
#endif // IBMBIDI
#ifdef NS_DEBUG
/**

View File

@ -805,6 +805,20 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext,
return rv;
}
#ifdef IBMBIDI
if (aPrevFrame) {
// Insert aFrameList after the last bidi continuation of aPrevFrame.
nsIFrame* nextBidi;
for (; ;) {
GetFrameProperty(aPrevFrame, nsLayoutAtoms::nextBidi, 0, (void**) &nextBidi);
if (!nextBidi) {
break;
}
aPrevFrame = nextBidi;
}
}
#endif // IBMBIDI
return aParentFrame->InsertFrames(aPresContext, aPresShell, aListName,
aPrevFrame, aFrameList);
}
@ -822,6 +836,15 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext,
if (insertionPoint)
return insertionPoint->RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
#ifdef IBMBIDI
// Don't let the parent remove next bidi. In the other cases the it should NOT be removed.
nsIFrame* nextBidi;
GetFrameProperty(aOldFrame, nsLayoutAtoms::nextBidi, 0, (void**) &nextBidi);
if (nextBidi) {
RemoveFrame(aPresContext, aPresShell, aParentFrame, aListName, nextBidi);
}
#endif // IBMBIDI
return aParentFrame->RemoveFrame(aPresContext, aPresShell, aListName,
aOldFrame);
}

View File

@ -66,6 +66,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mLineLayout = nsnull;
isTopOfPage = PR_FALSE;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = NS_UNCONSTRAINEDSIZE;
#endif
}
// Initialize a <b>root</b> reflow state for an <b>incremental</b>
@ -90,6 +93,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mLineLayout = nsnull;
isTopOfPage = PR_FALSE;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = NS_UNCONSTRAINEDSIZE;
#endif // IBMBIDI
}
// Initialize a reflow state for a child frames reflow. Some state
@ -117,6 +123,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
// Same as the previous except that the reason is taken from the
@ -140,6 +150,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
// Version that species the containing block width and height
@ -164,6 +178,10 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
isTopOfPage = aParentReflowState.isTopOfPage;
Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
#ifdef IBMBIDI
mRightEdge = aParentReflowState.mRightEdge;
#endif // IBMBIDI
}
void
@ -1833,6 +1851,18 @@ nsHTMLReflowState::ComputeBlockBoxData(nsIPresContext* aPresContext,
AdjustComputedWidth();
#ifdef IBMBIDI
// See what edge the width applies to (the default is the content
// edge)
if (mComputedWidth != NS_UNCONSTRAINEDSIZE) {
if (mStylePosition->mBoxSizing == NS_STYLE_BOX_SIZING_PADDING) {
mComputedWidth -= mComputedPadding.left + mComputedPadding.right;
} else if (mStylePosition->mBoxSizing == NS_STYLE_BOX_SIZING_BORDER) {
mComputedWidth -= mComputedBorderPadding.left + mComputedBorderPadding.right;
}
}
#endif // IBMBIDI
// Now that we have the computed-width, compute the side margins
CalculateBlockSideMargins(cbrs->mComputedWidth, mComputedWidth);
}

View File

@ -122,12 +122,18 @@ nsInlineFrame::InsertFrames(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
if (nsnull != aListName) {
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif
return NS_ERROR_INVALID_ARG;
}
if (aFrameList) {
// Insert frames after aPrevFrame
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
#ifdef IBMBIDI
if (nsnull == aListName)
#endif
// Ask the parent frame to reflow me.
ReflowDirtyChild(&aPresShell, nsnull);
}
@ -141,6 +147,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIFrame* aOldFrame)
{
if (nsnull != aListName) {
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif
return NS_ERROR_INVALID_ARG;
}
@ -151,6 +160,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
aOldFrame->GetParent(&oldFrameParent);
nsInlineFrame* parent = (nsInlineFrame*) oldFrameParent;
while (nsnull != aOldFrame) {
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName) {
#endif
// If the frame being removed has zero size then don't bother
// generating a reflow command, otherwise make sure we do.
nsRect bbox;
@ -158,6 +170,9 @@ nsInlineFrame::RemoveFrame(nsIPresContext* aPresContext,
if (bbox.width || bbox.height) {
generateReflowCommand = PR_TRUE;
}
#ifdef IBMBIDI
}
#endif
// When the parent is an inline frame we have a simple task - just
// remove the frame from its parents list and generate a reflow

View File

@ -653,9 +653,125 @@ nsLineIterator::FindLineAt(nscoord aY,
return NS_OK;
}
#ifdef IBMBIDI
NS_IMETHODIMP
nsLineIterator::CheckLineOrder(PRInt32 aLine,
PRBool *aIsReordered,
nsIFrame **aFirstVisual,
nsIFrame **aLastVisual)
{
nsRect checkRect;
PRInt32 currentLine, saveLine, testLine;
nscoord saveX;
nsIFrame *checkFrame;
nsIFrame *firstFrame;
nsIFrame *leftmostFrame;
nsIFrame *rightmostFrame;
nscoord minX, maxX;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
nsresult result;
// an RTL paragraph is always considered as reordered
// in an LTR paragraph, find out by examining the coordinates of each frame in the line
if (mRightToLeft)
*aIsReordered = PR_TRUE;
else {
*aIsReordered = PR_FALSE;
// Check the preceding and following line, since we might be moving into them
for (currentLine = PR_MAX(0, aLine-1); currentLine < aLine+1; currentLine++) {
nsLineBox* line = mLines[currentLine];
if (!line)
break;
checkFrame = line->mFirstChild;
checkFrame->GetRect(checkRect);
result = FindLineContaining(checkFrame, &saveLine);
if (NS_FAILED(result))
return result;
saveX = checkRect.x;
lineFrameCount = line->GetChildCount();
for (; checkFrame; result = checkFrame->GetNextSibling(&checkFrame)) {
if (NS_FAILED(result))
break;
result = FindLineContaining(checkFrame, &testLine);
if (NS_FAILED(result))
return result;
if (testLine != saveLine) {
*aIsReordered = PR_TRUE;
break;
}
checkFrame->GetRect(checkRect);
// If the origin of any frame is less than the previous frame, the line is reordered
if (checkRect.x < saveX) {
*aIsReordered = PR_TRUE;
break;
}
saveX = checkRect.x;
lineFrameCount--;
if (0 == lineFrameCount)
break;
}
if (*aIsReordered)
break;
}
}
// If the line is reordered, identify the first and last frames on the line
if (*aIsReordered) {
nsRect nonUsedRect;
result = GetLine(aLine, &firstFrame, &lineFrameCount, nonUsedRect, &lineFlags);
if (NS_FAILED(result))
return result;
leftmostFrame = rightmostFrame = firstFrame;
firstFrame->GetRect(checkRect);
maxX = checkRect.x;
minX = checkRect.x;
for (;lineFrameCount > 1;lineFrameCount--) {
result = firstFrame->GetNextSibling(&firstFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsLineBox\n");
return NS_ERROR_FAILURE;
}
firstFrame->GetRect(checkRect);
if (checkRect.x > maxX) {
maxX = checkRect.x;
rightmostFrame = firstFrame;
}
if (checkRect.x < minX) {
minX = checkRect.x;
leftmostFrame = firstFrame;
}
}
if (mRightToLeft) {
*aFirstVisual = rightmostFrame;
*aLastVisual = leftmostFrame;
}
else {
*aFirstVisual = leftmostFrame;
*aLastVisual = rightmostFrame;
}
}
return result;
}
#endif // IBMBIDI
NS_IMETHODIMP
nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
#ifdef IBMBIDI
PRBool aCouldBeReordered,
#endif // IBMBIDI
nsIFrame** aFrameFound,
PRBool* aXIsBeforeFirstFrame,
PRBool* aXIsAfterLastFrame)
@ -709,12 +825,50 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
// when checking.
*aXIsBeforeFirstFrame = PR_FALSE;
*aXIsAfterLastFrame = PR_FALSE;
#ifdef IBMBIDI
PRBool isReordered = PR_FALSE;
nsIFrame *firstVisual, *lastVisual;
if (aCouldBeReordered)
CheckLineOrder(aLineNumber, &isReordered, &firstVisual, &lastVisual);
#endif
nsRect r1, r2;
nsIFrame* frame = line->mFirstChild;
#ifdef IBMBIDI
if (isReordered)
frame = firstVisual;
#endif // IBMBIDI
PRInt32 n = line->GetChildCount();
if (mRightToLeft) {
while (--n >= 0) {
nsIFrame* nextFrame;
#ifdef IBMBIDI
if (isReordered) {
nscoord maxX, limX;
PRInt32 testLine;
nsRect tempRect;
nsIFrame* tempFrame;
maxX = -0x7fffffff;
frame->GetRect(tempRect);
limX = tempRect.x;
tempFrame = line->mFirstChild;
nextFrame = nsnull;
while (tempFrame) {
if (NS_SUCCEEDED(FindLineContaining(tempFrame, &testLine))
&& testLine == aLineNumber) {
tempFrame->GetRect(tempRect);
if (tempRect.x > maxX && tempRect.x < limX) { // we are looking for the highest value less than the current one
maxX = tempRect.x;
nextFrame = tempFrame;
}
}
tempFrame->GetNextSibling(&tempFrame);
}
}
else
#endif // IBMBIDI
frame->GetNextSibling(&nextFrame);
frame->GetRect(r1);
if (aX > r1.x) {
@ -740,6 +894,34 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
else {
while (--n >= 0) {
nsIFrame* nextFrame;
#ifdef IBMBIDI
if (isReordered) {
nsRect tempRect;
nsIFrame* tempFrame;
PRInt64 minX, limX;
PRInt32 testLine;
minX = 0x7fffffff;
frame->GetRect(tempRect);
limX = tempRect.x;
tempFrame = line->mFirstChild;
nextFrame = nsnull;
while (tempFrame) {
if (NS_SUCCEEDED(FindLineContaining(tempFrame, &testLine))
&& testLine == aLineNumber) {
tempFrame->GetRect(tempRect);
if (tempRect.x < minX && tempRect.x > limX) { // we are looking for the lowest value greater than the current one
minX = tempRect.x;
nextFrame = tempFrame;
}
}
tempFrame->GetNextSibling(&tempFrame);
}
}
else
#endif // IBMBIDI
frame->GetNextSibling(&nextFrame);
frame->GetRect(r1);
if (aX < r1.XMost()) {

View File

@ -412,12 +412,20 @@ public:
PRInt32* aLineNumberResult);
NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
#ifdef IBMBIDI
PRBool aCouldBeReordered,
#endif
nsIFrame** aFrameFound,
PRBool* aXIsBeforeFirstFrame,
PRBool* aXIsAfterLastFrame);
NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, PRInt32 aLineNumber);
#ifdef IBMBIDI
NS_IMETHOD CheckLineOrder(PRInt32 aLine,
PRBool *aIsReordered,
nsIFrame **aFirstVisual,
nsIFrame **aLastVisual);
#endif
nsresult Init(nsLineBox* aLines, PRBool aRightToLeft);
protected:

View File

@ -135,6 +135,10 @@
// SubShell map
#include "nsDST.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
#endif // IBMBIDI
#include "nsContentCID.h"
static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID);
@ -886,6 +890,12 @@ public:
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
NS_IMETHOD IsReflowLocked(PRBool* aIsLocked);
#ifdef IBMBIDI
NS_IMETHOD SetCursorBidiLevel(PRUint8 aLevel);
NS_IMETHOD GetCursorBidiLevel(PRUint8 *aOutLevel);
NS_IMETHOD UndefineCursorBidiLevel();
NS_IMETHOD BidiStyleChangeReflow();
#endif
//nsIViewObserver interface
@ -1022,6 +1032,10 @@ protected:
PRBool IsDragInProgress ( ) const ;
PRBool mCaretEnabled;
#ifdef IBMBIDI
PRUint8 mBidiLevel; // The Bidi level of the cursor
nsCOMPtr<nsIBidiKeyboard> mBidiKeyboard;
#endif // IBMBIDI
#ifdef NS_DEBUG
PRBool VerifyIncrementalReflow();
PRBool mInVerifyReflow;
@ -1246,6 +1260,9 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
mReflowCountMgr->SetPresContext(mPresContext);
mReflowCountMgr->SetPresShell(this);
#endif
#ifdef IBMBIDI
mBidiLevel = BIDI_LEVEL_UNDEFINED;
#endif
}
NS_IMPL_ADDREF(PresShell)
@ -1479,6 +1496,9 @@ PresShell::Init(nsIDocument* aDocument,
// cache the drag service so we can check it during reflows
mDragService = do_GetService("@mozilla.org/widget/dragservice;1");
#ifdef IBMBIDI
mBidiKeyboard = do_GetService("@mozilla.org/widget/bidikeyboard;1");
#endif
// setup the preference style rules up (no forced reflow)
SetPreferenceStyleRules(PR_FALSE);
@ -4535,6 +4555,55 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
return rv;
}
#ifdef IBMBIDI
NS_IMETHODIMP
PresShell::SetCursorBidiLevel(PRUint8 aLevel)
{
// If the current level is undefined, we have just inserted new text.
// In this case, we don't want to reset the keyboard language
PRBool afterInsert = mBidiLevel & BIDI_LEVEL_UNDEFINED;
mBidiLevel = aLevel;
// PRBool parityChange = ((mBidiLevel ^ aLevel) & 1); // is the parity of the new level different from the current level?
// if (parityChange) // if so, change the keyboard language
if (mBidiKeyboard && !afterInsert)
mBidiKeyboard->SetLangFromBidiLevel(aLevel);
return NS_OK;
}
NS_IMETHODIMP
PresShell::GetCursorBidiLevel(PRUint8 *aOutLevel)
{
if (!aOutLevel) { return NS_ERROR_INVALID_ARG; }
*aOutLevel = mBidiLevel;
return NS_OK;
}
NS_IMETHODIMP
PresShell::UndefineCursorBidiLevel()
{
mBidiLevel |= BIDI_LEVEL_UNDEFINED;
return NS_OK;
}
NS_IMETHODIMP
PresShell::BidiStyleChangeReflow()
{
// Have the root frame's style context remap its style
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
if (rootFrame) {
nsIStyleContext* rootStyleContext;
rootFrame->GetStyleContext(&rootStyleContext);
rootStyleContext->RemapStyle(mPresContext.get() );
NS_RELEASE(rootStyleContext);
ReconstructFrames();
}
return NS_OK;
}
#endif // IBMBIDI
//nsIViewObserver