File:  [WindowsNT SDKs] / ntddk / src / video / displays / vga / paint.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/******************************Module*Header*******************************\
* Module Name: paint.c
*
* DrvPaint
*
* Copyright (c) 1992 Microsoft Corporation
\**************************************************************************/
#include "driver.h"
#include "bitblt.h"

static DDAOBJ *gpdda = (DDAOBJ *) NULL;

/******************************Public*Data*********************************\
* MIX translation table
*
* Translates a mix 1-16, into an old style Rop 0-255.
*
\**************************************************************************/

BYTE gaMix[] =
{
    0xFF,  // R2_WHITE        - Allow rop = gaMix[mix & 0x0F]
    0x00,  // R2_BLACK
    0x05,  // R2_NOTMERGEPEN
    0x0A,  // R2_MASKNOTPEN
    0x0F,  // R2_NOTCOPYPEN
    0x50,  // R2_MASKPENNOT
    0x55,  // R2_NOT
    0x5A,  // R2_XORPEN
    0x5F,  // R2_NOTMASKPEN
    0xA0,  // R2_MASKPEN
    0xA5,  // R2_NOTXORPEN
    0xAA,  // R2_NOP
    0xAF,  // R2_MERGENOTPEN
    0xF0,  // R2_COPYPEN
    0xF5,  // R2_MERGEPENNOT
    0xFA,  // R2_MERGEPEN
    0xFF   // R2_WHITE
};

/******************************Public*Routine******************************\
* vTrgTrap(pdsurf, ptrap, mix, iColor)
*
* Blit to a trapezoid.
*
\**************************************************************************/

VOID vTrgTrap
(
    PDEVSURF   pdsurf,
    TRAPEZOID *ptrap,
    MIX        mix,
    ULONG      iColor,
    BRUSHINST  *pbri,
    POINTL     *pptlBrush
)
{
    DDAENUM ddae;
    RECTL   rcl[MAX_DDA_RECTS], *prcl;
    ULONG   culrcl;
    LONG   *px;
    LONG    yRow;
    VOID    (*pfnPatBlt)(PDEVSURF,ULONG,PRECTL,MIX, BRUSHINST *,PPOINTL);

    if (!DDAOBJ_bEnum(gpdda, (PVOID) ptrap, sizeof(ddae), (DDALIST *) &ddae,
            JD_ENUM_TRAPEZOID))
        return;

    if (pbri != (BRUSHINST *)NULL) {
        if (pbri->usStyle != BRI_MONO_PATTERN)
               pfnPatBlt = vClrPatBlt;
        else
            pfnPatBlt = vMonoPatBlt;
    }

    do {
        culrcl = 0;
        prcl = rcl;
        px = &ddae.axPairs[0];

        // Accumulate the rectangles for this trapezoid enumeration burst,
        // then send them to the solid filler as a group
        for (yRow = ddae.yTop; yRow < ddae.yBottom; yRow++) {
            if (*px < *(px+1)) {
                prcl->top    = yRow;
                prcl->left   = *px;
                prcl->bottom = yRow + 1;
                prcl++->right  = *(px+1);
                culrcl++;
            }

            px += 2;

        }

        // Draw the rectangles, if there are any
        if (culrcl > 0) {
            if (pbri == (BRUSHINST *)NULL)
                vTrgBlt(pdsurf, culrcl, rcl, mix, iColor);
            else
                (*pfnPatBlt)(pdsurf, culrcl, rcl, mix, pbri, pptlBrush);
        }

    } while (DDAOBJ_bEnum(gpdda, (PVOID) NULL, sizeof(ddae), (DDALIST *) &ddae,
            JD_ENUM_TRAPEZOID));
}

/******************************Public*Routine******************************\
* bPaintRgn
*
* Paint the clipping region with the specified color and mode
*
\**************************************************************************/

BOOL bPaintRgn
(
    SURFOBJ     *pso,
    CLIPOBJ     *pco,
    ULONG       iColor,
    MIX         mix,
    BRUSHINST   *pbri,
    POINTL      *pptlBrush
)
{
    RECT_ENUM      bben;
    BBENUMTRAP  bbent;
    PDEVSURF    pdsurf;
    ULONG       iRT;
    BOOL        bMore;
    VOID    (*pfnPatBlt)(PDEVSURF,ULONG,PRECTL,MIX, BRUSHINST *,PPOINTL);

    if (pbri != (BRUSHINST *)NULL) {
        if (pbri->usStyle != BRI_MONO_PATTERN)
               pfnPatBlt = vClrPatBlt;
        else
            pfnPatBlt = vMonoPatBlt;
    }

    // Get the target surface information.
    pdsurf = (PDEVSURF) pso->dhsurf;

    switch(pco->iMode) {

        case TC_RECTANGLES:

            // Rectangular clipping can be handled without enumeration.
            // Note that trivial clipping is not possible, since the clipping
            // region defines the area to fill
            if (pco->iDComplexity == DC_RECT) {
                if (pbri == (BRUSHINST *)NULL)
                    vTrgBlt(pdsurf, 1, &pco->rclBounds, mix, iColor);
                else
                    (*pfnPatBlt)(pdsurf, 1, &pco->rclBounds, mix, pbri,pptlBrush);

            } else {

                // Enumerate all the rectangles and draw them

                CLIPOBJ_cEnumStart(pco,TRUE,CT_RECTANGLES,CD_ANY,ENUM_RECT_LIMIT);

                do {
                    bMore = CLIPOBJ_bEnum(pco, sizeof(bben), (PVOID) &bben);

                    if (pbri == (BRUSHINST *)NULL)
                        vTrgBlt(pdsurf, bben.c, &bben.arcl[0], mix, iColor);
                    else
                        (*pfnPatBlt)(pdsurf, bben.c, &bben.arcl[0], mix, pbri,
                                pptlBrush);

                } while (bMore);
            }

            return(TRUE);

    case TC_TRAPEZOIDS:

        // !!! HACK - Get a DDA for trapezoid enumeration

        if ((gpdda = EngCreateDDA()) == NULL) {
            return(FALSE);
        }

        // Enumerate all the trapezoids and draw them

        CLIPOBJ_cEnumStart(pco,TRUE,CT_TRAPEZOIDS,CD_ANY,ENUM_RECT_LIMIT);

        do {
            bMore = CLIPOBJ_bEnum(pco, sizeof(bbent), (PVOID) &bbent);

            for (iRT = 0; iRT < bbent.c; iRT++)
                vTrgTrap(pdsurf, &bbent.atrap[iRT], mix, iColor, pbri,
                        pptlBrush);

        } while (bMore);

        EngDeleteDDA(gpdda);        // !!! Rest of above hack!

        return(TRUE);

    default:
        RIP("bPaintRgn: unhandled TC_xxx\n");
        return(FALSE);
    }
}


/******************************Public*Routine******************************\
* DrvPaint
*
* Paint the clipping region with the specified brush
*
\**************************************************************************/

BOOL DrvPaint
(
    SURFOBJ  *pso,
    CLIPOBJ  *pco,
    BRUSHOBJ *pbo,
    POINTL   *pptlBrush,
    MIX       mix
)
{
    ROP4        rop4;
    ULONG       iSolidColor;         // Solid color for solid brushes
    BRUSHINST   *pbri;               // Pointer to a brush instance

    pbri = (BRUSHINST *)NULL;
    iSolidColor = 0;

    // If the foreground and background mixes are the same,
    // (LATER or if there's no brush mask)
    // then see if we can use the solid brush accelerators

    if ((mix & 0xFF) == ((mix >> 8) & 0xFF)) {

        switch (mix & 0xFF) {
            case 0:
                break;

            // vTrgBlt can only handle solid color fills where if the
            // destination is inverted, no other action is also required
            case R2_MASKNOTPEN:
            case R2_NOTCOPYPEN:
            case R2_XORPEN:
            case R2_MASKPEN:
            case R2_NOTXORPEN:
            case R2_MERGENOTPEN:
            case R2_COPYPEN:
            case R2_MERGEPEN:
            case R2_NOTMERGEPEN:
            case R2_MASKPENNOT:
            case R2_NOTMASKPEN:
            case R2_MERGEPENNOT:

                // vTrgBlt can only handle solid color fills

                if (pbo->iSolidColor != 0xffffffff)
                    iSolidColor = pbo->iSolidColor;

                else
                {
                    // TrgBlt can only handle solid brushes, but let's
                    // see if we can use our special case pattern code.
                    //
                    if (pbo->pvRbrush == (PVOID)NULL)
                    {
                        pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo);

                        if (pbri == (BRUSHINST *)NULL)
                            break;
                    }
                    else
                    {
                        pbri = (BRUSHINST *)pbo->pvRbrush;
                    }

                    // We only support non-8 wide brushes with R2_COPYPEN

                    if (((mix & 0xFF) != R2_COPYPEN) && (pbri->RealWidth != 8))
                        break;

                }

            // Rops that are implicit solid colors

            case R2_NOT:
            case R2_WHITE:
            case R2_BLACK:

                // Brush color parameter doesn't matter for these rops

                return(bPaintRgn(pso, pco, iSolidColor, mix, pbri, pptlBrush));

            case R2_NOP:
                return(TRUE);

            default:
                break;
        }
    }

    rop4  = (gaMix[(mix >> 8) & 0x0F]) << 8;
    rop4 |= ((ULONG) gaMix[mix & 0x0F]);

    return(DrvBitBlt(
        pso,
        (SURFOBJ *) NULL,
        (SURFOBJ *) NULL,
        pco,
        (XLATEOBJ *) NULL,
        &pco->rclBounds,
        (POINTL *)  NULL,
        (POINTL *)  NULL,
        pbo,
        pptlBrush,
        rop4));
}

unix.superglobalmegacorp.com

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