/* * 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 #include #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<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; iinc_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; iinc_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<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> 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'; }