Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp |
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
index 4eea12475e641bce52e6482f6efa3b73d6060b7e..14b4d274e322c0117e53d536b2ce66da555eaab8 100644 |
--- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
@@ -83,6 +83,13 @@ static bool contextLostRestoredEventsEnabled() |
return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); |
} |
+static inline TextDirection inheritedDirection(HTMLCanvasElement& canvasElement) |
+{ |
+ canvasElement.document().updateRenderTreeIfNeeded(); |
+ RenderStyle* computedStyle = canvasElement.computedStyle(); |
+ return computedStyle ? computedStyle->direction() : LTR; |
+} |
+ |
CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode) |
: CanvasRenderingContext(canvas) |
, m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode) |
@@ -95,7 +102,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, co |
, m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispatchContextRestoredEvent) |
, m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreContextEvent) |
{ |
- m_stateStack.append(adoptPtrWillBeNoop(new State())); |
+ m_stateStack.append(adoptPtrWillBeNoop(new State(inheritedDirection(*canvas)))); |
ScriptWrappable::init(this); |
} |
@@ -230,7 +237,7 @@ void CanvasRenderingContext2D::reset() |
validateStateStack(); |
unwindStateStack(); |
m_stateStack.resize(1); |
- m_stateStack.first() = adoptPtrWillBeNoop(new State()); |
+ m_stateStack.first() = adoptPtrWillBeNoop(new State(inheritedDirection(*canvas()))); |
m_path.clear(); |
validateStateStack(); |
} |
@@ -239,7 +246,7 @@ void CanvasRenderingContext2D::reset() |
// StrokeData. The default values that StrokeData uses may not the same values |
// that the canvas 2d spec specifies. Make sure to sync the initial state of the |
// GraphicsContext in HTMLCanvasElement::createImageBuffer()! |
-CanvasRenderingContext2D::State::State() |
+CanvasRenderingContext2D::State::State(TextDirection direction) |
: m_unrealizedSaveCount(0) |
, m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) |
, m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) |
@@ -257,6 +264,7 @@ CanvasRenderingContext2D::State::State() |
, m_imageSmoothingEnabled(true) |
, m_textAlign(StartTextAlign) |
, m_textBaseline(AlphabeticTextBaseline) |
+ , m_direction(direction) |
, m_unparsedFont(defaultFont) |
, m_realizedFont(false) |
, m_hasClip(false) |
@@ -286,6 +294,7 @@ CanvasRenderingContext2D::State::State(const State& other) |
, m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) |
, m_textAlign(other.m_textAlign) |
, m_textBaseline(other.m_textBaseline) |
+ , m_direction(other.m_direction) |
, m_unparsedFont(other.m_unparsedFont) |
, m_font(other.m_font) |
, m_realizedFont(other.m_realizedFont) |
@@ -325,6 +334,7 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons |
m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; |
m_textAlign = other.m_textAlign; |
m_textBaseline = other.m_textBaseline; |
+ m_direction = other.m_direction; |
m_unparsedFont = other.m_unparsedFont; |
m_font = other.m_font; |
m_realizedFont = other.m_realizedFont; |
@@ -2016,6 +2026,27 @@ void CanvasRenderingContext2D::setTextBaseline(const String& s) |
modifiableState().m_textBaseline = baseline; |
} |
+String CanvasRenderingContext2D::direction() const |
+{ |
+ return state().m_direction == RTL ? "rtl" : "ltr"; |
+} |
+ |
+void CanvasRenderingContext2D::setDirection(const String& directionString) |
+{ |
+ TextDirection direction; |
+ if (directionString == "inherit") |
+ direction = inheritedDirection(*canvas()); |
esprehn
2014/08/19 17:46:53
This is now how inheritance is supposed to work, i
|
+ else if (directionString == "rtl") |
+ direction = RTL; |
+ else if (directionString == "ltr") |
+ direction = LTR; |
+ else |
+ return; |
+ |
+ realizeSaves(); |
+ modifiableState().m_direction = direction; |
+} |
+ |
void CanvasRenderingContext2D::fillText(const String& text, float x, float y) |
{ |
drawTextInternal(text, x, y, true); |
@@ -2143,15 +2174,14 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo |
// FIXME: Need to turn off font smoothing. |
RenderStyle* computedStyle = canvas()->computedStyle(); |
- TextDirection direction = computedStyle ? computedStyle->direction() : LTR; |
- bool isRTL = direction == RTL; |
+ bool isRTL = state().m_direction == RTL; |
bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : false; |
- TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true); |
+ TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, state().m_direction, override, true); |
// Draw the item text at the correct point. |
FloatPoint location(x, y + getFontBaseline(fontMetrics)); |
- float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override)); |
+ float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, state().m_direction, override)); |
useMaxWidth = (useMaxWidth && maxWidth < fontWidth); |
float width = useMaxWidth ? maxWidth : fontWidth; |