Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 1008173003: Move SkPaint mangement for 2D canvas into CanvasRenderingContext2DState (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698