Root/eeshow/gfx/text.c

1/*
2 * gfx/text.c - FIG text object
3 *
4 * Written 2016 by Werner Almesberger
5 * Copyright 2016 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stddef.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
18
19#include "misc/util.h"
20#include "gfx/misc.h"
21#include "gfx/style.h"
22#include "gfx/gfx.h"
23#include "gfx/text.h"
24
25
26void text_init(struct text *txt)
27{
28    txt->s = NULL;
29    txt->size = 0;
30    txt->x = txt->y = 0;
31    txt->rot = 0;
32    txt->hor = text_mid;
33    txt->vert = text_mid;
34}
35
36
37void text_free(struct text *txt)
38{
39    free((void *) txt->s);
40    txt->s = NULL;
41}
42
43
44void text_set(struct text *txt, const char *s)
45{
46    free((void *) txt->s);
47    txt->s = stralloc(s);
48}
49
50
51void text_rot(struct text *txt, int deg)
52{
53    txt->rot = angle_add(txt->rot, deg);
54}
55
56
57enum text_align text_flip(enum text_align align)
58{
59    switch (align) {
60    case text_min:
61        return text_max;
62    case text_mid:
63        return text_mid;
64    case text_max:
65        return text_min;
66    default:
67        abort();
68    }
69}
70
71
72void text_flip_x(struct text *txt)
73{
74    txt->rot = angle_add(txt->rot, 180);
75    txt->hor = text_flip(txt->hor);
76    // @@@ flip vert, too ?
77}
78
79
80static int align(int dim, enum text_align align)
81{
82    switch (align) {
83    case text_min:
84        return 0;
85    case text_mid:
86        return dim / 2;
87    case text_max:
88        return dim;
89    default:
90        abort();
91    }
92}
93
94
95void text_fig(const struct text *txt, int color, unsigned layer)
96{
97    char *buf = stralloc(txt->s);
98    char *tmp = buf;
99    const char *s;
100    int x = txt->x;
101    int y = txt->y;
102    unsigned multiline = 0;
103
104    for (s = txt->s; *s; s++)
105        if (*s == '\n')
106            multiline += NEWLINE_SKIP * txt->size;
107    x += rx(0, align(txt->size + multiline, txt->vert) - multiline,
108        txt->rot);
109    y += ry(0, align(txt->size + multiline, txt->vert) - multiline,
110        txt->rot);
111    while (1) {
112        s = strtok(tmp, "\n");
113        if (!s)
114            break;
115        tmp = NULL;
116        gfx_text(x, y, s, txt->size, txt->hor, txt->rot, color, layer);
117        x += rx(0, NEWLINE_SKIP * txt->size, txt->rot);
118        y += ry(0, NEWLINE_SKIP * txt->size, txt->rot);
119    }
120    free(buf);
121}
122
123
124void text_rel(const struct text *txt, enum text_align xr, enum text_align yr,
125    int dx, int dy, int *res_x, int *res_y)
126{
127    int width = gfx_text_width(txt->s, txt->size);
128
129    dx -= align(width, txt->hor);
130    dy += align(txt->size, txt->vert);
131    dx += align(width, xr);
132    dy -= align(txt->size, yr);
133    if (res_x)
134        *res_x = txt->x + rx(dx, dy, txt->rot);
135    if (res_y)
136        *res_y = txt->y + ry(dx, dy, txt->rot);
137}
138
139
140void text_shift(struct text *txt, enum text_align xr, enum text_align yr,
141    int dx, int dy)
142{
143    text_rel(txt, xr, yr, dx, dy, &txt->x, &txt->y);
144}
145
146
147int text_rel_x(const struct text *txt, enum text_align xr, enum text_align yr,
148    int dx, int dy)
149{
150    int x;
151
152    text_rel(txt, xr, yr, dx, dy, &x, NULL);
153    return x;
154}
155
156
157int text_rel_y(const struct text *txt, enum text_align xr, enum text_align yr,
158    int dx, int dy)
159{
160    int y;
161
162    text_rel(txt, xr, yr, dx, dy, NULL, &y);
163    return y;
164}
165

Archive Download this file

Branches:
master



interactive