MCPcopy Create free account
hub / github.com/MyGUI/mygui / orientContours

Method orientContours

MyGUIEngine/src/msdfgen/core/Shape.cpp:144–198  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

142}
143
144void Shape::orientContours() {
145 struct Intersection {
146 double x;
147 int direction;
148 int contourIndex;
149
150 static int compare(const void *a, const void *b) {
151 return sign(reinterpret_cast<const Intersection *>(a)->x-reinterpret_cast<const Intersection *>(b)->x);
152 }
153 };
154
155 const double ratio = .5*(sqrt(5)-1); // an irrational number to minimize chance of intersecting a corner or other point of interest
156 std::vector<int> orientations(contours.size());
157 std::vector<Intersection> intersections;
158 for (int i = 0; i < (int) contours.size(); ++i) {
159 if (!orientations[i] && !contours[i].edges.empty()) {
160 // Find an Y that crosses the contour
161 double y0 = contours[i].edges.front()->point(0).y;
162 double y1 = y0;
163 for (std::vector<EdgeHolder>::const_iterator edge = contours[i].edges.begin(); edge != contours[i].edges.end() && y0 == y1; ++edge)
164 y1 = (*edge)->point(1).y;
165 for (std::vector<EdgeHolder>::const_iterator edge = contours[i].edges.begin(); edge != contours[i].edges.end() && y0 == y1; ++edge)
166 y1 = (*edge)->point(ratio).y; // in case all endpoints are in a horizontal line
167 double y = mix(y0, y1, ratio);
168 // Scanline through whole shape at Y
169 double x[3];
170 int dy[3];
171 for (int j = 0; j < (int) contours.size(); ++j) {
172 for (std::vector<EdgeHolder>::const_iterator edge = contours[j].edges.begin(); edge != contours[j].edges.end(); ++edge) {
173 int n = (*edge)->scanlineIntersections(x, dy, y);
174 for (int k = 0; k < n; ++k) {
175 Intersection intersection = { x[k], dy[k], j };
176 intersections.push_back(intersection);
177 }
178 }
179 }
180 if (!intersections.empty()) {
181 qsort(&intersections[0], intersections.size(), sizeof(Intersection), &Intersection::compare);
182 // Disqualify multiple intersections
183 for (int j = 1; j < (int) intersections.size(); ++j)
184 if (intersections[j].x == intersections[j-1].x)
185 intersections[j].direction = intersections[j-1].direction = 0;
186 // Inspect scanline and deduce orientations of intersected contours
187 for (int j = 0; j < (int) intersections.size(); ++j)
188 if (intersections[j].direction)
189 orientations[intersections[j].contourIndex] += 2*((j&1)^(intersections[j].direction > 0))-1;
190 intersections.clear();
191 }
192 }
193 }
194 // Reverse contours that have the opposite orientation
195 for (int i = 0; i < (int) contours.size(); ++i)
196 if (orientations[i] < 0)
197 contours[i].reverse();
198}
199
200YAxisOrientation Shape::getYAxisOrientation() const {
201 return inverseYAxis ? MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION : MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION;

Callers 4

mainFunction · 0.80
loadSvgShapeFunction · 0.80
parseSvgShapeFunction · 0.80
resolveShapeGeometryFunction · 0.80

Calls 10

mixFunction · 0.85
scanlineIntersectionsMethod · 0.80
sizeMethod · 0.45
emptyMethod · 0.45
pointMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
push_backMethod · 0.45
clearMethod · 0.45
reverseMethod · 0.45

Tested by

no test coverage detected