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

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: TextOut.c
                      3: *
                      4: * Text
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: *
                      8: \**************************************************************************/
                      9: 
                     10: #include "driver.h"
                     11: 
                     12: BOOL vFastText(PDEV *, GLYPHPOS *, ULONG, PBYTE, ULONG, ULONG, RECTL *,
                     13:     RECTL *, INT, INT, ULONG);
                     14: VOID lclFillRect(CLIPOBJ *, ULONG, PRECTL, PPDEV, INT);
                     15: 
                     16: /****************************************************************************
                     17:  * DrvTextOut
                     18:  ***************************************************************************/
                     19: 
                     20: BOOL DrvTextOut(
                     21:     SURFOBJ*  pso,
                     22:     STROBJ*   pstro,
                     23:     FONTOBJ*  pfo,
                     24:     CLIPOBJ*  pco,
                     25:     RECTL*    prclExtra,
                     26:     RECTL*    prclOpaque,
                     27:     BRUSHOBJ* pboFore,
                     28:     BRUSHOBJ* pboOpaque,
                     29:     POINTL*   pptlOrg,
                     30:     MIX       mix)
                     31: {
                     32:     BOOL   b;
                     33:     PPDEV  ppdev;
                     34:     INT    iClip;           // clip object's complexity
                     35:     ULONG  iSolidForeColor; // Solid foreground color
                     36:     ULONG  iSolidBkColor;   // Solid background color
                     37:     RECTL  arclTmp[4];      // Temp storage for portions of opaquing rect
                     38:     ULONG  culRcl;          // Temp rectangle count
                     39: 
                     40:     ppdev = (PPDEV) pso->dhpdev;
                     41: 
                     42: 
                     43:     //---------------------------------------------------------------------
                     44:     // Get information about clip object.
                     45:     //---------------------------------------------------------------------
                     46: 
                     47:     iClip = DC_TRIVIAL;
                     48: 
                     49:     if (pco != NULL) {
                     50:         iClip = pco->iDComplexity;
                     51:     }
                     52: 
                     53:     //---------------------------------------------------------------------
                     54:     // Get text color.
                     55:     //---------------------------------------------------------------------
                     56: 
                     57:     iSolidForeColor = pboFore->iSolidColor;
                     58: 
                     59:     //---------------------------------------------------------------------
                     60:     // See if this is text we can handle faster with special-case code.
                     61:     //---------------------------------------------------------------------
                     62: 
                     63:     if (((ppdev->fl & DRIVER_PLANAR_CAPABLE) ||
                     64:         (prclOpaque == (PRECTL) NULL)) &&   // opaque only if planar for now
                     65:                                             // LATER implement fast non-planar
                     66:                                             // opaque
                     67:         (iClip == DC_TRIVIAL) &&            // no clipping for now
                     68:             ((pstro->rclBkGround.right & ~0x03) >
                     69:              ((pstro->rclBkGround.left + 3) & ~0x03)) &&
                     70:                                             // not if no full nibbles spanned
                     71:                                             //  for now @@@
                     72:             (pstro->pgp != NULL) &&         // no glyph enumeration for now
                     73:             (prclExtra == NULL) &&          // no extra rects for now
                     74:             ((pstro->flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) ==
                     75:              SO_HORIZONTAL)) {              // only left-to-right text for now
                     76: 
                     77:         ULONG ulBufferWidthInBytes;
                     78:         ULONG ulBufferBytes;
                     79:         BOOL  bTextPerfectFit;
                     80:         ULONG fDrawFlags;
                     81: 
                     82:         // It's the type of text we can special-case; see if the temp buffer is
                     83:         // big enough for the text.
                     84: 
                     85:         ulBufferWidthInBytes = ((((pstro->rclBkGround.right + 7) & ~0x07) -
                     86:                 (pstro->rclBkGround.left & ~0x07)) >> 3);
                     87:         ulBufferBytes = ulBufferWidthInBytes *
                     88:                 (pstro->rclBkGround.bottom - pstro->rclBkGround.top);
                     89: 
                     90:         if (ulBufferBytes <= TMP_BUFFER_SIZE) {
                     91: 
                     92:             // It's big enough; set up for the accelerator
                     93: 
                     94:             // Set fixed pitch, overlap, and top & bottom Y alignment flags
                     95:             fDrawFlags = ((pstro->ulCharInc != 0) ? 0x01 : 0) |
                     96:                          (((pstro->flAccel & (SO_ZERO_BEARINGS |
                     97:                           SO_FLAG_DEFAULT_PLACEMENT)) !=
                     98:                           (SO_ZERO_BEARINGS | SO_FLAG_DEFAULT_PLACEMENT))
                     99:                           ? 0x02 : 0) |
                    100:                          (((pstro->flAccel & (SO_ZERO_BEARINGS |
                    101:                           SO_FLAG_DEFAULT_PLACEMENT |
                    102:                           SO_MAXEXT_EQUAL_BM_SIDE)) ==
                    103:                           (SO_ZERO_BEARINGS | SO_FLAG_DEFAULT_PLACEMENT |
                    104:                           SO_MAXEXT_EQUAL_BM_SIDE)) ? 0x04 : 0);
                    105: 
                    106:             // If there's an opaque rectangle, we'll do as much opaquing as
                    107:             // possible as we do the text. If the opaque rectangle is larger
                    108:             // than the text rectangle, then we'll do the fringe areas right
                    109:             // now, and the text and associated background areas together,
                    110:             // later.
                    111:             if (prclOpaque != (PRECTL) NULL) {
                    112: 
                    113:                 // This driver only handles solid brushes
                    114:                 iSolidBkColor = pboOpaque->iSolidColor;
                    115: 
                    116:                 // See if we have fringe areas to do. If so, build a list of
                    117:                 // rectangles to fill, in rightdown order
                    118: 
                    119:                 culRcl = 0;
                    120: 
                    121:                 // Top fragment
                    122:                 if (pstro->rclBkGround.top > prclOpaque->top) {
                    123:                     arclTmp[culRcl].top = prclOpaque->top;
                    124:                     arclTmp[culRcl].left = prclOpaque->left;
                    125:                     arclTmp[culRcl].right = prclOpaque->right;
                    126:                     arclTmp[culRcl++].bottom = pstro->rclBkGround.top;
                    127:                 }
                    128: 
                    129:                 // Left fragment
                    130:                 if (pstro->rclBkGround.left > prclOpaque->left) {
                    131:                     arclTmp[culRcl].top = pstro->rclBkGround.top;
                    132:                     arclTmp[culRcl].left = prclOpaque->left;
                    133:                     arclTmp[culRcl].right = pstro->rclBkGround.left;
                    134:                     arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    135:                 }
                    136: 
                    137:                 // Right fragment
                    138:                 if (pstro->rclBkGround.right < prclOpaque->right) {
                    139:                     arclTmp[culRcl].top = pstro->rclBkGround.top;
                    140:                     arclTmp[culRcl].right = prclOpaque->right;
                    141:                     arclTmp[culRcl].left = pstro->rclBkGround.right;
                    142:                     arclTmp[culRcl++].bottom = pstro->rclBkGround.bottom;
                    143:                 }
                    144: 
                    145:                 // Bottom fragment
                    146:                 if (pstro->rclBkGround.bottom < prclOpaque->bottom) {
                    147:                     arclTmp[culRcl].bottom = prclOpaque->bottom;
                    148:                     arclTmp[culRcl].left = prclOpaque->left;
                    149:                     arclTmp[culRcl].right = prclOpaque->right;
                    150:                     arclTmp[culRcl++].top = pstro->rclBkGround.bottom;
                    151:                 }
                    152: 
                    153:                 if (culRcl != 0) {
                    154:                     if (iClip == DC_TRIVIAL) {
                    155:                         vTrgBlt(ppdev, culRcl, arclTmp, R2_COPYPEN,
                    156:                                 *((RBRUSH_COLOR*) &iSolidBkColor), NULL);
                    157:                     } else {
                    158:                         lclFillRect(pco, culRcl, arclTmp, ppdev,
                    159:                                     iSolidBkColor);
                    160:                     }
                    161:                 }
                    162:             }
                    163: 
                    164:             // We're done with separate opaquing; any further opaquing will
                    165:             // happen as part of the text drawing
                    166: 
                    167:             // Clear the buffer if the text isn't going to set every bit
                    168:             // BUGBUG do I have to pay attention to ulCharInc?
                    169:             bTextPerfectFit = (pstro->flAccel & (SO_ZERO_BEARINGS |
                    170:                     SO_FLAG_DEFAULT_PLACEMENT | SO_MAXEXT_EQUAL_BM_SIDE |
                    171:                     SO_CHAR_INC_EQUAL_BM_BASE)) ==
                    172:                     (SO_ZERO_BEARINGS | SO_FLAG_DEFAULT_PLACEMENT |
                    173:                     SO_MAXEXT_EQUAL_BM_SIDE | SO_CHAR_INC_EQUAL_BM_BASE);
                    174: 
                    175:             if (!bTextPerfectFit) {
                    176:                 vClearMemDword(ppdev->pvTmp, (ulBufferBytes + 3) >> 2);
                    177:             }
                    178: 
                    179:             // Draw the text into the temp buffer, and thence to the screen
                    180:             vFastText(ppdev,
                    181:                       pstro->pgp,
                    182:                       pstro->cGlyphs,
                    183:                       ppdev->pvTmp,
                    184:                       ulBufferWidthInBytes,
                    185:                       pstro->ulCharInc,
                    186:                       &pstro->rclBkGround,
                    187:                       prclOpaque,
                    188:                       iSolidForeColor,
                    189:                       iSolidBkColor,
                    190:                       fDrawFlags);
                    191: 
                    192:             return(TRUE);
                    193: 
                    194:         }
                    195:     }
                    196: 
                    197:     // Can't special-case; let the engine draw the text
                    198: 
                    199:     pso = ppdev->pSurfObj;
                    200: 
                    201:     // It may be that the opaquing rectangle is larger than the text rectangle,
                    202:     // so we'll want to use that to tell the bank manager which banks to
                    203:     // enumerate:
                    204: 
                    205:     pco = pcoBankStart(ppdev,
                    206:                        (prclOpaque != NULL) ? prclOpaque : &pstro->rclBkGround,
                    207:                        pso,
                    208:                        pco);
                    209: 
                    210:     do {
                    211:         b = EngTextOut(pso,
                    212:                        pstro,
                    213:                        pfo,
                    214:                        pco,
                    215:                        prclExtra,
                    216:                        prclOpaque,
                    217:                        pboFore,
                    218:                        pboOpaque,
                    219:                        pptlOrg,
                    220:                        mix);
                    221: 
                    222:     } while (b && bBankEnum(ppdev, pso, pco));
                    223: 
                    224:     return(b);
                    225: }
                    226: 
                    227: //--------------------------------------------------------------------------
                    228: // Fills the specified rectangles on the specified surface with the
                    229: // specified color, honoring the requested clipping. No more than four
                    230: // rectangles should be passed in. Intended for drawing the areas of the
                    231: // opaquing rectangle that extended beyond the text box. The rectangles must
                    232: // be in left to right, top to bottom order. Assumes there is at least one
                    233: // rectangle in the list.
                    234: //--------------------------------------------------------------------------
                    235: 
                    236: VOID lclFillRect(
                    237:  CLIPOBJ *pco,
                    238:  ULONG culRcl,
                    239:  PRECTL prcl,
                    240:  PPDEV ppdev,
                    241:  INT iColor)
                    242: {
                    243:     BOOL  bMore;                  // Flag for clip enumeration
                    244:     TEXTENUM txen;                // Clip enumeration object
                    245:     ULONG i, j;
                    246:     RECTL arclTmp[4];
                    247:     ULONG culRclTmp;
                    248:     RECTL *prclTmp, *prclClipTmp;
                    249:     INT   iLastBottom;
                    250:     RECTL *pClipRcl;
                    251:     INT iClip;
                    252: 
                    253:     iClip = DC_TRIVIAL;
                    254: 
                    255:     if (pco != NULL) {
                    256:         iClip = pco->iDComplexity;
                    257:     }
                    258: 
                    259:     switch ( iClip ) {
                    260: 
                    261:         case DC_TRIVIAL:
                    262: 
                    263:             vTrgBlt(ppdev, culRcl, prcl, R2_COPYPEN,
                    264:                     *((RBRUSH_COLOR*) &iColor), NULL);
                    265: 
                    266:             break;
                    267: 
                    268:         case DC_RECT:
                    269: 
                    270:             prclTmp = &pco->rclBounds;
                    271: 
                    272:             // Generate a list of clipped rects
                    273:             for (culRclTmp=0, i=0; i<culRcl; i++, prcl++) {
                    274: 
                    275:                 // Intersect fill and clip rectangles
                    276:                 if (bIntersectRect(&arclTmp[culRclTmp], prcl, prclTmp)) {
                    277: 
                    278:                     // Add to list if anything's left to draw
                    279:                     culRclTmp++;
                    280:                 }
                    281:             }
                    282: 
                    283:             // Draw the clipped rects
                    284:             if (culRclTmp != 0) {
                    285:                 vTrgBlt(ppdev, culRclTmp, arclTmp, R2_COPYPEN,
                    286:                         *((RBRUSH_COLOR*) &iColor), NULL);
                    287:             }
                    288: 
                    289:             break;
                    290: 
                    291:         case DC_COMPLEX:
                    292: 
                    293:             // Bottom of last rectangle to fill
                    294:             iLastBottom = prcl[culRcl-1].bottom;
                    295: 
                    296:             // Initialize the clip rectangle enumeration to rightdown so we can
                    297:             // take advantage of the rectangle list being rightdown
                    298:             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN,
                    299:                     TO_RECT_LIMIT);
                    300: 
                    301:             // Scan through all the clip rectangles, looking for intersects
                    302:             // of fill areas with region rectangles
                    303:             do {
                    304: 
                    305:                 // Get a batch of region rectangles
                    306:                 bMore = CLIPOBJ_bEnum(pco, (ULONG)sizeof(txen), (PVOID)&txen);
                    307: 
                    308:                 // Clip the rect list to each region rect
                    309:                 for (j = txen.c, pClipRcl = txen.arcl; j-- > 0; pClipRcl++) {
                    310: 
                    311:                     // Since the rectangles and the region enumeration are both
                    312:                     // rightdown, we can zip through the region until we reach
                    313:                     // the first fill rect, and are done when we've passed the
                    314:                     // last fill rect.
                    315: 
                    316:                     if (pClipRcl->top >= iLastBottom) {
                    317:                         // Past last fill rectangle; nothing left to do
                    318:                         return;
                    319:                     }
                    320: 
                    321:                     // Do intersection tests only if we've reached the top of
                    322:                     // the first rectangle to fill
                    323:                     if (pClipRcl->bottom > prcl->top) {
                    324: 
                    325:                         // We've reached the top Y scan of the first rect, so
                    326:                         // it's worth bothering checking for intersection
                    327: 
                    328:                         // Generate a list of the rects clipped to this region
                    329:                         // rect
                    330:                         prclTmp = prcl;
                    331:                         prclClipTmp = arclTmp;
                    332:                         for (i = culRcl, culRclTmp=0; i-- > 0; prclTmp++) {
                    333: 
                    334:                             // Intersect fill and clip rectangles
                    335:                             if (bIntersectRect(prclClipTmp, prclTmp,
                    336:                                     pClipRcl)) {
                    337: 
                    338:                                 // Add to list if anything's left to draw
                    339:                                 culRclTmp++;
                    340:                                 prclClipTmp++;
                    341:                             }
                    342:                         }
                    343: 
                    344:                         // Draw the clipped rects
                    345:                         if (culRclTmp != 0) {
                    346:                             vTrgBlt(ppdev, culRclTmp, arclTmp, R2_COPYPEN,
                    347:                                     *((RBRUSH_COLOR*) &iColor), NULL);
                    348:                         }
                    349:                     }
                    350:                 }
                    351:             } while (bMore);
                    352: 
                    353:             break;
                    354:     }
                    355: 
                    356: }
                    357: 

unix.superglobalmegacorp.com

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