Annotation of ntddk/src/video/displays/framebuf/mips/text.c, revision 1.1.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.