1706f2543Smrg 2706f2543Smrg/******************************************************************** 3706f2543Smrg 4706f2543Smrg In this file we have GC level replacements for PolyText8/16, 5706f2543Smrg ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional) 6706f2543Smrg fonts. The idea is that everything in this file is device independent. 7706f2543Smrg The mentioned GCOps are merely wrappers for the 8706f2543Smrg PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion 9706f2543Smrg functions which calculate the boxes containing arbitrarily clipped 10706f2543Smrg text and passes them to the NonTEGlyphRenderer which will usually 11706f2543Smrg be a lower level XAA function which renders these clipped glyphs using 12706f2543Smrg the basic color expansion functions exported by the chipset driver. 13706f2543Smrg The NonTEGlyphRenderer itself may optionally be driver supplied to 14706f2543Smrg facilitate work-arounds/optimizations at a higher level than usual. 15706f2543Smrg 16706f2543Smrg Written by Mark Vojkovich (mvojkovi@ucsd.edu) 17706f2543Smrg 18706f2543Smrg********************************************************************/ 19706f2543Smrg 20706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 21706f2543Smrg#include <xorg-config.h> 22706f2543Smrg#endif 23706f2543Smrg 24706f2543Smrg#include <string.h> 25706f2543Smrg 26706f2543Smrg#include "misc.h" 27706f2543Smrg#include "xf86.h" 28706f2543Smrg#include "xf86_OSproc.h" 29706f2543Smrg 30706f2543Smrg#include <X11/X.h> 31706f2543Smrg#include <X11/fonts/font.h> 32706f2543Smrg#include "scrnintstr.h" 33706f2543Smrg#include "dixfontstr.h" 34706f2543Smrg#include "xf86str.h" 35706f2543Smrg#include "xaa.h" 36706f2543Smrg#include "xaacexp.h" 37706f2543Smrg#include "xaalocal.h" 38706f2543Smrg#include "gcstruct.h" 39706f2543Smrg#include "pixmapstr.h" 40706f2543Smrg 41706f2543Smrg 42706f2543Smrgstatic void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn, 43706f2543Smrg int xInit, int yInit, FontPtr font, 44706f2543Smrg int fg, int bg, unsigned planemask, 45706f2543Smrg RegionPtr cclip, int nglyph, 46706f2543Smrg unsigned char* gBase, CharInfoPtr *ppci); 47706f2543Smrgstatic int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn, 48706f2543Smrg int xInit, int yInit, FontPtr font, 49706f2543Smrg int fg, int rop, unsigned planemask, 50706f2543Smrg RegionPtr cclip, int nglyph, 51706f2543Smrg unsigned char* gBase, CharInfoPtr *ppci); 52706f2543Smrg 53706f2543Smrg/******************************************************************** 54706f2543Smrg 55706f2543Smrg GC level replacements for PolyText8/16 and ImageText8/16 56706f2543Smrg for NonTE fonts when using color expansion. 57706f2543Smrg 58706f2543Smrg********************************************************************/ 59706f2543Smrg 60706f2543Smrg 61706f2543Smrgint 62706f2543SmrgXAAPolyText8NonTEColorExpansion( 63706f2543Smrg DrawablePtr pDraw, 64706f2543Smrg GCPtr pGC, 65706f2543Smrg int x, 66706f2543Smrg int y, 67706f2543Smrg int count, 68706f2543Smrg char *chars ) 69706f2543Smrg{ 70706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 71706f2543Smrg unsigned long n; 72706f2543Smrg int width = 0; 73706f2543Smrg 74706f2543Smrg (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 75706f2543Smrg (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo); 76706f2543Smrg 77706f2543Smrg if(n) { 78706f2543Smrg width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 79706f2543Smrg x + pDraw->x, y + pDraw->y, pGC->font, 80706f2543Smrg pGC->fgPixel, pGC->alu, pGC->planemask, 81706f2543Smrg pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), 82706f2543Smrg infoRec->CharInfo); 83706f2543Smrg } 84706f2543Smrg 85706f2543Smrg return x + width; 86706f2543Smrg} 87706f2543Smrg 88706f2543Smrg 89706f2543Smrgint 90706f2543SmrgXAAPolyText16NonTEColorExpansion( 91706f2543Smrg DrawablePtr pDraw, 92706f2543Smrg GCPtr pGC, 93706f2543Smrg int x, 94706f2543Smrg int y, 95706f2543Smrg int count, 96706f2543Smrg unsigned short *chars ) 97706f2543Smrg{ 98706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 99706f2543Smrg unsigned long n; 100706f2543Smrg int width = 0; 101706f2543Smrg 102706f2543Smrg (*pGC->font->get_glyphs)( 103706f2543Smrg pGC->font, (unsigned long)count, (unsigned char *)chars, 104706f2543Smrg (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, 105706f2543Smrg &n, infoRec->CharInfo); 106706f2543Smrg 107706f2543Smrg if(n) { 108706f2543Smrg width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 109706f2543Smrg x + pDraw->x, y + pDraw->y, pGC->font, 110706f2543Smrg pGC->fgPixel, pGC->alu, pGC->planemask, 111706f2543Smrg pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), 112706f2543Smrg infoRec->CharInfo); 113706f2543Smrg } 114706f2543Smrg 115706f2543Smrg return x + width; 116706f2543Smrg} 117706f2543Smrg 118706f2543Smrg 119706f2543Smrgvoid 120706f2543SmrgXAAImageText8NonTEColorExpansion( 121706f2543Smrg DrawablePtr pDraw, 122706f2543Smrg GCPtr pGC, 123706f2543Smrg int x, 124706f2543Smrg int y, 125706f2543Smrg int count, 126706f2543Smrg char *chars 127706f2543Smrg){ 128706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 129706f2543Smrg unsigned long n; 130706f2543Smrg 131706f2543Smrg if(!RegionNumRects(pGC->pCompositeClip)) 132706f2543Smrg return; 133706f2543Smrg 134706f2543Smrg (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 135706f2543Smrg (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo); 136706f2543Smrg 137706f2543Smrg if(n) ImageGlyphBltNonTEColorExpansion( 138706f2543Smrg infoRec->pScrn, x + pDraw->x, y + pDraw->y, 139706f2543Smrg pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 140706f2543Smrg pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo); 141706f2543Smrg} 142706f2543Smrg 143706f2543Smrg 144706f2543Smrgvoid 145706f2543SmrgXAAImageText16NonTEColorExpansion( 146706f2543Smrg DrawablePtr pDraw, 147706f2543Smrg GCPtr pGC, 148706f2543Smrg int x, 149706f2543Smrg int y, 150706f2543Smrg int count, 151706f2543Smrg unsigned short *chars 152706f2543Smrg){ 153706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 154706f2543Smrg unsigned long n; 155706f2543Smrg 156706f2543Smrg if(!RegionNumRects(pGC->pCompositeClip)) 157706f2543Smrg return; 158706f2543Smrg 159706f2543Smrg (*pGC->font->get_glyphs)( 160706f2543Smrg pGC->font, (unsigned long)count, (unsigned char *)chars, 161706f2543Smrg (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, 162706f2543Smrg &n, infoRec->CharInfo); 163706f2543Smrg 164706f2543Smrg if(n) ImageGlyphBltNonTEColorExpansion( 165706f2543Smrg infoRec->pScrn, x + pDraw->x, y + pDraw->y, 166706f2543Smrg pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 167706f2543Smrg pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo); 168706f2543Smrg} 169706f2543Smrg 170706f2543Smrg 171706f2543Smrg 172706f2543Smrg/******************************************************************** 173706f2543Smrg 174706f2543Smrg GC level replacements for ImageGlyphBlt and PolyGlyphBlt for 175706f2543Smrg NonTE fonts when using color expansion. 176706f2543Smrg 177706f2543Smrg********************************************************************/ 178706f2543Smrg 179706f2543Smrg 180706f2543Smrgvoid 181706f2543SmrgXAAImageGlyphBltNonTEColorExpansion( 182706f2543Smrg DrawablePtr pDraw, 183706f2543Smrg GCPtr pGC, 184706f2543Smrg int xInit, int yInit, 185706f2543Smrg unsigned int nglyph, 186706f2543Smrg CharInfoPtr *ppci, /* array of character info */ 187706f2543Smrg pointer pglyphBase /* start of array of glyphs */ 188706f2543Smrg){ 189706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 190706f2543Smrg 191706f2543Smrg if(!RegionNumRects(pGC->pCompositeClip)) 192706f2543Smrg return; 193706f2543Smrg 194706f2543Smrg ImageGlyphBltNonTEColorExpansion( 195706f2543Smrg infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y, 196706f2543Smrg pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 197706f2543Smrg pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci); 198706f2543Smrg} 199706f2543Smrg 200706f2543Smrgvoid 201706f2543SmrgXAAPolyGlyphBltNonTEColorExpansion( 202706f2543Smrg DrawablePtr pDraw, 203706f2543Smrg GCPtr pGC, 204706f2543Smrg int xInit, int yInit, 205706f2543Smrg unsigned int nglyph, 206706f2543Smrg CharInfoPtr *ppci, /* array of character info */ 207706f2543Smrg pointer pglyphBase /* start of array of glyphs */ 208706f2543Smrg){ 209706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 210706f2543Smrg 211706f2543Smrg if(!RegionNumRects(pGC->pCompositeClip)) 212706f2543Smrg return; 213706f2543Smrg 214706f2543Smrg PolyGlyphBltNonTEColorExpansion( 215706f2543Smrg infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y, 216706f2543Smrg pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask, 217706f2543Smrg pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci); 218706f2543Smrg} 219706f2543Smrg 220706f2543Smrg 221706f2543Smrg 222706f2543Smrg 223706f2543Smrg/******************************************************************** 224706f2543Smrg 225706f2543Smrg ImageGlyphBltNonTEColorExpansion - 226706f2543Smrg PolyGlyphBltNonTEColorExpansion - 227706f2543Smrg 228706f2543Smrg These guys compute the clipped pieces of text and send it to 229706f2543Smrg the lower-level function which will handle acceleration of 230706f2543Smrg arbitrarily clipped text. 231706f2543Smrg 232706f2543Smrg********************************************************************/ 233706f2543Smrg 234706f2543Smrg 235706f2543Smrg 236706f2543Smrgstatic int 237706f2543SmrgCollectCharacterInfo( 238706f2543Smrg NonTEGlyphPtr glyphs, 239706f2543Smrg unsigned int nglyph, 240706f2543Smrg CharInfoPtr *ppci, 241706f2543Smrg FontPtr pfont 242706f2543Smrg){ 243706f2543Smrg int i, w = 0; 244706f2543Smrg 245706f2543Smrg for(i = 0; i < nglyph; i++, ppci++, glyphs++) { 246706f2543Smrg glyphs->bits = (unsigned char*)((*ppci)->bits); 247706f2543Smrg glyphs->start = w + (*ppci)->metrics.leftSideBearing; 248706f2543Smrg glyphs->end = w + (*ppci)->metrics.rightSideBearing; 249706f2543Smrg glyphs->yoff = (*ppci)->metrics.ascent; 250706f2543Smrg glyphs->height = glyphs->yoff + (*ppci)->metrics.descent; 251706f2543Smrg glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start); 252706f2543Smrg w += (*ppci)->metrics.characterWidth; 253706f2543Smrg } 254706f2543Smrg return w; 255706f2543Smrg} 256706f2543Smrg 257706f2543Smrg 258706f2543Smrgstatic void 259706f2543SmrgPolyGlyphBltAsSingleBitmap ( 260706f2543Smrg ScrnInfoPtr pScrn, 261706f2543Smrg int nglyph, 262706f2543Smrg FontPtr font, 263706f2543Smrg int xInit, 264706f2543Smrg int yInit, 265706f2543Smrg int nbox, 266706f2543Smrg BoxPtr pbox, 267706f2543Smrg int fg, 268706f2543Smrg int rop, 269706f2543Smrg unsigned planemask 270706f2543Smrg){ 271706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 272706f2543Smrg CARD32 *block, *pntr, *bits; 273706f2543Smrg int pitch, topLine, botLine, top, bot, height; 274706f2543Smrg int Left, Right, Top, Bottom; 275706f2543Smrg int LeftEdge, RightEdge; 276706f2543Smrg int bitPitch, shift, size, i, skippix; 277706f2543Smrg NonTEGlyphPtr glyphs = infoRec->GlyphInfo; 278706f2543Smrg Bool extra; 279706f2543Smrg 280706f2543Smrg Left = xInit + infoRec->GlyphInfo[0].start; 281706f2543Smrg Right = xInit + infoRec->GlyphInfo[nglyph - 1].end; 282706f2543Smrg Top = yInit - FONTMAXBOUNDS(font,ascent); 283706f2543Smrg Bottom = yInit + FONTMAXBOUNDS(font,descent); 284706f2543Smrg 285706f2543Smrg /* get into the first band that may contain part of our string */ 286706f2543Smrg while(nbox && (Top >= pbox->y2)) { 287706f2543Smrg pbox++; nbox--; 288706f2543Smrg } 289706f2543Smrg 290706f2543Smrg if(!nbox) return; 291706f2543Smrg 292706f2543Smrg pitch = (Right - Left + 31) >> 5; 293706f2543Smrg size = (pitch << 2) * (Bottom - Top); 294706f2543Smrg block = calloc(1, size); 295706f2543Smrg 296706f2543Smrg topLine = 10000; botLine = -10000; 297706f2543Smrg 298706f2543Smrg while(nglyph--) { 299706f2543Smrg top = -glyphs->yoff; 300706f2543Smrg bot = top + glyphs->height; 301706f2543Smrg if(top < topLine) topLine = top; 302706f2543Smrg if(bot > botLine) botLine = bot; 303706f2543Smrg skippix = glyphs->start - infoRec->GlyphInfo[0].start; 304706f2543Smrg bits = (CARD32*)glyphs->bits; 305706f2543Smrg bitPitch = glyphs->srcwidth >> 2; 306706f2543Smrg pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) + 307706f2543Smrg (skippix >> 5); 308706f2543Smrg shift = skippix & 31; 309706f2543Smrg extra = ((shift + glyphs->end - glyphs->start) > 32); 310706f2543Smrg 311706f2543Smrg for(i = top; i < bot; i++) { 312706f2543Smrg *pntr |= SHIFT_L(*bits, shift); 313706f2543Smrg if(extra) 314706f2543Smrg *(pntr + 1) |= SHIFT_R(*bits,32 - shift); 315706f2543Smrg pntr += pitch; 316706f2543Smrg bits += bitPitch; 317706f2543Smrg } 318706f2543Smrg 319706f2543Smrg glyphs++; 320706f2543Smrg } 321706f2543Smrg 322706f2543Smrg pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch); 323706f2543Smrg 324706f2543Smrg Top = yInit + topLine; 325706f2543Smrg Bottom = yInit + botLine; 326706f2543Smrg 327706f2543Smrg while(nbox && (Top >= pbox->y2)) { 328706f2543Smrg pbox++; nbox--; 329706f2543Smrg } 330706f2543Smrg 331706f2543Smrg while(nbox && (Bottom > pbox->y1)) { 332706f2543Smrg LeftEdge = max(Left, pbox->x1); 333706f2543Smrg RightEdge = min(Right, pbox->x2); 334706f2543Smrg 335706f2543Smrg if(RightEdge > LeftEdge) { 336706f2543Smrg skippix = LeftEdge - Left; 337706f2543Smrg topLine = max(Top, pbox->y1); 338706f2543Smrg botLine = min(Bottom, pbox->y2); 339706f2543Smrg height = botLine - topLine; 340706f2543Smrg 341706f2543Smrg if(height > 0) 342706f2543Smrg (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine, 343706f2543Smrg RightEdge - LeftEdge, height, 344706f2543Smrg (unsigned char*)(pntr + ((topLine - Top) * pitch) + 345706f2543Smrg (skippix >> 5)), 346706f2543Smrg pitch << 2, skippix & 31, fg, -1, rop, planemask); 347706f2543Smrg } 348706f2543Smrg 349706f2543Smrg nbox--; pbox++; 350706f2543Smrg } 351706f2543Smrg 352706f2543Smrg free(block); 353706f2543Smrg} 354706f2543Smrg 355706f2543Smrgstatic void 356706f2543SmrgImageGlyphBltNonTEColorExpansion( 357706f2543Smrg ScrnInfoPtr pScrn, 358706f2543Smrg int xInit, int yInit, 359706f2543Smrg FontPtr font, 360706f2543Smrg int fg, int bg, 361706f2543Smrg unsigned planemask, 362706f2543Smrg RegionPtr cclip, 363706f2543Smrg int nglyph, 364706f2543Smrg unsigned char* gBase, 365706f2543Smrg CharInfoPtr *ppci 366706f2543Smrg){ 367706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 368706f2543Smrg int skippix, skipglyph, width, n, i; 369706f2543Smrg int Left, Right, Top, Bottom; 370706f2543Smrg int LeftEdge, RightEdge, ytop, ybot; 371706f2543Smrg int nbox = RegionNumRects(cclip); 372706f2543Smrg BoxPtr pbox = RegionRects(cclip); 373706f2543Smrg Bool AlreadySetup = FALSE; 374706f2543Smrg 375706f2543Smrg width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font); 376706f2543Smrg 377706f2543Smrg /* find our backing rectangle dimensions */ 378706f2543Smrg Left = xInit; 379706f2543Smrg Right = Left + width; 380706f2543Smrg Top = yInit - FONTASCENT(font); 381706f2543Smrg Bottom = yInit + FONTDESCENT(font); 382706f2543Smrg 383706f2543Smrg /* get into the first band that may contain part of our box */ 384706f2543Smrg while(nbox && (Top >= pbox->y2)) { 385706f2543Smrg pbox++; nbox--; 386706f2543Smrg } 387706f2543Smrg 388706f2543Smrg while(nbox && (Bottom >= pbox->y1)) { 389706f2543Smrg /* handle backing rect first */ 390706f2543Smrg LeftEdge = max(Left, pbox->x1); 391706f2543Smrg RightEdge = min(Right, pbox->x2); 392706f2543Smrg if(RightEdge > LeftEdge) { 393706f2543Smrg ytop = max(Top, pbox->y1); 394706f2543Smrg ybot = min(Bottom, pbox->y2); 395706f2543Smrg 396706f2543Smrg if(ybot > ytop) { 397706f2543Smrg if(!AlreadySetup) { 398706f2543Smrg (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask); 399706f2543Smrg AlreadySetup = TRUE; 400706f2543Smrg } 401706f2543Smrg (*infoRec->SubsequentSolidFillRect)(pScrn, 402706f2543Smrg LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop); 403706f2543Smrg } 404706f2543Smrg } 405706f2543Smrg nbox--; pbox++; 406706f2543Smrg } 407706f2543Smrg 408706f2543Smrg nbox = RegionNumRects(cclip); 409706f2543Smrg pbox = RegionRects(cclip); 410706f2543Smrg 411706f2543Smrg if(infoRec->WriteBitmap && (nglyph > 1) && 412706f2543Smrg ((FONTMAXBOUNDS(font, rightSideBearing) - 413706f2543Smrg FONTMINBOUNDS(font, leftSideBearing)) <= 32)) 414706f2543Smrg { 415706f2543Smrg PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 416706f2543Smrg xInit, yInit, nbox, pbox, 417706f2543Smrg fg, GXcopy, planemask); 418706f2543Smrg 419706f2543Smrg return; 420706f2543Smrg } 421706f2543Smrg 422706f2543Smrg /* compute an approximate but covering bounding box */ 423706f2543Smrg Left = xInit + infoRec->GlyphInfo[0].start; 424706f2543Smrg Right = xInit + infoRec->GlyphInfo[nglyph - 1].end; 425706f2543Smrg Top = yInit - FONTMAXBOUNDS(font,ascent); 426706f2543Smrg Bottom = yInit + FONTMAXBOUNDS(font,descent); 427706f2543Smrg 428706f2543Smrg /* get into the first band that may contain part of our box */ 429706f2543Smrg while(nbox && (Top >= pbox->y2)) { 430706f2543Smrg pbox++; nbox--; 431706f2543Smrg } 432706f2543Smrg 433706f2543Smrg /* stop when the lower edge of the box is beyond our string */ 434706f2543Smrg while(nbox && (Bottom >= pbox->y1)) { 435706f2543Smrg LeftEdge = max(Left, pbox->x1); 436706f2543Smrg RightEdge = min(Right, pbox->x2); 437706f2543Smrg 438706f2543Smrg if(RightEdge > LeftEdge) { /* we're possibly drawing something */ 439706f2543Smrg ytop = max(Top, pbox->y1); 440706f2543Smrg ybot = min(Bottom, pbox->y2); 441706f2543Smrg if(ybot > ytop) { 442706f2543Smrg skippix = LeftEdge - xInit; 443706f2543Smrg skipglyph = 0; 444706f2543Smrg while(skippix >= infoRec->GlyphInfo[skipglyph].end) 445706f2543Smrg skipglyph++; 446706f2543Smrg 447706f2543Smrg skippix = RightEdge - xInit; 448706f2543Smrg n = 0; i = skipglyph; 449706f2543Smrg while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) { 450706f2543Smrg i++; n++; 451706f2543Smrg } 452706f2543Smrg 453706f2543Smrg if(n) (*infoRec->NonTEGlyphRenderer)(pScrn, 454706f2543Smrg xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 455706f2543Smrg pbox, fg, GXcopy, planemask); 456706f2543Smrg } 457706f2543Smrg } 458706f2543Smrg 459706f2543Smrg nbox--; pbox++; 460706f2543Smrg } 461706f2543Smrg} 462706f2543Smrg 463706f2543Smrg 464706f2543Smrgstatic int 465706f2543SmrgPolyGlyphBltNonTEColorExpansion( 466706f2543Smrg ScrnInfoPtr pScrn, 467706f2543Smrg int xInit, int yInit, 468706f2543Smrg FontPtr font, 469706f2543Smrg int fg, int rop, 470706f2543Smrg unsigned planemask, 471706f2543Smrg RegionPtr cclip, 472706f2543Smrg int nglyph, 473706f2543Smrg unsigned char* gBase, 474706f2543Smrg CharInfoPtr *ppci 475706f2543Smrg){ 476706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 477706f2543Smrg int skippix, skipglyph, width, n, i; 478706f2543Smrg int Left, Right, Top, Bottom; 479706f2543Smrg int LeftEdge, RightEdge; 480706f2543Smrg int nbox = RegionNumRects(cclip); 481706f2543Smrg BoxPtr pbox = RegionRects(cclip); 482706f2543Smrg 483706f2543Smrg width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font); 484706f2543Smrg 485706f2543Smrg if(!nbox) 486706f2543Smrg return width; 487706f2543Smrg 488706f2543Smrg if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) && 489706f2543Smrg ((FONTMAXBOUNDS(font, rightSideBearing) - 490706f2543Smrg FONTMINBOUNDS(font, leftSideBearing)) <= 32)) { 491706f2543Smrg 492706f2543Smrg PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 493706f2543Smrg xInit, yInit, nbox, pbox, 494706f2543Smrg fg, rop, planemask); 495706f2543Smrg 496706f2543Smrg return width; 497706f2543Smrg } 498706f2543Smrg 499706f2543Smrg /* compute an approximate but covering bounding box */ 500706f2543Smrg Left = xInit + infoRec->GlyphInfo[0].start; 501706f2543Smrg Right = xInit + infoRec->GlyphInfo[nglyph - 1].end; 502706f2543Smrg Top = yInit - FONTMAXBOUNDS(font,ascent); 503706f2543Smrg Bottom = yInit + FONTMAXBOUNDS(font,descent); 504706f2543Smrg 505706f2543Smrg /* get into the first band that may contain part of our string */ 506706f2543Smrg while(nbox && (Top >= pbox->y2)) { 507706f2543Smrg pbox++; nbox--; 508706f2543Smrg } 509706f2543Smrg 510706f2543Smrg /* stop when the lower edge of the box is beyond our string */ 511706f2543Smrg while(nbox && (Bottom >= pbox->y1)) { 512706f2543Smrg LeftEdge = max(Left, pbox->x1); 513706f2543Smrg RightEdge = min(Right, pbox->x2); 514706f2543Smrg 515706f2543Smrg if(RightEdge > LeftEdge) { /* we're possibly drawing something */ 516706f2543Smrg 517706f2543Smrg skippix = LeftEdge - xInit; 518706f2543Smrg skipglyph = 0; 519706f2543Smrg while(skippix >= infoRec->GlyphInfo[skipglyph].end) 520706f2543Smrg skipglyph++; 521706f2543Smrg 522706f2543Smrg skippix = RightEdge - xInit; 523706f2543Smrg n = 0; i = skipglyph; 524706f2543Smrg while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) { 525706f2543Smrg i++; n++; 526706f2543Smrg } 527706f2543Smrg 528706f2543Smrg if(n) (*infoRec->NonTEGlyphRenderer)(pScrn, 529706f2543Smrg xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 530706f2543Smrg pbox, fg, rop, planemask); 531706f2543Smrg } 532706f2543Smrg 533706f2543Smrg nbox--; pbox++; 534706f2543Smrg } 535706f2543Smrg return width; 536706f2543Smrg} 537706f2543Smrg 538706f2543Smrg 539706f2543Smrg/* It is possible that the none of the glyphs passed to the 540706f2543Smrg NonTEGlyphRenderer will be drawn. This function being called 541706f2543Smrg indicates that part of the text string's bounding box is visible 542706f2543Smrg but not necessarily that any of the characters are visible */ 543706f2543Smrg 544706f2543Smrgvoid XAANonTEGlyphRenderer( 545706f2543Smrg ScrnInfoPtr pScrn, 546706f2543Smrg int x, int y, int n, 547706f2543Smrg NonTEGlyphPtr glyphs, 548706f2543Smrg BoxPtr pbox, 549706f2543Smrg int fg, int rop, 550706f2543Smrg unsigned int planemask 551706f2543Smrg){ 552706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 553706f2543Smrg int x1, x2, y1, y2, i, w, h, skipleft, skiptop; 554706f2543Smrg unsigned char *src; 555706f2543Smrg 556706f2543Smrg for(i = 0; i < n; i++, glyphs++) { 557706f2543Smrg x1 = x + glyphs->start; 558706f2543Smrg x2 = x + glyphs->end; 559706f2543Smrg y1 = y - glyphs->yoff; 560706f2543Smrg y2 = y1 + glyphs->height; 561706f2543Smrg 562706f2543Smrg if(y1 < pbox->y1) { 563706f2543Smrg skiptop = pbox->y1 - y1; 564706f2543Smrg y1 = pbox->y1; 565706f2543Smrg } else skiptop = 0; 566706f2543Smrg if(y2 > pbox->y2) y2 = pbox->y2; 567706f2543Smrg h = y2 - y1; 568706f2543Smrg if(h <= 0) continue; 569706f2543Smrg 570706f2543Smrg if(x1 < pbox->x1) { 571706f2543Smrg skipleft = pbox->x1 - x1; 572706f2543Smrg x1 = pbox->x1; 573706f2543Smrg } else skipleft = 0; 574706f2543Smrg if(x2 > pbox->x2) x2 = pbox->x2; 575706f2543Smrg 576706f2543Smrg w = x2 - x1; 577706f2543Smrg 578706f2543Smrg if(w > 0) { 579706f2543Smrg src = glyphs->bits + (skiptop * glyphs->srcwidth); 580706f2543Smrg 581706f2543Smrg if(skipleft) { 582706f2543Smrg src += (skipleft >> 5) << 2; 583706f2543Smrg skipleft &= 31; 584706f2543Smrg } 585706f2543Smrg 586706f2543Smrg (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src, 587706f2543Smrg glyphs->srcwidth, skipleft, fg, -1, rop, planemask); 588706f2543Smrg } 589706f2543Smrg } 590706f2543Smrg 591706f2543Smrg} 592