diff options
Diffstat (limited to '7_2')
-rw-r--r-- | 7_2/Makefile | 16 | ||||
-rw-r--r-- | 7_2/data | 4 | ||||
-rw-r--r-- | 7_2/include/common.h | 32 | ||||
-rw-r--r-- | 7_2/include/drawable.h | 55 | ||||
-rw-r--r-- | 7_2/include/figure.h | 56 | ||||
-rw-r--r-- | 7_2/include/input.h | 24 | ||||
-rw-r--r-- | 7_2/main.c | 44 | ||||
-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 |
10 files changed, 0 insertions, 599 deletions
diff --git a/7_2/Makefile b/7_2/Makefile deleted file mode 100644 index 7c29431..0000000 --- a/7_2/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -all: main - -build: - mkdir -p build - -build/%.o: src/%.c include/%.h build - $(CC) -c -g -ggdb -o $@ $< -Iinclude - -main: main.c build/drawable.o build/figure.o build/input.o - $(CC) -o $@ $^ -lm -lX11 -Iinclude - -.PHONY: clean - -clean: - $(RM) *.o main build/* diff --git a/7_2/data b/7_2/data deleted file mode 100644 index 9d831b7..0000000 --- a/7_2/data +++ /dev/null @@ -1,4 +0,0 @@ -l {0, 1} {1, 2}; -r {2, 2} {40, 18}; - -c {20, 20} 10; diff --git a/7_2/include/common.h b/7_2/include/common.h deleted file mode 100644 index 660532f..0000000 --- a/7_2/include/common.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef JAC_COMMON_H -#define JAC_COMMON_H - -/* Для чтающих: - * чтобы писать - * `vector2 point = { 10, 20 };` - * вместо - * `struct vector2 point = { 10, 20 };` - * (то есть чтобы писать struct перед vector2 было необязательно) - * надо объявлять структуру так: - * ``` - * typedef struct { - * long x, y; - * } vector2; - * ``` - * Таким образом мы объявляем структуру без официального названия, - * но присваиваем ей синоним. Чтобы пользоваться и тем, и тем вариантами, - * можно сделать так: - * ``` - * typedef struct vector2 { - * long x, y; - * } vector2; - * ``` - * Так мы и даём ей название, и даём ей синоним. - */ - -// координаты точки в 2-мерном пространстве -typedef struct vector2 { - long x, y; -} vector2; - -#endif // JAC_COMMON_H diff --git a/7_2/include/drawable.h b/7_2/include/drawable.h deleted file mode 100644 index 8986342..0000000 --- a/7_2/include/drawable.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef JCG_DRAWABLE_H -#define JCG_DRAWABLE_H - -#define FILL_CHR '#' -#define SPACE_CHR ' ' - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -extern struct X11context { - enum {CTX_NO, CTX_INIT, CTX_FAIL} init; - Display *d; - Window r, w; - int s; - GC gctx; - XVisualInfo v; - XImage *i; - int* data; -} X11; - -// что угодно, на чём можно ''нарисовать'' -// должно иметь размер, размер пикселей, данные -// функция put записывает пиксель по координатам x, y на поле -// функция show выводит данные на экран/куда угодно ещё -struct drawable { - long x, y, pix_s; - void *data; - void (*put)(struct drawable *self, long x, long y); - void(*show)(const struct drawable *self); -}; - - -// конструктор -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); -// деструктор -void drawable_destroy(struct drawable *self); -// конструктор для консольного поля -struct drawable drawable_plaintxt(long width, long height); -// конструктор для графического поля -struct drawable drawable_X11(long width, long height); - -// put для консольного drawable -void put_plaintxt(struct drawable *self, long x, long y); -// show для консольного drawable -void show_plaintxt(const struct drawable *self); -// put для графического drawable -void put_X11(struct drawable *self, long x, long y); -// show для графического drawable -void show_X11(const struct drawable *self); - -#endif // JCG_DRAWABLE_H diff --git a/7_2/include/figure.h b/7_2/include/figure.h deleted file mode 100644 index 393ca00..0000000 --- a/7_2/include/figure.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef JCG_FIGURE_H -#define JCG_FIGURE_H - -#include "drawable.h" -#include "common.h" - -// любая фигура -// создаётся функциями figure_point, figure_line и т.д. -// у каждой фигуры должен быть способ "нарисоваться" на -// любое "рисовальное" поле, используя функцию drawable.put -struct figure { - enum { - F_NONE, F_POINT, F_RECT, F_LINE, F_CIRCLE - } type; - union { - struct { - vector2 coords; - } point; - struct { - vector2 upleft, downright; - } rect; - struct { - vector2 start, end; - } line; - struct { - vector2 center; - long rad; - } circle; - }; - void (*draw)(const struct figure *self, struct drawable *d); -}; - -// массив функций по типам (lookup table) -extern void (*const draw_lookup[])(const struct figure *, struct drawable *); - -// конструктор 1 -struct figure figure_point(vector2 p); -// конструктор 2 -struct figure figure_rect(vector2 upleft, vector2 downright); -// конструктор 3 -struct figure figure_line(vector2 start, vector2 end); -// конструктор 4 -struct figure figure_circle(vector2 center, long radius); - -// draw для F_POINT -void draw_point(const struct figure *self, struct drawable *d); -// draw для F_RECT -void draw_rect(const struct figure *self, struct drawable *d); -// draw для F_LINE -void draw_line(const struct figure *self, struct drawable *d); -// draw для F_CIRCLE -void draw_circle(const struct figure *self, struct drawable *f); - -void print_figure(const struct figure *self); - -#endif // JCG_FIGURE_H diff --git a/7_2/include/input.h b/7_2/include/input.h deleted file mode 100644 index 24285b8..0000000 --- a/7_2/include/input.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef JAC_INPUT_H -#define JAC_INPUT_H - -#include "common.h" -#include "figure.h" - -extern void(*settings_handler)(const char *sett_string); - -// пропустить пробелы -void skipw(char const **s); -// проспустит цифры -void skipd(char const **s); -// проерить наличие символа -char chktok(char const **str, char tok); -// прочитать число -char parsel(char const **str, long *l); -// прочитать вектор из 2 чисел -char parsev(char const **str, vector2 *v); -// прочитать одну фигуру -struct figure read_figure(const char *str); -// прочитать целый файл -struct figure *read_file(const char *path); - -#endif // JAC_INPUT_H diff --git a/7_2/main.c b/7_2/main.c deleted file mode 100644 index edb4b76..0000000 --- a/7_2/main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include <X11/Xlib.h> - -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "input.h" -#include "drawable.h" -#include "figure.h" - -long fatness = 1; // пока никак не используется - -int sx = 100, sy = 100; - -int main(int argc, char *argv[]) { - char file[256] = {}; - if (argc >= 2) { - size_t len = strlen(argv[1]); - memcpy(file, argv[1], len > 255 ? 255 : len); - } else { - printf("введите файл: "); - scanf("%255s", file); - } - char x11 = 0; - for (int i = 0; i < argc; ++i) { - if (!strcmp("-X", argv[i])) x11 = 1; - } - struct figure *fs = read_file(file); - struct drawable d = x11 ? drawable_X11(sx, sy) : drawable_plaintxt(sx, sy); - if (!fs) { - fprintf(stderr, "ERROR: errno %i: %s\n", errno, strerror(errno)); - return 1; - } - for (struct figure *i = fs; i->type != F_NONE; ++i) - i->draw(i, &d); - - d.show(&d); - free(fs); - drawable_destroy(&d); - return 0; -} - 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; -} - |