X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=demo_prior;a=blobdiff_plain;f=libs%2Fdrawtext%2Fsrc%2Fdrawrast.c;fp=libs%2Fdrawtext%2Fsrc%2Fdrawrast.c;h=66543a5a9f028c2a2b5b613f5f93b0d84f89414c;hp=0000000000000000000000000000000000000000;hb=2f14a35e7d557da12f24056267b911f24774aa18;hpb=5eefe7b94c8d6c6caa2c10e3835ab0831a3c42a1 diff --git a/libs/drawtext/src/drawrast.c b/libs/drawtext/src/drawrast.c new file mode 100644 index 0000000..66543a5 --- /dev/null +++ b/libs/drawtext/src/drawrast.c @@ -0,0 +1,199 @@ +/* +libdrawtext - a simple library for fast text rendering in OpenGL +Copyright (C) 2011-2016 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ +#include +#include +#include +#include "drawtext.h" +#include "drawtext_impl.h" + +static const char *drawchar(const char *str, float *xpos, float *ypos, int *should_flush); +static void flush(void); +static void draw_glyph(struct glyph *g, float x, float y); + +static unsigned char *fb_pixels; +static int fb_width, fb_height; +static struct dtx_glyphmap *gmap; +static int threshold = -1; +static int use_alpha; + +void dtx_target_raster(unsigned char *pixels, int width, int height) +{ + fb_pixels = pixels; + fb_width = width; + fb_height = height; + dtx_drawchar = drawchar; + dtx_drawflush = flush; +} + +int dtx_rast_setopt(enum dtx_option opt, int val) +{ + switch(opt) { + case DTX_RASTER_THRESHOLD: + threshold = val; + break; + case DTX_RASTER_BLEND: + use_alpha = val; + break; + default: + return -1; + } + return 0; +} + +int dtx_rast_getopt(enum dtx_option opt, int *res) +{ + switch(opt) { + case DTX_RASTER_THRESHOLD: + *res = threshold; + break; + case DTX_RASTER_BLEND: + *res = use_alpha ? 1 : 0; + break; + default: + return -1; + } + return 0; +} + +static const char *drawchar(const char *str, float *xpos, float *ypos, int *should_flush) +{ + float px, py; + int code = dtx_utf8_char_code(str); + str = dtx_utf8_next_char((char*)str); + + *should_flush = 0; /* the raster renderer never buffers output */ + + px = *xpos; + py = *ypos; + + if((gmap = dtx_proc_char(code, xpos, ypos))) { + int idx = code - gmap->cstart; + draw_glyph(gmap->glyphs + idx, px, py); + } + return str; +} + +static void flush(void) +{ +} + +static void blit_opaque(unsigned char *dest, unsigned char *src, int xsz, int ysz) +{ + int i, j; + int *col = dtx_cur_color_int; + + for(i=0; ixsz; + } +} + +static void blit_thres(unsigned char *dest, unsigned char *src, int xsz, int ysz) +{ + int i, j; + int *col = dtx_cur_color_int; + + for(i=0; i threshold) { + *dest++ = col[0]; + *dest++ = col[1]; + *dest++ = col[2]; + *dest++ = col[3]; + } else { + dest += 4; + } + } + dest += (fb_width - xsz) * 4; + src += gmap->xsz; + } +} + +static void blit_blend(unsigned char *dest, unsigned char *src, int xsz, int ysz) +{ + int i, j, k; + int *col = dtx_cur_color_int; + + for(i=0; ixsz; + } +} + +static void draw_glyph(struct glyph *g, float x, float y) +{ + unsigned char *dest, *src; + int gx = (int)g->x; + int gy = (int)g->y; + int gwidth = (int)g->width; + int gheight = (int)g->height; + int ix = (int)(x - g->orig_x); + int iy = (int)(y - gheight + g->orig_y); + + if(ix >= fb_width || iy >= fb_height) + return; + + if(ix < 0) { + gwidth += ix; + gx -= ix; + ix = 0; + } + if(iy < 0) { + gheight += iy; + gy -= iy; + iy = 0; + } + if(ix + gwidth >= fb_width) { + gwidth = fb_width - ix; + } + if(iy + gheight >= fb_height) { + gheight = fb_height - iy; + } + + if(gwidth <= 0 || gheight <= 0) + return; + + dest = fb_pixels + (iy * fb_width + ix) * 4; + src = gmap->pixels + gy * gmap->xsz + gx; + + if(use_alpha) { + blit_blend(dest, src, gwidth, gheight); + } else if(threshold > 0) { + blit_thres(dest, src, gwidth, gheight); + } else { + blit_opaque(dest, src, gwidth, gheight); + } +} +