Correct a regression in Bidi ordering and simplify the way in which we determine whether Arabic shaping needs to be performed depending on the capabilities of the system and whether we are rendering character by character. Bug 192919, r/sr=rbs.

This commit is contained in:
smontagu%netscape.com 2003-03-07 20:56:03 +00:00
parent 6bde6f9da6
commit c27c3fff25
6 changed files with 104 additions and 102 deletions

View File

@ -667,7 +667,8 @@ public:
PRIntn PrepareUnicodeText(nsTextTransformer& aTransformer,
nsAutoIndexBuffer* aIndexBuffer,
nsAutoTextBuffer* aTextBuffer,
PRInt32* aTextLen);
PRInt32* aTextLen,
PRBool aForceArabicShaping = PR_FALSE);
void ComputeExtraJustificationSpacing(nsIRenderingContext& aRenderingContext,
TextStyle& aTextStyle,
PRUnichar* aBuffer, PRInt32 aLength, PRInt32 aNumSpaces);
@ -1523,13 +1524,14 @@ PRIntn
nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
nsAutoIndexBuffer* aIndexBuffer,
nsAutoTextBuffer* aTextBuffer,
PRInt32* aTextLen)
PRInt32* aTextLen,
PRBool aForceArabicShaping)
{
PRIntn numSpaces = 0;
// Setup transform to operate starting in the content at our content
// offset
aTX.Init(this, mContent, mContentOffset);
aTX.Init(this, mContent, mContentOffset, aForceArabicShaping);
PRInt32 strInx = mContentOffset;
PRInt32* indexp = aIndexBuffer ? aIndexBuffer->mBuffer : nsnull;
@ -2559,16 +2561,7 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
PRInt32 textLength;
PRInt32 numSpaces;
#ifdef IBMBIDI
// Simulate a non-Bidi system for char by char measuring
PRBool isBidiSystem = PR_FALSE;
aPresContext->GetIsBidiSystem(isBidiSystem);
aPresContext->SetIsBidiSystem(PR_FALSE);
#endif
numSpaces = PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
#ifdef IBMBIDI
aPresContext->SetIsBidiSystem(isBidiSystem);
#endif
numSpaces = PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength, PR_TRUE);
if (textLength <= 0) {
// If we've already assigned aNewContent, make sure to 0 it out here.
// aNewContent is undefined in the case that we return a failure,
@ -3000,17 +2993,8 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
#ifdef IBMBIDI
// Simulate a non-Bidi system for char by char painting
PRBool isBidiSystem = PR_FALSE;
aPresContext->GetIsBidiSystem(isBidiSystem);
aPresContext->SetIsBidiSystem(PR_FALSE);
#endif
numSpaces = PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
&paintBuffer, &textLength);
#ifdef IBMBIDI
aPresContext->SetIsBidiSystem(isBidiSystem);
#endif
&paintBuffer, &textLength, PR_TRUE);
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
@ -5341,31 +5325,24 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
nsLineLayout& lineLayout = *aReflowState.mLineLayout;
TextStyle ts(aPresContext, *aReflowState.rendContext, mStyleContext);
#ifdef IBMBIDI
if ( (mContentLength > 0) && (mState & NS_FRAME_IS_BIDI) ) {
startingOffset = mContentOffset;
}
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing)
|| ts.mJustifying) {
// simulate a non-Bidi system for char-by-char measuring and
// rendering
aPresContext->SetIsBidiSystem(PR_FALSE);
}
else {
PRBool bidiEnabled;
aPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
nsCharType charType = eCharType_LeftToRight;
PRUint32 hints = 0;
aReflowState.rendContext->GetHints(hints);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**)&charType, sizeof(charType));
PRBool isBidiSystem = (eCharType_RightToLeftArabic == charType) ?
(hints & NS_RENDERING_HINT_ARABIC_SHAPING) :
(hints & NS_RENDERING_HINT_BIDI_REORDERING);
aPresContext->SetIsBidiSystem(isBidiSystem);
PRBool bidiEnabled;
aPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
nsCharType charType = eCharType_LeftToRight;
PRUint32 hints = 0;
aReflowState.rendContext->GetHints(hints);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**)&charType, sizeof(charType));
if ((eCharType_RightToLeftArabic == charType &&
(hints & NS_RENDERING_HINT_ARABIC_SHAPING) == NS_RENDERING_HINT_ARABIC_SHAPING) ||
(eCharType_RightToLeft == charType &&
(hints & NS_RENDERING_HINT_BIDI_REORDERING) == NS_RENDERING_HINT_BIDI_REORDERING)) {
aPresContext->SetIsBidiSystem(PR_TRUE);
}
}
#endif //IBMBIDI
// Clear out the reflow state flags in mState (without destroying
// the TEXT_BLINK_ON bit).
@ -5406,11 +5383,15 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
}
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
PRBool forceArabicShaping = (ts.mSmallCaps ||
(0 != ts.mWordSpacing) ||
(0 != ts.mLetterSpacing) ||
ts.mJustifying);
nsTextTransformer tx(lb, nsnull, aPresContext);
// Keep the text in ascii if possible. Note that if we're measuring small
// caps text then transform to Unicode because the helper function only
// accepts Unicode text
nsresult rv = tx.Init(this, mContent, startingOffset, !ts.mSmallCaps);
nsresult rv = tx.Init(this, mContent, startingOffset, forceArabicShaping, !ts.mSmallCaps);
if (NS_OK != rv) {
return rv;
}
@ -5536,7 +5517,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
// there because of the need to repair counts when wrapped words are backed out.
// So I do it via PrepareUnicodeText ... a little slower perhaps, but a lot saner,
// and it localizes the counting logic to one place.
numSpaces = PrepareUnicodeText(tx, nsnull, nsnull, &textLength);
numSpaces = PrepareUnicodeText(tx, nsnull, nsnull, &textLength, PR_TRUE);
lineLayout.SetTextJustificationWeights(numSpaces, textLength - numSpaces);
}

View File

@ -203,23 +203,42 @@ nsresult
nsTextTransformer::Init(nsIFrame* aFrame,
nsIContent* aContent,
PRInt32 aStartingOffset,
PRBool aForceArabicShaping,
PRBool aLeaveAsAscii)
{
#ifdef IBMBIDI
/*
* If the document has Bidi content, check whether we need to do
* Arabic shaping.
*
* Does the frame contains Arabic characters
* (mCharType == eCharType_RightToLeftArabic)?
* Are we rendering character by character (aForceArabicShaping ==
* PR_TRUE)? If so, we always do our own Arabic shaping, even if
* the platform has native shaping support. Otherwise, we only do
* shaping if the platform has no shaping support.
*
* We do numeric shaping in all Bidi documents.
*/
PRBool bidiEnabled;
mPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
PRBool isBidiSystem;
aFrame->GetBidiProperty(mPresContext, nsLayoutAtoms::charType,
(void**)&mCharType, sizeof(mCharType));
mPresContext->GetIsBidiSystem(isBidiSystem);
if (mCharType == eCharType_RightToLeftArabic && !isBidiSystem) {
SetNeedsArabicShaping(PR_TRUE);
if (mCharType == eCharType_RightToLeftArabic) {
if (aForceArabicShaping) {
SetNeedsArabicShaping(PR_TRUE);
}
else {
PRBool isBidiSystem;
mPresContext->GetIsBidiSystem(isBidiSystem);
if (!isBidiSystem) {
SetNeedsArabicShaping(PR_TRUE);
}
}
}
SetNeedsNumericShaping(PR_TRUE);
}
#endif
// Get the contents text content
nsresult rv;

View File

@ -162,6 +162,7 @@ public:
nsresult Init(nsIFrame* aFrame,
nsIContent* aContent,
PRInt32 aStartingOffset,
PRBool aForceArabicShaping = PR_FALSE,
PRBool aLeaveAsAscii = PR_FALSE);
PRInt32 GetContentLength() const {

View File

@ -667,7 +667,8 @@ public:
PRIntn PrepareUnicodeText(nsTextTransformer& aTransformer,
nsAutoIndexBuffer* aIndexBuffer,
nsAutoTextBuffer* aTextBuffer,
PRInt32* aTextLen);
PRInt32* aTextLen,
PRBool aForceArabicShaping = PR_FALSE);
void ComputeExtraJustificationSpacing(nsIRenderingContext& aRenderingContext,
TextStyle& aTextStyle,
PRUnichar* aBuffer, PRInt32 aLength, PRInt32 aNumSpaces);
@ -1523,13 +1524,14 @@ PRIntn
nsTextFrame::PrepareUnicodeText(nsTextTransformer& aTX,
nsAutoIndexBuffer* aIndexBuffer,
nsAutoTextBuffer* aTextBuffer,
PRInt32* aTextLen)
PRInt32* aTextLen,
PRBool aForceArabicShaping)
{
PRIntn numSpaces = 0;
// Setup transform to operate starting in the content at our content
// offset
aTX.Init(this, mContent, mContentOffset);
aTX.Init(this, mContent, mContentOffset, aForceArabicShaping);
PRInt32 strInx = mContentOffset;
PRInt32* indexp = aIndexBuffer ? aIndexBuffer->mBuffer : nsnull;
@ -2559,16 +2561,7 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
PRInt32 textLength;
PRInt32 numSpaces;
#ifdef IBMBIDI
// Simulate a non-Bidi system for char by char measuring
PRBool isBidiSystem = PR_FALSE;
aPresContext->GetIsBidiSystem(isBidiSystem);
aPresContext->SetIsBidiSystem(PR_FALSE);
#endif
numSpaces = PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
#ifdef IBMBIDI
aPresContext->SetIsBidiSystem(isBidiSystem);
#endif
numSpaces = PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength, PR_TRUE);
if (textLength <= 0) {
// If we've already assigned aNewContent, make sure to 0 it out here.
// aNewContent is undefined in the case that we return a failure,
@ -3000,17 +2993,8 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
#ifdef IBMBIDI
// Simulate a non-Bidi system for char by char painting
PRBool isBidiSystem = PR_FALSE;
aPresContext->GetIsBidiSystem(isBidiSystem);
aPresContext->SetIsBidiSystem(PR_FALSE);
#endif
numSpaces = PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
&paintBuffer, &textLength);
#ifdef IBMBIDI
aPresContext->SetIsBidiSystem(isBidiSystem);
#endif
&paintBuffer, &textLength, PR_TRUE);
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
@ -5341,31 +5325,24 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
nsLineLayout& lineLayout = *aReflowState.mLineLayout;
TextStyle ts(aPresContext, *aReflowState.rendContext, mStyleContext);
#ifdef IBMBIDI
if ( (mContentLength > 0) && (mState & NS_FRAME_IS_BIDI) ) {
startingOffset = mContentOffset;
}
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing)
|| ts.mJustifying) {
// simulate a non-Bidi system for char-by-char measuring and
// rendering
aPresContext->SetIsBidiSystem(PR_FALSE);
}
else {
PRBool bidiEnabled;
aPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
nsCharType charType = eCharType_LeftToRight;
PRUint32 hints = 0;
aReflowState.rendContext->GetHints(hints);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**)&charType, sizeof(charType));
PRBool isBidiSystem = (eCharType_RightToLeftArabic == charType) ?
(hints & NS_RENDERING_HINT_ARABIC_SHAPING) :
(hints & NS_RENDERING_HINT_BIDI_REORDERING);
aPresContext->SetIsBidiSystem(isBidiSystem);
PRBool bidiEnabled;
aPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
nsCharType charType = eCharType_LeftToRight;
PRUint32 hints = 0;
aReflowState.rendContext->GetHints(hints);
GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**)&charType, sizeof(charType));
if ((eCharType_RightToLeftArabic == charType &&
(hints & NS_RENDERING_HINT_ARABIC_SHAPING) == NS_RENDERING_HINT_ARABIC_SHAPING) ||
(eCharType_RightToLeft == charType &&
(hints & NS_RENDERING_HINT_BIDI_REORDERING) == NS_RENDERING_HINT_BIDI_REORDERING)) {
aPresContext->SetIsBidiSystem(PR_TRUE);
}
}
#endif //IBMBIDI
// Clear out the reflow state flags in mState (without destroying
// the TEXT_BLINK_ON bit).
@ -5406,11 +5383,15 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
}
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
PRBool forceArabicShaping = (ts.mSmallCaps ||
(0 != ts.mWordSpacing) ||
(0 != ts.mLetterSpacing) ||
ts.mJustifying);
nsTextTransformer tx(lb, nsnull, aPresContext);
// Keep the text in ascii if possible. Note that if we're measuring small
// caps text then transform to Unicode because the helper function only
// accepts Unicode text
nsresult rv = tx.Init(this, mContent, startingOffset, !ts.mSmallCaps);
nsresult rv = tx.Init(this, mContent, startingOffset, forceArabicShaping, !ts.mSmallCaps);
if (NS_OK != rv) {
return rv;
}
@ -5536,7 +5517,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
// there because of the need to repair counts when wrapped words are backed out.
// So I do it via PrepareUnicodeText ... a little slower perhaps, but a lot saner,
// and it localizes the counting logic to one place.
numSpaces = PrepareUnicodeText(tx, nsnull, nsnull, &textLength);
numSpaces = PrepareUnicodeText(tx, nsnull, nsnull, &textLength, PR_TRUE);
lineLayout.SetTextJustificationWeights(numSpaces, textLength - numSpaces);
}

View File

@ -203,23 +203,42 @@ nsresult
nsTextTransformer::Init(nsIFrame* aFrame,
nsIContent* aContent,
PRInt32 aStartingOffset,
PRBool aForceArabicShaping,
PRBool aLeaveAsAscii)
{
#ifdef IBMBIDI
/*
* If the document has Bidi content, check whether we need to do
* Arabic shaping.
*
* Does the frame contains Arabic characters
* (mCharType == eCharType_RightToLeftArabic)?
* Are we rendering character by character (aForceArabicShaping ==
* PR_TRUE)? If so, we always do our own Arabic shaping, even if
* the platform has native shaping support. Otherwise, we only do
* shaping if the platform has no shaping support.
*
* We do numeric shaping in all Bidi documents.
*/
PRBool bidiEnabled;
mPresContext->GetBidiEnabled(&bidiEnabled);
if (bidiEnabled) {
PRBool isBidiSystem;
aFrame->GetBidiProperty(mPresContext, nsLayoutAtoms::charType,
(void**)&mCharType, sizeof(mCharType));
mPresContext->GetIsBidiSystem(isBidiSystem);
if (mCharType == eCharType_RightToLeftArabic && !isBidiSystem) {
SetNeedsArabicShaping(PR_TRUE);
if (mCharType == eCharType_RightToLeftArabic) {
if (aForceArabicShaping) {
SetNeedsArabicShaping(PR_TRUE);
}
else {
PRBool isBidiSystem;
mPresContext->GetIsBidiSystem(isBidiSystem);
if (!isBidiSystem) {
SetNeedsArabicShaping(PR_TRUE);
}
}
}
SetNeedsNumericShaping(PR_TRUE);
}
#endif
// Get the contents text content
nsresult rv;

View File

@ -162,6 +162,7 @@ public:
nsresult Init(nsIFrame* aFrame,
nsIContent* aContent,
PRInt32 aStartingOffset,
PRBool aForceArabicShaping = PR_FALSE,
PRBool aLeaveAsAscii = PR_FALSE);
PRInt32 GetContentLength() const {