/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"
#ifdef SK_XML

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkShader.h"
#include "include/core/SkStream.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTileMode.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/private/base/SkTo.h"
#include "include/svg/SkSVGCanvas.h"
#include "include/utils/SkParse.h"
#include "src/shaders/SkImageShader.h"
#include "src/svg/SkSVGDevice.h"
#include "src/xml/SkDOM.h"
#include "src/xml/SkXMLWriter.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
#include "include/encode/SkPngRustEncoder.h"
#else
#include "include/encode/SkPngEncoder.h"
#endif  // defined(SK_CODEC_ENCODES_PNG_WITH_RUST)

#include <string>

using namespace skia_private;

#define ABORT_TEST(r, cond, ...)                                   \
    do {                                                           \
        if (cond) {                                                \
            REPORT_FAILURE(r, #cond, SkStringPrintf(__VA_ARGS__)); \
            return;                                                \
        }                                                          \
    } while (0)


static std::unique_ptr<SkCanvas> MakeDOMCanvas(SkDOM* dom, uint32_t flags = 0) {
    SkSVGCanvas::Options opts;
    opts.flags = static_cast<SkSVGCanvas::Flags>(flags);
    opts.pngEncoder = [](SkWStream* dst, const SkPixmap& src) {
#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
        return SkPngRustEncoder::Encode(dst, src, {});
#else
        return SkPngEncoder::Encode(dst, src, {});
#endif // defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
    };
    auto svgDevice = SkSVGDevice::Make(SkISize::Make(100, 100),
                                       std::make_unique<SkXMLParserWriter>(dom->beginParsing()),
                                       opts);
    return svgDevice ? std::make_unique<SkCanvas>(svgDevice)
                     : nullptr;
}

namespace {


void check_text_node(skiatest::Reporter* reporter,
                     const SkDOM& dom,
                     const SkDOM::Node* root,
                     const SkPoint& offset,
                     unsigned scalarsPerPos,
                     const char* txt,
                     const char* expected) {
    if (root == nullptr) {
        ERRORF(reporter, "root element not found.");
        return;
    }

    const SkDOM::Node* textElem = dom.getFirstChild(root, "text");
    if (textElem == nullptr) {
        ERRORF(reporter, "<text> element not found.");
        return;
    }
    REPORTER_ASSERT(reporter, dom.getType(textElem) == SkDOM::kElement_Type);

    const SkDOM::Node* textNode= dom.getFirstChild(textElem);
    REPORTER_ASSERT(reporter, textNode != nullptr);
    if (textNode != nullptr) {
        REPORTER_ASSERT(reporter, dom.getType(textNode) == SkDOM::kText_Type);
        REPORTER_ASSERT(reporter, strcmp(expected, dom.getName(textNode)) == 0);
    }

    int textLen = SkToInt(strlen(expected));

    const char* x = dom.findAttr(textElem, "x");
    REPORTER_ASSERT(reporter, x != nullptr);
    if (x != nullptr) {
        int xposCount = textLen;
        REPORTER_ASSERT(reporter, SkParse::Count(x) == xposCount);

        AutoTMalloc<SkScalar> xpos(xposCount);
        SkParse::FindScalars(x, xpos.get(), xposCount);
        if (scalarsPerPos < 1) {
            // For default-positioned text, we cannot make any assumptions regarding
            // the first glyph position when the string has leading whitespace (to be stripped).
            if (txt[0] != ' ' && txt[0] != '\t') {
                REPORTER_ASSERT(reporter, xpos[0] == offset.x());
            }
        } else {
            for (int i = 0; i < xposCount; ++i) {
                REPORTER_ASSERT(reporter, xpos[i] == SkIntToScalar(expected[i]));
            }
        }
    }

    const char* y = dom.findAttr(textElem, "y");
    REPORTER_ASSERT(reporter, y != nullptr);
    if (y != nullptr) {
        int yposCount = (scalarsPerPos < 2) ? 1 : textLen;
        REPORTER_ASSERT(reporter, SkParse::Count(y) == yposCount);

        AutoTMalloc<SkScalar> ypos(yposCount);
        SkParse::FindScalars(y, ypos.get(), yposCount);
        if (scalarsPerPos < 2) {
            REPORTER_ASSERT(reporter, ypos[0] == offset.y());
        } else {
            for (int i = 0; i < yposCount; ++i) {
                REPORTER_ASSERT(reporter, ypos[i] == 150 - SkIntToScalar(expected[i]));
            }
        }
    }
}

void test_whitespace_pos(skiatest::Reporter* reporter,
                         const char* txt,
                         const char* expected) {
    size_t len = strlen(txt);

    SkDOM dom;
    SkPaint paint;
    SkFont font = ToolUtils::DefaultPortableFont();
    SkPoint offset = SkPoint::Make(10, 20);

    {
        MakeDOMCanvas(&dom)->drawSimpleText(txt, len, SkTextEncoding::kUTF8,
                                            offset.x(), offset.y(), font, paint);
    }
    check_text_node(reporter, dom, dom.finishParsing(), offset, 0, txt, expected);

    {
        AutoTArray<SkScalar> xpos(len);
        for (int i = 0; i < SkToInt(len); ++i) {
            xpos[i] = SkIntToScalar(txt[i]);
        }

        auto blob = SkTextBlob::MakeFromPosTextH(txt, len, xpos, offset.y(), font);
        MakeDOMCanvas(&dom)->drawTextBlob(blob, 0, 0, paint);
    }
    check_text_node(reporter, dom, dom.finishParsing(), offset, 1, txt, expected);

    {
        AutoTArray<SkPoint> pos(len);
        for (int i = 0; i < SkToInt(len); ++i) {
            pos[i] = SkPoint::Make(SkIntToScalar(txt[i]), 150 - SkIntToScalar(txt[i]));
        }

        auto blob = SkTextBlob::MakeFromPosText(txt, len, pos, font);
        MakeDOMCanvas(&dom)->drawTextBlob(blob, 0, 0, paint);
    }
    check_text_node(reporter, dom, dom.finishParsing(), offset, 2, txt, expected);
}

} // namespace

DEF_TEST(SVGDevice_whitespace_pos, reporter) {
    static const struct {
        const char* tst_in;
        const char* tst_out;
    } tests[] = {
        { "abcd"      , "abcd" },
        { "ab cd"     , "ab cd" },
        { "ab \t\t cd", "ab cd" },
        { " abcd"     , "abcd" },
        { "  abcd"    , "abcd" },
        { " \t\t abcd", "abcd" },
        { "abcd "     , "abcd " }, // we allow one trailing whitespace char
        { "abcd  "    , "abcd " }, // because it makes no difference and
        { "abcd\t  "  , "abcd " }, // simplifies the implementation
        { "\t\t  \t ab \t\t  \t cd \t\t   \t  ", "ab cd " },
    };

    for (unsigned i = 0; i < std::size(tests); ++i) {
        test_whitespace_pos(reporter, tests[i].tst_in, tests[i].tst_out);
    }
}

void SetImageShader(SkPaint* paint, int imageWidth, int imageHeight, SkTileMode xTile,
                    SkTileMode yTile) {
    auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(imageWidth, imageHeight));
    paint->setShader(surface->makeImageSnapshot()->makeShader(xTile, yTile, SkSamplingOptions()));
}

// Attempt to find the three nodes on which we have expectations:
// the pattern node, the image within that pattern, and the rect which
// uses the pattern as a fill.
// returns false if not all nodes are found.
bool FindImageShaderNodes(skiatest::Reporter* reporter, const SkDOM* dom, const SkDOM::Node* root,
                          const SkDOM::Node** patternOut, const SkDOM::Node** imageOut,
                          const SkDOM::Node** rectOut) {
    if (root == nullptr || dom == nullptr) {
        ERRORF(reporter, "root element not found");
        return false;
    }


    const SkDOM::Node* rect = dom->getFirstChild(root, "rect");
    if (rect == nullptr) {
        ERRORF(reporter, "rect not found");
        return false;
    }
    *rectOut = rect;

    const SkDOM::Node* defs = dom->getFirstChild(root, "defs");
    if (defs == nullptr) {
        ERRORF(reporter, "defs not found");
        return false;
    }

    const SkDOM::Node* pattern = dom->getFirstChild(defs, "pattern");
    if (pattern == nullptr) {
        ERRORF(reporter, "pattern not found");
        return false;
    }
    *patternOut = pattern;

    const SkDOM::Node* image = dom->getFirstChild(pattern, "image");
    if (image == nullptr) {
        ERRORF(reporter, "image not found");
        return false;
    }
    *imageOut = image;

    return true;
}

void ImageShaderTestSetup(SkDOM* dom, SkPaint* paint, int imageWidth, int imageHeight,
                          int rectWidth, int rectHeight, SkTileMode xTile, SkTileMode yTile) {
    SetImageShader(paint, imageWidth, imageHeight, xTile, yTile);
    auto svgCanvas = MakeDOMCanvas(dom);

    SkRect bounds{0, 0, SkIntToScalar(rectWidth), SkIntToScalar(rectHeight)};
    svgCanvas->drawRect(bounds, *paint);
}


DEF_TEST(SVGDevice_image_shader_norepeat, reporter) {
    SkDOM dom;
    SkPaint paint;
    int imageWidth = 3, imageHeight = 3;
    int rectWidth = 10, rectHeight = 10;
    ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
                         SkTileMode::kClamp, SkTileMode::kClamp);

    const SkDOM::Node* root = dom.finishParsing();

    const SkDOM::Node *patternNode, *imageNode, *rectNode;
    bool structureAppropriate =
            FindImageShaderNodes(reporter, &dom, root, &patternNode, &imageNode, &rectNode);
    REPORTER_ASSERT(reporter, structureAppropriate);

    // the image should always maintain its size.
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "width")) == imageWidth);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "height")) == imageHeight);

    // making the pattern as large as the container prevents
    // it from repeating.
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(patternNode, "width"), "100%") == 0);
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(patternNode, "height"), "100%") == 0);
}

DEF_TEST(SVGDevice_image_shader_tilex, reporter) {
    SkDOM dom;
    SkPaint paint;
    int imageWidth = 3, imageHeight = 3;
    int rectWidth = 10, rectHeight = 10;
    ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
                         SkTileMode::kRepeat, SkTileMode::kClamp);

    const SkDOM::Node* root = dom.finishParsing();
    const SkDOM::Node* innerSvg = dom.getFirstChild(root, "svg");
    if (innerSvg == nullptr) {
        ERRORF(reporter, "inner svg element not found");
        return;
    }

    const SkDOM::Node *patternNode, *imageNode, *rectNode;
    bool structureAppropriate =
            FindImageShaderNodes(reporter, &dom, innerSvg, &patternNode, &imageNode, &rectNode);
    REPORTER_ASSERT(reporter, structureAppropriate);

    // the imageNode should always maintain its size.
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "width")) == imageWidth);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "height")) == imageHeight);

    // if the patternNode width matches the imageNode width,
    // it will repeat in along the x axis.
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(patternNode, "width")) == imageWidth);
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(patternNode, "height"), "100%") == 0);
}

DEF_TEST(SVGDevice_image_shader_tiley, reporter) {
    SkDOM dom;
    SkPaint paint;
    int imageNodeWidth = 3, imageNodeHeight = 3;
    int rectNodeWidth = 10, rectNodeHeight = 10;
    ImageShaderTestSetup(&dom, &paint, imageNodeWidth, imageNodeHeight, rectNodeWidth,
                         rectNodeHeight, SkTileMode::kClamp, SkTileMode::kRepeat);

    const SkDOM::Node* root = dom.finishParsing();
    const SkDOM::Node* innerSvg = dom.getFirstChild(root, "svg");
    if (innerSvg == nullptr) {
        ERRORF(reporter, "inner svg element not found");
        return;
    }

    const SkDOM::Node *patternNode, *imageNode, *rectNode;
    bool structureAppropriate =
            FindImageShaderNodes(reporter, &dom, innerSvg, &patternNode, &imageNode, &rectNode);
    REPORTER_ASSERT(reporter, structureAppropriate);

    // the imageNode should always maintain its size.
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "width")) == imageNodeWidth);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "height")) == imageNodeHeight);

    // making the patternNode as large as the container prevents
    // it from repeating.
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(patternNode, "width"), "100%") == 0);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(patternNode, "height")) == imageNodeHeight);
}

DEF_TEST(SVGDevice_image_shader_tileboth, reporter) {
    SkDOM dom;
    SkPaint paint;
    int imageWidth = 3, imageHeight = 3;
    int rectWidth = 10, rectHeight = 10;
    ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
                         SkTileMode::kRepeat, SkTileMode::kRepeat);

    const SkDOM::Node* root = dom.finishParsing();

    const SkDOM::Node *patternNode, *imageNode, *rectNode;
    const SkDOM::Node* innerSvg = dom.getFirstChild(root, "svg");
    if (innerSvg == nullptr) {
        ERRORF(reporter, "inner svg element not found");
        return;
    }
    bool structureAppropriate =
            FindImageShaderNodes(reporter, &dom, innerSvg, &patternNode, &imageNode, &rectNode);
    REPORTER_ASSERT(reporter, structureAppropriate);

    // the imageNode should always maintain its size.
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "width")) == imageWidth);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(imageNode, "height")) == imageHeight);

    REPORTER_ASSERT(reporter, atoi(dom.findAttr(patternNode, "width")) == imageWidth);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(patternNode, "height")) == imageHeight);
}

DEF_TEST(SVGDevice_ColorFilters, reporter) {
    SkDOM dom;
    SkPaint paint;
    paint.setColorFilter(SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcIn));
    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        SkRect bounds{0, 0, SkIntToScalar(100), SkIntToScalar(100)};
        svgCanvas->drawRect(bounds, paint);
    }
    const SkDOM::Node* rootElement = dom.finishParsing();
    ABORT_TEST(reporter, !rootElement, "root element not found");

    const SkDOM::Node* filterElement = dom.getFirstChild(rootElement, "filter");
    ABORT_TEST(reporter, !filterElement, "filter element not found");

    const SkDOM::Node* floodElement = dom.getFirstChild(filterElement, "feFlood");
    ABORT_TEST(reporter, !floodElement, "feFlood element not found");

    const SkDOM::Node* compositeElement = dom.getFirstChild(filterElement, "feComposite");
    ABORT_TEST(reporter, !compositeElement, "feComposite element not found");

    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(filterElement, "width"), "100%") == 0);
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(filterElement, "height"), "100%") == 0);

    REPORTER_ASSERT(reporter,
                    strcmp(dom.findAttr(floodElement, "flood-color"), "red") == 0);
    REPORTER_ASSERT(reporter, atoi(dom.findAttr(floodElement, "flood-opacity")) == 1);

    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(compositeElement, "in"), "flood") == 0);
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(compositeElement, "operator"), "in") == 0);
}

DEF_TEST(SVGDevice_textpath, reporter) {
    SkDOM dom;
    SkFont font = ToolUtils::DefaultPortableFont();
    SkPaint paint;

    auto check_text = [&](uint32_t flags, bool expect_path) {
        // By default, we emit <text> nodes.
        {
            auto svgCanvas = MakeDOMCanvas(&dom, flags);
            svgCanvas->drawString("foo", 100, 100, font, paint);
        }
        const auto* rootElement = dom.finishParsing();
        REPORTER_ASSERT(reporter, rootElement, "root element not found");
        const auto* textElement = dom.getFirstChild(rootElement, "text");
        REPORTER_ASSERT(reporter, !!textElement == !expect_path, "unexpected text element");
        const auto* pathElement = dom.getFirstChild(rootElement, "path");
        REPORTER_ASSERT(reporter, !!pathElement == expect_path, "unexpected path element");
    };

    // By default, we emit <text> nodes.
    check_text(0, /*expect_path=*/false);

    // With kConvertTextToPaths_Flag, we emit <path> nodes.
    check_text(SkSVGCanvas::kConvertTextToPaths_Flag, /*expect_path=*/true);

    // We also use paths in the presence of path effects.
    SkScalar intervals[] = {10, 5};
    paint.setPathEffect(SkDashPathEffect::Make(intervals, 0));
    check_text(0, /*expect_path=*/true);
}

DEF_TEST(SVGDevice_fill_stroke, reporter) {
    struct {
        SkColor        color;
        SkPaint::Style style;
        const char*    expected_fill;
        const char*    expected_stroke;
    } gTests[] = {
        { SK_ColorBLACK, SkPaint::kFill_Style  , nullptr, nullptr },
        { SK_ColorBLACK, SkPaint::kStroke_Style, "none" , "black" },
        { SK_ColorRED  , SkPaint::kFill_Style  , "red"  , nullptr },
        { SK_ColorRED  , SkPaint::kStroke_Style, "none" , "red"   },
    };

    for (const auto& tst : gTests) {
        SkPaint p;
        p.setColor(tst.color);
        p.setStyle(tst.style);

        SkDOM dom;
        {
            MakeDOMCanvas(&dom)->drawRect(SkRect::MakeWH(100, 100), p);
        }

        const auto* root = dom.finishParsing();
        REPORTER_ASSERT(reporter, root, "root element not found");
        const auto* rect = dom.getFirstChild(root, "rect");
        REPORTER_ASSERT(reporter, rect, "rect element not found");
        const auto* fill = dom.findAttr(rect, "fill");
        REPORTER_ASSERT(reporter, !!fill == !!tst.expected_fill);
        if (fill) {
            REPORTER_ASSERT(reporter, strcmp(fill, tst.expected_fill) == 0);
        }
        const auto* stroke = dom.findAttr(rect, "stroke");
        REPORTER_ASSERT(reporter, !!stroke == !!tst.expected_stroke);
        if (stroke) {
            REPORTER_ASSERT(reporter, strcmp(stroke, tst.expected_stroke) == 0);
        }
    }
}

DEF_TEST(SVGDevice_fill_opacity_black_fill, reporter) {
    struct {
        SkColor     color;
        const char* expected_fill_opacity;
    } gTests[] = {
        // Semi-transparent black
        {  SkColorSetARGB(0x33, 0x00, 0x00, 0x00), "0.2" },
        // Opaque black
        {  SkColorSetARGB(0xFF, 0x00, 0x00, 0x00), nullptr },
    };

    for (const auto& tst : gTests) {
        SkPaint p;
        p.setColor(tst.color);
        p.setStyle(SkPaint::kFill_Style);

        SkDOM dom;
        {
            auto svgCanvas = MakeDOMCanvas(&dom);
            SkRect bounds{0, 0, SkIntToScalar(100), SkIntToScalar(100)};
            svgCanvas->drawRect(bounds, p);
        }

        const SkDOM::Node* rootElement = dom.finishParsing();
        ABORT_TEST(reporter, !rootElement, "root element not found");

        const SkDOM::Node* rectElement = dom.getFirstChild(rootElement, "rect");
        ABORT_TEST(reporter, !rectElement, "rect element not found");
        const auto* fill_opacity = dom.findAttr(rectElement, "fill-opacity");
        REPORTER_ASSERT(reporter, !!fill_opacity == !!tst.expected_fill_opacity);
        if (fill_opacity) {
            REPORTER_ASSERT(reporter, strcmp(fill_opacity, tst.expected_fill_opacity) == 0);
        }
    }
}

DEF_TEST(SVGDevice_fill_rect_hex, reporter) {
    SkDOM dom;
    SkPaint paint;
    paint.setColor(SK_ColorBLUE);
    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        SkRect bounds{0, 0, SkIntToScalar(100), SkIntToScalar(100)};
        svgCanvas->drawRect(bounds, paint);
    }
    const SkDOM::Node* rootElement = dom.finishParsing();
    ABORT_TEST(reporter, !rootElement, "root element not found");

    const SkDOM::Node* rectElement = dom.getFirstChild(rootElement, "rect");
    ABORT_TEST(reporter, !rectElement, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectElement, "fill"), "blue") == 0);
}

DEF_TEST(SVGDevice_fill_rect_custom_hex, reporter) {
    SkDOM dom;
    {
        SkPaint paint;
        paint.setColor(0xFFAABCDE);
        auto svgCanvas = MakeDOMCanvas(&dom);
        SkRect bounds{0, 0, SkIntToScalar(100), SkIntToScalar(100)};
        svgCanvas->drawRect(bounds, paint);
        paint.setColor(0xFFAABBCC);
        svgCanvas->drawRect(bounds, paint);
        paint.setColor(0xFFAA1123);
        svgCanvas->drawRect(bounds, paint);
    }
    const SkDOM::Node* rootElement = dom.finishParsing();
    ABORT_TEST(reporter, !rootElement, "root element not found");

    // Test 0xAABCDE filled rect.
    const SkDOM::Node* rectElement = dom.getFirstChild(rootElement, "rect");
    ABORT_TEST(reporter, !rectElement, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectElement, "fill"), "#AABCDE") == 0);

    // Test 0xAABBCC filled rect.
    rectElement = dom.getNextSibling(rectElement, "rect");
    ABORT_TEST(reporter, !rectElement, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectElement, "fill"), "#ABC") == 0);

    // Test 0xFFAA1123 filled rect. Make sure it does not turn into #A123.
    rectElement = dom.getNextSibling(rectElement, "rect");
    ABORT_TEST(reporter, !rectElement, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectElement, "fill"), "#AA1123") == 0);
}

DEF_TEST(SVGDevice_fill_stroke_rect_hex, reporter) {
    SkDOM dom;
    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        SkRect bounds{0, 0, SkIntToScalar(100), SkIntToScalar(100)};

        SkPaint paint;
        paint.setColor(0xFF00BBAC);
        svgCanvas->drawRect(bounds, paint);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setColor(0xFF123456);
        paint.setStrokeWidth(1);
        svgCanvas->drawRect(bounds, paint);
    }
    const SkDOM::Node* rootElement = dom.finishParsing();
    ABORT_TEST(reporter, !rootElement, "root element not found");

    const SkDOM::Node* rectNode = dom.getFirstChild(rootElement, "rect");
    ABORT_TEST(reporter, !rectNode, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectNode, "fill"), "#00BBAC") == 0);

    rectNode = dom.getNextSibling(rectNode, "rect");
    ABORT_TEST(reporter, !rectNode, "rect element not found");
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectNode, "stroke"), "#123456") == 0);
    REPORTER_ASSERT(reporter, strcmp(dom.findAttr(rectNode, "stroke-width"), "1") == 0);
}

DEF_TEST(SVGDevice_rect_with_path_effect, reporter) {
    SkDOM dom;

    SkScalar intervals[] = {0, 20};
    sk_sp<SkPathEffect> pathEffect = SkDashPathEffect::Make(intervals, 0);

    SkPaint paint;
    paint.setPathEffect(pathEffect);

    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        svgCanvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
    }

    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* pathElement = dom.getFirstChild(rootElement, "path");
    REPORTER_ASSERT(reporter, pathElement, "path element not found");
}

DEF_TEST(SVGDevice_rrect_with_path_effect, reporter) {
    SkDOM dom;

    SkScalar intervals[] = {0, 20};
    sk_sp<SkPathEffect> pathEffect = SkDashPathEffect::Make(intervals, 0);

    SkPaint paint;
    paint.setPathEffect(pathEffect);

    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        svgCanvas->drawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 100, 100), 10, 10), paint);
    }

    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* pathElement = dom.getFirstChild(rootElement, "path");
    REPORTER_ASSERT(reporter, pathElement, "path element not found");
}

DEF_TEST(SVGDevice_oval_with_path_effect, reporter) {
    SkDOM dom;

    SkScalar intervals[] = {0, 20};
    sk_sp<SkPathEffect> pathEffect = SkDashPathEffect::Make(intervals, 0);

    SkPaint paint;
    paint.setPathEffect(pathEffect);

    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        svgCanvas->drawOval(SkRect::MakeXYWH(0, 0, 100, 100), paint);
    }

    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* pathElement = dom.getFirstChild(rootElement, "path");
    REPORTER_ASSERT(reporter, pathElement, "path element not found");
}


DEF_TEST(SVGDevice_path_effect, reporter) {
    SkDOM dom;

    SkPaint paint;
    paint.setColor(SK_ColorRED);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(10);
    paint.setStrokeCap(SkPaint::kRound_Cap);

    // Produces a line of three red dots.
    SkScalar intervals[] = {0, 20};
    sk_sp<SkPathEffect> pathEffect = SkDashPathEffect::Make(intervals, 0);
    paint.setPathEffect(pathEffect);
    const SkPoint points[] = {{50, 15}, {100, 15}, {150, 15} };
    {
        auto svgCanvas = MakeDOMCanvas(&dom);
        svgCanvas->drawPoints(SkCanvas::kLines_PointMode, points, paint);
    }
    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* pathElement = dom.getFirstChild(rootElement, "path");
    REPORTER_ASSERT(reporter, pathElement, "path element not found");

    // The SVG path to draw the three dots is a complex list of instructions.
    // To avoid test brittleness, we don't attempt to match the entire path.
    // Instead, we simply confirm there are three (M)ove instructions, one per
    // dot.  If path effects were not being honored, we would expect only one
    // Move instruction, to the starting position, before drawing a continuous
    // straight line.
    const auto* d = dom.findAttr(pathElement, "d");
    int mCount = 0;
    const char* pos;
    for (pos = d; *pos != '\0'; pos++) {
      mCount += (*pos == 'M') ? 1 : 0;
    }
    REPORTER_ASSERT(reporter, mCount == 3);
}

DEF_TEST(SVGDevice_relative_path_encoding, reporter) {
    SkDOM dom;
    {
        auto svgCanvas = MakeDOMCanvas(&dom, SkSVGCanvas::kRelativePathEncoding_Flag);
        SkPath path = SkPathBuilder()
                      .moveTo(100, 50)
                      .lineTo(200, 50)
                      .lineTo(200, 150)
                      .close()
                      .detach();

        svgCanvas->drawPath(path, SkPaint());
    }

    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* pathElement = dom.getFirstChild(rootElement, "path");
    REPORTER_ASSERT(reporter, pathElement, "path element not found");
    const auto* d = dom.findAttr(pathElement, "d");
    REPORTER_ASSERT(reporter, !strcmp(d, "m100 50l100 0l0 100l-100 -100Z"));
}

DEF_TEST(SVGDevice_color_shader, reporter) {
    SkDOM dom;
    {
        auto svgCanvas = MakeDOMCanvas(&dom);

        SkPaint paint;
        paint.setShader(SkShaders::Color(0xffffff00));

        svgCanvas->drawCircle(100, 100, 100, paint);
    }

    const auto* rootElement = dom.finishParsing();
    REPORTER_ASSERT(reporter, rootElement, "root element not found");
    const auto* ellipseElement = dom.getFirstChild(rootElement, "ellipse");
    REPORTER_ASSERT(reporter, ellipseElement, "ellipse element not found");
    const auto* fill = dom.findAttr(ellipseElement, "fill");
    REPORTER_ASSERT(reporter, fill, "fill attribute not found");
    REPORTER_ASSERT(reporter, !strcmp(fill, "yellow"));
}

DEF_TEST(SVGDevice_parse_minmax, reporter) {
    auto check = [&](int64_t n, bool expected) {
        const auto str = std::to_string(n);

        int val;
        REPORTER_ASSERT(reporter, SkToBool(SkParse::FindS32(str.c_str(), &val)) == expected);
        if (expected) {
            REPORTER_ASSERT(reporter, val == n);
        }
    };

    check(std::numeric_limits<int>::max(), true);
    check(std::numeric_limits<int>::min(), true);
    check(static_cast<int64_t>(std::numeric_limits<int>::max()) + 1, false);
    check(static_cast<int64_t>(std::numeric_limits<int>::min()) - 1, false);
}

#endif
