Fix for bug 81773: Bidi XUL text (e.g. bookmarks, tab titles) was flipping to and fro on systems without native Bidi support. r=mkaply, r/sr=hyatt, sr=attinasi

This commit is contained in:
smontagu%netscape.com 2001-11-12 20:51:48 +00:00
Родитель 579d261870
Коммит ad90f8900c
5 изменённых файлов: 196 добавлений и 65 удалений

Просмотреть файл

@ -1080,5 +1080,76 @@ nsresult nsBidiPresUtils::GetBidiEngine(nsIBidi** aBidiEngine)
}
return rv;
}
nsresult nsBidiPresUtils::RenderText(PRUnichar* aText,
PRInt32 aLength,
nsBidiDirection aBaseDirection,
nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aX,
nscoord aY)
{
PRInt32 runCount;
mBuffer.Assign(aText);
nsresult rv = mBidiEngine->SetPara(mBuffer.get(), aLength, aBaseDirection, nsnull);
if (NS_FAILED(rv))
return rv;
rv = mBidiEngine->CountRuns(&runCount);
if (NS_FAILED(rv))
return rv;
nscoord width;
PRBool isRTL = PR_FALSE;
PRInt32 i, start, limit, length;
PRUint8 charType;
PRUint8 prevType = eCharType_LeftToRight;
nsBidiLevel level;
PRInt32 lineOffset = 0;
PRInt32 runLength = 0;
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
PRBool isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
for (i = 0; i < runCount; i++) {
rv = mBidiEngine->GetVisualRun(i, &start, &length, &aBaseDirection);
if (NS_FAILED(rv))
return rv;
rv = mBidiEngine->GetLogicalRun(start, &limit, &level);
if (NS_FAILED(rv))
return rv;
runLength = limit - start;
lineOffset = start;
PRInt32 typeLimit = PR_MIN(limit, aLength);
CalculateCharType(lineOffset, typeLimit, limit, runLength, runCount, charType, prevType);
if (eCharType_RightToLeftArabic == charType) {
isBidiSystem = (hints & NS_RENDERING_HINT_ARABIC_SHAPING);
}
if (isBidiSystem && (CHARTYPE_IS_RTL(charType) ^ isRTL) ) {
// set reading order into DC
isRTL = !isRTL;
aRenderingContext.SetRightToLeftText(isRTL);
}
FormatUnicodeText(aPresContext, aText + start, length,
(nsCharType)charType, level & 1,
isBidiSystem);
aRenderingContext.GetWidth(aText + start, length, width, nsnull);
aRenderingContext.DrawString(aText + start, length, aX, aY, width);
aX += width;
} // for
// Restore original reading order
if (isRTL) {
aRenderingContext.SetRightToLeftText(PR_FALSE);
}
return NS_OK;
}
#endif // IBMBIDI

Просмотреть файл

@ -79,6 +79,27 @@ public:
*/
nsresult GetBidiEngine(nsIBidi** aBidiEngine);
/**
* Reorder plain text using the Unicode Bidi algorithm and send it to
* a rendering context for rendering.
*
* @param aText the string to be rendered
* @param aLength the number of characters in the string
* @param aBaseDirection the base direction of the string
* NSBIDI_LTR - left-to-right string
* NSBIDI_RTL - right-to-left string
* @param aPresContext the presentation context
* @param aRenderingContext the rendering context
* @param aTextRect contains the coordinates to render the string
*/
nsresult nsBidiPresUtils::RenderText(PRUnichar* aText,
PRInt32 aLength,
nsBidiDirection aBaseDirection,
nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aX,
nscoord aY);
private:
/**
* Create a string containing entire text content of this block.

Просмотреть файл

@ -79,6 +79,27 @@ public:
*/
nsresult GetBidiEngine(nsIBidi** aBidiEngine);
/**
* Reorder plain text using the Unicode Bidi algorithm and send it to
* a rendering context for rendering.
*
* @param aText the string to be rendered
* @param aLength the number of characters in the string
* @param aBaseDirection the base direction of the string
* NSBIDI_LTR - left-to-right string
* NSBIDI_RTL - right-to-left string
* @param aPresContext the presentation context
* @param aRenderingContext the rendering context
* @param aTextRect contains the coordinates to render the string
*/
nsresult nsBidiPresUtils::RenderText(PRUnichar* aText,
PRInt32 aLength,
nsBidiDirection aBaseDirection,
nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aX,
nscoord aY);
private:
/**
* Create a string containing entire text content of this block.

Просмотреть файл

@ -1080,5 +1080,76 @@ nsresult nsBidiPresUtils::GetBidiEngine(nsIBidi** aBidiEngine)
}
return rv;
}
nsresult nsBidiPresUtils::RenderText(PRUnichar* aText,
PRInt32 aLength,
nsBidiDirection aBaseDirection,
nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aX,
nscoord aY)
{
PRInt32 runCount;
mBuffer.Assign(aText);
nsresult rv = mBidiEngine->SetPara(mBuffer.get(), aLength, aBaseDirection, nsnull);
if (NS_FAILED(rv))
return rv;
rv = mBidiEngine->CountRuns(&runCount);
if (NS_FAILED(rv))
return rv;
nscoord width;
PRBool isRTL = PR_FALSE;
PRInt32 i, start, limit, length;
PRUint8 charType;
PRUint8 prevType = eCharType_LeftToRight;
nsBidiLevel level;
PRInt32 lineOffset = 0;
PRInt32 runLength = 0;
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
PRBool isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
for (i = 0; i < runCount; i++) {
rv = mBidiEngine->GetVisualRun(i, &start, &length, &aBaseDirection);
if (NS_FAILED(rv))
return rv;
rv = mBidiEngine->GetLogicalRun(start, &limit, &level);
if (NS_FAILED(rv))
return rv;
runLength = limit - start;
lineOffset = start;
PRInt32 typeLimit = PR_MIN(limit, aLength);
CalculateCharType(lineOffset, typeLimit, limit, runLength, runCount, charType, prevType);
if (eCharType_RightToLeftArabic == charType) {
isBidiSystem = (hints & NS_RENDERING_HINT_ARABIC_SHAPING);
}
if (isBidiSystem && (CHARTYPE_IS_RTL(charType) ^ isRTL) ) {
// set reading order into DC
isRTL = !isRTL;
aRenderingContext.SetRightToLeftText(isRTL);
}
FormatUnicodeText(aPresContext, aText + start, length,
(nsCharType)charType, level & 1,
isBidiSystem);
aRenderingContext.GetWidth(aText + start, length, width, nsnull);
aRenderingContext.DrawString(aText + start, length, aX, aY, width);
aX += width;
} // for
// Restore original reading order
if (isRTL) {
aRenderingContext.SetRightToLeftText(PR_FALSE);
}
return NS_OK;
}
#endif // IBMBIDI

Просмотреть файл

@ -64,6 +64,7 @@
#ifdef IBMBIDI
#include "nsIUBidiUtils.h"
#include "nsBidiPresUtils.h"
#include "nsReadableUtils.h"
#endif // IBMBIDI
#define ELLIPSIS "..."
@ -409,77 +410,23 @@ nsTextBoxFrame::PaintTitle(nsIPresContext* aPresContext,
if (mState & NS_FRAME_IS_BIDI) {
nsBidiPresUtils* bidiUtils;
aPresContext->SetBidiEnabled(PR_TRUE);
aPresContext->GetBidiUtils(&bidiUtils);
if (bidiUtils) {
nsCOMPtr<nsIBidi> bidiEngine;
bidiUtils->GetBidiEngine(getter_AddRefs(bidiEngine));
if (bidiEngine) {
const nsStyleVisibility* vis;
GetStyleData(eStyleStruct_Visibility, (const nsStyleStruct*&) vis);
PRUnichar* buffer = (PRUnichar*) mCroppedTitle.get();
PRInt32 runCount;
PRUnichar* buffer = ToNewUnicode(mCroppedTitle);
if (buffer) {
const nsStyleVisibility* vis = (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility);
nsBidiDirection direction =
(NS_STYLE_DIRECTION_RTL == vis->mDirection)
? NSBIDI_RTL : NSBIDI_LTR;
rv = bidiEngine->SetPara(buffer, mCroppedTitle.Length(), direction, nsnull);
if (NS_SUCCEEDED(rv) ) {
rv = bidiEngine->CountRuns(&runCount);
if (NS_SUCCEEDED(rv) ) {
nscoord width;
PRBool isRTL = PR_FALSE;
PRInt32 i, start, limit, length;
nsCharType charType;
nsBidiLevel level;
PRBool isBidiSystem;
PRUint32 hints = 0;
aRenderingContext.GetHints(hints);
isBidiSystem = (hints & NS_RENDERING_HINT_BIDI_REORDERING);
for (i = 0; i < runCount; i++) {
rv = bidiEngine->GetVisualRun(i, &start, &length, &direction);
if (NS_FAILED(rv) ) {
break;
}
bidiEngine->GetCharTypeAt(start, &charType);
rv = bidiEngine->GetLogicalRun(start, &limit, &level);
if (NS_FAILED(rv) ) {
break;
}
if (eCharType_RightToLeftArabic == charType) {
isBidiSystem = (hints & NS_RENDERING_HINT_ARABIC_SHAPING);
}
if (isBidiSystem && (CHARTYPE_IS_RTL(charType) ^ isRTL) ) {
// set reading order into DC
isRTL = !isRTL;
aRenderingContext.SetRightToLeftText(isRTL);
}
bidiUtils->FormatUnicodeText(aPresContext, buffer + start, length,
charType, level & 1,
isBidiSystem);
aRenderingContext.GetWidth(buffer + start, length, width, nsnull);
aRenderingContext.DrawString(buffer + start, length, textRect.x,
textRect.y + baseline, width);
textRect.x += width;
} // for
// Restore original x (for aRenderingContext.FillRect below),
// as well as reading order
textRect.x = aRect.x;
if (isRTL) {
aRenderingContext.SetRightToLeftText(PR_FALSE);
}
}
}
} // bidiEngine
} // bidiUtils
} // frame is bidi
rv = bidiUtils->RenderText(buffer, mCroppedTitle.Length(), direction,
aPresContext, aRenderingContext,
textRect.x, textRect.y + baseline);
nsMemory::Free(buffer);
}
}
}
if (NS_FAILED(rv) )
#endif // IBMBIDI
aRenderingContext.DrawString(mCroppedTitle, textRect.x, textRect.y + baseline);