Felisp
84436a5ae0
http://my.svgalib.org/svgalib/svgalib-1.9.25.tar.gz http://my.svgalib.org/svgalib/
328 lines
6.5 KiB
C
328 lines
6.5 KiB
C
/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
|
|
/* text.c Text writing and fonts */
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <vga.h>
|
|
#include "inlstring.h" /* include inline string operations */
|
|
|
|
#include "vgagl.h"
|
|
#include "def.h"
|
|
|
|
|
|
|
|
/* Text/font functions */
|
|
|
|
static int font_width = 8;
|
|
static int font_height = 8;
|
|
static char *font_address;
|
|
static int font_charactersize = 64;
|
|
static int font_writemode = WRITEMODE_OVERWRITE;
|
|
static int compressed_font_bg = 0;
|
|
static int compressed_font_fg = 15;
|
|
|
|
static void writecompressed(int x, int y, int n, unsigned char *s);
|
|
|
|
|
|
void gl_colorfont(int fw, int fh, int fg, void *_dp)
|
|
{
|
|
uchar *dp = _dp;
|
|
int i;
|
|
i = fw * fh * 256;
|
|
switch (BYTESPERPIXEL) {
|
|
case 1:
|
|
while (i > 0) {
|
|
if (*dp)
|
|
*dp = fg;
|
|
dp++;
|
|
i--;
|
|
}
|
|
break;
|
|
case 2:
|
|
while (i > 0) {
|
|
if (*(ushort *) dp)
|
|
*(ushort *) dp = fg;
|
|
dp += 2;
|
|
i--;
|
|
}
|
|
break;
|
|
case 3:
|
|
while (i > 0) {
|
|
if (*(ushort *) dp || *(dp + 2)) {
|
|
*(ushort *) dp = fg;
|
|
*(dp + 2) = fg >> 16;
|
|
}
|
|
dp += 3;
|
|
i--;
|
|
}
|
|
break;
|
|
case 4:
|
|
while (i > 0) {
|
|
if (*(int *) dp)
|
|
*(int *) dp = fg;
|
|
dp += 4;
|
|
i--;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
void gl_setfont(int fw, int fh, void *font)
|
|
{
|
|
font_width = fw;
|
|
font_height = fh;
|
|
font_charactersize = font_width * font_height * BYTESPERPIXEL;
|
|
font_address = font;
|
|
}
|
|
|
|
void gl_setwritemode(int m)
|
|
{
|
|
font_writemode = m;
|
|
}
|
|
|
|
void gl_writen(int x, int y, int n, char *s)
|
|
{
|
|
/* clipping in putbox */
|
|
int i;
|
|
if (font_writemode & FONT_COMPRESSED) {
|
|
writecompressed(x, y, n, s);
|
|
return;
|
|
}
|
|
if (!(font_writemode & WRITEMODE_MASKED)) {
|
|
for (i=0; i<n; i++) {
|
|
gl_putbox(x + i * font_width, y, font_width,
|
|
font_height, font_address +
|
|
(unsigned char) s[i] * font_charactersize);
|
|
}
|
|
} else { /* masked write */
|
|
for (i=0; i<n; i++) {
|
|
gl_putboxmask(x + i * font_width, y, font_width,
|
|
font_height, font_address +
|
|
(unsigned char) s[i] * font_charactersize);
|
|
}
|
|
}
|
|
}
|
|
|
|
void gl_write(int x, int y, char *s)
|
|
{
|
|
int n;
|
|
for (n=0; s[n]; n++);
|
|
gl_writen(x, y, n, s);
|
|
}
|
|
|
|
#ifndef SVGA_AOUT
|
|
|
|
static int gl_nprintf(int sx, int sy, size_t bufs, const char *fmt, va_list args)
|
|
{
|
|
unsigned char *buf;
|
|
static int x = 0, y = 0, x_start = 0;
|
|
int n;
|
|
|
|
buf = alloca(bufs);
|
|
n = vsnprintf(buf, bufs, fmt, args);
|
|
if (n < 0)
|
|
return n; /* buffer did not suffice, return and retry */
|
|
|
|
if ((sx >= 0) && (sy >= 0)) {
|
|
x = x_start = sx;
|
|
y = sy;
|
|
}
|
|
|
|
for (; *buf; buf++)
|
|
switch (*buf) {
|
|
case '\a': /* badly implemented */
|
|
fputc('\a', stdout);
|
|
fflush(stdout);
|
|
break;
|
|
case '\b':
|
|
x -= font_width;
|
|
if (x < x_start) {
|
|
x = WIDTH + (x_start % font_width);
|
|
while(x + font_width > WIDTH)
|
|
x -= font_width;
|
|
if (y >= font_height)
|
|
y -= font_height;
|
|
}
|
|
break;
|
|
case '\n':
|
|
newline:
|
|
y += font_height;
|
|
if (y + font_height > HEIGHT)
|
|
y %= font_height;
|
|
case '\r':
|
|
x = x_start;
|
|
break;
|
|
case '\t':
|
|
x += ((TEXT_TABSIZE - ((x - x_start) / font_width) % TEXT_TABSIZE) * font_width);
|
|
goto chk_wrap;
|
|
break;
|
|
case '\v':
|
|
y += font_height;
|
|
if (y + font_height > HEIGHT)
|
|
y %= font_height;
|
|
break;
|
|
default:
|
|
gl_writen(x, y, 1, buf);
|
|
x += font_width;
|
|
chk_wrap:
|
|
if (x + font_width > WIDTH)
|
|
goto newline;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
int gl_printf(int x, int y, const char *fmt, ...)
|
|
{
|
|
size_t bufs = BUFSIZ;
|
|
int result;
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
|
|
/* Loop until buffer size suffices */
|
|
do {
|
|
result = gl_nprintf(x, y, bufs, fmt, args);
|
|
bufs <<= 1;
|
|
} while(result < 0);
|
|
|
|
va_end(args);
|
|
return result;
|
|
}
|
|
|
|
#endif
|
|
void gl_expandfont(int fw, int fh, int fg, void *_f1, void *_f2)
|
|
{
|
|
/* Convert bit-per-pixel font to byte(s)-per-pixel font */
|
|
uchar *f1 = _f1;
|
|
uchar *f2 = _f2;
|
|
int i, x, y, b = 0; /* keep gcc happy with b = 0 - MW */
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
for (y = 0; y < fh; y++)
|
|
for (x = 0; x < fw; x++) {
|
|
if (x % 8 == 0)
|
|
b = *f1++;
|
|
if (b & (128 >> (x % 8))) /* pixel */
|
|
switch (BYTESPERPIXEL) {
|
|
case 1:
|
|
*f2 = fg;
|
|
f2++;
|
|
break;
|
|
case 2:
|
|
*(ushort *) f2 = fg;
|
|
f2 += 2;
|
|
break;
|
|
case 3:
|
|
*(ushort *) f2 = fg;
|
|
*(f2 + 2) = fg >> 16;
|
|
f2 += 3;
|
|
break;
|
|
case 4:
|
|
*(uint *) f2 = fg;
|
|
f2 += 4;
|
|
} else /* no pixel */
|
|
switch (BYTESPERPIXEL) {
|
|
case 1:
|
|
*f2 = 0;
|
|
f2++;
|
|
break;
|
|
case 2:
|
|
*(ushort *) f2 = 0;
|
|
f2 += 2;
|
|
break;
|
|
case 3:
|
|
*(ushort *) f2 = 0;
|
|
*(f2 + 2) = 0;
|
|
f2 += 3;
|
|
break;
|
|
case 4:
|
|
*(uint *) f2 = 0;
|
|
f2 += 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void expandcharacter(int bg, int fg, int c, unsigned char *bitmap)
|
|
{
|
|
int x, y;
|
|
unsigned char *font;
|
|
int b = 0; /* keep gcc happy with b = 0 - MW */
|
|
|
|
font = font_address + c * (font_height * ((font_width + 7) / 8));
|
|
|
|
for (y = 0; y < font_height; y++)
|
|
for (x = 0; x < font_width; x++) {
|
|
if (x % 8 == 0)
|
|
b = *font++;
|
|
if (b & (128 >> (x % 8))) /* pixel */
|
|
switch (BYTESPERPIXEL) {
|
|
case 1:
|
|
*bitmap = fg;
|
|
bitmap++;
|
|
break;
|
|
case 2:
|
|
*(ushort *) bitmap = fg;
|
|
bitmap += 2;
|
|
break;
|
|
case 3:
|
|
*(ushort *) bitmap = fg;
|
|
*(bitmap + 2) = fg >> 16;
|
|
bitmap += 3;
|
|
break;
|
|
case 4:
|
|
*(uint *) bitmap = fg;
|
|
bitmap += 4;
|
|
} else /* background pixel */
|
|
switch (BYTESPERPIXEL) {
|
|
case 1:
|
|
*bitmap = bg;
|
|
bitmap++;
|
|
break;
|
|
case 2:
|
|
*(ushort *) bitmap = bg;
|
|
bitmap += 2;
|
|
break;
|
|
case 3:
|
|
*(ushort *) bitmap = bg;
|
|
*(bitmap + 2) = bg >> 16;
|
|
bitmap += 3;
|
|
break;
|
|
case 4:
|
|
*(uint *) bitmap = bg;
|
|
bitmap += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Write using compressed font. */
|
|
|
|
static void writecompressed(int x, int y, int n, unsigned char *s)
|
|
{
|
|
unsigned char *bitmap;
|
|
int i;
|
|
bitmap = alloca(font_width * font_height * BYTESPERPIXEL);
|
|
if (!(font_writemode & WRITEMODE_MASKED)) {
|
|
for (i=0; i<n; i++) {
|
|
expandcharacter(compressed_font_bg,
|
|
compressed_font_fg, s[i], bitmap);
|
|
gl_putbox(x + i * font_width, y, font_width,
|
|
font_height, bitmap);
|
|
}
|
|
} else { /* masked write */
|
|
for (i=0; i<n; i++) {
|
|
expandcharacter(0, compressed_font_fg, s[i], bitmap);
|
|
gl_putboxmask(x + i * font_width, y, font_width,
|
|
font_height, bitmap);
|
|
}
|
|
}
|
|
}
|
|
|
|
void gl_setfontcolors(int bg, int fg)
|
|
{
|
|
compressed_font_bg = bg;
|
|
compressed_font_fg = fg;
|
|
}
|