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 |