| 1027 | */ |
| 1028 | template<typename XAt, typename YAt> |
| 1029 | inline void dsEmitColumnPoints(std::size_t c, |
| 1030 | ssfp_t scaleY, |
| 1031 | const DownsampleWorkspace* ws, |
| 1032 | XAt xAt, |
| 1033 | YAt yAt, |
| 1034 | QList<QPointF>& out) |
| 1035 | { |
| 1036 | int k = 0; |
| 1037 | std::size_t tmp[4]; |
| 1038 | auto push_unique = [&](std::size_t v) { |
| 1039 | for (int j = 0; j < k; ++j) |
| 1040 | if (tmp[j] == v) |
| 1041 | return; |
| 1042 | |
| 1043 | tmp[k++] = v; |
| 1044 | }; |
| 1045 | |
| 1046 | push_unique(ws->firstI[c]); |
| 1047 | |
| 1048 | const ssfp_t vspan_px = (ws->maxY[c] - ws->minY[c]) * scaleY; |
| 1049 | if (vspan_px >= 1.0) { |
| 1050 | push_unique(ws->minI[c]); |
| 1051 | push_unique(ws->maxI[c]); |
| 1052 | } |
| 1053 | |
| 1054 | push_unique(ws->lastI[c]); |
| 1055 | |
| 1056 | for (int a = 1; a < k; ++a) { |
| 1057 | int b = a - 1; |
| 1058 | std::size_t v = tmp[a]; |
| 1059 | while (b >= 0 && tmp[b] > v) { |
| 1060 | tmp[b + 1] = tmp[b]; |
| 1061 | --b; |
| 1062 | } |
| 1063 | |
| 1064 | tmp[b + 1] = v; |
| 1065 | } |
| 1066 | |
| 1067 | for (int j = 0; j < k; ++j) |
| 1068 | out.append(QPointF(xAt(tmp[j]), yAt(tmp[j]))); |
| 1069 | } |
| 1070 | |
| 1071 | //-------------------------------------------------------------------------------------------------- |
| 1072 | // Downsample 2D series into screen-space pixels |
no test coverage detected