8 using std::runtime_error;
13 Canvas::Canvas(SDL_Window *win, int index, Uint32 flags)
14 : canv(SDL_CreateRenderer(win, index, flags)) {
16 throw runtime_error(std::string("create canvas: ") + SDL_GetError());
21 if (canv) SDL_DestroyRenderer(canv);
24 Canvas::Canvas(Canvas &&other)
29 Canvas &Canvas::operator =(Canvas &&other) {
30 std::swap(canv, other.canv);
35 void Canvas::Present() {
36 SDL_RenderPresent(canv);
40 Vector<int> Canvas::Size() const {
43 SDL_GetRendererOutputSize(canv, &size.x, &size.y);
48 void Canvas::SetColor(Color c) {
49 SDL_SetRenderDrawColor(canv, c.r, c.g, c.b, c.a);
54 SDL_RenderClear(canv);
57 void Canvas::Outline() {
58 SDL_RenderDrawRect(canv, nullptr);
62 void Canvas::Line(Vector<int> from, Vector<int> to) {
63 SDL_RenderDrawLine(canv, from.x, from.y, to.x, to.y);
66 void Canvas::FillRect(Vector<int> pos, Vector<int> size) {
72 SDL_RenderFillRect(canv, &destRect);
75 void Canvas::OutlineRect(Vector<int> pos, Vector<int> size) {
81 SDL_RenderDrawRect(canv, &destRect);
85 void Canvas::Dot(Vector<int> pos) {
86 SDL_RenderDrawPoint(canv, pos.x, pos.y);
89 void Canvas::Cross(Vector<int> pos, int extent) {
91 Vector<int>(pos.x - extent, pos.y),
92 Vector<int>(pos.x + extent, pos.y));
94 Vector<int>(pos.x, pos.y - extent),
95 Vector<int>(pos.x, pos.y + extent));
101 template<class Scalar>
106 Vector<Scalar> step) {
107 Vector<int> from(pos);
108 Vector<int> to(pos + size);
109 Vector<int> clip(canv.Size());
111 if (from.x > clip.x || from.y > clip.y || to.x < 0 || to.y < 0) {
114 if (step.x <= 1 || step.y <= 1) {
115 canv.FillRect(pos, size);
119 if (from.x < -step.x) {
120 int skip = from.x / -step.x;
121 from.x += skip * step.x;
123 if (from.y < -step.y) {
124 int skip = from.y / -step.y;
125 from.y += skip * step.y;
127 if (to.x > clip.x + step.x) {
128 int skip = (to.x - clip.x) / step.x;
129 to.x -= skip * step.x;
131 if (to.y > clip.y + step.y) {
132 int skip = (to.y - clip.y) / step.y;
133 to.y -= skip * step.y;
136 int width = to.x - from.x;
137 int height = to.y - from.y;
139 for (Vector<Scalar> pos(from); pos.x <= to.x; pos.x += step.x) {
140 canv.Line(pos, Vector<int>(pos.x, pos.y + height));
142 for (Vector<Scalar> pos(from); pos.y <= to.y; pos.y += step.y) {
143 canv.Line(pos, Vector<int>(pos.x + width, pos.y));
147 template<class Scalar>
156 Vector<int> from(pos);
157 Vector<int> to(pos + size);
158 Vector<int> clip(canv.Size());
160 if (from.x > clip.x || from.y > clip.y || to.x < 0 || to.y < 0) {
163 if (step.x <= 1 || step.y <= 1) {
165 canv.FillRect(pos, size);
167 GridImpl(canv, pos, size, step);
173 if (from.x < -step.x) {
174 int skip = from.x / -step.x;
175 from.x += skip * step.x;
178 if (from.y < -step.y) {
179 int skip = from.y / -step.y;
180 from.y += skip * step.y;
183 if (to.x > clip.x + step.x) {
184 int skip = (to.x - clip.x) / step.x;
185 to.x -= skip * step.x;
187 if (to.y > clip.y + step.y) {
188 int skip = (to.y - clip.y) / step.y;
189 to.y -= skip * step.y;
192 int width = to.x - from.x;
193 int height = to.y - from.y;
195 for (Vector<Scalar> pos(from); pos.x <= to.x; pos.x += step.x) {
196 canv.SetColor((i.x++ % n.x) ? c1 : c2);
197 canv.Line(pos, Vector<int>(pos.x, pos.y + height));
199 for (Vector<Scalar> pos(from); pos.y <= to.y; pos.y += step.y) {
200 canv.SetColor((i.y++ % n.y) ? c1 : c2);
201 canv.Line(pos, Vector<int>(pos.x + width, pos.y));
207 void Canvas::Grid(Vector<int> pos, Vector<int> size, Vector<int> step) {
208 GridImpl(*this, pos, size, step);
211 void Canvas::Grid(Vector<int> pos, Vector<int> size, Vector<float> step) {
212 GridImpl(*this, pos, size, step);
216 Vector<int> pos, Vector<int> size, Vector<int> step,
217 Vector<int> n, Color c1, Color c2) {
218 Grid2Impl(*this, pos, size, step, n, c1, c2);
222 Vector<int> pos, Vector<int> size, Vector<float> step,
223 Vector<int> n, Color c1, Color c2) {
224 Grid2Impl(*this, pos, size, step, n, c1, c2);