utils.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <type_traits>
  2. #include "utils.hpp"
  3. template <typename Filler, typename Range>
  4. void outline(Range bounds, const Filler& fill)
  5. {
  6. constexpr size_t dimensions = std::remove_reference_t<decltype(bounds.lower())>::dimensions;
  7. for(size_t coord = 0; coord < dimensions; ++coord)
  8. {
  9. auto lower_edge = bounds;
  10. lower_edge.upper()[coord] = lower_edge.lower()[coord]+1;
  11. auto upper_edge = bounds;
  12. upper_edge.lower()[coord] = upper_edge.upper()[coord]-1;
  13. std::invoke(fill, lower_edge);
  14. std::invoke(fill, upper_edge);
  15. }
  16. }
  17. void outline(const graphical::surface& target, graphical::color color, range2D bounds)
  18. {
  19. outline(bounds, [&](range2D bounds){ graphical::fill(target, color, bounds); });
  20. }
  21. void lowlight(const graphical::surface& target, graphical::color color, range2D bounds, int2 dim)
  22. {
  23. range2D target_bounds = rect{target.size()};
  24. bounds = intersection(bounds, target_bounds);
  25. if(!bounds.valid())
  26. return; // we are off target
  27. // unless there is no distance to travel, make sure to step forward
  28. assert(to_conjunction( (bounds.upper() - bounds.lower() == int2::zero()) | (dim > int2::zero()) ));
  29. std::visit([&](auto writer)
  30. {
  31. auto i = bounds.lower();
  32. auto dimension = i.begin();
  33. while(dimension != i.end())
  34. {
  35. writer.set(color, i);
  36. dimension = support::advance_vector(i, bounds.lower(), bounds.upper(), dim);
  37. }
  38. }, target.pixels());
  39. }
  40. void outline_lowlight(const graphical::surface& target, graphical::color color, range2D bounds, int2 dim)
  41. {
  42. outline(bounds, [&](range2D bounds){ lowlight(target, color, bounds, dim); });
  43. }