зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
579d261870
Коммит
ad90f8900c
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче