bug 74946; author=simon@softel.co.il; r=erik; sr=attinasi; diffs from IBM

bidi project (e.g. Arabic, Hebrew)
This commit is contained in:
erik%netscape.com 2001-04-11 23:32:21 +00:00
parent c83b74d6be
commit 3f8707c9fb
11 changed files with 1595 additions and 32 deletions

View File

@ -34,6 +34,7 @@
#include "nsIServiceManager.h"
#include "nsIFrameManager.h"
#include "nsBidiFrames.h"
#include "nsITextFrame.h"
#include "nsIUBidiUtils.h"
static const PRUnichar kSpace = 0x0020;
@ -214,7 +215,7 @@ nsBidiPresUtils::Resolve(nsIPresContext* aPresContext,
PRBool isTextFrame;
nsIFrame* frame = nsnull;
nsIFrame* nextBidi;
nsBidiTextFrame* textFrame;
nsITextFrame* textFrame;
nsCOMPtr<nsIAtom> frameType;
nsCOMPtr<nsIContent> content;
nsCOMPtr<nsITextContent> textContent;
@ -291,17 +292,25 @@ nsBidiPresUtils::Resolve(nsIPresContext* aPresContext,
&nextBidi, frameIndex) ) {
break;
}
frame->QueryInterface(NS_GET_IID(nsBidiTextFrame), (void**) &textFrame);
frame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
textFrame->SetOffsets(contentOffset, contentOffset + runLength);
nsFrameState frameState;
frame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
frame->SetFrameState(frameState);
}
frame = nextBidi;
contentOffset += runLength;
} // if (runLength < fragmentLength)
else {
frame->QueryInterface(NS_GET_IID(nsBidiTextFrame), (void**) &textFrame);
frame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
textFrame->SetOffsets(contentOffset, contentOffset + fragmentLength);
nsFrameState frameState;
frame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
frame->SetFrameState(frameState);
}
frame->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
@ -550,8 +559,8 @@ nsBidiPresUtils::RepositionInlineFrames(nsIPresContext* aPresContext,
PRInt32 i;
#ifdef FIX_FOR_BUG_40882
long ch;
long charType;
PRInt32 ch;
PRInt32 charType;
nscoord width, dWidth, alefWidth = 0, dx = 0;
PRUnichar buf[2] = {ALEF, 0x0000};
@ -608,7 +617,7 @@ nsBidiPresUtils::RepositionInlineFrames(nsIPresContext* aPresContext,
#ifdef FIX_FOR_BUG_40882
if (dx > 0) {
long alignRight;
PRInt32 alignRight;
frame->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel,
(void**) &alignRight);
if (0 == (alignRight & 1) ) {
@ -840,9 +849,9 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
}
// ahmed
//adjusted for correct numeral shaping
nsBidiOptions mBidioptions;
aPresContext->GetBidi(&mBidioptions);
switch (GET_BIDI_OPTION_NUMERAL(mBidioptions)) {
PRUint32 bidiOptions;
aPresContext->GetBidi(&bidiOptions);
switch (GET_BIDI_OPTION_NUMERAL(bidiOptions)) {
case IBMBIDI_NUMERAL_HINDI:
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_HINDI);
@ -870,7 +879,7 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
break;
case IBMBIDI_NUMERAL_HINDICONTEXT:
if ( ( (GET_BIDI_OPTION_DIRECTION(mBidioptions)==IBMBIDI_TEXTDIRECTION_RTL) && (IS_ARABIC_DIGIT (aText[0])) ) || (eCharType_ArabicNumber == aCharType) )
if ( ( (GET_BIDI_OPTION_DIRECTION(bidiOptions)==IBMBIDI_TEXTDIRECTION_RTL) && (IS_ARABIC_DIGIT (aText[0])) ) || (eCharType_ArabicNumber == aCharType) )
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_HINDI);
else if (eCharType_EuropeanNumber == aCharType)
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_ARABIC);
@ -886,9 +895,11 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
PRBool doReverse = PR_FALSE;
printf("aCharType is %d\n", aCharType);
if (aIsBidiSystem) {
if (CHARTYPE_IS_RTL(aCharType) ^ aIsOddLevel) {
doReverse = PR_TRUE;
printf("doReverse set to TRUE\n");
}
}
else if (aIsOddLevel) {
@ -915,6 +926,7 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
(PRUint32 *)&newLen);
} // eCharType_RightToLeftArabic
else {
printf("reversing buffer\n");
rv = mBidiEngine->WriteReverse(aText, aTextLength, buffer,
NSBIDI_REMOVE_BIDI_CONTROLS | NSBIDI_DO_MIRRORING,
&newLen);

View File

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* IBM Corporation. Portions created by IBM are
* Copyright (C) 2000 IBM Corporation.
* All Rights Reserved.
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsITextFrame_h___
#define nsITextFrame_h___
#include "nsISupports.h"
// {2DC80A03-66EF-11d4-BA58-006008CD3717}
#define NS_ITEXTFRAME_IID \
{ 0x2dc80a03, 0x66ef, 0x11d4, { 0xba, 0x58, 0x00, 0x60, 0x08, 0xcd, 0x37, 0x17 } }
class nsITextFrame : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITEXTFRAME_IID)
NS_IMETHOD SetOffsets(PRInt32 aStart, PRInt32 aEnd) = 0;
};
#endif /* nsITextFrame_h___ */

View File

@ -34,6 +34,7 @@
#include "nsIServiceManager.h"
#include "nsIFrameManager.h"
#include "nsBidiFrames.h"
#include "nsITextFrame.h"
#include "nsIUBidiUtils.h"
static const PRUnichar kSpace = 0x0020;
@ -214,7 +215,7 @@ nsBidiPresUtils::Resolve(nsIPresContext* aPresContext,
PRBool isTextFrame;
nsIFrame* frame = nsnull;
nsIFrame* nextBidi;
nsBidiTextFrame* textFrame;
nsITextFrame* textFrame;
nsCOMPtr<nsIAtom> frameType;
nsCOMPtr<nsIContent> content;
nsCOMPtr<nsITextContent> textContent;
@ -291,17 +292,25 @@ nsBidiPresUtils::Resolve(nsIPresContext* aPresContext,
&nextBidi, frameIndex) ) {
break;
}
frame->QueryInterface(NS_GET_IID(nsBidiTextFrame), (void**) &textFrame);
frame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
textFrame->SetOffsets(contentOffset, contentOffset + runLength);
nsFrameState frameState;
frame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
frame->SetFrameState(frameState);
}
frame = nextBidi;
contentOffset += runLength;
} // if (runLength < fragmentLength)
else {
frame->QueryInterface(NS_GET_IID(nsBidiTextFrame), (void**) &textFrame);
frame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
textFrame->SetOffsets(contentOffset, contentOffset + fragmentLength);
nsFrameState frameState;
frame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
frame->SetFrameState(frameState);
}
frame->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi,
(void**) &nextBidi);
@ -550,8 +559,8 @@ nsBidiPresUtils::RepositionInlineFrames(nsIPresContext* aPresContext,
PRInt32 i;
#ifdef FIX_FOR_BUG_40882
long ch;
long charType;
PRInt32 ch;
PRInt32 charType;
nscoord width, dWidth, alefWidth = 0, dx = 0;
PRUnichar buf[2] = {ALEF, 0x0000};
@ -608,7 +617,7 @@ nsBidiPresUtils::RepositionInlineFrames(nsIPresContext* aPresContext,
#ifdef FIX_FOR_BUG_40882
if (dx > 0) {
long alignRight;
PRInt32 alignRight;
frame->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel,
(void**) &alignRight);
if (0 == (alignRight & 1) ) {
@ -840,9 +849,9 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
}
// ahmed
//adjusted for correct numeral shaping
nsBidiOptions mBidioptions;
aPresContext->GetBidi(&mBidioptions);
switch (GET_BIDI_OPTION_NUMERAL(mBidioptions)) {
PRUint32 bidiOptions;
aPresContext->GetBidi(&bidiOptions);
switch (GET_BIDI_OPTION_NUMERAL(bidiOptions)) {
case IBMBIDI_NUMERAL_HINDI:
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_HINDI);
@ -870,7 +879,7 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
break;
case IBMBIDI_NUMERAL_HINDICONTEXT:
if ( ( (GET_BIDI_OPTION_DIRECTION(mBidioptions)==IBMBIDI_TEXTDIRECTION_RTL) && (IS_ARABIC_DIGIT (aText[0])) ) || (eCharType_ArabicNumber == aCharType) )
if ( ( (GET_BIDI_OPTION_DIRECTION(bidiOptions)==IBMBIDI_TEXTDIRECTION_RTL) && (IS_ARABIC_DIGIT (aText[0])) ) || (eCharType_ArabicNumber == aCharType) )
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_HINDI);
else if (eCharType_EuropeanNumber == aCharType)
mUnicodeUtils->HandleNumbers(aText,aTextLength,IBMBIDI_NUMERAL_ARABIC);
@ -886,9 +895,11 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
PRBool doReverse = PR_FALSE;
printf("aCharType is %d\n", aCharType);
if (aIsBidiSystem) {
if (CHARTYPE_IS_RTL(aCharType) ^ aIsOddLevel) {
doReverse = PR_TRUE;
printf("doReverse set to TRUE\n");
}
}
else if (aIsOddLevel) {
@ -915,6 +926,7 @@ nsBidiPresUtils::FormatUnicodeText(nsIPresContext* aPresContext,
(PRUint32 *)&newLen);
} // eCharType_RightToLeftArabic
else {
printf("reversing buffer\n");
rv = mBidiEngine->WriteReverse(aText, aTextLength, buffer,
NSBIDI_REMOVE_BIDI_CONTROLS | NSBIDI_DO_MIRRORING,
&newLen);

View File

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* IBM Corporation. Portions created by IBM are
* Copyright (C) 2000 IBM Corporation.
* All Rights Reserved.
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
* Contributor(s):
*/
#ifdef IBMBIDI
#include "nsBidiFrames.h"
#include "nsLayoutAtoms.h"
nsDirectionalFrame::nsDirectionalFrame(PRUnichar aChar)
: mChar(aChar)
{
}
nsDirectionalFrame::~nsDirectionalFrame()
{
}
PRUnichar
nsDirectionalFrame::GetChar(void) const
{
return mChar;
}
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::directionalFrame
*/
NS_IMETHODIMP
nsDirectionalFrame::GetFrameType(nsIAtom** aType) const
{
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
*aType = nsLayoutAtoms::directionalFrame;
NS_ADDREF(*aType);
return NS_OK;
}
const nsIID&
nsDirectionalFrame::GetIID()
{
static nsIID iid = NS_DIRECTIONAL_FRAME_IID;
return iid;
}
NS_IMETHODIMP
nsDirectionalFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
nsresult rv = NS_NOINTERFACE;
if (!aInstancePtr) {
rv = NS_ERROR_NULL_POINTER;
}
else if (aIID.Equals(NS_GET_IID(nsDirectionalFrame) ) ) {
*aInstancePtr = (void*) this;
rv = NS_OK;
}
return rv;
}
void*
nsDirectionalFrame::operator new(size_t aSize)
{
void* frame = ::operator new(aSize);
if (frame) {
nsCRT::zero(frame, aSize);
}
return frame;
}
nsresult
NS_NewDirectionalFrame(nsIFrame** aNewFrame, PRUnichar aChar)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsDirectionalFrame* frame = new nsDirectionalFrame(aChar);
*aNewFrame = frame;
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
#endif /* IBMBIDI */

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* IBM Corporation. Portions created by IBM are
* Copyright (C) 2000 IBM Corporation.
* All Rights Reserved.
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
* Contributor(s):
*/
#ifdef IBMBIDI
#ifndef nsBidiFrames_h___
#define nsBidiFrames_h___
#include "nsFrame.h"
// IID for the nsDirectionalFrame interface
// {90D69900-67AF-11d4-BA59-006008CD3717}
#define NS_DIRECTIONAL_FRAME_IID \
{ 0x90d69900, 0x67af, 0x11d4, { 0xba, 0x59, 0x00, 0x60, 0x08, 0xcd, 0x37, 0x17 } }
class nsDirectionalFrame : public nsFrame
{
protected:
virtual ~nsDirectionalFrame();
public:
nsDirectionalFrame(PRUnichar aChar);
void* operator new(size_t aSize);
static const nsIID& GetIID();
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
PRUnichar GetChar(void) const;
private:
PRUnichar mChar;
};
#endif /* nsBidiFrames_h___ */
#endif /* IBMBIDI */

View File

@ -46,6 +46,12 @@
#include "nsIViewManager.h"
#include "nsHTMLAtoms.h"
#include "nsTextFragment.h"
#ifdef IBMBIDI
#include "nsIUBidiUtils.h"
#include "nsIFormControlFrame.h"
#include "nsITextFrame.h"
#define FIX_FOR_BUG_40882
#endif // IBMBIDI
#ifdef DEBUG
#undef NOISY_HORIZONTAL_ALIGN
@ -916,8 +922,44 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
nscoord ty = y - psd->mReflowState->mComputedBorderPadding.top;
mSpaceManager->Translate(tx, ty);
#ifdef IBMBIDI
PRBool bidiEnabled;
mPresContext->BidiEnabled(bidiEnabled);
PRBool visual;
PRBool setMode = PR_FALSE;
PRInt32 start, end;
if (bidiEnabled) {
if (state & NS_FRAME_IS_BIDI) {
aFrame->GetOffsets(start, end);
}
else {
nsCOMPtr<nsIFormControlFrame> formFrame(do_QueryInterface(aFrame) );
if (formFrame) {
mPresContext->IsVisualMode(visual);
PRUint32 options;
mPresContext->GetBidi(&options);
if ( (IBMBIDI_CONTROLSTEXTMODE_VISUAL == GET_BIDI_OPTION_CONTROLSTEXTMODE(options)
&& !visual)
|| (IBMBIDI_CONTROLSTEXTMODE_LOGICAL == GET_BIDI_OPTION_CONTROLSTEXTMODE(options)
&& visual) ) {
mPresContext->SetVisualMode(!visual);
setMode = PR_TRUE;
}
}
}
}
#endif // IBMBIDI
aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus);
#ifdef IBMBIDI
if (setMode) {
mPresContext->SetVisualMode(visual);
}
#endif // IBMBIDI
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
@ -1011,6 +1053,21 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
if (NS_SUCCEEDED(result)) {
pfd->SetFlag(PFD_ISNONWHITESPACETEXTFRAME, !isWhitespace);
}
// fix for bug 40882
#ifdef IBMBIDI
const nsTextFragment* frag;
textContent->GetText(&frag);
if (frag && frag->Is2b() ) {
//PRBool isVisual;
//mPresContext->IsVisualMode(isVisual);
PRUnichar ch = /*(isVisual) ?
*(frag->Get2b() + frag->GetLength() - 1) :*/ *frag->Get2b();
if (IS_BIDI_DIACRITIC(ch) ) {
aFrame->SetBidiProperty(mPresContext,
nsLayoutAtoms::endsInDiacritic, (void*)ch);
}
}
#endif // IBMBIDI
}
}
}
@ -1168,6 +1225,45 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
nsFrame::ListTag(stdout, aFrame);
printf(" status=%x\n", aReflowStatus);
#endif
#ifdef IBMBIDI
if (state & NS_FRAME_IS_BIDI) {
nsITextFrame* textFrame = nsnull;
aFrame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
// Since aReflowStatus may change, check it at the end
if (NS_INLINE_IS_BREAK_BEFORE(aReflowStatus) ) {
textFrame->SetOffsets(start, end);
nsFrameState frameState;
aFrame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
aFrame->SetFrameState(frameState);
}
else if (!NS_FRAME_IS_COMPLETE(aReflowStatus) ) {
PRInt32 newEnd;
aFrame->GetOffsets(start, newEnd);
if (newEnd != end) {
nsIFrame* nextInFlow;
aFrame->GetNextInFlow(&nextInFlow);
if (nextInFlow) {
nsITextFrame* nextTextInFlow = nsnull;
nextInFlow->QueryInterface(NS_GET_IID(nsITextFrame),
(void**) &nextTextInFlow);
if (nextTextInFlow) {
nextInFlow->GetOffsets(start, end);
nextTextInFlow->SetOffsets(newEnd, end);
nsFrameState frameState;
nextInFlow->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
nextInFlow->SetFrameState(frameState);
}
} // nextInFlow
} // newEnd != end
} // !NS_FRAME_IS_COMPLETE(aReflowStatus)
} // textFrame
} // isBidiFrame
#endif // IBMBIDI
return rv;
}
@ -2469,11 +2565,13 @@ PRBool
nsLineLayout::TrimTrailingWhiteSpaceIn(PerSpanData* psd,
nscoord* aDeltaWidth)
{
#ifndef IBMBIDI
// XXX what about NS_STYLE_DIRECTION_RTL?
if (NS_STYLE_DIRECTION_RTL == psd->mDirection) {
*aDeltaWidth = 0;
return PR_TRUE;
}
#endif
PerFrameData* pfd = psd->mFirstFrame;
if (!pfd) {
@ -2701,6 +2799,13 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
#endif
return PR_TRUE;
}
#ifdef IBMBIDI
if (NS_STYLE_DIRECTION_RTL == psd->mDirection) {
// This is to ensure proper indentation (e.g. of list items)
availWidth -= aLineBounds.x;
}
else
#endif // IBMBIDI
availWidth -= psd->mLeftEdge;
nscoord remainingWidth = availWidth - aLineBounds.width;
#ifdef NOISY_HORIZONTAL_ALIGN
@ -2708,7 +2813,11 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
printf(": availWidth=%d lineWidth=%d delta=%d\n",
availWidth, aLineBounds.width, remainingWidth);
#endif
#ifdef IBMBIDI
if (remainingWidth + aLineBounds.x > 0) {
#else
if (remainingWidth > 0) {
#endif
nscoord dx = 0;
PRUint32 textAlign = mTextAlign;
// here is where we do special adjustments for HR's
@ -2798,7 +2907,37 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
dx = remainingWidth / 2;
break;
}
#ifdef IBMBIDI
PerFrameData* lastPfd = psd->mLastFrame;
PerFrameData* bulletPfd = nsnull;
if (lastPfd->GetFlag(PFD_ISBULLET)
&& (NS_STYLE_DIRECTION_RTL == psd->mDirection) ) {
bulletPfd = lastPfd;
lastPfd = lastPfd->mPrev;
}
PRUint32 maxX = lastPfd->mBounds.XMost() + dx;
PRBool visualRTL = PR_FALSE;
if ( (NS_STYLE_DIRECTION_RTL == psd->mDirection)
&& (!psd->mChangedFrameDirection) ) {
psd->mChangedFrameDirection = PR_TRUE;
/* Assume that all frames have been right aligned.*/
if (aShrinkWrapWidth) {
return PR_FALSE;
}
mPresContext->IsVisualMode(visualRTL);
if (bulletPfd) {
bulletPfd->mBounds.x += maxX;
bulletPfd->mFrame->SetRect(mPresContext, bulletPfd->mBounds);
}
}
if ( (0 != dx) || (visualRTL) ) {
#else
if (0 != dx) {
#endif // IBMBIDI
// If we need to move the frames but we're shrink wrapping, then
// we need to wait until the final width is known
if (aShrinkWrapWidth) {
@ -2806,14 +2945,27 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
}
PerFrameData* pfd = psd->mFirstFrame;
#ifdef IBMBIDI
while ( (nsnull != pfd) && (bulletPfd != pfd) ) {
#else
while (nsnull != pfd) {
#endif // IBMBIDI
pfd->mBounds.x += dx;
#ifdef IBMBIDI
if (visualRTL) {
maxX = pfd->mBounds.x = maxX - pfd->mBounds.width;
}
#endif // IBMBIDI
pfd->mFrame->SetRect(mPresContext, pfd->mBounds);
pfd = pfd->mNext;
}
#ifdef IBMBIDI
aLineBounds.x += dx;
#else
aLineBounds.width += dx;
#endif
}
#ifndef IBMBIDI
if ((NS_STYLE_DIRECTION_RTL == psd->mDirection) &&
!psd->mChangedFrameDirection) {
psd->mChangedFrameDirection = PR_TRUE;
@ -2831,6 +2983,7 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
pfd = pfd->mNext;
}
}
#endif // ndef IBMBIDI
}
return PR_TRUE;

View File

@ -70,6 +70,16 @@
#include "nsIAccessibilityService.h"
#include "nsIMutableAccessible.h"
#ifdef IBMBIDI
#include "nsBidiFrames.h"
#include "nsBidiPresUtils.h"
#include "nsITextFrame.h"
//ahmed
#include "nsIUBidiUtils.h"
//ahmed end
#endif // IBMBIDI
#ifndef PR_ABS
#define PR_ABS(x) ((x) < 0 ? -(x) : (x))
#endif
@ -343,7 +353,11 @@ nsresult nsBlinkTimer::RemoveBlinkFrame(nsIFrame* aFrame)
//----------------------------------------------------------------------
#ifdef IBMBIDI
class nsTextFrame : public nsFrame, public nsITextFrame {
#else
class nsTextFrame : public nsFrame {
#endif
public:
nsTextFrame();
@ -721,6 +735,11 @@ public:
void ToCString(nsString& aBuf, PRInt32* aTotalContentLength) const;
#ifdef IBMBIDI
// nsITextFrame methods here
NS_IMETHOD SetOffsets(PRInt32 aStart, PRInt32 aEnd);
#endif
protected:
virtual ~nsTextFrame();
@ -736,6 +755,11 @@ protected:
PRBool aGetWidth/* true=get width false = return length up to aWidthResult size*/);
nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength);
#ifdef IBMBIDI
private:
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
#endif
};
//-----------------------------------------------------------------------------
@ -781,8 +805,17 @@ NS_IMETHODIMP nsTextFrame::QueryInterface(const nsIID& aIID,
return NS_OK;
}
return NS_ERROR_FAILURE;
#ifdef IBMBIDI
}
if (aIID.Equals(NS_GET_IID(nsITextFrame))) {
*aInstancePtrResult = NS_STATIC_CAST(nsITextFrame*, this);
return NS_OK;
}
return nsFrame::QueryInterface(aIID, aInstancePtrResult);
#else
} else
return nsFrame::QueryInterface(aIID, aInstancePtrResult);
#endif
}
class nsContinuingTextFrame : public nsTextFrame {
@ -825,6 +858,35 @@ nsContinuingTextFrame::Init(nsIPresContext* aPresContext,
// Hook the frame into the flow
mPrevInFlow = aPrevInFlow;
aPrevInFlow->SetNextInFlow(this);
#ifdef IBMBIDI
nsFrameState state;
aPrevInFlow->GetFrameState(&state);
if (state & NS_FRAME_IS_BIDI) {
PRInt32 start, end;
aPrevInFlow->GetOffsets(start, mContentOffset);
void* value;
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::charType, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::charType, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, &value);
if (value) { // nextBidi
// aPrevInFlow and this frame will point to the same next bidi frame.
SetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, value);
( (nsIFrame*) value)->GetOffsets(start, end);
mContentLength = PR_MAX(1, start - mContentOffset);
} // value
mState |= NS_FRAME_IS_BIDI;
} // prev frame is bidi
#endif // IBMBIDI
}
return rv;
@ -1193,6 +1255,20 @@ nsTextFrame::~nsTextFrame()
}
}
#ifdef IBMBIDI
NS_IMETHODIMP_(nsrefcnt) nsTextFrame::AddRef(void)
{
NS_WARNING("not supported for frames");
return 1;
}
NS_IMETHODIMP_(nsrefcnt) nsTextFrame::Release(void)
{
NS_WARNING("not supported for frames");
return 1;
}
#endif // IBMBIDI
nsIDocument*
nsTextFrame::GetDocument(nsIPresContext* aPresContext)
{
@ -1269,6 +1345,13 @@ nsTextFrame::ContentChanged(nsIPresContext* aPresContext,
nsTextFrame* textFrame = this;
while (textFrame) {
textFrame->mState |= NS_FRAME_IS_DIRTY;
#ifdef IBMBIDI
nsIFrame* nextBidi;
textFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextBidi);
if (nextBidi)
textFrame = (nsTextFrame*)nextBidi;
else
#endif
textFrame = (nsTextFrame*)textFrame->mNextInFlow;
}
}
@ -1323,6 +1406,13 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
#ifdef IBMBIDI
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PaintUnicodeText(aPresContext, aRenderingContext, sc, ts, 0, 0);
} else
#endif // IBMBIDI
// If we have ascii text that doesn't contain multi-byte characters
// and the text doesn't need transforming then always render as ascii
if ((0 == (mState & TEXT_WAS_TRANSFORMED)) && !frag->Is2b() && !hasMultiByteChars) {
@ -1375,6 +1465,12 @@ nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
aTX.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed);
// we trip this assertion in bug 31053, but I think it's unnecessary
//NS_ASSERTION(isWhitespace, "mState and content are out of sync");
#ifdef IBMBIDI
if (mState & NS_FRAME_IS_BIDI
&& contentLen > mContentLength) {
contentLen = mContentLength;
}
#endif // IBMBIDI
if (isWhitespace) {
if (nsnull != indexp) {
@ -1406,6 +1502,13 @@ nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
// Get the next word
bp = aTX.GetNextWord(inWord, &wordLen, &contentLen, &isWhitespace, &wasTransformed);
if (nsnull == bp) {
#ifdef IBMBIDI
if (indexp && (mState & NS_FRAME_IS_BIDI) ) {
while (--n >= 0) {
*indexp++ = strInx++;
}
}
#endif // IBMBIDI
break;
}
if (contentLen > n) {
@ -2018,6 +2121,9 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PRBool isSelected;
PRInt16 selectionValue;
nsCOMPtr<nsILineBreaker> lb;
#ifdef IBMBIDI
PRInt32 level = 0;
#endif
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
@ -2056,6 +2162,48 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (0 != textLength)
{
#ifdef IBMBIDI
PRBool isRightToLeftOnBidiPlatform = PR_FALSE;
PRBool isBidiSystem;
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
//mrous
PRBool isVisual;
aPresContext->IsVisualMode(isVisual);
//ahmed
aPresContext->SetIsBidiSystem(isBidiSystem);
if (bidiEnabled) {
nsCharType charType;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**) &level);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**) &charType);
if (isBidiSystem && (eCharType_RightToLeft == charType) ) {
isRightToLeftOnBidiPlatform = PR_TRUE;
}
else if (eCharType_RightToLeftArabic == charType) {
//mrous add visual check to avoid reversing visual docs on bidi systems
// no need since it is already in the FE range, which the system does
// not interpret as bidi
isRightToLeftOnBidiPlatform =
((hints & NS_RENDERING_HINT_ARABIC_SHAPING) && (!isVisual));
}
if (isRightToLeftOnBidiPlatform) {
// indicate that the platform should use its native
// capabilities to reorder the text with right-to-left
// base direction
aRenderingContext.SetRightToLeftText(PR_TRUE);
}
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
bidiUtils->FormatUnicodeText(aPresContext, text, textLength, charType, level & 1, isRightToLeftOnBidiPlatform);
}
}
if (0 != textLength) { // textLength might change due to the bidi formattimg
#endif // IBMBIDI
if (!displaySelection || !isSelected ) //draw text normally
{
// When there is no selection showing, use the fastest and
@ -2096,6 +2244,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame on non-Bidi platform
if ((level & 1) && !(isRightToLeftOnBidiPlatform)) {
PRInt32 swap = sdptr->mStart;
sdptr->mStart = textLength - sdptr->mEnd;
sdptr->mEnd = textLength - swap;
}
#endif
sdptr = sdptr->mNext;
}
//while we have substrings...
@ -2105,6 +2260,12 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
{
nscoord currentX = dx;
nscoord newWidth;//temp
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame
nscoord FrameWidth = 0;
if (isRightToLeftOnBidiPlatform)
if (NS_SUCCEEDED(aRenderingContext.GetWidth(text, textLength, FrameWidth)))
currentX = dx + FrameWidth;
#endif
while (!iter.IsDone())
{
PRUnichar *currenttext = iter.CurrentTextUnicharPtr();
@ -2115,6 +2276,10 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
#ifdef IBMBIDI
if (isRightToLeftOnBidiPlatform)
currentX -= newWidth;
#endif
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
@ -2133,6 +2298,9 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
#ifdef IBMBIDI
if (!isRightToLeftOnBidiPlatform)
#endif
currentX+=newWidth;//increment twips X start
iter.Next();
@ -2154,6 +2322,14 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
delete details;
}
}
#ifdef IBMBIDI
}
if (isRightToLeftOnBidiPlatform) {
// indicate that future text should not be reordered with
// right-to-left base direction
aRenderingContext.SetRightToLeftText(PR_FALSE);
}
#endif // IBMBIDI
}
}
@ -2234,6 +2410,21 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
#ifdef IBMBIDI // Simon -- reverse RTL text here
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
PRBool isOddLevel = (level & 1);
if (isOddLevel) {
PRUnichar *tStart, *tEnd;
PRUnichar tSwap;
for (tStart = paintBuffer.mBuffer, tEnd = tStart + textLength - 1; tEnd > tStart; tStart++, tEnd--) {
tSwap = *tStart;
*tStart = *tEnd;
*tEnd = tSwap;
}
}
#endif // IBMBIDI
ComputeExtraJustificationSpacing(*aRendContext, ts, paintBuffer.mBuffer, textLength, numSpaces);
//IF STYLE SAYS TO SELECT TO END OF FRAME HERE...
@ -2266,6 +2457,11 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
//the following will first get the index into the PAINTBUFFER then the actual content
nscoord adjustedX = PR_MAX(0,aPoint.x-origin.x);
#ifdef IBMBIDI
if (isOddLevel)
aOffset = mContentOffset+textLength-GetLengthSlowly(*aRendContext, ts,paintBuffer.mBuffer,textLength,adjustedX);
else
#endif
aOffset = mContentOffset+GetLengthSlowly(*aRendContext, ts,paintBuffer.mBuffer,textLength,adjustedX);
PRInt32 i;
for (i = 0;i <= mContentLength; i ++){
@ -2629,6 +2825,28 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
PRUnichar* text = paintBuffer.mBuffer;
if (0 != textLength) {
#ifdef IBMBIDI
PRBool isRightToLeft = PR_FALSE;
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
nsCharType charType;
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**) &level);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**) &charType);
if (CHARTYPE_IS_RTL(charType))
isRightToLeft = PR_TRUE;
// Since we paint char by char, handle the text like on non-bidi platform
bidiUtils->FormatUnicodeText(aPresContext, text, textLength, charType, level & 1, PR_FALSE);
}
}
if (0 != textLength) { // textLength might change due to the bidi formattimg
#endif // IBMBIDI
ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces);
if (!displaySelection || !isSelected) {
// When there is no selection showing, use the fastest and
@ -2665,6 +2883,13 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame
if (isRightToLeft) {
PRInt32 swap = sdptr->mStart;
sdptr->mStart = textLength - sdptr->mEnd;
sdptr->mEnd = textLength - swap;
}
#endif
sdptr = sdptr->mNext;
}
@ -2724,6 +2949,9 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
delete details;
}
}
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
}
@ -3090,15 +3318,46 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
PRInt32 indx;
PRInt32 textWidth = 0;
PRUnichar* text = paintBuffer.mBuffer;
#ifdef IBMBIDI
PRBool getReversedPos = PR_FALSE;
PRUint32 hints = 0;
PRBool isVisual;
PRInt32 charType;
GetBidiProperty(aCX, nsLayoutAtoms::charType, (void**)&charType);
acx->GetHints(hints);
aCX->IsVisualMode(isVisual);
if (CHARTYPE_IS_RTL(charType) && !isVisual) {
getReversedPos = PR_TRUE;
}
nscoord posX = (getReversedPos) ?
(mRect.width + origin.x) - (aPoint.x - origin.x) : aPoint.x;
PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
PRInt32(textLength),
PRInt32(posX) , //go to local coordinates
indx, textWidth);
#else
PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
PRInt32(textLength),
PRInt32(aPoint.x) , //go to local coordinates
indx, textWidth);
#endif // IBMBIDI
if (found) {
PRInt32 charWidth;
acx->GetWidth(text[indx], charWidth);
charWidth /= 2;
#ifdef IBMBIDI
if (getReversedPos) {
if (mRect.width - aPoint.x + origin.x > textWidth+charWidth ) {
indx++;
}
}
else
#endif // IBMBIDI
if ((aPoint.x - origin.x) > textWidth+charWidth) {
indx++;
}
@ -3113,6 +3372,11 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
break;
}
}
#ifdef IBMBIDI
while (IS_BIDI_DIACRITIC(text[aContentOffset - mContentOffset]) ) {
aContentOffset++;
}
#endif // IBMBIDI
aContentOffsetEnd = aContentOffset;
NS_ASSERTION(i<= mContentLength, "offset we got from binary search is messed up");
}
@ -3309,6 +3573,12 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext,
if (NS_FAILED(result))
break;
}
#ifdef IBMBIDI
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &frame);
if (frame) {
frame->SetSelected(aPresContext, aRange, aSelected, aSpread);
}
#endif // IBMBIDI
}
return NS_OK;
}
@ -3398,6 +3668,15 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
width += ts.mSpaceWidth + ts.mWordSpacing;
}
}
#ifdef IBMBIDI
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
if (level & 1) {
outPoint->x = mRect.width - width;
}
else
#endif // IBMBIDI
outPoint->x = width;
outPoint->y = 0;
@ -3429,14 +3708,25 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
{
return nextInFlow->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame);
}
else if (contentOffset != mContentLength) //that condition was only for when there is a choice
return NS_ERROR_FAILURE;
else {
#ifdef IBMBIDI // Simon
nsIFrame *nextBidi;
GetNextSibling(&nextBidi);
if (nextBidi)
return nextBidi->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame);
else
#endif // IBMBIDI
{
if (contentOffset != mContentLength) //that condition was only for when there is a choice
return NS_ERROR_FAILURE;
}
}
}
if (inContentOffset < mContentOffset) //could happen with floaters!
{
result = GetPrevInFlow(outChildFrame);
if (NS_SUCCEEDED(result) && outChildFrame)
if (NS_SUCCEEDED(result) && *outChildFrame)
return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, inHint,
outFrameContentOffset,outChildFrame);
else
@ -3452,6 +3742,16 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
NS_IMETHODIMP
nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{
#ifdef IBMBIDI
PRInt32 level, baseLevel;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, (void**)&baseLevel);
PRBool isOddLevel = (level & 1);
if ((eSelectCharacter == aPos->mAmount)
|| (eSelectWord == aPos->mAmount))
aPos->mPreferLeft ^= isOddLevel;
#endif
if (!aPos || !mContent)
return NS_ERROR_NULL_POINTER;
@ -3462,6 +3762,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
}
if (aPos->mStartOffset > (mContentOffset + mContentLength)){
nsIFrame *nextInFlow;
#ifdef IBMBIDI
if (isOddLevel) {
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextInFlow);
}
else
#endif
GetNextInFlow(&nextInFlow);
if (!nextInFlow){
NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more flow \n");
@ -3536,7 +3842,14 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
#ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next
// so that right arrow always moves to the right on screen
// and left arrow always moves left
if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||
((aPos->mDirection == eDirNext) && isOddLevel) ){
#else
if (aPos->mDirection == eDirPrevious){
#endif
aPos->mContentOffset = 0;
PRInt32 i;
for (i = aPos->mStartOffset -1 - mContentOffset; i >=0; i--){
@ -3552,7 +3865,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
aPos->mContentOffset = start;//in case next call fails we stop at this offset
}
}
#ifdef IBMBIDI // Simon, as above
else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||
((aPos->mDirection == eDirPrevious) && isOddLevel) ){
#else
else if (aPos->mDirection == eDirNext){
#endif
PRInt32 i;
aPos->mContentOffset = mContentLength;
for (i = aPos->mStartOffset +1 - mContentOffset; i <= mContentLength; i++){
@ -3607,7 +3925,14 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
PRBool found = PR_FALSE;
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;
#ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next
// so that right arrow always moves to the right on screen
// and left arrow always moves left
if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||
((aPos->mDirection == eDirNext) && isOddLevel) ) {
#else
if (aPos->mDirection == eDirPrevious){
#endif
keepSearching = PR_TRUE;
tx.Init(this, mContent, aPos->mStartOffset);
aPos->mContentOffset = mContentOffset;//initialize
@ -3645,7 +3970,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
}
}
}
#ifdef IBMBIDI // Simon, as above
else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||
((aPos->mDirection == eDirPrevious) && isOddLevel) ) {
#else
else if (aPos->mDirection == eDirNext) {
#endif
tx.Init(this, mContent, aPos->mStartOffset );
aPos->mContentOffset = mContentOffset + mContentLength;//initialize
@ -3726,6 +4056,18 @@ TryNextFrame:
}
}
break;
#ifdef IBMBIDI
case eSelectDir:
result = GetFrameFromDirection(aPresContext, aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
return aPos->mResultFrame->PeekOffset(aPresContext, aPos);
else {
return result;
}
break;
#endif
default:
result = NS_ERROR_FAILURE; break;
}
@ -3906,7 +4248,11 @@ struct TextRun {
void AddSegment(PRInt32 aNumChars, PRInt32 aContentLen, PRBool aIsWhitespace)
{
NS_PRECONDITION(mNumSegments < TEXT_MAX_NUM_SEGMENTS, "segment overflow");
#ifdef IBMBIDI
if (mNumSegments >= TEXT_MAX_NUM_SEGMENTS) {
return;
}
#endif // IBMBIDI
mTotalNumChars += aNumChars;
mBreaks[mNumSegments] = mTotalNumChars;
mSegments[mNumSegments].mIsWhitespace = aIsWhitespace;
@ -3969,9 +4315,45 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// width divided by the average character width
estimatedNumChars = (maxWidth - aTextData.mX) / aTs.mAveCharWidth;
estimatedNumChars += estimatedNumChars / 20;
#ifdef IBMBIDI
nsTextFrame* nextBidi = nsnull;
PRInt32 start = -1, end;
if (mState & NS_FRAME_IS_BIDI) {
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextBidi);
if (nextBidi) {
if (mContentLength < 1) {
mContentLength = 1;
}
nextBidi->GetOffsets(start, end);
if (start <= mContentOffset) {
nextBidi->SetOffsets(mContentOffset + mContentLength, end);
nsFrameState frameState;
nextBidi->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
nextBidi->SetFrameState(frameState);
}
else {
mContentLength = start - mContentOffset;
}
}
}
#endif //IBMBIDI
aTextData.mX = 0;
for (;;firstThing = PR_FALSE) {
#ifdef IBMBIDI
if (nextBidi && (mContentLength <= 0) ) {
if (textRun.IsBuffering()) {
// Measure the remaining text
goto MeasureTextRun;
}
else {
break;
}
}
#endif // IBMBIDI
// Get next word/whitespace from the text
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;
@ -3981,6 +4363,16 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
};
bp2 = aTx.GetNextWord(aTextData.mInWord, &wordLen, &contentLen, &isWhitespace,
&wasTransformed, textRun.mNumSegments == 0);
#ifdef IBMBIDI
if (nextBidi) {
mContentLength -= contentLen;
if (mContentLength < 0) {
contentLen += mContentLength;
wordLen = PR_MIN(wordLen, contentLen);
}
}
#endif // IBMBIDI
// Remember if the text was transformed
if (wasTransformed) {
mState |= TEXT_WAS_TRANSFORMED;
@ -4184,6 +4576,9 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// See how much of the text fit
if ((0 != aTextData.mX) && aTextData.mWrapping && (aTextData.mX + width > maxWidth)) {
// None of the text fits
#ifdef IBMBIDI
nextBidi = nsnull;
#endif // IBMBIDI
break;
}
@ -4235,9 +4630,18 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// If all the text didn't fit, then we're done
if (numCharsFit != textRun.mTotalNumChars) {
#ifdef IBMBIDI
nextBidi = nsnull;
#endif // IBMBIDI
break;
}
#ifdef IBMBIDI
if (nextBidi && (mContentLength <= 0) ) {
break;
}
#endif // IBMBIDI
if (nsnull == bp2) {
// No more text so we're all finished. Advance the offset in case the last
// call to GetNextWord() discarded characters
@ -4405,6 +4809,9 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// Return our reflow status
nsReflowStatus rs = (aTextData.mOffset == contentLength)
#ifdef IBMBIDI
|| (aTextData.mOffset == start)
#endif // IBMBIDI
? NS_FRAME_COMPLETE
: NS_FRAME_NOT_COMPLETE;
if (endsInNewline) {
@ -4467,7 +4874,11 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
mState &= ~TEXT_OPTIMIZE_RESIZE;
}
}
#ifdef IBMBIDI
if ( (mContentLength > 0) && (mState & NS_FRAME_IS_BIDI) ) {
startingOffset = mContentOffset;
}
#endif //IBMBIDI
nsLineLayout& lineLayout = *aReflowState.mLineLayout;
TextStyle ts(aPresContext, *aReflowState.rendContext, mStyleContext);
@ -4560,6 +4971,9 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
(lastTimeWeSkippedLeadingWS == skipWhitespace) &&
((wrapping && (maxWidth >= realWidth)) ||
(!wrapping && (prevColumn == column))) &&
#ifdef IBMBIDI
(0 == (mState & NS_FRAME_IS_BIDI) ) &&
#endif // IBMBIDI
!ts.mJustifying) {
// We can skip measuring of text and use the value from our
// previous reflow
@ -5095,3 +5509,14 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons
return NS_OK;
}
#endif
#ifdef IBMBIDI
NS_IMETHODIMP
nsTextFrame::SetOffsets(PRInt32 aStart, PRInt32 aEnd)
{
mContentOffset = aStart;
mContentLength = aEnd - aStart;
return NS_OK;
}
#endif // IBMBIDI

View File

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* IBM Corporation. Portions created by IBM are
* Copyright (C) 2000 IBM Corporation.
* All Rights Reserved.
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
* Contributor(s):
*/
#ifdef IBMBIDI
#include "nsBidiFrames.h"
#include "nsLayoutAtoms.h"
nsDirectionalFrame::nsDirectionalFrame(PRUnichar aChar)
: mChar(aChar)
{
}
nsDirectionalFrame::~nsDirectionalFrame()
{
}
PRUnichar
nsDirectionalFrame::GetChar(void) const
{
return mChar;
}
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::directionalFrame
*/
NS_IMETHODIMP
nsDirectionalFrame::GetFrameType(nsIAtom** aType) const
{
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
*aType = nsLayoutAtoms::directionalFrame;
NS_ADDREF(*aType);
return NS_OK;
}
const nsIID&
nsDirectionalFrame::GetIID()
{
static nsIID iid = NS_DIRECTIONAL_FRAME_IID;
return iid;
}
NS_IMETHODIMP
nsDirectionalFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
nsresult rv = NS_NOINTERFACE;
if (!aInstancePtr) {
rv = NS_ERROR_NULL_POINTER;
}
else if (aIID.Equals(NS_GET_IID(nsDirectionalFrame) ) ) {
*aInstancePtr = (void*) this;
rv = NS_OK;
}
return rv;
}
void*
nsDirectionalFrame::operator new(size_t aSize)
{
void* frame = ::operator new(aSize);
if (frame) {
nsCRT::zero(frame, aSize);
}
return frame;
}
nsresult
NS_NewDirectionalFrame(nsIFrame** aNewFrame, PRUnichar aChar)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsDirectionalFrame* frame = new nsDirectionalFrame(aChar);
*aNewFrame = frame;
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
#endif /* IBMBIDI */

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* IBM Corporation. Portions created by IBM are
* Copyright (C) 2000 IBM Corporation.
* All Rights Reserved.
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
* Contributor(s):
*/
#ifdef IBMBIDI
#ifndef nsBidiFrames_h___
#define nsBidiFrames_h___
#include "nsFrame.h"
// IID for the nsDirectionalFrame interface
// {90D69900-67AF-11d4-BA59-006008CD3717}
#define NS_DIRECTIONAL_FRAME_IID \
{ 0x90d69900, 0x67af, 0x11d4, { 0xba, 0x59, 0x00, 0x60, 0x08, 0xcd, 0x37, 0x17 } }
class nsDirectionalFrame : public nsFrame
{
protected:
virtual ~nsDirectionalFrame();
public:
nsDirectionalFrame(PRUnichar aChar);
void* operator new(size_t aSize);
static const nsIID& GetIID();
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
PRUnichar GetChar(void) const;
private:
PRUnichar mChar;
};
#endif /* nsBidiFrames_h___ */
#endif /* IBMBIDI */

View File

@ -46,6 +46,12 @@
#include "nsIViewManager.h"
#include "nsHTMLAtoms.h"
#include "nsTextFragment.h"
#ifdef IBMBIDI
#include "nsIUBidiUtils.h"
#include "nsIFormControlFrame.h"
#include "nsITextFrame.h"
#define FIX_FOR_BUG_40882
#endif // IBMBIDI
#ifdef DEBUG
#undef NOISY_HORIZONTAL_ALIGN
@ -916,8 +922,44 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
nscoord ty = y - psd->mReflowState->mComputedBorderPadding.top;
mSpaceManager->Translate(tx, ty);
#ifdef IBMBIDI
PRBool bidiEnabled;
mPresContext->BidiEnabled(bidiEnabled);
PRBool visual;
PRBool setMode = PR_FALSE;
PRInt32 start, end;
if (bidiEnabled) {
if (state & NS_FRAME_IS_BIDI) {
aFrame->GetOffsets(start, end);
}
else {
nsCOMPtr<nsIFormControlFrame> formFrame(do_QueryInterface(aFrame) );
if (formFrame) {
mPresContext->IsVisualMode(visual);
PRUint32 options;
mPresContext->GetBidi(&options);
if ( (IBMBIDI_CONTROLSTEXTMODE_VISUAL == GET_BIDI_OPTION_CONTROLSTEXTMODE(options)
&& !visual)
|| (IBMBIDI_CONTROLSTEXTMODE_LOGICAL == GET_BIDI_OPTION_CONTROLSTEXTMODE(options)
&& visual) ) {
mPresContext->SetVisualMode(!visual);
setMode = PR_TRUE;
}
}
}
}
#endif // IBMBIDI
aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus);
#ifdef IBMBIDI
if (setMode) {
mPresContext->SetVisualMode(visual);
}
#endif // IBMBIDI
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
@ -1011,6 +1053,21 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
if (NS_SUCCEEDED(result)) {
pfd->SetFlag(PFD_ISNONWHITESPACETEXTFRAME, !isWhitespace);
}
// fix for bug 40882
#ifdef IBMBIDI
const nsTextFragment* frag;
textContent->GetText(&frag);
if (frag && frag->Is2b() ) {
//PRBool isVisual;
//mPresContext->IsVisualMode(isVisual);
PRUnichar ch = /*(isVisual) ?
*(frag->Get2b() + frag->GetLength() - 1) :*/ *frag->Get2b();
if (IS_BIDI_DIACRITIC(ch) ) {
aFrame->SetBidiProperty(mPresContext,
nsLayoutAtoms::endsInDiacritic, (void*)ch);
}
}
#endif // IBMBIDI
}
}
}
@ -1168,6 +1225,45 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
nsFrame::ListTag(stdout, aFrame);
printf(" status=%x\n", aReflowStatus);
#endif
#ifdef IBMBIDI
if (state & NS_FRAME_IS_BIDI) {
nsITextFrame* textFrame = nsnull;
aFrame->QueryInterface(NS_GET_IID(nsITextFrame), (void**) &textFrame);
if (textFrame) {
// Since aReflowStatus may change, check it at the end
if (NS_INLINE_IS_BREAK_BEFORE(aReflowStatus) ) {
textFrame->SetOffsets(start, end);
nsFrameState frameState;
aFrame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
aFrame->SetFrameState(frameState);
}
else if (!NS_FRAME_IS_COMPLETE(aReflowStatus) ) {
PRInt32 newEnd;
aFrame->GetOffsets(start, newEnd);
if (newEnd != end) {
nsIFrame* nextInFlow;
aFrame->GetNextInFlow(&nextInFlow);
if (nextInFlow) {
nsITextFrame* nextTextInFlow = nsnull;
nextInFlow->QueryInterface(NS_GET_IID(nsITextFrame),
(void**) &nextTextInFlow);
if (nextTextInFlow) {
nextInFlow->GetOffsets(start, end);
nextTextInFlow->SetOffsets(newEnd, end);
nsFrameState frameState;
nextInFlow->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
nextInFlow->SetFrameState(frameState);
}
} // nextInFlow
} // newEnd != end
} // !NS_FRAME_IS_COMPLETE(aReflowStatus)
} // textFrame
} // isBidiFrame
#endif // IBMBIDI
return rv;
}
@ -2469,11 +2565,13 @@ PRBool
nsLineLayout::TrimTrailingWhiteSpaceIn(PerSpanData* psd,
nscoord* aDeltaWidth)
{
#ifndef IBMBIDI
// XXX what about NS_STYLE_DIRECTION_RTL?
if (NS_STYLE_DIRECTION_RTL == psd->mDirection) {
*aDeltaWidth = 0;
return PR_TRUE;
}
#endif
PerFrameData* pfd = psd->mFirstFrame;
if (!pfd) {
@ -2701,6 +2799,13 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
#endif
return PR_TRUE;
}
#ifdef IBMBIDI
if (NS_STYLE_DIRECTION_RTL == psd->mDirection) {
// This is to ensure proper indentation (e.g. of list items)
availWidth -= aLineBounds.x;
}
else
#endif // IBMBIDI
availWidth -= psd->mLeftEdge;
nscoord remainingWidth = availWidth - aLineBounds.width;
#ifdef NOISY_HORIZONTAL_ALIGN
@ -2708,7 +2813,11 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
printf(": availWidth=%d lineWidth=%d delta=%d\n",
availWidth, aLineBounds.width, remainingWidth);
#endif
#ifdef IBMBIDI
if (remainingWidth + aLineBounds.x > 0) {
#else
if (remainingWidth > 0) {
#endif
nscoord dx = 0;
PRUint32 textAlign = mTextAlign;
// here is where we do special adjustments for HR's
@ -2798,7 +2907,37 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
dx = remainingWidth / 2;
break;
}
#ifdef IBMBIDI
PerFrameData* lastPfd = psd->mLastFrame;
PerFrameData* bulletPfd = nsnull;
if (lastPfd->GetFlag(PFD_ISBULLET)
&& (NS_STYLE_DIRECTION_RTL == psd->mDirection) ) {
bulletPfd = lastPfd;
lastPfd = lastPfd->mPrev;
}
PRUint32 maxX = lastPfd->mBounds.XMost() + dx;
PRBool visualRTL = PR_FALSE;
if ( (NS_STYLE_DIRECTION_RTL == psd->mDirection)
&& (!psd->mChangedFrameDirection) ) {
psd->mChangedFrameDirection = PR_TRUE;
/* Assume that all frames have been right aligned.*/
if (aShrinkWrapWidth) {
return PR_FALSE;
}
mPresContext->IsVisualMode(visualRTL);
if (bulletPfd) {
bulletPfd->mBounds.x += maxX;
bulletPfd->mFrame->SetRect(mPresContext, bulletPfd->mBounds);
}
}
if ( (0 != dx) || (visualRTL) ) {
#else
if (0 != dx) {
#endif // IBMBIDI
// If we need to move the frames but we're shrink wrapping, then
// we need to wait until the final width is known
if (aShrinkWrapWidth) {
@ -2806,14 +2945,27 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
}
PerFrameData* pfd = psd->mFirstFrame;
#ifdef IBMBIDI
while ( (nsnull != pfd) && (bulletPfd != pfd) ) {
#else
while (nsnull != pfd) {
#endif // IBMBIDI
pfd->mBounds.x += dx;
#ifdef IBMBIDI
if (visualRTL) {
maxX = pfd->mBounds.x = maxX - pfd->mBounds.width;
}
#endif // IBMBIDI
pfd->mFrame->SetRect(mPresContext, pfd->mBounds);
pfd = pfd->mNext;
}
#ifdef IBMBIDI
aLineBounds.x += dx;
#else
aLineBounds.width += dx;
#endif
}
#ifndef IBMBIDI
if ((NS_STYLE_DIRECTION_RTL == psd->mDirection) &&
!psd->mChangedFrameDirection) {
psd->mChangedFrameDirection = PR_TRUE;
@ -2831,6 +2983,7 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
pfd = pfd->mNext;
}
}
#endif // ndef IBMBIDI
}
return PR_TRUE;

View File

@ -70,6 +70,16 @@
#include "nsIAccessibilityService.h"
#include "nsIMutableAccessible.h"
#ifdef IBMBIDI
#include "nsBidiFrames.h"
#include "nsBidiPresUtils.h"
#include "nsITextFrame.h"
//ahmed
#include "nsIUBidiUtils.h"
//ahmed end
#endif // IBMBIDI
#ifndef PR_ABS
#define PR_ABS(x) ((x) < 0 ? -(x) : (x))
#endif
@ -343,7 +353,11 @@ nsresult nsBlinkTimer::RemoveBlinkFrame(nsIFrame* aFrame)
//----------------------------------------------------------------------
#ifdef IBMBIDI
class nsTextFrame : public nsFrame, public nsITextFrame {
#else
class nsTextFrame : public nsFrame {
#endif
public:
nsTextFrame();
@ -721,6 +735,11 @@ public:
void ToCString(nsString& aBuf, PRInt32* aTotalContentLength) const;
#ifdef IBMBIDI
// nsITextFrame methods here
NS_IMETHOD SetOffsets(PRInt32 aStart, PRInt32 aEnd);
#endif
protected:
virtual ~nsTextFrame();
@ -736,6 +755,11 @@ protected:
PRBool aGetWidth/* true=get width false = return length up to aWidthResult size*/);
nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength);
#ifdef IBMBIDI
private:
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
#endif
};
//-----------------------------------------------------------------------------
@ -781,8 +805,17 @@ NS_IMETHODIMP nsTextFrame::QueryInterface(const nsIID& aIID,
return NS_OK;
}
return NS_ERROR_FAILURE;
#ifdef IBMBIDI
}
if (aIID.Equals(NS_GET_IID(nsITextFrame))) {
*aInstancePtrResult = NS_STATIC_CAST(nsITextFrame*, this);
return NS_OK;
}
return nsFrame::QueryInterface(aIID, aInstancePtrResult);
#else
} else
return nsFrame::QueryInterface(aIID, aInstancePtrResult);
#endif
}
class nsContinuingTextFrame : public nsTextFrame {
@ -825,6 +858,35 @@ nsContinuingTextFrame::Init(nsIPresContext* aPresContext,
// Hook the frame into the flow
mPrevInFlow = aPrevInFlow;
aPrevInFlow->SetNextInFlow(this);
#ifdef IBMBIDI
nsFrameState state;
aPrevInFlow->GetFrameState(&state);
if (state & NS_FRAME_IS_BIDI) {
PRInt32 start, end;
aPrevInFlow->GetOffsets(start, mContentOffset);
void* value;
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::charType, &value);
SetBidiProperty(aPresContext, nsLayoutAtoms::charType, value);
aPrevInFlow->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, &value);
if (value) { // nextBidi
// aPrevInFlow and this frame will point to the same next bidi frame.
SetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, value);
( (nsIFrame*) value)->GetOffsets(start, end);
mContentLength = PR_MAX(1, start - mContentOffset);
} // value
mState |= NS_FRAME_IS_BIDI;
} // prev frame is bidi
#endif // IBMBIDI
}
return rv;
@ -1193,6 +1255,20 @@ nsTextFrame::~nsTextFrame()
}
}
#ifdef IBMBIDI
NS_IMETHODIMP_(nsrefcnt) nsTextFrame::AddRef(void)
{
NS_WARNING("not supported for frames");
return 1;
}
NS_IMETHODIMP_(nsrefcnt) nsTextFrame::Release(void)
{
NS_WARNING("not supported for frames");
return 1;
}
#endif // IBMBIDI
nsIDocument*
nsTextFrame::GetDocument(nsIPresContext* aPresContext)
{
@ -1269,6 +1345,13 @@ nsTextFrame::ContentChanged(nsIPresContext* aPresContext,
nsTextFrame* textFrame = this;
while (textFrame) {
textFrame->mState |= NS_FRAME_IS_DIRTY;
#ifdef IBMBIDI
nsIFrame* nextBidi;
textFrame->GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextBidi);
if (nextBidi)
textFrame = (nsTextFrame*)nextBidi;
else
#endif
textFrame = (nsTextFrame*)textFrame->mNextInFlow;
}
}
@ -1323,6 +1406,13 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
#ifdef IBMBIDI
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
PaintUnicodeText(aPresContext, aRenderingContext, sc, ts, 0, 0);
} else
#endif // IBMBIDI
// If we have ascii text that doesn't contain multi-byte characters
// and the text doesn't need transforming then always render as ascii
if ((0 == (mState & TEXT_WAS_TRANSFORMED)) && !frag->Is2b() && !hasMultiByteChars) {
@ -1375,6 +1465,12 @@ nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
aTX.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed);
// we trip this assertion in bug 31053, but I think it's unnecessary
//NS_ASSERTION(isWhitespace, "mState and content are out of sync");
#ifdef IBMBIDI
if (mState & NS_FRAME_IS_BIDI
&& contentLen > mContentLength) {
contentLen = mContentLength;
}
#endif // IBMBIDI
if (isWhitespace) {
if (nsnull != indexp) {
@ -1406,6 +1502,13 @@ nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
// Get the next word
bp = aTX.GetNextWord(inWord, &wordLen, &contentLen, &isWhitespace, &wasTransformed);
if (nsnull == bp) {
#ifdef IBMBIDI
if (indexp && (mState & NS_FRAME_IS_BIDI) ) {
while (--n >= 0) {
*indexp++ = strInx++;
}
}
#endif // IBMBIDI
break;
}
if (contentLen > n) {
@ -2018,6 +2121,9 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PRBool isSelected;
PRInt16 selectionValue;
nsCOMPtr<nsILineBreaker> lb;
#ifdef IBMBIDI
PRInt32 level = 0;
#endif
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
@ -2056,6 +2162,48 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (0 != textLength)
{
#ifdef IBMBIDI
PRBool isRightToLeftOnBidiPlatform = PR_FALSE;
PRBool isBidiSystem;
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
//mrous
PRBool isVisual;
aPresContext->IsVisualMode(isVisual);
//ahmed
aPresContext->SetIsBidiSystem(isBidiSystem);
if (bidiEnabled) {
nsCharType charType;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**) &level);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**) &charType);
if (isBidiSystem && (eCharType_RightToLeft == charType) ) {
isRightToLeftOnBidiPlatform = PR_TRUE;
}
else if (eCharType_RightToLeftArabic == charType) {
//mrous add visual check to avoid reversing visual docs on bidi systems
// no need since it is already in the FE range, which the system does
// not interpret as bidi
isRightToLeftOnBidiPlatform =
((hints & NS_RENDERING_HINT_ARABIC_SHAPING) && (!isVisual));
}
if (isRightToLeftOnBidiPlatform) {
// indicate that the platform should use its native
// capabilities to reorder the text with right-to-left
// base direction
aRenderingContext.SetRightToLeftText(PR_TRUE);
}
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
bidiUtils->FormatUnicodeText(aPresContext, text, textLength, charType, level & 1, isRightToLeftOnBidiPlatform);
}
}
if (0 != textLength) { // textLength might change due to the bidi formattimg
#endif // IBMBIDI
if (!displaySelection || !isSelected ) //draw text normally
{
// When there is no selection showing, use the fastest and
@ -2096,6 +2244,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame on non-Bidi platform
if ((level & 1) && !(isRightToLeftOnBidiPlatform)) {
PRInt32 swap = sdptr->mStart;
sdptr->mStart = textLength - sdptr->mEnd;
sdptr->mEnd = textLength - swap;
}
#endif
sdptr = sdptr->mNext;
}
//while we have substrings...
@ -2105,6 +2260,12 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
{
nscoord currentX = dx;
nscoord newWidth;//temp
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame
nscoord FrameWidth = 0;
if (isRightToLeftOnBidiPlatform)
if (NS_SUCCEEDED(aRenderingContext.GetWidth(text, textLength, FrameWidth)))
currentX = dx + FrameWidth;
#endif
while (!iter.IsDone())
{
PRUnichar *currenttext = iter.CurrentTextUnicharPtr();
@ -2115,6 +2276,10 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
#ifdef IBMBIDI
if (isRightToLeftOnBidiPlatform)
currentX -= newWidth;
#endif
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
@ -2133,6 +2298,9 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
#ifdef IBMBIDI
if (!isRightToLeftOnBidiPlatform)
#endif
currentX+=newWidth;//increment twips X start
iter.Next();
@ -2154,6 +2322,14 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
delete details;
}
}
#ifdef IBMBIDI
}
if (isRightToLeftOnBidiPlatform) {
// indicate that future text should not be reordered with
// right-to-left base direction
aRenderingContext.SetRightToLeftText(PR_FALSE);
}
#endif // IBMBIDI
}
}
@ -2234,6 +2410,21 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
#ifdef IBMBIDI // Simon -- reverse RTL text here
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
PRBool isOddLevel = (level & 1);
if (isOddLevel) {
PRUnichar *tStart, *tEnd;
PRUnichar tSwap;
for (tStart = paintBuffer.mBuffer, tEnd = tStart + textLength - 1; tEnd > tStart; tStart++, tEnd--) {
tSwap = *tStart;
*tStart = *tEnd;
*tEnd = tSwap;
}
}
#endif // IBMBIDI
ComputeExtraJustificationSpacing(*aRendContext, ts, paintBuffer.mBuffer, textLength, numSpaces);
//IF STYLE SAYS TO SELECT TO END OF FRAME HERE...
@ -2266,6 +2457,11 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
//the following will first get the index into the PAINTBUFFER then the actual content
nscoord adjustedX = PR_MAX(0,aPoint.x-origin.x);
#ifdef IBMBIDI
if (isOddLevel)
aOffset = mContentOffset+textLength-GetLengthSlowly(*aRendContext, ts,paintBuffer.mBuffer,textLength,adjustedX);
else
#endif
aOffset = mContentOffset+GetLengthSlowly(*aRendContext, ts,paintBuffer.mBuffer,textLength,adjustedX);
PRInt32 i;
for (i = 0;i <= mContentLength; i ++){
@ -2629,6 +2825,28 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
PRUnichar* text = paintBuffer.mBuffer;
if (0 != textLength) {
#ifdef IBMBIDI
PRBool isRightToLeft = PR_FALSE;
PRBool bidiEnabled;
aPresContext->BidiEnabled(bidiEnabled);
if (bidiEnabled) {
nsBidiPresUtils* bidiUtils;
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
nsCharType charType;
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**) &level);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**) &charType);
if (CHARTYPE_IS_RTL(charType))
isRightToLeft = PR_TRUE;
// Since we paint char by char, handle the text like on non-bidi platform
bidiUtils->FormatUnicodeText(aPresContext, text, textLength, charType, level & 1, PR_FALSE);
}
}
if (0 != textLength) { // textLength might change due to the bidi formattimg
#endif // IBMBIDI
ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces);
if (!displaySelection || !isSelected) {
// When there is no selection showing, use the fastest and
@ -2665,6 +2883,13 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame
if (isRightToLeft) {
PRInt32 swap = sdptr->mStart;
sdptr->mStart = textLength - sdptr->mEnd;
sdptr->mEnd = textLength - swap;
}
#endif
sdptr = sdptr->mNext;
}
@ -2724,6 +2949,9 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
delete details;
}
}
#ifdef IBMBIDI
}
#endif // IBMBIDI
}
}
@ -3090,15 +3318,46 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
PRInt32 indx;
PRInt32 textWidth = 0;
PRUnichar* text = paintBuffer.mBuffer;
#ifdef IBMBIDI
PRBool getReversedPos = PR_FALSE;
PRUint32 hints = 0;
PRBool isVisual;
PRInt32 charType;
GetBidiProperty(aCX, nsLayoutAtoms::charType, (void**)&charType);
acx->GetHints(hints);
aCX->IsVisualMode(isVisual);
if (CHARTYPE_IS_RTL(charType) && !isVisual) {
getReversedPos = PR_TRUE;
}
nscoord posX = (getReversedPos) ?
(mRect.width + origin.x) - (aPoint.x - origin.x) : aPoint.x;
PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
PRInt32(textLength),
PRInt32(posX) , //go to local coordinates
indx, textWidth);
#else
PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
PRInt32(textLength),
PRInt32(aPoint.x) , //go to local coordinates
indx, textWidth);
#endif // IBMBIDI
if (found) {
PRInt32 charWidth;
acx->GetWidth(text[indx], charWidth);
charWidth /= 2;
#ifdef IBMBIDI
if (getReversedPos) {
if (mRect.width - aPoint.x + origin.x > textWidth+charWidth ) {
indx++;
}
}
else
#endif // IBMBIDI
if ((aPoint.x - origin.x) > textWidth+charWidth) {
indx++;
}
@ -3113,6 +3372,11 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
break;
}
}
#ifdef IBMBIDI
while (IS_BIDI_DIACRITIC(text[aContentOffset - mContentOffset]) ) {
aContentOffset++;
}
#endif // IBMBIDI
aContentOffsetEnd = aContentOffset;
NS_ASSERTION(i<= mContentLength, "offset we got from binary search is messed up");
}
@ -3309,6 +3573,12 @@ nsTextFrame::SetSelected(nsIPresContext* aPresContext,
if (NS_FAILED(result))
break;
}
#ifdef IBMBIDI
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &frame);
if (frame) {
frame->SetSelected(aPresContext, aRange, aSelected, aSpread);
}
#endif // IBMBIDI
}
return NS_OK;
}
@ -3398,6 +3668,15 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
width += ts.mSpaceWidth + ts.mWordSpacing;
}
}
#ifdef IBMBIDI
PRInt32 level;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
if (level & 1) {
outPoint->x = mRect.width - width;
}
else
#endif // IBMBIDI
outPoint->x = width;
outPoint->y = 0;
@ -3429,14 +3708,25 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
{
return nextInFlow->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame);
}
else if (contentOffset != mContentLength) //that condition was only for when there is a choice
return NS_ERROR_FAILURE;
else {
#ifdef IBMBIDI // Simon
nsIFrame *nextBidi;
GetNextSibling(&nextBidi);
if (nextBidi)
return nextBidi->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame);
else
#endif // IBMBIDI
{
if (contentOffset != mContentLength) //that condition was only for when there is a choice
return NS_ERROR_FAILURE;
}
}
}
if (inContentOffset < mContentOffset) //could happen with floaters!
{
result = GetPrevInFlow(outChildFrame);
if (NS_SUCCEEDED(result) && outChildFrame)
if (NS_SUCCEEDED(result) && *outChildFrame)
return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, inHint,
outFrameContentOffset,outChildFrame);
else
@ -3452,6 +3742,16 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
NS_IMETHODIMP
nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{
#ifdef IBMBIDI
PRInt32 level, baseLevel;
GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level);
GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, (void**)&baseLevel);
PRBool isOddLevel = (level & 1);
if ((eSelectCharacter == aPos->mAmount)
|| (eSelectWord == aPos->mAmount))
aPos->mPreferLeft ^= isOddLevel;
#endif
if (!aPos || !mContent)
return NS_ERROR_NULL_POINTER;
@ -3462,6 +3762,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
}
if (aPos->mStartOffset > (mContentOffset + mContentLength)){
nsIFrame *nextInFlow;
#ifdef IBMBIDI
if (isOddLevel) {
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextInFlow);
}
else
#endif
GetNextInFlow(&nextInFlow);
if (!nextInFlow){
NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more flow \n");
@ -3536,7 +3842,14 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
#ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next
// so that right arrow always moves to the right on screen
// and left arrow always moves left
if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||
((aPos->mDirection == eDirNext) && isOddLevel) ){
#else
if (aPos->mDirection == eDirPrevious){
#endif
aPos->mContentOffset = 0;
PRInt32 i;
for (i = aPos->mStartOffset -1 - mContentOffset; i >=0; i--){
@ -3552,7 +3865,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
aPos->mContentOffset = start;//in case next call fails we stop at this offset
}
}
#ifdef IBMBIDI // Simon, as above
else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||
((aPos->mDirection == eDirPrevious) && isOddLevel) ){
#else
else if (aPos->mDirection == eDirNext){
#endif
PRInt32 i;
aPos->mContentOffset = mContentLength;
for (i = aPos->mStartOffset +1 - mContentOffset; i <= mContentLength; i++){
@ -3607,7 +3925,14 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
PRBool found = PR_FALSE;
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;
#ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next
// so that right arrow always moves to the right on screen
// and left arrow always moves left
if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||
((aPos->mDirection == eDirNext) && isOddLevel) ) {
#else
if (aPos->mDirection == eDirPrevious){
#endif
keepSearching = PR_TRUE;
tx.Init(this, mContent, aPos->mStartOffset);
aPos->mContentOffset = mContentOffset;//initialize
@ -3645,7 +3970,12 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
}
}
}
#ifdef IBMBIDI // Simon, as above
else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||
((aPos->mDirection == eDirPrevious) && isOddLevel) ) {
#else
else if (aPos->mDirection == eDirNext) {
#endif
tx.Init(this, mContent, aPos->mStartOffset );
aPos->mContentOffset = mContentOffset + mContentLength;//initialize
@ -3726,6 +4056,18 @@ TryNextFrame:
}
}
break;
#ifdef IBMBIDI
case eSelectDir:
result = GetFrameFromDirection(aPresContext, aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
return aPos->mResultFrame->PeekOffset(aPresContext, aPos);
else {
return result;
}
break;
#endif
default:
result = NS_ERROR_FAILURE; break;
}
@ -3906,7 +4248,11 @@ struct TextRun {
void AddSegment(PRInt32 aNumChars, PRInt32 aContentLen, PRBool aIsWhitespace)
{
NS_PRECONDITION(mNumSegments < TEXT_MAX_NUM_SEGMENTS, "segment overflow");
#ifdef IBMBIDI
if (mNumSegments >= TEXT_MAX_NUM_SEGMENTS) {
return;
}
#endif // IBMBIDI
mTotalNumChars += aNumChars;
mBreaks[mNumSegments] = mTotalNumChars;
mSegments[mNumSegments].mIsWhitespace = aIsWhitespace;
@ -3969,9 +4315,45 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// width divided by the average character width
estimatedNumChars = (maxWidth - aTextData.mX) / aTs.mAveCharWidth;
estimatedNumChars += estimatedNumChars / 20;
#ifdef IBMBIDI
nsTextFrame* nextBidi = nsnull;
PRInt32 start = -1, end;
if (mState & NS_FRAME_IS_BIDI) {
GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextBidi);
if (nextBidi) {
if (mContentLength < 1) {
mContentLength = 1;
}
nextBidi->GetOffsets(start, end);
if (start <= mContentOffset) {
nextBidi->SetOffsets(mContentOffset + mContentLength, end);
nsFrameState frameState;
nextBidi->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_BIDI;
nextBidi->SetFrameState(frameState);
}
else {
mContentLength = start - mContentOffset;
}
}
}
#endif //IBMBIDI
aTextData.mX = 0;
for (;;firstThing = PR_FALSE) {
#ifdef IBMBIDI
if (nextBidi && (mContentLength <= 0) ) {
if (textRun.IsBuffering()) {
// Measure the remaining text
goto MeasureTextRun;
}
else {
break;
}
}
#endif // IBMBIDI
// Get next word/whitespace from the text
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;
@ -3981,6 +4363,16 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
};
bp2 = aTx.GetNextWord(aTextData.mInWord, &wordLen, &contentLen, &isWhitespace,
&wasTransformed, textRun.mNumSegments == 0);
#ifdef IBMBIDI
if (nextBidi) {
mContentLength -= contentLen;
if (mContentLength < 0) {
contentLen += mContentLength;
wordLen = PR_MIN(wordLen, contentLen);
}
}
#endif // IBMBIDI
// Remember if the text was transformed
if (wasTransformed) {
mState |= TEXT_WAS_TRANSFORMED;
@ -4184,6 +4576,9 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// See how much of the text fit
if ((0 != aTextData.mX) && aTextData.mWrapping && (aTextData.mX + width > maxWidth)) {
// None of the text fits
#ifdef IBMBIDI
nextBidi = nsnull;
#endif // IBMBIDI
break;
}
@ -4235,9 +4630,18 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// If all the text didn't fit, then we're done
if (numCharsFit != textRun.mTotalNumChars) {
#ifdef IBMBIDI
nextBidi = nsnull;
#endif // IBMBIDI
break;
}
#ifdef IBMBIDI
if (nextBidi && (mContentLength <= 0) ) {
break;
}
#endif // IBMBIDI
if (nsnull == bp2) {
// No more text so we're all finished. Advance the offset in case the last
// call to GetNextWord() discarded characters
@ -4405,6 +4809,9 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
// Return our reflow status
nsReflowStatus rs = (aTextData.mOffset == contentLength)
#ifdef IBMBIDI
|| (aTextData.mOffset == start)
#endif // IBMBIDI
? NS_FRAME_COMPLETE
: NS_FRAME_NOT_COMPLETE;
if (endsInNewline) {
@ -4467,7 +4874,11 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
mState &= ~TEXT_OPTIMIZE_RESIZE;
}
}
#ifdef IBMBIDI
if ( (mContentLength > 0) && (mState & NS_FRAME_IS_BIDI) ) {
startingOffset = mContentOffset;
}
#endif //IBMBIDI
nsLineLayout& lineLayout = *aReflowState.mLineLayout;
TextStyle ts(aPresContext, *aReflowState.rendContext, mStyleContext);
@ -4560,6 +4971,9 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
(lastTimeWeSkippedLeadingWS == skipWhitespace) &&
((wrapping && (maxWidth >= realWidth)) ||
(!wrapping && (prevColumn == column))) &&
#ifdef IBMBIDI
(0 == (mState & NS_FRAME_IS_BIDI) ) &&
#endif // IBMBIDI
!ts.mJustifying) {
// We can skip measuring of text and use the value from our
// previous reflow
@ -5095,3 +5509,14 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons
return NS_OK;
}
#endif
#ifdef IBMBIDI
NS_IMETHODIMP
nsTextFrame::SetOffsets(PRInt32 aStart, PRInt32 aEnd)
{
mContentOffset = aStart;
mContentLength = aEnd - aStart;
return NS_OK;
}
#endif // IBMBIDI