Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 #include "core/platform/graphics/skia/SkiaUtils.h" | 36 #include "core/platform/graphics/skia/SkiaUtils.h" |
| 37 #include "core/platform/text/BidiResolver.h" | 37 #include "core/platform/text/BidiResolver.h" |
| 38 #include "third_party/skia/include/core/SkAnnotation.h" | 38 #include "third_party/skia/include/core/SkAnnotation.h" |
| 39 #include "third_party/skia/include/core/SkColorFilter.h" | 39 #include "third_party/skia/include/core/SkColorFilter.h" |
| 40 #include "third_party/skia/include/core/SkData.h" | 40 #include "third_party/skia/include/core/SkData.h" |
| 41 #include "third_party/skia/include/core/SkDevice.h" | 41 #include "third_party/skia/include/core/SkDevice.h" |
| 42 #include "third_party/skia/include/core/SkRRect.h" | 42 #include "third_party/skia/include/core/SkRRect.h" |
| 43 #include "third_party/skia/include/core/SkRefCnt.h" | 43 #include "third_party/skia/include/core/SkRefCnt.h" |
| 44 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" | 44 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" |
| 45 #include "third_party/skia/include/effects/SkCornerPathEffect.h" | 45 #include "third_party/skia/include/effects/SkCornerPathEffect.h" |
| 46 #include "third_party/skia/include/effects/SkLumaXfermode.h" | |
| 46 #include "weborigin/KURL.h" | 47 #include "weborigin/KURL.h" |
| 47 #include "wtf/Assertions.h" | 48 #include "wtf/Assertions.h" |
| 48 #include "wtf/MathExtras.h" | 49 #include "wtf/MathExtras.h" |
| 49 | 50 |
| 50 #if OS(DARWIN) | 51 #if OS(DARWIN) |
| 51 #include <ApplicationServices/ApplicationServices.h> | 52 #include <ApplicationServices/ApplicationServices.h> |
| 52 #endif | 53 #endif |
| 53 | 54 |
| 54 using namespace std; | 55 using namespace std; |
| 55 | 56 |
| 56 namespace WebCore { | 57 namespace WebCore { |
| 57 | 58 |
| 58 struct GraphicsContext::DeferredSaveState { | 59 struct GraphicsContext::DeferredSaveState { |
| 59 DeferredSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount( count) { } | 60 DeferredSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount( count) { } |
| 60 | 61 |
| 61 unsigned m_flags; | 62 unsigned m_flags; |
| 62 int m_restoreCount; | 63 int m_restoreCount; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 GraphicsContext::GraphicsContext(SkCanvas* canvas) | 66 GraphicsContext::GraphicsContext(SkCanvas* canvas) |
| 66 : m_canvas(canvas) | 67 : m_canvas(canvas) |
| 67 , m_deferredSaveFlags(0) | 68 , m_deferredSaveFlags(0) |
| 68 , m_annotationMode(0) | 69 , m_annotationMode(0) |
| 69 #if !ASSERT_DISABLED | 70 #if !ASSERT_DISABLED |
| 70 , m_annotationCount(0) | 71 , m_annotationCount(0) |
| 71 , m_transparencyCount(0) | 72 , m_layerCount(0) |
| 72 #endif | 73 #endif |
| 73 , m_trackOpaqueRegion(false) | 74 , m_trackOpaqueRegion(false) |
| 74 , m_trackTextRegion(false) | 75 , m_trackTextRegion(false) |
| 75 , m_useHighResMarker(false) | 76 , m_useHighResMarker(false) |
| 76 , m_updatingControlTints(false) | 77 , m_updatingControlTints(false) |
| 77 , m_accelerated(false) | 78 , m_accelerated(false) |
| 78 , m_isCertainlyOpaque(true) | 79 , m_isCertainlyOpaque(true) |
| 79 , m_printing(false) | 80 , m_printing(false) |
| 80 { | 81 { |
| 81 m_stateStack.append(adoptPtr(new GraphicsContextState())); | 82 m_stateStack.append(adoptPtr(new GraphicsContextState())); |
| 82 m_state = m_stateStack.last().get(); | 83 m_state = m_stateStack.last().get(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 GraphicsContext::~GraphicsContext() | 86 GraphicsContext::~GraphicsContext() |
| 86 { | 87 { |
| 87 ASSERT(m_stateStack.size() == 1); | 88 ASSERT(m_stateStack.size() == 1); |
| 88 ASSERT(!m_annotationCount); | 89 ASSERT(!m_annotationCount); |
| 89 ASSERT(!m_transparencyCount); | 90 ASSERT(!m_layerCount); |
| 90 } | 91 } |
| 91 | 92 |
| 92 const SkBitmap* GraphicsContext::bitmap() const | 93 const SkBitmap* GraphicsContext::bitmap() const |
| 93 { | 94 { |
| 94 TRACE_EVENT0("skia", "GraphicsContext::bitmap"); | 95 TRACE_EVENT0("skia", "GraphicsContext::bitmap"); |
| 95 return &m_canvas->getDevice()->accessBitmap(false); | 96 return &m_canvas->getDevice()->accessBitmap(false); |
| 96 } | 97 } |
| 97 | 98 |
| 98 const SkBitmap& GraphicsContext::layerBitmap(AccessMode access) const | 99 const SkBitmap& GraphicsContext::layerBitmap(AccessMode access) const |
| 99 { | 100 { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 123 void GraphicsContext::restore() | 124 void GraphicsContext::restore() |
| 124 { | 125 { |
| 125 if (paintingDisabled()) | 126 if (paintingDisabled()) |
| 126 return; | 127 return; |
| 127 | 128 |
| 128 if (m_stateStack.size() == 1) { | 129 if (m_stateStack.size() == 1) { |
| 129 LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty"); | 130 LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty"); |
| 130 return; | 131 return; |
| 131 } | 132 } |
| 132 | 133 |
| 133 if (!m_state->m_imageBufferClip.empty()) { | |
| 134 applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip); | |
| 135 m_canvas->restore(); | |
| 136 } | |
| 137 | |
| 138 m_stateStack.removeLast(); | 134 m_stateStack.removeLast(); |
| 139 m_state = m_stateStack.last().get(); | 135 m_state = m_stateStack.last().get(); |
| 140 | 136 |
| 141 DeferredSaveState savedState = m_saveStateStack.last(); | 137 DeferredSaveState savedState = m_saveStateStack.last(); |
| 142 m_saveStateStack.removeLast(); | 138 m_saveStateStack.removeLast(); |
| 143 m_deferredSaveFlags = savedState.m_flags; | 139 m_deferredSaveFlags = savedState.m_flags; |
| 144 m_canvas->restoreToCount(savedState.m_restoreCount); | 140 m_canvas->restoreToCount(savedState.m_restoreCount); |
| 145 } | 141 } |
| 146 | 142 |
| 147 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint, SkCa nvas::SaveFlags saveFlags) | 143 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint, SkCa nvas::SaveFlags saveFlags) |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 return shouldSmoothFonts(); | 359 return shouldSmoothFonts(); |
| 364 } | 360 } |
| 365 | 361 |
| 366 void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation , BlendMode blendMode) | 362 void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation , BlendMode blendMode) |
| 367 { | 363 { |
| 368 m_state->m_compositeOperator = compositeOperation; | 364 m_state->m_compositeOperator = compositeOperation; |
| 369 m_state->m_blendMode = blendMode; | 365 m_state->m_blendMode = blendMode; |
| 370 m_state->m_xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, bl endMode); | 366 m_state->m_xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, bl endMode); |
| 371 } | 367 } |
| 372 | 368 |
| 369 void GraphicsContext::setColorSpaceConversion(ColorSpace srcColorSpace, ColorSpa ce dstColorSpace) | |
| 370 { | |
| 371 m_state->m_colorFilter = ImageBuffer::createColorSpaceFilter(srcColorSpace, dstColorSpace); | |
| 372 } | |
| 373 | |
| 373 bool GraphicsContext::readPixels(SkBitmap* bitmap, int x, int y, SkCanvas::Confi g8888 config8888) | 374 bool GraphicsContext::readPixels(SkBitmap* bitmap, int x, int y, SkCanvas::Confi g8888 config8888) |
| 374 { | 375 { |
| 375 if (paintingDisabled()) | 376 if (paintingDisabled()) |
| 376 return false; | 377 return false; |
| 377 | 378 |
| 378 return m_canvas->readPixels(bitmap, x, y, config8888); | 379 return m_canvas->readPixels(bitmap, x, y, config8888); |
| 379 } | 380 } |
| 380 | 381 |
| 381 void GraphicsContext::setMatrix(const SkMatrix& matrix) | 382 void GraphicsContext::setMatrix(const SkMatrix& matrix) |
| 382 { | 383 { |
| 383 if (paintingDisabled()) | 384 if (paintingDisabled()) |
| 384 return; | 385 return; |
| 385 | 386 |
| 386 realizeSave(SkCanvas::kMatrix_SaveFlag); | 387 realizeSave(SkCanvas::kMatrix_SaveFlag); |
| 387 | 388 |
| 388 m_canvas->setMatrix(matrix); | 389 m_canvas->setMatrix(matrix); |
| 389 } | 390 } |
| 390 | 391 |
| 391 bool GraphicsContext::concat(const SkMatrix& matrix) | 392 bool GraphicsContext::concat(const SkMatrix& matrix) |
| 392 { | 393 { |
| 393 if (paintingDisabled()) | 394 if (paintingDisabled()) |
| 394 return false; | 395 return false; |
| 395 | 396 |
| 396 realizeSave(SkCanvas::kMatrix_SaveFlag); | 397 realizeSave(SkCanvas::kMatrix_SaveFlag); |
| 397 | 398 |
| 398 return m_canvas->concat(matrix); | 399 return m_canvas->concat(matrix); |
| 399 } | 400 } |
| 400 | 401 |
| 401 void GraphicsContext::beginTransparencyLayer(float opacity) | 402 void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bou nds) |
| 402 { | 403 { |
| 403 if (paintingDisabled()) | 404 if (paintingDisabled()) |
| 404 return; | 405 return; |
| 405 | 406 |
| 406 // We need the "alpha" layer flag here because the base layer is opaque | 407 // We need the "alpha" layer flag here because the base layer is opaque |
| 407 // (the surface of the page) but layers on top may have transparent parts. | 408 // (the surface of the page) but layers on top may have transparent parts. |
| 408 // Without explicitly setting the alpha flag, the layer will inherit the | 409 // Without explicitly setting the alpha flag, the layer will inherit the |
| 409 // opaque setting of the base and some things won't work properly. | 410 // opaque setting of the base and some things won't work properly. |
| 410 SkCanvas::SaveFlags saveFlags = static_cast<SkCanvas::SaveFlags>(SkCanvas::k HasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag); | 411 SkCanvas::SaveFlags saveFlags = static_cast<SkCanvas::SaveFlags>(SkCanvas::k HasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag); |
| 411 | 412 |
| 412 SkPaint layerPaint; | 413 SkPaint layerPaint; |
| 413 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255)); | 414 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255)); |
| 414 layerPaint.setXfermodeMode(m_state->m_xferMode); | 415 layerPaint.setXfermodeMode(m_state->m_xferMode); |
| 415 | 416 |
| 416 saveLayer(0, &layerPaint, saveFlags); | 417 SkRect* skBounds = 0; |
| 418 SkRect skBoundsStorage; | |
| 419 | |
| 420 if (bounds) { | |
| 421 skBoundsStorage = WebCoreFloatRectToSKRect(*bounds); | |
| 422 skBounds = &skBoundsStorage; | |
| 423 } | |
| 424 | |
| 425 saveLayer(skBounds, &layerPaint, saveFlags); | |
|
Stephen White
2013/08/28 20:16:12
As an alternative, this could be:
if (bounds)
f(malita)
2013/08/28 20:24:04
It does look cleaner, will do.
| |
| 417 | 426 |
| 418 #if !ASSERT_DISABLED | 427 #if !ASSERT_DISABLED |
| 419 ++m_transparencyCount; | 428 ++m_layerCount; |
| 420 #endif | 429 #endif |
| 421 } | 430 } |
| 422 | 431 |
| 423 void GraphicsContext::endTransparencyLayer() | 432 void GraphicsContext::beginMaskedLayer(const FloatRect& bounds, MaskType maskTyp e) |
| 433 { | |
| 434 if (paintingDisabled()) | |
| 435 return; | |
| 436 | |
| 437 SkPaint layerPaint; | |
| 438 layerPaint.setXfermode(maskType == AlphaMaskType | |
| 439 ? SkXfermode::Create(SkXfermode::kSrcIn_Mode) | |
| 440 : SkLumaMaskXfermode::Create(SkXfermode::kSrcIn_Mode)); | |
| 441 | |
| 442 SkRect skBounds = WebCoreFloatRectToSKRect(bounds); | |
| 443 saveLayer(&skBounds, &layerPaint); | |
| 444 | |
| 445 #if !ASSERT_DISABLED | |
| 446 ++m_layerCount; | |
| 447 #endif | |
| 448 } | |
| 449 | |
| 450 void GraphicsContext::endLayer() | |
|
Stephen White
2013/08/28 20:16:12
I guess the name change is this because endLayer()
| |
| 424 { | 451 { |
| 425 if (paintingDisabled()) | 452 if (paintingDisabled()) |
| 426 return; | 453 return; |
| 427 | 454 |
| 428 restoreLayer(); | 455 restoreLayer(); |
| 429 | 456 |
| 430 ASSERT(m_transparencyCount > 0); | 457 ASSERT(m_layerCount > 0); |
| 431 #if !ASSERT_DISABLED | 458 #if !ASSERT_DISABLED |
| 432 --m_transparencyCount; | 459 --m_layerCount; |
| 433 #endif | 460 #endif |
| 434 } | 461 } |
| 435 | 462 |
| 436 void GraphicsContext::clipToImageBuffer(const ImageBuffer* imageBuffer, const Fl oatRect& rect) | |
| 437 { | |
| 438 if (paintingDisabled()) | |
| 439 return; | |
| 440 | |
| 441 SkRect bounds = WebCoreFloatRectToSKRect(rect); | |
| 442 | |
| 443 if (imageBuffer->internalSize().isEmpty()) { | |
| 444 clipRect(bounds); | |
| 445 return; | |
| 446 } | |
| 447 | |
| 448 // Skia doesn't support clipping to an image, so we create a layer. The next | |
| 449 // time restore is invoked the layer and |imageBuffer| are combined to | |
| 450 // create the resulting image. | |
| 451 m_state->m_clip = bounds; | |
| 452 | |
| 453 // Get the absolute coordinates of the stored clipping rectangle to make it | |
| 454 // independent of any transform changes. | |
| 455 getTotalMatrix().mapRect(&m_state->m_clip); | |
| 456 | |
| 457 SkCanvas::SaveFlags saveFlags = static_cast<SkCanvas::SaveFlags>(SkCanvas::k HasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag); | |
| 458 saveLayer(&bounds, 0, saveFlags); | |
| 459 | |
| 460 const SkBitmap* bitmap = imageBuffer->context()->bitmap(); | |
| 461 | |
| 462 if (m_trackOpaqueRegion) { | |
| 463 SkRect opaqueRect = bitmap->isOpaque() ? m_state->m_clip : SkRect::MakeE mpty(); | |
| 464 m_opaqueRegion.setImageMask(opaqueRect); | |
| 465 } | |
| 466 | |
| 467 // Copy off the image as |imageBuffer| may be deleted before restore is invo ked. | |
| 468 if (bitmap->isImmutable()) | |
| 469 m_state->m_imageBufferClip = *bitmap; | |
| 470 else { | |
| 471 // We need to make a deep-copy of the pixels themselves, so they don't | |
| 472 // change on us between now and when we want to apply them in restore() | |
| 473 bitmap->copyTo(&m_state->m_imageBufferClip, SkBitmap::kARGB_8888_Config) ; | |
| 474 } | |
| 475 } | |
| 476 | |
| 477 void GraphicsContext::setupPaintForFilling(SkPaint* paint) const | 463 void GraphicsContext::setupPaintForFilling(SkPaint* paint) const |
| 478 { | 464 { |
| 479 if (paintingDisabled()) | 465 if (paintingDisabled()) |
| 480 return; | 466 return; |
| 481 | 467 |
| 482 setupPaintCommon(paint); | 468 setupPaintCommon(paint); |
| 483 | 469 |
| 484 setupShader(paint, m_state->m_fillGradient.get(), m_state->m_fillPattern.get (), m_state->m_fillColor.rgb()); | 470 setupShader(paint, m_state->m_fillGradient.get(), m_state->m_fillPattern.get (), m_state->m_fillColor.rgb()); |
| 485 } | 471 } |
| 486 | 472 |
| (...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1712 #if defined(SK_DEBUG) | 1698 #if defined(SK_DEBUG) |
| 1713 { | 1699 { |
| 1714 SkPaint defaultPaint; | 1700 SkPaint defaultPaint; |
| 1715 SkASSERT(*paint == defaultPaint); | 1701 SkASSERT(*paint == defaultPaint); |
| 1716 } | 1702 } |
| 1717 #endif | 1703 #endif |
| 1718 | 1704 |
| 1719 paint->setAntiAlias(m_state->m_shouldAntialias); | 1705 paint->setAntiAlias(m_state->m_shouldAntialias); |
| 1720 paint->setXfermodeMode(m_state->m_xferMode); | 1706 paint->setXfermodeMode(m_state->m_xferMode); |
| 1721 paint->setLooper(m_state->m_looper.get()); | 1707 paint->setLooper(m_state->m_looper.get()); |
| 1708 paint->setColorFilter(m_state->m_colorFilter.get()); | |
| 1722 } | 1709 } |
| 1723 | 1710 |
| 1724 void GraphicsContext::drawOuterPath(const SkPath& path, SkPaint& paint, int widt h) | 1711 void GraphicsContext::drawOuterPath(const SkPath& path, SkPaint& paint, int widt h) |
| 1725 { | 1712 { |
| 1726 #if OS(DARWIN) | 1713 #if OS(DARWIN) |
| 1727 paint.setAlpha(64); | 1714 paint.setAlpha(64); |
| 1728 paint.setStrokeWidth(width); | 1715 paint.setStrokeWidth(width); |
| 1729 paint.setPathEffect(new SkCornerPathEffect((width - 1) * 0.5f))->unref(); | 1716 paint.setPathEffect(new SkCornerPathEffect((width - 1) * 0.5f))->unref(); |
| 1730 #else | 1717 #else |
| 1731 paint.setStrokeWidth(1); | 1718 paint.setStrokeWidth(1); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1863 } else if (pat) { | 1850 } else if (pat) { |
| 1864 shader = pat->shader(); | 1851 shader = pat->shader(); |
| 1865 color = SK_ColorBLACK; | 1852 color = SK_ColorBLACK; |
| 1866 paint->setFilterBitmap(imageInterpolationQuality() != InterpolationNone) ; | 1853 paint->setFilterBitmap(imageInterpolationQuality() != InterpolationNone) ; |
| 1867 } | 1854 } |
| 1868 | 1855 |
| 1869 paint->setColor(m_state->applyAlpha(color)); | 1856 paint->setColor(m_state->applyAlpha(color)); |
| 1870 paint->setShader(shader.get()); | 1857 paint->setShader(shader.get()); |
| 1871 } | 1858 } |
| 1872 | 1859 |
| 1873 | |
| 1874 void GraphicsContext::applyClipFromImage(const SkRect& rect, const SkBitmap& ima geBuffer) | |
| 1875 { | |
| 1876 if (paintingDisabled()) | |
| 1877 return; | |
| 1878 | |
| 1879 // NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we | |
| 1880 // only look at the alpha when compositing. I'm not 100% sure this is what W ebKit expects for image clipping. | |
| 1881 SkPaint paint; | |
| 1882 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | |
| 1883 realizeSave(SkCanvas::kMatrixClip_SaveFlag); | |
| 1884 m_canvas->save(SkCanvas::kMatrix_SaveFlag); | |
| 1885 m_canvas->resetMatrix(); | |
| 1886 m_canvas->drawBitmapRect(imageBuffer, 0, rect, &paint); | |
| 1887 m_canvas->restore(); | |
| 1888 } | |
| 1889 | |
| 1890 void GraphicsContext::didDrawTextInRect(const SkRect& textRect) | 1860 void GraphicsContext::didDrawTextInRect(const SkRect& textRect) |
| 1891 { | 1861 { |
| 1892 if (m_trackTextRegion) { | 1862 if (m_trackTextRegion) { |
| 1893 TRACE_EVENT0("skia", "PlatformContextSkia::trackTextRegion"); | 1863 TRACE_EVENT0("skia", "PlatformContextSkia::trackTextRegion"); |
| 1894 m_textRegion.join(textRect); | 1864 m_textRegion.join(textRect); |
| 1895 } | 1865 } |
| 1896 } | 1866 } |
| 1897 | 1867 |
| 1898 } | 1868 } |
| OLD | NEW |