📄 font.c
字号:
/* Zgv v3.1 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-1998 Russell Marks. See README for license details. * * font.c - provides a font of sorts for use via svgalib, and * code to use (nicer) BDF fonts converted with bdf2h. *//* all the line-based font stuff is hard-coded and a bit ugly, so you * probably won't want much to look at that (hint) :-) */ #include <stdio.h>#include <string.h>#include <vga.h>#include "zgv.h"#include "font.h"#include "fontbmps.h"#include "rc_config.h"#include "rcfile.h"#define TABSIZE 64 /* size of a tab, in pixels */static int go_through_the_motions=0; /* if 1, we don't draw it, just do the width */static int stop_after_this_x=NO_CLIP_FONT;static int squish_x=0;/* the copyright/license for the bitmap fonts says that all * copies of the fonts must contain the copyright. Since a copy * was embedded in the program above (`fontbmps.h'), we'd * best have this: */static char *bitmap_fonts_copyright="The bitmap fonts zgv uses are: \Copyright 1984-1989, 1994 Adobe Systems Incorporated. \Copyright 1988, 1994 Digital Equipment Corporation.";/* prototypes */int vgadrawtext(int x, int y, int siz, char *str);void fontcircle(int x, int y, int r);void fontc_l(int x, int y, int r);void fontc_u(int x, int y, int r);void fontc_r(int x, int y, int r);void fontc_left(int x, int y, int r);void fontc_ul(int x, int y, int r);void fontc_ur(int x, int y, int r);void fontc_ll(int x, int y, int r);void fontc_lr(int x, int y, int r);int vgatextsize(int sizearg, char *str);void set_max_text_width(int width);static int vgadrawtext_bmp(int xpos,int ypos,int siz,char *str);/* unused dummy routine to stop -Wall complaining about the copyright * message not being used. */static void its_too_damn_picky_sometimes(){printf(bitmap_fonts_copyright);}/* needed for 360x480 mode */#define vga_drawline(x1,y1,x2,y2) \ (squish_x?vga_drawline((x1)>>1,y1,(x2)>>1,y2):\ vga_drawline(x1,y1,x2,y2))#define vga_drawpixel(x1,y1) \ (squish_x?vga_drawpixel((x1)>>1,y1):\ vga_drawpixel(x1,y1))/* returns width of text drawn in pixels */int vgadrawtext(int x,int y,int siz,char *str){int f,a,b,c,s1,s2,s3,s4,s5,s6,gap;/* needed for both line and bitmap fonts */squish_x=(vga_getcurrentmode()==G360x480x256);if(!cfg.linetext || siz==0) return(vgadrawtext_bmp(x,y,siz,str));/* bold not supported by linetext version, use siz=2 instead */if(siz==USE_BOLD_FONT) siz=2;if(squish_x) x*=2; /* since vga_drawline/pixel will divide by 2 */b=y;a=x;s1=siz; s2=s1<<1; s3=s1+s2; s4=s2<<1; s5=s4+s1; s6=s3<<1;gap=s1; if(gap==0) gap=1;for(f=0;f<strlen(str);f++) { /* s3+s4 is the size that an ellipsis will take up (s3), plus the * widest possible letter (M = s4). */ if(a-x>stop_after_this_x-s3-s4) { int tmp; /* print an ellipsis... well, three^H^H^H^H^Htwo dots :-) */ /* blast the width restriction to stop possible infinite recursion */ tmp=stop_after_this_x; set_max_text_width(NO_CLIP_FONT); a+=vgadrawtext(a,y,siz,".."); stop_after_this_x=tmp; /* now give up */ break; } c=str[f]; /*** 1st step: cover some common occurances ***/ if(!go_through_the_motions) /* only draw it if we really want to */ { if(strchr("abdgopq68",c)!=NULL) /* common circle position */ fontcircle(a+s1,b+s3,siz); else { /* common part-circle positions */ if(strchr("cehmnrs",c)!=NULL) fontc_ul(a+s1,b+s3,siz); if(strchr("ehmnrBS35",c)!=NULL) fontc_ur(a+s1,b+s3,siz); if(strchr("cetuyCGJOQSUl035",c)!=NULL) fontc_ll(a+s1,b+s3,siz); if(strchr("suyBCDGJOQSU035",c)!=NULL) fontc_lr(a+s1,b+s3,siz); /* common line */ if(strchr("BDEFHKLMNPR",c)!=NULL) vga_drawline(a,b,a,b+s4); } } /*** 2nd step: fill in rest - this is the *really* long, messy bit :-) ***/ /*** 2a: lowercase letters ***/ if(!go_through_the_motions) switch(c) { case 'a': vga_drawline(a+s2,b+s2,a+s2,b+s4); break; case 'b': vga_drawline(a,b,a,b+s4); break; case 'c': vga_drawline(a+s1,b+s2,a+s2,b+s2); vga_drawline(a+s1,b+s4,a+s2,b+s4); break; case 'd': vga_drawline(a+s2,b,a+s2,b+s4); break; case 'e': vga_drawline(a,b+s3,a+s2,b+s3); vga_drawline(a+s1,b+s4,a+s2,b+s4); break; case 'f': fontc_ul(a+s1,b+s1,siz); vga_drawline(a,b+s1,a,b+s4); vga_drawline(a,b+s2,a+s1,b+s2); break; case 'g': vga_drawline(a+s2,b+s2,a+s2,b+s5); fontc_l(a+s1,b+s5,siz); break; case 'h': vga_drawline(a,b,a,b+s4); vga_drawline(a+s2,b+s3,a+s2,b+s4); break; case 'i': vga_drawpixel(a,b+s1); vga_drawline(a,b+s2,a,b+s4); a+=-s1+1; break; case 'j': vga_drawline(a+s1,b+s2,a+s1,b+s5); fontc_lr(a,b+s5,siz); vga_drawpixel(a+s1,b+s1); break; case 'k': vga_drawline(a,b,a,b+s4); vga_drawline(a,b+s3,a+s1,b+s2); vga_drawline(a,b+s3,a+s1,b+s4); break; case 'l': vga_drawline(a,b,a,b+s3); break; case 'm': vga_drawline(a,b+s2,a,b+s4); vga_drawline(a+s2,b+s3,a+s2,b+s4); vga_drawline(a+s4,b+s3,a+s4,b+s4); fontc_u(a+s3,b+s3,siz); break; case 'n': vga_drawline(a,b+s2,a,b+s4); vga_drawline(a+s2,b+s3,a+s2,b+s4); break; case 'p': vga_drawline(a,b+s2,a,b+s6); break; case 'q': vga_drawline(a+s2,b+s2,a+s2,b+s6); break; case 'r': vga_drawline(a,b+s2,a,b+s4); break; case 's': vga_drawline(a,b+s3,a+s2,b+s3); vga_drawline(a+s1,b+s2,a+s2,b+s2); vga_drawline(a,b+s4,a+s1,b+s4); break; case 't': vga_drawline(a,b+s1,a,b+s3); vga_drawline(a,b+s2,a+s1,b+s2); break; case 'u': vga_drawline(a,b+s2,a,b+s3); vga_drawline(a+s2,b+s2,a+s2,b+s4); break; case 'v': vga_drawline(a,b+s2,a+s1,b+s4); vga_drawline(a+s1,b+s4,a+s2,b+s2); break; case 'w': vga_drawline(a,b+s2,a+s1,b+s4); vga_drawline(a+s1,b+s4,a+s2,b+s3); vga_drawline(a+s2,b+s3,a+s3,b+s4); vga_drawline(a+s3,b+s4,a+s4,b+s2); break; case 'x': vga_drawline(a,b+s2,a+s2,b+s4); vga_drawline(a,b+s4,a+s2,b+s2); break; case 'y': vga_drawline(a,b+s2,a,b+s3); vga_drawline(a+s2,b+s2,a+s2,b+s5); fontc_l(a+s1,b+s5,siz); break; case 'z': vga_drawline(a,b+s2,a+s2,b+s2); vga_drawline(a+s2,b+s2,a,b+s4); vga_drawline(a,b+s4,a+s2,b+s4); break; /*** 2b: uppercase letters ***/ case 'A': vga_drawline(a,b+s4,a+s1,b); vga_drawline(a+s1,b,a+s2,b+s4); vga_drawline(a+(s1>>1),b+s2,a+s2-(s1>>1),b+s2); break; case 'B': fontc_r(a+s1,b+s1,siz); vga_drawline(a,b,a+s1,b); vga_drawline(a,b+s2,a+s1,b+s2); vga_drawline(a,b+s4,a+s1,b+s4); break; case 'C': fontc_u(a+s1,b+s1,siz); vga_drawline(a,b+s1,a,b+s3); break; case 'D': vga_drawline(a,b,a+s1,b); vga_drawline(a,b+s4,a+s1,b+s4); fontc_ur(a+s1,b+s1,siz); vga_drawline(a+s2,b+s1,a+s2,b+s3); break; case 'E': vga_drawline(a,b,a+s2,b); vga_drawline(a,b+s2,a+s1,b+s2); vga_drawline(a,b+s4,a+s2,b+s4); break; case 'F': vga_drawline(a,b,a+s2,b); vga_drawline(a,b+s2,a+s1,b+s2); break; case 'G': fontc_u(a+s1,b+s1,siz); vga_drawline(a,b+s1,a,b+s3); vga_drawline(a+s1,b+s2,a+s2,b+s2); vga_drawline(a+s2,b+s2,a+s2,b+s3); break; case 'H': vga_drawline(a,b+s2,a+s2,b+s2); vga_drawline(a+s2,b,a+s2,b+s4); break; case 'I': vga_drawline(a,b,a+s2,b); vga_drawline(a+s1,b,a+s1,b+s4); vga_drawline(a,b+s4,a+s2,b+s4); break; case 'J': vga_drawline(a+s2,b,a+s2,b+s3); break; case 'K': vga_drawline(a+s2,b,a,b+s2); vga_drawline(a,b+s2,a+s2,b+s4); break; case 'L': vga_drawline(a,b+s4,a+s2,b+s4); break; case 'M': vga_drawline(a,b,a+s1+(s1>>1),b+s2); vga_drawline(a+s1+(s1>>1),b+s2,a+s3,b); vga_drawline(a+s3,b,a+s3,b+s4); a-=s1; break; case 'N': vga_drawline(a,b,a+s2,b+s4); vga_drawline(a+s2,b+s4,a+s2,b); break; case 'Q': vga_drawline(a+s1,b+s3,a+s2,b+s4); /* FALLS THROUGH and adds an O, finishing the Q */ case 'O': case '0': /* all other numbers done later */ fontc_u(a+s1,b+s1,siz); vga_drawline(a,b+s1,a,b+s3); vga_drawline(a+s2,b+s1,a+s2,b+s3); break; case 'R': vga_drawline(a+s1,b+s2,a+s2,b+s4); /* FALLS THROUGH and adds a P, finishing the R */ case 'P': fontc_r(a+s1,b+s1,siz); vga_drawline(a,b,a+s1,b); vga_drawline(a,b+s2,a+s1,b+s2); break; case 'S': fontc_left(a+s1,b+s1,siz); fontc_ur(a+s1,b+s1,siz); break; case 'T': vga_drawline(a,b,a+s2,b); vga_drawline(a+s1,b,a+s1,b+s4); break; case 'U': vga_drawline(a,b,a,b+s3); vga_drawline(a+s2,b,a+s2,b+s3); break; case 'V': vga_drawline(a,b,a+s1,b+s4); vga_drawline(a+s1,b+s4,a+s2,b); break; case 'W': vga_drawline(a,b,a+s1,b+s4); vga_drawline(a+s1,b+s4,a+s2,b+s2); vga_drawline(a+s2,b+s2,a+s3,b+s4); vga_drawline(a+s3,b+s4,a+s4,b); break; case 'X': vga_drawline(a,b,a+s2,b+s4); vga_drawline(a+s2,b,a,b+s4); break; case 'Y': vga_drawline(a,b,a+s1,b+s2); vga_drawline(a+s2,b,a+s1,b+s2); vga_drawline(a+s1,b+s2,a+s1,b+s4); break; case 'Z': vga_drawline(a,b,a+s2,b); vga_drawline(a+s2,b,a,b+s4); vga_drawline(a,b+s4,a+s2,b+s4); break; /*** 2c: numbers ***/ /* 0 already done */ case '1': vga_drawline(a,b+s1,a+s1,b); vga_drawline(a+s1,b,a+s1,b+s4); vga_drawline(a,b+s4,a+s2,b+s4); break; case '2': fontc_u(a+s1,b+s1,siz); vga_drawline(a+s2,b+s1,a,b+s4); vga_drawline(a,b+s4,a+s2,b+s4); break; case '3': fontc_u(a+s1,b+s1,siz); fontc_lr(a+s1,b+s1,siz); break; case '4': vga_drawline(a+s1,b+s4,a+s1,b); vga_drawline(a+s1,b,a,b+s2); vga_drawline(a,b+s2,a+s2,b+s2); break; case '5': vga_drawline(a+s2,b,a,b); vga_drawline(a,b,a,b+s2); vga_drawline(a,b+s2,a+s1,b+s2); break; case '6': fontc_u(a+s1,b+s1,siz); vga_drawline(a,b+s1,a,b+s3); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -