| 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..5f04765aca098135d7a192fe40d54aaa5e83bf28 100644
|
| --- a/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp
|
| +++ b/third_party/WebKit/Source/platform/testing/PictureMatchers.cpp
|
| @@ -16,81 +16,165 @@ 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 {
|
| + m_saveCount++;
|
| + unsigned layerAlpha = static_cast<unsigned>(rec.fPaint->getAlpha());
|
| + if (layerAlpha < 255) {
|
| + DCHECK_EQ(m_alphaSaveLayerCount, -1);
|
| + m_alphaSaveLayerCount = m_saveCount;
|
| + m_alpha = layerAlpha;
|
| + }
|
| + return SkCanvas::getSaveLayerStrategy(rec);
|
| + }
|
| +
|
| + void willSave() override {
|
| + m_saveCount++;
|
| + SkCanvas::willSave();
|
| + }
|
| +
|
| + void willRestore() override {
|
| + DCHECK_GT(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_alphaSaveLayerCount = -1;
|
| + }
|
| + 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
|
|
|