diff options
author | justanothercatgirl <sotov@twistea.su> | 2024-12-06 15:08:31 +0300 |
---|---|---|
committer | justanothercatgirl <sotov@twistea.su> | 2024-12-06 15:08:31 +0300 |
commit | a470c304199866aa1f3d39ff22ec30734f03d617 (patch) | |
tree | b08858e91b39fc108f2ab9b83c03ef7f881711ba /7_2/src | |
parent | 24b8430fa7a9a81b88c5c172c99bbc9a520ff4ba (diff) |
сделал 8 задание))))task8
Diffstat (limited to '7_2/src')
-rw-r--r-- | 7_2/src/drawable.c | 113 | ||||
-rw-r--r-- | 7_2/src/figure.c | 139 | ||||
-rw-r--r-- | 7_2/src/input.c | 116 |
3 files changed, 0 insertions, 368 deletions
diff --git a/7_2/src/drawable.c b/7_2/src/drawable.c deleted file mode 100644 index ab4bf27..0000000 --- a/7_2/src/drawable.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "drawable.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <assert.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -struct X11context X11 = { .init=CTX_NO }; - -struct drawable drawable_plaintxt(long width, long height) { - struct drawable ret; - // with, height +1 because inclusive - drawable_init(&ret, put_plaintxt, show_plaintxt, width + 1, height + 1, sizeof (char)); - memset(ret.data, 0, height*width*1); - return ret; -} -struct drawable drawable_X11(long width, long height) { - struct drawable ret; - drawable_init(&ret, put_X11, show_X11, width, height, sizeof (int)); - int* data = ret.data; - for (size_t i = 0; i < width*height; ++i) - data[i] = 0xFFFFFFFF; - return ret; -} - -void drawable_init(struct drawable* self, - void(*put_f)(struct drawable *, long, long), - void(*show_f)(const struct drawable *), - long width, - long height, - long pix_s) -{ - self->x = width; - self->y = height; - self->pix_s = pix_s; - self->data = malloc(height*width*pix_s); - self->put = put_f; - self->show = show_f; -} - -void drawable_destroy(struct drawable *self) { - free(self->data); -} - -/// plaintxt methods /// - -void put_plaintxt(struct drawable *self, long x, long y) { - if (x >= self->x || y >= self->y || x < 0 || y < 0) return; - char *data = self->data; - data[self->x * y + x] = 1; -} - -void show_plaintxt(const struct drawable *self) { - char map[2] = {SPACE_CHR, FILL_CHR}; - for (int i = 0; i < self->y; ++i) { - for (int j = 0; j < self->x; ++j) { - char *d = self->data; - putchar(map[d[i*self->x + j]]); - } - putchar('\n'); - } -} - - -/// X11 from now on /// - -void init_X11(const struct drawable *self) { - X11.d = XOpenDisplay(NULL); - if (X11.d == NULL) { - X11.init = CTX_FAIL; - printf("why tho???\n"); - return; - } - X11.s = DefaultScreen(X11.d); - X11.r = RootWindow(X11.d, X11.s); - X11.gctx = DefaultGC(X11.d, X11.s); - if (!XMatchVisualInfo(X11.d, X11.s, 24, TrueColor, &X11.v)) { - XDestroyWindow(X11.d, X11.w); - XCloseDisplay(X11.d); - X11.init = CTX_FAIL; - return; - }; - X11.w = XCreateSimpleWindow(X11.d, X11.r, 0, 0, self->x, self->y, 0, 0, 0x00FFFFFF); - XSelectInput(X11.d, X11.w, ExposureMask); - XMapWindow(X11.d, X11.w); - X11.data = self->data; - X11.i = XCreateImage(X11.d, X11.v.visual, X11.v.depth, ZPixmap, 0, (void*)X11.data, self->x, self->y, 32, 0); - X11.init = CTX_INIT; -} - -void put_X11(struct drawable *self, long x, long y) { - if (x >= self->x || y >= self->y || x < 0 || y < 0) return; - int *data = self->data; - data[self->x * y + x] = 0x00000000; -} - -void show_X11(const struct drawable *self) { -start: - switch (X11.init) { - case CTX_NO: init_X11(self); goto start; - case CTX_INIT: break; - case CTX_FAIL: - fprintf(stderr, "Error: Could not initialize Xlib\n"); - return; - } - XEvent e = {}; - while (!XNextEvent(X11.d, &e)) { - XPutImage(X11.d, X11.w, X11.gctx, X11.i, 0, 0, 0, 0, self->x, self->y); - } -} - diff --git a/7_2/src/figure.c b/7_2/src/figure.c deleted file mode 100644 index 290d4af..0000000 --- a/7_2/src/figure.c +++ /dev/null @@ -1,139 +0,0 @@ - -#include "figure.h" -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -void (*const draw_lookup[])(const struct figure *, struct drawable *) = { - [F_NONE] = NULL, - [F_POINT] = draw_point, - [F_RECT] = draw_rect, - [F_LINE] = draw_line, - [F_CIRCLE] = draw_circle -}; - -void swapl(long *x, long *y) { - long tmp = *x; - *x = *y; - *y = tmp; -} - -struct figure figure_point(vector2 p) { - return (struct figure) { - .type = F_POINT, - .point.coords = p, - .draw = draw_point - }; -} - -struct figure figure_rect(vector2 upleft, vector2 downright) { - return (struct figure) { - .type = F_RECT, - .rect = {upleft, downright}, - .draw = draw_rect - }; -} - -struct figure figure_line(vector2 start, vector2 end) { - return (struct figure) { - .type = F_LINE, - .line = {start, end}, - .draw = draw_line - }; -} - -struct figure figure_circle(vector2 center, long radius) { - return (struct figure) { - .type = F_CIRCLE, - .circle = {center, radius}, - .draw = draw_circle - }; -} - - -void draw_point(const struct figure *self, struct drawable *d) { - d->put(d, self->point.coords.x, self->point.coords.y); -} - -void draw_rect(const struct figure *self, struct drawable *d) { - vector2 upleft = self->rect.upleft; - vector2 downright = self->rect.downright; - for (long i = upleft.x; i < downright.x + 1; ++i) { - d->put(d, i, upleft.y); - d->put(d, i, downright.y); - } - for (long j = upleft.y + 1; j < downright.y; ++j) { - d->put(d, upleft.x, j); - d->put(d, downright.x, j); - } -} - -void draw_line(const struct figure *self, struct drawable *d) { - vector2 start = self->line.start; - vector2 end = self->line.end; - char gt45 = labs(end.y - start.y) > labs(end.x - start.x); - long x0 = start.x, y0 = start.y, - x1 = end.x, y1 = end.y; - if (gt45) { - swapl(&x0, &y0); - swapl(&x1, &y1); - } - if (x0 > x1) { - swapl(&x0, &x1); - swapl(&y0, &y1); - } - long dy = labs(y1-y0), - dx = x1 - x0, - err = dx >> 1, // *2 - yinc = (y1 > y0 ? 1 : -1); - - for (long x = x0, y = y0; x <= x1; ++x) { - if (gt45) d->put(d, y, x); - else d->put(d, x, y); - err -= dy; - if (err < 0) { - y += yinc; - err += dx; - } - } -} - -void draw_circle(const struct figure *self, struct drawable *f) { - const vector2 p = self->circle.center; - const long rad = self->circle.rad - 1; - const long pi4 = ceil(M_SQRT1_2 * rad); - long x0 = 0, y0 = rad; - do { - // выглядит коряво, зато в 8 раз меньше повторений цикла - f->put(f, p.x-x0, p.y-y0); // 3 четверть - f->put(f, p.x-x0, p.y+y0); // 2 чет. - f->put(f, p.x+x0, p.y-y0); // 4 ч. - f->put(f, p.x+x0, p.y+y0); // 1 ч - f->put(f, p.x-y0, p.y-x0); - f->put(f, p.x-y0, p.y+x0); - f->put(f, p.x+y0, p.y-x0); - f->put(f, p.x+y0, p.y+x0); - ++x0; - // вычисляем x^2 + (y+1/2)^2 - r^2 - // раскрыли скобки и умножили на 4, чтобы не иметь дело - // с дробными числами (они медленные) - long func = 4*x0*x0 + 4*y0*y0 - 4*y0 + 1 - 4*rad*rad; - y0 = (func >= 0 ? y0 - 1 : y0); - } while (x0 < pi4); -} - -void print_figure(const struct figure *self) { - printf("figure {\n\t.type = %i\n\t{%li, %li},\n\t", self->type, self->line.start.x, self->line.start.y); - switch (self->type) { - case F_LINE: - case F_RECT: - printf("{%li, %li}\n\t", self->line.end.x, self->line.end.y); - break; - case F_CIRCLE: - printf("%li\n\t", self->circle.rad); - // fallthrough - case F_NONE: - case F_POINT:; - } - printf(".draw = %p\n}\n", self->draw); -} diff --git a/7_2/src/input.c b/7_2/src/input.c deleted file mode 100644 index d2dca7c..0000000 --- a/7_2/src/input.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "input.h" - -#include <ctype.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -const char *const unexpchtok = "Unexpected token: %c\n"; -const char *const invalidint = "Invalid integer: %s\n"; - -#define error(fmt, ...) do { \ - fprintf(stderr, fmt, __VA_ARGS__); \ - return 0; \ -} while(0) - -#define maybe_realloc(size, cap, pointer, type) do { \ - if (size >= cap) { \ - cap <<= 1; \ - pointer = realloc(pointer, cap * sizeof (type));\ - } \ -} while(0) - -void(*settings_handler)(const char*) = NULL; - -void skipw(char const **s) { while(isspace(**s)) ++*s; } -void skipd(char const **s) { while(isdigit(**s)) ++*s; } - -char chktok(char const **str, char tok) { - skipw(str); - long tmp = atol(*str); - if (**str != tok) error(unexpchtok, **str); - ++*str; - return 1; -} - -char parsel(char const **str, long *l) { - skipw(str); - long tmp = atoi(*str); - if (tmp == 0 && **str != '0') error(invalidint, *str); - *l = tmp; - skipd(str); - return 1; -} - -char parsev(char const **str, vector2 *v) { - long x, y; - // я ща кончу на этот код - char suc = chktok(str, '{') - && parsel(str, &x) - && chktok(str, ',') - && parsel(str, &y) - && chktok(str, '}'); - if (suc) { - v->x = x; - v->y = y; - return 1; - } else return 0; -} - -struct figure read_figure(const char *str) { - struct figure ret = {.type = F_NONE}; - const char *strp = str; - skipw(&strp); - ++strp; - switch(strp[-1]) { - case '.': { - if (settings_handler != NULL) settings_handler(strp); - } break; - case 'p': { - if (parsev(&strp, &ret.point.coords) - && chktok(&strp, ';')) ret.type = F_POINT; - } break; - case 'r': { - if (parsev(&strp, &ret.rect.upleft) - && parsev(&strp, &ret.rect.downright) - && chktok(&strp, ';')) ret.type = F_RECT; - } break; - case 'l': { - if (parsev(&strp, &ret.line.start) - && parsev(&strp, &ret.line.end) - && chktok(&strp, ';')) ret.type = F_LINE; - } break; - case 'c': { - if (parsev(&strp, &ret.circle.center) - && parsel(&strp, &ret.circle.rad) - && chktok(&strp, ';')) ret.type = F_CIRCLE; - } break; - default:; - } - ret.draw = draw_lookup[ret.type]; - return ret; -} - -struct figure *read_file(const char *path) { - FILE *f = fopen(path, "r"); - if (!f) return NULL; - size_t bs = 1024; - size_t fs = -1, fcap = 16; - char *buf = malloc(fcap * sizeof(struct figure)); - struct figure *figures = malloc(fcap * sizeof (struct figure)); - while (!feof(f)) { - if (getdelim(&buf, &bs, ';', f) < 0) break; - struct figure f = read_figure(buf); - if (f.type == F_NONE) continue; - ++fs; - maybe_realloc(fs, fcap, figures, struct figure); - memcpy(figures + fs, &f, sizeof (struct figure)); - } - ++fs; - maybe_realloc(fs, fcap, figures, struct figure); - struct figure END = {.type = F_NONE, 0}; - memcpy(figures + fs, &END, sizeof (struct figure)); - free(buf); - return figures; -} - |