blob: 710abdd1037cc644d58c84582948c7936893a281 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "tests/common/svg/svg_scene.h"
#include <gtest/gtest.h>
#include "scoped_svg.h"
#include "tests/common/affine_transform_test_utils.h"
TEST(SvgSceneTest, SingleSvg)
{
// clang-format off
ScopedSvg svg = ScopedSvg::parseString(
"<svg xmlns=\"http://www.w3.org/2000/svg\">"
" <g style = \"fill: #FF0000\">"
" <rect x=\"10\" y=\"20\" width=\"100\" height=\"50\" />"
" </g>"
"</svg>"
);
// clang-format on
SvgScene scene;
scene.addSvgDocument(svg.get(), 200., 300.);
double xmin, ymin, xmax, ymax;
scene.getBounds(&xmin, &ymin, &xmax, &ymax);
EXPECT_DOUBLE_EQ(xmin, 210.);
EXPECT_DOUBLE_EQ(ymin, 320.);
EXPECT_DOUBLE_EQ(xmax, 310.);
EXPECT_DOUBLE_EQ(ymax, 370.);
const auto & svgs = scene.unique_svgs();
ASSERT_EQ(svgs.size(), 1u);
EXPECT_EQ(svgs[0], svg.get());
const auto & paths = scene.unique_paths();
ASSERT_EQ(paths.size(), 1u);
EXPECT_EQ(paths[0].svg_index, 0u);
EXPECT_EQ(paths[0].path_id, 0u);
const auto & rasters = scene.unique_rasters();
ASSERT_EQ(rasters.size(), 1u);
EXPECT_EQ(rasters[0].svg_index, 0u);
EXPECT_EQ(rasters[0].raster_id, 0u);
EXPECT_EQ(rasters[0].path_index, 0u);
EXPECT_AFFINE_TRANSFORM_EQ(rasters[0].transform, affine_transform_make_translation(200., 300.));
const auto & layers = scene.layers();
ASSERT_EQ(layers.size(), 1u);
EXPECT_EQ(layers[0].svg_index, 0u);
EXPECT_EQ(layers[0].layer_id, 0u);
EXPECT_EQ(layers[0].fill_color, 0xff0000u);
EXPECT_DOUBLE_EQ(layers[0].fill_opacity, 1.0);
EXPECT_FALSE(layers[0].fill_even_odd);
EXPECT_DOUBLE_EQ(layers[0].opacity, 1.0);
ASSERT_EQ(layers[0].prints.size(), 1u);
EXPECT_EQ(layers[0].prints[0].raster_index, 0u);
EXPECT_EQ(layers[0].prints[0].tx, 0);
EXPECT_EQ(layers[0].prints[0].ty, 0);
}
TEST(SvgSceneTest, RepeatedSvg)
{
// Same SVG document repeated multiple times on the scene with different
// transforms.
// clang-format off
ScopedSvg svg = ScopedSvg::parseString(
"<svg xmlns=\"http://www.w3.org/2000/svg\">"
" <g style = \"fill: #FF0000\">"
" <rect x=\"10\" y=\"20\" width=\"100\" height=\"50\" />"
" </g>"
"</svg>"
);
// clang-format on
SvgScene scene;
const size_t kCount = 10;
const double kTranslateX = 20.;
const double kTranslateY = 60.;
for (size_t nn = 0; nn < kCount; ++nn)
scene.addSvgDocument(svg.get(), nn * kTranslateX, nn * kTranslateY);
double xmin, ymin, xmax, ymax;
scene.getBounds(&xmin, &ymin, &xmax, &ymax);
EXPECT_DOUBLE_EQ(xmin, 10.);
EXPECT_DOUBLE_EQ(ymin, 20.);
EXPECT_DOUBLE_EQ(xmax, 110. + kTranslateX * (kCount - 1));
EXPECT_DOUBLE_EQ(ymax, 70. + kTranslateY * (kCount - 1));
const auto & svgs = scene.unique_svgs();
ASSERT_EQ(svgs.size(), 1u);
EXPECT_EQ(svgs[0], svg.get());
const auto & paths = scene.unique_paths();
ASSERT_EQ(paths.size(), 1u);
EXPECT_EQ(paths[0].svg_index, 0u);
EXPECT_EQ(paths[0].path_id, 0u);
const auto & rasters = scene.unique_rasters();
ASSERT_EQ(rasters.size(), kCount);
for (size_t nn = 0; nn < kCount; ++nn)
{
std::string text = std::string("raster") + std::to_string(nn);
const auto & raster = rasters[nn];
EXPECT_EQ(raster.svg_index, 0u) << text;
EXPECT_EQ(raster.raster_id, 0u) << text;
EXPECT_EQ(raster.path_index, 0u) << text;
EXPECT_AFFINE_TRANSFORM_EQ(
raster.transform,
affine_transform_make_translation(nn * kTranslateX, nn * kTranslateY));
}
const auto & layers = scene.layers();
ASSERT_EQ(layers.size(), kCount);
for (size_t nn = 0; nn < kCount; ++nn)
{
std::string text = std::string("layer") + std::to_string(nn);
const auto & layer = layers[nn];
EXPECT_EQ(layer.svg_index, 0u) << text;
EXPECT_EQ(layer.layer_id, nn) << text;
EXPECT_EQ(layer.fill_color, 0xff0000u) << text;
EXPECT_DOUBLE_EQ(layer.fill_opacity, 1.0) << text;
EXPECT_FALSE(layer.fill_even_odd) << text;
EXPECT_DOUBLE_EQ(layer.opacity, 1.0) << text;
ASSERT_EQ(layer.prints.size(), 1u) << text;
EXPECT_EQ(layer.prints[0].raster_index, nn) << text;
EXPECT_EQ(layer.prints[0].tx, 0) << text;
EXPECT_EQ(layer.prints[0].ty, 0) << text;
}
}
TEST(SvgSceneTest, MultipleSvgs)
{
// Same SVG document repeated multiple times on the scene with different
// transforms.
// clang-format off
ScopedSvg svg1 = ScopedSvg::parseString(
"<svg xmlns=\"http://www.w3.org/2000/svg\">"
" <g style = \"fill: #FF0000\">"
" <rect x=\"10\" y=\"20\" width=\"100\" height=\"50\" />"
" </g>"
"</svg>"
);
ScopedSvg svg2 = ScopedSvg::parseString(
"<svg xmlns=\"http://www.w3.org/2000/svg\">"
" <g style = \"fill: #0000FF\">"
" <path d=\"M 10 20 l 100 25 l -100 25 Z\" />"
" </g>"
"</svg>"
);
// clang-format on
const size_t kGridWidth = 8;
const size_t kGridHeight = 4;
const size_t kCount = kGridWidth * kGridHeight;
const double kTranslateX = 20.;
const double kTranslateY = 60.;
SvgScene scene;
for (size_t nn = 0; nn < kCount; ++nn)
{
// Organize items in a grid, alternating each instance between svg1 and
// svg2, so it looks like:
//
// X O X O X O
// O X O X O X
// X O X O X O
// ...
size_t grid_y = nn / kGridWidth;
size_t grid_x = nn % kGridWidth;
const svg * item = (nn & 1) ? svg2.get() : svg1.get();
scene.addSvgDocument(
item,
affine_transform_make_translation(grid_x * kTranslateX, grid_y * kTranslateY));
}
double xmin, ymin, xmax, ymax;
scene.getBounds(&xmin, &ymin, &xmax, &ymax);
EXPECT_DOUBLE_EQ(xmin, 10.);
EXPECT_DOUBLE_EQ(ymin, 20.);
EXPECT_DOUBLE_EQ(xmax, 110. + kTranslateX * (kGridWidth - 1));
EXPECT_DOUBLE_EQ(ymax, 70. + kTranslateY * (kGridHeight - 1));
const auto & svgs = scene.unique_svgs();
ASSERT_EQ(svgs.size(), 2u);
EXPECT_EQ(svgs[0], svg1.get());
EXPECT_EQ(svgs[1], svg2.get());
const auto & paths = scene.unique_paths();
ASSERT_EQ(paths.size(), 2u);
EXPECT_EQ(paths[0].svg_index, 0u);
EXPECT_EQ(paths[0].path_id, 0u);
EXPECT_EQ(paths[1].svg_index, 1u);
EXPECT_EQ(paths[1].path_id, 0u);
const auto & rasters = scene.unique_rasters();
ASSERT_EQ(rasters.size(), kCount);
for (size_t nn = 0; nn < kCount; ++nn)
{
std::string text = std::string("raster") + std::to_string(nn);
size_t grid_x = nn % kGridWidth;
size_t grid_y = nn / kGridWidth;
const auto & raster = rasters[nn];
EXPECT_EQ(raster.svg_index, (nn & 1u)) << text;
EXPECT_EQ(raster.raster_id, 0u) << text;
EXPECT_EQ(raster.path_index, (nn & 1u)) << text;
EXPECT_AFFINE_TRANSFORM_EQ(
raster.transform,
affine_transform_make_translation(grid_x * kTranslateX, grid_y * kTranslateY));
}
const auto & layers = scene.layers();
ASSERT_EQ(layers.size(), kCount);
for (size_t nn = 0; nn < kCount; ++nn)
{
std::string text = std::string("layer") + std::to_string(nn);
const auto & layer = layers[nn];
EXPECT_EQ(layer.svg_index, (nn & 1u)) << text;
EXPECT_EQ(layer.layer_id, nn) << text;
EXPECT_EQ(layer.fill_color, (nn & 1u) ? 0x000000ffu : 0xff0000u) << text;
EXPECT_DOUBLE_EQ(layer.fill_opacity, 1.0) << text;
EXPECT_FALSE(layer.fill_even_odd) << text;
EXPECT_DOUBLE_EQ(layer.opacity, 1.0) << text;
ASSERT_EQ(layer.prints.size(), 1u) << text;
EXPECT_EQ(layer.prints[0].raster_index, nn) << text;
EXPECT_EQ(layer.prints[0].tx, 0) << text;
EXPECT_EQ(layer.prints[0].ty, 0) << text;
}
}