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

View file

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

View file

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

View file

@ -10,22 +10,23 @@
#include <stdio.h> // for nullptr, stdout #include <stdio.h> // for nullptr, stdout
#include <string.h> // for strcmp #include <string.h> // for strcmp
#include "ChangeAttributeTransaction.h" // for ChangeAttributeTransaction #include "ChangeAttributeTransaction.h" // for ChangeAttributeTransaction
#include "CompositionTransaction.h" // for CompositionTransaction #include "CompositionTransaction.h" // for CompositionTransaction
#include "CreateElementTransaction.h" // for CreateElementTransaction #include "CreateElementTransaction.h" // for CreateElementTransaction
#include "DeleteNodeTransaction.h" // for DeleteNodeTransaction #include "DeleteNodeTransaction.h" // for DeleteNodeTransaction
#include "DeleteRangeTransaction.h" // for DeleteRangeTransaction #include "DeleteRangeTransaction.h" // for DeleteRangeTransaction
#include "DeleteTextTransaction.h" // for DeleteTextTransaction #include "DeleteTextTransaction.h" // for DeleteTextTransaction
#include "EditAggregateTransaction.h" // for EditAggregateTransaction #include "EditAggregateTransaction.h" // for EditAggregateTransaction
#include "EditTransactionBase.h" // for EditTransactionBase #include "EditTransactionBase.h" // for EditTransactionBase
#include "EditorEventListener.h" // for EditorEventListener #include "EditorEventListener.h" // for EditorEventListener
#include "gfxFontUtils.h" // for gfxFontUtils #include "gfxFontUtils.h" // for gfxFontUtils
#include "HTMLEditUtils.h" // for HTMLEditUtils #include "HTMLEditUtils.h" // for HTMLEditUtils
#include "InsertNodeTransaction.h" // for InsertNodeTransaction #include "InsertNodeTransaction.h" // for InsertNodeTransaction
#include "InsertTextTransaction.h" // for InsertTextTransaction #include "InsertTextTransaction.h" // for InsertTextTransaction
#include "JoinNodeTransaction.h" // for JoinNodeTransaction #include "JoinNodeTransaction.h" // for JoinNodeTransaction
#include "PlaceholderTransaction.h" // for PlaceholderTransaction #include "PlaceholderTransaction.h" // for PlaceholderTransaction
#include "SplitNodeTransaction.h" // for SplitNodeTransaction #include "SplitNodeTransaction.h" // for SplitNodeTransaction
#include "mozilla/intl/Bidi.h"
#include "mozilla/BasePrincipal.h" // for BasePrincipal #include "mozilla/BasePrincipal.h" // for BasePrincipal
#include "mozilla/CheckedInt.h" // for CheckedInt #include "mozilla/CheckedInt.h" // for CheckedInt
#include "mozilla/ComposerCommandsUpdater.h" // for ComposerCommandsUpdater #include "mozilla/ComposerCommandsUpdater.h" // for ComposerCommandsUpdater
@ -5765,12 +5766,13 @@ EditorBase::AutoCaretBidiLevelManager::AutoCaretBidiLevelManager(
nsPrevNextBidiLevels levels = frameSelection->GetPrevNextBidiLevels( nsPrevNextBidiLevels levels = frameSelection->GetPrevNextBidiLevels(
aPointAtCaret.GetContainerAsContent(), aPointAtCaret.Offset(), true); aPointAtCaret.GetContainerAsContent(), aPointAtCaret.Offset(), true);
nsBidiLevel levelBefore = levels.mLevelBefore; mozilla::intl::Bidi::EmbeddingLevel levelBefore = levels.mLevelBefore;
nsBidiLevel levelAfter = levels.mLevelAfter; 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 || levelOfDeletion = (nsIEditor::eNext == aDirectionAndAmount ||
nsIEditor::eNextWord == aDirectionAndAmount) nsIEditor::eNextWord == aDirectionAndAmount)
? levelAfter ? levelAfter

View file

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

View file

@ -51,25 +51,6 @@ enum nsCharType {
*/ */
typedef enum nsCharType 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 * definitions of bidirection character types by category
*/ */

View file

@ -6,6 +6,8 @@
#include "nsBidiPresUtils.h" #include "nsBidiPresUtils.h"
#include "mozilla/intl/Bidi.h"
#include "mozilla/Casting.h"
#include "mozilla/IntegerRange.h" #include "mozilla/IntegerRange.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/PresShell.h" #include "mozilla/PresShell.h"
@ -39,6 +41,7 @@
#undef REALLY_NOISY_BIDI #undef REALLY_NOISY_BIDI
using namespace mozilla; using namespace mozilla;
using EmbeddingLevel = mozilla::intl::Bidi::EmbeddingLevel;
static const char16_t kSpace = 0x0020; static const char16_t kSpace = 0x0020;
static const char16_t kZWSP = 0x200B; static const char16_t kZWSP = 0x200B;
@ -163,7 +166,7 @@ struct MOZ_STACK_CLASS BidiParagraphData {
nsPresContext* mPresContext; nsPresContext* mPresContext;
bool mIsVisual; bool mIsVisual;
bool mRequiresBidi; bool mRequiresBidi;
nsBidiLevel mParaLevel; EmbeddingLevel mParaLevel;
nsIContent* mPrevContent; nsIContent* mPrevContent;
/** /**
@ -335,37 +338,49 @@ struct MOZ_STACK_CLASS BidiParagraphData {
} }
nsresult SetPara() { nsresult SetPara() {
return mPresContext->GetBidiEngine().SetPara(mBuffer.get(), BufferLength(), if (mPresContext->GetBidiEngine()
mParaLevel); .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. * mParaLevel can be intl::Bidi::Direction::LTR as well as
* GetParaLevel() returns the actual (resolved) paragraph level which is * intl::Bidi::Direction::LTR or intl::Bidi::Direction::RTL.
* always either NSBIDI_LTR or NSBIDI_RTL * GetParagraphEmbeddingLevel() returns the actual (resolved) paragraph level
* which is always either intl::Bidi::Direction::LTR or
* intl::Bidi::Direction::RTL
*/ */
nsBidiLevel GetParaLevel() { EmbeddingLevel GetParagraphEmbeddingLevel() {
nsBidiLevel paraLevel = mParaLevel; EmbeddingLevel paraLevel = mParaLevel;
if (paraLevel == NSBIDI_DEFAULT_LTR || paraLevel == NSBIDI_DEFAULT_RTL) { if (paraLevel == EmbeddingLevel::DefaultLTR() ||
paraLevel = mPresContext->GetBidiEngine().GetParaLevel(); paraLevel == EmbeddingLevel::DefaultRTL()) {
paraLevel = mPresContext->GetBidiEngine().GetParagraphEmbeddingLevel();
} }
return paraLevel; return paraLevel;
} }
nsBidiDirection GetDirection() { intl::Bidi::ParagraphDirection GetParagraphDirection() {
return mPresContext->GetBidiEngine().GetDirection(); return mPresContext->GetBidiEngine().GetParagraphDirection();
} }
nsresult CountRuns(int32_t* runCount) { 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, void GetLogicalRun(int32_t aLogicalStart, int32_t* aLogicalLimit,
nsBidiLevel* aLevel) { EmbeddingLevel* aLevel) {
mPresContext->GetBidiEngine().GetLogicalRun(aLogicalStart, aLogicalLimit, mPresContext->GetBidiEngine().GetLogicalRun(aLogicalStart, aLogicalLimit,
aLevel); aLevel);
if (mIsVisual) { if (mIsVisual) {
*aLevel = GetParaLevel(); *aLevel = GetParagraphEmbeddingLevel();
} }
} }
@ -465,7 +480,7 @@ struct MOZ_STACK_CLASS BidiLineData {
AutoTArray<nsIFrame*, 16> mLogicalFrames; AutoTArray<nsIFrame*, 16> mLogicalFrames;
AutoTArray<nsIFrame*, 16> mVisualFrames; AutoTArray<nsIFrame*, 16> mVisualFrames;
AutoTArray<int32_t, 16> mIndexMap; AutoTArray<int32_t, 16> mIndexMap;
AutoTArray<uint8_t, 16> mLevels; AutoTArray<EmbeddingLevel, 16> mLevels;
bool mIsReordered; bool mIsReordered;
BidiLineData(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine) { BidiLineData(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine) {
@ -477,11 +492,11 @@ struct MOZ_STACK_CLASS BidiLineData {
bool hasRTLFrames = false; bool hasRTLFrames = false;
bool hasVirtualControls = false; bool hasVirtualControls = false;
auto appendFrame = [&](nsIFrame* frame, nsBidiLevel level) { auto appendFrame = [&](nsIFrame* frame, EmbeddingLevel level) {
mLogicalFrames.AppendElement(frame); mLogicalFrames.AppendElement(frame);
mLevels.AppendElement(level); mLevels.AppendElement(level);
mIndexMap.AppendElement(0); mIndexMap.AppendElement(0);
if (IS_LEVEL_RTL(level)) { if (level.IsRTL()) {
hasRTLFrames = true; hasRTLFrames = true;
} }
}; };
@ -502,8 +517,8 @@ struct MOZ_STACK_CLASS BidiLineData {
} }
// Reorder the line // Reorder the line
nsBidi::ReorderVisual(mLevels.Elements(), FrameCount(), mozilla::intl::Bidi::ReorderVisual(mLevels.Elements(), FrameCount(),
mIndexMap.Elements()); mIndexMap.Elements());
// Strip virtual frames // Strip virtual frames
if (hasVirtualControls) { if (hasVirtualControls) {
@ -865,7 +880,8 @@ nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) {
nsresult rv = aBpd->SetPara(); nsresult rv = aBpd->SetPara();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsBidiLevel embeddingLevel = aBpd->GetParaLevel(); intl::Bidi::EmbeddingLevel embeddingLevel =
aBpd->GetParagraphEmbeddingLevel();
rv = aBpd->CountRuns(&runCount); rv = aBpd->CountRuns(&runCount);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -897,8 +913,9 @@ nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) {
# endif # endif
#endif #endif
if (runCount == 1 && frameCount == 1 && aBpd->GetDirection() == NSBIDI_LTR && if (runCount == 1 && frameCount == 1 &&
aBpd->GetParaLevel() == 0) { aBpd->GetParagraphDirection() == intl::Bidi::ParagraphDirection::LTR &&
aBpd->GetParagraphEmbeddingLevel() == 0) {
// We have a single left-to-right frame in a left-to-right paragraph, // We have a single left-to-right frame in a left-to-right paragraph,
// without bidi isolation from the surrounding text. // without bidi isolation from the surrounding text.
// Make sure that the embedding level and base level frame properties aren't // 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; BidiParagraphData::FrameInfo lastRealFrame;
nsBidiLevel lastEmbeddingLevel = kBidiLevelNone; EmbeddingLevel lastEmbeddingLevel = kBidiLevelNone;
nsBidiLevel precedingControl = kBidiLevelNone; EmbeddingLevel precedingControl = kBidiLevelNone;
auto storeBidiDataToFrame = [&]() { auto storeBidiDataToFrame = [&]() {
FrameBidiData bidiData; FrameBidiData bidiData;
bidiData.embeddingLevel = embeddingLevel; bidiData.embeddingLevel = embeddingLevel;
bidiData.baseLevel = aBpd->GetParaLevel(); bidiData.baseLevel = aBpd->GetParagraphEmbeddingLevel();
// If a control character doesn't have a lower embedding level than // If a control character doesn't have a lower embedding level than
// both the preceding and the following frame, it isn't something // both the preceding and the following frame, it isn't something
// needed for getting the correct result. This optimization should // needed for getting the correct result. This optimization should
@ -1506,11 +1523,11 @@ FrameBidiData nsBidiPresUtils::GetFrameBidiData(nsIFrame* aFrame) {
return GetFirstLeaf(aFrame)->GetBidiData(); return GetFirstLeaf(aFrame)->GetBidiData();
} }
nsBidiLevel nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame) { EmbeddingLevel nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame) {
return GetFirstLeaf(aFrame)->GetEmbeddingLevel(); return GetFirstLeaf(aFrame)->GetEmbeddingLevel();
} }
nsBidiLevel nsBidiPresUtils::GetFrameBaseLevel(const nsIFrame* aFrame) { EmbeddingLevel nsBidiPresUtils::GetFrameBaseLevel(const nsIFrame* aFrame) {
const nsIFrame* firstLeaf = aFrame; const nsIFrame* firstLeaf = aFrame;
while (!IsBidiLeaf(firstLeaf)) { while (!IsBidiLeaf(firstLeaf)) {
firstLeaf = firstLeaf->PrincipalChildList().FirstChild(); firstLeaf = firstLeaf->PrincipalChildList().FirstChild();
@ -1871,7 +1888,7 @@ nscoord nsBidiPresUtils::RepositionInlineFrames(BidiLineData* aBld,
for (; index != limit; index += step) { for (; index != limit; index += step) {
frame = aBld->VisualFrameAt(index); frame = aBld->VisualFrameAt(index);
start += RepositionFrame( start += RepositionFrame(
frame, !(IS_LEVEL_RTL(aBld->mLevels[aBld->mIndexMap[index]])), start, frame, !(aBld->mLevels[aBld->mIndexMap[index]].IsRTL()), start,
&continuationStates, aLineWM, false, aContainerSize); &continuationStates, aLineWM, false, aContainerSize);
} }
return start; return start;
@ -2079,7 +2096,7 @@ RemoveDiacritics(char16_t* aText,
} }
#endif #endif
void nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine, void nsBidiPresUtils::CalculateCharType(intl::Bidi* aBidiEngine,
const char16_t* aText, int32_t& aOffset, const char16_t* aText, int32_t& aOffset,
int32_t aCharTypeLimit, int32_t aCharTypeLimit,
int32_t& aRunLimit, int32_t& aRunLength, int32_t& aRunLimit, int32_t& aRunLength,
@ -2143,27 +2160,29 @@ void nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine,
aOffset = offset; aOffset = offset;
} }
nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength, nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
nsBidiLevel aBaseLevel, EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, nsPresContext* aPresContext,
BidiProcessor& aprocessor, Mode aMode, BidiProcessor& aprocessor, Mode aMode,
nsBidiPositionResolve* aPosResolve, nsBidiPositionResolve* aPosResolve,
int32_t aPosResolveCount, nscoord* aWidth, int32_t aPosResolveCount, nscoord* aWidth,
nsBidi* aBidiEngine) { mozilla::intl::Bidi* aBidiEngine) {
NS_ASSERTION((aPosResolve == nullptr) != (aPosResolveCount > 0), NS_ASSERTION((aPosResolve == nullptr) != (aPosResolveCount > 0),
"Incorrect aPosResolve / aPosResolveCount arguments"); "Incorrect aPosResolve / aPosResolveCount arguments");
int32_t runCount;
nsAutoString textBuffer(aText, aLength); nsAutoString textBuffer(aText, aLength);
textBuffer.ReplaceChar(kSeparators, kSpace); textBuffer.ReplaceChar(kSeparators, kSpace);
const char16_t* text = textBuffer.get(); const char16_t* text = textBuffer.get();
nsresult rv = aBidiEngine->SetPara(text, aLength, aBaseLevel); if (aBidiEngine->SetParagraph(Span(text, aLength), aBaseLevel).isErr()) {
if (NS_FAILED(rv)) return rv; return NS_ERROR_FAILURE;
}
rv = aBidiEngine->CountRuns(&runCount); auto result = aBidiEngine->CountRuns();
if (NS_FAILED(rv)) return rv; if (result.isErr()) {
return NS_ERROR_FAILURE;
}
int32_t runCount = result.unwrap();
nscoord xOffset = 0; nscoord xOffset = 0;
nscoord width, xEndRun = 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++) { 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); aBidiEngine->GetLogicalRun(start, &limit, &level);
dir = DIRECTION_FROM_LEVEL(level); dir = level.Direction();
int32_t subRunLength = limit - start; int32_t subRunLength = limit - start;
int32_t lineOffset = 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 subRunCount = 1;
int32_t subRunLimit = typeLimit; 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. * x-coordinate of the end of the run for the start of the next run.
*/ */
if (dir == NSBIDI_RTL) { if (dir == intl::Bidi::Direction::RTL) {
aprocessor.SetText(text + start, subRunLength, dir); aprocessor.SetText(text + start, subRunLength,
intl::Bidi::Direction::RTL);
width = aprocessor.GetWidth(); width = aprocessor.GetWidth();
xOffset += width; xOffset += width;
xEndRun = xOffset; xEndRun = xOffset;
@ -2227,7 +2248,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
aprocessor.SetText(runVisualText.get(), subRunLength, dir); aprocessor.SetText(runVisualText.get(), subRunLength, dir);
width = aprocessor.GetWidth(); width = aprocessor.GetWidth();
totalWidth += width; totalWidth += width;
if (dir == NSBIDI_RTL) { if (dir == mozilla::intl::Bidi::Direction::RTL) {
xOffset -= width; xOffset -= width;
} }
if (aMode == MODE_DRAW) { 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. // The position in the text where this run's "left part" begins.
const char16_t* visualLeftPart; const char16_t* visualLeftPart;
const char16_t* visualRightSide; const char16_t* visualRightSide;
if (dir == NSBIDI_RTL) { if (dir == mozilla::intl::Bidi::Direction::RTL) {
// One day, son, this could all be replaced with // One day, son, this could all be replaced with
// mPresContext->GetBidiEngine().GetVisualIndex() ... // mPresContext->GetBidiEngine().GetVisualIndex() ...
posResolve->visualIndex = 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; xOffset += width;
} }
@ -2335,7 +2356,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, int32_t aLength,
subRunLimit = typeLimit; subRunLimit = typeLimit;
subRunLength = typeLimit - lineOffset; subRunLength = typeLimit - lineOffset;
} // while } // while
if (dir == NSBIDI_RTL) { if (dir == intl::Bidi::Direction::RTL) {
xOffset = xEndRun; xOffset = xEndRun;
} }
@ -2367,8 +2388,8 @@ class MOZ_STACK_CLASS nsIRenderingContextBidiProcessor final
~nsIRenderingContextBidiProcessor() { mFontMetrics->SetTextRunRTL(false); } ~nsIRenderingContextBidiProcessor() { mFontMetrics->SetTextRunRTL(false); }
virtual void SetText(const char16_t* aText, int32_t aLength, virtual void SetText(const char16_t* aText, int32_t aLength,
nsBidiDirection aDirection) override { intl::Bidi::Direction aDirection) override {
mFontMetrics->SetTextRunRTL(aDirection == NSBIDI_RTL); mFontMetrics->SetTextRunRTL(aDirection == intl::Bidi::Direction::RTL);
mText = aText; mText = aText;
mLength = aLength; mLength = aLength;
} }
@ -2399,7 +2420,7 @@ class MOZ_STACK_CLASS nsIRenderingContextBidiProcessor final
}; };
nsresult nsBidiPresUtils::ProcessTextForRenderingContext( 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, nsPresContext* aPresContext, gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics, DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics,
Mode aMode, nscoord aX, nscoord aY, nsBidiPositionResolve* aPosResolve, Mode aMode, nscoord aX, nscoord aY, nsBidiPositionResolve* aPosResolve,
@ -2413,15 +2434,16 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(
} }
/* static */ /* static */
nsBidiLevel nsBidiPresUtils::BidiLevelFromStyle(ComputedStyle* aComputedStyle) { EmbeddingLevel nsBidiPresUtils::BidiLevelFromStyle(
ComputedStyle* aComputedStyle) {
if (aComputedStyle->StyleTextReset()->mUnicodeBidi & if (aComputedStyle->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) { NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
return NSBIDI_DEFAULT_LTR; return EmbeddingLevel::DefaultLTR();
} }
if (aComputedStyle->StyleVisibility()->mDirection == StyleDirection::Rtl) { 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___ #define nsBidiPresUtils_h___
#include "gfxContext.h" #include "gfxContext.h"
#include "nsBidi.h" #include "mozilla/intl/Bidi.h"
#include "nsBidiUtils.h" #include "nsBidiUtils.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsCoord.h" #include "nsCoord.h"
@ -164,7 +164,7 @@ class nsBidiPresUtils {
* mixed direction. * mixed direction.
*/ */
virtual void SetText(const char16_t* aText, int32_t aLength, 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 * 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[in] aText the string to be rendered (in logical order)
* @param aLength the number of characters in the string * @param aLength the number of characters in the string
* @param aBaseLevel the base embedding level 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 aPresContext the presentation context
* @param aRenderingContext the rendering context to render to * @param aRenderingContext the rendering context to render to
* @param aTextRunConstructionContext the rendering context to be used to * @param aTextRunConstructionContext the rendering context to be used to
@ -248,23 +239,26 @@ class nsBidiPresUtils {
* visual positions; can be nullptr if this functionality is not required * visual positions; can be nullptr if this functionality is not required
* @param aPosResolveCount number of items in the aPosResolve array * @param aPosResolveCount number of items in the aPosResolve array
*/ */
static nsresult RenderText( static nsresult RenderText(const char16_t* aText, int32_t aLength,
const char16_t* aText, int32_t aLength, nsBidiLevel aBaseLevel, mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, gfxContext& aRenderingContext, nsPresContext* aPresContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics, gfxContext& aRenderingContext,
nscoord aX, nscoord aY, nsBidiPositionResolve* aPosResolve = nullptr, DrawTarget* aTextRunConstructionDrawTarget,
int32_t aPosResolveCount = 0) { nsFontMetrics& aFontMetrics, nscoord aX,
nscoord aY,
nsBidiPositionResolve* aPosResolve = nullptr,
int32_t aPosResolveCount = 0) {
return ProcessTextForRenderingContext( return ProcessTextForRenderingContext(
aText, aLength, aBaseLevel, aPresContext, aRenderingContext, aText, aLength, aBaseLevel, aPresContext, aRenderingContext,
aTextRunConstructionDrawTarget, aFontMetrics, MODE_DRAW, aX, aY, aTextRunConstructionDrawTarget, aFontMetrics, MODE_DRAW, aX, aY,
aPosResolve, aPosResolveCount, nullptr); aPosResolve, aPosResolveCount, nullptr);
} }
static nscoord MeasureTextWidth(const char16_t* aText, int32_t aLength, static nscoord MeasureTextWidth(
nsBidiLevel aBaseLevel, const char16_t* aText, int32_t aLength,
nsPresContext* aPresContext, mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
gfxContext& aRenderingContext, nsPresContext* aPresContext, gfxContext& aRenderingContext,
nsFontMetrics& aFontMetrics) { nsFontMetrics& aFontMetrics) {
nscoord length; nscoord length;
nsresult rv = ProcessTextForRenderingContext( nsresult rv = ProcessTextForRenderingContext(
aText, aLength, aBaseLevel, aPresContext, aRenderingContext, aText, aLength, aBaseLevel, aPresContext, aRenderingContext,
@ -317,31 +311,32 @@ class nsBidiPresUtils {
/** /**
* Get the bidi embedding level of the given (inline) frame. * 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. * 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 * Get a mozilla::intl::Bidi::Direction representing the direction implied by
* bidi base level of the frame. * the bidi base level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left) * @return mozilla::intl::Bidi::Direction
* NSBIDI_MIXED will never be returned.
*/ */
static nsBidiDirection ParagraphDirection(const nsIFrame* aFrame) { static mozilla::intl::Bidi::Direction ParagraphDirection(
return DIRECTION_FROM_LEVEL(GetFrameBaseLevel(aFrame)); const nsIFrame* aFrame) {
return GetFrameBaseLevel(aFrame).Direction();
} }
/** /**
* Get an nsBidiDirection representing the direction implied by the * Get a mozilla::intl::Bidi::Direction representing the direction implied by
* bidi embedding level of the frame. * the bidi embedding level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left) * @return mozilla::intl::Bidi::Direction
* NSBIDI_MIXED will never be returned.
*/ */
static nsBidiDirection FrameDirection(nsIFrame* aFrame) { static mozilla::intl::Bidi::Direction FrameDirection(nsIFrame* aFrame) {
return DIRECTION_FROM_LEVEL(GetFrameEmbeddingLevel(aFrame)); return GetFrameEmbeddingLevel(aFrame).Direction();
} }
static bool IsFrameInParagraphDirection(nsIFrame* aFrame) { static bool IsFrameInParagraphDirection(nsIFrame* aFrame) {
@ -353,7 +348,7 @@ class nsBidiPresUtils {
// the leaf frame. // the leaf frame.
static bool IsReversedDirectionFrame(const nsIFrame* aFrame) { static bool IsReversedDirectionFrame(const nsIFrame* aFrame) {
mozilla::FrameBidiData bidiData = aFrame->GetBidiData(); 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 }; enum Mode { MODE_DRAW, MODE_MEASURE };
@ -365,15 +360,6 @@ class nsBidiPresUtils {
* @param[in] aText the string to be processed (in logical order) * @param[in] aText the string to be processed (in logical order)
* @param aLength the number of characters in the string * @param aLength the number of characters in the string
* @param aBaseLevel the base embedding level 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 aPresContext the presentation context
* @param aprocessor the bidi processor * @param aprocessor the bidi processor
* @param aMode the operation to process * @param aMode the operation to process
@ -385,31 +371,33 @@ class nsBidiPresUtils {
* @param aPosResolveCount number of items in the aPosResolve array * @param aPosResolveCount number of items in the aPosResolve array
* @param[out] aWidth Pointer to where the width will be stored (may be null) * @param[out] aWidth Pointer to where the width will be stored (may be null)
*/ */
static nsresult ProcessText(const char16_t* aText, int32_t aLength, static nsresult ProcessText(const char16_t* aText, size_t aLength,
nsBidiLevel aBaseLevel, mozilla::intl::Bidi::EmbeddingLevel aBaseLevel,
nsPresContext* aPresContext, nsPresContext* aPresContext,
BidiProcessor& aprocessor, Mode aMode, BidiProcessor& aprocessor, Mode aMode,
nsBidiPositionResolve* aPosResolve, nsBidiPositionResolve* aPosResolve,
int32_t aPosResolveCount, nscoord* aWidth, int32_t aPosResolveCount, nscoord* aWidth,
nsBidi* aBidiEngine); mozilla::intl::Bidi* aBidiEngine);
/** /**
* Use style attributes to determine the base paragraph level to pass to the * Use style attributes to determine the base paragraph level to pass to the
* bidi algorithm. * bidi algorithm.
* *
* If |unicode-bidi| is set to "[-moz-]plaintext", returns NSBIDI_DEFAULT_LTR, * If |unicode-bidi| is set to "[-moz-]plaintext", returns
* in other words the direction is determined from the first strong character * EmbeddingLevel::DefaultLTR, in other words the direction is determined from
* in the text according to rules P2 and P3 of the bidi algorithm, or LTR if * the first strong character in the text according to rules P2 and P3 of the
* there is no strong character. * bidi algorithm, or LTR if there is no strong character.
* *
* Otherwise returns NSBIDI_LTR or NSBIDI_RTL depending on the value of * Otherwise returns EmbeddingLevel::LTR or EmbeddingLevel::RTL depending on
* |direction| * the value of |direction|
*/ */
static nsBidiLevel BidiLevelFromStyle(mozilla::ComputedStyle* aComputedStyle); static mozilla::intl::Bidi::EmbeddingLevel BidiLevelFromStyle(
mozilla::ComputedStyle* aComputedStyle);
private: private:
static nsresult ProcessTextForRenderingContext( 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, nsPresContext* aPresContext, gfxContext& aRenderingContext,
DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics, DrawTarget* aTextRunConstructionDrawTarget, nsFontMetrics& aFontMetrics,
Mode aMode, Mode aMode,
@ -572,11 +560,11 @@ class nsBidiPresUtils {
*/ */
static void RemoveBidiContinuation(BidiParagraphData* aBpd, nsIFrame* aFrame, static void RemoveBidiContinuation(BidiParagraphData* aBpd, nsIFrame* aFrame,
int32_t aFirstIndex, int32_t aLastIndex); int32_t aFirstIndex, int32_t aLastIndex);
static void CalculateCharType(nsBidi* aBidiEngine, const char16_t* aText, static void CalculateCharType(mozilla::intl::Bidi* aBidiEngine,
int32_t& aOffset, int32_t aCharTypeLimit, const char16_t* aText, int32_t& aOffset,
int32_t& aRunLimit, int32_t& aRunLength, int32_t aCharTypeLimit, int32_t& aRunLimit,
int32_t& aRunCount, uint8_t& aCharType, int32_t& aRunLength, int32_t& aRunCount,
uint8_t& aPrevCharType); uint8_t& aCharType, uint8_t& aPrevCharType);
static void StripBidiControlCharacters(char16_t* aText, int32_t& aTextLength); static void StripBidiControlCharacters(char16_t* aText, int32_t& aTextLength);
}; };

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -78,6 +78,7 @@
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/gfx/CompositorHitTestInfo.h" #include "mozilla/gfx/CompositorHitTestInfo.h"
#include "mozilla/gfx/MatrixFwd.h" #include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/intl/Bidi.h"
#include "nsDisplayItemTypes.h" #include "nsDisplayItemTypes.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsTHashSet.h" #include "nsTHashSet.h"
@ -359,76 +360,6 @@ class nsReflowStatus final {
// Convert nsReflowStatus to a human-readable string. // Convert nsReflowStatus to a human-readable string.
std::ostream& operator<<(std::ostream& aStream, const nsReflowStatus& aStatus); 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 { namespace mozilla {
// https://drafts.csswg.org/css-align-3/#baseline-sharing-group // https://drafts.csswg.org/css-align-3/#baseline-sharing-group
@ -473,15 +404,16 @@ struct IntrinsicSize {
}; };
// Pseudo bidi embedding level indicating nonexistence. // 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 { struct FrameBidiData {
nsBidiLevel baseLevel; mozilla::intl::Bidi::EmbeddingLevel baseLevel;
nsBidiLevel embeddingLevel; mozilla::intl::Bidi::EmbeddingLevel embeddingLevel;
// The embedding level of virtual bidi formatting character before // The embedding level of virtual bidi formatting character before
// this frame if any. kBidiLevelNone is used to indicate nonexistence // this frame if any. kBidiLevelNone is used to indicate nonexistence
// or unnecessity of such virtual character. // or unnecessity of such virtual character.
nsBidiLevel precedingControl; mozilla::intl::Bidi::EmbeddingLevel precedingControl;
}; };
} // namespace mozilla } // namespace mozilla
@ -1398,9 +1330,13 @@ class nsIFrame : public nsQueryFrame {
return bidiData; 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 * Return the distance between the border edge of the frame and the

View file

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

View file

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

View file

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