Index: Source/platform/graphics/GraphicsContext.cpp |
diff --git a/Source/platform/graphics/GraphicsContext.cpp b/Source/platform/graphics/GraphicsContext.cpp |
index c75c0cf53327cf7d8f54e8286c2eb75ceeb637f3..d40eff4a59e3c033a37fbb437f088f6032dae257 100644 |
--- a/Source/platform/graphics/GraphicsContext.cpp |
+++ b/Source/platform/graphics/GraphicsContext.cpp |
@@ -88,7 +88,6 @@ GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr |
, m_annotationMode(0) |
#if ENABLE(ASSERT) |
, m_annotationCount(0) |
- , m_layerCount(0) |
, m_disableDestructionChecks(false) |
#endif |
, m_disabledState(disableContextOrPainting) |
@@ -114,7 +113,7 @@ GraphicsContext::~GraphicsContext() |
ASSERT(!m_paintStateIndex); |
ASSERT(!m_paintState->saveCount()); |
ASSERT(!m_annotationCount); |
- ASSERT(!m_layerCount); |
+ ASSERT(m_clipStackPointersOfLayerStack.isEmpty()); |
ASSERT(m_recordingStateStack.isEmpty()); |
ASSERT(!saveCount()); |
} |
@@ -182,6 +181,18 @@ unsigned GraphicsContext::saveCount() const |
} |
#endif |
+static unsigned getClipStackPointer(const SkCanvas* canvas) |
+{ |
+ SkClipStack::B2TIter iter(*canvas->getClipStack()); |
+ const SkClipStack::Element* element = iter.next(); |
+ unsigned stackPointer = 0; |
+ while (element) { |
+ stackPointer++; |
+ element = iter.next(); |
+ } |
+ return stackPointer; |
+} |
+ |
void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) |
{ |
if (contextDisabled()) |
@@ -192,6 +203,7 @@ void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) |
m_canvas->saveLayer(bounds, paint); |
if (regionTrackingEnabled()) |
m_trackedRegion.pushCanvasLayer(paint); |
+ m_clipStackPointersOfLayerStack.append(getClipStackPointer(m_canvas)); |
} |
void GraphicsContext::restoreLayer() |
@@ -200,10 +212,48 @@ void GraphicsContext::restoreLayer() |
return; |
ASSERT(m_canvas); |
+ ASSERT(m_clipStackPointersOfLayerStack.size() > 0); |
+ |
+ // beginLayer()/endLayer() must not expose states stacking mechanism. |
+ // Currently SkCanvas::save()/restore() in GraphicsContext affected only ctm and clip. |
+ SkMatrix currentCTM = m_canvas->getTotalMatrix(); |
+ SkClipStack currentSkClipStack(*m_canvas->getClipStack()); |
Justin Novosad
2014/10/16 17:51:58
Seems unfortunate to duplicate the entire clip sta
|
m_canvas->restore(); |
if (regionTrackingEnabled()) |
m_trackedRegion.popCanvasLayer(this); |
+ |
+ // SkCanvas::clipXXX() transforms a rect/path by CTM. |
+ m_canvas->resetMatrix(); |
+ |
+ static const SkRect kEmptyRect = { 0, 0, 0, 0 }; |
+ SkClipStack::B2TIter iter(currentSkClipStack); |
+ const SkClipStack::Element* element = nullptr; |
+ unsigned stackPointer = m_clipStackPointersOfLayerStack.last(); |
+ m_clipStackPointersOfLayerStack.removeLast(); |
+ for (unsigned i = 0; i < stackPointer; i++) { |
+ iter.next(); |
+ } |
+ element = iter.next(); |
+ while (element) { |
+ switch (element->getType()) { |
+ case SkClipStack::Element::kPath_Type: |
+ m_canvas->clipPath(element->getPath(), element->getOp(), element->isAA()); |
+ break; |
+ case SkClipStack::Element::kRRect_Type: |
+ m_canvas->clipRRect(element->getRRect(), element->getOp(), element->isAA()); |
+ break; |
+ case SkClipStack::Element::kRect_Type: |
+ m_canvas->clipRect(element->getRect(), element->getOp(), element->isAA()); |
+ break; |
+ case SkClipStack::Element::kEmpty_Type: |
+ m_canvas->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false); |
+ break; |
+ } |
+ element = iter.next(); |
+ } |
+ |
+ m_canvas->setMatrix(currentCTM); |
} |
dshwang
2014/10/16 15:58:20
Feel like using implementation detail of skia, but
Justin Novosad
2014/10/16 17:51:58
I agree. reverse engineering the state seems unfor
|
void GraphicsContext::beginAnnotation(const AnnotationList& annotations) |
@@ -462,10 +512,6 @@ void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const Floa |
} else { |
saveLayer(0, &layerPaint); |
} |
- |
-#if ENABLE(ASSERT) |
- ++m_layerCount; |
-#endif |
} |
void GraphicsContext::endLayer() |
@@ -474,11 +520,6 @@ void GraphicsContext::endLayer() |
return; |
restoreLayer(); |
- |
- ASSERT(m_layerCount > 0); |
-#if ENABLE(ASSERT) |
- --m_layerCount; |
-#endif |
} |
void GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFlags) |