Chromium Code Reviews| Index: third_party/WebKit/Source/platform/testing/PictureMatchers.cpp |
| diff --git a/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp b/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp |
| index 1324f7bac63bc61bf23d0f7f7c59562c5a8fd855..41e095a9b8c108a8daf138d7202e62308028bfa2 100644 |
| --- a/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp |
| +++ b/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp |
| @@ -4,6 +4,8 @@ |
| #include "platform/testing/PictureMatchers.h" |
| +#include "base/debug/stack_trace.h" |
|
pdr.
2016/12/22 19:46:26
Nit: remove
|
| + |
| #include "platform/geometry/FloatQuad.h" |
| #include "platform/geometry/FloatRect.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| @@ -16,81 +18,161 @@ namespace blink { |
| namespace { |
| +struct QuadWithColor { |
| + FloatQuad quad; |
| + Color color; |
| +}; |
| + |
| class DrawsRectangleCanvas : public SkCanvas { |
| public: |
| - DrawsRectangleCanvas() : SkCanvas(800, 600) {} |
| - const Vector<std::pair<FloatQuad, Color>>& quads() const { return m_quads; } |
| + DrawsRectangleCanvas() |
| + : SkCanvas(800, 600), |
| + m_saveCount(0), |
| + m_alpha(255), |
| + m_alphaSaveLayerCount(-1) {} |
| + const Vector<QuadWithColor>& quadsWithColor() const { return m_quads; } |
| + |
| void onDrawRect(const SkRect& rect, const SkPaint& paint) override { |
| + SkRect clippedRect(rect); |
| + for (Vector<ClipAndIndex>::const_reverse_iterator clip = m_clips.rbegin(); |
| + clip != m_clips.rend(); clip++) { |
| + if (SkRect::Intersects(rect, clip->rect)) |
| + CHECK(clippedRect.intersect(clip->rect)); |
| + } |
| SkPoint quad[4]; |
| - getTotalMatrix().mapRectToQuad(quad, rect); |
| - FloatQuad floatQuad(quad); |
| - m_quads.append(std::make_pair(floatQuad, Color(paint.getColor()))); |
| - SkCanvas::onDrawRect(rect, paint); |
| + getTotalMatrix().mapRectToQuad(quad, clippedRect); |
| + QuadWithColor quadWithColor; |
| + quadWithColor.quad = FloatQuad(quad); |
| + |
| + unsigned paintAlpha = static_cast<unsigned>(paint.getAlpha()); |
| + SkPaint paintWithAlpha(paint); |
| + paintWithAlpha.setAlpha(static_cast<U8CPU>(m_alpha * paintAlpha / 255)); |
| + quadWithColor.color = Color(paintWithAlpha.getColor()); |
| + m_quads.append(quadWithColor); |
| + SkCanvas::onDrawRect(clippedRect, paint); |
| + } |
| + |
| + SkCanvas::SaveLayerStrategy getSaveLayerStrategy( |
| + const SaveLayerRec& rec) override { |
| + DCHECK(m_alphaSaveLayerCount == -1); |
| + m_alpha = static_cast<unsigned>(rec.fPaint->getAlpha()); |
| + m_saveCount++; |
| + if (m_alpha < 255) |
| + m_alphaSaveLayerCount = m_saveCount; |
| + return SkCanvas::getSaveLayerStrategy(rec); |
| + } |
| + |
| + void willSave() override { |
| + m_saveCount++; |
| + SkCanvas::willSave(); |
| + } |
| + |
| + void willRestore() override { |
| + DCHECK(m_saveCount > 0); |
| + if (m_clips.size() && m_saveCount == m_clips.back().saveCount) |
| + m_clips.pop_back(); |
| + if (m_alphaSaveLayerCount == m_saveCount) |
| + m_alpha = 255; |
| + m_saveCount--; |
| + SkCanvas::willRestore(); |
| } |
| + void onClipRect(const SkRect& rect, |
| + SkClipOp op, |
| + ClipEdgeStyle style) override { |
| + ClipAndIndex clipStruct; |
| + clipStruct.rect = rect; |
| + clipStruct.saveCount = m_saveCount; |
| + m_clips.push_back(clipStruct); |
| + SkCanvas::onClipRect(rect, op, style); |
| + } |
| + |
| + struct ClipAndIndex { |
| + SkRect rect; |
| + int saveCount; |
| + }; |
| + |
| private: |
| - Vector<std::pair<FloatQuad, Color>> m_quads; |
| + Vector<QuadWithColor> m_quads; |
| + Vector<ClipAndIndex> m_clips; |
| + int m_saveCount; |
| + unsigned m_alpha; |
| + int m_alphaSaveLayerCount; |
| }; |
| -class DrawsRectangleMatcher |
| +class DrawsRectanglesMatcher |
| : public ::testing::MatcherInterface<const SkPicture&> { |
| public: |
| - DrawsRectangleMatcher(const FloatRect& rect, Color color) |
| - : m_rect(rect), m_color(color) {} |
| + DrawsRectanglesMatcher(const Vector<RectWithColor>& rectsWithColor) |
| + : m_rectsWithColor(rectsWithColor) {} |
| bool MatchAndExplain( |
| const SkPicture& picture, |
| ::testing::MatchResultListener* listener) const override { |
| DrawsRectangleCanvas canvas; |
| picture.playback(&canvas); |
| - const auto& quads = canvas.quads(); |
| - |
| - if (quads.size() != 1) { |
| + const auto& quads = canvas.quadsWithColor(); |
| + if (quads.size() != m_rectsWithColor.size()) { |
| *listener << "which draws " << quads.size() << " quads"; |
| return false; |
| } |
| - const FloatQuad& quad = quads[0].first; |
| - if (!quad.isRectilinear()) { |
| - if (listener->IsInterested()) { |
| - *listener << "which draws "; |
| - PrintTo(quad, listener->stream()); |
| - *listener << " with color " |
| - << quads[0].second.serialized().ascii().data(); |
| + for (unsigned index = 0; index < quads.size(); index++) { |
| + const auto& quadWithColor = quads[index]; |
| + const auto& rectWithColor = m_rectsWithColor[index]; |
| + if (!quadWithColor.quad.isRectilinear()) { |
| + if (listener->IsInterested()) { |
| + *listener << "at index " << index << " which draws "; |
| + PrintTo(quadWithColor.quad, listener->stream()); |
| + *listener << " with color " |
| + << quadWithColor.color.serialized().ascii().data() << "\n"; |
| + } |
| + return false; |
| } |
| - return false; |
| - } |
| - const FloatRect& rect = quad.boundingBox(); |
| - if (rect != m_rect || quads[0].second != m_color) { |
| - if (listener->IsInterested()) { |
| - *listener << "which draws "; |
| - PrintTo(rect, listener->stream()); |
| - *listener << " with color " |
| - << quads[0].second.serialized().ascii().data(); |
| + const FloatRect& rect = quadWithColor.quad.boundingBox(); |
| + if (rect != rectWithColor.rect || |
| + quadWithColor.color != rectWithColor.color) { |
| + if (listener->IsInterested()) { |
| + *listener << "at index " << index << " which draws "; |
| + PrintTo(rect, listener->stream()); |
| + *listener << " with color " |
| + << quadWithColor.color.serialized().ascii().data() << "\n"; |
| + } |
| + return false; |
| } |
| - return false; |
| } |
| return true; |
| } |
| void DescribeTo(::std::ostream* os) const override { |
| - *os << "draws "; |
| - PrintTo(m_rect, os); |
| - *os << " with color " << m_color.serialized().ascii().data(); |
| + *os << "\n"; |
| + for (unsigned index = 0; index < m_rectsWithColor.size(); index++) { |
| + const auto& rectWithColor = m_rectsWithColor[index]; |
| + *os << "at index " << index << " rect draws "; |
| + PrintTo(rectWithColor.rect, os); |
| + *os << " with color " << rectWithColor.color.serialized().ascii().data() |
| + << "\n"; |
| + } |
| } |
| private: |
| - const FloatRect m_rect; |
| - const Color m_color; |
| + const Vector<RectWithColor> m_rectsWithColor; |
| }; |
| } // namespace |
| ::testing::Matcher<const SkPicture&> drawsRectangle(const FloatRect& rect, |
| Color color) { |
| - return ::testing::MakeMatcher(new DrawsRectangleMatcher(rect, color)); |
| + Vector<RectWithColor> rectsWithColor; |
| + rectsWithColor.push_back(RectWithColor(rect, color)); |
| + return ::testing::MakeMatcher(new DrawsRectanglesMatcher(rectsWithColor)); |
| +} |
| + |
| +::testing::Matcher<const SkPicture&> drawsRectangles( |
| + const Vector<RectWithColor>& rectsWithColor) { |
| + return ::testing::MakeMatcher(new DrawsRectanglesMatcher(rectsWithColor)); |
| } |
| } // namespace blink |