MCPcopy Create free account
hub / github.com/VCVRack/Rack / svgDraw

Function svgDraw

src/window/Svg.cpp:141–296  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

139}
140
141void svgDraw(NVGcontext* vg, NSVGimage* svg) {
142 DEBUG_ONLY(printf("new image: %g x %g px\n", svg->width, svg->height);)
143 int shapeIndex = 0;
144 // Iterate shape linked list
145 for (NSVGshape* shape = svg->shapes; shape; shape = shape->next, shapeIndex++) {
146 DEBUG_ONLY(printf(" new shape: %d id \"%s\", fillrule %d, from (%f, %f) to (%f, %f)\n", shapeIndex, shape->id, shape->fillRule, shape->bounds[0], shape->bounds[1], shape->bounds[2], shape->bounds[3]);)
147
148 // Visibility
149 if (!(shape->flags & NSVG_FLAGS_VISIBLE))
150 continue;
151
152 nvgSave(vg);
153
154 // Opacity
155 if (shape->opacity < 1.0)
156 nvgAlpha(vg, shape->opacity);
157
158 // Build path
159 nvgBeginPath(vg);
160
161 // Iterate path linked list
162 for (NSVGpath* path = shape->paths; path; path = path->next) {
163 DEBUG_ONLY(printf(" new path: %d points, %s, from (%f, %f) to (%f, %f)\n", path->npts, path->closed ? "closed" : "open", path->bounds[0], path->bounds[1], path->bounds[2], path->bounds[3]);)
164
165 nvgMoveTo(vg, path->pts[0], path->pts[1]);
166 for (int i = 1; i < path->npts; i += 3) {
167 float* p = &path->pts[2 * i];
168 nvgBezierTo(vg, p[0], p[1], p[2], p[3], p[4], p[5]);
169 // nvgLineTo(vg, p[4], p[5]);
170 DEBUG_ONLY(printf(" bezier (%f, %f) to (%f, %f)\n", p[-2], p[-1], p[4], p[5]);)
171 }
172
173 // Close path
174 if (path->closed)
175 nvgClosePath(vg);
176
177 // Compute whether this is a hole or a solid.
178 // Assume that no paths are crossing (usually true for normal SVG graphics).
179 // Also assume that the topology is the same if we use straight lines rather than Beziers (not always the case but usually true).
180 // Using the even-odd fill rule, if we draw a line from a point on the path to a point outside the boundary (e.g. top left) and count the number of times it crosses another path, the parity of this count determines whether the path is a hole (odd) or solid (even).
181 int crossings = 0;
182 math::Vec p0 = math::Vec(path->pts[0], path->pts[1]);
183 math::Vec p1 = math::Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.0);
184 // Iterate all other paths
185 for (NSVGpath* path2 = shape->paths; path2; path2 = path2->next) {
186 if (path2 == path)
187 continue;
188
189 // Iterate all lines on the path
190 if (path2->npts < 4)
191 continue;
192 for (int i = 1; i < path2->npts + 3; i += 3) {
193 float* p = &path2->pts[2 * i];
194 // The previous point
195 math::Vec p2 = math::Vec(p[-2], p[-1]);
196 // The current point
197 math::Vec p3 = (i < path2->npts) ? math::Vec(p[4], p[5]) : math::Vec(path2->pts[0], path2->pts[1]);
198 float crossing = getLineCrossing(p0, p1, p2, p3);

Callers 2

drawMethod · 0.85
drawMethod · 0.85

Calls 3

VecClass · 0.85
getLineCrossingFunction · 0.85
getNVGColorFunction · 0.85

Tested by

no test coverage detected