OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> | 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> |
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. | 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. |
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
10 * | 10 * |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 static const char defaultFontFamily[] = "sans-serif"; | 76 static const char defaultFontFamily[] = "sans-serif"; |
77 static const char defaultFont[] = "10px sans-serif"; | 77 static const char defaultFont[] = "10px sans-serif"; |
78 static const double TryRestoreContextInterval = 0.5; | 78 static const double TryRestoreContextInterval = 0.5; |
79 static const unsigned MaxTryRestoreContextAttempts = 4; | 79 static const unsigned MaxTryRestoreContextAttempts = 4; |
80 | 80 |
81 static bool contextLostRestoredEventsEnabled() | 81 static bool contextLostRestoredEventsEnabled() |
82 { | 82 { |
83 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); | 83 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); |
84 } | 84 } |
85 | 85 |
86 static inline TextDirection inheritedDirection(HTMLCanvasElement& canvasElement) | |
87 { | |
88 RenderStyle* computedStyle = canvasElement.computedStyle(); | |
89 return computedStyle ? computedStyle->direction() : LTR; | |
90 } | |
91 | |
86 CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, co nst Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode) | 92 CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, co nst Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode) |
87 : CanvasRenderingContext(canvas) | 93 : CanvasRenderingContext(canvas) |
88 , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode) | 94 , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode) |
89 , m_hasAlpha(!attrs || attrs->alpha()) | 95 , m_hasAlpha(!attrs || attrs->alpha()) |
90 , m_isContextLost(false) | 96 , m_isContextLost(false) |
91 , m_contextRestorable(true) | 97 , m_contextRestorable(true) |
92 , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage()) | 98 , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage()) |
93 , m_tryRestoreContextAttemptCount(0) | 99 , m_tryRestoreContextAttemptCount(0) |
94 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC ontextLostEvent) | 100 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC ontextLostEvent) |
95 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa tchContextRestoredEvent) | 101 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa tchContextRestoredEvent) |
96 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent) | 102 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent) |
97 { | 103 { |
98 m_stateStack.append(adoptPtrWillBeNoop(new State())); | 104 m_stateStack.append(adoptPtrWillBeNoop(new State())); |
105 m_stateStack.first()->m_direction = inheritedDirection(*canvas); | |
99 ScriptWrappable::init(this); | 106 ScriptWrappable::init(this); |
100 } | 107 } |
101 | 108 |
102 void CanvasRenderingContext2D::unwindStateStack() | 109 void CanvasRenderingContext2D::unwindStateStack() |
103 { | 110 { |
104 if (size_t stackSize = m_stateStack.size()) { | 111 if (size_t stackSize = m_stateStack.size()) { |
105 if (GraphicsContext* context = canvas()->existingDrawingContext()) { | 112 if (GraphicsContext* context = canvas()->existingDrawingContext()) { |
106 while (--stackSize) | 113 while (--stackSize) |
107 context->restore(); | 114 context->restore(); |
108 } | 115 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 canvas()->dispatchEvent(event); | 231 canvas()->dispatchEvent(event); |
225 } | 232 } |
226 } | 233 } |
227 | 234 |
228 void CanvasRenderingContext2D::reset() | 235 void CanvasRenderingContext2D::reset() |
229 { | 236 { |
230 validateStateStack(); | 237 validateStateStack(); |
231 unwindStateStack(); | 238 unwindStateStack(); |
232 m_stateStack.resize(1); | 239 m_stateStack.resize(1); |
233 m_stateStack.first() = adoptPtrWillBeNoop(new State()); | 240 m_stateStack.first() = adoptPtrWillBeNoop(new State()); |
241 m_stateStack.first()->m_direction = inheritedDirection(*canvas()); | |
234 m_path.clear(); | 242 m_path.clear(); |
235 validateStateStack(); | 243 validateStateStack(); |
236 } | 244 } |
237 | 245 |
238 // Important: Several of these properties are also stored in GraphicsContext's | 246 // Important: Several of these properties are also stored in GraphicsContext's |
239 // StrokeData. The default values that StrokeData uses may not the same values | 247 // StrokeData. The default values that StrokeData uses may not the same values |
240 // that the canvas 2d spec specifies. Make sure to sync the initial state of the | 248 // that the canvas 2d spec specifies. Make sure to sync the initial state of the |
241 // GraphicsContext in HTMLCanvasElement::createImageBuffer()! | 249 // GraphicsContext in HTMLCanvasElement::createImageBuffer()! |
242 CanvasRenderingContext2D::State::State() | 250 CanvasRenderingContext2D::State::State() |
243 : m_unrealizedSaveCount(0) | 251 : m_unrealizedSaveCount(0) |
244 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) | 252 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) |
245 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) | 253 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) |
246 , m_lineWidth(1) | 254 , m_lineWidth(1) |
247 , m_lineCap(ButtCap) | 255 , m_lineCap(ButtCap) |
248 , m_lineJoin(MiterJoin) | 256 , m_lineJoin(MiterJoin) |
249 , m_miterLimit(10) | 257 , m_miterLimit(10) |
250 , m_shadowBlur(0) | 258 , m_shadowBlur(0) |
251 , m_shadowColor(Color::transparent) | 259 , m_shadowColor(Color::transparent) |
252 , m_globalAlpha(1) | 260 , m_globalAlpha(1) |
253 , m_globalComposite(CompositeSourceOver) | 261 , m_globalComposite(CompositeSourceOver) |
254 , m_globalBlend(blink::WebBlendModeNormal) | 262 , m_globalBlend(blink::WebBlendModeNormal) |
255 , m_invertibleCTM(true) | 263 , m_invertibleCTM(true) |
256 , m_lineDashOffset(0) | 264 , m_lineDashOffset(0) |
257 , m_imageSmoothingEnabled(true) | 265 , m_imageSmoothingEnabled(true) |
258 , m_textAlign(StartTextAlign) | 266 , m_textAlign(StartTextAlign) |
259 , m_textBaseline(AlphabeticTextBaseline) | 267 , m_textBaseline(AlphabeticTextBaseline) |
268 , m_direction(LTR) | |
260 , m_unparsedFont(defaultFont) | 269 , m_unparsedFont(defaultFont) |
261 , m_realizedFont(false) | 270 , m_realizedFont(false) |
262 , m_hasClip(false) | 271 , m_hasClip(false) |
263 { | 272 { |
264 } | 273 } |
265 | 274 |
266 CanvasRenderingContext2D::State::State(const State& other) | 275 CanvasRenderingContext2D::State::State(const State& other) |
267 : CSSFontSelectorClient() | 276 : CSSFontSelectorClient() |
268 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) | 277 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) |
269 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) | 278 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) |
270 , m_unparsedFillColor(other.m_unparsedFillColor) | 279 , m_unparsedFillColor(other.m_unparsedFillColor) |
271 , m_strokeStyle(other.m_strokeStyle) | 280 , m_strokeStyle(other.m_strokeStyle) |
272 , m_fillStyle(other.m_fillStyle) | 281 , m_fillStyle(other.m_fillStyle) |
273 , m_lineWidth(other.m_lineWidth) | 282 , m_lineWidth(other.m_lineWidth) |
274 , m_lineCap(other.m_lineCap) | 283 , m_lineCap(other.m_lineCap) |
275 , m_lineJoin(other.m_lineJoin) | 284 , m_lineJoin(other.m_lineJoin) |
276 , m_miterLimit(other.m_miterLimit) | 285 , m_miterLimit(other.m_miterLimit) |
277 , m_shadowOffset(other.m_shadowOffset) | 286 , m_shadowOffset(other.m_shadowOffset) |
278 , m_shadowBlur(other.m_shadowBlur) | 287 , m_shadowBlur(other.m_shadowBlur) |
279 , m_shadowColor(other.m_shadowColor) | 288 , m_shadowColor(other.m_shadowColor) |
280 , m_globalAlpha(other.m_globalAlpha) | 289 , m_globalAlpha(other.m_globalAlpha) |
281 , m_globalComposite(other.m_globalComposite) | 290 , m_globalComposite(other.m_globalComposite) |
282 , m_globalBlend(other.m_globalBlend) | 291 , m_globalBlend(other.m_globalBlend) |
283 , m_transform(other.m_transform) | 292 , m_transform(other.m_transform) |
284 , m_invertibleCTM(other.m_invertibleCTM) | 293 , m_invertibleCTM(other.m_invertibleCTM) |
285 , m_lineDashOffset(other.m_lineDashOffset) | 294 , m_lineDashOffset(other.m_lineDashOffset) |
286 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) | 295 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) |
287 , m_textAlign(other.m_textAlign) | 296 , m_textAlign(other.m_textAlign) |
288 , m_textBaseline(other.m_textBaseline) | 297 , m_textBaseline(other.m_textBaseline) |
298 , m_direction(other.m_direction) | |
289 , m_unparsedFont(other.m_unparsedFont) | 299 , m_unparsedFont(other.m_unparsedFont) |
290 , m_font(other.m_font) | 300 , m_font(other.m_font) |
291 , m_realizedFont(other.m_realizedFont) | 301 , m_realizedFont(other.m_realizedFont) |
292 , m_hasClip(other.m_hasClip) | 302 , m_hasClip(other.m_hasClip) |
293 { | 303 { |
294 if (m_realizedFont) | 304 if (m_realizedFont) |
295 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 305 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
296 } | 306 } |
297 | 307 |
298 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other) | 308 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other) |
(...skipping 19 matching lines...) Expand all Loading... | |
318 m_shadowBlur = other.m_shadowBlur; | 328 m_shadowBlur = other.m_shadowBlur; |
319 m_shadowColor = other.m_shadowColor; | 329 m_shadowColor = other.m_shadowColor; |
320 m_globalAlpha = other.m_globalAlpha; | 330 m_globalAlpha = other.m_globalAlpha; |
321 m_globalComposite = other.m_globalComposite; | 331 m_globalComposite = other.m_globalComposite; |
322 m_globalBlend = other.m_globalBlend; | 332 m_globalBlend = other.m_globalBlend; |
323 m_transform = other.m_transform; | 333 m_transform = other.m_transform; |
324 m_invertibleCTM = other.m_invertibleCTM; | 334 m_invertibleCTM = other.m_invertibleCTM; |
325 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; | 335 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; |
326 m_textAlign = other.m_textAlign; | 336 m_textAlign = other.m_textAlign; |
327 m_textBaseline = other.m_textBaseline; | 337 m_textBaseline = other.m_textBaseline; |
338 m_direction = other.m_direction; | |
328 m_unparsedFont = other.m_unparsedFont; | 339 m_unparsedFont = other.m_unparsedFont; |
329 m_font = other.m_font; | 340 m_font = other.m_font; |
330 m_realizedFont = other.m_realizedFont; | 341 m_realizedFont = other.m_realizedFont; |
331 m_hasClip = other.m_hasClip; | 342 m_hasClip = other.m_hasClip; |
332 | 343 |
333 if (m_realizedFont) | 344 if (m_realizedFont) |
334 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 345 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
335 | 346 |
336 return *this; | 347 return *this; |
337 } | 348 } |
(...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2009 { | 2020 { |
2010 TextBaseline baseline; | 2021 TextBaseline baseline; |
2011 if (!parseTextBaseline(s, baseline)) | 2022 if (!parseTextBaseline(s, baseline)) |
2012 return; | 2023 return; |
2013 if (state().m_textBaseline == baseline) | 2024 if (state().m_textBaseline == baseline) |
2014 return; | 2025 return; |
2015 realizeSaves(); | 2026 realizeSaves(); |
2016 modifiableState().m_textBaseline = baseline; | 2027 modifiableState().m_textBaseline = baseline; |
2017 } | 2028 } |
2018 | 2029 |
2030 String CanvasRenderingContext2D::direction() const | |
2031 { | |
2032 return (state().m_direction == RTL) ? "rtl" : "ltr"; | |
esprehn
2014/08/18 19:22:44
no parens
| |
2033 } | |
2034 | |
2035 void CanvasRenderingContext2D::setDirection(const String& s) | |
esprehn
2014/08/18 19:22:44
Don't use single letter variable bames.
| |
2036 { | |
2037 if (s != "inherit" && s != "rtl" && s != "ltr") | |
2038 return; | |
2039 | |
2040 TextDirection direction = (s == "inherit") ? inheritedDirection(*canvas()) : (s == "rtl") ? RTL : LTR; | |
esprehn
2014/08/18 19:22:44
Don't nest ternaries.
| |
2041 if (state().m_direction == direction) | |
2042 return; | |
2043 | |
2044 realizeSaves(); | |
2045 modifiableState().m_direction = direction; | |
2046 } | |
2047 | |
2019 void CanvasRenderingContext2D::fillText(const String& text, float x, float y) | 2048 void CanvasRenderingContext2D::fillText(const String& text, float x, float y) |
2020 { | 2049 { |
2021 drawTextInternal(text, x, y, true); | 2050 drawTextInternal(text, x, y, true); |
2022 } | 2051 } |
2023 | 2052 |
2024 void CanvasRenderingContext2D::fillText(const String& text, float x, float y, fl oat maxWidth) | 2053 void CanvasRenderingContext2D::fillText(const String& text, float x, float y, fl oat maxWidth) |
2025 { | 2054 { |
2026 drawTextInternal(text, x, y, true, maxWidth, true); | 2055 drawTextInternal(text, x, y, true, maxWidth, true); |
2027 } | 2056 } |
2028 | 2057 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2136 | 2165 |
2137 FontCachePurgePreventer fontCachePurgePreventer; | 2166 FontCachePurgePreventer fontCachePurgePreventer; |
2138 | 2167 |
2139 const Font& font = accessFont(); | 2168 const Font& font = accessFont(); |
2140 const FontMetrics& fontMetrics = font.fontMetrics(); | 2169 const FontMetrics& fontMetrics = font.fontMetrics(); |
2141 String normalizedText = normalizeSpaces(text); | 2170 String normalizedText = normalizeSpaces(text); |
2142 | 2171 |
2143 // FIXME: Need to turn off font smoothing. | 2172 // FIXME: Need to turn off font smoothing. |
2144 | 2173 |
2145 RenderStyle* computedStyle = canvas()->computedStyle(); | 2174 RenderStyle* computedStyle = canvas()->computedStyle(); |
2146 TextDirection direction = computedStyle ? computedStyle->direction() : LTR; | 2175 bool isRTL = state().m_direction == RTL; |
2147 bool isRTL = direction == RTL; | |
2148 bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : f alse; | 2176 bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : f alse; |
2149 | 2177 |
2150 TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direc tion, override, true); | 2178 TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, state ().m_direction, override, true); |
2151 // Draw the item text at the correct point. | 2179 // Draw the item text at the correct point. |
2152 FloatPoint location(x, y + getFontBaseline(fontMetrics)); | 2180 FloatPoint location(x, y + getFontBaseline(fontMetrics)); |
2153 | 2181 |
2154 float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTra ilingExpansion, direction, override)); | 2182 float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTra ilingExpansion, state().m_direction, override)); |
2155 | 2183 |
2156 useMaxWidth = (useMaxWidth && maxWidth < fontWidth); | 2184 useMaxWidth = (useMaxWidth && maxWidth < fontWidth); |
2157 float width = useMaxWidth ? maxWidth : fontWidth; | 2185 float width = useMaxWidth ? maxWidth : fontWidth; |
2158 | 2186 |
2159 TextAlign align = state().m_textAlign; | 2187 TextAlign align = state().m_textAlign; |
2160 if (align == StartTextAlign) | 2188 if (align == StartTextAlign) |
2161 align = isRTL ? RightTextAlign : LeftTextAlign; | 2189 align = isRTL ? RightTextAlign : LeftTextAlign; |
2162 else if (align == EndTextAlign) | 2190 else if (align == EndTextAlign) |
2163 align = isRTL ? LeftTextAlign : RightTextAlign; | 2191 align = isRTL ? LeftTextAlign : RightTextAlign; |
2164 | 2192 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2444 | 2472 |
2445 unsigned CanvasRenderingContext2D::hitRegionsCount() const | 2473 unsigned CanvasRenderingContext2D::hitRegionsCount() const |
2446 { | 2474 { |
2447 if (m_hitRegionManager) | 2475 if (m_hitRegionManager) |
2448 return m_hitRegionManager->getHitRegionsCount(); | 2476 return m_hitRegionManager->getHitRegionsCount(); |
2449 | 2477 |
2450 return 0; | 2478 return 0; |
2451 } | 2479 } |
2452 | 2480 |
2453 } // namespace blink | 2481 } // namespace blink |
OLD | NEW |