diff options
author | pixel <pixel> | 2004-11-27 21:48:01 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-11-27 21:48:01 +0000 |
commit | f9969775e6d2f798a3bfea5c58fc5478dad07eae (patch) | |
tree | c82d4ed9c87d7e09c71be3554ac5d0486c774eda /lib/font.cc | |
parent | 1ae229afb9bff4a3636c08632032b509e1e80ec4 (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 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 <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.16 2004-11-27 21:48:03 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; +} |