Annotation of ntddk/src/video/displays/vga256/brush.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: Brush.c
        !             3: *
        !             4: * Brush support.
        !             5: *
        !             6: * Copyright (c) 1992-1993 Microsoft Corporation
        !             7: *
        !             8: \**************************************************************************/
        !             9: 
        !            10: #include "driver.h"
        !            11: 
        !            12: /****************************************************************************
        !            13:  * DrvRealizeBrush
        !            14:  ***************************************************************************/
        !            15: 
        !            16: BOOL DrvRealizeBrush(
        !            17: BRUSHOBJ* pbo,
        !            18: SURFOBJ*  psoTarget,
        !            19: SURFOBJ*  psoPattern,
        !            20: SURFOBJ*  psoMask,
        !            21: XLATEOBJ* pxlo,
        !            22: ULONG     iHatch)
        !            23: {
        !            24:     RBRUSH* prb;        // Pointer to where realization goes
        !            25:     ULONG*  pulSrc;     // Temporary pointer
        !            26:     ULONG*  pulDst;     // Temporary pointer
        !            27:     BYTE*   pjSrc;
        !            28:     BYTE*   pjDst;
        !            29:     ULONG*  pulRBits;   // Points to RBRUSH pattern bits
        !            30:     BYTE    jBkColor;
        !            31:     BYTE    jFgColor;
        !            32:     LONG    i;
        !            33:     LONG    j;
        !            34: 
        !            35:     PPDEV   ppdev = (PPDEV) psoTarget->dhsurf;
        !            36: 
        !            37:     // For now, we only accelerate patterns using the latches, and we
        !            38:     // sometimes need offscreen memory as a temporary work space to
        !            39:     // initialize the latches for 2-color patterns:
        !            40: 
        !            41:     if ((ppdev->fl & (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN)) !=
        !            42:         (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN) )
        !            43:     {
        !            44:         return(FALSE);
        !            45:     }
        !            46: 
        !            47:     // See if it's a default hatch brush:
        !            48: 
        !            49:     if (iHatch < HS_DDI_MAX)
        !            50:     {
        !            51:         DISPDBG((1, "\n  RBrush: Default"));
        !            52: 
        !            53:         prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH));
        !            54:         if (prb == NULL)
        !            55:             return(FALSE);
        !            56: 
        !            57:         prb->xBrush    = 0;
        !            58:         prb->ulBkColor = (pxlo->pulXlate[0] & 0xff);
        !            59:         prb->ulFgColor = (pxlo->pulXlate[1] & 0xff);
        !            60: 
        !            61:         if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00)
        !            62:         {
        !            63:             prb->fl = RBRUSH_BLACKWHITE;
        !            64:             memcpy(&prb->aulPattern[0],
        !            65:                    &gaaulPlanarPat[iHatch][0],
        !            66:                    8 * sizeof(DWORD));
        !            67:         }
        !            68:         else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff)
        !            69:         {
        !            70:             // We have to invert the brush:
        !            71: 
        !            72:             prb->fl = RBRUSH_BLACKWHITE;
        !            73:             for (i = 0; i < 8; i++)
        !            74:             {
        !            75:                 prb->aulPattern[i] = ~gaaulPlanarPat[iHatch][i];
        !            76:             }
        !            77:         }
        !            78:         else
        !            79:         {
        !            80:             prb->fl = RBRUSH_2COLOR;
        !            81:             memmove(&prb->aulPattern[0], &gaaulPlanarPat[iHatch][0], 32);
        !            82:         }
        !            83: 
        !            84:         return(TRUE);
        !            85:     }
        !            86: 
        !            87:     // We only accelerate 8x8 patterns:
        !            88: 
        !            89:     if (psoPattern->sizlBitmap.cx != 8 || psoPattern->sizlBitmap.cy != 8)
        !            90:         return(FALSE);
        !            91: 
        !            92:     // We only implement n-color patterns on devices that have multiple
        !            93:     // or separate read/write banks:
        !            94: 
        !            95:     if (ppdev->vbtPlanarType == VideoBanked1RW)
        !            96:         return(FALSE);
        !            97: 
        !            98:     // We also only handle 1bpp, 4bpp and 8bpp patterns:
        !            99: 
        !           100:     if (psoPattern->iBitmapFormat > BMF_8BPP)
        !           101:         return(FALSE);
        !           102: 
        !           103:     // At this point, we're definitely going to realize the brush:
        !           104: 
        !           105:     prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH));
        !           106:     if (prb == NULL)
        !           107:         return(FALSE);
        !           108: 
        !           109:     pulRBits = &prb->aulPattern[0];
        !           110: 
        !           111:     DISPDBG((1, "\n  RBrush: "));
        !           112: 
        !           113:     // If 8bpp or 4bpp, copy the bitmap to our local buffer:
        !           114: 
        !           115:     if (psoPattern->iBitmapFormat == BMF_1BPP)
        !           116:     {
        !           117:         ULONG ulFlippedGlyph;
        !           118: 
        !           119:         DISPDBG((1, "1bpp "));
        !           120: 
        !           121:         // First, convert the bits to our desired format:
        !           122: 
        !           123:         pjSrc  = psoPattern->pvScan0;
        !           124:         pulDst = pulRBits;
        !           125:         for (i = 8; i > 0; i--)
        !           126:         {
        !           127:             // We want to take the byte with bits 76543210 and convert it
        !           128:             // to the word 4567012301234567.  The pjGlyphFlipTable gives
        !           129:             // us 45670123 from 76543210.
        !           130: 
        !           131:             ulFlippedGlyph = (ULONG) ppdev->pjGlyphFlipTable[*pjSrc];
        !           132:             *pulDst = (ulFlippedGlyph << 8) | ((ulFlippedGlyph & 15) << 4) |
        !           133:                       (ulFlippedGlyph >> 4);
        !           134: 
        !           135:             pulDst++;
        !           136:             pjSrc += psoPattern->lDelta;
        !           137:         }
        !           138: 
        !           139:         // Now initialize the rest of the RBrush fields:
        !           140: 
        !           141:         prb->xBrush    = 0;
        !           142:         prb->ulBkColor = (pxlo->pulXlate[0] & 0xff);
        !           143:         prb->ulFgColor = (pxlo->pulXlate[1] & 0xff);
        !           144: 
        !           145:         if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00)
        !           146:         {
        !           147:             prb->fl = RBRUSH_BLACKWHITE;
        !           148:         }
        !           149:         else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff)
        !           150:         {
        !           151:             // We have to invert the brush:
        !           152: 
        !           153:             prb->fl = RBRUSH_BLACKWHITE;
        !           154:             for (i = 0; i < 8; i++)
        !           155:             {
        !           156:                 prb->aulPattern[i] = ~prb->aulPattern[i];
        !           157:             }
        !           158:         }
        !           159:         else
        !           160:         {
        !           161:             prb->fl = RBRUSH_2COLOR;
        !           162:         }
        !           163: 
        !           164:         return(TRUE);
        !           165:     }
        !           166:     else if (psoPattern->iBitmapFormat == BMF_8BPP)
        !           167:     {
        !           168: 
        !           169:         if (pxlo == NULL || pxlo->flXlate & XO_TRIVIAL)
        !           170:         {
        !           171:             pulSrc = psoPattern->pvScan0;
        !           172:             pulDst = pulRBits;
        !           173: 
        !           174:             DISPDBG((1, "8bpp noxlate "));
        !           175: 
        !           176:             // 8bpp no translate case:
        !           177: 
        !           178:             for (i = 4; i > 0; i--)
        !           179:             {
        !           180:                 *(pulDst)     = *(pulSrc);
        !           181:                 *(pulDst + 1) = *(pulSrc + 1);
        !           182:                 pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta);
        !           183: 
        !           184:                 *(pulDst + 2) = *(pulSrc);
        !           185:                 *(pulDst + 3) = *(pulSrc + 1);
        !           186: 
        !           187:                 pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta);
        !           188:                 pulDst += 4;
        !           189:             }
        !           190:         }
        !           191:         else
        !           192:         {
        !           193:             pjSrc = (BYTE*) psoPattern->pvScan0;
        !           194:             pjDst = (BYTE*) pulRBits;
        !           195: 
        !           196:             DISPDBG((1, "8bpp xlate "));
        !           197: 
        !           198:             // 8bpp translate case:
        !           199: 
        !           200:             for (i = 8; i > 0; i--)
        !           201:             {
        !           202:                 for (j = 8; j > 0; j--)
        !           203:                 {
        !           204:                     *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc++];
        !           205:                 }
        !           206: 
        !           207:                 pjSrc += psoPattern->lDelta - 8;
        !           208:             }
        !           209:         }
        !           210:     }
        !           211:     else
        !           212:     {
        !           213:         DISPDBG((1, "4bpp xlate "));
        !           214: 
        !           215:         ASSERTVGA(psoPattern->iBitmapFormat == BMF_4BPP, "Extra case added?");
        !           216: 
        !           217:         // 4bpp case:
        !           218: 
        !           219:         pjSrc = (BYTE*) psoPattern->pvScan0;
        !           220:         pjDst = (BYTE*) pulRBits;
        !           221: 
        !           222:         for (i = 8; i > 0; i--)
        !           223:         {
        !           224:             // Inner loop is repeated only 4 times because each loop handles
        !           225:             // 2 pixels:
        !           226: 
        !           227:             for (j = 4; j > 0; j--)
        !           228:             {
        !           229:                 *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc >> 4];
        !           230:                 *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc & 15];
        !           231:                 pjSrc++;
        !           232:             }
        !           233: 
        !           234:             pjSrc += psoPattern->lDelta - 4;
        !           235:         }
        !           236:     }
        !           237: 
        !           238:     // We want to check if the 4bpp or 8bpp patterns are actually
        !           239:     // only two colors:
        !           240: 
        !           241:     if (b2ColorBrush(pulRBits, &jFgColor, &jBkColor))
        !           242:     {
        !           243:         DISPDBG((1, "2 color "));
        !           244: 
        !           245:         // ??? We could actually also handle this case even if we have only
        !           246:         // 1 r/w window in planar format:
        !           247: 
        !           248:         prb->xBrush    = 0;
        !           249:         prb->ulBkColor = (ULONG) jBkColor;
        !           250:         prb->ulFgColor = (ULONG) jFgColor;
        !           251:         prb->fl        = RBRUSH_2COLOR;
        !           252: 
        !           253:         if (jFgColor == 0x00 && jBkColor == 0xff)
        !           254:         {
        !           255:             // Monochrome brushes always have to have the '0' bits
        !           256:             // as black and the '1' bits as white, so we'll have to
        !           257:             // invert the 1bpp pattern:
        !           258: 
        !           259:             prb->fl = RBRUSH_BLACKWHITE;
        !           260:             for (i = 0; i < 8; i++)
        !           261:             {
        !           262:                 prb->aulPattern[i] = ~prb->aulPattern[i];
        !           263:             }
        !           264:         }
        !           265: 
        !           266:         return(TRUE);
        !           267:     }
        !           268: 
        !           269:     // For n-color brushes, we maintain a brush cache in offscreen memory.
        !           270:     // If the DRIVER_USE_OFFSCREEN flag isn't set (i.e., the offscreen
        !           271:     // memory isn't being refreshed), the cache is pretty useless.  In that
        !           272:     // case, we simply disable n-color patterns:
        !           273: 
        !           274:     if ((ppdev->fl & DRIVER_USE_OFFSCREEN) == 0)
        !           275:     {
        !           276:         return(FALSE);
        !           277:     }
        !           278: 
        !           279:     prb->fl     = RBRUSH_NCOLOR;
        !           280:     prb->cy     = 8;
        !           281:     prb->cyLog2 = 3;
        !           282: 
        !           283:     // xBrush is the brush alignment for the cached brush, and this value
        !           284:     // will get compared to (pptlBrush->x & 7) to see if the cache brush
        !           285:     // is correctly aligned with the brush requested.  Since it will never
        !           286:     // match with -1, the brush will be correctly aligned and placed in
        !           287:     // the cache (which, of course, is what we want to finish our
        !           288:     // initialization):
        !           289: 
        !           290:     prb->xBrush = -1;
        !           291: 
        !           292:     // Copy those bitmap bits:
        !           293: 
        !           294:     // See if pattern is really only 4 scans long:
        !           295: 
        !           296:     if (pulRBits[0] == pulRBits[8]  && pulRBits[1] == pulRBits[9]  &&
        !           297:         pulRBits[2] == pulRBits[10] && pulRBits[3] == pulRBits[11] &&
        !           298:         pulRBits[4] == pulRBits[12] && pulRBits[5] == pulRBits[13] &&
        !           299:         pulRBits[6] == pulRBits[14] && pulRBits[7] == pulRBits[15])
        !           300:     {
        !           301:         prb->cy     = 4;
        !           302:         prb->cyLog2 = 2;
        !           303: 
        !           304:         // See if pattern is really only 2 scans long:
        !           305: 
        !           306:         if (pulRBits[0] == pulRBits[4] && pulRBits[1] == pulRBits[5] &&
        !           307:             pulRBits[2] == pulRBits[6] && pulRBits[3] == pulRBits[7])
        !           308:         {
        !           309:             DISPDBG((1, "cy = 2 "));
        !           310: 
        !           311:             prb->cy     = 2;
        !           312:             prb->cyLog2 = 1;
        !           313:         }
        !           314:         else
        !           315:         {
        !           316:             DISPDBG((1, "cy = 4 "));
        !           317:         }
        !           318:     }
        !           319: 
        !           320:     // See if pattern is really only 4 pels wide:
        !           321: 
        !           322:     pulDst = pulRBits;
        !           323:     for (i = prb->cy / 2; i > 0; i--)
        !           324:     {
        !           325:         if (*(pulDst    ) != *(pulDst + 1) ||
        !           326:             *(pulDst + 2) != *(pulDst + 3))
        !           327:             goto done_this_realize_brush_stuff;
        !           328: 
        !           329:         pulDst += 4;
        !           330:     }
        !           331: 
        !           332:     DISPDBG((1, "4pels wide"));
        !           333: 
        !           334:     prb->fl |= RBRUSH_4PELS_WIDE;
        !           335: 
        !           336: done_this_realize_brush_stuff:
        !           337: 
        !           338:     return(TRUE);
        !           339: }

unix.superglobalmegacorp.com

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