Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/testing/PictureMatchers.h" | 5 #include "platform/testing/PictureMatchers.h" |
| 6 | 6 |
| 7 #include "base/debug/stack_trace.h" | |
|
pdr.
2016/12/22 19:46:26
Nit: remove
| |
| 8 | |
| 7 #include "platform/geometry/FloatQuad.h" | 9 #include "platform/geometry/FloatQuad.h" |
| 8 #include "platform/geometry/FloatRect.h" | 10 #include "platform/geometry/FloatRect.h" |
| 9 #include "third_party/skia/include/core/SkCanvas.h" | 11 #include "third_party/skia/include/core/SkCanvas.h" |
| 10 #include "third_party/skia/include/core/SkPicture.h" | 12 #include "third_party/skia/include/core/SkPicture.h" |
| 11 #include "wtf/Vector.h" | 13 #include "wtf/Vector.h" |
| 12 #include "wtf/text/WTFString.h" | 14 #include "wtf/text/WTFString.h" |
| 13 #include <utility> | 15 #include <utility> |
| 14 | 16 |
| 15 namespace blink { | 17 namespace blink { |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 21 struct QuadWithColor { | |
| 22 FloatQuad quad; | |
| 23 Color color; | |
| 24 }; | |
| 25 | |
| 19 class DrawsRectangleCanvas : public SkCanvas { | 26 class DrawsRectangleCanvas : public SkCanvas { |
| 20 public: | 27 public: |
| 21 DrawsRectangleCanvas() : SkCanvas(800, 600) {} | 28 DrawsRectangleCanvas() |
| 22 const Vector<std::pair<FloatQuad, Color>>& quads() const { return m_quads; } | 29 : SkCanvas(800, 600), |
| 30 m_saveCount(0), | |
| 31 m_alpha(255), | |
| 32 m_alphaSaveLayerCount(-1) {} | |
| 33 const Vector<QuadWithColor>& quadsWithColor() const { return m_quads; } | |
| 34 | |
| 23 void onDrawRect(const SkRect& rect, const SkPaint& paint) override { | 35 void onDrawRect(const SkRect& rect, const SkPaint& paint) override { |
| 36 SkRect clippedRect(rect); | |
| 37 for (Vector<ClipAndIndex>::const_reverse_iterator clip = m_clips.rbegin(); | |
| 38 clip != m_clips.rend(); clip++) { | |
| 39 if (SkRect::Intersects(rect, clip->rect)) | |
| 40 CHECK(clippedRect.intersect(clip->rect)); | |
| 41 } | |
| 24 SkPoint quad[4]; | 42 SkPoint quad[4]; |
| 25 getTotalMatrix().mapRectToQuad(quad, rect); | 43 getTotalMatrix().mapRectToQuad(quad, clippedRect); |
| 26 FloatQuad floatQuad(quad); | 44 QuadWithColor quadWithColor; |
| 27 m_quads.append(std::make_pair(floatQuad, Color(paint.getColor()))); | 45 quadWithColor.quad = FloatQuad(quad); |
| 28 SkCanvas::onDrawRect(rect, paint); | 46 |
| 47 unsigned paintAlpha = static_cast<unsigned>(paint.getAlpha()); | |
| 48 SkPaint paintWithAlpha(paint); | |
| 49 paintWithAlpha.setAlpha(static_cast<U8CPU>(m_alpha * paintAlpha / 255)); | |
| 50 quadWithColor.color = Color(paintWithAlpha.getColor()); | |
| 51 m_quads.append(quadWithColor); | |
| 52 SkCanvas::onDrawRect(clippedRect, paint); | |
| 29 } | 53 } |
| 30 | 54 |
| 55 SkCanvas::SaveLayerStrategy getSaveLayerStrategy( | |
| 56 const SaveLayerRec& rec) override { | |
| 57 DCHECK(m_alphaSaveLayerCount == -1); | |
| 58 m_alpha = static_cast<unsigned>(rec.fPaint->getAlpha()); | |
| 59 m_saveCount++; | |
| 60 if (m_alpha < 255) | |
| 61 m_alphaSaveLayerCount = m_saveCount; | |
| 62 return SkCanvas::getSaveLayerStrategy(rec); | |
| 63 } | |
| 64 | |
| 65 void willSave() override { | |
| 66 m_saveCount++; | |
| 67 SkCanvas::willSave(); | |
| 68 } | |
| 69 | |
| 70 void willRestore() override { | |
| 71 DCHECK(m_saveCount > 0); | |
| 72 if (m_clips.size() && m_saveCount == m_clips.back().saveCount) | |
| 73 m_clips.pop_back(); | |
| 74 if (m_alphaSaveLayerCount == m_saveCount) | |
| 75 m_alpha = 255; | |
| 76 m_saveCount--; | |
| 77 SkCanvas::willRestore(); | |
| 78 } | |
| 79 | |
| 80 void onClipRect(const SkRect& rect, | |
| 81 SkClipOp op, | |
| 82 ClipEdgeStyle style) override { | |
| 83 ClipAndIndex clipStruct; | |
| 84 clipStruct.rect = rect; | |
| 85 clipStruct.saveCount = m_saveCount; | |
| 86 m_clips.push_back(clipStruct); | |
| 87 SkCanvas::onClipRect(rect, op, style); | |
| 88 } | |
| 89 | |
| 90 struct ClipAndIndex { | |
| 91 SkRect rect; | |
| 92 int saveCount; | |
| 93 }; | |
| 94 | |
| 31 private: | 95 private: |
| 32 Vector<std::pair<FloatQuad, Color>> m_quads; | 96 Vector<QuadWithColor> m_quads; |
| 97 Vector<ClipAndIndex> m_clips; | |
| 98 int m_saveCount; | |
| 99 unsigned m_alpha; | |
| 100 int m_alphaSaveLayerCount; | |
| 33 }; | 101 }; |
| 34 | 102 |
| 35 class DrawsRectangleMatcher | 103 class DrawsRectanglesMatcher |
| 36 : public ::testing::MatcherInterface<const SkPicture&> { | 104 : public ::testing::MatcherInterface<const SkPicture&> { |
| 37 public: | 105 public: |
| 38 DrawsRectangleMatcher(const FloatRect& rect, Color color) | 106 DrawsRectanglesMatcher(const Vector<RectWithColor>& rectsWithColor) |
| 39 : m_rect(rect), m_color(color) {} | 107 : m_rectsWithColor(rectsWithColor) {} |
| 40 | 108 |
| 41 bool MatchAndExplain( | 109 bool MatchAndExplain( |
| 42 const SkPicture& picture, | 110 const SkPicture& picture, |
| 43 ::testing::MatchResultListener* listener) const override { | 111 ::testing::MatchResultListener* listener) const override { |
| 44 DrawsRectangleCanvas canvas; | 112 DrawsRectangleCanvas canvas; |
| 45 picture.playback(&canvas); | 113 picture.playback(&canvas); |
| 46 const auto& quads = canvas.quads(); | 114 const auto& quads = canvas.quadsWithColor(); |
| 47 | 115 if (quads.size() != m_rectsWithColor.size()) { |
| 48 if (quads.size() != 1) { | |
| 49 *listener << "which draws " << quads.size() << " quads"; | 116 *listener << "which draws " << quads.size() << " quads"; |
| 50 return false; | 117 return false; |
| 51 } | 118 } |
| 52 | 119 |
| 53 const FloatQuad& quad = quads[0].first; | 120 for (unsigned index = 0; index < quads.size(); index++) { |
| 54 if (!quad.isRectilinear()) { | 121 const auto& quadWithColor = quads[index]; |
| 55 if (listener->IsInterested()) { | 122 const auto& rectWithColor = m_rectsWithColor[index]; |
| 56 *listener << "which draws "; | 123 if (!quadWithColor.quad.isRectilinear()) { |
| 57 PrintTo(quad, listener->stream()); | 124 if (listener->IsInterested()) { |
| 58 *listener << " with color " | 125 *listener << "at index " << index << " which draws "; |
| 59 << quads[0].second.serialized().ascii().data(); | 126 PrintTo(quadWithColor.quad, listener->stream()); |
| 127 *listener << " with color " | |
| 128 << quadWithColor.color.serialized().ascii().data() << "\n"; | |
| 129 } | |
| 130 return false; | |
| 60 } | 131 } |
| 61 return false; | |
| 62 } | |
| 63 | 132 |
| 64 const FloatRect& rect = quad.boundingBox(); | 133 const FloatRect& rect = quadWithColor.quad.boundingBox(); |
| 65 if (rect != m_rect || quads[0].second != m_color) { | 134 if (rect != rectWithColor.rect || |
| 66 if (listener->IsInterested()) { | 135 quadWithColor.color != rectWithColor.color) { |
| 67 *listener << "which draws "; | 136 if (listener->IsInterested()) { |
| 68 PrintTo(rect, listener->stream()); | 137 *listener << "at index " << index << " which draws "; |
| 69 *listener << " with color " | 138 PrintTo(rect, listener->stream()); |
| 70 << quads[0].second.serialized().ascii().data(); | 139 *listener << " with color " |
| 140 << quadWithColor.color.serialized().ascii().data() << "\n"; | |
| 141 } | |
| 142 return false; | |
| 71 } | 143 } |
| 72 return false; | |
| 73 } | 144 } |
| 74 | 145 |
| 75 return true; | 146 return true; |
| 76 } | 147 } |
| 77 | 148 |
| 78 void DescribeTo(::std::ostream* os) const override { | 149 void DescribeTo(::std::ostream* os) const override { |
| 79 *os << "draws "; | 150 *os << "\n"; |
| 80 PrintTo(m_rect, os); | 151 for (unsigned index = 0; index < m_rectsWithColor.size(); index++) { |
| 81 *os << " with color " << m_color.serialized().ascii().data(); | 152 const auto& rectWithColor = m_rectsWithColor[index]; |
| 153 *os << "at index " << index << " rect draws "; | |
| 154 PrintTo(rectWithColor.rect, os); | |
| 155 *os << " with color " << rectWithColor.color.serialized().ascii().data() | |
| 156 << "\n"; | |
| 157 } | |
| 82 } | 158 } |
| 83 | 159 |
| 84 private: | 160 private: |
| 85 const FloatRect m_rect; | 161 const Vector<RectWithColor> m_rectsWithColor; |
| 86 const Color m_color; | |
| 87 }; | 162 }; |
| 88 | 163 |
| 89 } // namespace | 164 } // namespace |
| 90 | 165 |
| 91 ::testing::Matcher<const SkPicture&> drawsRectangle(const FloatRect& rect, | 166 ::testing::Matcher<const SkPicture&> drawsRectangle(const FloatRect& rect, |
| 92 Color color) { | 167 Color color) { |
| 93 return ::testing::MakeMatcher(new DrawsRectangleMatcher(rect, color)); | 168 Vector<RectWithColor> rectsWithColor; |
| 169 rectsWithColor.push_back(RectWithColor(rect, color)); | |
| 170 return ::testing::MakeMatcher(new DrawsRectanglesMatcher(rectsWithColor)); | |
| 171 } | |
| 172 | |
| 173 ::testing::Matcher<const SkPicture&> drawsRectangles( | |
| 174 const Vector<RectWithColor>& rectsWithColor) { | |
| 175 return ::testing::MakeMatcher(new DrawsRectanglesMatcher(rectsWithColor)); | |
| 94 } | 176 } |
| 95 | 177 |
| 96 } // namespace blink | 178 } // namespace blink |
| OLD | NEW |