Annotation of ntddk/src/video/displays/s3/textout.c, revision 1.1.1.1

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: TextOut.c
                      3: *
                      4: * S3 Text accelerations
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: *
                      8: \**************************************************************************/
                      9: 
                     10: #include "driver.h"
                     11: #include "memory.h"
                     12: 
                     13: // Part of the fix to limit the amount of resources allocated for fonts
                     14: 
                     15: #define MAX_GLYPHS_TO_ALLOC 256
                     16: 
                     17: // number of bytes in the glyph bitmap scanline
                     18: 
                     19: #define CJ_SCAN(cx) (((cx) + 7) >> 3)
                     20: 
                     21: #define TRIVIAL_ACCEPT      0x00000001
                     22: #define MONO_SPACED_FONT    0x00000002
                     23: #define MONO_SIZE_VALID     0x00000004
                     24: #define MONO_FIRST_TIME     0x00000008
                     25: 
                     26: PCACHEDFONT pCachedFontsRoot;             // Cached Fonts list root.
                     27: 
                     28: WORD   iPlaneBits[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
                     29: 
                     30: BOOL bOpaqueRect(
                     31:     PPDEV ppdev,
                     32:     RECTL *prclOpaque,
                     33:     RECTL *prclBounds,
                     34:     BRUSHOBJ *pboOpaque);
                     35: 
                     36: BOOL bSetS3TextColorAndMix(
                     37:     PPDEV ppdev,
                     38:     MIX mix,
                     39:     BRUSHOBJ *pboFore,
                     40:     BRUSHOBJ *pboOpaque);
                     41: 
                     42: VOID vBlowCache(PPDEV ppdev);
                     43: 
                     44: VOID vInitGlyphAlloc(PPDEV ppdev);
                     45: 
                     46: BOOL bAllocGlyphMemory(PPDEV ppdev,
                     47:                        PSIZEL psizlGlyph,
                     48:                        PXYZPOINTL pxyzGlyph);
                     49: 
                     50: PCACHEDGLYPH pCacheFont(PPDEV ppdev,
                     51:                         STROBJ *pstro,
                     52:                         FONTOBJ  *pfo,
                     53:                         PCACHEDFONT *ppCachedFont);
                     54: 
                     55: BOOL bAllocateGlyph(PPDEV ppdev,
                     56:                     HGLYPH hg,
                     57:                     GLYPHBITS *pgb,
                     58:                     PCACHEDGLYPH pcg);
                     59: 
                     60: BOOL bHandleNonCachedFonts(SURFOBJ  *pso,
                     61:                            STROBJ   *pstro,
                     62:                            FONTOBJ  *pfo,
                     63:                            RECTL    *prclClip,
                     64:                            RECTL    *prclExtra,
                     65:                            RECTL    *prclOpaque,
                     66:                            BRUSHOBJ *pboFore,
                     67:                            BRUSHOBJ *pboOpaque,
                     68:                            POINTL   *pptlOrg,
                     69:                            MIX      mix);
                     70: 
                     71: BOOL bHandleCachedFonts(SURFOBJ  *pso,
                     72:                         STROBJ   *pstro,
                     73:                         RECTL    *prclClip,
                     74:                         FONTOBJ  *pfo,
                     75:                         RECTL    *prclOpaque,
                     76:                         BRUSHOBJ *pboFore,
                     77:                         BRUSHOBJ *pboOpaque,
                     78:                         POINTL   *pptlOrg,
                     79:                         MIX      mix);
                     80: 
                     81: #if DBG
                     82: 
                     83: ULONG   nGlyphs, nOverlaps;
                     84: 
                     85: #define TFIFOWAIT(level)    nGlyphs++;                         \
                     86:                             if (INPW(GP_STAT) & level) {         \
                     87:                                 nOverlaps++;                   \
                     88:                                 while (INPW(GP_STAT) & level); \
                     89:                              }
                     90: #else
                     91: 
                     92: #define TFIFOWAIT(level) FIFOWAIT(level)
                     93: 
                     94: #endif
                     95: 
                     96: 
                     97: /****************************************************************************
                     98:  * DrvDestroyFont
                     99:  ***************************************************************************/
                    100: VOID DrvDestroyFont(FONTOBJ *pfo)
                    101: {
                    102:     PCACHEDFONT pCachedFont, pcfLast;
                    103:     PCACHEDGLYPH pcg, pcgNext;
                    104:     INT nGlyphs, i;
                    105: 
                    106:     DISPDBG((1, "S3.DLL!DrvDestroyFont - Entry\n"));
                    107: 
                    108:     if (((pCachedFont = ((PCACHEDFONT) pfo->pvConsumer)) != NULL))
                    109:     {
                    110:         if (pfo->iUniq == pCachedFont->iUniq)
                    111:         {
                    112:             // We have found our font.
                    113: 
                    114:             DISPDBG((1, "S3.DLL: Destroying font: pfo->iUniq: %x\n",
                    115:                          pfo->iUniq));
                    116: 
                    117:             // First free any nodes in the collision list.
                    118: 
                    119:             nGlyphs = pCachedFont->cGlyphs+1;
                    120:             for (i = 0; i < nGlyphs; i++)
                    121:             {
                    122:                 // get a pointer to this glyph node.
                    123: 
                    124:                 pcg = &(pCachedFont->pCachedGlyphs[i]);
                    125: 
                    126:                 // get a pointer to this glyphs collision list
                    127: 
                    128:                 pcg = pcg->pcgCollisionLink;
                    129:                 for (; pcg != NULL; pcg = pcgNext)
                    130:                 {
                    131:                     pcgNext = pcg->pcgCollisionLink;
                    132:                     LocalFree(pcg);
                    133:                 }
                    134:             }
                    135: 
                    136:             // Now free the cached glyph array
                    137: 
                    138:             LocalFree(pCachedFont->pCachedGlyphs);
                    139: 
                    140:             // Now remove the font node from the list of fonts
                    141:             // and free it.
                    142: 
                    143:             pcfLast = (PCACHEDFONT) &pCachedFontsRoot;
                    144:             for (pCachedFont = pCachedFontsRoot;
                    145:                  pCachedFont != NULL;
                    146:                  pCachedFont = pCachedFont->pcfNext)
                    147:             {
                    148:                 if (pCachedFont->iUniq == pfo->iUniq)
                    149:                 {
                    150:                     pcfLast->pcfNext = pCachedFont->pcfNext;
                    151:                     LocalFree(pCachedFont);
                    152:                     break;
                    153:                 }
                    154:                 pcfLast = pCachedFont;
                    155:             }
                    156: 
                    157:             if (pCachedFont == NULL)
                    158:             {
                    159:                 RIP("S3.DLL!DrvDestroyFont - pCachedFont not found\n");
                    160:             }
                    161:         }
                    162:         else
                    163:         {
                    164:             RIP("S3.DLL!DrvDestroyFont - pfo->pvConsumer error\n");
                    165:         }
                    166:     }
                    167: 
                    168:     // In all cases we want to zero out the pvConsumer field.
                    169: 
                    170:     pfo->pvConsumer = NULL;
                    171: 
                    172: }
                    173: 
                    174: 
                    175: /****************************************************************************
                    176:  * DrvTextOut
                    177:  ***************************************************************************/
                    178: BOOL DrvTextOut(
                    179:     SURFOBJ  *pso,
                    180:     STROBJ   *pstro,
                    181:     FONTOBJ  *pfo,
                    182:     CLIPOBJ  *pco,
                    183:     RECTL    *prclExtra,
                    184:     RECTL    *prclOpaque,
                    185:     BRUSHOBJ *pboFore,
                    186:     BRUSHOBJ *pboOpaque,
                    187:     POINTL   *pptlOrg,
                    188:     MIX      mix)
                    189: {
                    190:     BOOL        b, bMore;
                    191:     UINT        i;
                    192:     ENUMRECTS8  EnumRects8;
                    193:     PPDEV       ppdev;
                    194: 
                    195:     DISPDBG((3, "S3.DLL: DrvTextOut - Entry\n"));
                    196: 
                    197:     // Pickup the ppdev.
                    198: 
                    199:     ppdev = (PPDEV) pso->dhpdev;
                    200: 
                    201:     // Protect the code path from a potentially NULL clip object
                    202:     // This also gives a maximum rclBounds which we use later:
                    203: 
                    204:     if (pco == NULL || pco->iDComplexity == DC_TRIVIAL)
                    205:     {
                    206:         pco = ppdev->pcoDefault;
                    207:     }
                    208: 
                    209:     // Determine if we can cache this string.
                    210:     // This is done by checking the size of glyph.
                    211: 
                    212:     b = TRUE;
                    213: 
                    214:     if ((pfo->cxMax > GLYPH_CACHE_CX) ||
                    215:         ((pstro->rclBkGround.bottom - pstro->rclBkGround.top) > GLYPH_CACHE_CY))
                    216:     {
                    217:         b = FALSE;
                    218:     }
                    219: 
                    220:     // If the glyphs in this string will fit in the font cache
                    221:     // then try to render it as a cached font.
                    222: 
                    223:     if (b == TRUE)
                    224:     {
                    225:         // Take care of the clipping.
                    226: 
                    227:         if (pco->iDComplexity != DC_COMPLEX)
                    228:         {
                    229:             b = bHandleCachedFonts(pso, pstro, &(pco->rclBounds), pfo,
                    230:                                    prclOpaque, pboFore,
                    231:                                    pboOpaque, pptlOrg, mix);
                    232: 
                    233:         }
                    234:         else
                    235:         {
                    236:             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
                    237: 
                    238:             do
                    239:             {
                    240:                 bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
                    241:                         (PULONG)&EnumRects8);
                    242: 
                    243:                 for (i = 0; i < EnumRects8.c; i++)
                    244:                 {
                    245:                     b = bHandleCachedFonts(pso, pstro, &(EnumRects8.arcl[i]),
                    246:                             pfo, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
                    247:                     if (!b)
                    248:                     {
                    249:                         // If we failed, stop immediately, so we can fall back
                    250:                         // to bHandleNonCachedFonts. Otherwise, if we just blew
                    251:                         // the cache, the next call in this loop will succeed,
                    252:                         // and we'll never redo this rectangle properly. Note
                    253:                         // that this is very inefficient, forcing the whole
                    254:                         // rest of the call to go through
                    255:                         // bHandleNonCachedFonts
                    256:                         break;
                    257:                     }
                    258:                 }
                    259: 
                    260:             } while (bMore & b);
                    261:         }
                    262:     }
                    263: 
                    264:     // If something went wrong with rendering the string as a cached
                    265:     // font then render it as a large font.
                    266: 
                    267:     if (b == FALSE)
                    268:     {
                    269:         if (pco->iDComplexity != DC_COMPLEX)
                    270:         {
                    271:             b = bHandleNonCachedFonts(pso, pstro, pfo, &(pco->rclBounds),
                    272:                     prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
                    273: 
                    274:         }
                    275:         else
                    276:         {
                    277:             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
                    278: 
                    279:             do
                    280:             {
                    281:                 bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
                    282:                         (PULONG)&EnumRects8);
                    283: 
                    284:                 for (i = 0; i < EnumRects8.c; i++)
                    285:                 {
                    286:                     b = bHandleNonCachedFonts(pso, pstro, pfo,
                    287:                             &(EnumRects8.arcl[i]), prclExtra, prclOpaque,
                    288:                             pboFore, pboOpaque, pptlOrg, mix);
                    289:                 }
                    290: 
                    291:             } while (bMore);
                    292:         }
                    293: 
                    294:         vResetS3Clipping(ppdev);
                    295:     }
                    296: 
                    297:     return (b);
                    298: }
                    299: 
                    300: 
                    301: /****************************************************************************
                    302:  * bHandleCachedFonts
                    303:  ***************************************************************************/
                    304: BOOL bHandleCachedFonts(
                    305:     SURFOBJ  *pso,
                    306:     STROBJ   *pstro,
                    307:     RECTL    *prclClip,
                    308:     FONTOBJ  *pfo,
                    309:     RECTL    *prclOpaque,
                    310:     BRUSHOBJ *pboFore,
                    311:     BRUSHOBJ *pboOpaque,
                    312:     POINTL   *pptlOrg,
                    313:     MIX      mix)
                    314: {
                    315:     BOOL        b, bMoreGlyphs, bFound;
                    316:     ULONG       iGlyph, cGlyphs;
                    317:     POINTL      ptl;
                    318:     GLYPHPOS    *pgp;
                    319:     INT         ihGlyph, cxGlyph, cyGlyph;
                    320:     PCACHEDGLYPH pCachedGlyphs, pcg, pcgNew;
                    321:     WORD        Cmd;
                    322:     XYZPOINTL   xyzGlyph;
                    323:     PCACHEDFONT pCachedFont;
                    324:     PPDEV       ppdev;
                    325:     INT         i, culRcl;
                    326:     ULONG       flAccel;
                    327:     RECTL       arclTmp[4];
                    328:     ULONG       ulCharInc;
                    329:     ULONG       yMonoStart, xMonoPosition;
                    330:     POINTL      ptlSrc;
                    331:     RECTL       rclGlyph;
                    332:     HGLYPH      hg;
                    333:     GLYPHBITS   *pgb;
                    334:     ULONG       fl = 0;
                    335:     BYTE        jBackgroundRop;
                    336: 
                    337:     DISPDBG((4, "S3.DLL:bHandleCachedFonts - Entry\n"));
                    338: 
                    339:     ppdev = (PPDEV) pso->dhpdev;
                    340: 
                    341:     //
                    342:     // If we have seen this font before then pvConsumer will be non-NULL.
                    343:     //
                    344: 
                    345:     if (((pCachedFont = ((PCACHEDFONT) pfo->pvConsumer)) != NULL))
                    346:     {
                    347:         pCachedGlyphs = pCachedFont->pCachedGlyphs;
                    348: 
                    349:         if (pfo->iUniq != pCachedFont->iUniq)
                    350:         {
                    351:             DISPDBG((1, "S3.DLL: pfo->iUniq: %x, pCachedFont->iUniq: %x\n",
                    352:                                  pfo->iUniq, pCachedFont->iUniq));
                    353:             return (FALSE);
                    354:         }
                    355:     }
                    356: 
                    357:     else
                    358:     {
                    359:         DISPDBG((2, "S3.DLL!bHandleCachedFonts - Caching Font: %d\n", pfo->iUniq));
                    360: 
                    361:         pCachedGlyphs = pCacheFont(ppdev, pstro, pfo, &pCachedFont);
                    362: 
                    363:         if (pCachedGlyphs == NULL)
                    364:         {
                    365:             DISPDBG((1, "S3.DLL!bHandleCachedFonts - pCacheFont failed once\n"));
                    366: 
                    367:             vBlowCache(ppdev);
                    368: 
                    369:             pCachedGlyphs = pCacheFont(ppdev, pstro, pfo, &pCachedFont);
                    370:             if (pCachedGlyphs == NULL)
                    371:             {
                    372:                 DISPDBG((1, "S3.DLL!bHandleCachedFonts - pCacheFont failed twice\n"));
                    373:                 return(FALSE);
                    374:             }
                    375:         }
                    376: 
                    377:         (PCACHEDFONT)(pfo->pvConsumer) = pCachedFont;
                    378:     }
                    379: 
                    380:     // If this string has a Zero Bearing and the string object's
                    381:     // opaque rectangle is the same size as the opaque rectangle then
                    382:     // and opaque mode is requested, then lay down the glyphs in
                    383:     // opaque mode.
                    384: 
                    385:     if (((flAccel = pstro->flAccel) & SO_ZERO_BEARINGS) &&
                    386:         ((flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) == SO_HORIZONTAL) &&
                    387:         (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) &&
                    388:         (prclOpaque != NULL))
                    389:     {
                    390:         // If the Opaque rect and the string rect match then
                    391:         // were done.  If not then we have to fill in the strips
                    392:         // (top, bottom, left, and right) around the text.
                    393: 
                    394:         culRcl = 0;
                    395: 
                    396:         // Top fragment
                    397: 
                    398:         if (pstro->rclBkGround.top > prclOpaque->top)
                    399:         {
                    400:             arclTmp[culRcl].top      = prclOpaque->top;
                    401:             arclTmp[culRcl].left     = prclOpaque->left;
                    402:             arclTmp[culRcl].right    = prclOpaque->right;
                    403:             arclTmp[culRcl++].bottom = pstro->rclBkGround.top;
                    404:         }
                    405: 
                    406:         // Left fragment
                    407: 
                    408:         if (pstro->rclBkGround.left > prclOpaque->left)
                    409:         {
                    410:             arclTmp[culRcl].top      = pstro->rclBkGround.top;
                    411:             arclTmp[culRcl].left     = prclOpaque->left;
                    412:             arclTmp[culRcl].right    = pstro->rclBkGround.left;
                    413:             arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    414:         }
                    415: 
                    416:         // Right fragment
                    417: 
                    418:         if (pstro->rclBkGround.right < prclOpaque->right)
                    419:         {
                    420:             arclTmp[culRcl].top      = pstro->rclBkGround.top;
                    421:             arclTmp[culRcl].right    = prclOpaque->right;
                    422:             arclTmp[culRcl].left     = pstro->rclBkGround.right;
                    423:             arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    424:         }
                    425: 
                    426:         // Bottom fragment
                    427: 
                    428:         if (pstro->rclBkGround.bottom < prclOpaque->bottom)
                    429:         {
                    430:             arclTmp[culRcl].bottom = prclOpaque->bottom;
                    431:             arclTmp[culRcl].left   = prclOpaque->left;
                    432:             arclTmp[culRcl].right  = prclOpaque->right;
                    433:             arclTmp[culRcl++].top  = pstro->rclBkGround.bottom;
                    434:         }
                    435: 
                    436:         // Fill any fringe rectangles we found
                    437: 
                    438:         for (i = 0; i < culRcl; i++)
                    439:         {
                    440:             bOpaqueRect(ppdev, &(arclTmp[i]), prclClip, pboOpaque);
                    441:         }
                    442: 
                    443:         // Set the mix mode for opaque text.
                    444: 
                    445:         mix = (mix & 0x0F) | (R2_COPYPEN << 8);
                    446:         b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    447:         if (b == FALSE)
                    448:             return (b);
                    449: 
                    450:     }
                    451:     else
                    452:     {
                    453:         // Take care of any opaque rectangles.
                    454: 
                    455:         if (prclOpaque != NULL)
                    456:         {
                    457:             bOpaqueRect(ppdev, prclOpaque, prclClip, pboOpaque);
                    458:         }
                    459: 
                    460:         jBackgroundRop = R2_NOP;
                    461: 
                    462:         // Take care of the glyph attributes, color and mix.
                    463: 
                    464:         mix = (mix & 0x0F) | (jBackgroundRop << 8);
                    465:         b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    466:         if (b == FALSE)
                    467:             return (b);
                    468:     }
                    469: 
                    470:     // Test for a trivial accept of the string rect.
                    471: 
                    472:     if (bTrivialAcceptTest(&(pstro->rclBkGround), prclClip))
                    473:         fl |= TRIVIAL_ACCEPT;
                    474: 
                    475:     // Test and setup for a mono-spaced font.
                    476: 
                    477:     if ((ulCharInc = pstro->ulCharInc) != 0)
                    478:         fl |= MONO_SPACED_FONT;
                    479: 
                    480:     // Set the S3 command.
                    481: 
                    482:     Cmd  = BITBLT         | DRAW               | DIR_TYPE_XY | WRITE |
                    483:            MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
                    484: 
                    485:     // This does not change in the inner loop so it is now out of it.
                    486: 
                    487:     FIFOWAIT(FIFO_1_EMPTY);
                    488:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
                    489: 
                    490:     // Get the Glyph Handles.
                    491: 
                    492:     if ((pstro->pgp) == NULL)
                    493:         STROBJ_vEnumStart(pstro);
                    494: 
                    495:     do
                    496:     {
                    497:         if (pstro->pgp == NULL)
                    498:         {
                    499:             bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
                    500: 
                    501:         }
                    502:         else
                    503:         {
                    504:             pgp = pstro->pgp;
                    505:             cGlyphs = pstro->cGlyphs;
                    506:             bMoreGlyphs = FALSE;
                    507:         }
                    508: 
                    509:         // For mono space fonts this is non-zero.
                    510: 
                    511:         if (fl & MONO_SPACED_FONT)
                    512:         {
                    513:             xMonoPosition = pgp[0].ptl.x;
                    514:             yMonoStart    = pgp[0].ptl.y;
                    515:         }
                    516: 
                    517:         for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
                    518:         {
                    519:             // Get the Glyph Handle.
                    520:             // If there was a hash table hit for the glygph
                    521:             // then were "golden", if not then we have to search
                    522:             // the collision list.
                    523: 
                    524:             ihGlyph = pgp[iGlyph].hg & pCachedFont->cGlyphs;
                    525: 
                    526:             pcg = &(pCachedGlyphs[ihGlyph]);
                    527: 
                    528:             if ((hg = pgp[iGlyph].hg) != pcg->hg)
                    529:             {
                    530:                 if (!(pcg->fl & VALID_GLYPH))
                    531:                 {
                    532:                     // Allocate a place in the cache.
                    533: 
                    534:                     pgb = pgp[iGlyph].pgdf->pgb;
                    535:                     b = bAllocateGlyph(ppdev, hg, pgb, pcg);
                    536:                     if (b == FALSE)
                    537:                     {
                    538:                         vBlowCache(ppdev);
                    539:                         return (FALSE);
                    540:                     }
                    541: 
                    542:                     b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    543:                     if (b == FALSE)
                    544:                         return (FALSE);
                    545: 
                    546:                     FIFOWAIT(FIFO_1_EMPTY);
                    547:                     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
                    548: 
                    549:                 }
                    550:                 else
                    551:                 {
                    552:                     // Search the collision list.
                    553: 
                    554:                     DISPDBG((1, "S3.DLL!bHandleCachedFonts - searching collision list\n"));
                    555: 
                    556:                     bFound = FALSE;
                    557:                     while (pcg->pcgCollisionLink != END_COLLISIONS)
                    558:                     {
                    559:                         pcg = pcg->pcgCollisionLink;
                    560: 
                    561:                         if (pcg->hg == pgp[iGlyph].hg)
                    562:                         {
                    563:                             bFound = TRUE;
                    564:                             break;
                    565:                         }
                    566:                     }
                    567: 
                    568:                     if (!bFound)
                    569:                     {
                    570:                         // Allocate a new font glyph node.
                    571: 
                    572:                         pcgNew = (PCACHEDGLYPH) LocalAlloc(LPTR, sizeof(CACHEDGLYPH));
                    573:                         if (pcgNew == NULL)
                    574:                         {
                    575:                             DISPDBG((1, "S3.DLL!bHandleCachedFont - Local Alloc (pcgNew) failed\n"));
                    576:                             return (FALSE);
                    577:                         }
                    578: 
                    579:                         // Connect the end of the collision list to the new
                    580:                         // glyph node.
                    581: 
                    582:                         pcg->pcgCollisionLink = pcgNew;
                    583: 
                    584:                         // Set up the pointer to the node where going to init.
                    585: 
                    586:                         pcg = pcgNew;
                    587: 
                    588:                         pgb = pgp[iGlyph].pgdf->pgb;
                    589:                         b = bAllocateGlyph(ppdev, hg, pgb, pcg);
                    590:                         if (b == FALSE)
                    591:                         {
                    592:                             vBlowCache(ppdev);
                    593:                             return (FALSE);
                    594:                         }
                    595: 
                    596:                         b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    597:                         if (b == FALSE)
                    598:                             return (FALSE);
                    599: 
                    600:                         FIFOWAIT(FIFO_1_EMPTY);
                    601:                         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
                    602: 
                    603:                     }
                    604:                 }
                    605:             }
                    606: 
                    607:             // Adjust the placement of the glyph.
                    608:             // And if this is a mono-spaced font set the blt height & width.
                    609: 
                    610:             if (fl & MONO_SPACED_FONT)
                    611:             {
                    612:                 ptl.x = xMonoPosition + pcg->ptlOrigin.x;
                    613:                 ptl.y = yMonoStart + pcg->ptlOrigin.y;
                    614:                 xMonoPosition += ulCharInc;
                    615: 
                    616:                 if ((!(fl & MONO_SIZE_VALID) && (fl & TRIVIAL_ACCEPT)) ||
                    617:                     (!(fl & MONO_FIRST_TIME)))
                    618:                 {
                    619:                     fl |= MONO_SIZE_VALID;
                    620: 
                    621:                     TFIFOWAIT(FIFO_2_EMPTY);
                    622:                     OUTPW(RECT_WIDTH, pcg->sizlBitmap.cx - 1);
                    623:                     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (pcg->sizlBitmap.cy - 1)));
                    624:                 }
                    625: 
                    626:             }
                    627:             else
                    628:             {
                    629:                 ptl.x = pgp[iGlyph].ptl.x + pcg->ptlOrigin.x;
                    630:                 ptl.y = pgp[iGlyph].ptl.y + pcg->ptlOrigin.y;
                    631:             }
                    632: 
                    633:             if (fl & TRIVIAL_ACCEPT)
                    634:             {
                    635:                 // Blit the glyph
                    636: 
                    637:                 if (!(fl & MONO_SPACED_FONT))
                    638:                 {
                    639:                     TFIFOWAIT(FIFO_2_EMPTY);
                    640:                     OUTPW(RECT_WIDTH, pcg->sizlBitmap.cx - 1);
                    641:                     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (pcg->sizlBitmap.cy - 1)));
                    642:                 }
                    643: 
                    644:                 TFIFOWAIT(FIFO_6_EMPTY);
                    645:                 TEST_AND_SET_RD_MASK(LOWORD(pcg->xyzGlyph.z));
                    646: 
                    647:                 OUTPW(CUR_X, pcg->xyzGlyph.x);
                    648:                 OUTPW(CUR_Y, pcg->xyzGlyph.y);
                    649:                 OUTPW(DEST_X, ptl.x);
                    650:                 OUTPW(DEST_Y, ptl.y);
                    651:                 OUTPW(CMD, Cmd);
                    652: 
                    653:             }
                    654:             else
                    655:             {
                    656:                 xyzGlyph = pcg->xyzGlyph;
                    657: 
                    658:                 // Clip each character,
                    659: 
                    660:                 rclGlyph.left   = ptl.x;
                    661:                 rclGlyph.top    = ptl.y;
                    662:                 rclGlyph.right  = ptl.x + pcg->sizlBitmap.cx;
                    663:                 rclGlyph.bottom = ptl.y + pcg->sizlBitmap.cy;
                    664: 
                    665:                 if (bIntersectTest(&rclGlyph, prclClip))
                    666:                 {
                    667:                     rclGlyph.left   = max (rclGlyph.left,   prclClip->left);
                    668:                     rclGlyph.top    = max (rclGlyph.top,    prclClip->top);
                    669:                     rclGlyph.right  = min (rclGlyph.right,  prclClip->right);
                    670:                     rclGlyph.bottom = min (rclGlyph.bottom, prclClip->bottom);
                    671: 
                    672:                     cxGlyph  = (rclGlyph.right - rclGlyph.left) -  1;
                    673:                     cyGlyph  = (rclGlyph.bottom - rclGlyph.top) - 1;
                    674: 
                    675:                     if (cxGlyph < 0 || cyGlyph < 0)
                    676:                         continue;
                    677: 
                    678:                     ptlSrc.x = xyzGlyph.x + (rclGlyph.left - ptl.x);
                    679:                     ptlSrc.y = xyzGlyph.y + (rclGlyph.top - ptl.y);
                    680: 
                    681:                     // Blit the glyph
                    682: 
                    683:                     TFIFOWAIT(FIFO_8_EMPTY);
                    684:                     TEST_AND_SET_RD_MASK(LOWORD(pcg->xyzGlyph.z));
                    685: 
                    686:                     OUTPW(RECT_WIDTH, cxGlyph);
                    687:                     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph));
                    688:                     OUTPW(CUR_X, ptlSrc.x);
                    689:                     OUTPW(CUR_Y, ptlSrc.y);
                    690:                     OUTPW(DEST_X, rclGlyph.left);
                    691:                     OUTPW(DEST_Y, rclGlyph.top);
                    692:                     OUTPW(CMD, Cmd);
                    693: 
                    694:                 }
                    695:                 else
                    696:                 {
                    697:                     continue;
                    698:                 }
                    699:             }
                    700:         }
                    701: 
                    702:     } while(bMoreGlyphs);
                    703: 
                    704:     return (TRUE);
                    705: 
                    706: }
                    707: 
                    708: 
                    709: /****************************************************************************
                    710:  * bHandleNonCachedFonts
                    711:  ***************************************************************************/
                    712: BOOL bHandleNonCachedFonts(
                    713:     SURFOBJ  *pso,
                    714:     STROBJ   *pstro,
                    715:     FONTOBJ  *pfo,
                    716:     RECTL    *prclClip,
                    717:     RECTL    *prclExtra,
                    718:     RECTL    *prclOpaque,
                    719:     BRUSHOBJ *pboFore,
                    720:     BRUSHOBJ *pboOpaque,
                    721:     POINTL   *pptlOrg,
                    722:     MIX      mix)
                    723: {
                    724:     BOOL        b,
                    725:                 bMoreGlyphs;
                    726:     ULONG       iGlyph,
                    727:                 cGlyphs;
                    728:     GLYPHBITS   *pgb;
                    729:     POINTL      ptl;
                    730:     GLYPHPOS    *pgp;
                    731:     LONG        cyGlyph,
                    732:                 cjGlyph,
                    733:                 GlyphBmPitchInBytes;
                    734:     WORD        S3Cmd;
                    735:     INT         i, culRcl;
                    736:     ULONG       flAccel;
                    737:     RECTL       arclTmp[4];
                    738: 
                    739:     ULONG       ulCharInc;
                    740:     ULONG       yMonoStart, xMonoPosition;
                    741:     PPDEV       ppdev;
                    742:     BYTE        jBackgroundRop;
                    743:     RECTL       rclClip;
                    744: 
                    745:     ULONG       fl = 0;
                    746: 
                    747:     DISPDBG((4, "S3.DLL!bHandleNonCachedFonts\n"));
                    748: 
                    749:     ppdev = (PPDEV) pso->dhpdev;
                    750: 
                    751:     // We need to reset the clipping so any opaque rectangles are
                    752:     // rendered correctly.
                    753: 
                    754:     vResetS3Clipping(ppdev);
                    755: 
                    756:     // If this string has a Zero Bearing and the string object's
                    757:     // opaque rectangle is the same size as the opaque rectangle then
                    758:     // and opaque mode is requested, then lay down the glyphs in
                    759:     // opaque mode.
                    760: 
                    761:     if (((flAccel = pstro->flAccel) & SO_ZERO_BEARINGS) &&
                    762:         ((flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) == SO_HORIZONTAL) &&
                    763:         (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) &&
                    764:         (prclOpaque != NULL))
                    765:     {
                    766:         // If the Opaque rect and the string rect match then
                    767:         // were done.  If not then we have to fill in the strips
                    768:         // (top, bottom, left, and right) around the text.
                    769: 
                    770:         culRcl = 0;
                    771: 
                    772:         // Top fragment
                    773: 
                    774:         if (pstro->rclBkGround.top > prclOpaque->top)
                    775:         {
                    776:             arclTmp[culRcl].top      = prclOpaque->top;
                    777:             arclTmp[culRcl].left     = prclOpaque->left;
                    778:             arclTmp[culRcl].right    = prclOpaque->right;
                    779:             arclTmp[culRcl++].bottom = pstro->rclBkGround.top;
                    780:         }
                    781: 
                    782:         // Left fragment
                    783: 
                    784:         if (pstro->rclBkGround.left > prclOpaque->left)
                    785:         {
                    786:             arclTmp[culRcl].top      = pstro->rclBkGround.top;
                    787:             arclTmp[culRcl].left     = prclOpaque->left;
                    788:             arclTmp[culRcl].right    = pstro->rclBkGround.left;
                    789:             arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    790:         }
                    791: 
                    792:         // Right fragment
                    793: 
                    794:         if (pstro->rclBkGround.right < prclOpaque->right)
                    795:         {
                    796:             arclTmp[culRcl].top      = pstro->rclBkGround.top;
                    797:             arclTmp[culRcl].right    = prclOpaque->right;
                    798:             arclTmp[culRcl].left     = pstro->rclBkGround.right;
                    799:             arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    800:         }
                    801: 
                    802:         // Bottom fragment
                    803: 
                    804:         if (pstro->rclBkGround.bottom < prclOpaque->bottom)
                    805:         {
                    806:             arclTmp[culRcl].bottom = prclOpaque->bottom;
                    807:             arclTmp[culRcl].left   = prclOpaque->left;
                    808:             arclTmp[culRcl].right  = prclOpaque->right;
                    809:             arclTmp[culRcl++].top  = pstro->rclBkGround.bottom;
                    810:         }
                    811: 
                    812:         // Fill any fringe rectangles we found
                    813: 
                    814:         for (i = 0; i < culRcl; i++)
                    815:         {
                    816:             bOpaqueRect(ppdev, &(arclTmp[i]), prclClip, pboOpaque);
                    817:         }
                    818: 
                    819:         // Set the mix mode for opaque text.
                    820: 
                    821:         mix = (mix & 0x0F) | (R2_COPYPEN << 8);
                    822:         b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    823:         if (b == FALSE)
                    824:             return (b);
                    825:     }
                    826:     else
                    827:     {
                    828:         // Take care of any opaque rectangles.
                    829: 
                    830:         if (prclOpaque != NULL)
                    831:         {
                    832:             bOpaqueRect(ppdev, prclOpaque, prclClip, pboOpaque);
                    833:         }
                    834: 
                    835:         jBackgroundRop = R2_NOP;
                    836: 
                    837:         // Take care of the glyph attributes, color and mix.
                    838: 
                    839:         mix = (mix & 0x0F) | (jBackgroundRop << 8);
                    840:         b = bSetS3TextColorAndMix(ppdev, mix, pboFore, pboOpaque);
                    841:         if (b == FALSE)
                    842:             return (b);
                    843:     }
                    844: 
                    845:     rclClip = *prclClip;
                    846:     rclClip.bottom;
                    847:     rclClip.right;
                    848:     vSetS3ClipRect(ppdev, &rclClip);
                    849: 
                    850:     // Test and setup for a mono-spaced font.
                    851: 
                    852:     if ((ulCharInc = pstro->ulCharInc) != 0)
                    853:         fl |= MONO_SPACED_FONT;
                    854: 
                    855:     // Setup the Command Word for the S3.
                    856: 
                    857:     S3Cmd = RECTANGLE_FILL  | BUS_SIZE_8         |
                    858:             WAIT            | DRAWING_DIR_TBLRXM | DRAW |
                    859:             LAST_PIXEL_ON   | MULTIPLE_PIXELS    | WRITE;
                    860: 
                    861:     FIFOWAIT(FIFO_2_EMPTY)
                    862: 
                    863:     // Enable the write mask for all planes.
                    864:     // and set the S3 for CPU Data.
                    865: 
                    866:     TEST_AND_SET_WRT_MASK(0xFF);
                    867:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
                    868: 
                    869:     // Get the Glyph Handles.
                    870: 
                    871:     if ((pstro->pgp) == NULL)
                    872:         STROBJ_vEnumStart(pstro);
                    873: 
                    874:     do
                    875:     {
                    876:         if (pstro->pgp == NULL)
                    877:         {
                    878:             bMoreGlyphs = STROBJ_bEnum(pstro, &cGlyphs, &pgp);
                    879:         }
                    880:         else
                    881:         {
                    882:             pgp = pstro->pgp;
                    883:             cGlyphs = pstro->cGlyphs;
                    884:             bMoreGlyphs = FALSE;
                    885:         }
                    886: 
                    887:         // For mono space fonts this is non-zero.
                    888: 
                    889:         if (fl & MONO_SPACED_FONT)
                    890:         {
                    891:             xMonoPosition = pgp[0].ptl.x;
                    892:             yMonoStart    = pgp[0].ptl.y;
                    893:         }
                    894: 
                    895:         for (iGlyph = 0; iGlyph < cGlyphs; iGlyph++)
                    896:         {
                    897:             // Get a pointer to the GlyphBits.
                    898: 
                    899:             pgb = pgp[iGlyph].pgdf->pgb;
                    900: 
                    901:             // Adjust the placement of the glyph.
                    902:             // If this is a mono-spaced font set the blt height & width only
                    903:             // once for the string.
                    904: 
                    905:             if (fl & MONO_SPACED_FONT)
                    906:             {
                    907:                 ptl.x = xMonoPosition + pgb->ptlOrigin.x;
                    908:                 ptl.y = yMonoStart + pgb->ptlOrigin.y;
                    909:                 xMonoPosition += ulCharInc;
                    910: 
                    911:                 if (!(fl & MONO_SIZE_VALID))
                    912:                 {
                    913:                     fl |= MONO_SIZE_VALID;
                    914: 
                    915:                     // Calculate the number of bytes in this glyph.
                    916: 
                    917:                     cyGlyph = pgb->sizlBitmap.cy;
                    918: 
                    919:                     GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
                    920:                     cjGlyph = GlyphBmPitchInBytes * cyGlyph;
                    921: 
                    922:                     TFIFOWAIT(FIFO_2_EMPTY);
                    923:                     OUTPW(RECT_WIDTH, pgb->sizlBitmap.cx - 1);
                    924:                     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
                    925:                 }
                    926: 
                    927:                 FIFOWAIT(FIFO_3_EMPTY)
                    928:             }
                    929:             else
                    930:             {
                    931:                 ptl.x = pgp[iGlyph].ptl.x + pgb->ptlOrigin.x;
                    932:                 ptl.y = pgp[iGlyph].ptl.y + pgb->ptlOrigin.y;
                    933: 
                    934:                 // Calculate the number of bytes in this glyph.
                    935: 
                    936:                 cyGlyph = pgb->sizlBitmap.cy;
                    937: 
                    938:                 GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
                    939:                 cjGlyph = GlyphBmPitchInBytes * cyGlyph;
                    940: 
                    941:                 FIFOWAIT(FIFO_5_EMPTY)
                    942: 
                    943:                 // Set up for the image transfer.
                    944: 
                    945:                 OUTPW(RECT_WIDTH, pgb->sizlBitmap.cx - 1);
                    946:                 OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
                    947:             }
                    948: 
                    949:             // If a character is way off to the left then continue
                    950: 
                    951:             if ((ptl.x < 0) && ((ptl.x + pgb->sizlBitmap.cx) < 0))
                    952:                 continue;
                    953: 
                    954:             // Yes, believe it or not we have to check for chipping on the right also.
                    955: 
                    956:             if ((ptl.x > (LONG) ppdev->cxScreen) && ((ptl.x + pgb->sizlBitmap.cx) > (LONG) ppdev->cxScreen))
                    957:                 continue;
                    958: 
                    959:             // Set up for the image transfer.
                    960: 
                    961:             OUTPW(CUR_X, LOWORD(ptl.x));
                    962:             OUTPW(CUR_Y, LOWORD(ptl.y));
                    963: 
                    964:             GPWAIT();
                    965: 
                    966:             OUTPW(CMD, S3Cmd);
                    967: 
                    968:             CHECK_DATA_READY;
                    969: 
                    970:             vDataPortOutB(ppdev, pgb->aj, cjGlyph);
                    971: 
                    972:             CHECK_DATA_COMPLETE;
                    973: 
                    974:         }
                    975: 
                    976:     } while(bMoreGlyphs);
                    977: 
                    978:     return (TRUE);
                    979: 
                    980: }
                    981: 
                    982: 
                    983: /*****************************************************************************
                    984:  * S3 Solid Opaque Rect.
                    985:  *
                    986:  *  Returns TRUE if the Opaque Rect was handled.
                    987:  ****************************************************************************/
                    988: BOOL bOpaqueRect(
                    989:     PPDEV ppdev,
                    990:     RECTL *prclOpaque,
                    991:     RECTL *prclBounds,
                    992:     BRUSHOBJ *pboOpaque)
                    993: {
                    994:     INT     width, height;
                    995:     WORD    S3Cmd;
                    996:     ULONG   iSolidColor;
                    997:     RECTL   rclClipped;
                    998:     BOOL    bClipRequired;
                    999: 
                   1000:     DISPDBG((4, "S3.DLL!bOpaqueRect - Entry\n"));
                   1001: 
                   1002:     rclClipped = *prclOpaque;
                   1003: 
                   1004:     // First handle the trivial rejection.
                   1005: 
                   1006:     bClipRequired = bIntersectTest(&rclClipped, prclBounds);
                   1007: 
                   1008:     // define the clipped target rectangle.
                   1009: 
                   1010:     if (bClipRequired)
                   1011:     {
                   1012:         rclClipped.left   = max (rclClipped.left,   prclBounds->left);
                   1013:         rclClipped.top    = max (rclClipped.top,    prclBounds->top);
                   1014:         rclClipped.right  = min (rclClipped.right,  prclBounds->right);
                   1015:         rclClipped.bottom = min (rclClipped.bottom, prclBounds->bottom);
                   1016:     }
                   1017:     else
                   1018:         return (TRUE);
                   1019: 
                   1020:     // Set the color
                   1021: 
                   1022:     iSolidColor = pboOpaque->iSolidColor;
                   1023:     if (iSolidColor == -1)
                   1024:         return(FALSE);
                   1025: 
                   1026:     width  = (rclClipped.right - rclClipped.left) - 1;
                   1027:     height = (rclClipped.bottom - rclClipped.top) - 1;
                   1028: 
                   1029:     if (width >= 0 && height >= 0)
                   1030:     {
                   1031: 
                   1032:         FIFOWAIT(FIFO_8_EMPTY)
                   1033: 
                   1034:         TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
                   1035:         TEST_AND_SET_FRGD_COLOR(LOWORD(iSolidColor));
                   1036:         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                   1037:         OUTPW(CUR_X, LOWORD(rclClipped.left));
                   1038:         OUTPW(CUR_Y, LOWORD(rclClipped.top));
                   1039:         OUTPW(RECT_WIDTH, width);
                   1040:         OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | height));
                   1041: 
                   1042:         S3Cmd = RECTANGLE_FILL  | DRAWING_DIR_TBLRXM | DRAW |
                   1043:                 DIR_TYPE_XY     | LAST_PIXEL_ON      |
                   1044:                 MULTIPLE_PIXELS | WRITE;
                   1045: 
                   1046:         OUTPW(CMD, S3Cmd);
                   1047:     }
                   1048: 
                   1049:     return (TRUE);
                   1050: }
                   1051: 
                   1052: 
                   1053: 
                   1054: /******************************************************************************
                   1055:  * bSetS3TextColorAndMix - Setup the S3's Text Colors and mix modes
                   1056:  *
                   1057:  *  Note: We will always set the mode to transparent.  We will assume the
                   1058:  *        opaque rectangle will take care of any opaqueing we may need.
                   1059:  *****************************************************************************/
                   1060: BOOL bSetS3TextColorAndMix(
                   1061:     PPDEV ppdev,
                   1062:     MIX mix,
                   1063:     BRUSHOBJ *pboFore,
                   1064:     BRUSHOBJ *pboOpaque)
                   1065: {
                   1066:     ULONG       ulForeSolidColor, ulBackSolidColor;
                   1067:     BYTE        jS3ForeMix, jS3BackMix;
                   1068: 
                   1069:     // Pickup all the glyph attributes.
                   1070: 
                   1071:     jS3ForeMix       = Rop2ToS3Rop[(mix & 0xF) - R2_BLACK];
                   1072:     ulForeSolidColor = pboFore->iSolidColor;
                   1073: 
                   1074:     jS3BackMix       = Rop2ToS3Rop[((mix >> 8) & 0xF) - R2_BLACK];
                   1075:     ulBackSolidColor = pboOpaque->iSolidColor;
                   1076: 
                   1077:     // For now let the engine handle the non-solid brush cases. !!!
                   1078:     // We should use S3 when we get some more time !!!
                   1079: 
                   1080:     if (ulForeSolidColor == -1 || ulBackSolidColor == -1)
                   1081:         return(FALSE);
                   1082: 
                   1083:     FIFOWAIT(FIFO_4_EMPTY)
                   1084: 
                   1085:     // Set the S3 Attributes.
                   1086: 
                   1087:     TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | jS3ForeMix);
                   1088:     TEST_AND_SET_FRGD_COLOR(LOWORD(ulForeSolidColor));
                   1089: 
                   1090:     TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | jS3BackMix);
                   1091:     TEST_AND_SET_BKGD_COLOR(LOWORD(ulBackSolidColor));
                   1092: 
                   1093:     return (TRUE);
                   1094: 
                   1095: }
                   1096: 
                   1097: /*****************************************************************************
                   1098:  * pCacheFont - Make sure the glyphs we need in this font are cached.
                   1099:  *              Return a pointer to the array of glyph caches.
                   1100:  *
                   1101:  *              if there is an error, return NULL.
                   1102:  ****************************************************************************/
                   1103: PCACHEDGLYPH pCacheFont(
                   1104:     PPDEV ppdev,
                   1105:     STROBJ *pstro,
                   1106:     FONTOBJ  *pfo,
                   1107:     PCACHEDFONT *ppCachedFont)
                   1108: {
                   1109:     FONTINFO    fi;
                   1110:     PCACHEDFONT pCachedFont;
                   1111:     ULONG       cFntGlyphs;
                   1112:     UINT        nSize;
                   1113: 
                   1114:     BOOL    bFoundBit, bEven;
                   1115:     ULONG   mask, mask1;
                   1116:     INT     i, j;
                   1117: 
                   1118:     DISPDBG((3, "S3.DLL!pCacheFont - Entry\n"));
                   1119: 
                   1120:     // Allocate a Font Cache node.
                   1121: 
                   1122:     pCachedFont = (PCACHEDFONT) LocalAlloc(LPTR, sizeof(CACHEDFONT));
                   1123:     if (pCachedFont == NULL)
                   1124:     {
                   1125:         DISPDBG((1, "S3.DLL!pCacheFont - LocalAlloc of pCachedFont failed\n"));
                   1126:         return(NULL);
                   1127:     }
                   1128: 
                   1129:     // Add this font to the beginning of the font list.
                   1130: 
                   1131:     pCachedFont->pcfNext = pCachedFontsRoot;
                   1132:     pCachedFontsRoot     = pCachedFont;
                   1133: 
                   1134:     // Set the font ID for the font.
                   1135: 
                   1136:     pCachedFont->iUniq = pfo->iUniq;
                   1137: 
                   1138:     // Allocate the glyph cache.
                   1139: 
                   1140:     FONTOBJ_vGetInfo(pfo, sizeof(FONTINFO), &fi);
                   1141:     cFntGlyphs = fi.cGlyphsSupported;
                   1142: 
                   1143:     // This is where we clamp the size of the Font structures we are allocating.
                   1144: 
                   1145:     if (cFntGlyphs > MAX_GLYPHS_TO_ALLOC)
                   1146:         cFntGlyphs = MAX_GLYPHS_TO_ALLOC;
                   1147: 
                   1148:     // Round up to the next power of 2.
                   1149: 
                   1150:     bFoundBit = FALSE;
                   1151:     mask = 0x80000000;
                   1152:     for (i = 32; i != 0 && !bFoundBit; i--)
                   1153:     {
                   1154:         if (cFntGlyphs & mask)
                   1155:         {
                   1156:             bFoundBit = TRUE;
                   1157:             mask1 = mask >> 1;
                   1158:             bEven = TRUE;
                   1159:             for (j = i - 1; j != 0; j--)
                   1160:             {
                   1161:                 if (cFntGlyphs & mask1 )
                   1162:                 {
                   1163:                     bEven = FALSE;
                   1164:                     break;
                   1165:                 }
                   1166:                 mask1 >>= 1;
                   1167:             }
                   1168:         }
                   1169:         else
                   1170:             mask >>= 1;
                   1171:     }
                   1172: 
                   1173:     if (bEven)
                   1174:         cFntGlyphs = mask;
                   1175:     else
                   1176:         cFntGlyphs = mask << 1;
                   1177: 
                   1178:     // Get the font info.
                   1179: 
                   1180:     pCachedFont->cGlyphs = cFntGlyphs - 1;
                   1181: 
                   1182:     // Allocate memory for the CachedGlyphs of this font.
                   1183: 
                   1184:     nSize = cFntGlyphs * sizeof(CACHEDGLYPH);
                   1185: 
                   1186:     pCachedFont->pCachedGlyphs = (PCACHEDGLYPH) LocalAlloc(LPTR, nSize);
                   1187:     if (pCachedFont->pCachedGlyphs == NULL)
                   1188:     {
                   1189:         DISPDBG((1, "S3.DLL!pCacheFont - LocalAlloc of pCachedGlyphs failed\n"));
                   1190:         pCachedFont->cGlyphs = 0;
                   1191:         return(NULL);
                   1192:     }
                   1193: 
                   1194:     pCachedFont->pCachedGlyphs[0].hg = (HGLYPH)-1;
                   1195: 
                   1196:     // Return the pointer to the cached font.  This is required
                   1197:     // by the collision handling code.
                   1198: 
                   1199:     *ppCachedFont = pCachedFont;
                   1200: 
                   1201:     return(pCachedFont->pCachedGlyphs);
                   1202: 
                   1203: }
                   1204: 
                   1205: 
                   1206: /*****************************************************************************
                   1207:  * bAllocateGlyph - Allocate and initialize the cached glyph
                   1208:  ****************************************************************************/
                   1209: BOOL bAllocateGlyph(
                   1210:     PPDEV ppdev,
                   1211:     HGLYPH hg,
                   1212:     GLYPHBITS *pgb,
                   1213:     PCACHEDGLYPH pcg)
                   1214: {
                   1215:     BOOL   b;
                   1216:     ULONG  cyGlyph, GlyphBmPitchInPels, GlyphBmPitchInBytes;
                   1217:     XYZPOINTL  xyzGlyph;
                   1218:     WORD  Cmd;
                   1219: 
                   1220:     DISPDBG((3, "S3.DLL!bAllocateGlyph - Entry\n"));
                   1221: 
                   1222:     cyGlyph = pgb->sizlBitmap.cy;
                   1223: 
                   1224:     GlyphBmPitchInBytes = CJ_SCAN(pgb->sizlBitmap.cx);
                   1225:     GlyphBmPitchInPels  = GlyphBmPitchInBytes * 8;
                   1226: 
                   1227:     // Allocate memory for the glyph data on the S3.
                   1228: 
                   1229:     b = bAllocGlyphMemory(ppdev, &(pgb->sizlBitmap), &xyzGlyph);
                   1230:     if (b == FALSE)
                   1231:     {
                   1232:         DISPDBG((1, "S3.DLL!bAllocateGlyph - hCpAlloc failed\n"));
                   1233:         return(FALSE);
                   1234:     }
                   1235: 
                   1236:     // Initialize the Glyph Cache node.
                   1237: 
                   1238:     pcg->fl              |= VALID_GLYPH;
                   1239:     pcg->hg               = hg;
                   1240:     pcg->pcgCollisionLink = END_COLLISIONS;
                   1241:     pcg->ptlOrigin        = pgb->ptlOrigin;
                   1242:     pcg->sizlBitmap       = pgb->sizlBitmap;
                   1243:     pcg->BmPitchInPels    = GlyphBmPitchInPels;
                   1244:     pcg->BmPitchInBytes   = GlyphBmPitchInBytes;
                   1245:     pcg->xyzGlyph         = xyzGlyph;
                   1246: 
                   1247:     // Initialize the Glyph Cache data in S3 memory.
                   1248: 
                   1249:     Cmd = RECTANGLE_FILL | BUS_SIZE_8         | WAIT |
                   1250:           DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                   1251:           LAST_PIXEL_ON  | MULTIPLE_PIXELS    | WRITE;
                   1252: 
                   1253:     // Setup the S3 chip.
                   1254: 
                   1255:     FIFOWAIT(FIFO_5_EMPTY);
                   1256: 
                   1257:     TEST_AND_SET_FRGD_MIX(LOGICAL_1);
                   1258:     TEST_AND_SET_BKGD_MIX(LOGICAL_0);
                   1259:     TEST_AND_SET_WRT_MASK(LOWORD(xyzGlyph.z));
                   1260:     OUTPW(CUR_X, xyzGlyph.x);
                   1261:     OUTPW(CUR_Y, xyzGlyph.y);
                   1262: 
                   1263:     FIFOWAIT(FIFO_4_EMPTY);
                   1264: 
                   1265:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
                   1266:     OUTPW(RECT_WIDTH, GlyphBmPitchInPels - 1);
                   1267:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyGlyph - 1));
                   1268:     GPWAIT();
                   1269:     OUTPW(CMD, Cmd);
                   1270: 
                   1271:     CHECK_DATA_READY;
                   1272: 
                   1273:     // Now transfer the data.
                   1274: 
                   1275:     vDataPortOutB(ppdev, pgb->aj, GlyphBmPitchInBytes * cyGlyph);
                   1276: 
                   1277:     CHECK_DATA_COMPLETE;
                   1278: 
                   1279:     // Need to reset the write mask.
                   1280: 
                   1281:     FIFOWAIT(FIFO_1_EMPTY);
                   1282: 
                   1283:     TEST_AND_SET_WRT_MASK(0xFF);
                   1284: 
                   1285:     return (TRUE);
                   1286: }
                   1287: 
                   1288: 
                   1289: /****************************************************************************
                   1290:  * vBlowCache - Blow Away the Cache
                   1291:  ***************************************************************************/
                   1292: VOID vBlowCache(PPDEV ppdev)
                   1293: {
                   1294:     PCACHEDFONT pcf;
                   1295:     PCACHEDGLYPH pcg, pcgNext;
                   1296:     INT nGlyphs, i;
                   1297: 
                   1298:     DISPDBG((2, "S3.DLL!vBlowCache - Entry\n"));
                   1299: 
                   1300:     // Traverse the CachedFonts list.
                   1301:     // Free the collision nodes, and invalidate the cached glyphs
                   1302: 
                   1303:     for (pcf = pCachedFontsRoot; pcf != NULL; pcf = pcf->pcfNext)
                   1304:     {
                   1305:         // If there are any collision nodes for this glyph
                   1306:         // free them.
                   1307: 
                   1308:         nGlyphs = pcf->cGlyphs+1;
                   1309: 
                   1310:         for (i = 0; i < nGlyphs; i++)
                   1311:         {
                   1312:             pcg = &(pcf->pCachedGlyphs[i]);
                   1313:             pcg = pcg->pcgCollisionLink;
                   1314:             for (; pcg != NULL; pcg = pcgNext)
                   1315:             {
                   1316:                 pcgNext = pcg->pcgCollisionLink;
                   1317:                 LocalFree(pcg);
                   1318:             }
                   1319:             pcf->pCachedGlyphs[i].pcgCollisionLink = NULL;
                   1320: 
                   1321:         }
                   1322: 
                   1323:         // Invalidate all the glyphs in the glyph array.
                   1324: 
                   1325:         pcg = pcf->pCachedGlyphs;
                   1326:         for (i = 0; i < nGlyphs; i++)
                   1327:         {
                   1328:             pcg[i].hg  = (HGLYPH) -1;
                   1329:             pcg[i].fl &= ~VALID_GLYPH;
                   1330:         }
                   1331:     }
                   1332: 
                   1333:     // Now ReInitialize the S3 Heap.
                   1334: 
                   1335:     memset((PVOID)ppdev->ajGlyphAllocBitVector,
                   1336:             0, CACHED_GLYPHS_ROWS * GLYPHS_PER_ROW);
                   1337: 
                   1338:     return;
                   1339: }
                   1340: 
                   1341: /******************************************************************************
                   1342:  * bAllocGlyphMemory -
                   1343:  *
                   1344:  *  Allocate the some memory for the glyph.
                   1345:  *
                   1346:  *
                   1347:  *  return: TRUE    - if memory was allocated.
                   1348:  *          FALSE   - if there was no more memory.
                   1349:  *
                   1350:  *****************************************************************************/
                   1351: BOOL bAllocGlyphMemory(
                   1352:     PPDEV ppdev,
                   1353:     PSIZEL psizlGlyph,
                   1354:     PXYZPOINTL pxyzGlyph)
                   1355: {
                   1356:     BOOL    bFound;
                   1357:     INT     iPlane, iRow, iGlyph;
                   1358:     BYTE    jPlaneBitVector;
                   1359: 
                   1360: 
                   1361:     // Search the bit vector
                   1362: 
                   1363:     bFound = FALSE;
                   1364:     for (iPlane = 0; iPlane < 8; iPlane++)
                   1365:     {
                   1366:         jPlaneBitVector = (BYTE) iPlaneBits[iPlane];
                   1367: 
                   1368:         for (iRow = 0; iRow < CACHED_GLYPHS_ROWS; iRow++)
                   1369:         {
                   1370:             for (iGlyph = 0; iGlyph < GLYPHS_PER_ROW; iGlyph++)
                   1371:             {
                   1372:                 if (!(ppdev->ajGlyphAllocBitVector[iRow][iGlyph] & jPlaneBitVector))
                   1373:                 {
                   1374:                     bFound = TRUE;
                   1375:                     ppdev->ajGlyphAllocBitVector[iRow][iGlyph] |=
                   1376:                             jPlaneBitVector;
                   1377: 
                   1378:                     pxyzGlyph->z = jPlaneBitVector;
                   1379:                     pxyzGlyph->x = iGlyph * GLYPH_CACHE_CX;
                   1380:                     pxyzGlyph->y = (iRow * GLYPH_CACHE_CY) + GLYPH_CACHE_Y;
                   1381: 
                   1382:                     DISPDBG((5, "S3.DLL!bAllocGlyphMemory\n"));
                   1383:                     DISPDBG((5, "\t pxyzGlyph->z: %0x\n", pxyzGlyph->z));
                   1384:                     DISPDBG((5, "\t pxyzGlyph->x: %d\n",  pxyzGlyph->x));
                   1385:                     DISPDBG((5, "\t pxyzGlyph->y: %d\n",  pxyzGlyph->y));
                   1386: 
                   1387:                     return (bFound);
                   1388:                 }
                   1389:             }
                   1390:         }
                   1391:     }
                   1392: 
                   1393:     return (bFound);
                   1394: }
                   1395: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.