#ifdef GFX_TEXT_COORD int txt_offset(int *xc, int *yc, int ox, int oy, int x, int y, int h, int x1, int y1, int x2, int y2, font_t *font, const char *str) { #undef GFX_TEXT_COORD #define GFX_TEXT_OFFSET #endif #ifdef GFX_TEXT_SIZE void txt_coord(int *xc, int *yc, int offset, int x, int y, int h, int x1, int y1, int x2, int y2, font_t *font, const char *str) { #undef GFX_TEXT_SIZE #define GFX_TEXT_COORD #endif #ifdef GFX_TEXT_DRAW_R void txt_size(int *xs, int *ys, int x, int y, int w, int h, int l, int x1, int y1, int x2, int y2, font_t *font, const char *str) { #undef GFX_TEXT_DRAW_R #define GFX_TEXT_SIZE #endif #ifdef GFX_TEXT_DRAW byte txt_draw_range(int start, int end, int x, int y, int w, int h, int l, int x1, int y1, int x2, int y2, uint color, uint back, font_t *font, const char *str) { #define GFX_TEXT_DRAW_R #endif #ifndef GFX_TEXT_BASE byte txt_draw(int x, int y, int w, int h, int l, int x1, int y1, int x2, int y2, uint color, uint back, font_t *font, const char *str) { #define GFX_TEXT_BASE #define GFX_TEXT_DRAW #endif #ifdef GFX_TEXT_SIZE int ix = x; int iy = y; #endif #if defined(GFX_TEXT_OFFSET) || defined(GFX_TEXT_COORD) int w = 0; int l = h; #endif int tx, ty, u, v; fchar_t glyph; uint tex; uint ch; #if defined(GFX_TEXT_OFFSET) || defined(GFX_TEXT_COORD) || defined(GFX_TEXT_DRAW_R) int pos = 0; int lpos = 0; #endif #ifdef GFX_TEXT_DRAW byte flags; byte sflags; #endif x = (w && l < 0) ? x+l : x; y = (h && l < 0) ? y+l : y; #ifdef GFX_TEXT_OFFSET if(oy < y) { return 0; } ox = ox < x1 ? x1 : ox; #endif #ifdef GFX_TEXT_DRAW shd_sel(gdr.shd_text, NULL); shd_vec2v("font_size", (float)font->xglyph, (float)font->yglyph); shd_int("flags", sflags = flags = 0); shd_color("color", color); shd_color("back", back); #endif #if defined(GFX_TEXT_OFFSET) || defined(GFX_TEXT_COORD) || defined(GFX_TEXT_DRAW_R) while(1) { pos = lpos; if(!(ch = utf_readn(str, &lpos))) break; #else while(ch = utf_read(&str)) { #endif #ifdef GFX_TEXT_COORD if(pos == offset) { *xc = x; *yc = y; return; } #endif if(ch == CHR_NLN) { #ifdef GFX_TEXT_OFFSET if(ox >= x && oy >= y && oy < (y + h)) { *xc = x; *yc = y; return pos; } #endif x = w ? (x+l) : ((h < 0) ? x2 : x1); y = h ? (y+l) : ((w < 0) ? y2 : y1); continue; } #ifdef GFX_TEXT_DRAW else if(ch >= CHR_ULINE && ch <= CHR_FADE) { shd_int("flags", flags ^= 1 << (ch - CHR_ULINE)); sflags |= flags; continue; } else if(ch >= CHR_COLORS1 && ch <= CHR_COLORE1) { shd_color("color", text_colors[ch - CHR_COLORS1] | (color & 0xff000000)); continue; } else if(ch >= CHR_COLORS2 && ch <= CHR_COLORE2) { shd_color("color", gdr.aux_colors[ch - CHR_COLORS2] | (color & 0xff000000)); continue; } else if(ch == CHR_FRESET) { shd_int("flags", flags = 0); continue; } else if(ch == CHR_CRESET) { shd_color("color", color); continue; } #else else if(ch < CHR_SPC) { continue; } #endif if(ch >= (UNI_MAX_PAGES * 256) || !(tex = font->textures[ch >> 8])) ch = CHR_UNK; glyph = font->sizes[ch >> 8][ch & 0xff]; if((!(glyph.u)) && glyph.v) continue; else if(!(glyph.u)) glyph = font->sizes[0][CHR_UNK]; u = h ? ((glyph.u + 3 - glyph.s) * (h < 0 ? -h : h) / font->yglyph) : (w < 0 ? -w : w); v = w ? ((glyph.v + 3 - glyph.t) * (w < 0 ? -w : w) / font->xglyph) : (h < 0 ? -h : h); tx = (h < 0) ? (((x - u) < x1) ? x2 : x) : ((h > 0) ? (((x + u) > x2) ? x1 : x) : ((w < 0) ? (((y - v) < y1) ? x+l : x) : ((w > 0) ? (((y + v) > y2) ? x+l : x) : x))); ty = (w < 0) ? (((y - v) < y1) ? y2 : y) : ((w > 0) ? (((y + v) > y2) ? y1 : y) : ((h < 0) ? (((x - u) < x1) ? y+l : y) : ((h > 0) ? (((x + u) > x2) ? y+l : y) : y))); #ifdef GFX_TEXT_OFFSET if(ty > y && ox >= x && oy >= y && oy < (y + h)) { *xc = tx; *yc = ty; return pos; } #endif x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { #ifdef GFX_TEXT_OFFSET pos = lpos; #endif break; } #ifdef GFX_TEXT_DRAW #ifdef GFX_TEXT_DRAW_R if(pos >= start && pos < end) { #endif shd_vec2v("offset", (float)(h < 0 ? (x - u) : x), (float)(w < 0 ? (y - v) : y)); shd_vec4v("pad", (float)(h < 0 ? 2 : (h > 0 ? 1 : 0)), (float)(w < 0 ? 2 : (w > 0 ? 1 : 0)), (float)(h > 0 ? 2 : (h < 0 ? 1 : 0)), (float)(w > 0 ? 2 : (w < 0 ? 1 : 0))); shd_vec2v("size", (float)u, (float)v); shd_vec4v("glyph", (float)(h ? glyph.s : 0), (float)(w ? glyph.t : 0), (float)(h ? glyph.u : font->xglyph), (float)(w ? glyph.v : font->yglyph)); shd_int("ch_index", ch & 0xff); glBindTexture(GL_TEXTURE_2D, font->textures[ch >> 8]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #ifdef GFX_TEXT_DRAW_R } #endif #endif #ifdef GFX_TEXT_OFFSET if(ox >= x && oy >= y && ox < (x + u) && oy < (y + h)) { *xc = x; *yc = y; return pos; } #endif x += ((h < 0) ? -u : ((h > 0) ? u : 0)); y += ((w < 0) ? -v : ((w > 0) ? v : 0)); } #ifdef GFX_TEXT_SIZE *xs = x - ix; *ys = y - iy; #endif #ifdef GFX_TEXT_OFFSET *xc = x; *yc = y; return pos; #endif #ifdef GFX_TEXT_COORD *xc = x; *yc = y; #endif #ifdef GFX_TEXT_DRAW return sflags & (SHD_FLAG_BL | SHD_FLAG_FD); #endif } #ifdef GFX_TEXT_OFFSET #undef GFX_TEXT_OFFSET #endif #ifdef GFX_TEXT_DRAW_R #undef GFX_TEXT_DRAW #endif