1 #include <mbgl/layout/clip_lines.hpp>
2 
3 #include <cmath>
4 
5 namespace mbgl {
6 namespace util {
7 
clipLines(const GeometryCollection & lines,const int16_t x1,const int16_t y1,const int16_t x2,const int16_t y2)8 GeometryCollection clipLines(const GeometryCollection &lines,
9         const int16_t x1, const int16_t y1, const int16_t x2, const int16_t y2) {
10 
11     GeometryCollection clippedLines;
12 
13     for (auto& line : lines) {
14 
15         if (line.empty())
16             continue;
17 
18         auto end = line.end() - 1;
19         for (auto it = line.begin(); it != end; it++) {
20             GeometryCoordinate p0 = *(it);
21             GeometryCoordinate p1 = *(it + 1);
22 
23             if (p0.x < x1 && p1.x < x1) {
24                 continue;
25             } else if (p0.x < x1) {
26                 p0 = { x1, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x)))) };
27             } else if (p1.x < x1) {
28                 p1 = { x1, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x)))) };
29             }
30 
31             if (p0.y < y1 && p1.y < y1) {
32                 continue;
33             } else if (p0.y < y1) {
34                 p0 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y)))), y1 };
35             } else if (p1.y < y1) {
36                 p1 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y)))), y1 };
37             }
38 
39             if (p0.x >= x2 && p1.x >= x2) {
40                 continue;
41             } else if (p0.x >= x2) {
42                 p0 = { x2, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x)))) };
43             } else if (p1.x >= x2) {
44                 p1 = { x2, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x)))) };
45             }
46 
47             if (p0.y >= y2 && p1.y >= y2) {
48                 continue;
49             } else if (p0.y >= y2) {
50                 p0 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y)))), y2 };
51             } else if (p1.y >= y2) {
52                 p1 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y)))), y2 };
53             }
54 
55             if (clippedLines.empty() || (!clippedLines.back().empty() && !(p0 == clippedLines.back().back()))) {
56                 clippedLines.emplace_back();
57                 clippedLines.back().push_back(p0);
58             }
59 
60             clippedLines.back().push_back(p1);
61         }
62     }
63 
64     return clippedLines;
65 }
66 
67 } // end namespace util
68 } // end namespace mbgl
69