Chromium Code Reviews| 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 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1183 c->drawRect(rect, clearPaint); | 1183 c->drawRect(rect, clearPaint); |
| 1184 didDraw(dirtyRect); | 1184 didDraw(dirtyRect); |
| 1185 } | 1185 } |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 if (m_hitRegionManager) { | 1188 if (m_hitRegionManager) { |
| 1189 m_hitRegionManager->removeHitRegionsInRect(rect, state().transform()); | 1189 m_hitRegionManager->removeHitRegionsInRect(rect, state().transform()); |
| 1190 } | 1190 } |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. | 1193 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. |
|
Stephen White
2015/03/18 22:09:34
Is this comment still relevant?
Justin Novosad
2015/03/19 14:32:21
Yes, unfortunately. because drawRect is virtual, w
| |
| 1194 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) | 1194 static void drawRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const SkPa int* paint) |
| 1195 { | 1195 { |
| 1196 context->fillRect(rect); | 1196 canvas->drawRect(rect, *paint); |
| 1197 } | |
| 1198 | |
| 1199 static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect) | |
| 1200 { | |
| 1201 context->strokeRect(rect); | |
| 1202 } | 1197 } |
| 1203 | 1198 |
| 1204 void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei ght) | 1199 void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei ght) |
| 1205 { | 1200 { |
| 1206 if (!validateRectForCanvas(x, y, width, height)) | 1201 if (!validateRectForCanvas(x, y, width, height)) |
| 1207 return; | 1202 return; |
| 1208 | 1203 |
| 1209 GraphicsContext* c = drawingContext(); | 1204 if (!drawingCanvas()) |
| 1210 if (!c) | |
| 1211 return; | 1205 return; |
| 1212 if (!state().isTransformInvertible()) | 1206 if (!state().isTransformInvertible()) |
| 1213 return; | 1207 return; |
| 1214 SkIRect clipBounds; | 1208 SkIRect clipBounds; |
| 1215 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds)) | 1209 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds)) |
| 1216 return; | 1210 return; |
| 1217 | 1211 |
| 1218 // from the HTML5 Canvas spec: | 1212 // from the HTML5 Canvas spec: |
| 1219 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing | 1213 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing |
| 1220 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing | 1214 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing |
| 1221 Gradient* gradient = c->fillGradient(); | 1215 CanvasGradient* gradient = state().fillStyle()->canvasGradient(); |
| 1222 if (gradient && gradient->isZeroSize()) | 1216 if (gradient && gradient->gradient()->isZeroSize()) |
| 1223 return; | 1217 return; |
| 1224 | 1218 |
| 1225 FloatRect rect(x, y, width, height); | 1219 FloatRect rect(x, y, width, height); |
| 1226 if (rectContainsTransformedRect(rect, clipBounds)) { | 1220 if (rectContainsTransformedRect(rect, clipBounds)) { |
| 1227 checkOverdraw(rect, &c->fillPaint(), NoImage, ClipFill); | 1221 const SkPaint* paint = state().skPaint(FillPaintType, DrawShadowAndForeg round, DrawLooperShadowStrategy); |
| 1228 c->fillRect(rect); | 1222 checkOverdraw(rect, paint, NoImage, ClipFill); |
| 1223 drawingCanvas()->drawRect(rect, *paint); | |
| 1229 didDraw(clipBounds); | 1224 didDraw(clipBounds); |
| 1230 } else if (isFullCanvasCompositeMode(state().globalComposite())) { | 1225 } else if (isFullCanvasCompositeMode(state().globalComposite())) { |
| 1231 fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect)); | 1226 fullCanvasCompositedDraw(bind<SkCanvas*, const SkPaint*>(drawRectOnCanva s, rect), FillPaintType, DrawLooperShadowStrategy); |
| 1232 didDraw(clipBounds); | 1227 didDraw(clipBounds); |
| 1233 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { | 1228 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { |
| 1234 clearCanvas(); | 1229 clearCanvas(); |
| 1235 c->clearShadow(); // Takes care of signaling the overdraw | 1230 const SkPaint* paint = state().skPaint(FillPaintType, DrawForegroundOnly , DrawLooperShadowStrategy); |
| 1236 c->fillRect(rect); | 1231 drawingCanvas()->drawRect(rect, *paint); |
| 1237 applyShadow(DrawShadowAndForeground); | |
| 1238 didDraw(clipBounds); | 1232 didDraw(clipBounds); |
| 1239 } else { | 1233 } else { |
| 1240 SkIRect dirtyRect; | 1234 SkIRect dirtyRect; |
| 1241 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { | 1235 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { |
| 1242 c->fillRect(rect); | 1236 const SkPaint* paint = state().skPaint(FillPaintType, DrawShadowAndF oreground, DrawLooperShadowStrategy); |
| 1237 drawingCanvas()->drawRect(rect, *paint); | |
| 1243 didDraw(dirtyRect); | 1238 didDraw(dirtyRect); |
| 1244 } | 1239 } |
| 1245 } | 1240 } |
| 1246 } | 1241 } |
| 1247 | 1242 |
| 1248 void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h eight) | 1243 void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h eight) |
| 1249 { | 1244 { |
| 1250 if (!validateRectForCanvas(x, y, width, height)) | 1245 if (!validateRectForCanvas(x, y, width, height)) |
| 1251 return; | 1246 return; |
| 1252 | 1247 |
| 1253 if (!(state().lineWidth() >= 0)) | 1248 if (!(state().lineWidth() >= 0)) |
| 1254 return; | 1249 return; |
| 1255 | 1250 |
| 1256 GraphicsContext* c = drawingContext(); | 1251 if (!drawingCanvas()) |
| 1257 if (!c) | |
| 1258 return; | 1252 return; |
| 1253 | |
| 1259 if (!state().isTransformInvertible()) | 1254 if (!state().isTransformInvertible()) |
| 1260 return; | 1255 return; |
| 1256 | |
| 1261 SkIRect clipBounds; | 1257 SkIRect clipBounds; |
| 1262 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds)) | 1258 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds)) |
| 1263 return; | 1259 return; |
| 1264 | 1260 |
| 1265 // If gradient size is zero, then paint nothing. | 1261 // If gradient size is zero, then paint nothing. |
| 1266 Gradient* gradient = c->strokeGradient(); | 1262 CanvasGradient* gradient = state().strokeStyle()->canvasGradient(); |
| 1267 if (gradient && gradient->isZeroSize()) | 1263 if (gradient && gradient->gradient()->isZeroSize()) |
| 1268 return; | 1264 return; |
| 1269 | 1265 |
| 1270 FloatRect rect(x, y, width, height); | 1266 FloatRect rect(x, y, width, height); |
| 1271 if (isFullCanvasCompositeMode(state().globalComposite())) { | 1267 if (isFullCanvasCompositeMode(state().globalComposite())) { |
| 1272 fullCanvasCompositedDraw(bind(&strokeRectOnContext, c, rect)); | 1268 fullCanvasCompositedDraw(bind<SkCanvas*, const SkPaint*>(drawRectOnCanva s, rect), StrokePaintType, DrawLooperShadowStrategy); |
| 1273 didDraw(clipBounds); | 1269 didDraw(clipBounds); |
| 1274 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { | 1270 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { |
| 1275 clearCanvas(); | 1271 clearCanvas(); |
| 1276 c->clearShadow(); | 1272 const SkPaint* paint = state().skPaint(StrokePaintType, DrawForegroundOn ly, DrawLooperShadowStrategy); |
| 1277 c->strokeRect(rect); | 1273 drawingCanvas()->drawRect(rect, *paint); |
| 1278 applyShadow(DrawShadowAndForeground); | |
| 1279 didDraw(clipBounds); | 1274 didDraw(clipBounds); |
| 1280 } else { | 1275 } else { |
| 1281 FloatRect boundingRect = rect; | 1276 FloatRect boundingRect = rect; |
| 1282 boundingRect.inflate(state().lineWidth() / 2); | 1277 boundingRect.inflate(state().lineWidth() / 2); |
| 1283 SkIRect dirtyRect; | 1278 SkIRect dirtyRect; |
| 1284 if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) { | 1279 if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) { |
| 1285 c->strokeRect(rect); | 1280 const SkPaint* paint = state().skPaint(StrokePaintType, DrawShadowAn dForeground, DrawLooperShadowStrategy); |
| 1281 drawingCanvas()->drawRect(rect, *paint); | |
| 1286 didDraw(dirtyRect); | 1282 didDraw(dirtyRect); |
| 1287 } | 1283 } |
| 1288 } | 1284 } |
| 1289 } | 1285 } |
| 1290 | 1286 |
| 1291 void CanvasRenderingContext2D::applyShadow(ShadowMode shadowMode) | 1287 void CanvasRenderingContext2D::applyShadow(ShadowMode shadowMode) |
| 1292 { | 1288 { |
| 1293 GraphicsContext* c = drawingContext(); | 1289 GraphicsContext* c = drawingContext(); |
| 1294 if (!c) | 1290 if (!c) |
| 1295 return; | 1291 return; |
| 1296 | 1292 |
| 1297 if (shouldDrawShadows()) { | 1293 if (state().shouldDrawShadows()) { |
| 1298 c->setShadow(state().shadowOffset(), state().shadowBlur(), state().shado wColor(), | 1294 c->setShadow(state().shadowOffset(), state().shadowBlur(), state().shado wColor(), |
| 1299 DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::Shado wRespectsAlpha, shadowMode); | 1295 DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::Shado wRespectsAlpha, shadowMode); |
| 1300 } else { | 1296 } else { |
| 1301 c->clearShadow(); | 1297 c->clearShadow(); |
| 1302 } | 1298 } |
| 1303 } | 1299 } |
| 1304 | 1300 |
| 1305 bool CanvasRenderingContext2D::shouldDrawShadows() const | |
| 1306 { | |
| 1307 return alphaChannel(state().shadowColor()) && (state().shadowBlur() || !stat e().shadowOffset().isZero()); | |
| 1308 } | |
| 1309 | |
| 1310 static inline FloatRect normalizeRect(const FloatRect& rect) | 1301 static inline FloatRect normalizeRect(const FloatRect& rect) |
| 1311 { | 1302 { |
| 1312 return FloatRect(std::min(rect.x(), rect.maxX()), | 1303 return FloatRect(std::min(rect.x(), rect.maxX()), |
| 1313 std::min(rect.y(), rect.maxY()), | 1304 std::min(rect.y(), rect.maxY()), |
| 1314 std::max(rect.width(), -rect.width()), | 1305 std::max(rect.width(), -rect.width()), |
| 1315 std::max(rect.height(), -rect.height())); | 1306 std::max(rect.height(), -rect.height())); |
| 1316 } | 1307 } |
| 1317 | 1308 |
| 1318 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s rcRect, FloatRect* dstRect) | 1309 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s rcRect, FloatRect* dstRect) |
| 1319 { | 1310 { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1492 drawingCanvas()->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK); | 1483 drawingCanvas()->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK); |
| 1493 } | 1484 } |
| 1494 | 1485 |
| 1495 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const SkIRect& transformedRect) const | 1486 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const SkIRect& transformedRect) const |
| 1496 { | 1487 { |
| 1497 FloatQuad quad(rect); | 1488 FloatQuad quad(rect); |
| 1498 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y() , transformedRect.width(), transformedRect.height())); | 1489 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y() , transformedRect.width(), transformedRect.height())); |
| 1499 return state().transform().mapQuad(quad).containsQuad(transformedQuad); | 1490 return state().transform().mapQuad(quad).containsQuad(transformedQuad); |
| 1500 } | 1491 } |
| 1501 | 1492 |
| 1493 void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Function<void (SkCanvas*, const SkPaint*)>> draw, CanvasPaintType paintType, CanvasShadowStrat egy shadowStrategy) | |
| 1494 { | |
| 1495 ASSERT(isFullCanvasCompositeMode(state().globalComposite())); | |
| 1496 ASSERT(draw); | |
| 1497 | |
| 1498 SkCanvas* c = drawingCanvas(); | |
| 1499 ASSERT(c); | |
| 1500 | |
| 1501 SkPaint layerPaint; | |
| 1502 layerPaint.setXfermodeMode(state().globalComposite()); | |
| 1503 if (state().shouldDrawShadows()) { | |
| 1504 // unroll into two independently composited passes if drawing shadows | |
| 1505 c->saveLayer(0, &layerPaint); | |
| 1506 SkPaint shadowPaint = *state().skPaint(paintType, DrawShadowOnly, shadow Strategy); | |
| 1507 shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
| 1508 (*draw)(c, &shadowPaint); | |
| 1509 c->restore(); | |
| 1510 } | |
| 1511 | |
| 1512 c->saveLayer(0, &layerPaint); | |
| 1513 SkPaint foregroundPaint = *state().skPaint(paintType, DrawForegroundOnly, sh adowStrategy); | |
| 1514 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
| 1515 (*draw)(c, &foregroundPaint); | |
| 1516 c->restore(); | |
| 1517 } | |
| 1518 | |
| 1502 void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw ) | 1519 void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw ) |
| 1503 { | 1520 { |
| 1504 ASSERT(isFullCanvasCompositeMode(state().globalComposite())); | 1521 ASSERT(isFullCanvasCompositeMode(state().globalComposite())); |
| 1505 | 1522 |
| 1506 GraphicsContext* c = drawingContext(); | 1523 GraphicsContext* c = drawingContext(); |
| 1507 ASSERT(c); | 1524 ASSERT(c); |
| 1508 | 1525 |
| 1509 if (shouldDrawShadows()) { | 1526 if (state().shouldDrawShadows()) { |
| 1510 // unroll into two independently composited passes if drawing shadows | 1527 // unroll into two independently composited passes if drawing shadows |
| 1511 c->beginLayer(1, state().globalComposite()); | 1528 c->beginLayer(1, state().globalComposite()); |
| 1512 c->setCompositeOperation(SkXfermode::kSrcOver_Mode); | 1529 c->setCompositeOperation(SkXfermode::kSrcOver_Mode); |
| 1513 applyShadow(DrawShadowOnly); | 1530 applyShadow(DrawShadowOnly); |
| 1514 (*draw)(); | 1531 (*draw)(); |
| 1515 c->setCompositeOperation(state().globalComposite()); | 1532 c->setCompositeOperation(state().globalComposite()); |
| 1516 c->endLayer(); | 1533 c->endLayer(); |
| 1517 } | 1534 } |
| 1518 | 1535 |
| 1519 c->beginLayer(1, state().globalComposite()); | 1536 c->beginLayer(1, state().globalComposite()); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1607 *dirtyRect = canvasIRect; | 1624 *dirtyRect = canvasIRect; |
| 1608 | 1625 |
| 1609 return true; | 1626 return true; |
| 1610 } | 1627 } |
| 1611 | 1628 |
| 1612 void CanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect) | 1629 void CanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect) |
| 1613 { | 1630 { |
| 1614 if (dirtyRect.isEmpty()) | 1631 if (dirtyRect.isEmpty()) |
| 1615 return; | 1632 return; |
| 1616 | 1633 |
| 1617 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && should DrawShadows() && state().shadowBlur() > 0) { | 1634 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && state( ).shouldDrawShadows() && state().shadowBlur() > 0) { |
| 1618 ImageBuffer* buffer = canvas()->buffer(); | 1635 ImageBuffer* buffer = canvas()->buffer(); |
| 1619 if (buffer) | 1636 if (buffer) |
| 1620 buffer->setHasExpensiveOp(); | 1637 buffer->setHasExpensiveOp(); |
| 1621 } | 1638 } |
| 1622 | 1639 |
| 1623 canvas()->didDraw(SkRect::MakeFromIRect(dirtyRect)); | 1640 canvas()->didDraw(SkRect::MakeFromIRect(dirtyRect)); |
| 1624 } | 1641 } |
| 1625 | 1642 |
| 1626 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const | 1643 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const |
| 1627 { | 1644 { |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2411 if (imageType == NonOpaqueImage) | 2428 if (imageType == NonOpaqueImage) |
| 2412 return; | 2429 return; |
| 2413 if (alpha < 0xFF) | 2430 if (alpha < 0xFF) |
| 2414 return; | 2431 return; |
| 2415 } | 2432 } |
| 2416 | 2433 |
| 2417 canvas()->buffer()->willOverwriteCanvas(); | 2434 canvas()->buffer()->willOverwriteCanvas(); |
| 2418 } | 2435 } |
| 2419 | 2436 |
| 2420 } // namespace blink | 2437 } // namespace blink |
| OLD | NEW |