Main Page Data Structures File List Data Fields Globals Related Pages

# gfxfont.cpp

Go to the documentation of this file.

    00001 /*  gfxfont.cpp
    00002     Font handling functions
    00003
    00004     28.06.2002: tk, initial implementation.
    00005
    00006     Copyright (c)2001 by Thomas Kindler, thomas.kindler@gmx.de
    00007
    00008     This program is free software; you can redistribute it and/or
    00009     modify it under the terms of the GNU General Public License as
    00010     published by the Free Software Foundation; either version 2 of
    00011     the License, or (at your option) any later version. Read the
    00012     full License at http://www.gnu.org/copyleft for more details.
    00013 */
    00014
    00015 // include files -----
    00016 //
    00017 #include "gfxfont.h"
    00018 #include "gfxcore.h"
    00019 #include "misc.h"
    00020 #include <stdio.h>
    00021 #include <stdlib.h>
    00022 #include <stdarg.h>
    00023 #include <assert.h>
    00024 #include <mem.h>
    00025 #include <dos.h>
    00026
    00027
    00028 static char printfbuf[256];
    00029
    00030
    00038 Font *GFX_LoadFont(char *fn)
    00039 {
    00040   unsigned long magic, size;
    00041   Font *font = NULL;
    00042   FILE *file = NULL;
    00043
    00044   printf("loading \"%s\".. ", fn);
    00045
    00046   file = fopen(fn, "rb");
    00047   if (!file) {
    00048     perror("");
    00049     goto error;
    00050   }
    00051
    00052   fread(&magic, sizeof(magic), 1, file);
    00053   fread(&size,  sizeof(size),  1, file);
    00054
    00055   if (magic != FONT_MAGIC) {
    00056     printf("invalid format.\n");
    00057     goto error;
    00058   }
    00059
    00060   font = (Font*)malloc(size);
    00061   if (!font) {
    00062     printf("out of memory.\n");
    00063     goto error;
    00064   }
    00065   fread(font, size, 1, file);
    00066   fclose(file);
    00067
    00068   printf( "%dx%d, %d-%d (%d bytes).\n",
    00069           font->maxWidth, font->height, font->firstChar,
    00070           font->firstChar+font->numChars, size );
    00071   return  font;
    00072
    00073 error:
    00074   if (font) free(font);
    00075   if (file) fclose(file);
    00076   return  NULL;
    00077 }
    00078
    00079
    00085 void GFX_FreeFont(Font *font)
    00086 {
    00087   if (font)
    00088     free(font);
    00089 }
    00090
    00091
    00100 #pragma  warn -rvl  // ignore compiler warning (return value is in ax)
    00101 static int printScratch(char *bmBits, Font *font, char *string)
    00102 {
    00103   int    pages = font->numPages;
    00104
    00105   asm {
    00106         push  bx
    00107         push  cx
    00108         push  dx
    00109         push  si
    00110         push  di
    00111         push  ds
    00112         push  es
    00113
    00114         xor   bx, bx
    00115         xor   dx, dx
    00116
    00117         // es:di points to destination bitmap
    00118         //
    00119         les   di, dword ptr bmBits
    00120
    00121 copypage:
    00122         push  word ptr[string]    // save string pointer
    00123         mov   ax, di              // save beginning-of-page
    00124
    00125 nextchar:
    00126         lds   si, [string]        // fetch character
    00127         inc   word ptr [string]
    00128         xor   bx, bx
    00129         mov   bl, [si]
    00130
    00131         lds   si, [font]
    00132         or    bx, bx              // == 0?
    00133         je    nextpage
    00134         sub   bx, [si+0]          // < firstChar?
    00135         jl    nextchar
    00136         cmp   bx, [si+2]          // >= numChars?
    00137         jge   nextchar
    00138
    00139         add   bx, bx              // bx = (char*2)+12
    00140         add   bx, 12
    00141
    00142         mov   cx, [si+bx+2]       // get near pointer to (char+1)
    00143         sub   cx, [si+bx]         // calculate width
    00144         add   si, [si+bx]         // get near pointer to char
    00145
    00146         rep   movsb               // copy char
    00147         jmp   nextchar
    00148
    00149 nextpage:
    00150         pop   word ptr[string]    // reset string pointer
    00151
    00152         add   dx, [si+8]          // advance to next page
    00153         sub   pages, 1            //
    00154         jne   copypage
    00155
    00156         sub   di, ax              // return width of text
    00157         mov   ax, di              //
    00158
    00159         pop   es
    00160         pop   ds
    00161         pop   di
    00162         pop   si
    00163         pop   dx
    00164         pop   cx
    00165         pop   bx
    00166   }
    00167 }
    00168 #pragma  warn .rvl
    00169
    00170
    00171 /*
    00172  * Print a text string at the current cursor position.
    00173  * The x-cursor position is moved to the end of the string,
    00174  * the y position doesn't get modified (no wrapping!)
    00175  *
    00176  * \param  gfx  Graphics context to use.
    00177  * \param  string  pointer to text string.
    00178  * \return width of printed text (in pixels).
    00179  */
    00180 int GFX_Print(Graphics *gfx, char *string)
    00181 {
    00182   _gfx_scratch->width  = printScratch(_gfx_scratch->bmBits, gfx->font, string);
    00183   _gfx_scratch->height = gfx->font->height;
    00184   assert(
    00185     _gfx_scratch->width*(_gfx_scratch->height+7)/8 < _gfx_scratch->bmBitsSize
    00186   );
    00187
    00188   BM_Blit(
    00189     gfx->bitmap, gfx->x, gfx->y,
    00190     _gfx_scratch, 0, 0, -1, -1,
    00191     gfx->blitMode
    00192   );
    00193
    00194   gfx->x += _gfx_scratch->width;
    00195   return  _gfx_scratch->width;
    00196 }
    00197
    00198
    00207 int GFX_PrintAt(Graphics *gfx, int x, int y, char *string)
    00208 {
    00209   swap(gfx->x, x);  swap(gfx->y, y);
    00210   int width = GFX_Print(gfx, string);
    00211   swap(gfx->x, x);  swap(gfx->y, y);
    00212   return width;
    00213 }
    00214
    00215
    00225 int GFX_Printf(Graphics *gfx, char *format, ...)
    00226 {
    00227   int  width;
    00228
    00229   va_list arglist;
    00230   va_start(arglist, format);
    00231
    00232   int ret = vsprintf(printfbuf, format, arglist);
    00233   assert(ret < sizeof(printfbuf));
    00234
    00235   width = GFX_Print(gfx, printfbuf);
    00236   va_end(arglist);
    00237
    00238   return  width;
    00239 }
    00240
    00241
    00251 int GFX_PrintfAt(Graphics *gfx, int x, int y, char *format, ...)
    00252 {
    00253   int  width;
    00254
    00255   va_list arglist;
    00256   va_start(arglist, format);
    00257
    00258   int ret = vsprintf(printfbuf, format, arglist);
    00259   assert(ret < sizeof(printfbuf));
    00260
    00261   width = GFX_PrintAt(gfx, x, y, printfbuf);
    00262   va_end(arglist);
    00263
    00264   return  width;
    00265 }
    00266
    00267
    00277 int GFX_TextWidth(Graphics *gfx, char *string)
    00278 {
    00279   int  width = 0;
    00280   Font *font = gfx->font;
    00281
    00282   while (char c = *string++) {
    00283     c -= font->firstChar;
    00284     if (c < 0) continue;
    00285     if (c >= font->numChars)  continue;
    00286     width += font->offsets[c+1] - font->offsets[c];
    00287   }
    00288
    00289   return width;
    00290 }
    00291