Skip to content

Commit

Permalink
Merge pull request #88 from asalzburger/feat-allow-custom-view-box
Browse files Browse the repository at this point in the history
feat: allow for a custom view box setting
  • Loading branch information
asalzburger authored Sep 24, 2024
2 parents f736dfa + 81c890a commit 8f7c1ea
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 56 deletions.
14 changes: 14 additions & 0 deletions core/include/actsvg/core/svg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ struct file {
scalar _height = 800;
scalar _border = 10;

std::array<scalar, 2> _x_range = {std::numeric_limits<scalar>::max(),
std::numeric_limits<scalar>::min()};
std::array<scalar, 2> _y_range = {std::numeric_limits<scalar>::max(),
std::numeric_limits<scalar>::min()};

std::optional<std::array<scalar, 4>> _view_box = std::nullopt;

std::vector<object> _objects = {};

/** Add an object and respect the min/max range
Expand All @@ -196,6 +203,13 @@ struct file {
**/
void add_objects(const std::vector<svg::object> &os_);

/** Get the view box from the x-y range */
std::array<scalar, 4> view_box() const;

/** Set a view box, this will overwrite the auto-determined one */
void set_view_box(const std::array<scalar, 4> &vb_);

/** Write to ostream */
friend std::ostream &operator<<(std::ostream &os_, const file &f_);
};

Expand Down
69 changes: 38 additions & 31 deletions core/src/core/svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,57 +122,64 @@ std::ostream &operator<<(std::ostream &os_, const object &o_) {
}

void file::add_object(const svg::object &o_) {
// Add the object
if (o_._active) {
_objects.push_back(o_);
}
add_objects({o_});
}

void file::add_objects(const std::vector<svg::object> &os_) {
// Add the objects one by one
for (const auto &o_ : os_)
if (o_._active) {
_objects.push_back(o_);
for (const auto &o : os_) {
if (o._active) {
_objects.push_back(o);
// Adjust range
_x_range[0] = std::min(_x_range[0], o._x_range[0]);
_x_range[1] = std::max(_x_range[1], o._x_range[1]);
_y_range[0] = std::min(_y_range[0], o._y_range[0]);
_y_range[1] = std::max(_y_range[1], o._y_range[1]);
}
}
}

std::ostream &operator<<(std::ostream &os_, const file &f_) {
// Do the viewBox adjustment
std::array<scalar, 2> x_range = {std::numeric_limits<scalar>::max(),
std::numeric_limits<scalar>::min()};
std::array<scalar, 2> y_range = {std::numeric_limits<scalar>::max(),
std::numeric_limits<scalar>::min()};
std::array<scalar, 4> file::view_box() const {

std::array<scalar, 4> viewBox = {-800, -800, 1600, 1600};
std::array<scalar, 4> vbox = {-800, -800, 1600, 1600};

std::map<std::string, svg::object> definitions;
// Enlarge the view box by 10 percent
vbox[2] = 1.2_scalar * (_x_range[1] - _x_range[0]);
vbox[3] = 1.2_scalar * (_y_range[1] - _y_range[0]);

// Include a fixed size border
vbox[0] = (_x_range[0] - 0.1_scalar * vbox[2]) - _border;
vbox[1] = (_y_range[0] - 0.1_scalar * vbox[3]) - _border;
vbox[2] += _border;
vbox[3] += _border;

return vbox;
}

void file::set_view_box(const std::array<scalar, 4> &vbox_) {
_view_box = vbox_;
}

std::ostream &operator<<(std::ostream &os_, const file &f_) {

std::map<std::string, svg::object> definitions;
for (const auto &o : f_._objects) {
x_range[0] = std::min(x_range[0], o._x_range[0]);
x_range[1] = std::max(x_range[1], o._x_range[1]);
y_range[0] = std::min(y_range[0], o._y_range[0]);
y_range[1] = std::max(y_range[1], o._y_range[1]);
for (const auto &d : o._definitions) {
definitions[d._id] = d;
if (o._active) {
for (const auto &d : o._definitions) {
definitions[d._id] = d;
}
}
}
// Enlarge the view box by 10 percent
viewBox[2] = 1.2_scalar * (x_range[1] - x_range[0]);
viewBox[3] = 1.2_scalar * (y_range[1] - y_range[0]);

// Include a fixed size border
viewBox[0] = (x_range[0] - 0.1_scalar * viewBox[2]) - f_._border;
viewBox[1] = (y_range[0] - 0.1_scalar * viewBox[3]) - f_._border;
viewBox[2] += f_._border;
viewBox[3] += f_._border;
std::array<scalar, 4> vbox = f_._view_box.value_or(f_.view_box());

if (f_._add_html) {
os_ << f_._html_head;
}
os_ << f_._svg_head;
os_ << " width=\"" << f_._width << "\" height=\"" << f_._height << "\"";
os_ << " viewBox=\"" << viewBox[0] << " " << viewBox[1] << " " << viewBox[2]
<< " " << viewBox[3] << "\"";
os_ << " viewBox=\"" << vbox[0] << " " << vbox[1] << " " << vbox[2] << " "
<< vbox[3] << "\"";
os_ << f_._svg_def_end;
// Write the definitions first
if (not definitions.empty()) {
Expand Down
13 changes: 4 additions & 9 deletions tests/core/barrel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ TEST(barrel, x_y_view) {
}

// Add the surfaces
barrel_file._objects.insert(barrel_file._objects.end(), modules.begin(),
modules.end());
barrel_file.add_objects(modules);

// File output
std::ofstream barrel_stream;
Expand Down Expand Up @@ -80,8 +79,7 @@ TEST(barrel, z_phi_view) {
}

// Add the surfaces
barrel_file._objects.insert(barrel_file._objects.end(), modules.begin(),
modules.end());
barrel_file.add_objects(modules);

// File output
std::ofstream barrel_stream;
Expand Down Expand Up @@ -160,12 +158,9 @@ TEST(barrel, z_phi_view_grid) {
grid_color, grid_stroke, scale);

// Add the surfaces
barrel_file._objects.insert(barrel_file._objects.end(), modules.begin(),
modules.end());
barrel_file.add_objects(modules);
// Add the grid tiles
barrel_file._objects.insert(barrel_file._objects.end(),
grid._sub_objects.begin(),
grid._sub_objects.end());
barrel_file.add_objects(grid._sub_objects);

// File output
std::ofstream barrel_stream;
Expand Down
19 changes: 6 additions & 13 deletions tests/core/endcap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ TEST(endcap, z_r_view) {
}

// Add the surfaces
ec_file._objects.insert(ec_file._objects.end(), modules.begin(),
modules.end());
ec_file.add_objects(modules);

// File output
std::ofstream ec_stream;
Expand Down Expand Up @@ -93,10 +92,8 @@ TEST(endcap, x_y_view) {
}

// Add the surfaces
ec_file._objects.insert(ec_file._objects.end(), modules.begin(),
modules.end());
ec_file._objects.insert(ec_file._objects.end(), labels.begin(),
labels.end());
ec_file.add_objects(modules);
ec_file.add_objects(labels);

// File output
std::ofstream ec_stream;
Expand Down Expand Up @@ -176,16 +173,12 @@ TEST(endcap, x_y_view_grid) {
// Build the connectors
auto c_objects = connectors::connect_action(grid_sectors._sub_objects,
modules, associations);
ec_file._objects.insert(ec_file._objects.end(), c_objects.begin(),
c_objects.end());
ec_file.add_objects(c_objects);

// Add the surfaces
ec_file._objects.insert(ec_file._objects.end(), modules.begin(),
modules.end());
ec_file.add_objects(modules);
// Add the grid sectors
ec_file._objects.insert(ec_file._objects.end(),
grid_sectors._sub_objects.begin(),
grid_sectors._sub_objects.end());
ec_file.add_objects(grid_sectors._sub_objects);

// File output
std::ofstream ec_stream;
Expand Down
9 changes: 9 additions & 0 deletions tests/core/svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@ TEST(svg, empty_object) {
svg::object empty{"empty"};
std::stringstream ss;
}

TEST(svg, file_set_view_box) {
svg::file file;
file.set_view_box({0, 0, 100, 100});
std::stringstream ss;
ss << file;
std::string svg = ss.str();
ASSERT_TRUE(svg.find("viewBox=\"0 0 100 100\"") != std::string::npos);
}
5 changes: 2 additions & 3 deletions tests/meta/barrel_sheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,11 @@ TEST(display, barrel_x_y_view) {
}
}
// Add the surfaces
barrel_file._objects.insert(barrel_file._objects.end(), modules.begin(),
modules.end());
barrel_file.add_objects(modules);

// Write out the file
std::ofstream eout;
eout.open("barrel_xy_view.svg");
eout.open("sheet_barrel_xy_view.svg");
eout << barrel_file;
eout.close();
}
Expand Down
11 changes: 11 additions & 0 deletions tests/meta/detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,15 @@ TEST(proto, cylindrical_detector) {
rstream.open("test_meta_cylinder_detector_zr.svg");
rstream << rfile_zr;
rstream.close();

// Let's adjust the view box as a test
std::array<scalar, 4u> view_box = rfile_zr.view_box();
view_box[0] = -10;
view_box[2] *= 0.5;
view_box[2] += 100.;
rfile_zr.set_view_box(view_box);

rstream.open("test_meta_cylinder_detector_zr_half.svg");
rstream << rfile_zr;
rstream.close();
}

0 comments on commit 8f7c1ea

Please sign in to comment.