| 1047 | } |
| 1048 | |
| 1049 | void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step) |
| 1050 | { |
| 1051 | if (radius < 0.5f) |
| 1052 | { |
| 1053 | _Path.push_back(center); |
| 1054 | return; |
| 1055 | } |
| 1056 | |
| 1057 | // Calculate arc auto segment step size |
| 1058 | if (a_step <= 0) |
| 1059 | a_step = IM_DRAWLIST_ARCFAST_SAMPLE_MAX / _CalcCircleAutoSegmentCount(radius); |
| 1060 | |
| 1061 | // Make sure we never do steps larger than one quarter of the circle |
| 1062 | a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4); |
| 1063 | |
| 1064 | const int sample_range = ImAbs(a_max_sample - a_min_sample); |
| 1065 | const int a_next_step = a_step; |
| 1066 | |
| 1067 | int samples = sample_range + 1; |
| 1068 | bool extra_max_sample = false; |
| 1069 | if (a_step > 1) |
| 1070 | { |
| 1071 | samples = sample_range / a_step + 1; |
| 1072 | const int overstep = sample_range % a_step; |
| 1073 | |
| 1074 | if (overstep > 0) |
| 1075 | { |
| 1076 | extra_max_sample = true; |
| 1077 | samples++; |
| 1078 | |
| 1079 | // When we have overstep to avoid awkwardly looking one long line and one tiny one at the end, |
| 1080 | // distribute first step range evenly between them by reducing first step size. |
| 1081 | if (sample_range > 0) |
| 1082 | a_step -= (a_step - overstep) / 2; |
| 1083 | } |
| 1084 | } |
| 1085 | |
| 1086 | _Path.resize(_Path.Size + samples); |
| 1087 | ImVec2* out_ptr = _Path.Data + (_Path.Size - samples); |
| 1088 | |
| 1089 | int sample_index = a_min_sample; |
| 1090 | if (sample_index < 0 || sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) |
| 1091 | { |
| 1092 | sample_index = sample_index % IM_DRAWLIST_ARCFAST_SAMPLE_MAX; |
| 1093 | if (sample_index < 0) |
| 1094 | sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX; |
| 1095 | } |
| 1096 | |
| 1097 | if (a_max_sample >= a_min_sample) |
| 1098 | { |
| 1099 | for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step) |
| 1100 | { |
| 1101 | // a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more |
| 1102 | if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) |
| 1103 | sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX; |
| 1104 | |
| 1105 | const ImVec2 s = _Data->ArcFastVtx[sample_index]; |
| 1106 | out_ptr->x = center.x + s.x * radius; |