/* * text.c - FIG text object * * Written 2016 by Werner Almesberger * Copyright 2016 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include "util.h" #include "misc.h" #include "fig.h" #include "text.h" void text_init(struct text *txt) { txt->s = NULL; txt->size = 0; txt->x = txt->y = 0; txt->rot = 0; txt->hor = text_mid; txt->vert = text_mid; } void text_free(struct text *txt) { free((void *) txt->s); txt->s = NULL; } void text_set(struct text *txt, const char *s) { free((void *) txt->s); txt->s = stralloc(s); } void text_rot(struct text *txt, int deg) { txt->rot = angle_add(txt->rot, deg); } enum text_align text_flip(enum text_align align) { switch (align) { case text_min: return text_max; case text_mid: return text_mid; case text_max: return text_min; default: abort(); } } void text_flip_x(struct text *txt) { txt->rot = angle_add(txt->rot, 180); txt->hor = text_flip(txt->hor); // @@@ flip vert, too ? } static int rx(int x, int y, int rot) { float a = rot / 180.0 * M_PI; return cos(a) * x + sin(a) * y; } static int ry(int x, int y, int rot) { float a = rot / 180.0 * M_PI; return -sin(a) * x + cos(a) * y; } static int align(int dim, enum text_align align) { switch (align) { case text_min: return 0; case text_mid: return dim / 2; case text_max: return dim; default: abort(); } } void text_fig(const struct text *txt, int color, unsigned layer) { int x = txt->x; int y = txt->y; x += rx(0, align(txt->size, txt->vert), txt->rot); y += ry(0, align(txt->size, txt->vert), txt->rot); fig_text(x, y, txt->s, txt->size, txt->hor, txt->rot, color, layer); } static unsigned guess_width(const struct text *txt) { /* * Note that fig.c stretches the text size, so the ratio is larger than * expressed here. */ return strlen(txt->s) * txt->size * 1.0; } void text_rel(const struct text *txt, enum text_align xr, enum text_align yr, int dx, int dy, int *res_x, int *res_y) { dx -= align(guess_width(txt), txt->hor); dy += align(txt->size, txt->vert); dx += align(guess_width(txt), xr); dy -= align(txt->size, yr); if (res_x) *res_x = txt->x + rx(dx, dy, txt->rot); if (res_y) *res_y = txt->y + ry(dx, dy, txt->rot); } void text_shift(struct text *txt, enum text_align xr, enum text_align yr, int dx, int dy) { text_rel(txt, xr, yr, dx, dy, &txt->x, &txt->y); } int text_rel_x(const struct text *txt, enum text_align xr, enum text_align yr, int dx, int dy) { int x; text_rel(txt, xr, yr, dx, dy, &x, NULL); return x; } int text_rel_y(const struct text *txt, enum text_align xr, enum text_align yr, int dx, int dy) { int y; text_rel(txt, xr, yr, dx, dy, NULL, &y); return y; }