Project

General

Profile

Statistics
| Revision:

root / proj / src / font.c @ 183

History | View | Annotate | Download (4.71 KB)

1 182 up20180642
#include <lcom/lcf.h>
2
3
#include "font.h"
4
5 183 up20180642
#include "xpm_utils.h"
6
#include "graph.h"
7
#include "utils.h"
8
#include "errors.h"
9
10 182 up20180642
struct glyph{
11
    uint16_t w, h;
12
    uint8_t *map;
13
};
14 183 up20180642
typedef struct glyph glyph_t;
15
static glyph_t* (glyph_ctor)(const char **xpm){
16
    if(xpm == NULL) return NULL;
17 182 up20180642
    glyph_t *ret = malloc(sizeof(glyph_t));
18
    if(ret == NULL) return NULL;
19
    enum xpm_image_type type = XPM_8_8_8_8;
20
    xpm_image_t img;
21
    ret->map = xpm_load((xpm_map_t)xpm, type, &img);
22
    if(ret->map == NULL){
23
        free(ret);
24
        return NULL;
25
    }
26
    ret->w = img.width;
27
    ret->h = img.height;
28
    return ret;
29
}
30 183 up20180642
static void (glyph_dtor)(glyph_t *p){
31 182 up20180642
    if(p == NULL) return;
32
    free(p->map);
33
    free(p);
34
}
35 183 up20180642
static int (glyph_draw_to_alpha_buffer)(const glyph_t *p, int16_t x, int16_t y, uint8_t *alp_buf, uint16_t W, uint16_t H){
36
    if(p == NULL) return NULL_PTR;
37
    int r;
38
    for(int16_t h = 0; h < p->h; ++h){
39
        for(int16_t w = 0; w < p->w; ++w){
40
            uint32_t c = *((uint32_t*)p->map + w + h*p->w);
41
            uint8_t a = GET_ALP(c);
42
            //c = c & 0xFF000000;
43
            //if(c != 0) printf("%d %d 0x%X\n", w, h, c);
44
            //else       printf("%d %d <========================\n");
45
46
            r = graph_set_pixel_alpha_buffer(x+w, y-p->h+h, a, alp_buf, W, H);
47
48
49
            //r = graph_set_pixel_alpha(x+w, y-p->h+h, GET_COLOR(c), GET_ALP(c));
50
51
            //printf("%d %d 0x%X\n", x, y, *(buf+(x+y*p->w)*sizeof(uint32_t)));
52
            if(r != SUCCESS && r != OUT_OF_RANGE) return r;
53
        }
54
    }
55
    return SUCCESS;
56
}
57
58
struct font{
59
    size_t nchars;
60
    glyph_t **glyphs;
61
};
62
#include "sprite.h"
63
#include "rectangle.h"
64
font_t* (font_ctor)(const char *s){
65
    font_t *ret = malloc(sizeof(font_t));
66
    if(ret == NULL) return NULL;
67
    ret->nchars = 128;
68
    ret->glyphs = malloc(ret->nchars*sizeof(glyph_t*));
69
    if(ret->glyphs == NULL){
70
        free(ret->glyphs);
71
        free(ret);
72
        return NULL;
73
    }
74
    char filepath[1024];
75
    for(size_t i = 0; i < ret->nchars; ++i){
76
        sprintf(filepath, "%s/ascii%03d.xpm2", s, i);
77
        char **xpm = xpm_load_xpm2(filepath);
78
        ret->glyphs[i] = glyph_ctor((const char**)xpm);
79
    }
80
    return ret;
81
}
82
void (font_dtor)(font_t *p){
83
    if(p == NULL) return;
84
    for(size_t i = 0; i < p->nchars; ++i)
85
        glyph_dtor(p->glyphs[i]);
86
    free(p->glyphs);
87
    free(p);
88
}
89
90
struct text{
91
    const font_t *fnt;
92
    char *txt;
93
    int16_t x, y;
94
    int size;
95
    uint32_t color;
96
};
97
text_t* (text_ctor)(const font_t *fnt, const char *txt){
98
    if(fnt == NULL) return NULL;
99
    text_t *ret = malloc(sizeof(text_t));
100
    if(ret == NULL) return NULL;
101
    ret->fnt = fnt;
102
    ret->txt = NULL;
103
    text_set_text(ret, txt);
104
    ret->x = 0;
105
    ret->y = 0;
106
    ret->size = 70;
107
    ret->color = BLACK;
108
    return ret;
109
}
110
void (text_dtor)(text_t *p){
111
    if(p == NULL) return;
112
    free(p->txt);
113
    free(p);
114
}
115
void (text_set_text) (text_t *p, const char *txt){
116
    size_t sz = strlen(txt);
117
    p->txt = realloc(p->txt, (sz+1)*sizeof(char));
118
    if(p->txt == NULL) return;
119
    strcpy(p->txt, txt);
120
}
121
void (text_set_pos)  (text_t *p, int16_t x, int16_t y){ p->x = x; p->y = y; }
122
void (text_set_size) (text_t *p, unsigned size       ){ p->size = size;     }
123
void (text_set_color)(text_t *p, uint32_t color      ){ p->color = color;   }
124
void (text_draw)(const text_t *p){
125
    printf("-%s-\n", p->txt);
126
    const size_t len = strlen(p->txt);
127
    uint16_t W = 0, H = 0;
128
    for(size_t i = 0; i < len; ++i){
129
        const glyph_t *g = p->fnt->glyphs[(size_t)p->txt[i]];
130
        if(g != NULL){ W += g->w; H = max(H, g->h); }
131
    }
132
    printf("%d %d\n", W, H);
133
134
    uint8_t *alp_buf = malloc(W*H);
135
136
    {
137
        int16_t y = H;
138
        int16_t x = 0;
139
        for(size_t i = 0; i < len; ++i){
140
            const glyph_t *g = p->fnt->glyphs[(size_t)p->txt[i]];
141
            if(g != NULL){
142
                if(glyph_draw_to_alpha_buffer(g, x, y, alp_buf, W, H)) return;
143
                x += g->w;
144
            }
145
        }
146
    }
147
    double factor = (double)p->size/(double)H;
148
149
    uint16_t newH = H*factor;
150
    uint16_t newW = W*factor;
151
152
    for(size_t newy = 0; newy < newH; ++newy){
153
        size_t y = newy/factor;
154
        for(size_t newx = 0; newx < newW; ++newx){
155
            size_t x = newx/factor;
156
            *(alp_buf+newx+newy*W) = *(alp_buf+x+y*W);
157
            (void)x;
158
            (void)y;
159
        }
160
    }
161
162
    printf("L163\n");
163
    for(int16_t y = 0; y < newH; ++y){ //printf("L163,%d\n", y);
164
        for(int16_t x = 0; x < newW; ++x){ //if(y > 147) printf("L164, %d %d\n", x, y);
165
            uint8_t a = *(alp_buf+x+y*W); //if(y > 147) printf("L165\n");
166
            graph_set_pixel_alpha(x+p->x,y+p->y,p->color, a); //if(y > 147) printf("L166\n");
167
        }
168
    }
169
    printf("L170\n");
170
    free(alp_buf);
171
    printf("L172\n");
172
}