Annotation of ntddk/src/video/displays/s3/textout.c, revision 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.