diff options
author | pixel <pixel> | 2004-11-27 21:44:50 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-11-27 21:44:50 +0000 |
commit | 1ae229afb9bff4a3636c08632032b509e1e80ec4 (patch) | |
tree | 9a78b288fcff587617d5174d8e74b7bdd6d41aa3 /lib/font.cc | |
parent | 70b1a3c1c6b7f33b3af777bedaa784e34ef81719 (diff) |
Large dos2unix commit...
Diffstat (limited to 'lib/font.cc')
-rw-r--r-- | lib/font.cc | 1410 |
1 files changed, 705 insertions, 705 deletions
diff --git a/lib/font.cc b/lib/font.cc index 1683387..2a17d20 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.14 2004-07-15 14:21:31 pixel Exp $ */ - -#include <stdarg.h> -#include <SDL.h> -#include <Input.h> -#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.15 2004-11-27 21:44:53 pixel Exp $ */
+
+#include <stdarg.h>
+#include <SDL.h>
+#include <Input.h>
+#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;
+}
|