Example #1
0
/* Same as DrawEdge invoked with BF_DIAGONAL */
BOOL FASTCALL IntDrawDiagEdge(HDC hdc, LPRECT rc, UINT uType, UINT uFlags)
{
    POINT Points[4];
    signed char InnerI, OuterI;
    HPEN InnerPen, OuterPen;
    POINT SavePoint;
    HPEN SavePen;
    int spx, spy;
    int epx, epy;
    int Width = rc->right - rc->left;
    int Height= rc->bottom - rc->top;
    int SmallDiam = Width > Height ? Height : Width;
    BOOL retval = !(   ((uType & BDR_INNER) == BDR_INNER
                        || (uType & BDR_OUTER) == BDR_OUTER)
                       && !(uFlags & (BF_FLAT|BF_MONO)) );
    int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
                  + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);

    /* Init some vars */
    OuterPen = InnerPen = (HPEN)NtGdiGetStockObject(NULL_PEN);
    SavePen = (HPEN)NtGdiSelectPen(hdc, InnerPen);
    spx = spy = epx = epy = 0; /* Satisfy the compiler... */

    /* Determine the colors of the edges */
    if(uFlags & BF_MONO)
    {
        InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
        OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
    }
    else if(uFlags & BF_FLAT)
    {
        InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
        OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
    }
    else if(uFlags & BF_SOFT)
    {
        if(uFlags & BF_BOTTOM)
        {
            InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
            OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
        }
        else
        {
            InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
            OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
        }
    }
    else
    {
        if(uFlags & BF_BOTTOM)
        {
            InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
            OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
        }
        else
        {
            InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
            OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
        }
    }

    if(InnerI != -1)
        InnerPen = NtGdiGetStockObject(DC_PEN);
    if(OuterI != -1)
        OuterPen = NtGdiGetStockObject(DC_PEN);

    GreMoveTo(hdc, 0, 0, &SavePoint);

    /* Don't ask me why, but this is what is visible... */
    /* This must be possible to do much simpler, but I fail to */
    /* see the logic in the MS implementation (sigh...). */
    /* So, this might look a bit brute force here (and it is), but */
    /* it gets the job done;) */

    switch(uFlags & BF_RECT)
    {
        case 0:
        case BF_LEFT:
        case BF_BOTTOM:
        case BF_BOTTOMLEFT:
            /* Left bottom endpoint */
            epx = rc->left-1;
            spx = epx + SmallDiam;
            epy = rc->bottom;
            spy = epy - SmallDiam;
            break;

        case BF_TOPLEFT:
        case BF_BOTTOMRIGHT:
            /* Left top endpoint */
            epx = rc->left-1;
            spx = epx + SmallDiam;
            epy = rc->top-1;
            spy = epy + SmallDiam;
            break;

        case BF_TOP:
        case BF_RIGHT:
        case BF_TOPRIGHT:
        case BF_RIGHT|BF_LEFT:
        case BF_RIGHT|BF_LEFT|BF_TOP:
        case BF_BOTTOM|BF_TOP:
        case BF_BOTTOM|BF_TOP|BF_LEFT:
        case BF_BOTTOMRIGHT|BF_LEFT:
        case BF_BOTTOMRIGHT|BF_TOP:
        case BF_RECT:
            /* Right top endpoint */
            spx = rc->left;
            epx = spx + SmallDiam;
            spy = rc->bottom-1;
            epy = spy - SmallDiam;
            break;
    }

    GreMoveTo(hdc, spx, spy, NULL);
    NtGdiSelectPen(hdc, OuterPen);
    IntSetDCPenColor(hdc, IntGetSysColor(OuterI));
    NtGdiLineTo(hdc, epx, epy);

    NtGdiSelectPen(hdc, InnerPen);
    IntSetDCPenColor(hdc, IntGetSysColor(InnerI));

    switch(uFlags & (BF_RECT|BF_DIAGONAL))
    {
        case BF_DIAGONAL_ENDBOTTOMLEFT:
        case (BF_DIAGONAL|BF_BOTTOM):
                    case BF_DIAGONAL:
                        case (BF_DIAGONAL|BF_LEFT):
                                GreMoveTo(hdc, spx-1, spy, NULL);
            NtGdiLineTo(hdc, epx, epy-1);
            Points[0].x = spx-add;
            Points[0].y = spy;
            Points[1].x = rc->left;
            Points[1].y = rc->top;
            Points[2].x = epx+1;
            Points[2].y = epy-1-add;
            Points[3] = Points[2];
            break;

        case BF_DIAGONAL_ENDBOTTOMRIGHT:
            GreMoveTo(hdc, spx-1, spy, NULL);
            NtGdiLineTo(hdc, epx, epy+1);
            Points[0].x = spx-add;
            Points[0].y = spy;
            Points[1].x = rc->left;
            Points[1].y = rc->bottom-1;
            Points[2].x = epx+1;
            Points[2].y = epy+1+add;
            Points[3] = Points[2];
            break;

        case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP):
                    case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT):
                        case BF_DIAGONAL_ENDTOPRIGHT:
                            case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT):
                                    GreMoveTo(hdc, spx+1, spy, NULL);
            NtGdiLineTo(hdc, epx, epy+1);
            Points[0].x = epx-1;
            Points[0].y = epy+1+add;
            Points[1].x = rc->right-1;
            Points[1].y = rc->top+add;
            Points[2].x = rc->right-1;
            Points[2].y = rc->bottom-1;
            Points[3].x = spx+add;
            Points[3].y = spy;
            break;

        case BF_DIAGONAL_ENDTOPLEFT:
            GreMoveTo(hdc, spx, spy-1, NULL);
            NtGdiLineTo(hdc, epx+1, epy);
            Points[0].x = epx+1+add;
            Points[0].y = epy+1;
            Points[1].x = rc->right-1;
            Points[1].y = rc->top;
            Points[2].x = rc->right-1;
            Points[2].y = rc->bottom-1-add;
            Points[3].x = spx;
            Points[3].y = spy-add;
            break;

        case (BF_DIAGONAL|BF_TOP):
                    case (BF_DIAGONAL|BF_BOTTOM|BF_TOP):
                        case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT):
                                GreMoveTo(hdc, spx+1, spy-1, NULL);
            NtGdiLineTo(hdc, epx, epy);
            Points[0].x = epx-1;
            Points[0].y = epy+1;
            Points[1].x = rc->right-1;
            Points[1].y = rc->top;
            Points[2].x = rc->right-1;
            Points[2].y = rc->bottom-1-add;
            Points[3].x = spx+add;
            Points[3].y = spy-add;
            break;

        case (BF_DIAGONAL|BF_RIGHT):
                    case (BF_DIAGONAL|BF_RIGHT|BF_LEFT):
                        case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM):
                                GreMoveTo(hdc, spx, spy, NULL);
            NtGdiLineTo(hdc, epx-1, epy+1);
            Points[0].x = spx;
            Points[0].y = spy;
            Points[1].x = rc->left;
            Points[1].y = rc->top+add;
            Points[2].x = epx-1-add;
            Points[2].y = epy+1+add;
            Points[3] = Points[2];
            break;
    }

    /* Fill the interior if asked */
    if((uFlags & BF_MIDDLE) && retval)
    {
        HBRUSH hbsave;
        HPEN hpsave;
        hbsave = (HBRUSH)NtGdiSelectBrush(hdc, NtGdiGetStockObject(DC_BRUSH));
        hpsave = (HPEN)NtGdiSelectPen(hdc, NtGdiGetStockObject(DC_PEN));
        IntSetDCBrushColor(hdc, IntGetSysColor(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE));
        IntSetDCPenColor(hdc, IntGetSysColor(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE));
        IntPolygon(hdc, Points, 4);
        NtGdiSelectBrush(hdc, hbsave);
        NtGdiSelectPen(hdc, hpsave);
    }

    /* Adjust rectangle if asked */
    if(uFlags & BF_ADJUST)
    {
        if(uFlags & BF_LEFT)
            rc->left   += add;
        if(uFlags & BF_RIGHT)
            rc->right  -= add;
        if(uFlags & BF_TOP)
            rc->top    += add;
        if(uFlags & BF_BOTTOM)
            rc->bottom -= add;
    }

    /* Cleanup */
    NtGdiSelectPen(hdc, SavePen);
    GreMoveTo(hdc, SavePoint.x, SavePoint.y, NULL);

    return retval;
}
Example #2
0
INT
Test_NtGdiSelectPen(PTESTINFO pti)
{
	HDC hDC;
	HPEN hPen, hOldPen;
	LOGBRUSH logbrush;

	hDC = GetDC(NULL);
	ASSERT(hDC);

	hPen = GetStockObject(WHITE_PEN);

	/* Test NULL DC */
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen(NULL, hPen);
	TEST(hOldPen == NULL);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test invalid DC */
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen((HDC)((ULONG_PTR)hDC & 0x0000ffff), hPen);
	TEST(hOldPen == NULL);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test NULL pen */
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen(hDC, NULL);
	TEST(hOldPen == NULL);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test invalid pen */
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen(hDC, (HPEN)((ULONG_PTR)hPen & 0x0000ffff));
	TEST(hOldPen == NULL);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test valid pen */
	SelectObject(hDC, GetStockObject(BLACK_PEN));
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen(hDC, hPen);
	TEST(hOldPen == GetStockObject(BLACK_PEN));
	hOldPen = NtGdiSelectPen(hDC, hOldPen);
	TEST(hOldPen == hPen);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test extpen */
	SetLastError(ERROR_SUCCESS);
	logbrush.lbStyle = BS_SOLID;
	logbrush.lbColor = RGB(0x12,0x34,0x56);
	hPen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &logbrush, 0, NULL);
	ASSERT(hPen);
	hOldPen = NtGdiSelectPen(hDC, hPen);
	TEST(hOldPen != NULL);
	hOldPen = NtGdiSelectPen(hDC, hOldPen);
	TEST(hOldPen == hPen);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test deleting pen */
	SetLastError(ERROR_SUCCESS);
	hOldPen = NtGdiSelectPen(hDC, hPen);
	TEST(DeleteObject(hPen) == 1);
	hOldPen = NtGdiSelectPen(hDC, hOldPen);
	TEST(hOldPen == hPen);
	TEST(GetLastError() == ERROR_SUCCESS);

	/* Test that fallback pen is BLACK_PEN */

	DeleteDC(hDC);

	return APISTATUS_NORMAL;
}
Example #3
0
/* Same as DrawEdge invoked without BF_DIAGONAL
 *
 * 23-Nov-1997: Changed by Bertho Stultiens
 *
 * Well, I started testing this and found out that there are a few things
 * that weren't quite as win95. The following rewrite should reproduce
 * win95 results completely.
 * The colorselection is table-driven to avoid awfull if-statements.
 * The table below show the color settings.
 *
 * Pen selection table for uFlags = 0
 *
 * uType |  LTI  |  LTO  |  RBI  |  RBO
 * ------+-------+-------+-------+-------
 *  0000 |   x   |   x   |   x   |   x
 *  0001 |   x   |  22   |   x   |  21
 *  0010 |   x   |  16   |   x   |  20
 *  0011 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  0100 |   x   |  20   |   x   |  16
 *  0101 |  20   |  22   |  16   |  21
 *  0110 |  20   |  16   |  16   |  20
 *  0111 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  1000 |   x   |  21   |   x   |  22
 *  1001 |  21   |  22   |  22   |  21
 *  1010 |  21   |  16   |  22   |  20
 *  1011 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  1100 |   x   |   x   |   x   |   x
 *  1101 |   x   | x (22)|   x   | x (21)
 *  1110 |   x   | x (16)|   x   | x (20)
 *  1111 |   x   |   x   |   x   |   x
 *
 * Pen selection table for uFlags = BF_SOFT
 *
 * uType |  LTI  |  LTO  |  RBI  |  RBO
 * ------+-------+-------+-------+-------
 *  0000 |   x   |   x   |   x   |   x
 *  0001 |   x   |  20   |   x   |  21
 *  0010 |   x   |  21   |   x   |  20
 *  0011 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  0100 |   x   |  22   |   x   |  16
 *  0101 |  22   |  20   |  16   |  21
 *  0110 |  22   |  21   |  16   |  20
 *  0111 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  1000 |   x   |  16   |   x   |  22
 *  1001 |  16   |  20   |  22   |  21
 *  1010 |  16   |  21   |  22   |  20
 *  1011 |   x   |   x   |   x   |   x
 * ------+-------+-------+-------+-------
 *  1100 |   x   |   x   |   x   |   x
 *  1101 |   x   | x (20)|   x   | x (21)
 *  1110 |   x   | x (21)|   x   | x (20)
 *  1111 |   x   |   x   |   x   |   x
 *
 * x = don't care; (n) = is what win95 actually uses
 * LTI = left Top Inner line
 * LTO = left Top Outer line
 * RBI = Right Bottom Inner line
 * RBO = Right Bottom Outer line
 * 15 = COLOR_BTNFACE
 * 16 = COLOR_BTNSHADOW
 * 20 = COLOR_BTNHIGHLIGHT
 * 21 = COLOR_3DDKSHADOW
 * 22 = COLOR_3DLIGHT
 */
BOOL FASTCALL IntDrawRectEdge(HDC hdc, LPRECT rc, UINT uType, UINT uFlags)
{
    signed char LTInnerI, LTOuterI;
    signed char RBInnerI, RBOuterI;
    HPEN LTInnerPen, LTOuterPen;
    HPEN RBInnerPen, RBOuterPen;
    RECT InnerRect = *rc;
    POINT SavePoint;
    HPEN SavePen;
    int LBpenplus = 0;
    int LTpenplus = 0;
    int RTpenplus = 0;
    int RBpenplus = 0;
    BOOL retval = !(   ((uType & BDR_INNER) == BDR_INNER
                        || (uType & BDR_OUTER) == BDR_OUTER)
                       && !(uFlags & (BF_FLAT|BF_MONO)) );
    /* Init some vars */
    LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)NtGdiGetStockObject(NULL_PEN);
    SavePen = (HPEN)NtGdiSelectPen(hdc, LTInnerPen);

    /* Determine the colors of the edges */
    if(uFlags & BF_MONO)
    {
        LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
        LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
    }
    else if(uFlags & BF_FLAT)
    {
        LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
        LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];

        /* Bertho Stultiens states above that this function exactly matches win95
         * In win98 BF_FLAT rectangles have an inner border same color as the
        * middle (COLOR_BTNFACE). I believe it's the same for win95 but since
        * I don't know I go with Bertho and just sets it for win98 until proven
        * otherwise.
        *                                          Dennis Björklund, 10 June, 99
        */
        if( LTInnerI != -1 )
            LTInnerI = RBInnerI = COLOR_BTNFACE;
    }
    else if(uFlags & BF_SOFT)
    {
        LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
        LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
        RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
        RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
    }
    else
    {
        LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
        LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
        RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
        RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
    }

    if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT)
        LBpenplus = 1;
    if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT)
        RTpenplus = 1;
    if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT)
        RBpenplus = 1;
    if((uFlags & BF_TOPLEFT) == BF_TOPLEFT)
        LTpenplus = 1;

    if(LTInnerI != -1)
        LTInnerPen = NtGdiGetStockObject(DC_PEN);
    if(LTOuterI != -1)
        LTOuterPen = NtGdiGetStockObject(DC_PEN);
    if(RBInnerI != -1)
        RBInnerPen = NtGdiGetStockObject(DC_PEN);
    if(RBOuterI != -1)
        RBOuterPen = NtGdiGetStockObject(DC_PEN);
    if((uFlags & BF_MIDDLE) && retval)
    {
        FillRect(hdc, &InnerRect, IntGetSysColorBrush(uFlags & BF_MONO ?
                 COLOR_WINDOW : COLOR_BTNFACE));
    }
    GreMoveTo(hdc, 0, 0, &SavePoint);

    /* Draw the outer edge */
    NtGdiSelectPen(hdc, LTOuterPen);
    IntSetDCPenColor(hdc, IntGetSysColor(LTOuterI));
    if(uFlags & BF_TOP)
    {
        GreMoveTo(hdc, InnerRect.left, InnerRect.top, NULL);
        NtGdiLineTo(hdc, InnerRect.right, InnerRect.top);
    }
    if(uFlags & BF_LEFT)
    {
        GreMoveTo(hdc, InnerRect.left, InnerRect.top, NULL);
        NtGdiLineTo(hdc, InnerRect.left, InnerRect.bottom);
    }
    NtGdiSelectPen(hdc, RBOuterPen);
    IntSetDCPenColor(hdc, IntGetSysColor(RBOuterI));
    if(uFlags & BF_BOTTOM)
    {
        GreMoveTo(hdc, InnerRect.left, InnerRect.bottom-1, NULL);
        NtGdiLineTo(hdc, InnerRect.right, InnerRect.bottom-1);
    }
    if(uFlags & BF_RIGHT)
    {
        GreMoveTo(hdc, InnerRect.right-1, InnerRect.top, NULL);
        NtGdiLineTo(hdc, InnerRect.right-1, InnerRect.bottom);
    }

    /* Draw the inner edge */
    NtGdiSelectPen(hdc, LTInnerPen);
    IntSetDCPenColor(hdc, IntGetSysColor(LTInnerI));
    if(uFlags & BF_TOP)
    {
        GreMoveTo(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL);
        NtGdiLineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1);
    }
    if(uFlags & BF_LEFT)
    {
        GreMoveTo(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL);
        NtGdiLineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus);
    }
    NtGdiSelectPen(hdc, RBInnerPen);
    IntSetDCPenColor(hdc, IntGetSysColor(RBInnerI));
    if(uFlags & BF_BOTTOM)
    {
        GreMoveTo(hdc, InnerRect.left+LBpenplus, InnerRect.bottom-2, NULL);
        NtGdiLineTo(hdc, InnerRect.right-RBpenplus, InnerRect.bottom-2);
    }
    if(uFlags & BF_RIGHT)
    {
        GreMoveTo(hdc, InnerRect.right-2, InnerRect.top+RTpenplus, NULL);
        NtGdiLineTo(hdc, InnerRect.right-2, InnerRect.bottom-RBpenplus);
    }

    if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) )
    {
        int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
                      + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);

        if(uFlags & BF_LEFT)
            InnerRect.left += add;
        if(uFlags & BF_RIGHT)
            InnerRect.right -= add;
        if(uFlags & BF_TOP)
            InnerRect.top += add;
        if(uFlags & BF_BOTTOM)
            InnerRect.bottom -= add;

        if(uFlags & BF_ADJUST)
            *rc = InnerRect;
    }

    /* Cleanup */
    NtGdiSelectPen(hdc, SavePen);
    GreMoveTo(hdc, SavePoint.x, SavePoint.y, NULL);
    return retval;
}