home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / ppc / ppcCacheTx.c < prev    next >
C/C++ Source or Header  |  1991-07-16  |  20KB  |  746 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23. #include "X.h"
  24. #include "Xmd.h"
  25. #include "Xproto.h"
  26.  
  27. #include "scrnintstr.h"
  28. #include "dixfontstr.h"
  29. #include "fontstruct.h"
  30. #include "regionstr.h"
  31. #include "pixmapstr.h"
  32. #include "windowstr.h"
  33.  
  34. #include "ppcCache.h"
  35. #include "ppc.h"
  36. #include "ppcProcs.h"
  37. #include "OScompiler.h"
  38. extern int mfbGCPrivateIndex;
  39.  
  40. static unsigned int
  41. miWidth(n, charinfo)
  42.     register unsigned int n;
  43.     register CharInfoPtr charinfo[];
  44. {
  45.     register unsigned int w = 0;
  46.  
  47.     while ( n-- )
  48.     w += charinfo[n]->metrics.characterWidth ;
  49.  
  50.     return w;
  51. }
  52.  
  53.  
  54. static ppcBMInfoPtr
  55. ppcFaultChar(cacheInfo, pci, pglyphBase)
  56.     ppcCacheInfoPtr cacheInfo;
  57.     CharInfoPtr    pci;
  58.     char         *pglyphBase;
  59.     {
  60.     char *pglyph;
  61.     ppcBMInfoPtr bm;
  62.  
  63.     pglyph = pglyphBase + pci->byteOffset;
  64.  
  65.     if ( ( bm = newBM(cacheInfo, GLYPHWIDTHPIXELS(pci), GLYPHHEIGHTPIXELS(pci) ) ) == NULL )
  66.         return((ppcBMInfoPtr)NULL);
  67.  
  68.     (* cacheInfo->blitToCache)( pglyph, bm );
  69.  
  70.     return(bm);
  71.  
  72.     }
  73.  
  74. /*
  75.  * ppcGetGlyphs - ppc version of GetGlyphs routine.
  76.  */
  77.  
  78. static void
  79. ppcGetGlyphs(pScreen, font, count, chars, fontEncoding, glyphcount, glyphs, bms)
  80.     ScreenPtr pScreen;
  81.     FontPtr font;
  82.     unsigned long count;
  83.     register unsigned char *chars;
  84.     FontEncoding fontEncoding;
  85.     unsigned long *glyphcount;    /* RETURN */
  86.     CharInfoPtr glyphs[];    /* RETURN */
  87.     ppcBMInfoPtr bms[];        /* RETURN */
  88. {
  89.     CharInfoPtr        pCI = font->pCI;
  90.     FontInfoPtr        pFI = font->pFI;
  91.     unsigned int    firstCol = pFI->firstCol;
  92.     unsigned int    numCols = pFI->lastCol - firstCol + 1;
  93.     unsigned int    firstRow = pFI->firstRow;
  94.     unsigned int    numRows = pFI->lastRow - firstRow + 1;
  95.     unsigned int    chDefault = pFI->chDefault;
  96.     unsigned int    cDef = chDefault - firstCol;
  97.     register unsigned long    i;
  98.     unsigned long        n;
  99.     register unsigned int    c;
  100.     register CharInfoPtr    ci;
  101.     ppcBMInfoPtr        *bmtable;
  102.     ppcCacheInfoPtr        cacheInfo;
  103.     char             *pglyphBase;
  104.  
  105.     bmtable = (ppcBMInfoPtr *)font->devPriv[pScreen->myNum];
  106.     cacheInfo = ((ppcScrnPrivPtr)pScreen->devPrivate)->cacheInfo;
  107.     pglyphBase = font->pGlyphs;
  108.  
  109.     n = 0;
  110.     switch (fontEncoding) {
  111.  
  112.     case Linear8Bit:
  113.     case TwoD8Bit:
  114.         if (pFI->allExist && (cDef < numCols)) {
  115.         for (i=0; i < count; i++) {
  116.  
  117.             c = (*chars++) - firstCol;
  118.             if (c >= numCols) {
  119.             c = cDef;
  120.             }
  121.             ci = &pCI[c];
  122.             glyphs[i] = ci;
  123.             if ( ( bms[i] = bmtable[c] ) == NULL )
  124.             bmtable[c] = bms[i] = 
  125.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  126.         }
  127.         n = count;
  128.         } else {
  129.         for (i=0; i < count; i++) {
  130.     
  131.             c = (*chars++) - firstCol;
  132.             if (c < numCols) {
  133.             ci = &pCI[c];
  134.             if (ci->exists) {
  135.                 glyphs[n] = ci;
  136.                 if ( ( bms[n] = bmtable[c] ) == NULL )
  137.                 bmtable[c] = bms[n++] = 
  138.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  139.                 else
  140.                 n++;
  141.                 continue;
  142.             }
  143.             }
  144.     
  145.             if (cDef < numCols) {
  146.             ci = &pCI[cDef];
  147.             if (ci->exists) {
  148.                 glyphs[n] = ci;
  149.                 if ( ( bms[n] = bmtable[cDef] ) == NULL )
  150.                 bmtable[cDef] = bms[n++] = 
  151.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  152.                 else
  153.                 n++;
  154.             }
  155.             }
  156.         }
  157.         }
  158.         break;
  159.  
  160.     case Linear16Bit:
  161.         if (pFI->allExist && (cDef < numCols)) {
  162.         for (i=0; i < count; i++) {
  163.  
  164.             c = *chars++ << 8;
  165.             c = (c | *chars++) - firstCol;
  166.             if (c >= numCols) {
  167.             c = cDef;
  168.             }
  169.             ci = &pCI[c];
  170.             glyphs[i] = ci;
  171.             if ( ( bms[i] = bmtable[c] ) == NULL )
  172.             bmtable[c] = bms[i] = 
  173.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  174.         }
  175.         n = count;
  176.         } else {
  177.         for (i=0; i < count; i++) {
  178.     
  179.             c = *chars++ << 8;
  180.             c = (c | *chars++) - firstCol;
  181.             if (c < numCols) {
  182.             ci = &pCI[c];
  183.             if (ci->exists) {
  184.                 glyphs[n] = ci;
  185.                 if ( ( bms[n] = bmtable[c] ) == NULL )
  186.                 bmtable[c] = bms[n++] = 
  187.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  188.                 else
  189.                 n++;
  190.                 continue;
  191.             }
  192.             }
  193.     
  194.             if (cDef < numCols) {
  195.             ci = &pCI[cDef];
  196.             if (ci->exists) {
  197.                 glyphs[n] = ci;
  198.                 if ( ( bms[n] = bmtable[cDef] ) == NULL )
  199.                 bmtable[cDef] = bms[n++] = 
  200.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  201.                 else
  202.                 n++;
  203.             }
  204.             }
  205.         }
  206.         }
  207.         break;
  208.  
  209.     case TwoD16Bit:
  210.         for (i=0; i < count; i++) {
  211.         register unsigned int row;
  212.         register unsigned int col;
  213.  
  214.         row = (*chars++) - firstRow;
  215.         col = (*chars++) - firstCol;
  216.         if ((row < numRows) && (col < numCols)) {
  217.             c = row*numCols + col;
  218.             ci = &pCI[c];
  219.             if (ci->exists) {
  220.             glyphs[n] = ci;
  221.             if ( ( bms[n] = bmtable[c] ) == NULL )
  222.                 bmtable[c] = bms[n++] = 
  223.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  224.             else
  225.                 n++;
  226.             continue;
  227.             }
  228.         }
  229.  
  230.         row = (chDefault >> 8)-firstRow;
  231.         col = (chDefault & 0xff)-firstCol;
  232.         if ((row < numRows) && (col < numCols)) {
  233.             c = row*numCols + col;
  234.             ci = &pCI[c];
  235.             if (ci->exists) {
  236.             glyphs[n] = ci;
  237.             if ( ( bms[n] = bmtable[c] ) == NULL )
  238.                 bmtable[c] = bms[n++] = 
  239.                     ppcFaultChar(cacheInfo, ci, pglyphBase);
  240.             else
  241.                 n++;
  242.             }
  243.         }
  244.         }
  245.         break;
  246.     }
  247.     *glyphcount = n;
  248. }
  249.  
  250. int
  251. ppcCachedImageText(pDraw, pGC, x, y, count, chars, fontEncoding)
  252.     DrawablePtr pDraw;
  253.     GCPtr pGC;
  254.     int x, y;
  255.     int count;
  256.     char *chars;
  257.     FontEncoding fontEncoding;
  258.     {
  259.     CharInfoPtr *charinfo;
  260.     ppcBMInfoPtr *bms;
  261.     unsigned long n;
  262.     FontPtr font = pGC->font;
  263.     unsigned int w;
  264.     ppcCacheInfoPtr        cacheInfo;
  265.  
  266.     cacheInfo = ((ppcScrnPrivPtr)pDraw->pScreen->devPrivate)->cacheInfo;
  267.     if ( ! (charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(
  268.                         count * sizeof(CharInfoPtr))))
  269.         return(x);
  270.     if ( ! (bms = (ppcBMInfoPtr *)ALLOCATE_LOCAL(
  271.                         count * sizeof(ppcBMInfoPtr))))
  272.         {
  273.         DEALLOCATE_LOCAL(charinfo);
  274.         return(x);
  275.         }
  276.     ppcGetGlyphs(pDraw->pScreen, font, (unsigned long)count, 
  277.         (unsigned char *)chars, fontEncoding, &n, charinfo, bms);
  278.  
  279.     w = miWidth(n, charinfo);
  280.     if ( n != 0 )
  281.         {
  282.         (* ((ppcPrivGCPtr) pGC->devPrivates[mfbGCPrivateIndex].ptr )->cachedIGBlt)(pDraw, pGC, x, y, n, charinfo, bms, font->pGlyphs);
  283.         }
  284.     DEALLOCATE_LOCAL(charinfo);
  285.     DEALLOCATE_LOCAL(bms);
  286.  
  287.     return x+w;
  288.     }
  289.  
  290. void
  291. ppcCachedImageGlyphBlt( pDrawable, pGC, x, y, nglyph, ppci, bms, pglyphBase )
  292.     DrawablePtr pDrawable ;
  293.     GCPtr    pGC ;
  294.     int     x, y ;
  295.     unsigned int nglyph ;
  296.     CharInfoPtr *ppci ;        /* array of character info */
  297.     ppcBMInfoPtr *bms ;
  298.     unsigned char *pglyphBase ;    /* start of array of glyphs */
  299. {
  300.     register unsigned char    *pglyph ;
  301.     register BoxPtr        pbox ;
  302.     register int        nbox ;
  303.     ExtentInfoRec         info ;    
  304.     BoxRec             bbox ;    
  305.     xRectangle             backrect ;
  306.     CharInfoPtr          pci ;
  307.     FontInfoPtr            pfi ;
  308.     int             fg, bg, pm, ax,ay,zx,zy,zw,zh,
  309.                     w, h, widthGlyph ;
  310.  
  311.     RegionPtr             pRegion ;
  312.  
  313.     PixmapPtr            pTempPixmap = NULL ;
  314.     ScreenPtr            pScreen ;
  315.     ppcScrnPriv            *pScrPriv ;
  316.     int                been_here = FALSE ;
  317.     void            (*rectFunc)(), (*glyphFunc)(), (*stipFunc)() ;
  318.     int                CursorIsSaved ;
  319.     ppcBMInfoPtr        bm;
  320.     ppcCacheInfoPtr        cacheInfo;
  321.  
  322.     pRegion = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip ; 
  323.     if ( !( nbox = REGION_NUM_RECTS(pRegion) ) )
  324.     return ;
  325.  
  326.     pScreen = pGC->pScreen ;
  327.     pScrPriv = (ppcScrnPriv *) pScreen->devPrivate ;
  328.     cacheInfo = pScrPriv->cacheInfo;
  329.     pfi = pGC->font->pFI;
  330.  
  331.     rectFunc = pScrPriv->solidFill ;
  332.     stipFunc = pScrPriv->stipFill ;
  333.     glyphFunc = pScrPriv->glyphFill ;
  334.  
  335.     QueryGlyphExtents(pGC->font, ppci, nglyph, &info) ;
  336.  
  337.     x += pDrawable->x ;
  338.     y += pDrawable->y ;
  339.  
  340.     backrect.y = y - pfi->fontAscent ;
  341.     backrect.height = pfi->fontAscent + pfi->fontDescent ;
  342.     backrect.width =
  343.      MAX( ( info.overallRight - info.overallLeft ), info.overallWidth ) ;
  344.     backrect.x = x + info.overallLeft ;
  345.  
  346.     /* High Level Software Cursor Support */
  347.     CursorIsSaved = !(*(pScrPriv->CursorSemaphore))
  348.          && (* pScrPriv->CheckCursor)( backrect.x, backrect.y,
  349.                            backrect.width,
  350.                            backrect.height ) ;
  351.     (*(pScrPriv->CursorSemaphore))++ ;
  352.  
  353.     bbox.x1 = x + info.overallLeft ;
  354.     bbox.x2 = x + info.overallRight ;
  355.     bbox.y1 = y - info.overallAscent ;
  356.     bbox.y2 = y + info.overallDescent ;
  357.  
  358.     pm =  pGC->planemask ;
  359.     bg =  pGC->bgPixel ;
  360.     for ( pbox = REGION_RECTS(pRegion); nbox-- ; pbox++ ) {
  361.     ax = MAX( pbox->x1, backrect.x ) ;
  362.     ay = MAX( pbox->y1, backrect.y ) ;
  363.     zx = MIN( pbox->x2, backrect.x + backrect.width ) ;
  364.     zy = MIN( pbox->y2, backrect.y + backrect.height ) ;
  365.     if ( ( ( zw = zx - ax ) > 0 ) && ( ( zh = zy - ay ) > 0 ) )
  366.         (* rectFunc)( bg, GXcopy, pm, ax, ay, zw, zh ) ;
  367.     }
  368.  
  369.     fg =  pGC->fgPixel ;
  370.  
  371.     switch ( (* pScreen->RectIn)( pRegion, &bbox ) ) {
  372.       case rgnIN:
  373.         while ( nglyph-- ) {
  374.         pci = *ppci++ ;
  375.         if ( bm = *bms++ )
  376.         {
  377.         (* cacheInfo->blitToScreen)( bm, x + pci->metrics.leftSideBearing, y - pci->metrics.ascent, fg, GXcopy, pm );
  378.         }
  379.         else
  380.         {
  381.         pglyph = pglyphBase + pci->byteOffset ;
  382.         if ( ( w = GLYPHWIDTHPIXELS(pci) )
  383.           && ( h = GLYPHHEIGHTPIXELS(pci) ) )
  384.             (*glyphFunc)( pglyph,
  385.                   x + pci->metrics.leftSideBearing,
  386.                   y - pci->metrics.ascent,
  387.                   w, h, fg, GXcopy, pm ) ;
  388.         }
  389.         x += pci->metrics.characterWidth ;    /* update character origin */
  390.         } /* while nglyph-- */
  391.       case rgnOUT:
  392.     break ;
  393.       case rgnPART:
  394.       {
  395.     RegionPtr prgnClip ;
  396.  
  397.     BoxRec cbox ;
  398.     int glx, gly ;
  399.  
  400.         while ( nglyph-- )
  401.         {
  402.         pci = *ppci++ ;
  403.         bm = *bms++ ;
  404.         pglyph = pglyphBase + pci->byteOffset ;
  405.         w = GLYPHWIDTHPIXELS(pci) ;
  406.         h = GLYPHHEIGHTPIXELS(pci) ;
  407.         cbox.x1 = glx = x + pci->metrics.leftSideBearing ;
  408.         cbox.x2 = cbox.x1 + w ;
  409.         cbox.y1 = gly = y - pci->metrics.ascent ;
  410.         cbox.y2 = cbox.y1 + h ;
  411.  
  412.         switch ( (* pScreen->RectIn)( pRegion,  &cbox ) ) {
  413.           case rgnIN:
  414.         if ( bm )
  415.             (* cacheInfo->blitToScreen)( bm, glx, gly, fg, GXcopy, pm );
  416.         else
  417.                 (* glyphFunc)( pglyph, glx, gly, w, h, fg, GXcopy, pm ) ;
  418.           case rgnOUT:
  419.         break ;
  420.           case rgnPART:
  421.         if ( !been_here )
  422.             {
  423.             widthGlyph = pfi->maxbounds.metrics.rightSideBearing-
  424.                         pfi->minbounds.metrics.leftSideBearing;
  425.             widthGlyph = PADGLYPHWIDTHBYTES(widthGlyph);
  426.                 pTempPixmap = ppcCreatePixmap( pScreen, 
  427.                 widthGlyph * 8,
  428.                 pfi->maxbounds.metrics.ascent +
  429.                     pfi->maxbounds.metrics.descent ,
  430.                 1 ) ;
  431.             been_here = TRUE ;
  432.             }
  433.         prgnClip = (* pScreen->RegionCreate)( &cbox,
  434.                               REGION_NUM_RECTS(pRegion)) ;
  435.         (* pScreen->Intersect)( prgnClip, prgnClip, pRegion ) ;
  436.         if ( !( nbox = REGION_NUM_RECTS(prgnClip) ) ) {
  437.             (* pScreen->RegionDestroy)( prgnClip ) ;
  438.             break ;
  439.         }
  440.         widthGlyph = GLYPHWIDTHBYTESPADDED(pci) ;
  441.             filltempPixmap(pTempPixmap, pglyph, widthGlyph, h) ;
  442.         for ( pbox = REGION_RECTS(prgnClip); nbox-- ; pbox++ )
  443.             {
  444.             ax = MAX(pbox->x1, cbox.x1) ;
  445.             ay = MAX(pbox->y1, cbox.y1) ;
  446.             zx = MIN(pbox->x2, cbox.x2) ;
  447.             zy = MIN(pbox->y2, cbox.y2) ;
  448.                 if ( ( ( zw = zx - ax ) > 0 )
  449.                   && ( ( zh = zy - ay ) > 0 ) )
  450.                 (*stipFunc)( pTempPixmap, 
  451.                          fg, GXcopy, pm, ax, ay,
  452.                          zw, zh, glx, gly ) ;
  453.             }
  454.         (* pScreen->RegionDestroy)( prgnClip ) ;
  455.         break ;
  456.         }
  457.         /* update character origin */
  458.         x += pci->metrics.characterWidth ;
  459.         } /* while nglyph-- */
  460.  
  461.     if ( pTempPixmap )
  462.         (* pScreen->DestroyPixmap)( pTempPixmap ) ;
  463.  
  464.       }
  465.       default:
  466.     break ;
  467.     }
  468.     if ( !--(*(pScrPriv->CursorSemaphore)) && CursorIsSaved )
  469.     (* pScrPriv->ReplaceCursor)() ;
  470.  
  471.     return ;
  472. }
  473.  
  474. int
  475. ppcCachedImageText8(pDraw, pGC, x, y, count, chars)
  476.     DrawablePtr pDraw;
  477.     GCPtr pGC;
  478.     int x, y;
  479.     int count;
  480.     char *chars;
  481.     {
  482.     return ppcCachedImageText(pDraw, pGC, x, y, count, chars, Linear8Bit);
  483.     }
  484.  
  485. int
  486. ppcCachedImageText16(pDraw, pGC, x, y, count, chars)
  487.     DrawablePtr pDraw;
  488.     GCPtr       pGC;
  489.     int         x, y;
  490.     int         count;
  491.     unsigned short *chars;
  492. {
  493.     if (pGC->font->pFI->lastRow == 0)
  494.         return ppcCachedImageText(pDraw, pGC, x, y, count, (char *)chars, 
  495.                                 Linear16Bit);
  496.     else
  497.         return ppcCachedImageText(pDraw, pGC, x, y, count, (char *)chars, 
  498.                                 TwoD16Bit);
  499. }
  500.  
  501.  
  502. int
  503. ppcCachedPolyText(pDraw, pGC, x, y, count, chars, fontEncoding)
  504.     DrawablePtr pDraw;
  505.     GCPtr pGC;
  506.     int x, y;
  507.     int count;
  508.     char *chars;
  509.     FontEncoding fontEncoding;
  510.     {
  511.     CharInfoPtr *charinfo;
  512.     ppcBMInfoPtr *bms;
  513.     unsigned long n;
  514.     FontPtr font = pGC->font;
  515.     unsigned int w;
  516.     ppcCacheInfoPtr        cacheInfo;
  517.  
  518.     cacheInfo = ((ppcScrnPrivPtr)pDraw->pScreen->devPrivate)->cacheInfo;
  519.     if ( ! (charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(
  520.                         count * sizeof(CharInfoPtr))))
  521.         return(x);
  522.     if ( ! (bms = (ppcBMInfoPtr *)ALLOCATE_LOCAL(
  523.                         count * sizeof(ppcBMInfoPtr))))
  524.         {
  525.         DEALLOCATE_LOCAL(charinfo);
  526.         return(x);
  527.         }
  528.     ppcGetGlyphs(pDraw->pScreen, font, (unsigned long)count, 
  529.         (unsigned char *)chars, fontEncoding, &n, charinfo, bms);
  530.  
  531.     w = miWidth(n, charinfo);
  532.     if ( n != 0 )
  533.         {
  534.         (* ((ppcPrivGCPtr) pGC->devPrivates[mfbGCPrivateIndex].ptr )->cachedPGBlt)(pDraw, pGC, x, y, n, charinfo, bms, font->pGlyphs);
  535.         }
  536.     DEALLOCATE_LOCAL(charinfo);
  537.     DEALLOCATE_LOCAL(bms);
  538.  
  539.     return x+w;
  540.  
  541.     }
  542.  
  543.  
  544. void
  545. ppcCachedPolyGlyphBlt( pDrawable, pGC, x, y, nglyph, ppci, bms, pglyphBase )
  546.     DrawablePtr pDrawable ;
  547.     GCPtr    pGC ;
  548.     int     x, y ;
  549.     unsigned int nglyph ;
  550.     CharInfoPtr *ppci ;        /* array of character info */
  551.     ppcBMInfoPtr *bms ;
  552.     unsigned char *pglyphBase ;    /* start of array of glyphs */
  553. {
  554.     register unsigned char    *pglyph ;
  555.     register BoxPtr        pbox ;
  556.     register int        nbox ;
  557.     ExtentInfoRec         info ;    
  558.     BoxRec             bbox ;    
  559.     xRectangle             backrect ;
  560.     CharInfoPtr          pci ;
  561.     FontInfoPtr            pfi ;
  562.     int             fg, pm, ax,ay,zx,zy,zw,zh,
  563.                     w, h, widthGlyph ;
  564.  
  565.     RegionPtr             pRegion ;
  566.  
  567.     PixmapPtr            pTempPixmap = NULL ;
  568.     ScreenPtr            pScreen ;
  569.     ppcScrnPriv            *pScrPriv ;
  570.     int                been_here = FALSE ;
  571.     void            (*rectFunc)(), (*glyphFunc)(), (*stipFunc)() ;
  572.     int                CursorIsSaved ;
  573.     ppcBMInfoPtr        bm;
  574.     ppcCacheInfoPtr        cacheInfo;
  575.     int                alu;
  576.  
  577.     pRegion = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip ; 
  578.     if ( !( nbox = REGION_NUM_RECTS(pRegion) ) )
  579.     return ;
  580.  
  581.     pScreen = pGC->pScreen ;
  582.     pScrPriv = (ppcScrnPriv *) pScreen->devPrivate ;
  583.     cacheInfo = pScrPriv->cacheInfo;
  584.     pfi = pGC->font->pFI;
  585.  
  586.     rectFunc = pScrPriv->solidFill ;
  587.     stipFunc = pScrPriv->stipFill ;
  588.     glyphFunc = pScrPriv->glyphFill ;
  589.  
  590.     QueryGlyphExtents(pGC->font, ppci, nglyph, &info) ;
  591.  
  592.     x += pDrawable->x ;
  593.     y += pDrawable->y ;
  594.  
  595.     backrect.y = y - pfi->fontAscent ;
  596.     backrect.height = pfi->fontAscent + pfi->fontDescent ;
  597.     backrect.width =
  598.      MAX( ( info.overallRight - info.overallLeft ), info.overallWidth ) ;
  599.     backrect.x = x + info.overallLeft ;
  600.  
  601.     /* High Level Software Cursor Support */
  602.     CursorIsSaved = !(*(pScrPriv->CursorSemaphore))
  603.          && (* pScrPriv->CheckCursor)( backrect.x, backrect.y,
  604.                            backrect.width,
  605.                            backrect.height ) ;
  606.     (*(pScrPriv->CursorSemaphore))++ ;
  607.  
  608.     bbox.x1 = x + info.overallLeft ;
  609.     bbox.x2 = x + info.overallRight ;
  610.     bbox.y1 = y - info.overallAscent ;
  611.     bbox.y2 = y + info.overallDescent ;
  612.  
  613.     pm =  pGC->planemask ;
  614.     fg =  pGC->fgPixel ;
  615.     alu = pGC->alu ;
  616.  
  617.     switch ( (* pScreen->RectIn)( pRegion, &bbox ) ) {
  618.       case rgnIN:
  619.         while ( nglyph-- ) {
  620.         pci = *ppci++ ;
  621.         if ( bm = *bms++ )
  622.         {
  623.         (* cacheInfo->blitToScreen)( bm, x + pci->metrics.leftSideBearing, y - pci->metrics.ascent, fg, alu, pm );
  624.         }
  625.         else
  626.         {
  627.         pglyph = pglyphBase + pci->byteOffset ;
  628.         if ( ( w = GLYPHWIDTHPIXELS(pci) )
  629.           && ( h = GLYPHHEIGHTPIXELS(pci) ) )
  630.             (*glyphFunc)( pglyph,
  631.                   x + pci->metrics.leftSideBearing,
  632.                   y - pci->metrics.ascent,
  633.                   w, h, fg, alu, pm ) ;
  634.         }
  635.         x += pci->metrics.characterWidth ;    /* update character origin */
  636.         } /* while nglyph-- */
  637.       case rgnOUT:
  638.     break ;
  639.       case rgnPART:
  640.       {
  641.     RegionPtr prgnClip ;
  642.  
  643.     BoxRec cbox ;
  644.     int glx, gly ;
  645.  
  646.         while ( nglyph-- )
  647.         {
  648.         pci = *ppci++ ;
  649.         bm = *bms++ ;
  650.         pglyph = pglyphBase + pci->byteOffset ;
  651.         w = GLYPHWIDTHPIXELS(pci) ;
  652.         h = GLYPHHEIGHTPIXELS(pci) ;
  653.         cbox.x1 = glx = x + pci->metrics.leftSideBearing ;
  654.         cbox.x2 = cbox.x1 + w ;
  655.         cbox.y1 = gly = y - pci->metrics.ascent ;
  656.         cbox.y2 = cbox.y1 + h ;
  657.  
  658.         switch ( (* pScreen->RectIn)( pRegion,  &cbox ) ) {
  659.           case rgnIN:
  660.         if ( bm )
  661.             (* cacheInfo->blitToScreen)( bm, glx, gly, fg, alu, pm );
  662.         else
  663.                 (* glyphFunc)( pglyph, glx, gly, w, h, fg, alu, pm ) ;
  664.           case rgnOUT:
  665.         break ;
  666.           case rgnPART:
  667.         if ( !been_here )
  668.             {
  669.             widthGlyph = pfi->maxbounds.metrics.rightSideBearing-
  670.                         pfi->minbounds.metrics.leftSideBearing;
  671.             widthGlyph = PADGLYPHWIDTHBYTES(widthGlyph);
  672.                 pTempPixmap = ppcCreatePixmap( pScreen, 
  673.                 widthGlyph * 8,
  674.                 pfi->maxbounds.metrics.ascent +
  675.                     pfi->maxbounds.metrics.descent ,
  676.                 1 ) ;
  677.             been_here = TRUE ;
  678.             }
  679.         prgnClip = (* pScreen->RegionCreate)( &cbox,
  680.                               REGION_NUM_RECTS(pRegion)) ;
  681.         (* pScreen->Intersect)( prgnClip, prgnClip, pRegion ) ;
  682.         if ( !( nbox = REGION_NUM_RECTS(prgnClip) ) ) {
  683.             (* pScreen->RegionDestroy)( prgnClip ) ;
  684.             break ;
  685.         }
  686.         widthGlyph = GLYPHWIDTHBYTESPADDED(pci) ;
  687.             filltempPixmap(pTempPixmap, pglyph, widthGlyph, h) ;
  688.         for ( pbox = REGION_RECTS(prgnClip); nbox-- ; pbox++ )
  689.             {
  690.             ax = MAX(pbox->x1, cbox.x1) ;
  691.             ay = MAX(pbox->y1, cbox.y1) ;
  692.             zx = MIN(pbox->x2, cbox.x2) ;
  693.             zy = MIN(pbox->y2, cbox.y2) ;
  694.                 if ( ( ( zw = zx - ax ) > 0 )
  695.                   && ( ( zh = zy - ay ) > 0 ) )
  696.                 (*stipFunc)( pTempPixmap, 
  697.                          fg, alu, pm, ax, ay,
  698.                          zw, zh, glx, gly ) ;
  699.             }
  700.         (* pScreen->RegionDestroy)( prgnClip ) ;
  701.         break ;
  702.         }
  703.         /* update character origin */
  704.         x += pci->metrics.characterWidth ;
  705.         } /* while nglyph-- */
  706.  
  707.     if ( pTempPixmap )
  708.         (* pScreen->DestroyPixmap)( pTempPixmap ) ;
  709.  
  710.       }
  711.       default:
  712.     break ;
  713.     }
  714.     if ( !--(*(pScrPriv->CursorSemaphore)) && CursorIsSaved )
  715.     (* pScrPriv->ReplaceCursor)() ;
  716.  
  717.     return ;
  718. }
  719.  
  720. int
  721. ppcCachedPolyText8(pDraw, pGC, x, y, count, chars)
  722.     DrawablePtr pDraw;
  723.     GCPtr pGC;
  724.     int x, y;
  725.     int count;
  726.     char *chars;
  727.     {
  728.     return ppcCachedPolyText(pDraw, pGC, x, y, count, chars, Linear8Bit);
  729.     }
  730.  
  731. int
  732. ppcCachedPolyText16(pDraw, pGC, x, y, count, chars)
  733.     DrawablePtr pDraw;
  734.     GCPtr       pGC;
  735.     int         x, y;
  736.     int         count;
  737.     unsigned short *chars;
  738. {
  739.     if (pGC->font->pFI->lastRow == 0)
  740.         return ppcCachedPolyText(pDraw, pGC, x, y, count, (char *)chars, 
  741.                                 Linear16Bit);
  742.     else
  743.         return ppcCachedPolyText(pDraw, pGC, x, y, count, (char *)chars, 
  744.                                 TwoD16Bit);
  745. }
  746.