Bug 1719546 - Replace nsBidi with mozilla::intl::Bidi; r=platform-i18n-reviewers,dminor

Differential Revision: https://phabricator.services.mozilla.com/D128793
This commit is contained in:
Greg Tatum 2021-10-20 14:01:21 +00:00
parent e732101746
commit ee2694c97d
23 changed files with 329 additions and 338 deletions

View file

@ -9,6 +9,7 @@
*/
#include "mozilla/dom/Selection.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/AccessibleCaretEventHub.h"
#include "mozilla/AsyncEventDispatcher.h"
@ -385,7 +386,9 @@ Nullable<int16_t> Selection::GetCaretBidiLevel(
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return Nullable<int16_t>();
}
nsBidiLevel caretBidiLevel = mFrameSelection->GetCaretBidiLevel();
mozilla::intl::Bidi::EmbeddingLevel caretBidiLevel =
static_cast<mozilla::intl::Bidi::EmbeddingLevel>(
mFrameSelection->GetCaretBidiLevel());
return (caretBidiLevel & BIDI_LEVEL_UNDEFINED)
? Nullable<int16_t>()
: Nullable<int16_t>(caretBidiLevel);
@ -403,7 +406,7 @@ void Selection::SetCaretBidiLevel(const Nullable<int16_t>& aCaretBidiLevel,
mFrameSelection->UndefineCaretBidiLevel();
} else {
mFrameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(
aCaretBidiLevel.Value());
mozilla::intl::Bidi::EmbeddingLevel(aCaretBidiLevel.Value()));
}
}
@ -1357,7 +1360,8 @@ nsIFrame* Selection::GetPrimaryOrCaretFrameForNodeOffset(nsIContent* aContent,
CaretAssociationHint hint = mFrameSelection->GetHint();
if (aVisual) {
nsBidiLevel caretBidiLevel = mFrameSelection->GetCaretBidiLevel();
mozilla::intl::Bidi::EmbeddingLevel caretBidiLevel =
mFrameSelection->GetCaretBidiLevel();
return nsCaret::GetCaretFrameForNodeOffset(
mFrameSelection, aContent, aOffset, hint, caretBidiLevel,
@ -3298,9 +3302,10 @@ void Selection::Modify(const nsAString& aAlter, const nsAString& aDirection,
// If the paragraph direction of the focused frame is right-to-left,
// we may have to swap the direction of movement.
if (nsIFrame* frame = GetPrimaryFrameForFocusNode(visual)) {
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(frame);
mozilla::intl::Bidi::Direction paraDir =
nsBidiPresUtils::ParagraphDirection(frame);
if (paraDir == NSBIDI_RTL && visual) {
if (paraDir == mozilla::intl::Bidi::Direction::RTL && visual) {
if (amount == eSelectBeginLine) {
amount = eSelectEndLine;
forward = !forward;
@ -3474,7 +3479,9 @@ nsresult Selection::SelectionLanguageChange(bool aLangRTL) {
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
// if the direction of the language hasn't changed, nothing to do
nsBidiLevel kbdBidiLevel = aLangRTL ? NSBIDI_RTL : NSBIDI_LTR;
mozilla::intl::Bidi::EmbeddingLevel kbdBidiLevel =
aLangRTL ? mozilla::intl::Bidi::EmbeddingLevel::RTL()
: mozilla::intl::Bidi::EmbeddingLevel::LTR();
if (kbdBidiLevel == frameSelection->mKbdBidiLevel) {
return NS_OK;
}
@ -3488,12 +3495,12 @@ nsresult Selection::SelectionLanguageChange(bool aLangRTL) {
auto [frameStart, frameEnd] = focusFrame->GetOffsets();
RefPtr<nsPresContext> context = GetPresContext();
nsBidiLevel levelBefore, levelAfter;
mozilla::intl::Bidi::EmbeddingLevel levelBefore, levelAfter;
if (!context) {
return NS_ERROR_FAILURE;
}
nsBidiLevel level = focusFrame->GetEmbeddingLevel();
mozilla::intl::Bidi::EmbeddingLevel level = focusFrame->GetEmbeddingLevel();
int32_t focusOffset = static_cast<int32_t>(FocusOffset());
if ((focusOffset != frameStart) && (focusOffset != frameEnd))
// the cursor is not at a frame boundary, so the level of both the
@ -3511,27 +3518,31 @@ nsresult Selection::SelectionLanguageChange(bool aLangRTL) {
levelAfter = levels.mLevelAfter;
}
if (IS_SAME_DIRECTION(levelBefore, levelAfter)) {
if (levelBefore.IsSameDirection(levelAfter)) {
// if cursor is between two characters with the same orientation, changing
// the keyboard language must toggle the cursor level between the level of
// the character with the lowest level (if the new language corresponds to
// the orientation of that character) and this level plus 1 (if the new
// language corresponds to the opposite orientation)
if ((level != levelBefore) && (level != levelAfter))
if ((level != levelBefore) && (level != levelAfter)) {
level = std::min(levelBefore, levelAfter);
if (IS_SAME_DIRECTION(level, kbdBidiLevel))
}
if (level.IsSameDirection(kbdBidiLevel)) {
frameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(level);
else
frameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(level + 1);
} else {
frameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(
mozilla::intl::Bidi::EmbeddingLevel(level + 1));
}
} else {
// if cursor is between characters with opposite orientations, changing the
// keyboard language must change the cursor level to that of the adjacent
// character with the orientation corresponding to the new language.
if (IS_SAME_DIRECTION(levelBefore, kbdBidiLevel))
if (levelBefore.IsSameDirection(kbdBidiLevel)) {
frameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(levelBefore);
else
} else {
frameSelection->SetCaretBidiLevelAndMaybeSchedulePaint(levelAfter);
}
}
// The caret might have moved, so invalidate the desired position
// for future usages of up-arrow or down-arrow

View file

@ -12,6 +12,7 @@
#include "nsContentUtils.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h"
#include "mozilla/SVGImageContext.h"
@ -3503,11 +3504,11 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor
using ContextState = CanvasRenderingContext2D::ContextState;
virtual void SetText(const char16_t* aText, int32_t aLength,
nsBidiDirection aDirection) override {
mozilla::intl::Bidi::Direction aDirection) override {
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
// adjust flags for current direction run
gfx::ShapedTextFlags flags = mTextRunFlags;
if (aDirection == NSBIDI_RTL) {
if (aDirection == mozilla::intl::Bidi::Direction::RTL) {
flags |= gfx::ShapedTextFlags::TEXT_IS_RTL;
} else {
flags &= ~gfx::ShapedTextFlags::TEXT_IS_RTL;
@ -3873,7 +3874,9 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
// calls bidi algo twice since it needs the full text width and the
// bounding boxes before rendering anything
aError = nsBidiPresUtils::ProcessText(
textToDraw.get(), textToDraw.Length(), isRTL ? NSBIDI_RTL : NSBIDI_LTR,
textToDraw.get(), textToDraw.Length(),
isRTL ? mozilla::intl::Bidi::EmbeddingLevel::RTL()
: mozilla::intl::Bidi::EmbeddingLevel::LTR(),
presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_MEASURE,
nullptr, 0, &totalWidthCoord, &mBidiEngine);
if (aError.Failed()) {
@ -4014,7 +4017,9 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
processor.mDoMeasureBoundingBox = false;
aError = nsBidiPresUtils::ProcessText(
textToDraw.get(), textToDraw.Length(), isRTL ? NSBIDI_RTL : NSBIDI_LTR,
textToDraw.get(), textToDraw.Length(),
isRTL ? mozilla::intl::Bidi::EmbeddingLevel::RTL()
: mozilla::intl::Bidi::EmbeddingLevel::LTR(),
presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_DRAW,
nullptr, 0, nullptr, &mBidiEngine);

View file

@ -9,6 +9,7 @@
#include "mozilla/dom/BasicRenderingContext2D.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Attributes.h"
@ -19,8 +20,8 @@
#include "FilterDescription.h"
#include "gfx2DGlue.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsBidi.h"
#include "nsColor.h"
#include "nsIFrame.h"
class gfxFontGroup;
class nsGlobalWindowInner;
@ -797,7 +798,7 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal,
nsTArray<RegionInfo> mHitRegionsOptions;
nsBidi mBidiEngine;
mozilla::intl::Bidi mBidiEngine;
/**
* Returns true if a shadow should be drawn along with a

View file

@ -26,6 +26,7 @@
#include "JoinNodeTransaction.h" // for JoinNodeTransaction
#include "PlaceholderTransaction.h" // for PlaceholderTransaction
#include "SplitNodeTransaction.h" // for SplitNodeTransaction
#include "mozilla/intl/Bidi.h"
#include "mozilla/BasePrincipal.h" // for BasePrincipal
#include "mozilla/CheckedInt.h" // for CheckedInt
#include "mozilla/ComposerCommandsUpdater.h" // for ComposerCommandsUpdater
@ -5765,12 +5766,13 @@ EditorBase::AutoCaretBidiLevelManager::AutoCaretBidiLevelManager(
nsPrevNextBidiLevels levels = frameSelection->GetPrevNextBidiLevels(
aPointAtCaret.GetContainerAsContent(), aPointAtCaret.Offset(), true);
nsBidiLevel levelBefore = levels.mLevelBefore;
nsBidiLevel levelAfter = levels.mLevelAfter;
mozilla::intl::Bidi::EmbeddingLevel levelBefore = levels.mLevelBefore;
mozilla::intl::Bidi::EmbeddingLevel levelAfter = levels.mLevelAfter;
nsBidiLevel currentCaretLevel = frameSelection->GetCaretBidiLevel();
mozilla::intl::Bidi::EmbeddingLevel currentCaretLevel =
frameSelection->GetCaretBidiLevel();
nsBidiLevel levelOfDeletion;
mozilla::intl::Bidi::EmbeddingLevel levelOfDeletion;
levelOfDeletion = (nsIEditor::eNext == aDirectionAndAmount ||
nsIEditor::eNextWord == aDirectionAndAmount)
? levelAfter

View file

@ -6,6 +6,7 @@
#ifndef mozilla_EditorBase_h
#define mozilla_EditorBase_h
#include "mozilla/intl/Bidi.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
#include "mozilla/EditAction.h" // for EditAction and EditSubAction
#include "mozilla/EditorDOMPoint.h" // for EditorDOMPoint
@ -28,7 +29,6 @@
#include "nsGkAtoms.h"
#include "nsIContentInlines.h" // for nsINode::IsEditable()
#include "nsIEditor.h" // for nsIEditor, etc.
#include "nsIFrame.h" // for nsBidiLevel
#include "nsISelectionController.h" // for nsISelectionController constants
#include "nsISelectionListener.h" // for nsISelectionListener
#include "nsISupportsImpl.h" // for EditorBase::Release, etc.
@ -1985,7 +1985,7 @@ class EditorBase : public nsIEditor,
void MaybeUpdateCaretBidiLevel(const EditorBase& aEditorBase) const;
private:
Maybe<nsBidiLevel> mNewCaretBidiLevel;
Maybe<mozilla::intl::Bidi::EmbeddingLevel> mNewCaretBidiLevel;
bool mFailed = false;
bool mCanceled = false;
};

View file

@ -51,25 +51,6 @@ enum nsCharType {
*/
typedef enum nsCharType nsCharType;
/**
* Find the direction of an embedding level or paragraph level set by
* the Unicode Bidi Algorithm. (Even levels are left-to-right, odd
* levels right-to-left.
*/
#define IS_LEVEL_RTL(level) (((level)&1) == 1)
/**
* Check whether two bidi levels have the same parity and thus the same
* directionality
*/
#define IS_SAME_DIRECTION(level1, level2) (((level1 ^ level2) & 1) == 0)
/**
* Convert from nsBidiLevel to nsBidiDirection
*/
#define DIRECTION_FROM_LEVEL(level) \
((IS_LEVEL_RTL(level)) ? NSBIDI_RTL : NSBIDI_LTR)
/**
* definitions of bidirection character types by category
*/

View file

@ -6,6 +6,8 @@
#include "nsBidiPresUtils.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/Casting.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/Maybe.h"
#include "mozilla/PresShell.h"
@ -39,6 +41,7 @@
#undef REALLY_NOISY_BIDI
using namespace mozilla;
using EmbeddingLevel = mozilla::intl::Bidi::EmbeddingLevel;
static const char16_t kSpace = 0x0020;
static const char16_t kZWSP = 0x200B;
@ -163,7 +166,7 @@ struct MOZ_STACK_CLASS BidiParagraphData {
nsPresContext* mPresContext;
bool mIsVisual;
bool mRequiresBidi;
nsBidiLevel mParaLevel;
EmbeddingLevel mParaLevel;
nsIContent* mPrevContent;
/**
@ -335,37 +338,49 @@ struct MOZ_STACK_CLASS BidiParagraphData {
}
nsresult SetPara() {
return mPresContext->GetBidiEngine().SetPara(mBuffer.get(), BufferLength(),
mParaLevel);
if (mPresContext->GetBidiEngine()
.SetParagraph(mBuffer, mParaLevel)
.isErr()) {
return NS_ERROR_FAILURE;
};
return NS_OK;
}
/**
* mParaLevel can be NSBIDI_DEFAULT_LTR as well as NSBIDI_LTR or NSBIDI_RTL.
* GetParaLevel() returns the actual (resolved) paragraph level which is
* always either NSBIDI_LTR or NSBIDI_RTL
* mParaLevel can be intl::Bidi::Direction::LTR as well as
* intl::Bidi::Direction::LTR or intl::Bidi::Direction::RTL.
* GetParagraphEmbeddingLevel() returns the actual (resolved) paragraph level
* which is always either intl::Bidi::Direction::LTR or
* intl::Bidi::Direction::RTL
*/
nsBidiLevel GetParaLevel() {
nsBidiLevel paraLevel = mParaLevel;
if (paraLevel == NSBIDI_DEFAULT_LTR || paraLevel == NSBIDI_DEFAULT_RTL) {
paraLevel = mPresContext->GetBidiEngine().GetParaLevel();
EmbeddingLevel GetParagraphEmbeddingLevel() {
EmbeddingLevel paraLevel = mParaLevel;
if (paraLevel == EmbeddingLevel::DefaultLTR() ||
paraLevel == EmbeddingLevel::DefaultRTL()) {
paraLevel = mPresContext->GetBidiEngine().GetParagraphEmbeddingLevel();
}
return paraLevel;
}
nsBidiDirection GetDirection() {
return mPresContext->GetBidiEngine().GetDirection();
intl::Bidi::ParagraphDirection GetParagraphDirection() {
return mPresContext->GetBidiEngine().GetParagraphDirection();
}
nsresult CountRuns(int32_t* runCount) {
return mPresContext->GetBidiEngine().CountRuns(runCount);
auto result = mPresContext->GetBidiEngine().CountRuns();
if (result.isErr()) {
return NS_ERROR_FAILURE;
}
*runCount = result.unwrap();
return NS_OK;
}
void GetLogicalRun(int32_t aLogicalStart, int32_t* aLogicalLimit,
nsBidiLevel* aLevel) {
EmbeddingLevel* aLevel) {
mPresContext->GetBidiEngine().GetLogicalRun(aLogicalStart, aLogicalLimit,
aLevel);
if (mIsVisual) {
*aLevel = GetParaLevel();
*aLevel = GetParagraphEmbeddingLevel();
}
}
@ -465,7 +480,7 @@ struct MOZ_STACK_CLASS BidiLineData {
AutoTArray<nsIFrame*, 16> mLogicalFrames;
AutoTArray<nsIFrame*, 16> mVisualFrames;
AutoTArray<int32_t, 16> mIndexMap;
AutoTArray<uint8_t, 16> mLevels;
AutoTArray<EmbeddingLevel, 16> mLevels;
bool mIsReordered;
BidiLineData(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine) {
@ -477,11 +492,11 @@ struct MOZ_STACK_CLASS BidiLineData {
bool hasRTLFrames = false;
bool hasVirtualControls = false;
auto appendFrame = [&](nsIFrame* frame, nsBidiLevel level) {
auto appendFrame = [&](nsIFrame* frame, EmbeddingLevel level) {
mLogicalFrames.AppendElement(frame);
mLevels.AppendElement(level);
mIndexMap.AppendElement(0);
if (IS_LEVEL_RTL(level)) {
if (level.IsRTL()) {
hasRTLFrames = true;
}
};
@ -502,7 +517,7 @@ struct MOZ_STACK_CLASS BidiLineData {
}
// Reorder the line
nsBidi::ReorderVisual(mLevels.Elements(), FrameCount(),
mozilla::intl::Bidi::ReorderVisual(mLevels.Elements(), FrameCount(),
mIndexMap.Elements());
// Strip virtual frames
@ -865,7 +880,8 @@ nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) {
nsresult rv = aBpd->SetPara();
NS_ENSURE_SUCCESS(rv, rv);
nsBidiLevel embeddingLevel = aBpd->GetParaLevel();
intl::Bidi::EmbeddingLevel embeddingLevel =
aBpd->GetParagraphEmbeddingLevel();
rv = aBpd->CountRuns(&runCount);
NS_ENSURE_SUCCESS(rv, rv);
@ -897,8 +913,9 @@ nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) {
# endif
#endif
if (runCount == 1 && frameCount == 1 && aBpd->GetDirection() == NSBIDI_LTR &&
aBpd->GetParaLevel() == 0) {
if (runCount == 1 && frameCount == 1 &&
aBpd->GetParagraphDirection() == intl::Bidi::ParagraphDirection::LTR &&
aBpd->GetParagraphEmbeddingLevel() == 0) {
// We have a single left-to-right frame in a left-to-right paragraph,
// without bidi isolation from the surrounding text.
// Make sure that the embedding level and base level frame properties aren't
@ -920,13 +937,13 @@ nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) {
}
BidiParagraphData::FrameInfo lastRealFrame;
nsBidiLevel lastEmbeddingLevel = kBidiLevelNone;
nsBidiLevel precedingControl = kBidiLevelNone;
EmbeddingLevel lastEmbeddingLevel = kBidiLevelNone;
EmbeddingLevel precedingControl = kBidiLevelNone;
auto storeBidiDataToFrame = [&]() {
FrameBidiData bidiData;
bidiData.embeddingLevel = embeddingLevel;
bidiData.baseLevel = aBpd->GetParaLevel();
bidiData.baseLevel = aBpd->GetParagraphEmbeddingLevel();
// If a control character doesn't have a lower embedding level than
// both the preceding and the following frame, it isn't something
// needed for getting the correct result. This optimization should
@ -1506,11 +1523,11 @@ FrameBidiData nsBidiPresUtils::GetFrameBidiData(nsIFrame* aFrame) {
return GetFirstLeaf(aFrame)->GetBidiData();
}
nsBidiLevel nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame) {
EmbeddingLevel nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame) {
return GetFirstLeaf(aFrame)->GetEmbeddingLevel();
}
nsBidiLevel nsBidiPresUtils::GetFrameBaseLevel(const nsIFrame* aFrame) {
EmbeddingLevel nsBidiPresUtils::GetFrameBaseLevel(const nsIFrame* aFrame) {
const nsIFrame* firstLeaf = aFrame;
while (!IsBidiLeaf(firstLeaf)) {
firstLeaf = firstLeaf->PrincipalChildList().FirstChild();
@ -1871,7 +1888,7 @@ nscoord nsBidiPresUtils::RepositionInlineFrames(BidiLineData* aBld,
for (; index != limit; index += step) {
frame = aBld->VisualFrameAt(index);
start += RepositionFrame(
frame, !(IS_LEVEL_RTL(aBld->mLevels[aBld->mIndexMap[index]])), start,
frame, !(aBld->mLevels[aBld->mIndexMap[index]].IsRTL()), start,
&continuationStates, aLineWM, false, aContainerSize);
}
return start;
@ -2079,7 +2096,7 @@ RemoveDiacritics(char16_t* aText,
}
#endif
void nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine,
void nsBidiPresUtils::CalculateCharType(intl::Bidi* aBidiEngine,
const char16_t* aText, int32_t& aOffset,
int32_t aCharTypeLimit,
int32_t& aRunLimit, int32_t& aRunLength,
@ -2143,27 +2160,29 @@ void nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine,
aOffset = offset;
}
nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
nsBidiLevel aBaseLevel,
nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext,
BidiProcessor& aprocessor, Mode aMode,
nsBidiPositionResolve* aPosResolve,
int32_t aPosResolveCount, nscoord* aWidth,
nsBidi* aBidiEngine) {
mozilla::intl::Bidi* aBidiEngine) {
NS_ASSERTION((aPosResolve == nullptr) != (aPosResolveCount > 0),
"Incorrect aPosResolve / aPosResolveCount arguments");
int32_t runCount;
nsAutoString textBuffer(aText, aLength);
textBuffer.ReplaceChar(kSeparators, kSpace);
const char16_t* text = textBuffer.get();
nsresult rv = aBidiEngine->SetPara(text, aLength, aBaseLevel);
if (NS_FAILED(rv)) return rv;
if (aBidiEngine->SetParagraph(Span(text, aLength), aBaseLevel).isErr()) {
return NS_ERROR_FAILURE;
}
rv = aBidiEngine->CountRuns(&runCount);
if (NS_FAILED(rv)) return rv;
auto result = aBidiEngine->CountRuns();
if (result.isErr()) {
return NS_ERROR_FAILURE;
}
int32_t runCount = result.unwrap();
nscoord xOffset = 0;
nscoord width, xEndRun = 0;
@ -2180,15 +2199,16 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
}
for (i = 0; i < runCount; i++) {
nsBidiDirection dir = aBidiEngine->GetVisualRun(i, &start, &length);
mozilla::intl::Bidi::Direction dir =
aBidiEngine->GetVisualRun(i, &start, &length);
nsBidiLevel level;
EmbeddingLevel level;
aBidiEngine->GetLogicalRun(start, &limit, &level);
dir = DIRECTION_FROM_LEVEL(level);
dir = level.Direction();
int32_t subRunLength = limit - start;
int32_t lineOffset = start;
int32_t typeLimit = std::min(limit, aLength);
int32_t typeLimit = std::min(limit, AssertedCast<int32_t>(aLength));
int32_t subRunCount = 1;
int32_t subRunLimit = typeLimit;
@ -2204,8 +2224,9 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
* x-coordinate of the end of the run for the start of the next run.
*/
if (dir == NSBIDI_RTL) {
aprocessor.SetText(text + start, subRunLength, dir);
if (dir == intl::Bidi::Direction::RTL) {
aprocessor.SetText(text + start, subRunLength,
intl::Bidi::Direction::RTL);
width = aprocessor.GetWidth();
xOffset += width;
xEndRun = xOffset;
@ -2227,7 +2248,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
aprocessor.SetText(runVisualText.get(), subRunLength, dir);
width = aprocessor.GetWidth();
totalWidth += width;
if (dir == NSBIDI_RTL) {
if (dir == mozilla::intl::Bidi::Direction::RTL) {
xOffset -= width;
}
if (aMode == MODE_DRAW) {
@ -2297,7 +2318,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
// The position in the text where this run's "left part" begins.
const char16_t* visualLeftPart;
const char16_t* visualRightSide;
if (dir == NSBIDI_RTL) {
if (dir == mozilla::intl::Bidi::Direction::RTL) {
// One day, son, this could all be replaced with
// mPresContext->GetBidiEngine().GetVisualIndex() ...
posResolve->visualIndex =
@ -2326,7 +2347,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
}
}
if (dir == NSBIDI_LTR) {
if (dir == intl::Bidi::Direction::LTR) {
xOffset += width;
}
@ -2335,7 +2356,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
subRunLimit = typeLimit;
subRunLength = typeLimit - lineOffset;
} // while
if (dir == NSBIDI_RTL) {
if (dir == intl::Bidi::Direction::RTL) {
xOffset = xEndRun;
}
@ -2367,8 +2388,8 @@ class MOZ_STACK_CLASS nsIRenderingContextBidiProcessor final
~nsIRenderingContextBidiProcessor() { mFontMetrics->SetTextRunRTL(false); }
virtual void SetText(const char16_t* aText, int32_t aLength,
nsBidiDirection aDirection) override {
mFontMetrics->SetTextRunRTL(aDirection == NSBIDI_RTL);
intl::Bidi::Direction aDirection) override {
mFontMetrics->SetTextRunRTL(aDirection == intl::Bidi::Direction::RTL);
mText = aText;
mLength = aLength;
}
@ -2399,7 +2420,7 @@ class MOZ_STACK_CLASS nsIRenderingContextBidiProcessor final
};
nsresult nsBidiPresUtils::ProcessTextForRenderingContext(
const char16_t* aText, int32_t aLength, nsBidiLevel aBaseLevel,
const char16_t* aText, int32_t aLength, EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics,
Mode aMode, nscoord aX, nscoord aY, nsBidiPositionResolve* aPosResolve,
@ -2413,15 +2434,16 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(
}
/* static */
nsBidiLevel nsBidiPresUtils::BidiLevelFromStyle(ComputedStyle* aComputedStyle) {
EmbeddingLevel nsBidiPresUtils::BidiLevelFromStyle(
ComputedStyle* aComputedStyle) {
if (aComputedStyle->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
return NSBIDI_DEFAULT_LTR;
return EmbeddingLevel::DefaultLTR();
}
if (aComputedStyle->StyleVisibility()->mDirection == StyleDirection::Rtl) {
return NSBIDI_RTL;
return EmbeddingLevel::RTL();
}
return NSBIDI_LTR;
return EmbeddingLevel::LTR();
}

View file

@ -8,7 +8,7 @@
#define nsBidiPresUtils_h___
#include "gfxContext.h"
#include "nsBidi.h"
#include "mozilla/intl/Bidi.h"
#include "nsBidiUtils.h"
#include "nsHashKeys.h"
#include "nsCoord.h"
@ -164,7 +164,7 @@ class nsBidiPresUtils {
* mixed direction.
*/
virtual void SetText(const char16_t* aText, int32_t aLength,
nsBidiDirection aDirection) = 0;
mozilla::intl::Bidi::Direction aDirection) = 0;
/**
* Returns the measured width of the text given in SetText. If SetText was
@ -229,15 +229,6 @@ class nsBidiPresUtils {
* @param[in] aText the string to be rendered (in logical order)
* @param aLength the number of characters in 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
@ -248,11 +239,14 @@ class nsBidiPresUtils {
* visual positions; can be nullptr if this functionality is not required
* @param aPosResolveCount number of items in the aPosResolve array
*/
static nsresult RenderText(
const char16_t* aText, int32_t aLength, nsBidiLevel aBaseLevel,
nsPresContext* aPresContext, gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics,
nscoord aX, nscoord aY, nsBidiPositionResolve* aPosResolve = nullptr,
static nsresult RenderText(const char16_t* aText, int32_t aLength,
mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext,
gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget,
nsFontMetrics& aFontMetrics, nscoord aX,
nscoord aY,
nsBidiPositionResolve* aPosResolve = nullptr,
int32_t aPosResolveCount = 0) {
return ProcessTextForRenderingContext(
aText, aLength, aBaseLevel, aPresContext, aRenderingContext,
@ -260,10 +254,10 @@ class nsBidiPresUtils {
aPosResolve, aPosResolveCount, nullptr);
}
static nscoord MeasureTextWidth(const char16_t* aText, int32_t aLength,
nsBidiLevel aBaseLevel,
nsPresContext* aPresContext,
gfxContext& aRenderingContext,
static nscoord MeasureTextWidth(
const char16_t* aText, int32_t aLength,
mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, gfxContext& aRenderingContext,
nsFontMetrics& aFontMetrics) {
nscoord length;
nsresult rv = ProcessTextForRenderingContext(
@ -317,31 +311,32 @@ class nsBidiPresUtils {
/**
* Get the bidi embedding level of the given (inline) frame.
*/
static nsBidiLevel GetFrameEmbeddingLevel(nsIFrame* aFrame);
static mozilla::intl::Bidi::EmbeddingLevel GetFrameEmbeddingLevel(
nsIFrame* aFrame);
/**
* Get the bidi base level of the given (inline) frame.
*/
static nsBidiLevel GetFrameBaseLevel(const nsIFrame* aFrame);
static mozilla::intl::Bidi::EmbeddingLevel GetFrameBaseLevel(
const nsIFrame* aFrame);
/**
* Get an nsBidiDirection representing the direction implied by the
* bidi base level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left)
* NSBIDI_MIXED will never be returned.
* Get a mozilla::intl::Bidi::Direction representing the direction implied by
* the bidi base level of the frame.
* @return mozilla::intl::Bidi::Direction
*/
static nsBidiDirection ParagraphDirection(const nsIFrame* aFrame) {
return DIRECTION_FROM_LEVEL(GetFrameBaseLevel(aFrame));
static mozilla::intl::Bidi::Direction ParagraphDirection(
const nsIFrame* aFrame) {
return GetFrameBaseLevel(aFrame).Direction();
}
/**
* Get an nsBidiDirection representing the direction implied by the
* bidi embedding level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left)
* NSBIDI_MIXED will never be returned.
* Get a mozilla::intl::Bidi::Direction representing the direction implied by
* the bidi embedding level of the frame.
* @return mozilla::intl::Bidi::Direction
*/
static nsBidiDirection FrameDirection(nsIFrame* aFrame) {
return DIRECTION_FROM_LEVEL(GetFrameEmbeddingLevel(aFrame));
static mozilla::intl::Bidi::Direction FrameDirection(nsIFrame* aFrame) {
return GetFrameEmbeddingLevel(aFrame).Direction();
}
static bool IsFrameInParagraphDirection(nsIFrame* aFrame) {
@ -353,7 +348,7 @@ class nsBidiPresUtils {
// the leaf frame.
static bool IsReversedDirectionFrame(const nsIFrame* aFrame) {
mozilla::FrameBidiData bidiData = aFrame->GetBidiData();
return !IS_SAME_DIRECTION(bidiData.embeddingLevel, bidiData.baseLevel);
return !bidiData.embeddingLevel.IsSameDirection(bidiData.baseLevel);
}
enum Mode { MODE_DRAW, MODE_MEASURE };
@ -365,15 +360,6 @@ class nsBidiPresUtils {
* @param[in] aText the string to be processed (in logical order)
* @param aLength the number of characters in 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
@ -385,31 +371,33 @@ class nsBidiPresUtils {
* @param aPosResolveCount number of items in the aPosResolve array
* @param[out] aWidth Pointer to where the width will be stored (may be null)
*/
static nsresult ProcessText(const char16_t* aText, int32_t aLength,
nsBidiLevel aBaseLevel,
static nsresult ProcessText(const char16_t* aText, size_t aLength,
mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext,
BidiProcessor& aprocessor, Mode aMode,
nsBidiPositionResolve* aPosResolve,
int32_t aPosResolveCount, nscoord* aWidth,
nsBidi* aBidiEngine);
mozilla::intl::Bidi* aBidiEngine);
/**
* 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.
* If |unicode-bidi| is set to "[-moz-]plaintext", returns
* EmbeddingLevel::DefaultLTR, 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|
* Otherwise returns EmbeddingLevel::LTR or EmbeddingLevel::RTL depending on
* the value of |direction|
*/
static nsBidiLevel BidiLevelFromStyle(mozilla::ComputedStyle* aComputedStyle);
static mozilla::intl::Bidi::EmbeddingLevel BidiLevelFromStyle(
mozilla::ComputedStyle* aComputedStyle);
private:
static nsresult ProcessTextForRenderingContext(
const char16_t* aText, int32_t aLength, nsBidiLevel aBaseLevel,
const char16_t* aText, int32_t aLength,
mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics,
Mode aMode,
@ -572,11 +560,11 @@ class nsBidiPresUtils {
*/
static void RemoveBidiContinuation(BidiParagraphData* aBpd, nsIFrame* aFrame,
int32_t aFirstIndex, int32_t aLastIndex);
static void CalculateCharType(nsBidi* aBidiEngine, const char16_t* aText,
int32_t& aOffset, int32_t aCharTypeLimit,
int32_t& aRunLimit, int32_t& aRunLength,
int32_t& aRunCount, uint8_t& aCharType,
uint8_t& aPrevCharType);
static void CalculateCharType(mozilla::intl::Bidi* aBidiEngine,
const char16_t* aText, int32_t& aOffset,
int32_t aCharTypeLimit, int32_t& aRunLimit,
int32_t& aRunLength, int32_t& aRunCount,
uint8_t& aCharType, uint8_t& aPrevCharType);
static void StripBidiControlCharacters(char16_t* aText, int32_t& aTextLength);
};

View file

@ -12,6 +12,7 @@
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/intl/Bidi.h"
#include "nsCOMPtr.h"
#include "nsFontMetrics.h"
#include "nsITimer.h"
@ -39,6 +40,8 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
using EmbeddingLevel = mozilla::intl::Bidi::EmbeddingLevel;
// The bidi indicator hangs off the caret to one side, to show which
// direction the typing is in. It needs to be at least 2x2 to avoid looking like
// an insignificant dot
@ -389,7 +392,8 @@ nsIFrame* nsCaret::GetFrameAndOffset(const Selection* aSelection,
nsIContent* contentNode = focusNode->AsContent();
nsFrameSelection* frameSelection = aSelection->GetFrameSelection();
nsBidiLevel bidiLevel = frameSelection->GetCaretBidiLevel();
mozilla::intl::Bidi::EmbeddingLevel bidiLevel =
frameSelection->GetCaretBidiLevel();
return nsCaret::GetCaretFrameForNodeOffset(
frameSelection, contentNode, focusOffset, frameSelection->GetHint(),
@ -644,7 +648,8 @@ void nsCaret::StopBlinking() {
nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
nsFrameSelection* aFrameSelection, nsIContent* aContentNode,
int32_t aOffset, CaretAssociationHint aFrameHint, nsBidiLevel aBidiLevel,
int32_t aOffset, CaretAssociationHint aFrameHint,
mozilla::intl::Bidi::EmbeddingLevel aBidiLevel,
nsIFrame** aReturnUnadjustedFrame, int32_t* aReturnOffset) {
if (!aFrameSelection) {
return nullptr;
@ -696,8 +701,10 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
nsIFrame* frameBefore;
nsIFrame* frameAfter;
nsBidiLevel levelBefore; // Bidi level of the character before the caret
nsBidiLevel levelAfter; // Bidi level of the character after the caret
mozilla::intl::Bidi::EmbeddingLevel
levelBefore; // Bidi level of the character before the caret
mozilla::intl::Bidi::EmbeddingLevel
levelAfter; // Bidi level of the character after the caret
auto [start, end] = theFrame->GetOffsets();
if (start == 0 || end == 0 || start == theFrameOffset ||
@ -720,9 +727,9 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
std::max(levelBefore, levelAfter)); // rule c4
if (aBidiLevel == levelBefore || // rule c1
(aBidiLevel > levelBefore && aBidiLevel < levelAfter &&
IS_SAME_DIRECTION(aBidiLevel, levelBefore)) || // rule c5
aBidiLevel.IsSameDirection(levelBefore)) || // rule c5
(aBidiLevel < levelBefore && aBidiLevel > levelAfter &&
IS_SAME_DIRECTION(aBidiLevel, levelBefore))) // rule c9
aBidiLevel.IsSameDirection(levelBefore))) // rule c9
{
if (theFrame != frameBefore) {
if (frameBefore) { // if there is a frameBefore, move into it
@ -735,7 +742,8 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
// the first frame on the line has a different Bidi level from
// the paragraph level, there is no real frame for the caret to
// be in. We have to find the visually first frame on the line.
nsBidiLevel baseLevel = frameAfter->GetBaseLevel();
mozilla::intl::Bidi::EmbeddingLevel baseLevel =
frameAfter->GetBaseLevel();
if (baseLevel != levelAfter) {
nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0,
nsPoint(0, 0), false, true, false,
@ -749,9 +757,9 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
}
} else if (aBidiLevel == levelAfter || // rule c2
(aBidiLevel > levelBefore && aBidiLevel < levelAfter &&
IS_SAME_DIRECTION(aBidiLevel, levelAfter)) || // rule c6
aBidiLevel.IsSameDirection(levelAfter)) || // rule c6
(aBidiLevel < levelBefore && aBidiLevel > levelAfter &&
IS_SAME_DIRECTION(aBidiLevel, levelAfter))) // rule c10
aBidiLevel.IsSameDirection(levelAfter))) // rule c10
{
if (theFrame != frameAfter) {
if (frameAfter) {
@ -766,7 +774,8 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
// Bidi level from the paragraph level, there is no real frame
// for the caret to be in. We have to find the visually last
// frame on the line.
nsBidiLevel baseLevel = frameBefore->GetBaseLevel();
mozilla::intl::Bidi::EmbeddingLevel baseLevel =
frameBefore->GetBaseLevel();
if (baseLevel != levelBefore) {
nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0,
nsPoint(0, 0), false, true, false,
@ -781,34 +790,38 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(
} else if (aBidiLevel > levelBefore &&
aBidiLevel < levelAfter && // rule c7/8
// before and after have the same parity
IS_SAME_DIRECTION(levelBefore, levelAfter) &&
levelBefore.IsSameDirection(levelAfter) &&
// caret has different parity
!IS_SAME_DIRECTION(aBidiLevel, levelAfter)) {
!aBidiLevel.IsSameDirection(levelAfter)) {
if (NS_SUCCEEDED(aFrameSelection->GetFrameFromLevel(
frameAfter, eDirNext, aBidiLevel, &theFrame))) {
std::tie(start, end) = theFrame->GetOffsets();
levelAfter = theFrame->GetEmbeddingLevel();
if (IS_LEVEL_RTL(aBidiLevel)) // c8: caret to the right of the
// rightmost character
theFrameOffset = IS_LEVEL_RTL(levelAfter) ? start : end;
else // c7: caret to the left of the leftmost character
theFrameOffset = IS_LEVEL_RTL(levelAfter) ? end : start;
if (aBidiLevel.IsRTL()) {
// c8: caret to the right of the rightmost character
theFrameOffset = levelAfter.IsRTL() ? start : end;
} else {
// c7: caret to the left of the leftmost character
theFrameOffset = levelAfter.IsRTL() ? end : start;
}
}
} else if (aBidiLevel < levelBefore &&
aBidiLevel > levelAfter && // rule c11/12
// before and after have the same parity
IS_SAME_DIRECTION(levelBefore, levelAfter) &&
levelBefore.IsSameDirection(levelAfter) &&
// caret has different parity
!IS_SAME_DIRECTION(aBidiLevel, levelAfter)) {
!aBidiLevel.IsSameDirection(levelAfter)) {
if (NS_SUCCEEDED(aFrameSelection->GetFrameFromLevel(
frameBefore, eDirPrevious, aBidiLevel, &theFrame))) {
std::tie(start, end) = theFrame->GetOffsets();
levelBefore = theFrame->GetEmbeddingLevel();
if (IS_LEVEL_RTL(aBidiLevel)) // c12: caret to the left of the
// leftmost character
theFrameOffset = IS_LEVEL_RTL(levelBefore) ? end : start;
else // c11: caret to the right of the rightmost character
theFrameOffset = IS_LEVEL_RTL(levelBefore) ? start : end;
if (aBidiLevel.IsRTL()) {
// c12: caret to the left of the leftmost character
theFrameOffset = levelBefore.IsRTL() ? end : start;
} else {
// c11: caret to the right of the rightmost character
theFrameOffset = levelBefore.IsRTL() ? start : end;
}
}
}
}

View file

@ -9,6 +9,7 @@
#ifndef nsCaret_h__
#define nsCaret_h__
#include "mozilla/intl/Bidi.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/Selection.h"
#include "nsCoord.h"
@ -179,7 +180,8 @@ class nsCaret final : public nsISelectionListener {
nsRect* aRect);
static nsIFrame* GetCaretFrameForNodeOffset(
nsFrameSelection* aFrameSelection, nsIContent* aContentNode,
int32_t aOffset, CaretAssociationHint aFrameHint, uint8_t aBidiLevel,
int32_t aOffset, CaretAssociationHint aFrameHint,
mozilla::intl::Bidi::EmbeddingLevel aBidiLevel,
nsIFrame** aReturnUnadjustedFrame, int32_t* aReturnOffset);
static nsRect GetGeometryForFrame(nsIFrame* aFrame, int32_t aFrameOffset,
nscoord* aBidiIndicatorSize);

View file

@ -52,6 +52,7 @@
#include "mozilla/dom/KeyframeEffect.h"
#include "mozilla/dom/SVGViewportElement.h"
#include "mozilla/dom/UIEvent.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/EventDispatcher.h"
@ -1542,7 +1543,10 @@ nsRect nsLayoutUtils::GetScrolledRect(nsIFrame* aScrolledFrame,
WritingMode wm = aScrolledFrame->GetWritingMode();
// Potentially override the frame's direction to use the direction found
// by ScrollFrameHelper::GetScrolledFrameDir()
wm.SetDirectionFromBidiLevel(aDirection == StyleDirection::Rtl ? 1 : 0);
wm.SetDirectionFromBidiLevel(
aDirection == StyleDirection::Rtl
? mozilla::intl::Bidi::EmbeddingLevel::RTL()
: mozilla::intl::Bidi::EmbeddingLevel::LTR());
nscoord x1 = aScrolledFrameOverflowArea.x,
x2 = aScrolledFrameOverflowArea.XMost(),
@ -5552,7 +5556,8 @@ nscoord nsLayoutUtils::AppUnitWidthOfStringBidi(const char16_t* aString,
gfxContext& aContext) {
nsPresContext* presContext = aFrame->PresContext();
if (presContext->BidiEnabled()) {
nsBidiLevel level = nsBidiPresUtils::BidiLevelFromStyle(aFrame->Style());
mozilla::intl::Bidi::EmbeddingLevel level =
nsBidiPresUtils::BidiLevelFromStyle(aFrame->Style());
return nsBidiPresUtils::MeasureTextWidth(
aString, aLength, level, presContext, aContext, aFontMetrics);
}
@ -5631,7 +5636,8 @@ void nsLayoutUtils::DrawString(const nsIFrame* aFrame,
nsPresContext* presContext = aFrame->PresContext();
if (presContext->BidiEnabled()) {
nsBidiLevel level = nsBidiPresUtils::BidiLevelFromStyle(aComputedStyle);
mozilla::intl::Bidi::EmbeddingLevel level =
nsBidiPresUtils::BidiLevelFromStyle(aComputedStyle);
rv = nsBidiPresUtils::RenderText(aString, aLength, level, presContext,
*aContext, aContext->GetDrawTarget(),
aFontMetrics, aPoint.x, aPoint.y);

View file

@ -100,7 +100,6 @@
#include "nsBidiUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsBidi.h"
#include "mozilla/dom/URL.h"
#include "mozilla/ServoCSSParser.h"
@ -2683,11 +2682,11 @@ uint64_t nsPresContext::GetUndisplayedRestyleGeneration() const {
return mRestyleManager->GetUndisplayedRestyleGeneration();
}
nsBidi& nsPresContext::GetBidiEngine() {
mozilla::intl::Bidi& nsPresContext::GetBidiEngine() {
MOZ_ASSERT(NS_IsMainThread());
if (!mBidiEngine) {
mBidiEngine.reset(new nsBidi());
mBidiEngine.reset(new mozilla::intl::Bidi());
}
return *mBidiEngine;
}

View file

@ -9,6 +9,7 @@
#ifndef nsPresContext_h___
#define nsPresContext_h___
#include "mozilla/intl/Bidi.h"
#include "mozilla/AppUnits.h"
#include "mozilla/Attributes.h"
#include "mozilla/EnumeratedArray.h"
@ -43,7 +44,6 @@
#include "nsThreadUtils.h"
#include "Units.h"
class nsBidi;
class nsIPrintSettings;
class nsDocShell;
class nsIDocShell;
@ -1079,7 +1079,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
mHasWarnedAboutTooLargeDashedOrDottedRadius = true;
}
nsBidi& GetBidiEngine();
mozilla::intl::Bidi& GetBidiEngine();
gfxFontFeatureValueSet* GetFontFeatureValuesLookup() const {
return mFontFeatureValuesLookup;
@ -1207,7 +1207,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
nsCOMPtr<nsITheme> mTheme;
nsCOMPtr<nsIPrintSettings> mPrintSettings;
mozilla::UniquePtr<nsBidi> mBidiEngine;
mozilla::UniquePtr<mozilla::intl::Bidi> mBidiEngine;
AutoTArray<TransactionInvalidations, 4> mTransactions;

View file

@ -9,6 +9,7 @@
#include <ostream>
#include "mozilla/intl/Bidi.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/EnumeratedRange.h"
@ -524,8 +525,8 @@ class WritingMode {
*
* XXX change uint8_t to UBiDiLevel after bug 924851
*/
void SetDirectionFromBidiLevel(uint8_t level) {
if (IS_LEVEL_RTL(level) == IsBidiLTR()) {
void SetDirectionFromBidiLevel(mozilla::intl::Bidi::EmbeddingLevel level) {
if (level.IsRTL() == IsBidiLTR()) {
mWritingMode ^= StyleWritingMode::RTL | StyleWritingMode::INLINE_REVERSED;
}
}

View file

@ -6,6 +6,7 @@
#include "nsFrameList.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/ArenaObjectID.h"
#include "mozilla/PresShell.h"
#include "nsBidiPresUtils.h"
@ -305,7 +306,8 @@ nsIFrame* nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const {
nsIFrame* parent = mFirstChild->GetParent();
if (!parent) return aFrame ? aFrame->GetPrevSibling() : LastChild();
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(mFirstChild);
mozilla::intl::Bidi::Direction paraDir =
nsBidiPresUtils::ParagraphDirection(mFirstChild);
nsAutoLineIterator iter = parent->GetLineIterator();
if (!iter) {
@ -313,7 +315,7 @@ nsIFrame* nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const {
if (parent->IsLineFrame()) {
// Line frames are not bidi-splittable, so need to consider bidi
// reordering
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1);
} else { // RTL
return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1);
@ -345,7 +347,7 @@ nsIFrame* nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const {
if (aFrame) {
auto line = iter->GetLine(thisLine).unwrap();
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
frame = nsBidiPresUtils::GetFrameToLeftOf(aFrame, line.mFirstFrameOnLine,
line.mNumFramesOnLine);
} else { // RTL
@ -358,7 +360,7 @@ nsIFrame* nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const {
// Get the last frame of the previous line
auto line = iter->GetLine(thisLine - 1).unwrap();
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
frame = nsBidiPresUtils::GetFrameToLeftOf(nullptr, line.mFirstFrameOnLine,
line.mNumFramesOnLine);
} else { // RTL
@ -375,7 +377,8 @@ nsIFrame* nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const {
nsIFrame* parent = mFirstChild->GetParent();
if (!parent) return aFrame ? aFrame->GetPrevSibling() : mFirstChild;
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(mFirstChild);
mozilla::intl::Bidi::Direction paraDir =
nsBidiPresUtils::ParagraphDirection(mFirstChild);
nsAutoLineIterator iter = parent->GetLineIterator();
if (!iter) {
@ -383,7 +386,7 @@ nsIFrame* nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const {
if (parent->IsLineFrame()) {
// Line frames are not bidi-splittable, so need to consider bidi
// reordering
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1);
} else { // RTL
return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1);
@ -415,7 +418,7 @@ nsIFrame* nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const {
if (aFrame) {
auto line = iter->GetLine(thisLine).unwrap();
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
frame = nsBidiPresUtils::GetFrameToRightOf(aFrame, line.mFirstFrameOnLine,
line.mNumFramesOnLine);
} else { // RTL
@ -429,7 +432,7 @@ nsIFrame* nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const {
// Get the first frame of the next line
auto line = iter->GetLine(thisLine + 1).unwrap();
if (paraDir == NSBIDI_LTR) {
if (paraDir == mozilla::intl::Bidi::Direction::LTR) {
frame = nsBidiPresUtils::GetFrameToRightOf(
nullptr, line.mFirstFrameOnLine, line.mNumFramesOnLine);
} else { // RTL

View file

@ -10,6 +10,7 @@
#include "nsFrameSelection.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/Attributes.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/BasePrincipal.h"
@ -599,7 +600,7 @@ nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(
}
void nsFrameSelection::SetCaretBidiLevelAndMaybeSchedulePaint(
nsBidiLevel aLevel) {
mozilla::intl::Bidi::EmbeddingLevel aLevel) {
// If the current level is undefined, we have just inserted new text.
// In this case, we don't want to reset the keyboard language
mCaret.mBidiLevel = aLevel;
@ -610,12 +611,14 @@ void nsFrameSelection::SetCaretBidiLevelAndMaybeSchedulePaint(
}
}
nsBidiLevel nsFrameSelection::GetCaretBidiLevel() const {
mozilla::intl::Bidi::EmbeddingLevel nsFrameSelection::GetCaretBidiLevel()
const {
return mCaret.mBidiLevel;
}
void nsFrameSelection::UndefineCaretBidiLevel() {
mCaret.mBidiLevel |= BIDI_LEVEL_UNDEFINED;
mCaret.mBidiLevel = mozilla::intl::Bidi::EmbeddingLevel(mCaret.mBidiLevel |
BIDI_LEVEL_UNDEFINED);
}
#ifdef PRINT_RANGE
@ -662,9 +665,10 @@ static nsINode* GetClosestInclusiveTableCellAncestor(nsINode* aDomNode) {
static nsDirection GetCaretDirection(const nsIFrame& aFrame,
nsDirection aDirection,
bool aVisualMovement) {
const nsBidiDirection paragraphDirection =
const mozilla::intl::Bidi::Direction paragraphDirection =
nsBidiPresUtils::ParagraphDirection(&aFrame);
return (aVisualMovement && paragraphDirection == NSBIDI_RTL)
return (aVisualMovement &&
paragraphDirection == mozilla::intl::Bidi::Direction::RTL)
? nsDirection(1 - aDirection)
: aDirection;
}
@ -928,7 +932,8 @@ nsPrevNextBidiLevels nsFrameSelection::GetPrevNextBidiLevels(
nsDirection direction;
nsPrevNextBidiLevels levels{};
levels.SetData(nullptr, nullptr, 0, 0);
levels.SetData(nullptr, nullptr, mozilla::intl::Bidi::EmbeddingLevel::LTR(),
mozilla::intl::Bidi::EmbeddingLevel::LTR());
currentFrame = GetFrameForNodeOffset(
aNode, static_cast<int32_t>(aContentOffset), aHint, &currentOffset);
@ -947,7 +952,8 @@ nsPrevNextBidiLevels nsFrameSelection::GetPrevNextBidiLevels(
} else {
// we are neither at the beginning nor at the end of the frame, so we have
// no worries
nsBidiLevel currentLevel = currentFrame->GetEmbeddingLevel();
mozilla::intl::Bidi::EmbeddingLevel currentLevel =
currentFrame->GetEmbeddingLevel();
levels.SetData(currentFrame, currentFrame, currentLevel, currentLevel);
return levels;
}
@ -958,8 +964,8 @@ nsPrevNextBidiLevels nsFrameSelection::GetPrevNextBidiLevels(
.mFrame;
FrameBidiData currentBidi = currentFrame->GetBidiData();
nsBidiLevel currentLevel = currentBidi.embeddingLevel;
nsBidiLevel newLevel =
mozilla::intl::Bidi::EmbeddingLevel currentLevel = currentBidi.embeddingLevel;
mozilla::intl::Bidi::EmbeddingLevel newLevel =
newFrame ? newFrame->GetEmbeddingLevel() : currentBidi.baseLevel;
// If not jumping lines, disregard br frames, since they might be positioned
@ -984,12 +990,13 @@ nsPrevNextBidiLevels nsFrameSelection::GetPrevNextBidiLevels(
return levels;
}
nsresult nsFrameSelection::GetFrameFromLevel(nsIFrame* aFrameIn,
nsDirection aDirection,
nsBidiLevel aBidiLevel,
nsresult nsFrameSelection::GetFrameFromLevel(
nsIFrame* aFrameIn, nsDirection aDirection,
mozilla::intl::Bidi::EmbeddingLevel aBidiLevel,
nsIFrame** aFrameOut) const {
NS_ENSURE_STATE(mPresShell);
nsBidiLevel foundLevel = 0;
mozilla::intl::Bidi::EmbeddingLevel foundLevel =
mozilla::intl::Bidi::EmbeddingLevel::LTR();
nsIFrame* foundFrame = aFrameIn;
nsCOMPtr<nsIFrameEnumerator> frameTraversal;

View file

@ -7,6 +7,7 @@
#ifndef nsFrameSelection_h___
#define nsFrameSelection_h___
#include "mozilla/intl/Bidi.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
@ -25,7 +26,7 @@
class nsRange;
#define BIDI_LEVEL_UNDEFINED 0x80
#define BIDI_LEVEL_UNDEFINED mozilla::intl::Bidi::EmbeddingLevel(0x80)
//----------------------------------------------------------------------
@ -172,7 +173,8 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruct {
struct nsPrevNextBidiLevels {
void SetData(nsIFrame* aFrameBefore, nsIFrame* aFrameAfter,
nsBidiLevel aLevelBefore, nsBidiLevel aLevelAfter) {
mozilla::intl::Bidi::EmbeddingLevel aLevelBefore,
mozilla::intl::Bidi::EmbeddingLevel aLevelAfter) {
mFrameBefore = aFrameBefore;
mFrameAfter = aFrameAfter;
mLevelBefore = aLevelBefore;
@ -180,8 +182,8 @@ struct nsPrevNextBidiLevels {
}
nsIFrame* mFrameBefore;
nsIFrame* mFrameAfter;
nsBidiLevel mLevelBefore;
nsBidiLevel mLevelAfter;
mozilla::intl::Bidi::EmbeddingLevel mLevelBefore;
mozilla::intl::Bidi::EmbeddingLevel mLevelAfter;
};
namespace mozilla {
@ -475,12 +477,13 @@ class nsFrameSelection final {
void SetHint(CaretAssociateHint aHintRight) { mCaret.mHint = aHintRight; }
CaretAssociateHint GetHint() const { return mCaret.mHint; }
void SetCaretBidiLevelAndMaybeSchedulePaint(nsBidiLevel aLevel);
void SetCaretBidiLevelAndMaybeSchedulePaint(
mozilla::intl::Bidi::EmbeddingLevel aLevel);
/**
* GetCaretBidiLevel gets the caret bidi level.
*/
nsBidiLevel GetCaretBidiLevel() const;
mozilla::intl::Bidi::EmbeddingLevel GetCaretBidiLevel() const;
/**
* UndefineCaretBidiLevel sets the caret bidi level to "undefined".
@ -695,7 +698,7 @@ class nsFrameSelection final {
* @param aFrameOut will hold the frame returned
*/
nsresult GetFrameFromLevel(nsIFrame* aFrameIn, nsDirection aDirection,
nsBidiLevel aBidiLevel,
mozilla::intl::Bidi::EmbeddingLevel aBidiLevel,
nsIFrame** aFrameOut) const;
/**
@ -1040,7 +1043,7 @@ class nsFrameSelection final {
// Hint to tell if the selection is at the end of this line or beginning of
// next.
CaretAssociateHint mHint = mozilla::CARET_ASSOCIATE_BEFORE;
nsBidiLevel mBidiLevel = BIDI_LEVEL_UNDEFINED;
mozilla::intl::Bidi::EmbeddingLevel mBidiLevel = BIDI_LEVEL_UNDEFINED;
bool IsVisualMovement(bool aContinueSelection,
CaretMovementStyle aMovementStyle) const;
@ -1048,7 +1051,8 @@ class nsFrameSelection final {
Caret mCaret;
nsBidiLevel mKbdBidiLevel = NSBIDI_LTR;
mozilla::intl::Bidi::EmbeddingLevel mKbdBidiLevel =
mozilla::intl::Bidi::EmbeddingLevel::LTR();
class DesiredCaretPos {
public:

View file

@ -21,6 +21,7 @@
#include "nsContainerFrame.h"
#include "nsGkAtoms.h"
#include "nsNameSpaceManager.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/gfx/gfxVars.h"
#include "nsFontMetrics.h"
@ -7117,7 +7118,8 @@ StyleDirection ScrollFrameHelper::GetScrolledFrameDir() const {
if (mScrolledFrame->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
if (nsIFrame* child = mScrolledFrame->PrincipalChildList().FirstChild()) {
return nsBidiPresUtils::ParagraphDirection(child) == NSBIDI_LTR
return nsBidiPresUtils::ParagraphDirection(child) ==
mozilla::intl::Bidi::Direction::LTR
? StyleDirection::Ltr
: StyleDirection::Rtl;
}

View file

@ -25,6 +25,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h"
#include "mozilla/ResultExtensions.h"
@ -1697,7 +1698,8 @@ WritingMode nsIFrame::WritingModeForLine(WritingMode aSelfWM,
WritingMode writingMode = aSelfWM;
if (StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
nsBidiLevel frameLevel = nsBidiPresUtils::GetFrameBaseLevel(aSubFrame);
mozilla::intl::Bidi::EmbeddingLevel frameLevel =
nsBidiPresUtils::GetFrameBaseLevel(aSubFrame);
writingMode.SetDirectionFromBidiLevel(frameLevel);
}
@ -7923,8 +7925,9 @@ void nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix,
}
if (HasProperty(BidiDataProperty())) {
FrameBidiData bidi = GetBidiData();
aTo += nsPrintfCString(" bidi(%d,%d,%d)", bidi.baseLevel,
bidi.embeddingLevel, bidi.precedingControl);
aTo += nsPrintfCString(" bidi(%d,%d,%d)", bidi.baseLevel.Value(),
bidi.embeddingLevel.Value(),
bidi.precedingControl.Value());
}
if (IsTransformed()) {
aTo += nsPrintfCString(" transformed");
@ -8105,7 +8108,7 @@ nsresult nsIFrame::GetPointFromOffset(int32_t inOffset, nsPoint* outPoint) {
bool hasBidiData;
FrameBidiData bidiData = GetProperty(BidiDataProperty(), &hasBidiData);
bool isRTL = hasBidiData
? IS_LEVEL_RTL(bidiData.embeddingLevel)
? bidiData.embeddingLevel.IsRTL()
: StyleVisibility()->mDirection == StyleDirection::Rtl;
if ((!isRTL && inOffset > newOffset) ||
(isRTL && inOffset <= newOffset)) {
@ -9102,7 +9105,8 @@ Result<bool, nsresult> nsIFrame::IsVisuallyAtLineEdge(
return true;
}
bool frameIsRTL = (nsBidiPresUtils::FrameDirection(*framePtr) == NSBIDI_RTL);
bool frameIsRTL = (nsBidiPresUtils::FrameDirection(*framePtr) ==
mozilla::intl::Bidi::Direction::RTL);
if ((frameIsRTL == lineIsRTL) == (aDirection == eDirPrevious)) {
nsIFrame::GetFirstLeaf(framePtr);
} else {

View file

@ -78,6 +78,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/CompositorHitTestInfo.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/intl/Bidi.h"
#include "nsDisplayItemTypes.h"
#include "nsPresContext.h"
#include "nsTHashSet.h"
@ -359,76 +360,6 @@ class nsReflowStatus final {
// Convert nsReflowStatus to a human-readable string.
std::ostream& operator<<(std::ostream& aStream, const nsReflowStatus& aStatus);
/**
* nsBidiLevel is the type of the level values in our Unicode Bidi
* implementation.
* It holds an embedding level and indicates the visual direction
* by its bit 0 (even/odd value).<p>
*
* <li><code>aParaLevel</code> can be set to the
* pseudo-level values <code>NSBIDI_DEFAULT_LTR</code>
* and <code>NSBIDI_DEFAULT_RTL</code>.</li></ul>
*
* @see nsBidi::SetPara
*
* <p>The related constants are not real, valid level values.
* <code>NSBIDI_DEFAULT_XXX</code> can be used to specify
* a default for the paragraph level for
* when the <code>SetPara</code> function
* shall determine it but there is no
* strongly typed character in the input.<p>
*
* Note that the value for <code>NSBIDI_DEFAULT_LTR</code> is even
* and the one for <code>NSBIDI_DEFAULT_RTL</code> is odd,
* just like with normal LTR and RTL level values -
* these special values are designed that way. Also, the implementation
* assumes that NSBIDI_MAX_EXPLICIT_LEVEL is odd.
*
* @see NSBIDI_DEFAULT_LTR
* @see NSBIDI_DEFAULT_RTL
* @see NSBIDI_LEVEL_OVERRIDE
* @see NSBIDI_MAX_EXPLICIT_LEVEL
*/
typedef uint8_t nsBidiLevel;
/**
* Paragraph level setting.
* If there is no strong character, then set the paragraph level to 0
* (left-to-right).
*/
#define NSBIDI_DEFAULT_LTR 0xfe
/**
* Paragraph level setting.
* If there is no strong character, then set the paragraph level to 1
* (right-to-left).
*/
#define NSBIDI_DEFAULT_RTL 0xff
/**
* Maximum explicit embedding level.
* (The maximum resolved level can be up to
* <code>NSBIDI_MAX_EXPLICIT_LEVEL+1</code>).
*/
#define NSBIDI_MAX_EXPLICIT_LEVEL 125
/** Bit flag for level input.
* Overrides directional properties.
*/
#define NSBIDI_LEVEL_OVERRIDE 0x80
/**
* <code>nsBidiDirection</code> values indicate the text direction.
*/
enum nsBidiDirection {
/** All left-to-right text This is a 0 value. */
NSBIDI_LTR,
/** All right-to-left text This is a 1 value. */
NSBIDI_RTL,
/** Mixed-directional text. */
NSBIDI_MIXED
};
namespace mozilla {
// https://drafts.csswg.org/css-align-3/#baseline-sharing-group
@ -473,15 +404,16 @@ struct IntrinsicSize {
};
// Pseudo bidi embedding level indicating nonexistence.
static const nsBidiLevel kBidiLevelNone = 0xff;
static const mozilla::intl::Bidi::EmbeddingLevel kBidiLevelNone =
mozilla::intl::Bidi::EmbeddingLevel(0xff);
struct FrameBidiData {
nsBidiLevel baseLevel;
nsBidiLevel embeddingLevel;
mozilla::intl::Bidi::EmbeddingLevel baseLevel;
mozilla::intl::Bidi::EmbeddingLevel embeddingLevel;
// The embedding level of virtual bidi formatting character before
// this frame if any. kBidiLevelNone is used to indicate nonexistence
// or unnecessity of such virtual character.
nsBidiLevel precedingControl;
mozilla::intl::Bidi::EmbeddingLevel precedingControl;
};
} // namespace mozilla
@ -1398,9 +1330,13 @@ class nsIFrame : public nsQueryFrame {
return bidiData;
}
nsBidiLevel GetBaseLevel() const { return GetBidiData().baseLevel; }
mozilla::intl::Bidi::EmbeddingLevel GetBaseLevel() const {
return GetBidiData().baseLevel;
}
nsBidiLevel GetEmbeddingLevel() const { return GetBidiData().embeddingLevel; }
mozilla::intl::Bidi::EmbeddingLevel GetEmbeddingLevel() const {
return GetBidiData().embeddingLevel;
}
/**
* Return the distance between the border edge of the frame and the

View file

@ -12,6 +12,7 @@
#include "gfx2DGlue.h"
#include "gfxContext.h"
#include "gfxUtils.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Encoding.h"
@ -1434,31 +1435,31 @@ void nsImageFrame::DisplayAltText(nsPresContext* aPresContext,
nsresult rv = NS_ERROR_FAILURE;
if (aPresContext->BidiEnabled()) {
nsBidiDirection dir;
mozilla::intl::Bidi::EmbeddingLevel level;
nscoord x, y;
if (isVertical) {
x = pt.x + maxDescent;
if (wm.IsBidiLTR()) {
y = aRect.y;
dir = NSBIDI_LTR;
level = mozilla::intl::Bidi::EmbeddingLevel::LTR();
} else {
y = aRect.YMost() - strWidth;
dir = NSBIDI_RTL;
level = mozilla::intl::Bidi::EmbeddingLevel::RTL();
}
} else {
y = pt.y + maxAscent;
if (wm.IsBidiLTR()) {
x = aRect.x;
dir = NSBIDI_LTR;
level = mozilla::intl::Bidi::EmbeddingLevel::LTR();
} else {
x = aRect.XMost() - strWidth;
dir = NSBIDI_RTL;
level = mozilla::intl::Bidi::EmbeddingLevel::RTL();
}
}
rv = nsBidiPresUtils::RenderText(
str, maxFit, dir, aPresContext, aRenderingContext,
str, maxFit, level, aPresContext, aRenderingContext,
aRenderingContext.GetDrawTarget(), *fm, x, y);
}
if (NS_FAILED(rv)) {

View file

@ -69,6 +69,7 @@
#include "nsContentUtils.h"
#include "nsLineBreaker.h"
#include "nsIFrameInlines.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/intl/WordBreaker.h"
#include "mozilla/ServoStyleSet.h"
@ -1935,7 +1936,7 @@ bool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1,
Side side2 = wm.PhysicalSide(eLogicalSideIStart);
// If the frames have an embedding level that is opposite to the writing
// mode, we need to swap which sides we're checking.
if (IS_LEVEL_RTL(aFrame1->GetEmbeddingLevel()) == wm.IsBidiLTR()) {
if (aFrame1->GetEmbeddingLevel().IsRTL() == wm.IsBidiLTR()) {
std::swap(side1, side2);
}
@ -2396,7 +2397,7 @@ already_AddRefed<gfxTextRun> BuildTextRunsScanner::BuildTextRunForFrames(
if (flags2 & nsTextFrameUtils::Flags::HasShy) {
flags |= gfx::ShapedTextFlags::TEXT_ENABLE_HYPHEN_BREAKS;
}
if (mBidiEnabled && (IS_LEVEL_RTL(firstFrame->GetEmbeddingLevel()))) {
if (mBidiEnabled && (firstFrame->GetEmbeddingLevel().IsRTL())) {
flags |= gfx::ShapedTextFlags::TEXT_IS_RTL;
}
if (mNextRunContextInfo & nsTextFrameUtils::INCOMING_WHITESPACE) {

View file

@ -8,6 +8,7 @@
#include "gfx2DGlue.h"
#include "gfxUtils.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/Attributes.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/Preferences.h"
@ -484,7 +485,8 @@ void nsTextBoxFrame::DrawText(gfxContext& aRenderingContext,
if (mState & NS_FRAME_IS_BIDI) {
presContext->SetBidiEnabled();
nsBidiLevel level = nsBidiPresUtils::BidiLevelFromStyle(Style());
mozilla::intl::Bidi::EmbeddingLevel level =
nsBidiPresUtils::BidiLevelFromStyle(Style());
if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
// We let the RenderText function calculate the mnemonic's
// underline position for us.