home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file contains routines which can be used to determine the character
- * present at a given location in a window. These functions are used to
- * determine the character under the mouse cursor, and for the log-top printer
- * function.
- */
-
- #include <stdio.h>
- #include <osbind.h>
- #include "windefs.h"
-
- extern struct wi_str w[];
-
- int highlighted_wdes = -1; /* make this global now for use in winmain.c*/
-
- /*
- * char_at returns the ascii code of the character in wdes window at
- * (x_loc, y_loc) cursor position. Zero is returned if the character can
- * not be identified.
- */
- int char_at(wdes, x_loc, y_loc)
- int wdes, x_loc, y_loc;
-
- {
-
- register struct wi_str *wp = &w[wdes];
- int ch, width, boffset, count, cur_y, cur_x;
- register unsigned long mask;
- register unsigned long *dptr;
- register int shift;
- register FNT *fnt = wp->font;
- static char pa[32]; /* pixel array containing character image */
-
- cur_x = x_loc * fnt->inc_x + X0;
- cur_y = y_loc * fnt->inc_y + wp->top_y;
-
- width = 2 * wp->wi_mf.wwords;
- boffset = wp->m_off+cur_x+fnt->inc_x-1;
- dptr = ((char *)(wp->wi_mf.ptr)) + cur_y * width
- + ((boffset >> 4) << 1) - 2;
- shift = 15 - (boffset & 15);
- mask = (-1L<<(shift+fnt->inc_x)|(1<<shift)-1);
- for (count = 0; count < fnt->inc_y; count ++)
- {
- pa[count] = (*dptr & (~ mask)) >> shift;
- ((char *) dptr) += width;
- }
-
- ch = which_char(fnt, &fnt->f_hash, pa);
- if (ch == 0) /* Not found, check for inverse vidio case */
- {
- for (count = 0; count < fnt->inc_y; count ++)
- pa[count] = ~pa[count] & (1<< fnt->inc_x) - 1;
- ch = which_char(fnt, &fnt->f_hash, pa);
- }
- return (ch);
- }
-
- /*
- * which_char returns the ascii code of the character bitmap in pa from font
- * font using hash table htbl.
- */
- int which_char(font, htbl, pa)
- FNT *font;
- HTBL *htbl;
- char *pa;
-
- {
- register int i, h, n;
-
- h = hash_char (pa, font->inc_y);
- if ((htbl->h_t[h] & 128) == 0) /* collision bit set? */
- {
- for (i=0; i<font->inc_y; i++)
- if (font->f_data[(htbl->h_t)[h] * 16 + i] != pa[i])
- break;
- if (i < font->inc_y){
- return 0;
- }
- else
- return (htbl->h_t[h]);
- }
- else /* collision, search colision list for char */
- {
- n = htbl->h_t[h] & 127;
- while (n != 0)
- {
- for (i=0; i<font->inc_y; i++)
- if (font->f_data[(htbl->h_colision)[n].h_try * 16 + i] != pa[i])
- break;
- if (i < font->inc_y)
- n = htbl->h_colision[n].h_next;
- else
- return (htbl->h_colision[n].h_try);
- }
- return 0;
- }
- }
-
- /*
- * gen_hash initalizes htbl with the hash table for font font.
- */
- void gen_hash(font, htbl)
- FNT *font;
- HTBL *htbl;
-
- {
- register int overflowcnt = 1;
- register int np, tp, i, j;
- int h;
-
- for (i=0; i<128; i++) /* initalize */
- htbl->h_colision[i].h_next = '\0';
- for (i=0; i<(1<<HASHBITS); i++)
- htbl->h_t[i] = '\0';
-
- for (i=32; i<128; i++)
- { /* for each character */
- h = hash_char(&font->f_data[i*16], font->inc_y);
- if (htbl->h_t[h] == 0)
- htbl->h_t[h] = i;
- else
- {
- if ((htbl->h_t[h] & 128) == 0) /* already overflowed? */
- { /* No, move first element to overflow list */
- htbl->h_colision[overflowcnt].h_try = htbl->h_t[h];
- htbl->h_t[h] = 128 | overflowcnt;
- overflowcnt++;
- }
-
- tp = htbl->h_t[h] & 127;
- j=0; /* dbug */
- while ((np = htbl->h_colision[tp].h_next) != 0){
- tp = np;
- j++; /* dbug */
- }
- #ifdef DEBUG
- printf("overflow=%d depth=%d hash %d = %d\n",overflowcnt, j, i, h);
- #endif
- htbl->h_colision[tp].h_next = overflowcnt;
- htbl->h_colision[overflowcnt].h_try = i;
- ++ overflowcnt;
- }
- }
-
- #ifdef DEBUG /* verify sanity of hash table */
- for (i=32; i<128; i++) /* dbug */
- if ((j = which_char(font, htbl, &font->f_data[i*16])) != i)
- {
- printf("%d != %d\n", i, j);
- }
- #endif
- }
-
- /*
- * hash_char returns the hash code for the character pixel image in pa of
- * height height.
- */
- int hash_char(pa, height)
- char *pa;
- int height;
-
- {
- register int h, i, j;
-
- h=0;
- for (i=0; i<height; i++)
- {
- h += pa[i] << i*3 % HASHBITS;
- }
- j = (1<<HASHBITS) - 1;
- h = (h + (h >> HASHBITS + 1)) & j;
-
- return h;
- }
-
- /*
- * dump_line send the y_coord'th line in the window wdes to the printer.
- * zero is returned if the line was printed ok.
- */
- dump_line(wdes, y_coord)
- {
- int i;
- char ch;
-
- for (i = 0; i < w[wdes].x_chrs; i++){
- ch = char_at(wdes, i, y_coord);
- #if 0
- if (Cprnout(ch) == 0) {
- w[wdes].ptr_status = LOG_NONE;
- return -1;
- }
- #endif
- }
- #if 0
- if (Cprnout('\n') == 0 | Cprnout('\r') == 0) {
- w[wdes].ptr_status = LOG_NONE;
- return -1;
- }
- #endif
- return 0;
- }
-
- /*
- * dump_window send the contents of wdes to the printer.
- */
- dump_window(wdes)
- {
- int i;
-
- for (i = 0; i < w[wdes].y_chrs; i++){
- dump_line(wdes, i);
- }
- }
- /* copy_word fills buffer with the word at (x1, y1) from wdes
- * No checks are made for buffer overflow.
- */
- copy_word(wdes, x1, y1, buffer)
- int wdes, x1, y1;
- char * buffer;
- {
- register int fx, lx, yo, xo;
-
- yo = w[wdes].y_off / w[wdes].font->inc_y; /* adjust for scroll bar action */
- xo = w[wdes].x_off / w[wdes].font->inc_x;
- fx = x1 - 1;
- lx = x1 + 1;
-
- while (fx + xo >= 0 && char_at(wdes, fx + xo, y1 + yo) != ' ')
- --fx;
- while (lx + xo < w[wdes].x_chrs && char_at(wdes, lx + xo, y1 + yo) != ' ')
- ++lx;
- copy_text(wdes, ++fx, y1, --lx, y1, buffer);
- }
-
- /* copy_text fills buffer with the text between (x1, y1) and (x2, y2) from wdes
- * where point 1 is before point 2. No checks are made for buffer overflow.
- */
- copy_text(wdes, x1, y1, x2, y2, buffer)
- int wdes, x1, y1, x2, y2;
- char * buffer;
- {
- static int old_hh;
- static int old_y1;
- register int cx, cy, i, lastnbi, lastnbx;
- int inc_y, inc_x, top_y;
-
- /* undo any old selected text which might be inverted on screen */
- if (highlighted_wdes > 0 && w[highlighted_wdes].font != NULL)
- {
- w_update(highlighted_wdes, FM_COPY, 0, old_y1,
- w[highlighted_wdes].x_chrs * w[highlighted_wdes].font->inc_x + X0 + 1,
- old_hh);
- }
- if (y1 > y2) return; /* nothing to do */
-
- inc_y = w[wdes].font->inc_y;
- inc_x = w[wdes].font->inc_x;
- top_y = w[wdes].top_y;
-
- y1 = y1 + w[wdes].y_off / inc_y; /* adjust for scroll bar action */
- y2 = y2 + w[wdes].y_off / inc_y; /* assumes _off is multiple of inc_ */
- x1 = x1 + w[wdes].x_off / inc_x;
- x2 = x2 + w[wdes].x_off / inc_x;
- i = 0;
- lastnbi = 0;
- lastnbx = x1;
-
- if (y1 > y2)
- {
- highlighted_wdes = -1; /* no undo required on next call */
- return;
- }
-
- old_y1 = y1 * inc_y + top_y;
- old_hh = (y2 - y1 + 2) * inc_y + Y0;
- highlighted_wdes = wdes;
-
- cx = x1;
- cy = y1;
-
- while (cy < y2 || (cy == y2 && cx <= x2))
- {
- buffer[i] = char_at(wdes, cx, cy);
- if (buffer[i] != ' ')
- {
- lastnbi = i;
- lastnbx = cx;
- }
- cx ++;
- if (cx >= w[wdes].x_chrs)
- {
- if (cy == y1) /* first line */
- w_update(wdes, FM_INVERT, x1 * inc_x, cy * inc_y + top_y,
- (++lastnbx - x1) * inc_x + X0, inc_y);
- else
- w_update(wdes, FM_INVERT, 0, cy * inc_y + top_y,
- ++lastnbx * inc_x + X0, inc_y);
- cx = 0;
- cy ++;
- i = ++lastnbi;
- lastnbx = -1;
- buffer[i] = '\r';
- }
- i++;
- }
- if (cy == y1) /* one line */
- w_update(wdes, FM_INVERT, x1 * inc_x, cy * inc_y + top_y,
- (++lastnbx - x1) * inc_x + X0, inc_y);
- else
- w_update(wdes, FM_INVERT, 0, cy * inc_y + top_y,
- ++lastnbx * inc_x + X0, inc_y);
- buffer[++lastnbi] = '\0';
- }
-
-