home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / glyphs.c < prev    next >
C/C++ Source or Header  |  1994-10-03  |  17KB  |  607 lines

  1. /* glyphs.c -- Construction of character images
  2.    Copyright (C) 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <string.h>
  24. #include <stdlib.h>
  25.  
  26. #ifdef NEED_MEMORY_H
  27. # include <memory.h>
  28. #endif
  29.  
  30. _PR long make_glyph_array(TX *, const u_char *, long, long, u_char *, long, long);
  31. _PR long string_glyph_length(TX *, const u_char *, long);
  32. _PR long glyph_col(TX *, long, long);
  33. _PR long char_col(TX *, long, long);
  34. _PR void calc_cursor_offset(VW *);
  35. _PR void adjust_cursor_to_glyph(VW *);
  36. _PR u_char *char_glyphs(TX *, u_char);
  37. _PR long expand_tabs(TX *, u_char *, long, long, long, long *);
  38.  
  39. _PR void glyphtable_sweep(void);
  40. _PR void glyphtable_prin(VALUE, VALUE);
  41. _PR void glyphs_init(void);
  42. _PR void glyphs_kill(void);
  43.  
  44. /* This table stores the number of glyphs which have to be printed to
  45.    make up each character. 0 is a special case -- TABSIZE spaces.  */
  46. typedef char glyph_widths_t[256];
  47.  
  48. /* This stores the glyphs which have to be printed to create each
  49.    single character, each character (except tabs) can be made of
  50.    no more than 4 glyphs. The above table is used to decide how
  51.    many to use out of the possible 4.  */
  52. typedef u_char glyph_glyphs_t[256][4];
  53.  
  54. typedef struct _GlyphTable{
  55.     u_char        gt_Type;
  56.     u_char        gt_Flags;
  57.     struct _GlyphTable *gt_Next;
  58.     glyph_widths_t    gt_Widths;
  59.     glyph_glyphs_t    gt_Glyphs;
  60. } GlyphTable;
  61. #define GTF_STATIC 1        /* Don't free() this table */
  62.  
  63. static GlyphTable default_glyph_table = {
  64.     V_GlyphTable,
  65.     GTF_STATIC,
  66.     NULL,
  67.     {
  68.     2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
  69.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  70.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  71.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  72.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  73.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  74.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  75.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
  76.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  77.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  78.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  79.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  80.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  81.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  82.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  83.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
  84.     },
  85.     {
  86.     "^@  ", "^A  ", "^B  ", "^C  ", "^D  ", "^E  ", "^F  ", "^G  ",
  87.     "^H  ", " TAB", "^J  ", "^K  ", "^L  ", "^M  ", "^N  ", "^O  ",
  88.     "^P  ", "^Q  ", "^R  ", "^S  ", "^T  ", "^U  ", "^V  ", "^W  ",
  89.     "^X  ", "^Y  ", "^Z  ", "^[  ", "^\\  ", "^]  ", "^^  ", "^_  ",
  90.     "    ", "!   ", "\"   ", "#   ", "$   ", "%   ", "&   ", "'   ",
  91.     "(   ", ")   ", "*   ", "+   ", ",   ", "-   ", ".   ", "/   ",
  92.     "0   ", "1   ", "2   ", "3   ", "4   ", "5   ", "6   ", "7   ",
  93.     "8   ", "9   ", ":   ", ";   ", "<   ", "=   ", ">   ", "?   ",
  94.     "@   ", "A   ", "B   ", "C   ", "D   ", "E   ", "F   ", "G   ",
  95.     "H   ", "I   ", "J   ", "K   ", "L   ", "M   ", "N   ", "O   ",
  96.     "P   ", "Q   ", "R   ", "S   ", "T   ", "U   ", "V   ", "W   ",
  97.     "X   ", "Y   ", "Z   ", "[   ", "\\   ", "]   ", "^   ", "_   ",
  98.     "`   ", "a   ", "b   ", "c   ", "d   ", "e   ", "f   ", "g   ",
  99.     "h   ", "i   ", "j   ", "k   ", "l   ", "m   ", "n   ", "o   ",
  100.     "p   ", "q   ", "r   ", "s   ", "t   ", "u   ", "v   ", "w   ",
  101.     "x   ", "y   ", "z   ", "{   ", "|   ", "}   ", "~   ", "^?  ",
  102.     "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
  103.     "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
  104.     "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
  105.     "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
  106.     "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
  107.     "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
  108.     "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
  109.     "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
  110.     "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
  111.     "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
  112.     "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
  113.     "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
  114.     "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
  115.     "\\350", "\\351", "\\252", "\\353", "\\354", "\\355", "\\356", "\\357",
  116.     "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
  117.     "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377"
  118.     }
  119. };
  120.  
  121. static GlyphTable *gt_chain = &default_glyph_table;
  122.  
  123. /* From the array of characters SRC, build an array of glyph codes DST.
  124.    SRC contains at least SRC-LEN characters. On return, there is guaranteed
  125.    to be no more than DST-LEN glyph codes in DST, the actual number is
  126.    the return value of the function. No glyphs are copied to DST until
  127.    DST-START glyphs have gone before. SRC-ORIG is the *true glyph* position
  128.    of SRC, for calculating tab sizes.  */
  129. long
  130. make_glyph_array(TX *tx, const u_char *src, long srcOrig, long srcLen,
  131.          register u_char *dst, long dstStart, long dstLen)
  132. {
  133.     glyph_widths_t *width_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Widths;
  134.     glyph_glyphs_t *glyph_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Glyphs;
  135.     register long i = 0;
  136.     if(dstStart != 0)
  137.     {
  138.     /* Skip DSTSTART glyphs */
  139.     register long j = 0;
  140.     while((j < dstStart) && (srcLen-- > 0))
  141.     {
  142.         register int w = (*width_table)[*src++];
  143.         if(w == 0)
  144.         {
  145.         j += tx->tx_TabSize - ((j + srcOrig) % tx->tx_TabSize);
  146.         if(j > dstStart)
  147.         {
  148.             i = j - dstStart;
  149.             memset(dst, ' ', i);
  150.             dst += i;
  151.             break;
  152.         }
  153.         }
  154.         else
  155.         {
  156.         j += w;
  157.         if(j > dstStart)
  158.         {
  159.             i = j - dstStart;
  160.             memcpy(dst, &(*glyph_table)[src[-1]][w-i], i);
  161.             dst += i;
  162.             break;
  163.         }
  164.         }
  165.     }
  166.     }
  167.     while((i < dstLen) && (srcLen-- > 0))
  168.     {
  169.     register u_char c;
  170.     switch((*width_table)[c = *src++])
  171.     {
  172.     case 0:
  173.         {
  174.         /* TAB special case */
  175.         register int size = tx->tx_TabSize - ((i + srcOrig + dstStart)
  176.                               % tx->tx_TabSize);
  177.         memset(dst, ' ', size);
  178.         dst += size;
  179.         i += size;
  180.         }
  181.         break;
  182.     case 1:
  183.         *dst++ = (*glyph_table)[c][0];
  184.         i++;
  185.         break;
  186.     case 2:
  187.         *dst++ = (*glyph_table)[c][0];
  188.         *dst++ = (*glyph_table)[c][1];
  189.         i += 2;
  190.         break;
  191.     case 3:
  192.         *dst++ = (*glyph_table)[c][0];
  193.         *dst++ = (*glyph_table)[c][1];
  194.         *dst++ = (*glyph_table)[c][2];
  195.         i += 3;
  196.         break;
  197.     case 4:
  198.         *dst++ = (*glyph_table)[c][0];
  199.         *dst++ = (*glyph_table)[c][1];
  200.         *dst++ = (*glyph_table)[c][2];
  201.         *dst++ = (*glyph_table)[c][3];
  202.         i += 4;
  203.         break;
  204.     }
  205.     }
  206.     return(i);
  207. }
  208.  
  209. /* Returns the number of glyphs needed to draw the string SRC.    */
  210. long
  211. string_glyph_length(TX *tx, const u_char *src, long srcLen)
  212. {
  213.     glyph_widths_t *width_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Widths;
  214.     register long w;
  215.     for(w = 0; srcLen-- > 0;)
  216.     {
  217.     register int w1 = (*width_table)[*src++];
  218.     if(w1 == 0)
  219.         w += tx->tx_TabSize - (w % tx->tx_TabSize);
  220.     else
  221.         w += w1;
  222.     }
  223.     return(w);
  224. }
  225.  
  226. /* Return the glyph index of (COL,LINE) in TX.    */
  227. long
  228. glyph_col(TX *tx, long col, long linenum)
  229. {
  230.     LINE *line = tx->tx_Lines + linenum;
  231.     if(col >= line->ln_Strlen)
  232.     {
  233.     return((string_glyph_length(tx, line->ln_Line, line->ln_Strlen - 1)
  234.         + (col - (line->ln_Strlen - 1))));
  235.     }
  236.     else
  237.     return(string_glyph_length(tx, line->ln_Line, col));
  238. }
  239.  
  240. /* Find how many chars