From f9969775e6d2f798a3bfea5c58fc5478dad07eae Mon Sep 17 00:00:00 2001 From: pixel Date: Sat, 27 Nov 2004 21:48:01 +0000 Subject: Large dos2unix commit... --- lib/font.cc | 1410 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 705 insertions(+), 705 deletions(-) (limited to 'lib/font.cc') diff --git a/lib/font.cc b/lib/font.cc index 2a17d20..07ade78 100644 --- a/lib/font.cc +++ b/lib/font.cc @@ -1,705 +1,705 @@ -/* - * mogltk - * Copyright (C) 1999-2004 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: font.cc,v 1.15 2004-11-27 21:44:53 pixel Exp $ */ - -#include -#include -#include -#include "base.h" -#include "font.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "engine.h" - -Uint8 prescale2[4] = { 0, 85, 170, 255 }, prescale3[8] = { 0, 36, 72, 109, 145, 182, 218, 255 }; - -#define STRBUFSIZ 512 - -/* - -font file format -================ - -off|siz|description ----+---+------------------------------- - 0 | 2 | Number of entries = nbentries - 2 | 1 | Flags - 3 | 1 | maxX (maximum width) - 4 | 1 | maxY (maximum height) - 5 | 1 | base (bottom line from top) - 6 | 1 | inter (size of the interline) - 7 | X | char entries -7+X| Y | char map - -X = (maxX * maxY + 1) * nbentries -Y = nbentries * 4 - - -Flags: -===== - -0000000R - -R = RGBA (=1) or Alpha (=0) - -RGBA in 1232 format: -ABBGGGRR - - -Each entries: -============ - -off|siz|description ----+---+------------------------------- - 0 | 1 | True size of the entry - 1 | Z | Datas - -Z = maxX * maxY -Datas are stored in order X first, then Y. - -Char map: -======== - -nbentries entries, each entry = 4 bytes = 2 uint16 - -off|siz|description ----+---+------------------------------- - 0 | 2 | Unicode (?) - 2 | 2 | Corresponding char entry - -I'm not sure about my word 'Unicode'. I write this only to say it's an attempt -to make the fonts "internationals". If the "unicode" is < 255, then it should -match only one byte in the string. Otherwise, it should match two bytes. - - -Variables comments -================== - -nbcU = number of chars on X by texture -nbcV = number of chars on Y by texture -nbcT = number of char by texture -nbT = number of textures - -*/ - -mogltk::ColorP colorcached[16] = { - DOS_BLACK, - DOS_BLUE, - DOS_GREEN, - DOS_CYAN, - DOS_RED, - DOS_MAGENTA, - DOS_BRAWN, - DOS_WHITE, - DOS_GRAY, - DOS_HIGH_BLUE, - DOS_HIGH_GREEN, - DOS_HIGH_CYAN, - DOS_HIGH_RED, - DOS_HIGH_MAGENTA, - DOS_YELLOW, - DOS_HIGH_WHITE -}; - -mogltk::font::font(Handle * ffont) : textcolor(255, 255, 255, 255), shadow(0), wspace(0) { - int i, j; - - nbentries = ffont->readU16(); - flags = ffont->readU8(); - maxX = ffont->readU8(); - maxY = ffont->readU8(); - base = ffont->readU8(); - inter = ffont->readU8(); - - nbcU = 256 / maxX; - nbcV = 256 / maxY; - - nbcT = nbcU * nbcV; - - nbT = nbentries / nbcT; - - if (nbentries % nbcT) { - nbT++; - } - - printm(M_INFO, "Creating font texture: %i entries, flags = 0x%02x, maxX = %i, maxY = %i\n", nbentries, flags, maxX, maxY); - printm(M_INFO, "Which makes %i texture(s), with %i char by texture, %i on X, and %i on Y\n", nbT, nbcT, nbcU, nbcV); - - fonttex = (texture **) malloc(nbT * sizeof(texture *)); - for (i = 0; i < 16; i++) { - fontcache[i] = (texture **) malloc(nbT * sizeof(texture *)); - } - - for (i = 0; i < nbT; i++) { - fonttex[i] = alloctexture(); - for (j = 0; j < 15; j++) { - fontcache[j][i] = 0; - } - fontcache[15][i] = fonttex[i]; - } - - sizes = (Uint8 *) malloc(nbentries * sizeof(Uint8)); - - Uint8 * curtex = (Uint8 *) fonttex[0]->GetSurface()->pixels; - Uint32 curU = 0, curV = 0, curT = 0; - for (i = 0; i < nbentries; i++) { - sizes[i] = ffont->readU8(); - for (int v = 0; v < maxY; v++) { - for (int u = 0; u < maxX; u++) { - Uint8 f; - f = ffont->readU8(); - if (flags & 1) { - Uint8 r, g, b, a; - r = f & 3; - g = (f >> 2) & 7; - b = (f >> 5) & 3; - a = (f >> 7) & 1; - curtex[(curU + u + (curV + v) * 256) * 4 + 0] = prescale2[r]; - curtex[(curU + u + (curV + v) * 256) * 4 + 1] = prescale3[g]; - curtex[(curU + u + (curV + v) * 256) * 4 + 2] = prescale2[b]; - curtex[(curU + u + (curV + v) * 256) * 4 + 3] = a ? 255 : 0; - } else { - curtex[(curU + u + (curV + v) * 256) * 4 + 0] = 255; - curtex[(curU + u + (curV + v) * 256) * 4 + 1] = 255; - curtex[(curU + u + (curV + v) * 256) * 4 + 2] = 255; - curtex[(curU + u + (curV + v) * 256) * 4 + 3] = f; - } - } - } - if (((curU += maxX) + maxX) > 256) { - curU = 0; - if (((curV += maxY) + maxY) > 256) { - curV = 0; - if ((curT + 1) != nbT) - curtex = (Uint8 *) fonttex[++curT]->GetSurface()->pixels; - } - } - } - - corresp = (Uint16 *) malloc(nbentries * 2 * sizeof(Uint16)); - - for (i = 0; i < 2 * nbentries; i++) { - corresp[i] = ffont->readU16(); - } -} - -mogltk::font::~font() { - int i, j; - for (i = 0; i < nbT; i++) - for (j = 0; j < 16; j++) - if (fontcache[j][i]) - delete fontcache[j][i]; - - for (i = 0; i < 16; i++) - free((void *&) fontcache[i]); - - free((void *&) fonttex); - free(sizes); -} - -void mogltk::font::drawentry(Uint16 entry, int x, int y, ColorP c) { - bool locked = false; - int trueentry, cx, cy, px, py; - SDL_Rect src, dst; - - if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) { - locked = true; - SDL_LockSurface(mogltk::engine::base_o->getsurface()); - } - - if (shadow) { - int os = shadow; - shadow = 0; - - drawentry(entry, x + os, y + os, BLACK); - - shadow = os; - } - - checknbind(entry / nbcT, c); - - y -= base; - - trueentry = entry % nbcT; - cx = trueentry % nbcU; - cy = trueentry / nbcU; - px = cx * maxX; - py = cy * maxY; - - src.x = px; src.y = py; src.w = maxX; src.h = maxY; - dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY; - - SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst); - - if (locked) - SDL_UnlockSurface(mogltk::engine::base_o->getsurface()); -} - -void mogltk::font::drawtotex(texture * t, Uint16 entry, int x, int y, ColorP c) { - bool locked = false; - int trueentry, cx, cy, px, py; - SDL_Rect src, dst; - - if (SDL_MUSTLOCK(t->GetSurface())) { - locked = true; - SDL_LockSurface(t->GetSurface()); - } - - if (shadow) { - int os = shadow; - shadow = 0; - - drawtotex(t, entry, x + os, y + os, BLACK); - - shadow = os; - } - - checknbind(entry / nbcT, c); - - y -= base; - - trueentry = entry % nbcT; - cx = trueentry % nbcU; - cy = trueentry / nbcU; - px = cx * maxX; - py = cy * maxY; - - src.x = px; src.y = py; src.w = maxX; src.h = maxY; - dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY; - - SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, t->GetSurface(), &dst); - - if (locked) - SDL_UnlockSurface(t->GetSurface()); -} - -void mogltk::font::putcursor(int x, int y) { - cx = ox = x; - cy = y; -} - -void mogltk::font::putentry(Uint16 entry, ColorP c) { - drawentry(entry, cx, cy, c); - cx += sizes[entry] + wspace; -} - -void mogltk::font::putentryontex(texture * t, Uint16 entry, ColorP c) { - drawtotex(t, entry, cx, cy, c); - cx += sizes[entry] + wspace; -} - -void mogltk::font::drawchar(char ch, ColorP c) { - Uint16 * p; - int i; - - for (i = 0, p = corresp; i < nbentries; i++, p++) { - if (*(p++) == ch) { - putentry(*p, c); - return; - } - } -} - -void mogltk::font::drawcharontex(texture * t, char ch, ColorP c) { - Uint16 * p; - int i; - - for (i = 0, p = corresp; i < nbentries; i++, p++) { - if (*(p++) == ch) { - putentryontex(t, *p, c); - return; - } - } -} - -int mogltk::font::findchar(char ch) const { - Uint16 * p; - int i; - - for (i = 0, p = corresp; i < nbentries; i++, p++) { - if (*(p++) == ch) { - return *p; - } - } - - return -1; -} - -void mogltk::font::newline(void) { - cx = ox; - cy += inter; -} - -int mogltk::font::printf(const ugly_string & m, va_list ap) { - char * p; - static char buffer[STRBUFSIZ + 1]; - int r; - -#ifdef HAVE_VSNPRINTF - r = vsnprintf(buffer, STRBUFSIZ, m.p, ap); -#else - r = vsprintf(buffer, m.p, ap); -#endif - - for (p = buffer; *p; p++) { - if (*p == '\n') { - newline(); - } else { - drawchar(*p, textcolor); - } - } - - return r; -} - -int mogltk::font::printf(const ugly_string & m, ...) { - va_list ap; - int r; - - va_start(ap, m); - r = printf(m, ap); - va_end(ap); - - return r; -} - -int mogltk::font::printf(const char * p, ...) { - ugly_string m; - va_list ap; - int r; - - m.p = p; - - va_start(ap, p); - r = printf(m, ap); - va_end(ap); - - return r; -} - -mogltk::rect mogltk::font::size(const ugly_string & m, va_list ap) { - char * p; - static char buffer[STRBUFSIZ + 1]; - rect r; - int mw, w; - - r.x = cx; - r.y = cy; - r.h = inter; - r.w = 0; - mw = 0; - w = 0; - -#ifdef HAVE_VSNPRINTF - vsnprintf(buffer, STRBUFSIZ, m.p, ap); -#else - vsprintf(buffer, m.p, ap); -#endif - - for (p = buffer; *p; p++) { - if (*p == '\n') { - if (*(p+1)) { - r.h += inter; - if (w > mw) { - mw = w; - } - w = 0; - } - } else { - w += sizes[findchar(*p)] + wspace; - } - } - - if (w > mw) { - mw = w; - } - - r.w = mw; - - return r; -} - -mogltk::rect mogltk::font::size(const ugly_string & m, ...) { - va_list ap; - rect r; - - va_start(ap, m); - r = size(m, ap); - va_end(ap); - - return r; -} - -mogltk::rect mogltk::font::size(const char * p, ...) { - ugly_string m; - va_list ap; - rect r; - - m.p = p; - - va_start(ap, p); - r = size(m, ap); - va_end(ap); - - return r; -} - -mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, va_list ap) { - char * p; - static char buffer[STRBUFSIZ + 1]; - rect r; - int mw, w; - - r.x = cx; - r.y = cy; - r.h = inter; - r.w = 0; - mw = 0; - w = 0; - -#ifdef HAVE_VSNPRINTF - vsnprintf(buffer, STRBUFSIZ, m.p, ap); -#else - vsprintf(buffer, m.p, ap); -#endif - - for (p = buffer; *p; p++) { - if (*p == '\n') { - if (*(p+1)) { - r.h += inter; - if (w > mw) { - mw = w; - } - w = 0; - } - } else { - w += sizes[findchar(*p)] + wspace; - } - } - - if (w > mw) { - mw = w; - } - - r.w = mw; - - for (p = buffer; *p; p++) { - if (*p == '\n') { - newline(); - } else { - drawcharontex(t, *p, textcolor); - } - } - - return r; -} - -mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, ...) { - va_list ap; - rect r; - - va_start(ap, m); - r = printtotex(t, m, ap); - va_end(ap); - - return r; -} - -mogltk::rect mogltk::font::printtotex(texture * t, const char * p, ...) { - ugly_string m; - va_list ap; - rect r; - - m.p = p; - - va_start(ap, p); - r = printtotex(t, m, ap); - va_end(ap); - - return r; -} - -inline static unsigned int nextpower(unsigned int n) { - unsigned int i; - - if (!n) - return n; - - if (ISPOT(n)) - return n; - - for (i = 31; i >= 0; i--) { - if ((n >> i) & 1) { - return 1 << (i + 1); - } - } -} - -mogltk::texture * mogltk::font::printtex(rect * _r, const ugly_string & m, va_list ap) { - rect r; - char * p; - static char buffer[STRBUFSIZ + 1]; - int mw, w, pw, ph; - texture * t; - int ocx, ocy, oox; - - ocx = cx; - ocy = cy; - oox = ox; - - cx = ox = 0; - cy = base; - - r.x = cx; - r.y = cy; - r.h = inter; - r.w = 0; - mw = 0; - w = 0; - -#ifdef HAVE_VSNPRINTF - vsnprintf(buffer, STRBUFSIZ, m.p, ap); -#else - vsprintf(buffer, m.p, ap); -#endif - - for (p = buffer; *p; p++) { - if (*p == '\n') { - if (*(p+1)) { - r.h += inter; - if (w > mw) { - mw = w; - } - w = 0; - } - } else { - w += sizes[findchar(*p)] + wspace; - } - } - - if (w > mw) { - mw = w; - } - - r.w = mw; - - pw = nextpower(r.w); - ph = nextpower(r.h); - - t = new texture(pw, ph); - - for (p = buffer; *p; p++) { - if (*p == '\n') { - newline(); - } else { - drawcharontex(t, *p, textcolor); - } - } - - if (_r) - *_r = r; - - return t; -} - -mogltk::texture * mogltk::font::printtex(rect * r, const ugly_string & m, ...) { - va_list ap; - texture * t; - - va_start(ap, m); - t = printtex(r, m, ap); - va_end(ap); - - return t; -} - -mogltk::texture * mogltk::font::printtex(rect * r, const char * p, ...) { - ugly_string m; - va_list ap; - texture * t; - - m.p = p; - - va_start(ap, p); - t = printtex(r, m, ap); - va_end(ap); - - return t; -} - -void mogltk::font::setcolor(ColorP c) { - textcolor = c; -} - -void mogltk::font::setshadow(int s) { - shadow = s; -} - -void mogltk::font::setwspace(int w) { - wspace = w; -} - -int mogltk::font::singletextsize(const String & s) const { - unsigned int i; - int r = 0; - - for (i = 0; i < s.strlen(); i++) { - r += sizes[findchar(s[i])] + wspace; - } - - return r; -} - -mogltk::font * mogltk::SystemFont; -mogltk::font * mogltk::FixedFont; - -mogltk::texture * mogltk::font::alloctexture() { - return new mogltk::texture(256, 256); -} - -void mogltk::font::Bind(int f) { - fonttex[f]->Bind(); -} - -void mogltk::font::checknbind(int index, ColorP c) { - int i, x, y; - ColorP oldmax = ColorP::Max, t; - ColorP::Max = c.c; - SDL_PixelFormat * f = fonttex[0]->GetSurface()->format; - - for (i = 0; i < 15; i++) - if (c == colorcached[i]) - break; - - if (!fontcache[i][index]) { - fontcache[i][index] = alloctexture(); - for (y = 0; y < 256; y++) { - for (x = 0; x < 256; x++) { - t.fromSDL(fontcache[15][index]->GetPixels()[(y << 8) + x], f); - fontcache[i][index]->GetPixels()[(y << 8) + x] = t.toSDL(f); - } - } - } - - fonttex[index] = fontcache[i][index]; - - ColorP::Max = oldmax.c; -} +/* + * mogltk + * Copyright (C) 1999-2004 Nicolas "Pixel" Noble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id: font.cc,v 1.16 2004-11-27 21:48:03 pixel Exp $ */ + +#include +#include +#include +#include "base.h" +#include "font.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "engine.h" + +Uint8 prescale2[4] = { 0, 85, 170, 255 }, prescale3[8] = { 0, 36, 72, 109, 145, 182, 218, 255 }; + +#define STRBUFSIZ 512 + +/* + +font file format +================ + +off|siz|description +---+---+------------------------------- + 0 | 2 | Number of entries = nbentries + 2 | 1 | Flags + 3 | 1 | maxX (maximum width) + 4 | 1 | maxY (maximum height) + 5 | 1 | base (bottom line from top) + 6 | 1 | inter (size of the interline) + 7 | X | char entries +7+X| Y | char map + +X = (maxX * maxY + 1) * nbentries +Y = nbentries * 4 + + +Flags: +===== + +0000000R + +R = RGBA (=1) or Alpha (=0) + +RGBA in 1232 format: +ABBGGGRR + + +Each entries: +============ + +off|siz|description +---+---+------------------------------- + 0 | 1 | True size of the entry + 1 | Z | Datas + +Z = maxX * maxY +Datas are stored in order X first, then Y. + +Char map: +======== + +nbentries entries, each entry = 4 bytes = 2 uint16 + +off|siz|description +---+---+------------------------------- + 0 | 2 | Unicode (?) + 2 | 2 | Corresponding char entry + +I'm not sure about my word 'Unicode'. I write this only to say it's an attempt +to make the fonts "internationals". If the "unicode" is < 255, then it should +match only one byte in the string. Otherwise, it should match two bytes. + + +Variables comments +================== + +nbcU = number of chars on X by texture +nbcV = number of chars on Y by texture +nbcT = number of char by texture +nbT = number of textures + +*/ + +mogltk::ColorP colorcached[16] = { + DOS_BLACK, + DOS_BLUE, + DOS_GREEN, + DOS_CYAN, + DOS_RED, + DOS_MAGENTA, + DOS_BRAWN, + DOS_WHITE, + DOS_GRAY, + DOS_HIGH_BLUE, + DOS_HIGH_GREEN, + DOS_HIGH_CYAN, + DOS_HIGH_RED, + DOS_HIGH_MAGENTA, + DOS_YELLOW, + DOS_HIGH_WHITE +}; + +mogltk::font::font(Handle * ffont) : textcolor(255, 255, 255, 255), shadow(0), wspace(0) { + int i, j; + + nbentries = ffont->readU16(); + flags = ffont->readU8(); + maxX = ffont->readU8(); + maxY = ffont->readU8(); + base = ffont->readU8(); + inter = ffont->readU8(); + + nbcU = 256 / maxX; + nbcV = 256 / maxY; + + nbcT = nbcU * nbcV; + + nbT = nbentries / nbcT; + + if (nbentries % nbcT) { + nbT++; + } + + printm(M_INFO, "Creating font texture: %i entries, flags = 0x%02x, maxX = %i, maxY = %i\n", nbentries, flags, maxX, maxY); + printm(M_INFO, "Which makes %i texture(s), with %i char by texture, %i on X, and %i on Y\n", nbT, nbcT, nbcU, nbcV); + + fonttex = (texture **) malloc(nbT * sizeof(texture *)); + for (i = 0; i < 16; i++) { + fontcache[i] = (texture **) malloc(nbT * sizeof(texture *)); + } + + for (i = 0; i < nbT; i++) { + fonttex[i] = alloctexture(); + for (j = 0; j < 15; j++) { + fontcache[j][i] = 0; + } + fontcache[15][i] = fonttex[i]; + } + + sizes = (Uint8 *) malloc(nbentries * sizeof(Uint8)); + + Uint8 * curtex = (Uint8 *) fonttex[0]->GetSurface()->pixels; + Uint32 curU = 0, curV = 0, curT = 0; + for (i = 0; i < nbentries; i++) { + sizes[i] = ffont->readU8(); + for (int v = 0; v < maxY; v++) { + for (int u = 0; u < maxX; u++) { + Uint8 f; + f = ffont->readU8(); + if (flags & 1) { + Uint8 r, g, b, a; + r = f & 3; + g = (f >> 2) & 7; + b = (f >> 5) & 3; + a = (f >> 7) & 1; + curtex[(curU + u + (curV + v) * 256) * 4 + 0] = prescale2[r]; + curtex[(curU + u + (curV + v) * 256) * 4 + 1] = prescale3[g]; + curtex[(curU + u + (curV + v) * 256) * 4 + 2] = prescale2[b]; + curtex[(curU + u + (curV + v) * 256) * 4 + 3] = a ? 255 : 0; + } else { + curtex[(curU + u + (curV + v) * 256) * 4 + 0] = 255; + curtex[(curU + u + (curV + v) * 256) * 4 + 1] = 255; + curtex[(curU + u + (curV + v) * 256) * 4 + 2] = 255; + curtex[(curU + u + (curV + v) * 256) * 4 + 3] = f; + } + } + } + if (((curU += maxX) + maxX) > 256) { + curU = 0; + if (((curV += maxY) + maxY) > 256) { + curV = 0; + if ((curT + 1) != nbT) + curtex = (Uint8 *) fonttex[++curT]->GetSurface()->pixels; + } + } + } + + corresp = (Uint16 *) malloc(nbentries * 2 * sizeof(Uint16)); + + for (i = 0; i < 2 * nbentries; i++) { + corresp[i] = ffont->readU16(); + } +} + +mogltk::font::~font() { + int i, j; + for (i = 0; i < nbT; i++) + for (j = 0; j < 16; j++) + if (fontcache[j][i]) + delete fontcache[j][i]; + + for (i = 0; i < 16; i++) + free((void *&) fontcache[i]); + + free((void *&) fonttex); + free(sizes); +} + +void mogltk::font::drawentry(Uint16 entry, int x, int y, ColorP c) { + bool locked = false; + int trueentry, cx, cy, px, py; + SDL_Rect src, dst; + + if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) { + locked = true; + SDL_LockSurface(mogltk::engine::base_o->getsurface()); + } + + if (shadow) { + int os = shadow; + shadow = 0; + + drawentry(entry, x + os, y + os, BLACK); + + shadow = os; + } + + checknbind(entry / nbcT, c); + + y -= base; + + trueentry = entry % nbcT; + cx = trueentry % nbcU; + cy = trueentry / nbcU; + px = cx * maxX; + py = cy * maxY; + + src.x = px; src.y = py; src.w = maxX; src.h = maxY; + dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY; + + SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst); + + if (locked) + SDL_UnlockSurface(mogltk::engine::base_o->getsurface()); +} + +void mogltk::font::drawtotex(texture * t, Uint16 entry, int x, int y, ColorP c) { + bool locked = false; + int trueentry, cx, cy, px, py; + SDL_Rect src, dst; + + if (SDL_MUSTLOCK(t->GetSurface())) { + locked = true; + SDL_LockSurface(t->GetSurface()); + } + + if (shadow) { + int os = shadow; + shadow = 0; + + drawtotex(t, entry, x + os, y + os, BLACK); + + shadow = os; + } + + checknbind(entry / nbcT, c); + + y -= base; + + trueentry = entry % nbcT; + cx = trueentry % nbcU; + cy = trueentry / nbcU; + px = cx * maxX; + py = cy * maxY; + + src.x = px; src.y = py; src.w = maxX; src.h = maxY; + dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY; + + SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, t->GetSurface(), &dst); + + if (locked) + SDL_UnlockSurface(t->GetSurface()); +} + +void mogltk::font::putcursor(int x, int y) { + cx = ox = x; + cy = y; +} + +void mogltk::font::putentry(Uint16 entry, ColorP c) { + drawentry(entry, cx, cy, c); + cx += sizes[entry] + wspace; +} + +void mogltk::font::putentryontex(texture * t, Uint16 entry, ColorP c) { + drawtotex(t, entry, cx, cy, c); + cx += sizes[entry] + wspace; +} + +void mogltk::font::drawchar(char ch, ColorP c) { + Uint16 * p; + int i; + + for (i = 0, p = corresp; i < nbentries; i++, p++) { + if (*(p++) == ch) { + putentry(*p, c); + return; + } + } +} + +void mogltk::font::drawcharontex(texture * t, char ch, ColorP c) { + Uint16 * p; + int i; + + for (i = 0, p = corresp; i < nbentries; i++, p++) { + if (*(p++) == ch) { + putentryontex(t, *p, c); + return; + } + } +} + +int mogltk::font::findchar(char ch) const { + Uint16 * p; + int i; + + for (i = 0, p = corresp; i < nbentries; i++, p++) { + if (*(p++) == ch) { + return *p; + } + } + + return -1; +} + +void mogltk::font::newline(void) { + cx = ox; + cy += inter; +} + +int mogltk::font::printf(const ugly_string & m, va_list ap) { + char * p; + static char buffer[STRBUFSIZ + 1]; + int r; + +#ifdef HAVE_VSNPRINTF + r = vsnprintf(buffer, STRBUFSIZ, m.p, ap); +#else + r = vsprintf(buffer, m.p, ap); +#endif + + for (p = buffer; *p; p++) { + if (*p == '\n') { + newline(); + } else { + drawchar(*p, textcolor); + } + } + + return r; +} + +int mogltk::font::printf(const ugly_string & m, ...) { + va_list ap; + int r; + + va_start(ap, m); + r = printf(m, ap); + va_end(ap); + + return r; +} + +int mogltk::font::printf(const char * p, ...) { + ugly_string m; + va_list ap; + int r; + + m.p = p; + + va_start(ap, p); + r = printf(m, ap); + va_end(ap); + + return r; +} + +mogltk::rect mogltk::font::size(const ugly_string & m, va_list ap) { + char * p; + static char buffer[STRBUFSIZ + 1]; + rect r; + int mw, w; + + r.x = cx; + r.y = cy; + r.h = inter; + r.w = 0; + mw = 0; + w = 0; + +#ifdef HAVE_VSNPRINTF + vsnprintf(buffer, STRBUFSIZ, m.p, ap); +#else + vsprintf(buffer, m.p, ap); +#endif + + for (p = buffer; *p; p++) { + if (*p == '\n') { + if (*(p+1)) { + r.h += inter; + if (w > mw) { + mw = w; + } + w = 0; + } + } else { + w += sizes[findchar(*p)] + wspace; + } + } + + if (w > mw) { + mw = w; + } + + r.w = mw; + + return r; +} + +mogltk::rect mogltk::font::size(const ugly_string & m, ...) { + va_list ap; + rect r; + + va_start(ap, m); + r = size(m, ap); + va_end(ap); + + return r; +} + +mogltk::rect mogltk::font::size(const char * p, ...) { + ugly_string m; + va_list ap; + rect r; + + m.p = p; + + va_start(ap, p); + r = size(m, ap); + va_end(ap); + + return r; +} + +mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, va_list ap) { + char * p; + static char buffer[STRBUFSIZ + 1]; + rect r; + int mw, w; + + r.x = cx; + r.y = cy; + r.h = inter; + r.w = 0; + mw = 0; + w = 0; + +#ifdef HAVE_VSNPRINTF + vsnprintf(buffer, STRBUFSIZ, m.p, ap); +#else + vsprintf(buffer, m.p, ap); +#endif + + for (p = buffer; *p; p++) { + if (*p == '\n') { + if (*(p+1)) { + r.h += inter; + if (w > mw) { + mw = w; + } + w = 0; + } + } else { + w += sizes[findchar(*p)] + wspace; + } + } + + if (w > mw) { + mw = w; + } + + r.w = mw; + + for (p = buffer; *p; p++) { + if (*p == '\n') { + newline(); + } else { + drawcharontex(t, *p, textcolor); + } + } + + return r; +} + +mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, ...) { + va_list ap; + rect r; + + va_start(ap, m); + r = printtotex(t, m, ap); + va_end(ap); + + return r; +} + +mogltk::rect mogltk::font::printtotex(texture * t, const char * p, ...) { + ugly_string m; + va_list ap; + rect r; + + m.p = p; + + va_start(ap, p); + r = printtotex(t, m, ap); + va_end(ap); + + return r; +} + +inline static unsigned int nextpower(unsigned int n) { + unsigned int i; + + if (!n) + return n; + + if (ISPOT(n)) + return n; + + for (i = 31; i >= 0; i--) { + if ((n >> i) & 1) { + return 1 << (i + 1); + } + } +} + +mogltk::texture * mogltk::font::printtex(rect * _r, const ugly_string & m, va_list ap) { + rect r; + char * p; + static char buffer[STRBUFSIZ + 1]; + int mw, w, pw, ph; + texture * t; + int ocx, ocy, oox; + + ocx = cx; + ocy = cy; + oox = ox; + + cx = ox = 0; + cy = base; + + r.x = cx; + r.y = cy; + r.h = inter; + r.w = 0; + mw = 0; + w = 0; + +#ifdef HAVE_VSNPRINTF + vsnprintf(buffer, STRBUFSIZ, m.p, ap); +#else + vsprintf(buffer, m.p, ap); +#endif + + for (p = buffer; *p; p++) { + if (*p == '\n') { + if (*(p+1)) { + r.h += inter; + if (w > mw) { + mw = w; + } + w = 0; + } + } else { + w += sizes[findchar(*p)] + wspace; + } + } + + if (w > mw) { + mw = w; + } + + r.w = mw; + + pw = nextpower(r.w); + ph = nextpower(r.h); + + t = new texture(pw, ph); + + for (p = buffer; *p; p++) { + if (*p == '\n') { + newline(); + } else { + drawcharontex(t, *p, textcolor); + } + } + + if (_r) + *_r = r; + + return t; +} + +mogltk::texture * mogltk::font::printtex(rect * r, const ugly_string & m, ...) { + va_list ap; + texture * t; + + va_start(ap, m); + t = printtex(r, m, ap); + va_end(ap); + + return t; +} + +mogltk::texture * mogltk::font::printtex(rect * r, const char * p, ...) { + ugly_string m; + va_list ap; + texture * t; + + m.p = p; + + va_start(ap, p); + t = printtex(r, m, ap); + va_end(ap); + + return t; +} + +void mogltk::font::setcolor(ColorP c) { + textcolor = c; +} + +void mogltk::font::setshadow(int s) { + shadow = s; +} + +void mogltk::font::setwspace(int w) { + wspace = w; +} + +int mogltk::font::singletextsize(const String & s) const { + unsigned int i; + int r = 0; + + for (i = 0; i < s.strlen(); i++) { + r += sizes[findchar(s[i])] + wspace; + } + + return r; +} + +mogltk::font * mogltk::SystemFont; +mogltk::font * mogltk::FixedFont; + +mogltk::texture * mogltk::font::alloctexture() { + return new mogltk::texture(256, 256); +} + +void mogltk::font::Bind(int f) { + fonttex[f]->Bind(); +} + +void mogltk::font::checknbind(int index, ColorP c) { + int i, x, y; + ColorP oldmax = ColorP::Max, t; + ColorP::Max = c.c; + SDL_PixelFormat * f = fonttex[0]->GetSurface()->format; + + for (i = 0; i < 15; i++) + if (c == colorcached[i]) + break; + + if (!fontcache[i][index]) { + fontcache[i][index] = alloctexture(); + for (y = 0; y < 256; y++) { + for (x = 0; x < 256; x++) { + t.fromSDL(fontcache[15][index]->GetPixels()[(y << 8) + x], f); + fontcache[i][index]->GetPixels()[(y << 8) + x] = t.toSDL(f); + } + } + } + + fonttex[index] = fontcache[i][index]; + + ColorP::Max = oldmax.c; +} -- cgit v1.2.3