593 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			593 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
 | 
						|
/********************************************************************
 | 
						|
 | 
						|
   In this file we have GC level replacements for PolyText8/16,
 | 
						|
   ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional) 
 | 
						|
   fonts. The idea is that everything in this file is device independent.
 | 
						|
   The mentioned GCOps are merely wrappers for the 
 | 
						|
   PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
 | 
						|
   functions which calculate the boxes containing arbitrarily clipped 
 | 
						|
   text and passes them to the NonTEGlyphRenderer which will usually 
 | 
						|
   be a lower level XAA function which renders these clipped glyphs using
 | 
						|
   the basic color expansion functions exported by the chipset driver.
 | 
						|
   The NonTEGlyphRenderer itself may optionally be driver supplied to
 | 
						|
   facilitate work-arounds/optimizations at a higher level than usual.
 | 
						|
 | 
						|
   Written by Mark Vojkovich (mvojkovi@ucsd.edu)
 | 
						|
 | 
						|
********************************************************************/
 | 
						|
 | 
						|
#ifdef HAVE_XORG_CONFIG_H
 | 
						|
#include <xorg-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include "misc.h"
 | 
						|
#include "xf86.h"
 | 
						|
#include "xf86_OSproc.h"
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/fonts/font.h>
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "dixfontstr.h"
 | 
						|
#include "xf86str.h"
 | 
						|
#include "xaa.h"
 | 
						|
#include "xaacexp.h"
 | 
						|
#include "xaalocal.h"
 | 
						|
#include "gcstruct.h"
 | 
						|
#include "pixmapstr.h"
 | 
						|
 | 
						|
 | 
						|
static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
 | 
						|
				int xInit, int yInit, FontPtr font,
 | 
						|
				int fg, int bg, unsigned planemask,
 | 
						|
				RegionPtr cclip, int nglyph,
 | 
						|
				unsigned char* gBase, CharInfoPtr *ppci);
 | 
						|
static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
 | 
						|
				int xInit, int yInit, FontPtr font,
 | 
						|
				int fg, int rop, unsigned planemask,
 | 
						|
				RegionPtr cclip, int nglyph,
 | 
						|
				unsigned char* gBase, CharInfoPtr *ppci);
 | 
						|
 | 
						|
/********************************************************************
 | 
						|
 | 
						|
   GC level replacements for PolyText8/16 and ImageText8/16
 | 
						|
   for NonTE fonts when using color expansion.
 | 
						|
 | 
						|
********************************************************************/
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
XAAPolyText8NonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr	pGC,
 | 
						|
    int		x, 
 | 
						|
    int 	y,
 | 
						|
    int 	count,
 | 
						|
    char	*chars )
 | 
						|
{
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
    unsigned long n;
 | 
						|
    int width = 0;
 | 
						|
 | 
						|
    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
 | 
						|
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
 | 
						|
 | 
						|
    if(n) {
 | 
						|
	width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 
 | 
						|
		x + pDraw->x, y + pDraw->y, pGC->font, 
 | 
						|
		pGC->fgPixel, pGC->alu, pGC->planemask, 
 | 
						|
		pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
 | 
						|
 		infoRec->CharInfo);
 | 
						|
    }
 | 
						|
 | 
						|
    return (x + width);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
XAAPolyText16NonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr	pGC,
 | 
						|
    int		x, 
 | 
						|
    int		y,
 | 
						|
    int		count,
 | 
						|
    unsigned short *chars )
 | 
						|
{
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
    unsigned long n;
 | 
						|
    int width = 0;
 | 
						|
 | 
						|
    (*pGC->font->get_glyphs)(
 | 
						|
		pGC->font, (unsigned long)count, (unsigned char *)chars,
 | 
						|
		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
 | 
						|
		&n, infoRec->CharInfo);
 | 
						|
 | 
						|
    if(n) {
 | 
						|
	width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 
 | 
						|
		x + pDraw->x, y + pDraw->y, pGC->font, 
 | 
						|
		pGC->fgPixel, pGC->alu, pGC->planemask, 
 | 
						|
		pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
 | 
						|
		infoRec->CharInfo);
 | 
						|
    }
 | 
						|
 | 
						|
    return (x + width);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
XAAImageText8NonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr	pGC,
 | 
						|
    int		x, 
 | 
						|
    int		y,
 | 
						|
    int		count,
 | 
						|
    char	*chars 
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
    unsigned long n;
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
 | 
						|
	return;
 | 
						|
 | 
						|
    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
 | 
						|
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
 | 
						|
 | 
						|
    if(n) ImageGlyphBltNonTEColorExpansion(
 | 
						|
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
 | 
						|
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
 | 
						|
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
XAAImageText16NonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr	pGC,
 | 
						|
    int		x, 
 | 
						|
    int		y,
 | 
						|
    int		count,
 | 
						|
    unsigned short *chars 
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
    unsigned long n;
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
 | 
						|
	return;
 | 
						|
 | 
						|
    (*pGC->font->get_glyphs)(
 | 
						|
		pGC->font, (unsigned long)count, (unsigned char *)chars,
 | 
						|
		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
 | 
						|
		&n, infoRec->CharInfo);
 | 
						|
 | 
						|
    if(n) ImageGlyphBltNonTEColorExpansion(
 | 
						|
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
 | 
						|
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
 | 
						|
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/********************************************************************
 | 
						|
 | 
						|
   GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
 | 
						|
   NonTE fonts when using color expansion.
 | 
						|
 | 
						|
********************************************************************/
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
XAAImageGlyphBltNonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr pGC,
 | 
						|
    int xInit, int yInit,
 | 
						|
    unsigned int nglyph,
 | 
						|
    CharInfoPtr *ppci,      /* array of character info */
 | 
						|
    pointer pglyphBase	       /* start of array of glyphs */
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
 | 
						|
	return;
 | 
						|
 | 
						|
    ImageGlyphBltNonTEColorExpansion(
 | 
						|
	infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
 | 
						|
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
 | 
						|
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XAAPolyGlyphBltNonTEColorExpansion(
 | 
						|
    DrawablePtr pDraw,
 | 
						|
    GCPtr pGC,
 | 
						|
    int xInit, int yInit,
 | 
						|
    unsigned int nglyph,
 | 
						|
    CharInfoPtr *ppci,      /* array of character info */
 | 
						|
    pointer pglyphBase	       /* start of array of glyphs */
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
 | 
						|
	return;
 | 
						|
 | 
						|
    PolyGlyphBltNonTEColorExpansion(
 | 
						|
	infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
 | 
						|
	pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask, 
 | 
						|
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/********************************************************************
 | 
						|
 | 
						|
   ImageGlyphBltNonTEColorExpansion -
 | 
						|
   PolyGlyphBltNonTEColorExpansion -
 | 
						|
 | 
						|
   These guys compute the clipped pieces of text and send it to
 | 
						|
   the lower-level function which will handle acceleration of 
 | 
						|
   arbitrarily clipped text.
 | 
						|
  
 | 
						|
********************************************************************/
 | 
						|
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
CollectCharacterInfo(
 | 
						|
    NonTEGlyphPtr glyphs,
 | 
						|
    unsigned int nglyph,
 | 
						|
    CharInfoPtr *ppci,
 | 
						|
    FontPtr pfont
 | 
						|
){
 | 
						|
   int i, w = 0;
 | 
						|
   
 | 
						|
   for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
 | 
						|
	glyphs->bits = (unsigned char*)((*ppci)->bits);
 | 
						|
	glyphs->start = w + (*ppci)->metrics.leftSideBearing;
 | 
						|
	glyphs->end = w + (*ppci)->metrics.rightSideBearing;
 | 
						|
	glyphs->yoff = (*ppci)->metrics.ascent;
 | 
						|
	glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
 | 
						|
	glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
 | 
						|
	w += (*ppci)->metrics.characterWidth;
 | 
						|
   }
 | 
						|
   return w;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
PolyGlyphBltAsSingleBitmap (
 | 
						|
   ScrnInfoPtr pScrn,
 | 
						|
   int nglyph,
 | 
						|
   FontPtr font,
 | 
						|
   int xInit,
 | 
						|
   int yInit,
 | 
						|
   int nbox,
 | 
						|
   BoxPtr pbox,
 | 
						|
   int fg,
 | 
						|
   int rop,
 | 
						|
   unsigned planemask
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 | 
						|
    CARD32 *block, *pntr, *bits;
 | 
						|
    int pitch, topLine, botLine, top, bot, height;
 | 
						|
    int Left, Right, Top, Bottom;
 | 
						|
    int LeftEdge, RightEdge;
 | 
						|
    int bitPitch, shift, size, i, skippix;
 | 
						|
    NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
 | 
						|
    Bool extra;
 | 
						|
	
 | 
						|
    Left = xInit + infoRec->GlyphInfo[0].start;
 | 
						|
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
 | 
						|
    Top = yInit - FONTMAXBOUNDS(font,ascent);
 | 
						|
    Bottom = yInit + FONTMAXBOUNDS(font,descent);
 | 
						|
 | 
						|
    /* get into the first band that may contain part of our string */
 | 
						|
    while(nbox && (Top >= pbox->y2)) {
 | 
						|
	pbox++; nbox--;
 | 
						|
    }
 | 
						|
 | 
						|
    if(!nbox) return;
 | 
						|
 | 
						|
    pitch = (Right - Left + 31) >> 5;
 | 
						|
    size = (pitch << 2) * (Bottom - Top);
 | 
						|
    block = (CARD32*)ALLOCATE_LOCAL(size);
 | 
						|
    bzero(block, size);
 | 
						|
 | 
						|
    topLine = 10000; botLine = -10000;
 | 
						|
 | 
						|
    while(nglyph--) {
 | 
						|
	top = -glyphs->yoff;
 | 
						|
	bot = top + glyphs->height;
 | 
						|
	if(top < topLine) topLine = top;
 | 
						|
	if(bot > botLine) botLine = bot;
 | 
						|
	skippix = glyphs->start - infoRec->GlyphInfo[0].start;
 | 
						|
	bits = (CARD32*)glyphs->bits;
 | 
						|
	bitPitch = glyphs->srcwidth >> 2;
 | 
						|
	pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
 | 
						|
				(skippix >> 5);
 | 
						|
	shift = skippix & 31;
 | 
						|
	extra = ((shift + glyphs->end - glyphs->start) > 32);
 | 
						|
 | 
						|
	for(i = top; i < bot; i++) {
 | 
						|
	    *pntr |= SHIFT_L(*bits, shift);
 | 
						|
	    if(extra)
 | 
						|
		*(pntr + 1) |= SHIFT_R(*bits,32 - shift);
 | 
						|
	    pntr += pitch;
 | 
						|
	    bits += bitPitch;
 | 
						|
	}
 | 
						|
 | 
						|
	glyphs++;
 | 
						|
    }
 | 
						|
 | 
						|
    pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);
 | 
						|
 | 
						|
    Top = yInit + topLine;
 | 
						|
    Bottom = yInit + botLine;
 | 
						|
 | 
						|
    while(nbox && (Top >= pbox->y2)) {
 | 
						|
	pbox++; nbox--;
 | 
						|
    }
 | 
						|
 | 
						|
    while(nbox && (Bottom > pbox->y1)) {
 | 
						|
	LeftEdge = max(Left, pbox->x1);
 | 
						|
	RightEdge = min(Right, pbox->x2);
 | 
						|
 | 
						|
	if(RightEdge > LeftEdge) {
 | 
						|
	    skippix = LeftEdge - Left;
 | 
						|
	    topLine = max(Top, pbox->y1);
 | 
						|
	    botLine = min(Bottom, pbox->y2);	
 | 
						|
	    height = botLine - topLine;
 | 
						|
 | 
						|
	    if(height > 0) 
 | 
						|
	       (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine, 
 | 
						|
			RightEdge - LeftEdge, height,
 | 
						|
			(unsigned char*)(pntr + ((topLine - Top) * pitch) +
 | 
						|
				(skippix >> 5)),
 | 
						|
			pitch << 2, skippix & 31, fg, -1, rop, planemask);
 | 
						|
	}
 | 
						|
 | 
						|
	nbox--; pbox++;
 | 
						|
    }
 | 
						|
 | 
						|
    DEALLOCATE_LOCAL(block);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ImageGlyphBltNonTEColorExpansion(
 | 
						|
   ScrnInfoPtr pScrn,
 | 
						|
   int xInit, int yInit,
 | 
						|
   FontPtr font,
 | 
						|
   int fg, int bg,
 | 
						|
   unsigned planemask,
 | 
						|
   RegionPtr cclip,
 | 
						|
   int nglyph,
 | 
						|
   unsigned char* gBase,
 | 
						|
   CharInfoPtr *ppci 
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 | 
						|
    int skippix, skipglyph, width, n, i;
 | 
						|
    int Left, Right, Top, Bottom;
 | 
						|
    int LeftEdge, RightEdge, ytop, ybot;
 | 
						|
    int nbox = REGION_NUM_RECTS(cclip);
 | 
						|
    BoxPtr pbox = REGION_RECTS(cclip);
 | 
						|
    Bool AlreadySetup = FALSE;
 | 
						|
 | 
						|
    width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
 | 
						|
 | 
						|
    /* find our backing rectangle dimensions */
 | 
						|
    Left = xInit;
 | 
						|
    Right = Left + width;
 | 
						|
    Top = yInit - FONTASCENT(font);
 | 
						|
    Bottom = yInit + FONTDESCENT(font);
 | 
						|
 | 
						|
    /* get into the first band that may contain part of our box */
 | 
						|
    while(nbox && (Top >= pbox->y2)) {
 | 
						|
	pbox++; nbox--;
 | 
						|
    }
 | 
						|
 | 
						|
    while(nbox && (Bottom >= pbox->y1)) {
 | 
						|
	/* handle backing rect first */
 | 
						|
	LeftEdge = max(Left, pbox->x1);
 | 
						|
	RightEdge = min(Right, pbox->x2);
 | 
						|
	if(RightEdge > LeftEdge) {	    
 | 
						|
	    ytop = max(Top, pbox->y1);
 | 
						|
	    ybot = min(Bottom, pbox->y2);
 | 
						|
 | 
						|
	    if(ybot > ytop) {
 | 
						|
		if(!AlreadySetup) {
 | 
						|
		   (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
 | 
						|
		   AlreadySetup = TRUE;
 | 
						|
		}
 | 
						|
		(*infoRec->SubsequentSolidFillRect)(pScrn, 
 | 
						|
			LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	nbox--; pbox++;
 | 
						|
    }
 | 
						|
 
 | 
						|
    nbox = REGION_NUM_RECTS(cclip);
 | 
						|
    pbox = REGION_RECTS(cclip);
 | 
						|
 | 
						|
    if(infoRec->WriteBitmap && (nglyph > 1) && 
 | 
						|
			((FONTMAXBOUNDS(font, rightSideBearing) - 
 | 
						|
          		FONTMINBOUNDS(font, leftSideBearing)) <= 32)) 
 | 
						|
   {
 | 
						|
	PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 
 | 
						|
				xInit, yInit, nbox, pbox,
 | 
						|
				fg, GXcopy, planemask);
 | 
						|
 | 
						|
	return;
 | 
						|
    }
 | 
						|
 | 
						|
    /* compute an approximate but covering bounding box */
 | 
						|
    Left = xInit + infoRec->GlyphInfo[0].start;
 | 
						|
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
 | 
						|
    Top = yInit - FONTMAXBOUNDS(font,ascent);
 | 
						|
    Bottom = yInit + FONTMAXBOUNDS(font,descent);
 | 
						|
 | 
						|
    /* get into the first band that may contain part of our box */
 | 
						|
    while(nbox && (Top >= pbox->y2)) {
 | 
						|
	pbox++; nbox--;
 | 
						|
    }
 | 
						|
 | 
						|
    /* stop when the lower edge of the box is beyond our string */
 | 
						|
    while(nbox && (Bottom >= pbox->y1)) {
 | 
						|
	LeftEdge = max(Left, pbox->x1);
 | 
						|
	RightEdge = min(Right, pbox->x2);
 | 
						|
 | 
						|
	if(RightEdge > LeftEdge) { /* we're possibly drawing something */
 | 
						|
	    ytop = max(Top, pbox->y1);
 | 
						|
	    ybot = min(Bottom, pbox->y2);
 | 
						|
	    if(ybot > ytop) {
 | 
						|
		skippix = LeftEdge - xInit;
 | 
						|
		skipglyph = 0;
 | 
						|
		while(skippix >= infoRec->GlyphInfo[skipglyph].end)
 | 
						|
		   skipglyph++;
 | 
						|
 | 
						|
		skippix = RightEdge - xInit;
 | 
						|
		n = 0; i = skipglyph;
 | 
						|
		while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
 | 
						|
		    i++; n++;
 | 
						|
		}
 | 
						|
 | 
						|
		if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
 | 
						|
			xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 
 | 
						|
			pbox, fg, GXcopy, planemask); 
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	nbox--; pbox++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
PolyGlyphBltNonTEColorExpansion(
 | 
						|
   ScrnInfoPtr pScrn,
 | 
						|
   int xInit, int yInit,
 | 
						|
   FontPtr font,
 | 
						|
   int fg, int rop,
 | 
						|
   unsigned planemask,
 | 
						|
   RegionPtr cclip,
 | 
						|
   int nglyph,
 | 
						|
   unsigned char* gBase,
 | 
						|
   CharInfoPtr *ppci 
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 | 
						|
    int skippix, skipglyph, width, n, i;
 | 
						|
    int Left, Right, Top, Bottom;
 | 
						|
    int LeftEdge, RightEdge;
 | 
						|
    int nbox = REGION_NUM_RECTS(cclip);
 | 
						|
    BoxPtr pbox = REGION_RECTS(cclip);
 | 
						|
 | 
						|
    width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
 | 
						|
 | 
						|
    if(!nbox)
 | 
						|
	return width;
 | 
						|
 | 
						|
    if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) &&
 | 
						|
	((FONTMAXBOUNDS(font, rightSideBearing) - 
 | 
						|
          FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
 | 
						|
 | 
						|
	 PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 
 | 
						|
				xInit, yInit, nbox, pbox,
 | 
						|
				fg, rop, planemask);
 | 
						|
 | 
						|
	return width;
 | 
						|
    }
 | 
						|
 | 
						|
    /* compute an approximate but covering bounding box */
 | 
						|
    Left = xInit + infoRec->GlyphInfo[0].start;
 | 
						|
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
 | 
						|
    Top = yInit - FONTMAXBOUNDS(font,ascent);
 | 
						|
    Bottom = yInit + FONTMAXBOUNDS(font,descent);
 | 
						|
 | 
						|
    /* get into the first band that may contain part of our string */
 | 
						|
    while(nbox && (Top >= pbox->y2)) {
 | 
						|
	pbox++; nbox--;
 | 
						|
    }
 | 
						|
 | 
						|
    /* stop when the lower edge of the box is beyond our string */
 | 
						|
    while(nbox && (Bottom >= pbox->y1)) {
 | 
						|
	LeftEdge = max(Left, pbox->x1);
 | 
						|
	RightEdge = min(Right, pbox->x2);
 | 
						|
 | 
						|
	if(RightEdge > LeftEdge) { /* we're possibly drawing something */
 | 
						|
 | 
						|
	    skippix = LeftEdge - xInit;
 | 
						|
	    skipglyph = 0;
 | 
						|
	    while(skippix >= infoRec->GlyphInfo[skipglyph].end)
 | 
						|
		skipglyph++;
 | 
						|
 | 
						|
	    skippix = RightEdge - xInit;
 | 
						|
	    n = 0; i = skipglyph;
 | 
						|
	    while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
 | 
						|
		i++; n++;
 | 
						|
	    }
 | 
						|
 | 
						|
	    if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
 | 
						|
			xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 
 | 
						|
			pbox, fg, rop, planemask); 
 | 
						|
	}
 | 
						|
 | 
						|
	nbox--; pbox++;
 | 
						|
    }
 | 
						|
    return width;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* It is possible that the none of the glyphs passed to the 
 | 
						|
   NonTEGlyphRenderer will be drawn.  This function being called
 | 
						|
   indicates that part of the text string's bounding box is visible
 | 
						|
   but not necessarily that any of the characters are visible */
 | 
						|
 | 
						|
void XAANonTEGlyphRenderer(
 | 
						|
   ScrnInfoPtr pScrn,
 | 
						|
   int x, int y, int n,
 | 
						|
   NonTEGlyphPtr glyphs,
 | 
						|
   BoxPtr pbox,
 | 
						|
   int fg, int rop,
 | 
						|
   unsigned int planemask
 | 
						|
){
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 | 
						|
    int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
 | 
						|
    unsigned char *src;
 | 
						|
 | 
						|
    for(i = 0; i < n; i++, glyphs++) {
 | 
						|
	x1 = x + glyphs->start;
 | 
						|
	x2 = x + glyphs->end;
 | 
						|
	y1 = y - glyphs->yoff;
 | 
						|
	y2 = y1 + glyphs->height;
 | 
						|
 | 
						|
	if(y1 < pbox->y1) {
 | 
						|
	    skiptop = pbox->y1 - y1;
 | 
						|
	    y1 = pbox->y1;
 | 
						|
	} else skiptop = 0;
 | 
						|
	if(y2 > pbox->y2) y2 = pbox->y2;
 | 
						|
	h = y2 - y1;
 | 
						|
	if(h <= 0) continue;
 | 
						|
 | 
						|
	if(x1 < pbox->x1) {
 | 
						|
	    skipleft = pbox->x1 - x1;
 | 
						|
	    x1 = pbox->x1;
 | 
						|
	} else skipleft = 0;
 | 
						|
	if(x2 > pbox->x2) x2 = pbox->x2;
 | 
						|
 | 
						|
	w = x2 - x1;
 | 
						|
 | 
						|
	if(w > 0) {
 | 
						|
	    src = glyphs->bits + (skiptop * glyphs->srcwidth);
 | 
						|
 | 
						|
	    if(skipleft) {
 | 
						|
		src += (skipleft >> 5) << 2;
 | 
						|
		skipleft &= 31;
 | 
						|
	    }
 | 
						|
 | 
						|
	    (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
 | 
						|
			glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
 | 
						|
	}
 | 
						|
    }  
 | 
						|
 | 
						|
}
 |