home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
util
/
edit
/
jade
/
src
/
glyphs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-03
|
17KB
|
607 lines
/* glyphs.c -- Construction of character images
Copyright (C) 1994 John Harper <jsh@ukc.ac.uk>
This file is part of Jade.
Jade is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Jade is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jade; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "jade.h"
#include "jade_protos.h"
#include <string.h>
#include <stdlib.h>
#ifdef NEED_MEMORY_H
# include <memory.h>
#endif
_PR long make_glyph_array(TX *, const u_char *, long, long, u_char *, long, long);
_PR long string_glyph_length(TX *, const u_char *, long);
_PR long glyph_col(TX *, long, long);
_PR long char_col(TX *, long, long);
_PR void calc_cursor_offset(VW *);
_PR void adjust_cursor_to_glyph(VW *);
_PR u_char *char_glyphs(TX *, u_char);
_PR long expand_tabs(TX *, u_char *, long, long, long, long *);
_PR void glyphtable_sweep(void);
_PR void glyphtable_prin(VALUE, VALUE);
_PR void glyphs_init(void);
_PR void glyphs_kill(void);
/* This table stores the number of glyphs which have to be printed to
make up each character. 0 is a special case -- TABSIZE spaces. */
typedef char glyph_widths_t[256];
/* This stores the glyphs which have to be printed to create each
single character, each character (except tabs) can be made of
no more than 4 glyphs. The above table is used to decide how
many to use out of the possible 4. */
typedef u_char glyph_glyphs_t[256][4];
typedef struct _GlyphTable{
u_char gt_Type;
u_char gt_Flags;
struct _GlyphTable *gt_Next;
glyph_widths_t gt_Widths;
glyph_glyphs_t gt_Glyphs;
} GlyphTable;
#define GTF_STATIC 1 /* Don't free() this table */
static GlyphTable default_glyph_table = {
V_GlyphTable,
GTF_STATIC,
NULL,
{
2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
},
{
"^@ ", "^A ", "^B ", "^C ", "^D ", "^E ", "^F ", "^G ",
"^H ", " TAB", "^J ", "^K ", "^L ", "^M ", "^N ", "^O ",
"^P ", "^Q ", "^R ", "^S ", "^T ", "^U ", "^V ", "^W ",
"^X ", "^Y ", "^Z ", "^[ ", "^\\ ", "^] ", "^^ ", "^_ ",
" ", "! ", "\" ", "# ", "$ ", "% ", "& ", "' ",
"( ", ") ", "* ", "+ ", ", ", "- ", ". ", "/ ",
"0 ", "1 ", "2 ", "3 ", "4 ", "5 ", "6 ", "7 ",
"8 ", "9 ", ": ", "; ", "< ", "= ", "> ", "? ",
"@ ", "A ", "B ", "C ", "D ", "E ", "F ", "G ",
"H ", "I ", "J ", "K ", "L ", "M ", "N ", "O ",
"P ", "Q ", "R ", "S ", "T ", "U ", "V ", "W ",
"X ", "Y ", "Z ", "[ ", "\\ ", "] ", "^ ", "_ ",
"` ", "a ", "b ", "c ", "d ", "e ", "f ", "g ",
"h ", "i ", "j ", "k ", "l ", "m ", "n ", "o ",
"p ", "q ", "r ", "s ", "t ", "u ", "v ", "w ",
"x ", "y ", "z ", "{ ", "| ", "} ", "~ ", "^? ",
"\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
"\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
"\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
"\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
"\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
"\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
"\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
"\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
"\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
"\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
"\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
"\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
"\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
"\\350", "\\351", "\\252", "\\353", "\\354", "\\355", "\\356", "\\357",
"\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
"\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377"
}
};
static GlyphTable *gt_chain = &default_glyph_table;
/* From the array of characters SRC, build an array of glyph codes DST.
SRC contains at least SRC-LEN characters. On return, there is guaranteed
to be no more than DST-LEN glyph codes in DST, the actual number is
the return value of the function. No glyphs are copied to DST until
DST-START glyphs have gone before. SRC-ORIG is the *true glyph* position
of SRC, for calculating tab sizes. */
long
make_glyph_array(TX *tx, const u_char *src, long srcOrig, long srcLen,
register u_char *dst, long dstStart, long dstLen)
{
glyph_widths_t *width_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Widths;
glyph_glyphs_t *glyph_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Glyphs;
register long i = 0;
if(dstStart != 0)
{
/* Skip DSTSTART glyphs */
register long j = 0;
while((j < dstStart) && (srcLen-- > 0))
{
register int w = (*width_table)[*src++];
if(w == 0)
{
j += tx->tx_TabSize - ((j + srcOrig) % tx->tx_TabSize);
if(j > dstStart)
{
i = j - dstStart;
memset(dst, ' ', i);
dst += i;
break;
}
}
else
{
j += w;
if(j > dstStart)
{
i = j - dstStart;
memcpy(dst, &(*glyph_table)[src[-1]][w-i], i);
dst += i;
break;
}
}
}
}
while((i < dstLen) && (srcLen-- > 0))
{
register u_char c;
switch((*width_table)[c = *src++])
{
case 0:
{
/* TAB special case */
register int size = tx->tx_TabSize - ((i + srcOrig + dstStart)
% tx->tx_TabSize);
memset(dst, ' ', size);
dst += size;
i += size;
}
break;
case 1:
*dst++ = (*glyph_table)[c][0];
i++;
break;
case 2:
*dst++ = (*glyph_table)[c][0];
*dst++ = (*glyph_table)[c][1];
i += 2;
break;
case 3:
*dst++ = (*glyph_table)[c][0];
*dst++ = (*glyph_table)[c][1];
*dst++ = (*glyph_table)[c][2];
i += 3;
break;
case 4:
*dst++ = (*glyph_table)[c][0];
*dst++ = (*glyph_table)[c][1];
*dst++ = (*glyph_table)[c][2];
*dst++ = (*glyph_table)[c][3];
i += 4;
break;
}
}
return(i);
}
/* Returns the number of glyphs needed to draw the string SRC. */
long
string_glyph_length(TX *tx, const u_char *src, long srcLen)
{
glyph_widths_t *width_table = &VGLYPHTAB(tx->tx_GlyphTable)->gt_Widths;
register long w;
for(w = 0; srcLen-- > 0;)
{
register int w1 = (*width_table)[*src++];
if(w1 == 0)
w += tx->tx_TabSize - (w % tx->tx_TabSize);
else
w += w1;
}
return(w);
}
/* Return the glyph index of (COL,LINE) in TX. */
long
glyph_col(TX *tx, long col, long linenum)
{
LINE *line = tx->tx_Lines + linenum;
if(col >= line->ln_Strlen)
{
return((string_glyph_length(tx, line->ln_Line, line->ln_Strlen - 1)
+ (col - (line->ln_Strlen - 1))));
}
else
return(string_glyph_length(tx, line->ln_Line, col));
}
/* Find how many chars