home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / RIFED / RIFONT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-27  |  13.0 KB  |  376 lines

  1. // definice tridy RIFONT, deklarace jsou uvedeny v hlavickovem
  2. // souboru rifont.h
  3.  
  4. // ************************************************************************
  5. // *                  DEFINICE  METOD  TRIDY  RIFONT                        *
  6. // ************************************************************************
  7. // Nektere metody muzete vynechat pro zjednoduseni cele tridy,
  8. // napr. metody pro editovani textu. Naopak nejsou zde metody,
  9. // ktere jednoduse odvodite napr. showtextcolor a podobne.
  10.  
  11. #include "rifont.h"
  12.  
  13. RIFONT::RIFONT(void) {      // konstruktor tridy
  14.   d=NULL;
  15.   status=0;
  16. }
  17.  
  18. RIFONT::RIFONT(int *tbf, unsigned char *bmf) {
  19.   t = tbf;       // ukazatel na tabulku adres bit.map a sirek znaku
  20.   b = bmf;       // ukazatel na zacatek bitovych map
  21.   color=BLACK;   // barva textu
  22.   backgr=WHITE;  // barva pozadi (jen pri overtext)
  23.   status_ed=0;   // status editovaciho okna
  24.   status=1;      // data pripravena
  25. }
  26.  
  27. RIFONT::~RIFONT() {         // destruktor tridy, musi uvolnit pamet HEAP
  28.   if(d!=NULL) farfree(d);
  29. }
  30.  
  31. int RIFONT::load(char *filename) {
  32.   // do pripravene instance provede nacteni dat fontu ze souboru
  33.   // jedna instance muze stidat ruzne data. Vysledek diskovycch operaci
  34.   // a prideleni pameti je ulozen v promenne "status", ktera je vracena
  35.   // touto metodou a muze slouzit k testovani uspesnosti nacteni dat.
  36.  
  37.   if (d != NULL) { farfree(d); d=NULL; }
  38.   // d=NULL, je priznak uvolneneho HEAPu, aby nedoslo k opakovanemu uvolneni
  39.   struct stat statbuf; long data_size; char parita=0, id[3]; int c;
  40.   FILE *f0;
  41.   if((f0=fopen(filename, "rb"))==NULL) {
  42.     status=-2;               // chyba - nenalezen soubor, nezdaril se fopen()
  43.     return (status);
  44.   }
  45.   fstat(fileno(f0), &statbuf);
  46.   id[0]=fgetc(f0); id[1]=fgetc(f0); id[2]=0; parita=0; i=0;
  47.   if(strcmp(id, "af")==0) {
  48.     do {
  49.       c=fgetc(f0);         // preskoc pripadny copyright
  50.       parita^=c; i++;
  51.     } while (c!=0);
  52.   }
  53.   else {
  54.     fclose(f0);
  55.     status=-4;             // neznamy typ souboru
  56.     return (status);
  57.   }
  58.   data_size = statbuf.st_size-i-2;
  59.   // potrebna pamet je mensi o 2 znaky 'af' a delku textu copyright
  60.   // nez delka souboru
  61.   d = farmalloc(data_size);// prideleni potrebne pameti
  62.   if(d == NULL) {
  63.     fclose(f0);
  64.     status=-1;             // chyba - malo pameti HEAP
  65.     return (status);
  66.   }
  67.   b=(char*)d;
  68.   for(i=0; i<data_size; i++) {
  69.     b[i]=fgetc(f0);
  70.     parita^=b[i];
  71.   }
  72.   fclose(f0);
  73.   if(parita!=0xba) {
  74.     status=-3;             // chyba - nesouhlasi paritni byte
  75.     return(status);
  76.   }
  77.   t=(int*)d;
  78.   b=(char*) (t+2*(t[1]-30));
  79.   status=1;                // cteni OK !
  80.   color=BLACK;
  81.   backgr=WHITE;
  82.   return(status);
  83. }
  84.  
  85. int RIFONT::getstatus(void) {
  86.   // vraci vysledek metody load() a pripravenost dat fontu pro moznost
  87.   // testovani pred vystupem testu.
  88.   return(status);
  89. }
  90.  
  91. int RIFONT::ready(void) {
  92.   // Test pripravenosti dat fontu. Pokus o vypis textu po chybe pri load
  93.   // zpusobi vypis chyboveho hlaseni vestvenym fontem.
  94.   // Muze byt resen i jinak (dialog. okno, prevedeni adres na sytemovy font,
  95.   // ktery je soucasti programu ap.)  Zavisi na zkusenostech programatora.
  96.  
  97.   if (status== 1) return(1);
  98.   if (status== 0) outtextxy(xx, yy, "font neni inicializovan");
  99.   if (status==-1) outtextxy(xx, yy, "malo pameti heap pro font");
  100.   if (status==-2) outtextxy(xx, yy, "soubor fontu nenalezen");
  101.   if (status==-3) outtextxy(xx, yy, "data fontu porusena");
  102.   if (status==-4) outtextxy(xx, yy, "neznamy typ font souboru");
  103.   return(0);
  104. }
  105.  
  106. void RIFONT::showchar(void) {
  107.   // privatni metoda test ready() provedou verejne metody
  108.   int wide, index;          // sirka znaku, index v bitove mape
  109.   unsigned char pat;        // vzorek bitove mapy ( 1 byte)
  110.   cch -=32;
  111.   wide=t[2+2*cch+1];        // vybere sirku znaku
  112.   if (wide) {
  113.     index=t[2+2*cch];       // zacatek bitove mapy znaku
  114.       do{ for (int cy=yy; (cy-yy)<t[0]; cy++)  {     // cykl vysky znaku
  115.      pat = b[index++];
  116.      for (int cx=xx; pat !=0; cx++, pat <<=1)    // cykl jednoho vzorku
  117.        if (pat & 0x80) putpixel (cx, cy, color); // vypis aktiv. pixelu
  118.      } xx+=8;           // priprava pro sirsi znak nez 8 pixelu
  119.       } while((wide-=8)>0); // kdyz je znak sirsi nez 8 pixelu
  120.     xx+=wide;               // pripravi souradnici x pro dalsi znak;
  121.   }
  122. }
  123. // funkci putpixel by bylo mozne nahradit casti v assembleru,
  124. // vypisy znacne zrychli, ale bude zavisle na driveru grafiky
  125. // a tedy ruzne pro karty VGA, SVGA, Hercules.
  126.  
  127. void RIFONT::overchar(void) {
  128.   // privatni metoda test ready() provedou verejne metody
  129.   int cx, cy, ii, wide, index;
  130.   unsigned char pat;
  131.   cch -=32;
  132.   wide  = t[2+2*cch+1];
  133.   index = t[2+2*cch];
  134.     do{ for (cy=yy; (cy-yy)<t[0]; cy++)  {
  135.       pat = b[index++];
  136.       for (cx=xx, ii=0; (ii<8)&&(ii<wide); ii++, pat <<=1) {
  137.         if (pat & 0x80) putpixel (cx+ii, cy, color);
  138.         else putpixel(cx+ii, cy, backgr);   // zde je prepis pozadi
  139.       }
  140.     } xx+=8;
  141.     } while((wide-=8)>0);
  142.   xx+=wide;
  143. }
  144.  
  145. void RIFONT::showchar(int x, int y, unsigned char ch) {
  146.   xx=xstart=x; yy=y; cch=ch;
  147.   if (cch<=t[1] && cch>=32 && ready()) showchar();
  148. }
  149.  
  150. void RIFONT::overchar(int x, int y, unsigned char ch) {
  151.   xx=xstart=x; yy=y; cch=ch;
  152.   if(ch<=t[1] && ch>=32 && ready()) overchar();
  153. }
  154.  
  155. void RIFONT::showtext(int x, int y, char *str) {
  156.   xx=xstart=x; yy=y; i=0;
  157.   if (ready()) {
  158.     while ((cch=str[i++])!=0) {
  159.       if (cch<=t[1] && cch>=32) showchar();
  160.       else if(cch=='\n') { xx=xstart; yy+=gethigh(); }
  161.     }
  162.   }
  163. }
  164.  
  165. void RIFONT::overtext (int x, int y, char *str) {
  166.   // prepisuje pozadi textu, je pomala
  167.   // jeli mozne dejte prednost kombinaci bar() a showtext().
  168.   // rychejsi overtext je ve verzi 2.0
  169.   xx=xstart=x; yy=y; i=0;
  170.   if (ready()) {
  171.     while ((cch=str[i++])!=0) {
  172.       if (cch<=t[1] && cch>=32) overchar();
  173.       else if(cch=='\n') { xx=xstart; yy+=gethigh(); }
  174.     }
  175.   }
  176. }
  177. int RIFONT::getwidth(unsigned char ch) {  // sirka znaku
  178.   if (ch>t[1] || ch<32 || status!=1) return(0);
  179.   return(t[2*(ch-31)+1]);
  180. }
  181.  
  182. int RIFONT::getwidth(char *str) {        // sirka textu
  183.   if(status!=1) return(0);
  184.   int w=0; i=0;
  185.   while ((cch=str[i++]) != '\0') {
  186.     if ((cch<=t[1]) && (cch>=32))
  187.       w += t[2*(cch-31)+1];
  188.     if (cch == '\n') return(w);  // pro viceradkovy text urci sirku 1.radku
  189.   }
  190.   return (w);
  191. }
  192. void RIFONT::curs_hide(void) {     // uschova editacniho kurzoru
  193.   mouse_hide();
  194.   putimage(xcurr, ystarted, cursbuf, COPY_PUT);
  195.   if(status_ed!=1) mouse_show();
  196. }
  197.  
  198. void RIFONT::curs_show(void) {     // zobrazeni editacniho kurzoru
  199.   if(status_ed!=1) mouse_hide();
  200.   getimage(xcurr, ystarted, xcurr, ystarted+t[0]-1, cursbuf);
  201.   putimage(xcurr, ystarted, cursbuf, NOT_PUT);
  202.   mouse_show();
  203. }
  204.  
  205. void RIFONT::txed_show(int x, int y, int xwidth, int yhigh, int nchar,
  206.              int test, char *str) {
  207.   xstarted=xsed=x;
  208.   ystarted=ysed=y;                  // levy horni roh editacniho ramecku
  209.   tt=test; nlen=nchar;
  210.   xwed=(xwidth>24)?xwidth:24;       // minimalni sirka textu 24 pixelu
  211.   editbuf=str;
  212.   flaged=status_ed=1;               // povoli editaci a ev. vymaz pri 1.znaku
  213.   mouse_hide();
  214.   if(yhigh) {                       // bude-li zobrazen editacni ramecek
  215.     yhed=(yhigh>(t[0]+2)) ? yhigh : t[0]+2;
  216.     xstarted = xsed+4;              // pro lepsi citelnost
  217.     ystarted = ysed+(yhed-t[0])/2;  // stanoveni minimalni vysky ramecku
  218.     setfillstyle(SOLID_FILL, backgr);
  219.     setcolor(color);
  220.     bar3d(xsed, ysed, xsed+xwed, ysed+yhed, 0, 0);
  221.   }
  222.   xcurr=xstarted+getwidth(editbuf);         // nastavi edit.kurzor
  223.   pc=pe=strlen(editbuf);                    // nastavi citace znaku
  224.   showtext(xstarted, ystarted, editbuf);    // vypis pocatecniho textu
  225.   curs_show();                              // provede i mouse_show();
  226. }
  227. int RIFONT::txed_mouse(int mx, int my) {
  228.   if (status_ed==-1 || status!=1) return (-1);
  229.   if (mx<xsed||mx>xsed+xwed||my<ysed||my>ysed+yhed) {  // ** neni v ramecku
  230.      if (status_ed==1) { status_ed=0; curs_hide(); }   // pozastaveni editace
  231.   }
  232.   else {                                  // ** je v ramecku
  233.      if(status_ed==1) curs_hide();
  234.      for (pc=0, xcurr=xstarted;           // najde nejblizsi znak za mysi
  235.      (xcurr < mx) && (pc<pe);
  236.      xcurr += getwidth(editbuf[pc]), pc++);
  237.      flaged=0;                            // zrusi vymaz po 1.znaku
  238.      curs_show();
  239.      status_ed=1;                         // obnoveni ev. pozastavene editace
  240.   }
  241.   return (status_ed);
  242. }
  243. int RIFONT::txed_keyb(int character, int extended) {
  244.   if (status_ed==-1 || status!=1) return -1;
  245.   if (status_ed==0) return 1;  // pozastavena editace
  246.   if (character==13) {  // (klavesa enter)
  247.      status_ed=0;       // pozastavi editaci
  248.      curs_hide();       // zmizi textovy kurzor
  249.      return(0);
  250.   }
  251.   curs_hide();
  252.   if (character) {      // test pripustne mnoziny znaku
  253.     int res=0;          // budeteli rusit tento test, zruste
  254.     switch(tt) {        // i nasledne testy promenne "res" !
  255.       case 0: if (character>31) res=1; break;
  256.       case 1: res=(isalnum(character) || (character == '_')); break;
  257.       case 2: res=isalpha(character); break;
  258.       case 3: res=isdigit(character); break;
  259.       default:res=isprint(character);
  260.     }
  261.     if (flaged==1 && res) {         // prvni zapisovany znak vymaze buffer
  262.       setfillstyle(SOLID_FILL, backgr);
  263.       bar(xstarted, ystarted, xstarted+getwidth(editbuf), ystarted+t[0]-1);
  264.       xcurr=xstarted;
  265.       pc=pe=0;
  266.       editbuf[0]=0;                // vymaz pocatecniho textu
  267.     }
  268.     if ((pe<nlen) && res && (getwidth(editbuf)+getwidth(character))<xwed) {
  269.           // vynechateli test na res, musite testovat rozsah character
  270.           // < 32..t[1]> jinak nebude fungovat backspace !
  271.       for (i=pe++; i>=pc; i--) editbuf[i+1] = editbuf[i];
  272.       editbuf[pc]=character;
  273.       overtext(xcurr, ystarted, &editbuf[pc++]);
  274.       xcurr += getwidth(character);
  275.     }
  276.     if ((character==8) && (pc>0)) {
  277.       pc--; xcurr-=getwidth(editbuf[pc]);
  278.       character=0; extended=83;   // konverse backspace na delete.
  279.     }
  280.   }  // konec ascii znaku dale zpracovani pohybu kurzoru *************
  281.   switch(extended){
  282.      case 71: xcurr=xstarted; pc=0; break;                     // home
  283.      case 75: if(pc> 0) xcurr-=getwidth(editbuf[--pc]); break; // left
  284.      case 77: if(pc<pe) xcurr+=getwidth(editbuf[pc++]); break; // right
  285.      case 79: xcurr=xstarted+getwidth(editbuf); pc=pe;  break; // end
  286.      case 83: if (pc<pe) {                                     // delete
  287.         int wdel=getwidth(editbuf[pc]); int ff;
  288.         for (i=pc; i<pe; i++) {
  289.            ff=editbuf[i+1];
  290.            editbuf[i]=ff;
  291.         }
  292.         editbuf[--pe]=0;
  293.         overtext(xcurr, ystarted, &editbuf[pc]);
  294.         setfillstyle(SOLID_FILL, WHITE);
  295.         int xe=xstarted+getwidth(editbuf);
  296.         bar(xe, ystarted, xe+wdel, ystarted+t[0]-1);
  297.           }
  298.           break;
  299.      }
  300.   flaged=0;     // zrusi moznost vymazu pocatecniho textu
  301.   curs_show();
  302.   return(1);
  303. }
  304.  
  305. //************************ konec definice metod tridy RIFONT *****************
  306.  
  307. //                     *** pomocne funkce pro graficky rezim ***
  308. // Pomocne funkce jsou jen pro doplneni. Pokud pouzivate vlasti ovladace
  309. // grafickeho rezimu, nebo mysi tyto funkce smazte (i v souboru rifont.h)
  310.  
  311. // ------------------------------- NASTAVENI GRAFIKY -----------------------
  312.  
  313. void GrInit() {  // inicializace grafickeho rezimu VGA 640*480 bodu
  314. int driver = VGA;
  315. int mode = VGAHI;
  316. int gr;
  317. initgraph( &driver, &mode, "..\\bgi\\");
  318. // uvedena cesta "..\\bgi\\" muze zpusobit chybu. Zalezi na nastaveni
  319. // vystupniho adresare prekladace. Pri potizich udejte uplnou cestu
  320. // k vasemu adresari bgi, ktery je soucasti prekladace BORLAND C.
  321. if ((gr=graphresult()) == 0) return;
  322.   cprintf("Chyba grafickeho rezimu:\n>> %s <<\n",grapherrormsg(gr));
  323.   getch();
  324.   exit(1);
  325. }
  326.  
  327. // ---------------------------------  OVLADANI MYSI ------------------------
  328. // odladeno pro ovladac  GENIUS MOUSE  verze 6.06
  329. // pozici mysi zjisti funkce: mouse_pos(mys_x, mys_y, mys_b);
  330. // Predpoklada insatlovany driver mysi.
  331.  
  332. void mouse_init (void)
  333. // inicializace mysi, vola se jen pri startu programu,
  334. // po nastaveni grafickeho rezimu
  335. {  union REGS r;
  336.    r.x.ax = 0;
  337.    int86 (51, &r, &r);
  338.    if ((int)r.x.ax != -1)
  339.      {cprintf ("Potrebny hardware/software pro mys neni instalovan.\n");
  340.      getch();
  341.      exit (1);}
  342.    r.x.ax = 7;   //  mouse_x_range
  343.    r.x.cx = 0;   //  xmin
  344.    r.x.dx = 622; //  xmax
  345.    int86 (51, &r, &r);
  346.    r.x.ax = 8;   //  mouse_y_range
  347.    r.x.cx = 0;   //  ymin;
  348.    r.x.dx = 464; //  ymax;
  349.    int86 (51, &r, &r);
  350.    r.x.ax = 4;   //  mouse_set, pocatecni zobrazeni
  351.    r.x.cx = 115; //  x
  352.    r.x.dx = 260; //  y
  353.    int86 (51, &r, &r);
  354.    r.x.ax = 1;   //  mouse_show
  355.    int86 (51, &r, &r);
  356. }
  357.  
  358. void mouse_show() {
  359.    union REGS r; r.x.ax = 1;
  360.    int86 (51, &r, &r);
  361. }
  362.  
  363. void mouse_hide() {
  364.    union REGS r; r.x.ax = 2;
  365.    int86 (51, &r, &r);
  366. }
  367.  
  368. void mouse_pos (int *x, int *y, int *b) {
  369.    // funkce pro zjisteni pozice mysi a stavu tlacitek mysi.
  370.    union REGS r;
  371.    r.x.ax = 3;
  372.    int86 (51, &r, &r);
  373.    *x = r.x.cx;
  374.    *y = r.x.dx;
  375.    *b = r.x.bx & 3;
  376. }