Annotation of ntddk/src/video/displays/framebuf/mips/text.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: text.c
        !             3: *
        !             4: * Optimized TextOut for the MIPS.  Reduces the total number of memory writes
        !             5: * required to output a glyph which significantly improves performance when
        !             6: * using slower video memory.
        !             7: *
        !             8: * Copyright (c) 1992 Microsoft Corporation
        !             9: \**************************************************************************/
        !            10: 
        !            11: #include "driver.h"
        !            12: 
        !            13: //
        !            14: // Define string object accelerator masks.
        !            15: //
        !            16: 
        !            17: #define SO_MASK \
        !            18:     (SO_FLAG_DEFAULT_PLACEMENT | SO_ZERO_BEARINGS | \
        !            19:      SO_CHAR_INC_EQUAL_BM_BASE | SO_MAXEXT_EQUAL_BM_SIDE)
        !            20: 
        !            21: #define SO_LTOR (SO_MASK | SO_HORIZONTAL)
        !            22: #define SO_RTOL (SO_LTOR | SO_REVERSED)
        !            23: #define SO_TTOB (SO_MASK | SO_VERTICAL)
        !            24: #define SO_BTOT (SO_TTOB | SO_REVERSED)
        !            25: 
        !            26: //
        !            27: // Define enumeration structure.
        !            28: //
        !            29: 
        !            30: #define BB_RECT_LIMIT 20
        !            31: 
        !            32: typedef struct _ENUMRECTLIST {
        !            33:     ULONG c;
        !            34:     RECTL arcl[BB_RECT_LIMIT];
        !            35: } ENUMRECTLIST;
        !            36: 
        !            37: //
        !            38: // Define function prototype for glyph output routines.
        !            39: //
        !            40: 
        !            41: typedef
        !            42: VOID
        !            43: (*PDRVP_GLYPHOUT_ROUTINE) (
        !            44:     IN PBYTE DrawPoint,
        !            45:     IN PULONG GlyphBits,
        !            46:     IN ULONG GlyphWidth,
        !            47:     IN ULONG GlyphHeight
        !            48:     );
        !            49: 
        !            50: VOID
        !            51: DrvpOutputGlyphTransparent (
        !            52:     IN PBYTE DrawPoint,
        !            53:     IN PBYTE GlyphBitmap,
        !            54:     IN ULONG GlyphWidth,
        !            55:     IN ULONG GlyphHeight
        !            56:     );
        !            57: 
        !            58: //
        !            59: // Define big endian color mask table conversion table.
        !            60: //
        !            61: 
        !            62: const ULONG DrvpColorMask[16] = {
        !            63:     0x00000000,                         // 0000 -> 0000
        !            64:     0xff000000,                         // 0001 -> 1000
        !            65:     0x00ff0000,                         // 0010 -> 0100
        !            66:     0xffff0000,                         // 0011 -> 1100
        !            67:     0x0000ff00,                         // 0100 -> 0010
        !            68:     0xff00ff00,                         // 0101 -> 1010
        !            69:     0x00ffff00,                         // 0110 -> 0110
        !            70:     0xffffff00,                         // 0111 -> 1110
        !            71:     0x000000ff,                         // 1000 -> 0001
        !            72:     0xff0000ff,                         // 1001 -> 1001
        !            73:     0x00ff00ff,                         // 1010 -> 0101
        !            74:     0xffff00ff,                         // 1011 -> 1101
        !            75:     0x0000ffff,                         // 1100 -> 0011
        !            76:     0xff00ffff,                         // 1101 -> 1011
        !            77:     0x00ffffff,                         // 1110 -> 0111
        !            78:     0xffffffff};                        // 1111 -> 1111
        !            79: 
        !            80: //
        !            81: // Define draw color table that is generated for text output.
        !            82: //
        !            83: 
        !            84: ULONG DrvpDrawColorTable[16];
        !            85: 
        !            86: //
        !            87: // Define foreground color for transparent output.
        !            88: //
        !            89: 
        !            90: ULONG DrvpForeGroundColor;
        !            91: 
        !            92: //
        !            93: // Define scanline width value.
        !            94: //
        !            95: 
        !            96: ULONG DrvpScanLineWidth;
        !            97: 
        !            98: //
        !            99: // Define global opaque glyph output routine address table.
        !           100: //
        !           101: 
        !           102: extern PDRVP_GLYPHOUT_ROUTINE DrvpOpaqueTable[8];
        !           103: 
        !           104: /******************************Public*Routine******************************\
        !           105: * DrvpIntersectRect
        !           106: *
        !           107: * This routine checks to see if the two specified retangles intersect.
        !           108: *
        !           109: * A value of TRUE is returned if the rectangles intersect. Otherwise,
        !           110: * a value of FALSE is returned.
        !           111: *
        !           112: \**************************************************************************/
        !           113: 
        !           114: BOOL DrvpIntersectRect (
        !           115:     IN PRECTL Rectl1,
        !           116:     IN PRECTL Rectl2,
        !           117:     OUT PRECTL DestRectl)
        !           118: 
        !           119: {
        !           120: 
        !           121:     //
        !           122:     // Compute the maximum left edge and the minimum right edge.
        !           123:     //
        !           124: 
        !           125:     DestRectl->left  = max(Rectl1->left, Rectl2->left);
        !           126:     DestRectl->right = min(Rectl1->right, Rectl2->right);
        !           127: 
        !           128:     //
        !           129:     // If the minimum right edge is greater than the maximum left edge,
        !           130:     // then the rectanges may intersect. Otherwise, they do not intersect.
        !           131:     //
        !           132: 
        !           133:     if (DestRectl->left < DestRectl->right) {
        !           134: 
        !           135:         //
        !           136:         // Compute the maximum top edge and the minimum bottom edge.
        !           137:         //
        !           138: 
        !           139:         DestRectl->top = max(Rectl1->top, Rectl2->top);
        !           140:         DestRectl->bottom = min(Rectl1->bottom, Rectl2->bottom);
        !           141: 
        !           142:         //
        !           143:         // If the minimum bottom edge is greater than the maximum top
        !           144:         // edge, then the rectanges intersect. Otherwise, they do not
        !           145:         // intersect.
        !           146:         //
        !           147: 
        !           148:         if (DestRectl->top < DestRectl->bottom) {
        !           149:             return TRUE;
        !           150:         }
        !           151:     }
        !           152: 
        !           153:     return FALSE;
        !           154: }
        !           155: 
        !           156: /******************************Public*Routine******************************\
        !           157: * DrvpSolidColorFill
        !           158: *
        !           159: * Routine Description:
        !           160: *
        !           161: *     This routine fills a rectangle with a solid color.
        !           162: *
        !           163: * Arguments:
        !           164: *
        !           165: *     Rectangle - Supplies a pointer to a rectangle.
        !           166: *
        !           167: *     FillColor - Supplies the fill color.
        !           168: *
        !           169: *
        !           170: * Return Value:
        !           171: *
        !           172: *     None.
        !           173: *
        !           174: \**************************************************************************/
        !           175: 
        !           176: VOID DrvpSolidColorFill (
        !           177:     IN SURFOBJ *pso,
        !           178:     IN PRECTL Rectangle,
        !           179:     IN ULONG FillColor)
        !           180: 
        !           181: {
        !           182: 
        !           183:     PUCHAR Destination;
        !           184:     ULONG Index;
        !           185:     ULONG Length;
        !           186:     LONG  lDelta = pso->lDelta;
        !           187: 
        !           188:     //
        !           189:     // Compute rectangle fill parameters and fill rectangle with solid color.
        !           190:     //
        !           191: 
        !           192:     Destination = ((PBYTE) pso->pvScan0) + (Rectangle->top * lDelta) + Rectangle->left;
        !           193:     Length = Rectangle->right - Rectangle->left;
        !           194:     for (Index = 0; Index < (Rectangle->bottom - Rectangle->top); Index += 1) {
        !           195:         RtlFillMemory((PVOID)Destination, Length, FillColor);
        !           196:         Destination += lDelta;
        !           197:     }
        !           198: 
        !           199:     return;
        !           200: }
        !           201: 
        !           202: /******************************Public*Routine******************************\
        !           203: * DrvpEqualRectangle
        !           204: *
        !           205: * This routine compares two rectangles for equality.
        !           206: *
        !           207: \**************************************************************************/
        !           208: 
        !           209: BOOL DrvpEqualRectangle (
        !           210:     IN RECTL *prcl1,
        !           211:     IN RECTL *prcl2)
        !           212: 
        !           213: {
        !           214: 
        !           215:     if ((prcl1->left == prcl2->left) && (prcl1->right == prcl2->right) &&
        !           216:         (prcl1->bottom == prcl2->bottom) && (prcl1->top == prcl2->top)) {
        !           217:         return TRUE;
        !           218: 
        !           219:     } else {
        !           220:         return FALSE;
        !           221:     }
        !           222: }
        !           223: 
        !           224: /******************************Public*Routine******************************\
        !           225: * DrvpFillRectangle
        !           226: *
        !           227: * This routine fills a rectangle with clipping.
        !           228: *
        !           229: \**************************************************************************/
        !           230: 
        !           231: VOID DrvpFillRectangle (
        !           232:     IN SURFOBJ *pso,
        !           233:     IN CLIPOBJ *pco,
        !           234:     IN RECTL *prcl,
        !           235:     IN BRUSHOBJ *pbo)
        !           236: 
        !           237: {
        !           238: 
        !           239:     ENUMRECTLIST ClipEnum;
        !           240:     RECTL Region;
        !           241:     ULONG Index;
        !           242:     BOOL More;
        !           243:     ULONG iDComplexity;
        !           244: 
        !           245:     if (pco) {
        !           246:         iDComplexity = pco->iDComplexity;
        !           247: 
        !           248:     } else {
        !           249:         iDComplexity = DC_TRIVIAL;
        !           250:     }
        !           251: 
        !           252: 
        !           253:     //
        !           254:     // Clip and fill the rectangle with the specified color.
        !           255:     //
        !           256: 
        !           257:     switch(iDComplexity) {
        !           258:     case DC_TRIVIAL:
        !           259:         DrvpSolidColorFill(pso, prcl, pbo->iSolidColor);
        !           260:         return;
        !           261: 
        !           262:     case DC_RECT:
        !           263:         More = FALSE;
        !           264:         ClipEnum.c = 1;
        !           265:         ClipEnum.arcl[0] = pco->rclBounds;
        !           266:         break;
        !           267: 
        !           268:     case DC_COMPLEX:
        !           269:         More = TRUE;
        !           270:         CLIPOBJ_cEnumStart(pco,
        !           271:                            FALSE,
        !           272:                            CT_RECTANGLES,
        !           273:                            CD_LEFTWARDS,
        !           274:                            BB_RECT_LIMIT);
        !           275: 
        !           276:         break;
        !           277:     }
        !           278: 
        !           279:     //
        !           280:     // Do a solid color fill for each nonclipped region.
        !           281:     //
        !           282: 
        !           283:     do {
        !           284: 
        !           285:         //
        !           286:         // If more clip regions is TRUE, then get the next batch of
        !           287:         // clipping regions.
        !           288:         //
        !           289: 
        !           290:         if (More != FALSE) {
        !           291:             More = CLIPOBJ_bEnum(pco, sizeof(ClipEnum), (PVOID)&ClipEnum);
        !           292:         }
        !           293: 
        !           294:         //
        !           295:         // If the clipping is not trival, then do the clipping for the
        !           296:         // next region and do the solid fill. Otherwise, do the solid
        !           297:         // fill with no clipping.
        !           298:         //
        !           299: 
        !           300:         for (Index = 0; Index < ClipEnum.c; Index += 1) {
        !           301:             if (DrvpIntersectRect(&ClipEnum.arcl[Index],
        !           302:                                   prcl,
        !           303:                                   &Region)) {
        !           304:             DrvpSolidColorFill(pso, &Region, pbo->iSolidColor);
        !           305:             }
        !           306:         }
        !           307: 
        !           308:     } while (More);
        !           309:     return;
        !           310: }
        !           311: 
        !           312: /******************************Public*Routine******************************\
        !           313: * DrvTextOut
        !           314: *
        !           315: * This routine outputs text to the screen.
        !           316: *
        !           317: * History:
        !           318: *  07-Jul-1992 -by- David N. Cutler [davec]
        !           319: * Wrote it.
        !           320: \**************************************************************************/
        !           321: 
        !           322: BOOL DrvTextOut (
        !           323:     IN SURFOBJ *pso,
        !           324:     IN STROBJ *pstro,
        !           325:     IN FONTOBJ *pfo,
        !           326:     IN CLIPOBJ *pco,
        !           327:     IN RECTL *prclExtra,
        !           328:     IN RECTL *prclOpaque,
        !           329:     IN BRUSHOBJ *pboFore,
        !           330:     IN BRUSHOBJ *pboOpaque,
        !           331:     IN POINTL *pptlOrg,
        !           332:     IN MIX mix)
        !           333: 
        !           334: {
        !           335: 
        !           336:     ULONG BackGroundColor;
        !           337:     PBYTE DrawPoint;
        !           338:     FONTINFO FontInformation;
        !           339:     ULONG ForeGroundColor;
        !           340:     ULONG GlyphCount;
        !           341:     PGLYPHPOS GlyphEnd;
        !           342:     ULONG GlyphHeight;
        !           343:     PGLYPHPOS GlyphList;
        !           344:     PDRVP_GLYPHOUT_ROUTINE GlyphOutputRoutine;
        !           345:     PGLYPHPOS GlyphStart;
        !           346:     ULONG GlyphWidth;
        !           347:     LONG GlyphStride;
        !           348:     ULONG Index;
        !           349:     BOOL More;
        !           350:     RECTL OpaqueRectl;
        !           351:     LONG OriginX;
        !           352:     LONG OriginY;
        !           353:     PBYTE pjScreenBase;
        !           354:     GLYPHBITS *pgb;
        !           355: 
        !           356:     //
        !           357:     // DrvTextOut will only get called with solid color brushes and
        !           358:     // the mix mode being the simplest R2_COPYPEN. The driver must
        !           359:     // set a capabilities bit to get called with more complicated
        !           360:     // mix brushes.
        !           361:     //
        !           362: 
        !           363: //    ASSERT(pboFore->iSolidColor != 0xffffffff);
        !           364: //    ASSERT(pboOpaque->iSolidColor != 0xffffffff);
        !           365: //    ASSERT(mix == ((R2_COPYPEN << 8) | R2_COPYPEN));
        !           366: 
        !           367:     //
        !           368:     // If the complexity of the clipping is not trival, then let GDI
        !           369:     // process the request.
        !           370:     //
        !           371: 
        !           372:     if (pco->iDComplexity != DC_TRIVIAL) {
        !           373:         return(EngTextOut(pso,
        !           374:                           pstro,
        !           375:                           pfo,
        !           376:                           pco,
        !           377:                           prclExtra,
        !           378:                           prclOpaque,
        !           379:                           pboFore,
        !           380:                           pboOpaque,
        !           381:                           pptlOrg,
        !           382:                           mix));
        !           383:     }
        !           384: 
        !           385:     //
        !           386:     // The foreground color is used for the text and extra rectangle
        !           387:     // if it specified. The background color is used for the opaque
        !           388:     // rectangle. If the foreground color is not a solid color brush
        !           389:     // or the opaque rectangle is specified and is not a solid color
        !           390:     // brush, then let GDI process the request.
        !           391:     //
        !           392: 
        !           393:     DrvpScanLineWidth = pso->lDelta;
        !           394:     pjScreenBase = pso->pvScan0;
        !           395: 
        !           396:     //
        !           397:     // Check if the background and foreground can be draw at the same time.
        !           398:     //
        !           399: 
        !           400:     ForeGroundColor = pboFore->iSolidColor;
        !           401:     ForeGroundColor |= (ForeGroundColor << 8);
        !           402:     ForeGroundColor |= (ForeGroundColor << 16);
        !           403:     if (((pstro->flAccel == SO_LTOR) || (pstro->flAccel == SO_RTOL) ||
        !           404:         (pstro->flAccel == SO_TTOB) || (pstro->flAccel == SO_BTOT)) &&
        !           405:         (prclOpaque != NULL) && (pfo->cxMax <= 32)) {
        !           406: 
        !           407:         //
        !           408:         // The background and the foreground can be draw at the same
        !           409:         // time. Generate the drawing color table and draw the text
        !           410:         // opaquely.
        !           411:         //
        !           412: 
        !           413:         BackGroundColor = pboOpaque->iSolidColor;
        !           414:         BackGroundColor |= (BackGroundColor << 8);
        !           415:         BackGroundColor |= (BackGroundColor << 16);
        !           416:         for (Index = 0; Index < 16; Index += 1) {
        !           417:             DrvpDrawColorTable[Index] =
        !           418:                 (ForeGroundColor & DrvpColorMask[Index]) |
        !           419:                     (BackGroundColor & (~DrvpColorMask[Index]));
        !           420:         }
        !           421: 
        !           422:         //
        !           423:         // If the top of the opaque rectangle is less than the top of the
        !           424:         // background rectangle, then fill the region between the top of
        !           425:         // opaque rectangle and the top of the background rectangle and
        !           426:         // reduce the size of the opaque rectangle.
        !           427:         //
        !           428: 
        !           429:         OpaqueRectl = *prclOpaque;
        !           430:         if (OpaqueRectl.top < pstro->rclBkGround.top) {
        !           431:             OpaqueRectl.bottom = pstro->rclBkGround.top;
        !           432:             DrvpFillRectangle(pso,pco, &OpaqueRectl, pboOpaque);
        !           433:             OpaqueRectl.top = pstro->rclBkGround.top;
        !           434:             OpaqueRectl.bottom = prclOpaque->bottom;
        !           435:         }
        !           436: 
        !           437:         //
        !           438:         // If the bottom of the opaque rectangle is greater than the bottom
        !           439:         // of the background rectangle, then fill the region between the
        !           440:         // bottom of the background rectangle and the bottom of the opaque
        !           441:         // rectangle and reduce the size of the opaque rectangle.
        !           442:         //
        !           443: 
        !           444:         if (OpaqueRectl.bottom > pstro->rclBkGround.bottom) {
        !           445:             OpaqueRectl.top = pstro->rclBkGround.bottom;
        !           446:             DrvpFillRectangle(pso, pco, &OpaqueRectl, pboOpaque);
        !           447:             OpaqueRectl.top = pstro->rclBkGround.top;
        !           448:             OpaqueRectl.bottom = pstro->rclBkGround.bottom;
        !           449:         }
        !           450: 
        !           451:         //
        !           452:         // If the left of the opaque rectangle is less than the left of
        !           453:         // the background rectangle, then fill the region between the
        !           454:         // left of the opaque rectangle and the left of the background
        !           455:         // rectangle.
        !           456:         //
        !           457: 
        !           458:         if (OpaqueRectl.left < pstro->rclBkGround.left) {
        !           459:             OpaqueRectl.right = pstro->rclBkGround.left;
        !           460:             DrvpFillRectangle(pso, pco, &OpaqueRectl, pboOpaque);
        !           461:             OpaqueRectl.right = prclOpaque->right;
        !           462:         }
        !           463: 
        !           464:         //
        !           465:         // If the right of the opaque rectangle is greater than the right
        !           466:         // of the background rectangle, then fill the region between the
        !           467:         // right of the opaque rectangle and the right of the background
        !           468:         // rectangle.
        !           469:         //
        !           470: 
        !           471:         if (OpaqueRectl.right > pstro->rclBkGround.right) {
        !           472:             OpaqueRectl.left = pstro->rclBkGround.right;
        !           473:             DrvpFillRectangle(pso, pco, &OpaqueRectl, pboOpaque);
        !           474:         }
        !           475: 
        !           476:         //
        !           477:         // If the font is fixed pitch, then optimize the computation of
        !           478:         // x and y coordinate values. Otherwise, compute the x and y values
        !           479:         // for each glyph.
        !           480:         //
        !           481: 
        !           482:         if (pstro->ulCharInc != 0) {
        !           483: 
        !           484:             //
        !           485:             // The font is fixed pitch. Capture the glyph dimensions and
        !           486:             // compute the starting display address.
        !           487:             //
        !           488: 
        !           489:             if (pstro->pgp == NULL) {
        !           490:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           491: 
        !           492:             } else {
        !           493:                 GlyphCount = pstro->cGlyphs;
        !           494:                 GlyphList = pstro->pgp;
        !           495:                 More = FALSE;
        !           496:             }
        !           497: 
        !           498:             pgb = GlyphList->pgdf->pgb;
        !           499:             GlyphWidth = pgb->sizlBitmap.cx;
        !           500:             GlyphHeight = pgb->sizlBitmap.cy;
        !           501:             OriginX = GlyphList->ptl.x + pgb->ptlOrigin.x;
        !           502:             OriginY = GlyphList->ptl.y + pgb->ptlOrigin.y;
        !           503:             DrawPoint = pjScreenBase + ((OriginY * DrvpScanLineWidth) + OriginX);
        !           504: 
        !           505:             //
        !           506:             // Compute the glyph stride.
        !           507:             //
        !           508: 
        !           509:             GlyphStride = pstro->ulCharInc;
        !           510:             if ((pstro->flAccel & SO_VERTICAL) != 0) {
        !           511:                 GlyphStride *= DrvpScanLineWidth;
        !           512:             }
        !           513: 
        !           514:             //
        !           515:             // If the direction of drawing is reversed, then the stride is
        !           516:             // negative.
        !           517:             //
        !           518: 
        !           519:             if ((pstro->flAccel & SO_REVERSED) != 0) {
        !           520:                 GlyphStride = - GlyphStride;
        !           521:             }
        !           522: 
        !           523:             //
        !           524:             // Output the initial set of glyphs.
        !           525:             //
        !           526: 
        !           527:             GlyphOutputRoutine = DrvpOpaqueTable[(GlyphWidth - 1) >> 2];
        !           528:             GlyphEnd = &GlyphList[GlyphCount];
        !           529:             GlyphStart = GlyphList;
        !           530:             do {
        !           531:                 pgb = GlyphStart->pgdf->pgb;
        !           532:                 (GlyphOutputRoutine)(DrawPoint,
        !           533:                                      (PULONG)&pgb->aj[0],
        !           534:                                      GlyphWidth,
        !           535:                                      GlyphHeight);
        !           536: 
        !           537:                 DrawPoint += GlyphStride;
        !           538:                 GlyphStart += 1;
        !           539:             } while (GlyphStart != GlyphEnd);
        !           540: 
        !           541:             //
        !           542:             // Output the subsequent set of glyphs.
        !           543:             //
        !           544: 
        !           545:             while (More) {
        !           546:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           547:                 GlyphEnd = &GlyphList[GlyphCount];
        !           548:                 GlyphStart = GlyphList;
        !           549:                 do {
        !           550:                     pgb = GlyphStart->pgdf->pgb;
        !           551:                     (GlyphOutputRoutine)(DrawPoint,
        !           552:                                          (PULONG)&pgb->aj[0],
        !           553:                                          GlyphWidth,
        !           554:                                          GlyphHeight);
        !           555: 
        !           556:                     DrawPoint += GlyphStride;
        !           557:                     GlyphStart += 1;
        !           558:                 } while (GlyphStart != GlyphEnd);
        !           559:             }
        !           560: 
        !           561:         } else {
        !           562: 
        !           563:             //
        !           564:             // The font is not fixed pitch. Compute the x and y values for
        !           565:             // each glyph individually.
        !           566:             //
        !           567: 
        !           568:             do {
        !           569:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           570:                 GlyphEnd = &GlyphList[GlyphCount];
        !           571:                 GlyphStart = GlyphList;
        !           572:                 do {
        !           573:                     pgb = GlyphStart->pgdf->pgb;
        !           574:                     OriginX = GlyphStart->ptl.x + pgb->ptlOrigin.x;
        !           575:                     OriginY = GlyphStart->ptl.y + pgb->ptlOrigin.y;
        !           576:                     DrawPoint = pjScreenBase +
        !           577:                                     ((OriginY * DrvpScanLineWidth) + OriginX);
        !           578: 
        !           579:                     GlyphWidth = pgb->sizlBitmap.cx;
        !           580:                     GlyphOutputRoutine = DrvpOpaqueTable[(GlyphWidth - 1) >> 2];
        !           581:                     (GlyphOutputRoutine)(DrawPoint,
        !           582:                                          (PULONG)&pgb->aj[0],
        !           583:                                          GlyphWidth,
        !           584:                                          pgb->sizlBitmap.cy);
        !           585: 
        !           586:                     GlyphStart += 1;
        !           587:                 } while(GlyphStart != GlyphEnd);
        !           588:             } while(More);
        !           589:         }
        !           590: 
        !           591:     } else {
        !           592: 
        !           593:         //
        !           594:         // The background and the foreground cannot be draw at the same
        !           595:         // time. Set the foreground color and fill the background rectangle,
        !           596:         // if specified, and then draw the text transparently.
        !           597:         //
        !           598: 
        !           599:         DrvpForeGroundColor = ForeGroundColor;
        !           600:         if (prclOpaque != NULL) {
        !           601:             DrvpFillRectangle(pso, pco, prclOpaque, pboOpaque);
        !           602:         }
        !           603: 
        !           604:         //
        !           605:         // If the font is fixed pitch, then optimize the computation of
        !           606:         // x and y coordinate values. Otherwise, compute the x and y values
        !           607:         // for each glyph.
        !           608:         //
        !           609: 
        !           610:         if (pstro->ulCharInc != 0) {
        !           611: 
        !           612:             //
        !           613:             // The font is fixed pitch. Capture the glyph dimensions and
        !           614:             // compute the starting display address.
        !           615:             //
        !           616: 
        !           617:             if (pstro->pgp == NULL) {
        !           618:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           619: 
        !           620:             } else {
        !           621:                 GlyphCount = pstro->cGlyphs;
        !           622:                 GlyphList = pstro->pgp;
        !           623:                 More = FALSE;
        !           624:             }
        !           625: 
        !           626:             pgb = GlyphList->pgdf->pgb;
        !           627:             GlyphWidth = pgb->sizlBitmap.cx;
        !           628:             GlyphHeight = pgb->sizlBitmap.cy;
        !           629:             OriginX = GlyphList->ptl.x + pgb->ptlOrigin.x;
        !           630:             OriginY = GlyphList->ptl.y + pgb->ptlOrigin.y;
        !           631:             DrawPoint = pjScreenBase + ((OriginY * DrvpScanLineWidth) + OriginX);
        !           632: 
        !           633:             //
        !           634:             // Compute the glyph stride.
        !           635:             //
        !           636: 
        !           637:             GlyphStride = pstro->ulCharInc;
        !           638:             if ((pstro->flAccel & SO_VERTICAL) != 0) {
        !           639:                 GlyphStride *= DrvpScanLineWidth;
        !           640:             }
        !           641: 
        !           642:             //
        !           643:             // If the direction of drawing is reversed, then the stride is
        !           644:             // negative.
        !           645:             //
        !           646: 
        !           647:             if ((pstro->flAccel & SO_REVERSED) != 0) {
        !           648:                 GlyphStride = -GlyphStride;
        !           649:             }
        !           650: 
        !           651:             //
        !           652:             // Output the initial set of glyphs.
        !           653:             //
        !           654: 
        !           655:             GlyphEnd = &GlyphList[GlyphCount];
        !           656:             GlyphStart = GlyphList;
        !           657:             do {
        !           658:                 pgb = GlyphStart->pgdf->pgb;
        !           659:                 DrvpOutputGlyphTransparent(DrawPoint,
        !           660:                                            &pgb->aj[0],
        !           661:                                            GlyphWidth,
        !           662:                                            GlyphHeight);
        !           663: 
        !           664:                 DrawPoint += GlyphStride;
        !           665:                 GlyphStart += 1;
        !           666:             } while (GlyphStart != GlyphEnd);
        !           667: 
        !           668:             //
        !           669:             // Output the subsequent set of glyphs.
        !           670:             //
        !           671: 
        !           672:             while (More) {
        !           673:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           674:                 GlyphEnd = &GlyphList[GlyphCount];
        !           675:                 GlyphStart = GlyphList;
        !           676:                 do {
        !           677:                     pgb = GlyphStart->pgdf->pgb;
        !           678:                     DrvpOutputGlyphTransparent(DrawPoint,
        !           679:                                                &pgb->aj[0],
        !           680:                                                GlyphWidth,
        !           681:                                                GlyphHeight);
        !           682: 
        !           683:                     DrawPoint += GlyphStride;
        !           684:                     GlyphStart += 1;
        !           685:                 } while (GlyphStart != GlyphEnd);
        !           686:             }
        !           687: 
        !           688:         } else {
        !           689: 
        !           690:             //
        !           691:             // The font is not fixed pitch. Compute the x and y values for
        !           692:             // each glyph individually.
        !           693:             //
        !           694: 
        !           695:             do {
        !           696:                 More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList);
        !           697:                 GlyphEnd = &GlyphList[GlyphCount];
        !           698:                 GlyphStart = GlyphList;
        !           699:                 do {
        !           700:                     pgb = GlyphStart->pgdf->pgb;
        !           701:                     OriginX = GlyphStart->ptl.x + pgb->ptlOrigin.x;
        !           702:                     OriginY = GlyphStart->ptl.y + pgb->ptlOrigin.y;
        !           703:                     DrawPoint = pjScreenBase +
        !           704:                                     ((OriginY * DrvpScanLineWidth) + OriginX);
        !           705: 
        !           706:                     DrvpOutputGlyphTransparent(DrawPoint,
        !           707:                                                &pgb->aj[0],
        !           708:                                                pgb->sizlBitmap.cx,
        !           709:                                                pgb->sizlBitmap.cy);
        !           710: 
        !           711:                     GlyphStart += 1;
        !           712:                 } while(GlyphStart != GlyphEnd);
        !           713:             } while(More);
        !           714:         }
        !           715:     }
        !           716: 
        !           717:     //
        !           718:     // Fill the extra rectangles if specified.
        !           719:     //
        !           720: 
        !           721:     if (prclExtra != (PRECTL)NULL) {
        !           722:         while (prclExtra->left != prclExtra->right) {
        !           723:             DrvpFillRectangle(pso, pco, prclExtra, pboFore);
        !           724:             prclExtra += 1;
        !           725:         }
        !           726:     }
        !           727: 
        !           728:     return(TRUE);
        !           729: }

unix.superglobalmegacorp.com

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