home *** CD-ROM | disk | FTP | other *** search
- // definice tridy RIFONT, deklarace jsou uvedeny v hlavickovem
- // souboru rifont.h
-
- // ************************************************************************
- // * DEFINICE METOD TRIDY RIFONT *
- // ************************************************************************
- // Nektere metody muzete vynechat pro zjednoduseni cele tridy,
- // napr. metody pro editovani textu. Naopak nejsou zde metody,
- // ktere jednoduse odvodite napr. showtextcolor a podobne.
-
- #include "rifont.h"
-
- RIFONT::RIFONT(void) { // konstruktor tridy
- d=NULL;
- status=0;
- }
-
- RIFONT::RIFONT(int *tbf, unsigned char *bmf) {
- t = tbf; // ukazatel na tabulku adres bit.map a sirek znaku
- b = bmf; // ukazatel na zacatek bitovych map
- color=BLACK; // barva textu
- backgr=WHITE; // barva pozadi (jen pri overtext)
- status_ed=0; // status editovaciho okna
- status=1; // data pripravena
- }
-
- RIFONT::~RIFONT() { // destruktor tridy, musi uvolnit pamet HEAP
- if(d!=NULL) farfree(d);
- }
-
- int RIFONT::load(char *filename) {
- // do pripravene instance provede nacteni dat fontu ze souboru
- // jedna instance muze stidat ruzne data. Vysledek diskovycch operaci
- // a prideleni pameti je ulozen v promenne "status", ktera je vracena
- // touto metodou a muze slouzit k testovani uspesnosti nacteni dat.
-
- if (d != NULL) { farfree(d); d=NULL; }
- // d=NULL, je priznak uvolneneho HEAPu, aby nedoslo k opakovanemu uvolneni
- struct stat statbuf; long data_size; char parita=0, id[3]; int c;
- FILE *f0;
- if((f0=fopen(filename, "rb"))==NULL) {
- status=-2; // chyba - nenalezen soubor, nezdaril se fopen()
- return (status);
- }
- fstat(fileno(f0), &statbuf);
- id[0]=fgetc(f0); id[1]=fgetc(f0); id[2]=0; parita=0; i=0;
- if(strcmp(id, "af")==0) {
- do {
- c=fgetc(f0); // preskoc pripadny copyright
- parita^=c; i++;
- } while (c!=0);
- }
- else {
- fclose(f0);
- status=-4; // neznamy typ souboru
- return (status);
- }
- data_size = statbuf.st_size-i-2;
- // potrebna pamet je mensi o 2 znaky 'af' a delku textu copyright
- // nez delka souboru
- d = farmalloc(data_size);// prideleni potrebne pameti
- if(d == NULL) {
- fclose(f0);
- status=-1; // chyba - malo pameti HEAP
- return (status);
- }
- b=(char*)d;
- for(i=0; i<data_size; i++) {
- b[i]=fgetc(f0);
- parita^=b[i];
- }
- fclose(f0);
- if(parita!=0xba) {
- status=-3; // chyba - nesouhlasi paritni byte
- return(status);
- }
- t=(int*)d;
- b=(char*) (t+2*(t[1]-30));
- status=1; // cteni OK !
- color=BLACK;
- backgr=WHITE;
- return(status);
- }
-
- int RIFONT::getstatus(void) {
- // vraci vysledek metody load() a pripravenost dat fontu pro moznost
- // testovani pred vystupem testu.
- return(status);
- }
-
- int RIFONT::ready(void) {
- // Test pripravenosti dat fontu. Pokus o vypis textu po chybe pri load
- // zpusobi vypis chyboveho hlaseni vestvenym fontem.
- // Muze byt resen i jinak (dialog. okno, prevedeni adres na sytemovy font,
- // ktery je soucasti programu ap.) Zavisi na zkusenostech programatora.
-
- if (status== 1) return(1);
- if (status== 0) outtextxy(xx, yy, "font neni inicializovan");
- if (status==-1) outtextxy(xx, yy, "malo pameti heap pro font");
- if (status==-2) outtextxy(xx, yy, "soubor fontu nenalezen");
- if (status==-3) outtextxy(xx, yy, "data fontu porusena");
- if (status==-4) outtextxy(xx, yy, "neznamy typ font souboru");
- return(0);
- }
-
- void RIFONT::showchar(void) {
- // privatni metoda test ready() provedou verejne metody
- int wide, index; // sirka znaku, index v bitove mape
- unsigned char pat; // vzorek bitove mapy ( 1 byte)
- cch -=32;
- wide=t[2+2*cch+1]; // vybere sirku znaku
- if (wide) {
- index=t[2+2*cch]; // zacatek bitove mapy znaku
- do{ for (int cy=yy; (cy-yy)<t[0]; cy++) { // cykl vysky znaku
- pat = b[index++];
- for (int cx=xx; pat !=0; cx++, pat <<=1) // cykl jednoho vzorku
- if (pat & 0x80) putpixel (cx, cy, color); // vypis aktiv. pixelu
- } xx+=8; // priprava pro sirsi znak nez 8 pixelu
- } while((wide-=8)>0); // kdyz je znak sirsi nez 8 pixelu
- xx+=wide; // pripravi souradnici x pro dalsi znak;
- }
- }
- // funkci putpixel by bylo mozne nahradit casti v assembleru,
- // vypisy znacne zrychli, ale bude zavisle na driveru grafiky
- // a tedy ruzne pro karty VGA, SVGA, Hercules.
-
- void RIFONT::overchar(void) {
- // privatni metoda test ready() provedou verejne metody
- int cx, cy, ii, wide, index;
- unsigned char pat;
- cch -=32;
- wide = t[2+2*cch+1];
- index = t[2+2*cch];
- do{ for (cy=yy; (cy-yy)<t[0]; cy++) {
- pat = b[index++];
- for (cx=xx, ii=0; (ii<8)&&(ii<wide); ii++, pat <<=1) {
- if (pat & 0x80) putpixel (cx+ii, cy, color);
- else putpixel(cx+ii, cy, backgr); // zde je prepis pozadi
- }
- } xx+=8;
- } while((wide-=8)>0);
- xx+=wide;
- }
-
- void RIFONT::showchar(int x, int y, unsigned char ch) {
- xx=xstart=x; yy=y; cch=ch;
- if (cch<=t[1] && cch>=32 && ready()) showchar();
- }
-
- void RIFONT::overchar(int x, int y, unsigned char ch) {
- xx=xstart=x; yy=y; cch=ch;
- if(ch<=t[1] && ch>=32 && ready()) overchar();
- }
-
- void RIFONT::showtext(int x, int y, char *str) {
- xx=xstart=x; yy=y; i=0;
- if (ready()) {
- while ((cch=str[i++])!=0) {
- if (cch<=t[1] && cch>=32) showchar();
- else if(cch=='\n') { xx=xstart; yy+=gethigh(); }
- }
- }
- }
-
- void RIFONT::overtext (int x, int y, char *str) {
- // prepisuje pozadi textu, je pomala
- // jeli mozne dejte prednost kombinaci bar() a showtext().
- // rychejsi overtext je ve verzi 2.0
- xx=xstart=x; yy=y; i=0;
- if (ready()) {
- while ((cch=str[i++])!=0) {
- if (cch<=t[1] && cch>=32) overchar();
- else if(cch=='\n') { xx=xstart; yy+=gethigh(); }
- }
- }
- }
- int RIFONT::getwidth(unsigned char ch) { // sirka znaku
- if (ch>t[1] || ch<32 || status!=1) return(0);
- return(t[2*(ch-31)+1]);
- }
-
- int RIFONT::getwidth(char *str) { // sirka textu
- if(status!=1) return(0);
- int w=0; i=0;
- while ((cch=str[i++]) != '\0') {
- if ((cch<=t[1]) && (cch>=32))
- w += t[2*(cch-31)+1];
- if (cch == '\n') return(w); // pro viceradkovy text urci sirku 1.radku
- }
- return (w);
- }
- void RIFONT::curs_hide(void) { // uschova editacniho kurzoru
- mouse_hide();
- putimage(xcurr, ystarted, cursbuf, COPY_PUT);
- if(status_ed!=1) mouse_show();
- }
-
- void RIFONT::curs_show(void) { // zobrazeni editacniho kurzoru
- if(status_ed!=1) mouse_hide();
- getimage(xcurr, ystarted, xcurr, ystarted+t[0]-1, cursbuf);
- putimage(xcurr, ystarted, cursbuf, NOT_PUT);
- mouse_show();
- }
-
- void RIFONT::txed_show(int x, int y, int xwidth, int yhigh, int nchar,
- int test, char *str) {
- xstarted=xsed=x;
- ystarted=ysed=y; // levy horni roh editacniho ramecku
- tt=test; nlen=nchar;
- xwed=(xwidth>24)?xwidth:24; // minimalni sirka textu 24 pixelu
- editbuf=str;
- flaged=status_ed=1; // povoli editaci a ev. vymaz pri 1.znaku
- mouse_hide();
- if(yhigh) { // bude-li zobrazen editacni ramecek
- yhed=(yhigh>(t[0]+2)) ? yhigh : t[0]+2;
- xstarted = xsed+4; // pro lepsi citelnost
- ystarted = ysed+(yhed-t[0])/2; // stanoveni minimalni vysky ramecku
- setfillstyle(SOLID_FILL, backgr);
- setcolor(color);
- bar3d(xsed, ysed, xsed+xwed, ysed+yhed, 0, 0);
- }
- xcurr=xstarted+getwidth(editbuf); // nastavi edit.kurzor
- pc=pe=strlen(editbuf); // nastavi citace znaku
- showtext(xstarted, ystarted, editbuf); // vypis pocatecniho textu
- curs_show(); // provede i mouse_show();
- }
- int RIFONT::txed_mouse(int mx, int my) {
- if (status_ed==-1 || status!=1) return (-1);
- if (mx<xsed||mx>xsed+xwed||my<ysed||my>ysed+yhed) { // ** neni v ramecku
- if (status_ed==1) { status_ed=0; curs_hide(); } // pozastaveni editace
- }
- else { // ** je v ramecku
- if(status_ed==1) curs_hide();
- for (pc=0, xcurr=xstarted; // najde nejblizsi znak za mysi
- (xcurr < mx) && (pc<pe);
- xcurr += getwidth(editbuf[pc]), pc++);
- flaged=0; // zrusi vymaz po 1.znaku
- curs_show();
- status_ed=1; // obnoveni ev. pozastavene editace
- }
- return (status_ed);
- }
- int RIFONT::txed_keyb(int character, int extended) {
- if (status_ed==-1 || status!=1) return -1;
- if (status_ed==0) return 1; // pozastavena editace
- if (character==13) { // (klavesa enter)
- status_ed=0; // pozastavi editaci
- curs_hide(); // zmizi textovy kurzor
- return(0);
- }
- curs_hide();
- if (character) { // test pripustne mnoziny znaku
- int res=0; // budeteli rusit tento test, zruste
- switch(tt) { // i nasledne testy promenne "res" !
- case 0: if (character>31) res=1; break;
- case 1: res=(isalnum(character) || (character == '_')); break;
- case 2: res=isalpha(character); break;
- case 3: res=isdigit(character); break;
- default:res=isprint(character);
- }
- if (flaged==1 && res) { // prvni zapisovany znak vymaze buffer
- setfillstyle(SOLID_FILL, backgr);
- bar(xstarted, ystarted, xstarted+getwidth(editbuf), ystarted+t[0]-1);
- xcurr=xstarted;
- pc=pe=0;
- editbuf[0]=0; // vymaz pocatecniho textu
- }
- if ((pe<nlen) && res && (getwidth(editbuf)+getwidth(character))<xwed) {
- // vynechateli test na res, musite testovat rozsah character
- // < 32..t[1]> jinak nebude fungovat backspace !
- for (i=pe++; i>=pc; i--) editbuf[i+1] = editbuf[i];
- editbuf[pc]=character;
- overtext(xcurr, ystarted, &editbuf[pc++]);
- xcurr += getwidth(character);
- }
- if ((character==8) && (pc>0)) {
- pc--; xcurr-=getwidth(editbuf[pc]);
- character=0; extended=83; // konverse backspace na delete.
- }
- } // konec ascii znaku dale zpracovani pohybu kurzoru *************
- switch(extended){
- case 71: xcurr=xstarted; pc=0; break; // home
- case 75: if(pc> 0) xcurr-=getwidth(editbuf[--pc]); break; // left
- case 77: if(pc<pe) xcurr+=getwidth(editbuf[pc++]); break; // right
- case 79: xcurr=xstarted+getwidth(editbuf); pc=pe; break; // end
- case 83: if (pc<pe) { // delete
- int wdel=getwidth(editbuf[pc]); int ff;
- for (i=pc; i<pe; i++) {
- ff=editbuf[i+1];
- editbuf[i]=ff;
- }
- editbuf[--pe]=0;
- overtext(xcurr, ystarted, &editbuf[pc]);
- setfillstyle(SOLID_FILL, WHITE);
- int xe=xstarted+getwidth(editbuf);
- bar(xe, ystarted, xe+wdel, ystarted+t[0]-1);
- }
- break;
- }
- flaged=0; // zrusi moznost vymazu pocatecniho textu
- curs_show();
- return(1);
- }
-
- //************************ konec definice metod tridy RIFONT *****************
-
- // *** pomocne funkce pro graficky rezim ***
- // Pomocne funkce jsou jen pro doplneni. Pokud pouzivate vlasti ovladace
- // grafickeho rezimu, nebo mysi tyto funkce smazte (i v souboru rifont.h)
-
- // ------------------------------- NASTAVENI GRAFIKY -----------------------
-
- void GrInit() { // inicializace grafickeho rezimu VGA 640*480 bodu
- int driver = VGA;
- int mode = VGAHI;
- int gr;
- initgraph( &driver, &mode, "..\\bgi\\");
- // uvedena cesta "..\\bgi\\" muze zpusobit chybu. Zalezi na nastaveni
- // vystupniho adresare prekladace. Pri potizich udejte uplnou cestu
- // k vasemu adresari bgi, ktery je soucasti prekladace BORLAND C.
- if ((gr=graphresult()) == 0) return;
- cprintf("Chyba grafickeho rezimu:\n>> %s <<\n",grapherrormsg(gr));
- getch();
- exit(1);
- }
-
- // --------------------------------- OVLADANI MYSI ------------------------
- // odladeno pro ovladac GENIUS MOUSE verze 6.06
- // pozici mysi zjisti funkce: mouse_pos(mys_x, mys_y, mys_b);
- // Predpoklada insatlovany driver mysi.
-
- void mouse_init (void)
- // inicializace mysi, vola se jen pri startu programu,
- // po nastaveni grafickeho rezimu
- { union REGS r;
- r.x.ax = 0;
- int86 (51, &r, &r);
- if ((int)r.x.ax != -1)
- {cprintf ("Potrebny hardware/software pro mys neni instalovan.\n");
- getch();
- exit (1);}
- r.x.ax = 7; // mouse_x_range
- r.x.cx = 0; // xmin
- r.x.dx = 622; // xmax
- int86 (51, &r, &r);
- r.x.ax = 8; // mouse_y_range
- r.x.cx = 0; // ymin;
- r.x.dx = 464; // ymax;
- int86 (51, &r, &r);
- r.x.ax = 4; // mouse_set, pocatecni zobrazeni
- r.x.cx = 115; // x
- r.x.dx = 260; // y
- int86 (51, &r, &r);
- r.x.ax = 1; // mouse_show
- int86 (51, &r, &r);
- }
-
- void mouse_show() {
- union REGS r; r.x.ax = 1;
- int86 (51, &r, &r);
- }
-
- void mouse_hide() {
- union REGS r; r.x.ax = 2;
- int86 (51, &r, &r);
- }
-
- void mouse_pos (int *x, int *y, int *b) {
- // funkce pro zjisteni pozice mysi a stavu tlacitek mysi.
- union REGS r;
- r.x.ax = 3;
- int86 (51, &r, &r);
- *x = r.x.cx;
- *y = r.x.dx;
- *b = r.x.bx & 3;
- }