Add support for unicode-bidi: -moz-plaintext in XUL. Bug 869833, r=roc

This commit is contained in:
Simon Montagu 2013-11-18 17:24:16 +02:00
Родитель 46e6c5b93c
Коммит 342f8fc7a7
7 изменённых файлов: 89 добавлений и 65 удалений

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

@ -59,17 +59,7 @@ struct BidiParagraphData {
mPrevContent = nullptr;
mParagraphDepth = 0;
bool styleDirectionIsRTL =
(NS_STYLE_DIRECTION_RTL == aBlockFrame->StyleVisibility()->mDirection);
if (aBlockFrame->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
// unicode-bidi: plaintext: the Bidi algorithm will determine the
// directionality of the paragraph according to the first strong
// directional character, defaulting to LTR if there is none.
mParaLevel = NSBIDI_DEFAULT_LTR;
} else {
mParaLevel = styleDirectionIsRTL ? NSBIDI_RTL : NSBIDI_LTR;
}
mParaLevel = nsBidiPresUtils::BidiLevelFromStyle(aBlockFrame->StyleContext());
mIsVisual = aBlockFrame->PresContext()->IsVisualMode();
if (mIsVisual) {
@ -1813,7 +1803,7 @@ nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine,
nsresult nsBidiPresUtils::ProcessText(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
BidiProcessor& aprocessor,
Mode aMode,
@ -1828,7 +1818,7 @@ nsresult nsBidiPresUtils::ProcessText(const PRUnichar* aText,
nsAutoString textBuffer(aText, aLength);
nsresult rv = aBidiEngine->SetPara(aText, aLength, aBaseDirection, nullptr);
nsresult rv = aBidiEngine->SetPara(aText, aLength, aBaseLevel, nullptr);
if (NS_FAILED(rv))
return rv;
@ -1853,7 +1843,8 @@ nsresult nsBidiPresUtils::ProcessText(const PRUnichar* aText,
}
for (i = 0; i < runCount; i++) {
rv = aBidiEngine->GetVisualRun(i, &start, &length, &aBaseDirection);
nsBidiDirection dir;
rv = aBidiEngine->GetVisualRun(i, &start, &length, &dir);
if (NS_FAILED(rv))
return rv;
@ -2062,7 +2053,7 @@ private:
nsresult nsBidiPresUtils::ProcessTextForRenderingContext(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsRenderingContext& aTextRunConstructionContext,
@ -2075,7 +2066,7 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(const PRUnichar*
{
nsIRenderingContextBidiProcessor processor(&aRenderingContext, &aTextRunConstructionContext, nsPoint(aX, aY));
nsBidi bidiEngine;
return ProcessText(aText, aLength, aBaseDirection, aPresContext, processor,
return ProcessText(aText, aLength, aBaseLevel, aPresContext, processor,
aMode, aPosResolve, aPosResolveCount, aWidth, &bidiEngine);
}
@ -2197,4 +2188,20 @@ void nsBidiPresUtils::CopyLogicalToVisual(const nsAString& aSource,
aDest);
}
}
/* static */
nsBidiLevel
nsBidiPresUtils::BidiLevelFromStyle(nsStyleContext* aStyleContext)
{
if (aStyleContext->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
return NSBIDI_DEFAULT_LTR;
}
if (aStyleContext->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
return NSBIDI_RTL;
}
return NSBIDI_LTR;
}
#endif // IBMBIDI

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

@ -25,6 +25,7 @@ class nsBlockFrame;
class nsPresContext;
class nsRenderingContext;
class nsBlockInFlowLineIterator;
class nsStyleContext;
template<class T> class nsTHashtable;
/**
@ -179,9 +180,16 @@ public:
*
* @param[in] aText the string to be rendered (in logical order)
* @param aLength the number of characters in the string
* @param aBaseDirection the base direction of the string
* @param aBaseLevel the base embedding level of the string
* odd values are right-to-left; even values are left-to-right, plus special
* constants as follows (defined in nsBidi.h)
* NSBIDI_LTR - left-to-right string
* NSBIDI_RTL - right-to-left string
* NSBIDI_DEFAULT_LTR - auto direction determined by first strong character,
* default is left-to-right
* NSBIDI_DEFAULT_RTL - auto direction determined by first strong character,
* default is right-to-left
*
* @param aPresContext the presentation context
* @param aRenderingContext the rendering context to render to
* @param aTextRunConstructionContext the rendering context to be used to construct the textrun (affects font hinting)
@ -192,7 +200,7 @@ public:
*/
static nsresult RenderText(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsRenderingContext& aTextRunConstructionContext,
@ -201,18 +209,18 @@ public:
nsBidiPositionResolve* aPosResolve = nullptr,
int32_t aPosResolveCount = 0)
{
return ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext, aRenderingContext,
return ProcessTextForRenderingContext(aText, aLength, aBaseLevel, aPresContext, aRenderingContext,
aTextRunConstructionContext, MODE_DRAW, aX, aY, aPosResolve, aPosResolveCount, nullptr);
}
static nscoord MeasureTextWidth(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext)
{
nscoord length;
nsresult rv = ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext,
nsresult rv = ProcessTextForRenderingContext(aText, aLength, aBaseLevel, aPresContext,
aRenderingContext, aRenderingContext,
MODE_MEASURE, 0, 0, nullptr, 0, &length);
return NS_SUCCEEDED(rv) ? length : 0;
@ -278,9 +286,16 @@ public:
*
* @param[in] aText the string to be processed (in logical order)
* @param aLength the number of characters in the string
* @param aBaseDirection the base direction of the string
* @param aBaseLevel the base embedding level of the string
* odd values are right-to-left; even values are left-to-right, plus special
* constants as follows (defined in nsBidi.h)
* NSBIDI_LTR - left-to-right string
* NSBIDI_RTL - right-to-left string
* NSBIDI_DEFAULT_LTR - auto direction determined by first strong character,
* default is left-to-right
* NSBIDI_DEFAULT_RTL - auto direction determined by first strong character,
* default is right-to-left
*
* @param aPresContext the presentation context
* @param aprocessor the bidi processor
* @param aMode the operation to process
@ -294,7 +309,7 @@ public:
*/
static nsresult ProcessText(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
BidiProcessor& aprocessor,
Mode aMode,
@ -321,11 +336,25 @@ public:
nsBidiLevel aBaseDirection,
bool aOverride);
/**
* Use style attributes to determine the base paragraph level to pass to the
* bidi algorithm.
*
* If |unicode-bidi| is set to "[-moz-]plaintext", returns NSBIDI_DEFAULT_LTR,
* in other words the direction is determined from the first strong character
* in the text according to rules P2 and P3 of the bidi algorithm, or LTR if
* there is no strong character.
*
* Otherwise returns NSBIDI_LTR or NSBIDI_RTL depending on the value of
* |direction|
*/
static nsBidiLevel BidiLevelFromStyle(nsStyleContext* aStyleContext);
private:
static nsresult
ProcessTextForRenderingContext(const PRUnichar* aText,
int32_t aLength,
nsBidiDirection aBaseDirection,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsRenderingContext& aTextRunConstructionContext,

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

@ -3729,24 +3729,21 @@ nsLayoutUtils::GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
}
void
nsLayoutUtils::DrawString(const nsIFrame* aFrame,
nsRenderingContext* aContext,
const PRUnichar* aString,
int32_t aLength,
nsPoint aPoint,
uint8_t aDirection)
nsLayoutUtils::DrawString(const nsIFrame* aFrame,
nsRenderingContext* aContext,
const PRUnichar* aString,
int32_t aLength,
nsPoint aPoint,
nsStyleContext* aStyleContext)
{
#ifdef IBMBIDI
nsresult rv = NS_ERROR_FAILURE;
nsPresContext* presContext = aFrame->PresContext();
if (presContext->BidiEnabled()) {
if (aDirection == NS_STYLE_DIRECTION_INHERIT) {
aDirection = aFrame->StyleVisibility()->mDirection;
}
nsBidiDirection direction =
(NS_STYLE_DIRECTION_RTL == aDirection) ?
NSBIDI_RTL : NSBIDI_LTR;
rv = nsBidiPresUtils::RenderText(aString, aLength, direction,
nsBidiLevel level =
nsBidiPresUtils::BidiLevelFromStyle(aStyleContext ?
aStyleContext : aFrame->StyleContext());
rv = nsBidiPresUtils::RenderText(aString, aLength, level,
presContext, *aContext, *aContext,
aPoint.x, aPoint.y);
}
@ -3767,12 +3764,10 @@ nsLayoutUtils::GetStringWidth(const nsIFrame* aFrame,
#ifdef IBMBIDI
nsPresContext* presContext = aFrame->PresContext();
if (presContext->BidiEnabled()) {
const nsStyleVisibility* vis = aFrame->StyleVisibility();
nsBidiDirection direction =
(NS_STYLE_DIRECTION_RTL == vis->mDirection) ?
NSBIDI_RTL : NSBIDI_LTR;
nsBidiLevel level =
nsBidiPresUtils::BidiLevelFromStyle(aFrame->StyleContext());
return nsBidiPresUtils::MeasureTextWidth(aString, aLength,
direction, presContext, *aContext);
level, presContext, *aContext);
}
#endif // IBMBIDI
aContext->SetTextRunRTL(false);

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

@ -1145,12 +1145,12 @@ public:
static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
nscoord aY, nscoord aAscent);
static void DrawString(const nsIFrame* aFrame,
nsRenderingContext* aContext,
const PRUnichar* aString,
int32_t aLength,
nsPoint aPoint,
uint8_t aDirection = NS_STYLE_DIRECTION_INHERIT);
static void DrawString(const nsIFrame* aFrame,
nsRenderingContext* aContext,
const PRUnichar* aString,
int32_t aLength,
nsPoint aPoint,
nsStyleContext* aStyleContext = nullptr);
static nscoord GetStringWidth(const nsIFrame* aFrame,
nsRenderingContext* aContext,

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -510,14 +510,13 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
if (mState & NS_FRAME_IS_BIDI) {
presContext->SetBidiEnabled();
const nsStyleVisibility* vis = StyleVisibility();
nsBidiDirection direction = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? NSBIDI_RTL : NSBIDI_LTR;
nsBidiLevel level = nsBidiPresUtils::BidiLevelFromStyle(StyleContext());
if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
// We let the RenderText function calculate the mnemonic's
// underline position for us.
nsBidiPositionResolve posResolve;
posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex;
rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level,
presContext, aRenderingContext,
*refContext,
aTextRect.x, baseline,
@ -528,7 +527,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
}
else
{
rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level,
presContext, aRenderingContext,
*refContext,
aTextRect.x, baseline);

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

@ -3275,11 +3275,9 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
nsRect elementRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, elementRect)) {
bool textRTL = cellContext->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
switch (aColumn->GetType()) {
case nsITreeColumn::TYPE_TEXT:
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX,
textRTL);
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX);
break;
case nsITreeColumn::TYPE_CHECKBOX:
PaintCheckbox(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect);
@ -3294,8 +3292,7 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
break;
case nsITreeView::PROGRESS_NONE:
default:
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX,
textRTL);
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX);
break;
}
break;
@ -3555,8 +3552,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nscoord& aCurrX,
bool aTextRTL)
nscoord& aCurrX)
{
NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed");
@ -3639,8 +3635,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
fontMet->GetStrikeout(offset, size);
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size);
}
uint8_t direction = aTextRTL ? NS_STYLE_DIRECTION_RTL :
NS_STYLE_DIRECTION_LTR;
nsStyleContext* cellContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecell);
gfxContext* ctx = aRenderingContext.ThebesContext();
if (opacity != 1.0f) {
@ -3648,7 +3643,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
}
nsLayoutUtils::DrawString(this, &aRenderingContext, text.get(), text.Length(),
textRect.TopLeft() + nsPoint(0, baseline), direction);
textRect.TopLeft() + nsPoint(0, baseline), cellContext);
if (opacity != 1.0f) {
ctx->PopGroupToSource();

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

@ -248,8 +248,7 @@ protected:
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nscoord& aCurrX,
bool aTextRTL);
nscoord& aCurrX);
// This method paints the checkbox inside a particular cell of the tree.
void PaintCheckbox(int32_t aRowIndex,