home *** CD-ROM | disk | FTP | other *** search
- /**
- ** DRAWTEXT.C
- **
- ** Copyright (C) 1992, Csaba Biegl
- ** 820 Stirrup Dr, Nashville, TN, 37221
- ** csaba@vuse.vanderbilt.edu
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.cb", available from the author at the address above.
- ** A copy of "copying.cb" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.cb".
- ** You should also have received a copy of the GNU General Public
- ** License along with this program (it is in the file "copying");
- ** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
- ** Cambridge, MA 02139, USA.
- **
- ** This program 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.
- **/
-
- #include "grx.h"
- #include "libgrx.h"
- #include "grxfont.h"
- #include "clipping.h"
- #include "gmalloc.h"
- #include "memfill.h"
- #include "memcopy.h"
- #include <string.h>
-
-
- #define TXT_CLIP 1
- #define TXT_NORMAL 0
- #define TXT_ONEPIX 2
- #define TXT_LARGE 4
-
-
- #define BUILDMAT(m00,m01,m10,m11) \
- { mat00 = m00; mat01 = m01; mat10 = m10; mat11 = m11; }
- #define MMULT_X(_x,_y) (mat00*(_x) + mat01*(_y))
- #define MMULT_Y(_x,_y) (mat10*(_x) + mat11*(_y))
- /*
- #define UPDATE_X(x,y) x += MMULT_X(1,0),y += MMULT_Y(1,0)
- #define UPDATE_Y(x,y) x += MMULT_X(0,1),y += MMULT_Y(0,1)
- */
- #define UPDATE_X(x,y) x += mat00,y += mat10
- #define UPDATE_Y(x,y) x += mat01,y += mat11
-
-
- #define GETBITS() if((mask >>= 1) == 0) { bits = *bitmap++; mask = 0x80; }
-
- void GrDrawString(char *text,int length,int x,int y,GrTextOption *opt)
- {
- GrFont *f = CHECK_FONT(opt->txo_font);
- GrColorTableP fgcp,bgcp;
- char far *bitmap,*tempp = NULL;
- int type = opt->txo_chrtype;
- int needs_clipping;
- int mode,mode2,fixed;
- int xchr,chr,attr;
- int width,height;
- int mat00,mat01;
- int mat10,mat11;
- int pixww,pixhh;
- int pixdx,pixdy;
- int chrww,chrhh;
- int chrdx,chrdy;
- int x1,x2,y1,y2;
- int xdot,ydot;
- int bits,mask;
- int fgc,bgc;
- int underline = 0;
- int ww,hh;
- MOUSE_FLAG;
-
- if((f == NULL) ||
- (_GrGetTextSize(text,length,&width,&height,opt) == FALSE) ||
- (width == 0) ||
- (height == 0))
- return;
- if((ww = width) < 0) { ww = (-ww); x += (ww - 1); }
- if((hh = height) < 0) { hh = (-hh); y += (hh - 1); }
- switch(opt->txo_xalign) {
- case GR_ALIGN_RIGHT:
- x -= (ww - 1);
- break;
- case GR_ALIGN_CENTER:
- x -= (ww >> 1);
- break;
- }
- switch(opt->txo_yalign) {
- case GR_ALIGN_BASELINE:
- if(opt->txo_direct == GR_TEXT_DEFAULT) y -= f->fnt_baseline;
- break;
- case GR_ALIGN_BOTTOM:
- y -= (hh - 1);
- break;
- case GR_ALIGN_CENTER:
- y -= (hh >> 1);
- break;
- }
- x2 = (x1 = x) + width + ((width > 0) ? (-1) : 1);
- y2 = (y1 = y) + height + ((height > 0) ? (-1) : 1);
- needs_clipping = FALSE;
- #undef WHEN_CLIPPED
- #define WHEN_CLIPPED needs_clipping = TRUE
- CLIPBOX(CURC,x1,y1,x2,y2);
- MOUSE_BLOCK(CURC,x1,y1,x2,y2);
- switch(type) {
- case GR_ATTR_TEXT:
- attr = (-1);
- fgcp = opt->txo_fgcolor.p;
- bgcp = opt->txo_bgcolor.p;
- break;
- case GR_WORD_TEXT:
- default:
- fgc = opt->txo_fgcolor.v;
- bgc = opt->txo_bgcolor.v;
- if(fgc & GR_UNDERLINE_TEXT) {
- fgc &= ~GR_UNDERLINE_TEXT;
- underline = f->fnt_undwidth;
- }
- if((fgc & (GrXOR | GrOR | GrAND)) == GrWRITE) {
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,x2-x1+1,y2-y1+1);
- bgc = GrNOCOLOR;
- }
- }
- switch(opt->txo_direct) {
- case GR_TEXT_DOWN:
- mode = TXT_ONEPIX;
- pixww = opt->txo_ymag;
- pixhh = opt->txo_xmag;
- BUILDMAT(0,-pixww,pixhh,0);
- break;
- case GR_TEXT_LEFT:
- mode = TXT_ONEPIX;
- pixww = opt->txo_xmag;
- pixhh = opt->txo_ymag;
- BUILDMAT(-pixww,0,0,-pixhh);
- break;
- case GR_TEXT_UP:
- mode = TXT_ONEPIX;
- pixww = opt->txo_ymag;
- pixhh = opt->txo_xmag;
- BUILDMAT(0,pixww,-pixhh,0);
- break;
- default:
- mode = TXT_NORMAL;
- pixww = opt->txo_xmag;
- pixhh = opt->txo_ymag;
- BUILDMAT(pixww,0,0,pixhh);
- break;
- }
- if((pixww > 1) || (pixhh > 1)) mode = TXT_LARGE;
- if((pixdx = MMULT_X(1,1)) > 0) pixdx = 0; else pixdx++;
- if((pixdy = MMULT_Y(1,1)) > 0) pixdy = 0; else pixdy++;
- if((fixed = f->fnt_isfixed) != FALSE) {
- width = f->fnt_width;
- height = f->fnt_height;
- chrdx = MMULT_X(width,0);
- chrdy = MMULT_Y(width,0);
- if((chrww = MMULT_X(width,height)) > 0) chrww--; else chrww++;
- if((chrhh = MMULT_Y(width,height)) > 0) chrhh--; else chrhh++;
- }
- mode2 = mode;
- while(--length >= 0) {
- switch(type) {
- case GR_WORD_TEXT:
- chr = *((unsigned short *)text)++;
- break;
- case GR_ATTR_TEXT:
- xchr = *((short *)text)++;
- chr = xchr & 0xff;
- if(attr != (xchr &= 0xff00)) {
- fgc = (xchr >> 8) & 0x0f;
- bgc = (xchr >> 12) & 0x07;
- fgc = GR_CTABLE_COLOR(fgcp,fgc);
- bgc = GR_CTABLE_COLOR(bgcp,bgc);
- underline = (xchr & 0x8000) ? f->fnt_undwidth : 0;
- attr = xchr;
- }
- break;
- default:
- chr = *((unsigned char *)text)++;
- break;
- }
- if((chr > f->fnt_maxchar) || ((chr -= f->fnt_minchar) < 0)) {
- if(fixed) {
- x1 = x; x2 = x + chrww; x += chrdx;
- y1 = y; y2 = y + chrhh; y += chrdy;
- if(bgc == GrNOCOLOR) continue;
- SORT2(x1,x2);
- SORT2(y1,y2);
- #undef WHEN_OUTSIDE
- #undef WHEN_CLIPPED
- #define WHEN_OUTSIDE continue
- #define WHEN_CLIPPED
- if(needs_clipping) CLIPSORTEDBOX(CURC,x1,y1,x2,y2);
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,x2-x1+1,y2-y1+1);
- }
- continue;
- }
- if(fixed)
- bitmap = FFP(f)->ff_bits + (chr * FFP(f)->ff_chrsize);
- else {
- bitmap = PFP(f)->pf_bits[chr];
- width = PFP(f)->pf_width[chr];
- height = f->fnt_height;
- chrdx = MMULT_X(width,0);
- chrdy = MMULT_Y(width,0);
- if((chrww = MMULT_X(width,height)) > 0) chrww--; else chrww++;
- if((chrhh = MMULT_Y(width,height)) > 0) chrhh--; else chrhh++;
- }
- if(underline > 0) {
- if(tempp == NULL)
- tempp = _GrGetTempBuffer((fixed ? width : PFP(f)->pf_maxwidth) * height);
- if(tempp != NULL) {
- _ClrDir();
- ww = (width + 7) >> 3;
- hh = height - underline;
- _SaveDS();
- _RowCpyB(TXT,tempp,bitmap,(ww * hh));
- _RestoreDS();
- bitmap = &tempp[ww * hh];
- _SaveDS();
- _RowSetB(TXT,bitmap,0xff,(ww * underline));
- _RestoreDS();
- bitmap = tempp;
- }
- }
- xdot = x; x += chrdx;
- ydot = y; y += chrdy;
- if(needs_clipping) {
- x1 = xdot; x2 = xdot + chrww;
- y1 = ydot; y2 = ydot + chrhh;
- mode2 = mode;
- #undef WHEN_CLIPPED
- #define WHEN_CLIPPED mode2 |= TXT_CLIP
- CLIPBOX(CURC,x1,y1,x2,y2);
- }
- xdot += pixdx;
- ydot += pixdy;
- switch(mode2) {
- case TXT_NORMAL:
- _GrDrawChar(PIXEL_ADDR(xdot,ydot),width,height,bitmap,fgc,bgc);
- break;
- case TXT_ONEPIX:
- for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
- x1 = xdot; y1 = ydot;
- for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
- GETBITS();
- if(bits & mask) {
- _GrSetPixel(PIXEL_ADDR(x1,y1),fgc);
- }
- else if(bgc != GrNOCOLOR) {
- _GrSetPixel(PIXEL_ADDR(x1,y1),bgc);
- }
- }
- }
- break;
- case (TXT_NORMAL | TXT_CLIP):
- case (TXT_ONEPIX | TXT_CLIP):
- for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
- x1 = xdot; y1 = ydot;
- for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
- GETBITS();
- #undef WHEN_CLIPPED
- #define WHEN_CLIPPED
- CLIPDOT(CURC,x1,y1);
- if(bits & mask) {
- _GrSetPixel(PIXEL_ADDR(x1,y1),fgc);
- }
- else if(bgc != GrNOCOLOR) {
- _GrSetPixel(PIXEL_ADDR(x1,y1),bgc);
- }
- }
- }
- break;
- case TXT_LARGE:
- for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
- x1 = xdot; y1 = ydot;
- for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
- GETBITS();
- if(bits & mask) {
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),fgc,pixww,pixhh);
- }
- else if(bgc != GrNOCOLOR) {
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,pixww,pixhh);
- }
- }
- }
- break;
- case (TXT_LARGE | TXT_CLIP):
- for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
- int x0 = xdot, y0 = ydot;
- for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x0,y0)) {
- GETBITS();
- x2 = (x1 = x0) + pixww - 1;
- y2 = (y1 = y0) + pixhh - 1;
- CLIPSORTEDBOX(CURC,x1,y1,x2,y2);
- if(bits & mask) {
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),
- fgc,
- (x2 - x1 + 1),
- (y2 - y1 + 1)
- );
- }
- else if(bgc != GrNOCOLOR) {
- _GrSetPixBlock(PIXEL_ADDR(x1,y1),
- bgc,
- (x2 - x1 + 1),
- (y2 - y1 + 1)
- );
- }
- }
- }
- break;
- }
- }
- MOUSE_UNBLOCK();
- }
-
- void GrDrawChar(int chr,int x,int y,GrTextOption *opt)
- {
- char cbuff[2];
- short sbuff[2];
-
- switch(opt->txo_chrtype) {
- case GR_WORD_TEXT:
- case GR_ATTR_TEXT:
- sbuff[0] = chr;
- GrDrawString((char *)sbuff,1,x,y,opt);
- break;
- default:
- cbuff[0] = chr;
- GrDrawString(cbuff,1,x,y,opt);
- break;
- }
- }
-
- void GrTextXY(int x,int y,char *text,int fg,int bg)
- {
- static GrTextOption opt = { NULL, 1, 1, 0 };
-
- if(opt.txo_font == NULL) opt.txo_font = CHECK_FONT(NULL);
- opt.txo_fgcolor.v = fg;
- opt.txo_bgcolor.v = bg;
- GrDrawString(text,strlen(text),x,y,&opt);
- }
-