| 7 | namespace msdfgen { |
| 8 | |
| 9 | void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) { |
| 10 | if (!(sdf.width > 0 && sdf.height > 0)) |
| 11 | return line.setIntersections(std::vector<Scanline::Intersection>()); |
| 12 | double pixelY = clamp(projection.projectY(y)-.5, double(sdf.height-1)); |
| 13 | if (yAxisOrientation == Y_DOWNWARD) |
| 14 | pixelY = sdf.height-1-pixelY; |
| 15 | int b = (int) floor(pixelY); |
| 16 | int t = b+1; |
| 17 | double bt = pixelY-b; |
| 18 | if (t >= sdf.height) { |
| 19 | b = sdf.height-1; |
| 20 | t = sdf.height-1; |
| 21 | bt = 1; |
| 22 | } |
| 23 | bool inside = false; |
| 24 | std::vector<Scanline::Intersection> intersections; |
| 25 | float lv, rv = mix(*sdf(0, b), *sdf(0, t), bt); |
| 26 | if ((inside = rv > .5f)) { |
| 27 | Scanline::Intersection intersection = { -1e240, 1 }; |
| 28 | intersections.push_back(intersection); |
| 29 | } |
| 30 | for (int l = 0, r = 1; r < sdf.width; ++l, ++r) { |
| 31 | lv = rv; |
| 32 | rv = mix(*sdf(r, b), *sdf(r, t), bt); |
| 33 | if (lv != rv) { |
| 34 | double lr = double(.5f-lv)/double(rv-lv); |
| 35 | if (lr >= 0 && lr <= 1) { |
| 36 | Scanline::Intersection intersection = { projection.unprojectX(l+lr+.5), sign(rv-lv) }; |
| 37 | intersections.push_back(intersection); |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | #ifdef MSDFGEN_USE_CPP11 |
| 42 | line.setIntersections((std::vector<Scanline::Intersection> &&) intersections); |
| 43 | #else |
| 44 | line.setIntersections(intersections); |
| 45 | #endif |
| 46 | } |
| 47 | |
| 48 | template <int N> |
| 49 | void scanlineMSDF(Scanline &line, const BitmapConstSection<float, N> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) { |
no test coverage detected