home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / sprint / spfonts4.zip / SPFONTED.C < prev    next >
C/C++ Source or Header  |  1989-06-24  |  11KB  |  503 lines

  1. /* SPFONTED - SPFONT Font Editor */
  2.  
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <sys\stat.h>
  6. #include <dos.h>
  7.  
  8.  
  9. #ifdef RAMFONT
  10.  #define MAXFONTS    12
  11.  #define CHARSPERFONT    256
  12.  #define CHAROFFSET    0
  13. #else
  14.  #define MAXFONTS    8
  15.  #define CHARSPERFONT    224
  16.  #define CHAROFFSET    32
  17. #endif
  18.  
  19. #define MAXCHARHEIGHT    16
  20.  
  21. #define BLOCKSPERPIXEL    2
  22.  
  23. #define NORMAL        0x07
  24.  
  25. int charheight;
  26.  
  27. /***************************************************************************/
  28.  
  29. imax(int a, int b)
  30.     {
  31.     return((a > b) ? a : b);
  32.     }
  33.  
  34. /***************************************************************************/
  35.  
  36. static int VidRow, VidCol;
  37.  
  38. VidGotoRC(int row, int column)
  39.     {
  40.     VidRow = row;
  41.     VidCol = column;
  42.  
  43.     _DX = (row * 256) + column;
  44.     _BX = 0;
  45.     _AH = 0x02;
  46.     geninterrupt(0x10);
  47.     }
  48.  
  49. VidClearScreen()
  50.     {
  51.     _BH = NORMAL;
  52.     _CX = 0x0000;
  53.     _DX = 0x184F;
  54.     _AX = 0x0600;            /* scroll whole window = clear */
  55.     geninterrupt(0x10);
  56.  
  57.     VidGotoRC(VidRow = 0, VidCol = 0);
  58.     }
  59.  
  60. /* Place a char at the current cursor position */
  61. VidPlaceChr(int ch)
  62.     {
  63.     _BX = NORMAL;
  64.     _CX = 1;
  65.     _AX = ch;
  66.     _AH = 0x09;
  67.     geninterrupt(0x10);
  68.     }
  69.  
  70. /* Print a char. Supports backspace. */
  71. VidPutChr(int ch)
  72.     {
  73.     if (ch == '\b')
  74.         {
  75.         if (0 < VidCol)
  76.             VidGotoRC(VidRow, --VidCol);
  77.         }
  78.     else
  79.         {
  80.         VidPlaceChr(ch);
  81.         VidGotoRC(VidRow, ++VidCol);
  82.         }
  83.     }
  84.  
  85. VidRptChr(int ch, int n)
  86.     {
  87.     while (0 < n--)
  88.         VidPutChr(ch);
  89.     }
  90.  
  91. VidPutStr(char *str)
  92.     {
  93.     while (*str)
  94.         {
  95.         VidPutChr(*str++);
  96.         }
  97.     }
  98.  
  99. VidBox(int upperrow, int leftcolumn, int lowerrow, int rightcolumn)
  100.     {
  101.     int r, c;
  102.  
  103.     VidGotoRC(upperrow, leftcolumn); VidPlaceChr('┌');
  104.     for (c = leftcolumn+1; c <= rightcolumn-1; c++)
  105.         { VidGotoRC(upperrow, c); VidPlaceChr('─'); }
  106.     VidGotoRC(upperrow, rightcolumn); VidPlaceChr('┐');
  107.     for (r = upperrow+1; r <= lowerrow-1; r++)
  108.         { VidGotoRC(r, rightcolumn); VidPlaceChr('│'); }
  109.     VidGotoRC(lowerrow, rightcolumn); VidPlaceChr('┘');
  110.     for (c = rightcolumn-1; c >= leftcolumn+1; c--)
  111.         { VidGotoRC(lowerrow, c); VidPlaceChr('─'); }
  112.     VidGotoRC(lowerrow, leftcolumn); VidPlaceChr('└');
  113.     for (r = lowerrow-1; r >= upperrow+1; r--)
  114.         { VidGotoRC(r, leftcolumn); VidPlaceChr('│'); }
  115.     }
  116.  
  117. /***************************************************************************/
  118.  
  119. KbdGetch()
  120.     {
  121.     int key;
  122.  
  123.     if ((key = getch()) == 0)
  124.         return(256 + getch());
  125.     else
  126.         return(key);
  127.     }
  128.  
  129. /* input up to n-1 characters into buf. backspace & del are the only
  130.  * editing characters.  input is terminated by any control character
  131.  * (which is not echoed).  returns the (effective) number of chars typed,
  132.  * or -1 if ESC was pressed.
  133.  */
  134. KbdGetStr(char *buf, int n)
  135.     {
  136.     char *bp;
  137.     int c;
  138.  
  139.     bp = buf;
  140.     for (;;)
  141.         {
  142.         c = KbdGetch();
  143.         if (' ' <= c && c <= 0x7e)
  144.             {
  145.             if (bp < buf+n)
  146.                 VidPutChr(*bp++ = c);
  147.             }
  148.         else if (c == '\b' || c == 0x7f)
  149.             {
  150.             if (buf < bp)
  151.                 {
  152.                 VidPutStr("\b \b");
  153.                 bp--;
  154.                 }
  155.             }
  156.         else if (c == '\r')
  157.             break;
  158.         else if (c == 0x1b)
  159.             {
  160.             buf[0] = '\0';
  161.             return(-1);
  162.             }
  163.         }
  164.  
  165.     *bp = '\0';
  166.     return(bp - buf);
  167.     }
  168.  
  169. /* input a string, with default.  return NULL is ESC pressed during entry */
  170. char *
  171. KbdAskStr(str, x, y, prompt, defalt, width)
  172. char *str, *prompt, *defalt;
  173. int x, y, width;
  174.     {
  175.     char def[80+1];
  176.     int len;
  177.  
  178.     strcpy(def, defalt);    /* save 'cause str & default may be the same */
  179.  
  180.     VidGotoRC(x, y);
  181.  
  182.     if (prompt)
  183.         {
  184.         VidPutStr(prompt);
  185.         if (*prompt)
  186.             VidPutStr(" ? ");
  187.         }
  188.  
  189.     VidPutStr(def);
  190.     VidRptChr('_', imax(width-strlen(def), 0));
  191.  
  192.     VidRptChr('\b', imax(strlen(def), width));
  193.  
  194.     if ((len = KbdGetStr(str, width)) == -1)
  195.         return(NULL);
  196.     else if (len == 0)
  197.         {
  198.         strcpy(str, def);
  199.         VidPutStr(str);
  200.         }
  201.     VidRptChr(' ', imax(width-strlen(str), 0));
  202.  
  203.     return(str);
  204.     }
  205.  
  206. /***************************************************************************/
  207.  
  208. #define ROWBASE        2
  209. #define COLBASE        15
  210.  
  211. static int mask[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } ;
  212.  
  213. FontPrintBackground()
  214.     {
  215.     int r;
  216.  
  217.     VidClearScreen();
  218.     VidPutStr("SPFONTED - SPFONT Font Editor");
  219.  
  220.     VidGotoRC(ROWBASE,   0); VidPutStr("Font");
  221.     VidGotoRC(ROWBASE+1, 0); VidPutStr("Char");
  222.  
  223.     VidBox(ROWBASE, COLBASE, ROWBASE+charheight+1, COLBASE+(BLOCKSPERPIXEL*8)+1);
  224.  
  225.     r = 0;
  226.     VidGotoRC(r++, 50); VidPutStr("Key Functions");
  227.     VidGotoRC(r++, 50); VidPutStr("");
  228.     VidGotoRC(r++, 50); VidPutStr("F     next Font");
  229.     VidGotoRC(r++, 50); VidPutStr("");
  230.     VidGotoRC(r++, 50); VidPutStr("PgUp  previous char");
  231.     VidGotoRC(r++, 50); VidPutStr("PgDn  next char");
  232.     VidGotoRC(r++, 50); VidPutStr("");
  233.     VidGotoRC(r++, 50); VidPutChr(24); VidPutStr("     pixel up");
  234.     VidGotoRC(r++, 50); VidPutChr(27); VidPutStr("     pixel left");
  235.     VidGotoRC(r++, 50); VidPutChr(26); VidPutStr("     pixel right");
  236.     VidGotoRC(r++, 50); VidPutChr(25); VidPutStr("     pixel down");
  237.     VidGotoRC(r++, 50); VidPutStr("");
  238.     VidGotoRC(r++, 50); VidPutStr("Ins,+ pixel on");
  239.     VidGotoRC(r++, 50); VidPutStr("Del,- pixel off");
  240.     VidGotoRC(r++, 50); VidPutStr("space pixel toggle");
  241.     VidGotoRC(r++, 50); VidPutStr("");
  242.     VidGotoRC(r++, 50); VidPutStr("^Z    Zap (clear) char");
  243.     VidGotoRC(r++, 50); VidPutStr("");
  244.     VidGotoRC(r++, 50); VidPutStr("W     Write font file");
  245.     VidGotoRC(r++, 50); VidPutStr("ESC   exit program");
  246.  
  247.     }
  248.  
  249. FontTogglePixel(char *map, int r, int c)
  250.     {
  251.     map[r] = (map[r] ^ mask[c]);
  252.     FontPrintPixel(map, r, c);
  253.     }
  254.  
  255. FontClearPixel(char *map, int r, int c)
  256.     {
  257.     map[r] = (map[r] & ~mask[c]);
  258.     FontPrintPixel(map, r, c);
  259.     }
  260.  
  261. FontSetPixel(char *map, int r, int c)
  262.     {
  263.     map[r] = (map[r] | mask[c]);
  264.     FontPrintPixel(map, r, c);
  265.     }
  266.  
  267. FontPrintPixel(char *map, int r, int c)
  268.     {
  269.     VidGotoRC(ROWBASE+1+r, COLBASE+1+((7-c)*BLOCKSPERPIXEL));
  270.     VidPlaceChr((map[r] & mask[c]) ? 0xf : ' ');
  271.     }
  272.  
  273. FontPrintChar(int fnum, int cnum, char *map)
  274.     {
  275.     int r, c, i;
  276.     char work[10], pixch;
  277.  
  278.     itoa(fnum, work, 10);
  279.     VidGotoRC(ROWBASE, 5+2); VidPutStr(work); VidPutStr("   ");
  280.     itoa(CHAROFFSET+cnum, work, 10);
  281.     VidGotoRC(ROWBASE+1, 5); VidPutStr(work); VidPutStr("   ");
  282.  
  283.     for (r = 0; r < charheight; r++)
  284.         {
  285.         for (c = 7; 0 <= c; c--)
  286.             {
  287.             FontPrintPixel(map, r, c);
  288.             }
  289.         }
  290.     VidGotoRC(ROWBASE+1, COLBASE+1);
  291.     }
  292.  
  293. /***************************************************************************/
  294.  
  295. #define PROMPTLINE    21
  296. #define STRINGSIZE    60
  297.  
  298. ClearPromptLine()
  299.     {
  300.     VidGotoRC(PROMPTLINE, 0);
  301.     VidRptChr(' ', 79);
  302.     VidGotoRC(PROMPTLINE, 0);
  303.     }
  304.  
  305. WriteFile(char *defname, char font[MAXFONTS][CHARSPERFONT][MAXCHARHEIGHT])
  306.     {
  307.     char fname[STRINGSIZE+1], *result;
  308.     int fd;
  309.     int fnt, chr;
  310.  
  311.     result = KbdAskStr(fname, PROMPTLINE, 0, "Write to", defname, STRINGSIZE);
  312.     if (result == NULL)
  313.         {
  314.         ClearPromptLine();
  315.         return(0);
  316.         }
  317.  
  318.     if ((fd = open(fname, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)) < 0)
  319.         {
  320.         ClearPromptLine();
  321.         VidPutStr("can't create font file!  press any key.");
  322.         KbdGetch();
  323.         return(0);
  324.         }
  325.     for (fnt = 0; fnt < MAXFONTS; fnt++)
  326.         for (chr = 0; chr < CHARSPERFONT; chr++)
  327.             {
  328.             if (write(fd, font[fnt][chr], charheight) != charheight)
  329.                 {
  330.                 ClearPromptLine();
  331.                 VidPutStr("can't write font file!  press any key.");
  332.                 KbdGetch();
  333.                 return(0);
  334.                 }
  335.             }
  336.     close(fd);
  337.  
  338.     ClearPromptLine();
  339.     VidPutStr("Saved!  press any key.");
  340.     KbdGetch();
  341.     return(1);
  342.     }
  343.  
  344. main(int ac, char *av[])
  345.     {
  346.     char font[MAXFONTS][CHARSPERFONT][MAXCHARHEIGHT];
  347.     int fd;
  348.     struct stat fntstat;
  349.     int dirty, reprint;
  350.     char resp[1+1], *result;
  351.  
  352.     int fnt, chr;
  353.     int byt, bit;
  354.  
  355.     if (ac != 2)
  356.         {
  357.         fprintf(stderr, "usage: SPFONTED fontfile\n");
  358.         exit(1);
  359.         }
  360.     if ((fd = open(av[1], O_RDONLY|O_BINARY)) < 0)
  361.         {
  362.         fprintf(stderr, "can't open font file: %s\n", av[1]);
  363.         exit(2);
  364.         }
  365.     fstat(fd, &fntstat);
  366.     charheight = fntstat.st_size / (MAXFONTS*CHARSPERFONT);
  367.  
  368.     for (fnt = 0; fnt < MAXFONTS; fnt++)
  369.         for (chr = 0; chr < CHARSPERFONT; chr++)
  370.             {
  371.             if (read(fd, font[fnt][chr], charheight) != charheight)
  372.                 {
  373.                 fprintf(stderr, "can't read font file\n");
  374.                 exit(2);
  375.                 }
  376.             }
  377.     close(fd);
  378.     dirty = 0;
  379.  
  380.     FontPrintBackground();
  381.     fnt = 0; chr = 0;
  382.  
  383.     reprint = 1;
  384.     for (;;)
  385.         {
  386.         if (reprint)
  387.             {
  388.             FontPrintChar(fnt, chr, font[fnt][chr]);
  389.             byt = 0; bit = 7;
  390.             reprint = 0;
  391.             }
  392.  
  393.         switch (KbdGetch())
  394.             {
  395.         case 'F':
  396.         case 'f':
  397.             if (MAXFONTS <= ++fnt)
  398.                 fnt = 0;
  399.             reprint = 1;
  400.             break;
  401.         case 256+81:    /* PgDn */
  402.             if (CHARSPERFONT <= ++chr)
  403.                 chr = 0;
  404.             reprint = 1;
  405.             break;
  406.         case 256+73:    /* PgUp */
  407.             if (--chr < 0)
  408.                 chr = CHARSPERFONT-1;
  409.             reprint = 1;
  410.             break;
  411.         case 0x1a:    /* ^Z */
  412.             for (byt = 0; byt < charheight; byt++)
  413.                 font[fnt][chr][byt] = '\0';
  414.             reprint = 1;
  415.             break;
  416.         case 0x04:    /* ^D */
  417.             for (byt = charheight-2; 0 <= byt; byt--)
  418.                 font[fnt][chr][byt+1] = font[fnt][chr][byt];
  419.             font[fnt][chr][0] = '\0';
  420.             reprint = 1;
  421.             break;
  422.         case 0x15:    /* ^U */
  423.             for (byt = 0; byt <= charheight-2; byt++)
  424.                 font[fnt][chr][byt] = font[fnt][chr][byt+1];
  425.             font[fnt][chr][charheight-1] = '\0';
  426.             reprint = 1;
  427.             break;
  428.         case 256+77:    /* Right */
  429.             if (0 < bit)
  430.                 bit--;
  431.             FontPrintPixel(font[fnt][chr], byt, bit);
  432.             break;
  433.         case 256+75:    /* Left */
  434.             if (bit < 7)
  435.                 bit++;
  436.             FontPrintPixel(font[fnt][chr], byt, bit);
  437.             break;
  438.         case 256+72:    /* Up */
  439.             if (0 < byt)
  440.                 byt--;
  441.             FontPrintPixel(font[fnt][chr], byt, bit);
  442.             break;
  443.         case 256+80:    /* Down */
  444.             if (byt < (charheight-1))
  445.                 byt++;
  446.             FontPrintPixel(font[fnt][chr], byt, bit);
  447.             break;
  448.         case ' ':
  449.             FontTogglePixel(font[fnt][chr], byt, bit);
  450.             dirty = 1;
  451.             break;
  452.         case 256+82:    /* Ins */
  453.             FontSetPixel(font[fnt][chr], byt, bit);
  454.             dirty = 1;
  455.             break;
  456.         case 256+83:    /* Del */
  457.             FontClearPixel(font[fnt][chr], byt, bit);
  458.             dirty = 1;
  459.             break;
  460.         case 'W':
  461.         case 'w':
  462.             if (WriteFile(av[1], font))
  463.                 dirty = 0;
  464.             reprint = 1;
  465.             break;
  466.         case 0x1b:
  467.             if (dirty)
  468.                 {
  469. asksave:            result = KbdAskStr(resp, PROMPTLINE, 0, "Font file has been modified, save it (Y/N)", "Y", 1);
  470.                 if (result == NULL)
  471.                     {
  472.                     ClearPromptLine();
  473.                     reprint = 1;
  474.                     break;
  475.                     }
  476.                 else if (resp[0] == 'Y' || resp[0] == 'y')
  477.                     {
  478.                     if (WriteFile(av[1], font))
  479.                         {
  480.                         VidGotoRC(23, 0);
  481.                         exit(0);
  482.                         }
  483.                     else
  484.                         reprint = 1;
  485.                     }
  486.                 else if (resp[0] == 'N' || resp[0] == 'n')
  487.                     {
  488.                     VidGotoRC(23, 0);
  489.                     exit(0);
  490.                     }
  491.                 else
  492.                     goto asksave;        /* so I'm a lousy programmer -- sue me! */
  493.                 }
  494.             else
  495.                 {
  496.                 VidGotoRC(23, 0);
  497.                 exit(0);
  498.                 }
  499.             break;
  500.             }
  501.         }
  502.     }
  503.