summaryrefslogtreecommitdiff
path: root/web/web_svg.c
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-28 01:06:08 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-28 01:10:21 -0700
commit1db534799ef5b41114d80fce0c38f1c93235a8a3 (patch)
treeabccdc2e7418f27ffbdabe87813fa20c8f8581f2 /web/web_svg.c
parenta0ca7ab5421d001f50fabbc6c139ded380f597d8 (diff)
downloaddartboat-1db534799ef5b41114d80fce0c38f1c93235a8a3.tar.gz
dartboat-1db534799ef5b41114d80fce0c38f1c93235a8a3.tar.xz
web: reduce mem used during drawing of board
Diffstat (limited to 'web/web_svg.c')
-rw-r--r--web/web_svg.c145
1 files changed, 63 insertions, 82 deletions
diff --git a/web/web_svg.c b/web/web_svg.c
index 125f8a4..70dc900 100644
--- a/web/web_svg.c
+++ b/web/web_svg.c
@@ -14,8 +14,8 @@
#define C_GREEN "#22912d"
#define C_WIRE "#909ca0"
#define C_WIRE_INNER "#d8e6ec"
-#define C_NUMBER_RING "#ddd"
#define C_NUMBER "#fff"
+#define C_NUMBER_RING "#ddd"
#define C_POINT "#33f"
#define C_POINT_OUTLINE "#ff0"
@@ -31,7 +31,6 @@ static struct dom_elem *gen_circle(double r, char *col)
struct dom_elem *e = svg_elem_init("circle", 2);
dom_elem_add_attrd(e, "r", r);
dom_elem_add_attr(e, "fill", col);
-
return e;
}
@@ -39,6 +38,8 @@ static struct dom_elem *gen_circle(double r, char *col)
static struct dom_elem *gen_arc(double a1, double a2, double r1, double r2,
char *col)
{
+ struct dom_elem *e = svg_elem_init("path", 2);
+
bool ring = (a1 == a2);
if (ring) {
// these values are not significant. the ring is drawn as two
@@ -53,9 +54,6 @@ static struct dom_elem *gen_arc(double a1, double a2, double r1, double r2,
struct ccoords cc3 = pol_to_cart((struct pcoords){ .a = a1, .r = r2 });
struct ccoords cc4 = pol_to_cart((struct pcoords){ .a = a2, .r = r2 });
- struct dom_elem *e = svg_elem_init("path", 2);
- dom_elem_add_attr(e, "fill", col);
-
// (arc)
// M - move to inner start
// A - draw arc to inner end
@@ -89,6 +87,7 @@ static struct dom_elem *gen_arc(double a1, double a2, double r1, double r2,
r2, r2, cc3.x, cc3.y);
dom_elem_add_attr(e, "d", buf);
+ dom_elem_add_attr(e, "fill", col);
return e;
}
@@ -106,151 +105,133 @@ static struct dom_elem *gen_segment(double a, double r1, double r2, char *col)
static struct dom_elem *gen_line(double a, double r1, double r2, double w,
char *col)
{
+ struct dom_elem *e = svg_elem_init("line", 6);
+
struct ccoords cc1 = pol_to_cart((struct pcoords){ .a = a, .r = r1 });
struct ccoords cc2 = pol_to_cart((struct pcoords){ .a = a, .r = r2 });
-
- struct dom_elem *e = svg_elem_init("line", 6);
dom_elem_add_attrd(e, "x1", cc1.x);
dom_elem_add_attrd(e, "y1", cc1.y);
dom_elem_add_attrd(e, "x2", cc2.x);
dom_elem_add_attrd(e, "y2", cc2.y);
+
dom_elem_add_attr(e, "stroke", col);
dom_elem_add_attrd(e, "stroke-width", w);
-
return e;
}
-static int gen_segments(struct dom_elem **elemv)
+static void add_segments(struct dom_elem *e)
{
- int elemc = 0;
-
for (int i = R_DOUBLE; i > R_25; --i) {
for (int j = 0; j < NUM_SECTORS; ++j) {
double a = 90 - (j * SECTOR_WIDTH);
if (a < 0)
a += 360;
- elemv[elemc++] = gen_segment(a, OUTER_DISTS[i - 1],
- OUTER_DISTS[i],
- i % 2 ? (j % 2 ? C_GREEN : C_RED) :
- (j % 2 ? C_WHITE : C_BLACK));
+ dom_elem_add_child(e,
+ gen_segment(a, OUTER_DISTS[i - 1],
+ OUTER_DISTS[i],
+ i % 2 ? (j % 2 ? C_GREEN : C_RED) :
+ (j % 2 ? C_WHITE : C_BLACK)));
}
}
- elemv[elemc++] = gen_circle(OUTER_DISTS[R_25], C_GREEN);
- elemv[elemc++] = gen_circle(OUTER_DISTS[R_BULL], C_RED);
-
- return elemc;
+ dom_elem_add_child(e, gen_circle(OUTER_DISTS[R_25], C_GREEN));
+ dom_elem_add_child(e, gen_circle(OUTER_DISTS[R_BULL], C_RED));
}
-static int gen_wires(struct dom_elem **elemv)
+static void add_wires(struct dom_elem *e)
{
- int elemc = 0;
-
for (int i = R_DOUBLE; i > R_25; --i) {
- elemv[elemc++] = gen_ring(OUTER_DISTS[i], WIRE_WIDTH, C_WIRE);
- elemv[elemc++] = gen_ring(OUTER_DISTS[i], WIRE_WIDTH / 2,
- C_WIRE_INNER);
+ dom_elem_add_child(e,
+ gen_ring(OUTER_DISTS[i], WIRE_WIDTH, C_WIRE));
+ dom_elem_add_child(e,
+ gen_ring(OUTER_DISTS[i], WIRE_WIDTH / 2,
+ C_WIRE_INNER));
}
for (int i = 0; i < NUM_SECTORS; ++i) {
double a = 90 - (i * SECTOR_WIDTH) - (SECTOR_WIDTH / 2);
if (a < 0)
a += 360;
- elemv[elemc++] = gen_line(a, OUTER_DISTS[R_25],
- OUTER_DISTS[R_DOUBLE] + 10, WIRE_WIDTH, C_WIRE);
- elemv[elemc++] = gen_line(a, OUTER_DISTS[R_25],
- OUTER_DISTS[R_DOUBLE] + 10, WIRE_WIDTH / 2,
- C_WIRE_INNER);
+ dom_elem_add_child(e,
+ gen_line(a, OUTER_DISTS[R_25],
+ OUTER_DISTS[R_DOUBLE] + 10,
+ WIRE_WIDTH, C_WIRE));
+ dom_elem_add_child(e,
+ gen_line(a, OUTER_DISTS[R_25],
+ OUTER_DISTS[R_DOUBLE] + 10,
+ WIRE_WIDTH / 2, C_WIRE_INNER));
}
for (int i = R_25; i >= R_BULL; --i) {
- elemv[elemc++] = gen_ring(OUTER_DISTS[i], WIRE_WIDTH, C_WIRE);
- elemv[elemc++] = gen_ring(OUTER_DISTS[i], WIRE_WIDTH / 2,
- C_WIRE_INNER);
+ dom_elem_add_child(e,
+ gen_ring(OUTER_DISTS[i], WIRE_WIDTH, C_WIRE));
+ dom_elem_add_child(e,
+ gen_ring(OUTER_DISTS[i], WIRE_WIDTH / 2,
+ C_WIRE_INNER));
}
-
- return elemc;
}
-static int gen_numbers(struct dom_elem **elemv)
+static void add_numbers(struct dom_elem *e)
{
- int elemc = 0;
-
- elemv[elemc++] = gen_ring((DIAMETER / 2) - (WIRE_WIDTH * 4),
- WIRE_WIDTH, C_NUMBER_RING);
+ dom_elem_add_child(e,
+ gen_ring((DIAMETER / 2) - (WIRE_WIDTH * 4),
+ WIRE_WIDTH, C_NUMBER_RING));
int r = (DIAMETER / 2) - (33 / 2);
for (int i = 0; i < NUM_SECTORS; ++i) {
- struct dom_elem *e = svg_elem_init("text", 5);
- elemv[elemc++] = e;
-
- dom_elem_add_attr(e, "font-size", "33");
- dom_elem_add_attr(e, "text-anchor", "middle");
- dom_elem_add_attr(e, "dominant-baseline", "central");
- dom_elem_add_attr(e, "fill", C_NUMBER);
+ struct dom_elem *c = svg_elem_init("text", 5);
+ asprintf(&c->content, "%d", SECTORS[i]);
double a = 90 - (i * SECTOR_WIDTH);
if (a < 0)
a += 360;
struct ccoords cc = pol_to_cart(
(struct pcoords){ .a = a, .r = r });
- dom_elem_add_attrf(e, "transform",
+ dom_elem_add_attrf(c, "transform",
"scale(1 -1) translate(%f %f) rotate(%f)",
cc.x, -cc.y, a <= 180 ? 90 - a : 270 - a);
- asprintf(&e->content, "%d", SECTORS[i]);
+ dom_elem_add_attr(c, "font-size", "33");
+ dom_elem_add_attr(c, "text-anchor", "middle");
+ dom_elem_add_attr(c, "dominant-baseline", "central");
+ dom_elem_add_attr(c, "fill", C_NUMBER);
+ dom_elem_add_child(e, c);
}
-
- return elemc;
}
-static void draw_board()
+static void add_board(struct dom_elem *e)
{
- struct dom_elem **elemv = malloc(200 * sizeof(*elemv));
- int elemc = 0;
-
- elemv[elemc++] = gen_circle(DIAMETER / 2, C_BLACK);
- elemc += gen_segments(elemv + elemc);
- elemc += gen_wires(elemv + elemc);
- elemc += gen_numbers(elemv + elemc);
-
- dom_append_elemv("#dartboard .base", elemc, elemv);
-
- for (int i = 0; i < elemc; ++i)
- dom_elem_free(elemv[i]);
- free(elemv);
+ dom_elem_add_child(e, gen_circle(DIAMETER / 2, C_BLACK));
+ add_segments(e);
+ add_wires(e);
+ add_numbers(e);
}
-static void create_board()
+static void draw_board()
{
- struct dom_elem *e = svg_elem_init("svg", 2);
- dom_elem_add_attr(e, "id", "dartboard");
- dom_elem_add_attrf(e, "viewBox", "0 0 %f %f", DIAMETER, DIAMETER);
- dom_append_elemv("#dartboard-container", 1, &e);
- free(e);
-
- struct dom_elem **elemv = malloc(2 * sizeof(*elemv));
- int elemc = 0;
+ struct dom_elem *svg = svg_elem_init("svg", 2);
+ dom_elem_add_attr(svg, "id", "dartboard");
+ dom_elem_add_attrf(svg, "viewBox", "0 0 %f %f", DIAMETER, DIAMETER);
for (int i = 0; i < 2; ++i) {
struct dom_elem *e = svg_elem_init("g", 2);
- dom_elem_add_attr(e, "class", i ? "overlay" : "base");
+ dom_elem_add_attr(e, "class", i ? "overlay" : "board");
dom_elem_add_attrf(e, "transform",
"translate(%f %f) scale(1 -1)",
DIAMETER / 2, DIAMETER / 2);
- elemv[elemc++] = e;
- }
- dom_append_elemv("#dartboard", elemc, elemv);
+ if (!i)
+ add_board(e);
+
+ dom_elem_add_child(svg, e);
+ }
- for (int i = 0; i < elemc; ++i)
- dom_elem_free(elemv[i]);
- free(elemv);
+ dom_append_elemv("#dartboard-container", 1, &svg);
+ dom_elem_free(svg);
}
void svg_init()
{
- create_board();
draw_board();
}