2 libdrawtext - a simple library for fast text rendering in OpenGL
3 Copyright (C) 2011-2016 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 static const char *drawchar(const char *str, float *xpos, float *ypos, int *should_flush);
25 static void flush(void);
26 static void draw_glyph(struct glyph *g, float x, float y);
28 static unsigned char *fb_pixels;
29 static int fb_width, fb_height;
30 static struct dtx_glyphmap *gmap;
31 static int threshold = -1;
34 void dtx_target_raster(unsigned char *pixels, int width, int height)
39 dtx_drawchar = drawchar;
40 dtx_drawflush = flush;
43 int dtx_rast_setopt(enum dtx_option opt, int val)
46 case DTX_RASTER_THRESHOLD:
49 case DTX_RASTER_BLEND:
58 int dtx_rast_getopt(enum dtx_option opt, int *res)
61 case DTX_RASTER_THRESHOLD:
64 case DTX_RASTER_BLEND:
65 *res = use_alpha ? 1 : 0;
73 static const char *drawchar(const char *str, float *xpos, float *ypos, int *should_flush)
76 int code = dtx_utf8_char_code(str);
77 str = dtx_utf8_next_char((char*)str);
79 *should_flush = 0; /* the raster renderer never buffers output */
84 if((gmap = dtx_proc_char(code, xpos, ypos))) {
85 int idx = code - gmap->cstart;
86 draw_glyph(gmap->glyphs + idx, px, py);
91 static void flush(void)
95 static void blit_opaque(unsigned char *dest, unsigned char *src, int xsz, int ysz)
98 int *col = dtx_cur_color_int;
100 for(i=0; i<ysz; i++) {
101 for(j=0; j<xsz; j++) {
103 *dest++ = val * col[0] / 255;
104 *dest++ = val * col[1] / 255;
105 *dest++ = val * col[2] / 255;
108 dest += (fb_width - xsz) * 4;
113 static void blit_thres(unsigned char *dest, unsigned char *src, int xsz, int ysz)
116 int *col = dtx_cur_color_int;
118 for(i=0; i<ysz; i++) {
119 for(j=0; j<xsz; j++) {
121 if(val > threshold) {
130 dest += (fb_width - xsz) * 4;
135 static void blit_blend(unsigned char *dest, unsigned char *src, int xsz, int ysz)
138 int *col = dtx_cur_color_int;
140 for(i=0; i<ysz; i++) {
141 for(j=0; j<xsz; j++) {
143 int inv_alpha = 255 - alpha;
146 dest[k] = (col[k] * alpha + dest[k] * inv_alpha) / 255;
150 dest += (fb_width - xsz) * 4;
155 static void draw_glyph(struct glyph *g, float x, float y)
157 unsigned char *dest, *src;
160 int gwidth = (int)g->width;
161 int gheight = (int)g->height;
162 int ix = (int)(x - g->orig_x);
163 int iy = (int)(y - gheight + g->orig_y);
165 if(ix >= fb_width || iy >= fb_height)
178 if(ix + gwidth >= fb_width) {
179 gwidth = fb_width - ix;
181 if(iy + gheight >= fb_height) {
182 gheight = fb_height - iy;
185 if(gwidth <= 0 || gheight <= 0)
188 dest = fb_pixels + (iy * fb_width + ix) * 4;
189 src = gmap->pixels + gy * gmap->xsz + gx;
192 blit_blend(dest, src, gwidth, gheight);
193 } else if(threshold > 0) {
194 blit_thres(dest, src, gwidth, gheight);
196 blit_opaque(dest, src, gwidth, gheight);