| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 static const double TryRestoreContextInterval = 0.5; | 79 static const double TryRestoreContextInterval = 0.5; |
| 80 static const unsigned MaxTryRestoreContextAttempts = 4; | 80 static const unsigned MaxTryRestoreContextAttempts = 4; |
| 81 | 81 |
| 82 static bool contextLostRestoredEventsEnabled() | 82 static bool contextLostRestoredEventsEnabled() |
| 83 { | 83 { |
| 84 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); | 84 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, co
nst Canvas2DContextAttributes* attrs) | 87 CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, co
nst Canvas2DContextAttributes* attrs) |
| 88 : CanvasRenderingContext(canvas) | 88 : CanvasRenderingContext(canvas) |
| 89 , m_hasAlpha(!attrs || attrs->alpha()) | |
| 90 , m_isContextLost(false) | 89 , m_isContextLost(false) |
| 91 , m_contextRestorable(true) | 90 , m_contextRestorable(true) |
| 92 , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage()) | 91 , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage()) |
| 93 , m_tryRestoreContextAttemptCount(0) | 92 , m_tryRestoreContextAttemptCount(0) |
| 94 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC
ontextLostEvent) | 93 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC
ontextLostEvent) |
| 95 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa
tchContextRestoredEvent) | 94 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa
tchContextRestoredEvent) |
| 96 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC
ontextEvent) | 95 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC
ontextEvent) |
| 97 { | 96 { |
| 98 m_stateStack.append(adoptPtr(new State())); | 97 m_stateStack.append(adoptPtr(new State())); |
| 99 } | 98 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 CanvasRenderingContext2D::State::State() | 230 CanvasRenderingContext2D::State::State() |
| 232 : m_unrealizedSaveCount(0) | 231 : m_unrealizedSaveCount(0) |
| 233 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) | 232 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) |
| 234 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) | 233 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) |
| 235 , m_lineWidth(1) | 234 , m_lineWidth(1) |
| 236 , m_lineCap(ButtCap) | 235 , m_lineCap(ButtCap) |
| 237 , m_lineJoin(MiterJoin) | 236 , m_lineJoin(MiterJoin) |
| 238 , m_miterLimit(10) | 237 , m_miterLimit(10) |
| 239 , m_shadowBlur(0) | 238 , m_shadowBlur(0) |
| 240 , m_shadowColor(Color::transparent) | 239 , m_shadowColor(Color::transparent) |
| 241 , m_globalAlpha(1) | |
| 242 , m_globalComposite(CompositeSourceOver) | |
| 243 , m_globalBlend(blink::WebBlendModeNormal) | |
| 244 , m_invertibleCTM(true) | 240 , m_invertibleCTM(true) |
| 245 , m_lineDashOffset(0) | 241 , m_lineDashOffset(0) |
| 246 , m_imageSmoothingEnabled(true) | 242 , m_imageSmoothingEnabled(true) |
| 247 , m_textAlign(StartTextAlign) | 243 , m_textAlign(StartTextAlign) |
| 248 , m_textBaseline(AlphabeticTextBaseline) | 244 , m_textBaseline(AlphabeticTextBaseline) |
| 249 , m_direction(DirectionInherit) | 245 , m_direction(DirectionInherit) |
| 250 , m_unparsedFont(defaultFont) | 246 , m_unparsedFont(defaultFont) |
| 251 , m_realizedFont(false) | 247 , m_realizedFont(false) |
| 252 , m_hasClip(false) | 248 , m_hasClip(false) |
| 253 { | 249 { |
| 254 } | 250 } |
| 255 | 251 |
| 256 CanvasRenderingContext2D::State::State(const State& other) | 252 CanvasRenderingContext2D::State::State(const State& other) |
| 257 : CSSFontSelectorClient() | 253 : CSSFontSelectorClient() |
| 258 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) | 254 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) |
| 259 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) | 255 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) |
| 260 , m_unparsedFillColor(other.m_unparsedFillColor) | 256 , m_unparsedFillColor(other.m_unparsedFillColor) |
| 261 , m_strokeStyle(other.m_strokeStyle) | 257 , m_strokeStyle(other.m_strokeStyle) |
| 262 , m_fillStyle(other.m_fillStyle) | 258 , m_fillStyle(other.m_fillStyle) |
| 263 , m_lineWidth(other.m_lineWidth) | 259 , m_lineWidth(other.m_lineWidth) |
| 264 , m_lineCap(other.m_lineCap) | 260 , m_lineCap(other.m_lineCap) |
| 265 , m_lineJoin(other.m_lineJoin) | 261 , m_lineJoin(other.m_lineJoin) |
| 266 , m_miterLimit(other.m_miterLimit) | 262 , m_miterLimit(other.m_miterLimit) |
| 267 , m_shadowOffset(other.m_shadowOffset) | 263 , m_shadowOffset(other.m_shadowOffset) |
| 268 , m_shadowBlur(other.m_shadowBlur) | 264 , m_shadowBlur(other.m_shadowBlur) |
| 269 , m_shadowColor(other.m_shadowColor) | 265 , m_shadowColor(other.m_shadowColor) |
| 270 , m_globalAlpha(other.m_globalAlpha) | |
| 271 , m_globalComposite(other.m_globalComposite) | |
| 272 , m_globalBlend(other.m_globalBlend) | |
| 273 , m_transform(other.m_transform) | 266 , m_transform(other.m_transform) |
| 274 , m_invertibleCTM(other.m_invertibleCTM) | 267 , m_invertibleCTM(other.m_invertibleCTM) |
| 275 , m_lineDashOffset(other.m_lineDashOffset) | 268 , m_lineDashOffset(other.m_lineDashOffset) |
| 276 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) | 269 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) |
| 277 , m_textAlign(other.m_textAlign) | 270 , m_textAlign(other.m_textAlign) |
| 278 , m_textBaseline(other.m_textBaseline) | 271 , m_textBaseline(other.m_textBaseline) |
| 279 , m_direction(other.m_direction) | 272 , m_direction(other.m_direction) |
| 280 , m_unparsedFont(other.m_unparsedFont) | 273 , m_unparsedFont(other.m_unparsedFont) |
| 281 , m_font(other.m_font) | 274 , m_font(other.m_font) |
| 282 , m_realizedFont(other.m_realizedFont) | 275 , m_realizedFont(other.m_realizedFont) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 301 m_unparsedFillColor = other.m_unparsedFillColor; | 294 m_unparsedFillColor = other.m_unparsedFillColor; |
| 302 m_strokeStyle = other.m_strokeStyle; | 295 m_strokeStyle = other.m_strokeStyle; |
| 303 m_fillStyle = other.m_fillStyle; | 296 m_fillStyle = other.m_fillStyle; |
| 304 m_lineWidth = other.m_lineWidth; | 297 m_lineWidth = other.m_lineWidth; |
| 305 m_lineCap = other.m_lineCap; | 298 m_lineCap = other.m_lineCap; |
| 306 m_lineJoin = other.m_lineJoin; | 299 m_lineJoin = other.m_lineJoin; |
| 307 m_miterLimit = other.m_miterLimit; | 300 m_miterLimit = other.m_miterLimit; |
| 308 m_shadowOffset = other.m_shadowOffset; | 301 m_shadowOffset = other.m_shadowOffset; |
| 309 m_shadowBlur = other.m_shadowBlur; | 302 m_shadowBlur = other.m_shadowBlur; |
| 310 m_shadowColor = other.m_shadowColor; | 303 m_shadowColor = other.m_shadowColor; |
| 311 m_globalAlpha = other.m_globalAlpha; | |
| 312 m_globalComposite = other.m_globalComposite; | |
| 313 m_globalBlend = other.m_globalBlend; | |
| 314 m_transform = other.m_transform; | 304 m_transform = other.m_transform; |
| 315 m_invertibleCTM = other.m_invertibleCTM; | 305 m_invertibleCTM = other.m_invertibleCTM; |
| 316 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; | 306 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; |
| 317 m_textAlign = other.m_textAlign; | 307 m_textAlign = other.m_textAlign; |
| 318 m_textBaseline = other.m_textBaseline; | 308 m_textBaseline = other.m_textBaseline; |
| 319 m_direction = other.m_direction; | 309 m_direction = other.m_direction; |
| 320 m_unparsedFont = other.m_unparsedFont; | 310 m_unparsedFont = other.m_unparsedFont; |
| 321 m_font = other.m_font; | 311 m_font = other.m_font; |
| 322 m_realizedFont = other.m_realizedFont; | 312 m_realizedFont = other.m_realizedFont; |
| 323 m_hasClip = other.m_hasClip; | 313 m_hasClip = other.m_hasClip; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 { | 629 { |
| 640 GraphicsContext* c = drawingContext(); | 630 GraphicsContext* c = drawingContext(); |
| 641 if (!c) | 631 if (!c) |
| 642 return; | 632 return; |
| 643 DashArray convertedLineDash(state().m_lineDash.size()); | 633 DashArray convertedLineDash(state().m_lineDash.size()); |
| 644 for (size_t i = 0; i < state().m_lineDash.size(); ++i) | 634 for (size_t i = 0; i < state().m_lineDash.size(); ++i) |
| 645 convertedLineDash[i] = static_cast<DashArrayElement>(state().m_lineDash[
i]); | 635 convertedLineDash[i] = static_cast<DashArrayElement>(state().m_lineDash[
i]); |
| 646 c->setLineDash(convertedLineDash, state().m_lineDashOffset); | 636 c->setLineDash(convertedLineDash, state().m_lineDashOffset); |
| 647 } | 637 } |
| 648 | 638 |
| 649 float CanvasRenderingContext2D::globalAlpha() const | |
| 650 { | |
| 651 return state().m_globalAlpha; | |
| 652 } | |
| 653 | |
| 654 void CanvasRenderingContext2D::setGlobalAlpha(float alpha) | |
| 655 { | |
| 656 if (!(alpha >= 0 && alpha <= 1)) | |
| 657 return; | |
| 658 if (state().m_globalAlpha == alpha) | |
| 659 return; | |
| 660 GraphicsContext* c = drawingContext(); | |
| 661 realizeSaves(c); | |
| 662 modifiableState().m_globalAlpha = alpha; | |
| 663 if (!c) | |
| 664 return; | |
| 665 c->setAlphaAsFloat(alpha); | |
| 666 } | |
| 667 | |
| 668 String CanvasRenderingContext2D::globalCompositeOperation() const | |
| 669 { | |
| 670 return compositeOperatorName(state().m_globalComposite, state().m_globalBlen
d); | |
| 671 } | |
| 672 | |
| 673 void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
on) | |
| 674 { | |
| 675 CompositeOperator op = CompositeSourceOver; | |
| 676 blink::WebBlendMode blendMode = blink::WebBlendModeNormal; | |
| 677 if (!parseCompositeAndBlendOperator(operation, op, blendMode)) | |
| 678 return; | |
| 679 if ((state().m_globalComposite == op) && (state().m_globalBlend == blendMode
)) | |
| 680 return; | |
| 681 GraphicsContext* c = drawingContext(); | |
| 682 realizeSaves(c); | |
| 683 modifiableState().m_globalComposite = op; | |
| 684 modifiableState().m_globalBlend = blendMode; | |
| 685 if (!c) | |
| 686 return; | |
| 687 c->setCompositeOperation(op, blendMode); | |
| 688 } | |
| 689 | |
| 690 void CanvasRenderingContext2D::scale(float sx, float sy) | 639 void CanvasRenderingContext2D::scale(float sx, float sy) |
| 691 { | 640 { |
| 692 GraphicsContext* c = drawingContext(); | 641 GraphicsContext* c = drawingContext(); |
| 693 if (!c) | 642 if (!c) |
| 694 return; | 643 return; |
| 695 if (!state().m_invertibleCTM) | 644 if (!state().m_invertibleCTM) |
| 696 return; | 645 return; |
| 697 | 646 |
| 698 if (!std::isfinite(sx) | !std::isfinite(sy)) | 647 if (!std::isfinite(sx) | !std::isfinite(sy)) |
| 699 return; | 648 return; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 } | 889 } |
| 941 | 890 |
| 942 if (height < 0) { | 891 if (height < 0) { |
| 943 height = -height; | 892 height = -height; |
| 944 y -= height; | 893 y -= height; |
| 945 } | 894 } |
| 946 | 895 |
| 947 return true; | 896 return true; |
| 948 } | 897 } |
| 949 | 898 |
| 950 static bool isFullCanvasCompositeMode(CompositeOperator op) | |
| 951 { | |
| 952 // See 4.8.11.1.3 Compositing | |
| 953 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th
e platforms already | |
| 954 // implement the specification's behavior. | |
| 955 return op == CompositeSourceIn || op == CompositeSourceOut || op == Composit
eDestinationIn || op == CompositeDestinationAtop; | |
| 956 } | |
| 957 | |
| 958 static WindRule parseWinding(const String& windingRuleString) | 899 static WindRule parseWinding(const String& windingRuleString) |
| 959 { | 900 { |
| 960 if (windingRuleString == "nonzero") | 901 if (windingRuleString == "nonzero") |
| 961 return RULE_NONZERO; | 902 return RULE_NONZERO; |
| 962 if (windingRuleString == "evenodd") | 903 if (windingRuleString == "evenodd") |
| 963 return RULE_EVENODD; | 904 return RULE_EVENODD; |
| 964 | 905 |
| 965 ASSERT_NOT_REACHED(); | 906 ASSERT_NOT_REACHED(); |
| 966 return RULE_EVENODD; | 907 return RULE_EVENODD; |
| 967 } | 908 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 985 | 926 |
| 986 // If gradient size is zero, then paint nothing. | 927 // If gradient size is zero, then paint nothing. |
| 987 Gradient* gradient = c->fillGradient(); | 928 Gradient* gradient = c->fillGradient(); |
| 988 if (gradient && gradient->isZeroSize()) { | 929 if (gradient && gradient->isZeroSize()) { |
| 989 return; | 930 return; |
| 990 } | 931 } |
| 991 | 932 |
| 992 WindRule windRule = c->fillRule(); | 933 WindRule windRule = c->fillRule(); |
| 993 c->setFillRule(parseWinding(windingRuleString)); | 934 c->setFillRule(parseWinding(windingRuleString)); |
| 994 | 935 |
| 995 if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 936 FloatRect dirtyRect; |
| 996 fullCanvasCompositedFill(path); | 937 if (computeDirtyRect(path.boundingRect(), clipBounds, &dirtyRect)) { |
| 997 didDraw(clipBounds); | |
| 998 } else if (state().m_globalComposite == CompositeCopy) { | |
| 999 clearCanvas(); | |
| 1000 c->fillPath(path); | 938 c->fillPath(path); |
| 1001 didDraw(clipBounds); | 939 didDraw(dirtyRect); |
| 1002 } else { | |
| 1003 FloatRect dirtyRect; | |
| 1004 if (computeDirtyRect(path.boundingRect(), clipBounds, &dirtyRect)) { | |
| 1005 c->fillPath(path); | |
| 1006 didDraw(dirtyRect); | |
| 1007 } | |
| 1008 } | 940 } |
| 1009 | 941 |
| 1010 c->setFillRule(windRule); | 942 c->setFillRule(windRule); |
| 1011 } | 943 } |
| 1012 | 944 |
| 1013 void CanvasRenderingContext2D::fill(const String& windingRuleString) | 945 void CanvasRenderingContext2D::fill(const String& windingRuleString) |
| 1014 { | 946 { |
| 1015 fillInternal(m_path, windingRuleString); | 947 fillInternal(m_path, windingRuleString); |
| 1016 } | 948 } |
| 1017 | 949 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1035 FloatRect clipBounds; | 967 FloatRect clipBounds; |
| 1036 if (!c->getTransformedClipBounds(&clipBounds)) | 968 if (!c->getTransformedClipBounds(&clipBounds)) |
| 1037 return; | 969 return; |
| 1038 | 970 |
| 1039 // If gradient size is zero, then paint nothing. | 971 // If gradient size is zero, then paint nothing. |
| 1040 Gradient* gradient = c->strokeGradient(); | 972 Gradient* gradient = c->strokeGradient(); |
| 1041 if (gradient && gradient->isZeroSize()) { | 973 if (gradient && gradient->isZeroSize()) { |
| 1042 return; | 974 return; |
| 1043 } | 975 } |
| 1044 | 976 |
| 1045 if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 977 FloatRect bounds = path.boundingRect(); |
| 1046 fullCanvasCompositedStroke(path); | 978 inflateStrokeRect(bounds); |
| 1047 didDraw(clipBounds); | 979 FloatRect dirtyRect; |
| 1048 } else if (state().m_globalComposite == CompositeCopy) { | 980 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { |
| 1049 clearCanvas(); | |
| 1050 c->strokePath(path); | 981 c->strokePath(path); |
| 1051 didDraw(clipBounds); | 982 didDraw(dirtyRect); |
| 1052 } else { | |
| 1053 FloatRect bounds = path.boundingRect(); | |
| 1054 inflateStrokeRect(bounds); | |
| 1055 FloatRect dirtyRect; | |
| 1056 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { | |
| 1057 c->strokePath(path); | |
| 1058 didDraw(dirtyRect); | |
| 1059 } | |
| 1060 } | 983 } |
| 1061 } | 984 } |
| 1062 | 985 |
| 1063 void CanvasRenderingContext2D::stroke() | 986 void CanvasRenderingContext2D::stroke() |
| 1064 { | 987 { |
| 1065 strokeInternal(m_path); | 988 strokeInternal(m_path); |
| 1066 } | 989 } |
| 1067 | 990 |
| 1068 void CanvasRenderingContext2D::stroke(Path2D* domPath) | 991 void CanvasRenderingContext2D::stroke(Path2D* domPath) |
| 1069 { | 992 { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 FloatRect dirtyRect; | 1128 FloatRect dirtyRect; |
| 1206 if (!computeDirtyRect(rect, &dirtyRect)) | 1129 if (!computeDirtyRect(rect, &dirtyRect)) |
| 1207 return; | 1130 return; |
| 1208 | 1131 |
| 1209 bool saved = false; | 1132 bool saved = false; |
| 1210 if (shouldDrawShadows()) { | 1133 if (shouldDrawShadows()) { |
| 1211 context->save(); | 1134 context->save(); |
| 1212 saved = true; | 1135 saved = true; |
| 1213 context->clearShadow(); | 1136 context->clearShadow(); |
| 1214 } | 1137 } |
| 1215 if (state().m_globalAlpha != 1) { | |
| 1216 if (!saved) { | |
| 1217 context->save(); | |
| 1218 saved = true; | |
| 1219 } | |
| 1220 context->setAlphaAsFloat(1); | |
| 1221 } | |
| 1222 if (state().m_globalComposite != CompositeSourceOver) { | |
| 1223 if (!saved) { | |
| 1224 context->save(); | |
| 1225 saved = true; | |
| 1226 } | |
| 1227 context->setCompositeOperation(CompositeSourceOver); | |
| 1228 } | |
| 1229 context->clearRect(rect); | 1138 context->clearRect(rect); |
| 1230 if (m_hitRegionManager) | 1139 if (m_hitRegionManager) |
| 1231 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform); | 1140 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform); |
| 1232 if (saved) | 1141 if (saved) |
| 1233 context->restore(); | 1142 context->restore(); |
| 1234 | 1143 |
| 1235 validateStateStack(); | 1144 validateStateStack(); |
| 1236 didDraw(dirtyRect); | 1145 didDraw(dirtyRect); |
| 1237 } | 1146 } |
| 1238 | 1147 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1254 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing | 1163 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing |
| 1255 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n
othing | 1164 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n
othing |
| 1256 Gradient* gradient = c->fillGradient(); | 1165 Gradient* gradient = c->fillGradient(); |
| 1257 if (gradient && gradient->isZeroSize()) | 1166 if (gradient && gradient->isZeroSize()) |
| 1258 return; | 1167 return; |
| 1259 | 1168 |
| 1260 FloatRect rect(x, y, width, height); | 1169 FloatRect rect(x, y, width, height); |
| 1261 if (rectContainsTransformedRect(rect, clipBounds)) { | 1170 if (rectContainsTransformedRect(rect, clipBounds)) { |
| 1262 c->fillRect(rect); | 1171 c->fillRect(rect); |
| 1263 didDraw(clipBounds); | 1172 didDraw(clipBounds); |
| 1264 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { | |
| 1265 fullCanvasCompositedFill(rect); | |
| 1266 didDraw(clipBounds); | |
| 1267 } else if (state().m_globalComposite == CompositeCopy) { | |
| 1268 clearCanvas(); | |
| 1269 c->fillRect(rect); | |
| 1270 didDraw(clipBounds); | |
| 1271 } else { | 1173 } else { |
| 1272 FloatRect dirtyRect; | 1174 FloatRect dirtyRect; |
| 1273 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { | 1175 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { |
| 1274 c->fillRect(rect); | 1176 c->fillRect(rect); |
| 1275 didDraw(dirtyRect); | 1177 didDraw(dirtyRect); |
| 1276 } | 1178 } |
| 1277 } | 1179 } |
| 1278 } | 1180 } |
| 1279 | 1181 |
| 1280 void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
eight) | 1182 void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
eight) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1294 if (!c->getTransformedClipBounds(&clipBounds)) | 1196 if (!c->getTransformedClipBounds(&clipBounds)) |
| 1295 return; | 1197 return; |
| 1296 | 1198 |
| 1297 // If gradient size is zero, then paint nothing. | 1199 // If gradient size is zero, then paint nothing. |
| 1298 Gradient* gradient = c->strokeGradient(); | 1200 Gradient* gradient = c->strokeGradient(); |
| 1299 if (gradient && gradient->isZeroSize()) | 1201 if (gradient && gradient->isZeroSize()) |
| 1300 return; | 1202 return; |
| 1301 | 1203 |
| 1302 FloatRect rect(x, y, width, height); | 1204 FloatRect rect(x, y, width, height); |
| 1303 | 1205 |
| 1304 if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 1206 FloatRect boundingRect = rect; |
| 1305 fullCanvasCompositedStroke(rect); | 1207 boundingRect.inflate(state().m_lineWidth / 2); |
| 1306 didDraw(clipBounds); | 1208 FloatRect dirtyRect; |
| 1307 } else if (state().m_globalComposite == CompositeCopy) { | 1209 if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) { |
| 1308 clearCanvas(); | |
| 1309 c->strokeRect(rect); | 1210 c->strokeRect(rect); |
| 1310 didDraw(clipBounds); | 1211 didDraw(dirtyRect); |
| 1311 } else { | |
| 1312 FloatRect boundingRect = rect; | |
| 1313 boundingRect.inflate(state().m_lineWidth / 2); | |
| 1314 FloatRect dirtyRect; | |
| 1315 if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) { | |
| 1316 c->strokeRect(rect); | |
| 1317 didDraw(dirtyRect); | |
| 1318 } | |
| 1319 } | 1212 } |
| 1320 } | 1213 } |
| 1321 | 1214 |
| 1322 void CanvasRenderingContext2D::setShadow(float width, float height, float blur) | 1215 void CanvasRenderingContext2D::setShadow(float width, float height, float blur) |
| 1323 { | 1216 { |
| 1324 setShadow(FloatSize(width, height), blur, Color::transparent); | 1217 setShadow(FloatSize(width, height), blur, Color::transparent); |
| 1325 } | 1218 } |
| 1326 | 1219 |
| 1327 void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
const String& color) | 1220 void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
const String& color) |
| 1328 { | 1221 { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &sr
cRect, &dstRect); | 1380 clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &sr
cRect, &dstRect); |
| 1488 | 1381 |
| 1489 imageSource->adjustDrawRects(&srcRect, &dstRect); | 1382 imageSource->adjustDrawRects(&srcRect, &dstRect); |
| 1490 | 1383 |
| 1491 if (srcRect.isEmpty()) | 1384 if (srcRect.isEmpty()) |
| 1492 return; | 1385 return; |
| 1493 | 1386 |
| 1494 FloatRect dirtyRect = clipBounds; | 1387 FloatRect dirtyRect = clipBounds; |
| 1495 if (rectContainsTransformedRect(dstRect, clipBounds)) { | 1388 if (rectContainsTransformedRect(dstRect, clipBounds)) { |
| 1496 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); | 1389 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); |
| 1497 } else if (isFullCanvasCompositeMode(op)) { | |
| 1498 fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op); | |
| 1499 } else if (op == CompositeCopy) { | |
| 1500 clearCanvas(); | |
| 1501 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); | |
| 1502 } else { | 1390 } else { |
| 1503 FloatRect dirtyRect; | 1391 FloatRect dirtyRect; |
| 1504 computeDirtyRect(dstRect, clipBounds, &dirtyRect); | 1392 computeDirtyRect(dstRect, clipBounds, &dirtyRect); |
| 1505 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); | 1393 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); |
| 1506 } | 1394 } |
| 1507 | 1395 |
| 1508 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can
vas()->buffer()) | 1396 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can
vas()->buffer()) |
| 1509 canvas()->buffer()->flush(); | 1397 canvas()->buffer()->flush(); |
| 1510 | 1398 |
| 1511 didDraw(dirtyRect); | 1399 didDraw(dirtyRect); |
| 1512 } | 1400 } |
| 1513 | 1401 |
| 1514 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, | 1402 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, |
| 1515 float sx, float sy, float sw, float sh, | 1403 float sx, float sy, float sw, float sh, |
| 1516 float dx, float dy, float dw, float dh, | 1404 float dx, float dy, float dw, float dh, |
| 1517 const String& compositeOperation) | 1405 const String& compositeOperation) |
| 1518 { | 1406 { |
| 1519 if (!image) | 1407 if (!image) |
| 1520 return; | 1408 return; |
| 1521 CompositeOperator op; | 1409 CompositeOperator op; |
| 1522 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; | 1410 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; |
| 1523 if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blen
dOp != blink::WebBlendModeNormal) | 1411 if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blen
dOp != blink::WebBlendModeNormal) |
| 1524 op = CompositeSourceOver; | 1412 op = CompositeSourceOver; |
| 1525 | 1413 |
| 1526 drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, o
p, blendOp); | 1414 drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, o
p, blendOp); |
| 1527 } | 1415 } |
| 1528 | 1416 |
| 1529 void CanvasRenderingContext2D::setAlpha(float alpha) | |
| 1530 { | |
| 1531 setGlobalAlpha(alpha); | |
| 1532 } | |
| 1533 | |
| 1534 void CanvasRenderingContext2D::setCompositeOperation(const String& operation) | |
| 1535 { | |
| 1536 setGlobalCompositeOperation(operation); | |
| 1537 } | |
| 1538 | |
| 1539 void CanvasRenderingContext2D::clearCanvas() | 1417 void CanvasRenderingContext2D::clearCanvas() |
| 1540 { | 1418 { |
| 1541 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); | 1419 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); |
| 1542 GraphicsContext* c = drawingContext(); | 1420 GraphicsContext* c = drawingContext(); |
| 1543 if (!c) | 1421 if (!c) |
| 1544 return; | 1422 return; |
| 1545 | 1423 |
| 1546 c->save(); | 1424 c->save(); |
| 1547 c->setCTM(canvas()->baseTransform()); | 1425 c->setCTM(canvas()->baseTransform()); |
| 1548 c->clearRect(canvasRect); | 1426 c->clearRect(canvasRect); |
| 1549 c->restore(); | 1427 c->restore(); |
| 1550 } | 1428 } |
| 1551 | 1429 |
| 1552 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect
, const FloatRect& transformedRect) const | 1430 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect
, const FloatRect& transformedRect) const |
| 1553 { | 1431 { |
| 1554 FloatQuad quad(rect); | 1432 FloatQuad quad(rect); |
| 1555 FloatQuad transformedQuad(transformedRect); | 1433 FloatQuad transformedQuad(transformedRect); |
| 1556 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); | 1434 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); |
| 1557 } | 1435 } |
| 1558 | 1436 |
| 1559 static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
atRect& dest, const FloatRect& src, CompositeOperator op) | |
| 1560 { | |
| 1561 context->drawImage(image, dest, src, op); | |
| 1562 } | |
| 1563 | |
| 1564 template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(
T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op) | |
| 1565 { | |
| 1566 ASSERT(isFullCanvasCompositeMode(op)); | |
| 1567 | |
| 1568 GraphicsContext* c = drawingContext(); | |
| 1569 c->beginLayer(1, op); | |
| 1570 drawImageToContext(image, c, dest, src, CompositeSourceOver); | |
| 1571 c->endLayer(); | |
| 1572 } | |
| 1573 | |
| 1574 static void fillPrimitive(const FloatRect& rect, GraphicsContext* context) | |
| 1575 { | |
| 1576 context->fillRect(rect); | |
| 1577 } | |
| 1578 | |
| 1579 static void fillPrimitive(const Path& path, GraphicsContext* context) | |
| 1580 { | |
| 1581 context->fillPath(path); | |
| 1582 } | |
| 1583 | |
| 1584 template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const
T& area) | |
| 1585 { | |
| 1586 ASSERT(isFullCanvasCompositeMode(state().m_globalComposite)); | |
| 1587 | |
| 1588 GraphicsContext* c = drawingContext(); | |
| 1589 ASSERT(c); | |
| 1590 c->beginLayer(1, state().m_globalComposite); | |
| 1591 CompositeOperator previousOperator = c->compositeOperation(); | |
| 1592 c->setCompositeOperation(CompositeSourceOver); | |
| 1593 fillPrimitive(area, c); | |
| 1594 c->setCompositeOperation(previousOperator); | |
| 1595 c->endLayer(); | |
| 1596 } | |
| 1597 | |
| 1598 static void strokePrimitive(const FloatRect& rect, GraphicsContext* context) | |
| 1599 { | |
| 1600 context->strokeRect(rect); | |
| 1601 } | |
| 1602 | |
| 1603 static void strokePrimitive(const Path& path, GraphicsContext* context) | |
| 1604 { | |
| 1605 context->strokePath(path); | |
| 1606 } | |
| 1607 | |
| 1608 template<class T> void CanvasRenderingContext2D::fullCanvasCompositedStroke(cons
t T& area) | |
| 1609 { | |
| 1610 ASSERT(isFullCanvasCompositeMode(state().m_globalComposite)); | |
| 1611 | |
| 1612 GraphicsContext* c = drawingContext(); | |
| 1613 ASSERT(c); | |
| 1614 c->beginLayer(1, state().m_globalComposite); | |
| 1615 CompositeOperator previousOperator = c->compositeOperation(); | |
| 1616 c->setCompositeOperation(CompositeSourceOver); | |
| 1617 strokePrimitive(area, c); | |
| 1618 c->setCompositeOperation(previousOperator); | |
| 1619 c->endLayer(); | |
| 1620 } | |
| 1621 | |
| 1622 PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float
x0, float y0, float x1, float y1) | 1437 PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float
x0, float y0, float x1, float y1) |
| 1623 { | 1438 { |
| 1624 RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0),
FloatPoint(x1, y1)); | 1439 RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0),
FloatPoint(x1, y1)); |
| 1625 return gradient.release(); | 1440 return gradient.release(); |
| 1626 } | 1441 } |
| 1627 | 1442 |
| 1628 PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float
x0, float y0, float r0, float x1, float y1, float r1, ExceptionState& exceptionS
tate) | 1443 PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float
x0, float y0, float r0, float x1, float y1, float r1, ExceptionState& exceptionS
tate) |
| 1629 { | 1444 { |
| 1630 if (r0 < 0 || r1 < 0) { | 1445 if (r0 < 0 || r1 < 0) { |
| 1631 exceptionState.throwDOMException(IndexSizeError, String::format("The %s
provided is less than 0.", r0 < 0 ? "r0" : "r1")); | 1446 exceptionState.throwDOMException(IndexSizeError, String::format("The %s
provided is less than 0.", r0 < 0 ? "r0" : "r1")); |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2183 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" o
p) still work. | 1998 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" o
p) still work. |
| 2184 c->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1); | 1999 c->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1); |
| 2185 location = FloatPoint(); | 2000 location = FloatPoint(); |
| 2186 } | 2001 } |
| 2187 | 2002 |
| 2188 FloatRect clipBounds; | 2003 FloatRect clipBounds; |
| 2189 if (!c->getTransformedClipBounds(&clipBounds)) { | 2004 if (!c->getTransformedClipBounds(&clipBounds)) { |
| 2190 return; | 2005 return; |
| 2191 } | 2006 } |
| 2192 | 2007 |
| 2193 if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 2008 FloatRect dirtyRect; |
| 2194 c->beginLayer(1, state().m_globalComposite); | 2009 if (computeDirtyRect(textRunPaintInfo.bounds, clipBounds, &dirtyRect)) { |
| 2195 CompositeOperator previousOperator = c->compositeOperation(); | |
| 2196 c->setCompositeOperation(CompositeSourceOver); | |
| 2197 c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFon
tNotReady); | 2010 c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFon
tNotReady); |
| 2198 c->setCompositeOperation(previousOperator); | 2011 didDraw(dirtyRect); |
| 2199 c->endLayer(); | |
| 2200 didDraw(clipBounds); | |
| 2201 } else if (state().m_globalComposite == CompositeCopy) { | |
| 2202 clearCanvas(); | |
| 2203 c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFon
tNotReady); | |
| 2204 didDraw(clipBounds); | |
| 2205 } else { | |
| 2206 FloatRect dirtyRect; | |
| 2207 if (computeDirtyRect(textRunPaintInfo.bounds, clipBounds, &dirtyRect)) { | |
| 2208 c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackI
fFontNotReady); | |
| 2209 didDraw(dirtyRect); | |
| 2210 } | |
| 2211 } | 2012 } |
| 2212 } | 2013 } |
| 2213 | 2014 |
| 2214 void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const | 2015 void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const |
| 2215 { | 2016 { |
| 2216 // Fast approximation of the stroke's bounding rect. | 2017 // Fast approximation of the stroke's bounding rect. |
| 2217 // This yields a slightly oversized rect but is very fast | 2018 // This yields a slightly oversized rect but is very fast |
| 2218 // compared to Path::strokeBoundingRect(). | 2019 // compared to Path::strokeBoundingRect(). |
| 2219 static const float root2 = sqrtf(2); | 2020 static const float root2 = sqrtf(2); |
| 2220 float delta = state().m_lineWidth / 2; | 2021 float delta = state().m_lineWidth / 2; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 GraphicsContext* c = drawingContext(); | 2083 GraphicsContext* c = drawingContext(); |
| 2283 realizeSaves(c); | 2084 realizeSaves(c); |
| 2284 modifiableState().m_imageSmoothingEnabled = enabled; | 2085 modifiableState().m_imageSmoothingEnabled = enabled; |
| 2285 if (c) | 2086 if (c) |
| 2286 c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQual
ity : InterpolationNone); | 2087 c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQual
ity : InterpolationNone); |
| 2287 } | 2088 } |
| 2288 | 2089 |
| 2289 PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib
utes() const | 2090 PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib
utes() const |
| 2290 { | 2091 { |
| 2291 RefPtr<Canvas2DContextAttributes> attributes = Canvas2DContextAttributes::cr
eate(); | 2092 RefPtr<Canvas2DContextAttributes> attributes = Canvas2DContextAttributes::cr
eate(); |
| 2292 attributes->setAlpha(m_hasAlpha); | |
| 2293 return attributes.release(); | 2093 return attributes.release(); |
| 2294 } | 2094 } |
| 2295 | 2095 |
| 2296 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) | 2096 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) |
| 2297 { | 2097 { |
| 2298 drawFocusIfNeededInternal(m_path, element); | 2098 drawFocusIfNeededInternal(m_path, element); |
| 2299 } | 2099 } |
| 2300 | 2100 |
| 2301 void CanvasRenderingContext2D::drawFocusIfNeeded(Path2D* path2d, Element* elemen
t) | 2101 void CanvasRenderingContext2D::drawFocusIfNeeded(Path2D* path2d, Element* elemen
t) |
| 2302 { | 2102 { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2444 | 2244 |
| 2445 unsigned CanvasRenderingContext2D::hitRegionsCount() const | 2245 unsigned CanvasRenderingContext2D::hitRegionsCount() const |
| 2446 { | 2246 { |
| 2447 if (m_hitRegionManager) | 2247 if (m_hitRegionManager) |
| 2448 return m_hitRegionManager->getHitRegionsCount(); | 2248 return m_hitRegionManager->getHitRegionsCount(); |
| 2449 | 2249 |
| 2450 return 0; | 2250 return 0; |
| 2451 } | 2251 } |
| 2452 | 2252 |
| 2453 } // namespace blink | 2253 } // namespace blink |
| OLD | NEW |