mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1728999 - Implement the CanvasRenderingContext2D.direction property. r=lsalzman,emilio
Differential Revision: https://phabricator.services.mozilla.com/D142701
This commit is contained in:
parent
8169edb3db
commit
b50d715cc5
@ -1006,6 +1006,7 @@ CanvasRenderingContext2D::ContextState::ContextState(const ContextState& aOther)
|
||||
font(aOther.font),
|
||||
textAlign(aOther.textAlign),
|
||||
textBaseline(aOther.textBaseline),
|
||||
textDirection(aOther.textDirection),
|
||||
shadowColor(aOther.shadowColor),
|
||||
transform(aOther.transform),
|
||||
shadowOffset(aOther.shadowOffset),
|
||||
@ -3534,6 +3535,30 @@ void CanvasRenderingContext2D::GetTextBaseline(nsAString& aTextBaseline) {
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::SetDirection(const nsAString& aDirection) {
|
||||
if (aDirection.EqualsLiteral("ltr")) {
|
||||
CurrentState().textDirection = TextDirection::LTR;
|
||||
} else if (aDirection.EqualsLiteral("rtl")) {
|
||||
CurrentState().textDirection = TextDirection::RTL;
|
||||
} else if (aDirection.EqualsLiteral("inherit")) {
|
||||
CurrentState().textDirection = TextDirection::INHERIT;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::GetDirection(nsAString& aDirection) {
|
||||
switch (CurrentState().textDirection) {
|
||||
case TextDirection::LTR:
|
||||
aDirection.AssignLiteral("ltr");
|
||||
break;
|
||||
case TextDirection::RTL:
|
||||
aDirection.AssignLiteral("rtl");
|
||||
break;
|
||||
case TextDirection::INHERIT:
|
||||
aDirection.AssignLiteral("inherit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function that replaces the whitespace characters in a string
|
||||
* with U+0020 SPACE. The whitespace characters are defined as U+0020 SPACE,
|
||||
@ -3689,11 +3714,11 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor
|
||||
using ContextState = CanvasRenderingContext2D::ContextState;
|
||||
|
||||
virtual void SetText(const char16_t* aText, int32_t aLength,
|
||||
mozilla::intl::BidiDirection aDirection) override {
|
||||
intl::BidiDirection aDirection) override {
|
||||
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
||||
// adjust flags for current direction run
|
||||
gfx::ShapedTextFlags flags = mTextRunFlags;
|
||||
if (aDirection == mozilla::intl::BidiDirection::RTL) {
|
||||
if (aDirection == intl::BidiDirection::RTL) {
|
||||
flags |= gfx::ShapedTextFlags::TEXT_IS_RTL;
|
||||
} else {
|
||||
flags &= ~gfx::ShapedTextFlags::TEXT_IS_RTL;
|
||||
@ -3962,9 +3987,6 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
|
||||
textToDraw.Truncate();
|
||||
}
|
||||
|
||||
// for now, default to ltr if not in doc
|
||||
bool isRTL = false;
|
||||
|
||||
RefPtr<ComputedStyle> canvasStyle;
|
||||
if (mCanvasElement && mCanvasElement->IsInComposedDoc()) {
|
||||
// try to find the closest context
|
||||
@ -3973,11 +3995,25 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
|
||||
aError = NS_ERROR_FAILURE;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
isRTL = canvasStyle->StyleVisibility()->mDirection == StyleDirection::Rtl;
|
||||
} else {
|
||||
isRTL = GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) ==
|
||||
IBMBIDI_TEXTDIRECTION_RTL;
|
||||
// Get text direction, either from the property or inherited from context.
|
||||
const ContextState& state = CurrentState();
|
||||
bool isRTL;
|
||||
switch (state.textDirection) {
|
||||
case TextDirection::LTR:
|
||||
isRTL = false;
|
||||
break;
|
||||
case TextDirection::RTL:
|
||||
isRTL = true;
|
||||
break;
|
||||
case TextDirection::INHERIT:
|
||||
isRTL = canvasStyle
|
||||
? canvasStyle->StyleVisibility()->mDirection ==
|
||||
StyleDirection::Rtl
|
||||
: GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) ==
|
||||
IBMBIDI_TEXTDIRECTION_RTL;
|
||||
break;
|
||||
}
|
||||
|
||||
// This is only needed to know if we can know the drawing bounding box easily.
|
||||
@ -4060,8 +4096,7 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
|
||||
// bounding boxes before rendering anything
|
||||
aError = nsBidiPresUtils::ProcessText(
|
||||
textToDraw.get(), textToDraw.Length(),
|
||||
isRTL ? mozilla::intl::BidiEmbeddingLevel::RTL()
|
||||
: mozilla::intl::BidiEmbeddingLevel::LTR(),
|
||||
isRTL ? intl::BidiEmbeddingLevel::RTL() : intl::BidiEmbeddingLevel::LTR(),
|
||||
presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_MEASURE,
|
||||
nullptr, 0, &totalWidthCoord, &mBidiEngine);
|
||||
if (aError.Failed()) {
|
||||
@ -4073,7 +4108,6 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
|
||||
// offset pt.x based on text align
|
||||
gfxFloat anchorX;
|
||||
|
||||
const ContextState& state = CurrentState();
|
||||
if (state.textAlign == TextAlign::CENTER) {
|
||||
anchorX = .5;
|
||||
} else if (state.textAlign == TextAlign::LEFT ||
|
||||
@ -4203,8 +4237,7 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText(
|
||||
|
||||
aError = nsBidiPresUtils::ProcessText(
|
||||
textToDraw.get(), textToDraw.Length(),
|
||||
isRTL ? mozilla::intl::BidiEmbeddingLevel::RTL()
|
||||
: mozilla::intl::BidiEmbeddingLevel::LTR(),
|
||||
isRTL ? intl::BidiEmbeddingLevel::RTL() : intl::BidiEmbeddingLevel::LTR(),
|
||||
presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_DRAW,
|
||||
nullptr, 0, nullptr, &mBidiEngine);
|
||||
|
||||
|
@ -304,6 +304,8 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
|
||||
void SetTextAlign(const nsAString& aTextAlign);
|
||||
void GetTextBaseline(nsAString& aTextBaseline);
|
||||
void SetTextBaseline(const nsAString& aTextBaseline);
|
||||
void GetDirection(nsAString& aDirection);
|
||||
void SetDirection(const nsAString& aDirection);
|
||||
|
||||
void ClosePath() override {
|
||||
EnsureWritablePath();
|
||||
@ -886,6 +888,8 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
|
||||
|
||||
enum class TextDrawOperation : uint8_t { FILL, STROKE, MEASURE };
|
||||
|
||||
enum class TextDirection : uint8_t { LTR, RTL, INHERIT };
|
||||
|
||||
protected:
|
||||
gfxFontGroup* GetCurrentFontStyle();
|
||||
|
||||
@ -953,6 +957,7 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
|
||||
nsCString font;
|
||||
TextAlign textAlign = TextAlign::START;
|
||||
TextBaseline textBaseline = TextBaseline::ALPHABETIC;
|
||||
TextDirection textDirection = TextDirection::INHERIT;
|
||||
|
||||
nscolor shadowColor = 0;
|
||||
|
||||
|
@ -302,6 +302,7 @@ interface mixin CanvasTextDrawingStyles {
|
||||
attribute UTF8String font; // (default 10px sans-serif)
|
||||
attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
|
||||
attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
|
||||
attribute DOMString direction; // "ltr", "rtl", "inherit" (default: "inherit")
|
||||
};
|
||||
|
||||
interface mixin CanvasPathMethods {
|
||||
|
Loading…
Reference in New Issue
Block a user