/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach8/mach8fc.c,v 3.7 1996/12/23 06:39:50 dawes Exp $ */ /* * Copyright 1992 by Kevin E. Martin, Chapel Hill, North Carolina. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Kevin E. Martin not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Kevin E. Martin makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * */ /* * Extract from s3fcach.c * Adapted to Mach8, Hans Nasten. (nasten@everyware.se). */ /* $XConsortium: mach8fc.c /main/6 1996/10/25 16:22:43 kaleb $ */ #include "X.h" #include "Xmd.h" #include "Xproto.h" #include "cfb.h" #include "misc.h" #include "xf86.h" #include "windowstr.h" #include "gcstruct.h" #include "fontstruct.h" #include "dixfontstr.h" #include "xf86bcache.h" #include "xf86fcache.h" #include "mach8.h" #include "regmach8.h" static unsigned long FontAge; #define NEXT_FONT_AGE ++FontAge /* * When using the 8514 compatible read mask, the read mask * is rotated right 1 bit compared to the write mask. */ unsigned char mach8cachemask[ 8 ] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; unsigned char mach8cachemaskswapped[ 8 ] = { 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01 }; /* * Move the glyphs to the screen using the GE. */ static void Domach8CPolyText8(x, y, count, chars, fentry, pGC, pBox) int x, y, count; unsigned char *chars; CacheFont8Ptr fentry; GCPtr pGC; BoxPtr pBox; { int gHeight, gWidth; int w = fentry->w; int blocki = 255; unsigned short height = 0; /* Cache for height, width and */ unsigned short width = 0; /* readmask registers. */ unsigned short pmsk = 0; /* ( Out instructions _are_ expensive ). */ for (;count > 0; count--, chars++) { CharInfoPtr pci; short xoff; pci = fentry->pci[*chars]; if (pci != NULL) { gHeight = GLYPHHEIGHTPIXELS(pci); gWidth = GLYPHWIDTHPIXELS(pci); if (gHeight && x + pci->metrics.leftSideBearing + gWidth-1 >= pBox->x1 && x + pci->metrics.leftSideBearing < pBox->x2 && y - pci->metrics.ascent + gHeight-1 >= pBox->y1 && y - pci->metrics.ascent < pBox->y2 ) { if (*chars / 32 != blocki) { bitMapBlockPtr block; blocki = *chars / 32; if( ( block = fentry->fblock[blocki] ) == NULL) { /* * Reset the GE context to a known state before * calling the xf86loadfontblock function. */ WaitQueue(8); outw(MULTIFUNC_CNTL, SCISSORS_T | 0); outw(MULTIFUNC_CNTL, SCISSORS_L | 0); outw(MULTIFUNC_CNTL, SCISSORS_R | 1023); outw(MULTIFUNC_CNTL, SCISSORS_B | 1023); outw(RD_MASK, 0xff); outw(MULTIFUNC_CNTL, PIX_CNTL | MIXSEL_FRGDMIX | COLCMPOP_F); outw(FRGD_MIX, FSS_FRGDCOL | MIX_SRC); outw(BKGD_MIX, BSS_BKGDCOL | MIX_SRC); xf86loadFontBlock(fentry, blocki); block = fentry->fblock[blocki]; /* * Restore the GE context. */ WaitQueue(9); outw(MULTIFUNC_CNTL, SCISSORS_L | (short)pBox->x1); outw(MULTIFUNC_CNTL, SCISSORS_T | (short)pBox->y1); outw(MULTIFUNC_CNTL, SCISSORS_R | (short)(pBox->x2 - 1)); outw(MULTIFUNC_CNTL, SCISSORS_B | (short)(pBox->y2 - 1)); outw(FRGD_COLOR, (short)pGC->fgPixel); outw(MULTIFUNC_CNTL, PIX_CNTL | MIXSEL_EXPBLT | COLCMPOP_F); outw(FRGD_MIX, FSS_FRGDCOL | mach8alu[pGC->alu]); outw(BKGD_MIX, BSS_BKGDCOL | MIX_DST); outw(WRT_MASK, (short)pGC->planemask); height = width = pmsk = 0; /* Invalidate register caches. */ } WaitQueue(2); outw(CUR_Y, block->y); /* * Is the readmask altered ? */ if( mach8cachemaskswapped[block->id] != pmsk ) { pmsk = mach8cachemaskswapped[block->id]; outw(RD_MASK, pmsk); } xoff = block->x; block->lru = NEXT_FONT_AGE; } WaitQueue(6); outw(CUR_X, (short) (xoff + (*chars & 0x1f) * w)); outw(DESTX_DIASTP, (short)(x + pci->metrics.leftSideBearing)); outw(DESTY_AXSTP, (short)(y - pci->metrics.ascent)); /* * Need to update width register ? */ if( (short)(GLYPHWIDTHPIXELS(pci)) != width) { width = (short)(GLYPHWIDTHPIXELS(pci)); outw(MAJ_AXIS_PCNT, width - 1); } /* * How about the height register ? */ if( (short)(gHeight) != height ) { height = (short)(gHeight); outw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | height - 1); } outw(CMD, CMD_BITBLT | INC_X | INC_Y | DRAW | PLANAR | WRTDATA); } x += pci->metrics.characterWidth; } } } /* * Set the hardware scissors to match the clipping rectangles and * call the glyph output routine. */ void mach8GlyphWrite( x, y, count, chars, fentry, pGC, pBox, numRects ) int x, y, count, numRects; unsigned char *chars; CacheFont8Ptr fentry; GCPtr pGC; BoxPtr pBox; { int maxAscent, maxDescent; maxAscent = FONTMAXBOUNDS(pGC->font, ascent); maxDescent = FONTMAXBOUNDS(pGC->font, descent); WaitQueue(5); outw(FRGD_COLOR, (short)pGC->fgPixel); outw(MULTIFUNC_CNTL, PIX_CNTL | MIXSEL_EXPBLT | COLCMPOP_F); outw(FRGD_MIX, FSS_FRGDCOL | mach8alu[pGC->alu]); outw(BKGD_MIX, BSS_BKGDCOL | MIX_DST); outw(WRT_MASK, (short)pGC->planemask); for (; --numRects >= 0; ++pBox) { /* * Skip all boxes that are completely above or below the text string. */ if( pBox->y2 >= y - maxAscent && pBox->y1 <= y + maxDescent ) { WaitQueue(4); outw(MULTIFUNC_CNTL, SCISSORS_L | (short)pBox->x1); outw(MULTIFUNC_CNTL, SCISSORS_T | (short)pBox->y1); outw(MULTIFUNC_CNTL, SCISSORS_R | (short)(pBox->x2 - 1)); outw(MULTIFUNC_CNTL, SCISSORS_B | (short)(pBox->y2 - 1)); Domach8CPolyText8(x, y, count, chars, fentry, pGC, pBox); } } WaitQueue(8); outw(MULTIFUNC_CNTL, SCISSORS_T | 0); outw(MULTIFUNC_CNTL, SCISSORS_L | 0); outw(MULTIFUNC_CNTL, SCISSORS_R | 1023); outw(MULTIFUNC_CNTL, SCISSORS_B | 1023); outw(RD_MASK, 0xff); outw(MULTIFUNC_CNTL, PIX_CNTL | MIXSEL_FRGDMIX | COLCMPOP_F); outw(FRGD_MIX, FSS_FRGDCOL | MIX_SRC); outw(BKGD_MIX, BSS_BKGDCOL | MIX_SRC); }