00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00118
00119 les di, dword ptr bmBits
00120
00121 copypage:
00122 push word ptr[string]
00123 mov ax, di
00124
00125 nextchar:
00126 lds si, [string]
00127 inc word ptr [string]
00128 xor bx, bx
00129 mov bl, [si]
00130
00131 lds si, [font]
00132 or bx, bx
00133 je nextpage
00134 sub bx, [si+0]
00135 jl nextchar
00136 cmp bx, [si+2]
00137 jge nextchar
00138
00139 add bx, bx
00140 add bx, 12
00141
00142 mov cx, [si+bx+2]
00143 sub cx, [si+bx]
00144 add si, [si+bx]
00145
00146 rep movsb
00147 jmp nextchar
00148
00149 nextpage:
00150 pop word ptr[string]
00151
00152 add dx, [si+8]
00153 sub pages, 1
00154 jne copypage
00155
00156 sub di, ax
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
00173
00174
00175
00176
00177
00178
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