Esempio n. 1
0
VOID
FASTCALL
IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color)
{
    PBRUSH pbrPen;

    pbrPen = PEN_ShareLockPen(hPen);
    if (pbrPen)
    {
        if (pbrPen->flAttrs & BR_IS_SOLID)
        {
            pbrPen->BrushAttr.lbColor = Color & 0xFFFFFF;
        }
        PEN_ShareUnlockPen(pbrPen);
    }
}
Esempio n. 2
0
BOOL
FASTCALL
IntRoundRect(
    PDC  dc,
    int  Left,
    int  Top,
    int  Right,
    int  Bottom,
    int  xCurveDiameter,
    int  yCurveDiameter)
{
    PDC_ATTR pdcattr;
    PBRUSH   pbrLine, pbrFill;
    RECTL RectBounds;
    LONG PenWidth, PenOrigWidth;
    BOOL ret = TRUE; // Default to success
    BRUSH brushTemp;

    ASSERT ( dc ); // Caller's responsibility to set this up

    if ( PATH_IsPathOpen(dc->dclevel) )
        return PATH_RoundRect ( dc, Left, Top, Right, Bottom,
                                xCurveDiameter, yCurveDiameter );

    if ((Left == Right) || (Top == Bottom)) return TRUE;

    xCurveDiameter = max(abs( xCurveDiameter ), 1);
    yCurveDiameter = max(abs( yCurveDiameter ), 1);

    if (Right < Left)
    {
       INT tmp = Right; Right = Left; Left = tmp;
    }
    if (Bottom < Top)
    {
       INT tmp = Bottom; Bottom = Top; Top = tmp;
    }

    pdcattr = dc->pdcattr;

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

    pbrLine = PEN_ShareLockPen(pdcattr->hpen);
    if (!pbrLine)
    {
        /* Nothing to do, as we don't have a bitmap */
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    PenOrigWidth = PenWidth = pbrLine->ptPenWidth.x;
    if (pbrLine->ulPenStyle == PS_NULL) PenWidth = 0;

    if (pbrLine->ulPenStyle == PS_INSIDEFRAME)
    {
       if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
       if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
       Left   += PenWidth / 2;
       Right  -= (PenWidth - 1) / 2;
       Top    += PenWidth / 2;
       Bottom -= (PenWidth - 1) / 2;
    }

    if (!PenWidth) PenWidth = 1;
    pbrLine->ptPenWidth.x = PenWidth;

    RectBounds.left = Left;
    RectBounds.top = Top;
    RectBounds.right = Right;
    RectBounds.bottom = Bottom;

    IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);

    RectBounds.left   += dc->ptlDCOrig.x;
    RectBounds.top    += dc->ptlDCOrig.y;
    RectBounds.right  += dc->ptlDCOrig.x;
    RectBounds.bottom += dc->ptlDCOrig.y;

    pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
    if (!pbrFill)
    {
        DPRINT1("FillRound Fail\n");
        EngSetLastError(ERROR_INTERNAL_ERROR);
        ret = FALSE;
    }
    else
    {

        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);

        RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp));
        brushTemp.ptOrigin.x += RectBounds.left - Left;
        brushTemp.ptOrigin.y += RectBounds.top - Top;
        ret = IntFillRoundRect( dc,
                                RectBounds.left,
                                RectBounds.top,
                                RectBounds.right,
                                RectBounds.bottom,
                                xCurveDiameter,
                                yCurveDiameter,
                                &brushTemp);
        BRUSH_ShareUnlockBrush(pbrFill);

        if (ret)
        {
           ret = IntDrawRoundRect( dc,
                      RectBounds.left,
                       RectBounds.top,
                     RectBounds.right,
                    RectBounds.bottom,
                       xCurveDiameter,
                       yCurveDiameter,
                       pbrLine);
        }

        DC_vFinishBlit(dc, NULL);
    }


    pbrLine->ptPenWidth.x = PenOrigWidth;
    PEN_ShareUnlockPen(pbrLine);
    return ret;
}
Esempio n. 3
0
BOOL APIENTRY
NtGdiEllipse(
    HDC hDC,
    int Left,
    int Top,
    int Right,
    int Bottom)
{
    PDC dc;
    PDC_ATTR pdcattr;
    RECTL RectBounds;
    PBRUSH pbrush;
    BOOL ret = TRUE;
    LONG PenWidth, PenOrigWidth;
    LONG RadiusX, RadiusY, CenterX, CenterY;
    PBRUSH pFillBrushObj;
    BRUSH tmpFillBrushObj;

    if ((Left == Right) || (Top == Bottom)) return TRUE;

    dc = DC_LockDc(hDC);
    if (dc == NULL)
    {
       EngSetLastError(ERROR_INVALID_HANDLE);
       return FALSE;
    }
    if (dc->dctype == DC_TYPE_INFO)
    {
       DC_UnlockDc(dc);
       /* Yes, Windows really returns TRUE in this case */
       return TRUE;
    }

    if (PATH_IsPathOpen(dc->dclevel))
    {
        ret = PATH_Ellipse(dc, Left, Top, Right, Bottom);
        DC_UnlockDc(dc);
        return ret;
    }

    if (Right < Left)
    {
       INT tmp = Right; Right = Left; Left = tmp;
    }
    if (Bottom < Top)
    {
       INT tmp = Bottom; Bottom = Top; Top = tmp;
    }

    pdcattr = dc->pdcattr;

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

    pbrush = PEN_ShareLockPen(pdcattr->hpen);
    if (!pbrush)
    {
        DPRINT1("Ellipse Fail 1\n");
        DC_UnlockDc(dc);
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    PenOrigWidth = PenWidth = pbrush->ptPenWidth.x;
    if (pbrush->ulPenStyle == PS_NULL) PenWidth = 0;

    if (pbrush->ulPenStyle == PS_INSIDEFRAME)
    {
       if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
       if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
       Left   += PenWidth / 2;
       Right  -= (PenWidth - 1) / 2;
       Top    += PenWidth / 2;
       Bottom -= (PenWidth - 1) / 2;
    }

    if (!PenWidth) PenWidth = 1;
    pbrush->ptPenWidth.x = PenWidth;

    RectBounds.left   = Left;
    RectBounds.right  = Right;
    RectBounds.top    = Top;
    RectBounds.bottom = Bottom;

    IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);

    RectBounds.left += dc->ptlDCOrig.x;
    RectBounds.right += dc->ptlDCOrig.x;
    RectBounds.top += dc->ptlDCOrig.y;
    RectBounds.bottom += dc->ptlDCOrig.y;

    // Setup for dynamic width and height.
    RadiusX = max((RectBounds.right - RectBounds.left) / 2, 2); // Needs room
    RadiusY = max((RectBounds.bottom - RectBounds.top) / 2, 2);
    CenterX = (RectBounds.right + RectBounds.left) / 2;
    CenterY = (RectBounds.bottom + RectBounds.top) / 2;

    DPRINT("Ellipse 1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
               RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);

    DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n",
               CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);

    pFillBrushObj = BRUSH_ShareLockBrush(pdcattr->hbrush);
    if (NULL == pFillBrushObj)
    {
        DPRINT1("FillEllipse Fail\n");
        EngSetLastError(ERROR_INTERNAL_ERROR);
        ret = FALSE;
    }
    else
    {
        RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj));
        //tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left;
        //tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
        tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
        tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;

        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);

        ret = IntFillEllipse( dc,
                              CenterX - RadiusX,
                              CenterY - RadiusY,
                              RadiusX*2, // Width
                              RadiusY*2, // Height
                              &tmpFillBrushObj);
        BRUSH_ShareUnlockBrush(pFillBrushObj);

        if (ret)
        {
           ret = IntDrawEllipse( dc,
                                 CenterX - RadiusX,
                                 CenterY - RadiusY,
                                 RadiusX*2, // Width
                                 RadiusY*2, // Height
                                 pbrush);
        }

        DC_vFinishBlit(dc, NULL);
    }

    pbrush->ptPenWidth.x = PenOrigWidth;
    PEN_ShareUnlockPen(pbrush);
    DC_UnlockDc(dc);
    DPRINT("Ellipse Exit.\n");
    return ret;
}
Esempio n. 4
0
static
BOOL
FASTCALL
IntArc( DC *dc,
        int  Left,
        int  Top,
        int  Right,
        int  Bottom,
        int  XRadialStart,
        int  YRadialStart,
        int  XRadialEnd,
        int  YRadialEnd,
        ARCTYPE arctype)
{
    PDC_ATTR pdcattr;
    RECTL RectBounds, RectSEpts;
    PBRUSH pbrPen;
    SURFACE *psurf;
    BOOL ret = TRUE;
    LONG PenWidth, PenOrigWidth;
    double AngleStart, AngleEnd;
    LONG RadiusX, RadiusY, CenterX, CenterY;
    LONG SfCx, SfCy, EfCx, EfCy;

    if (Right < Left)
    {
       INT tmp = Right; Right = Left; Left = tmp;
    }
    if (Bottom < Top)
    {
       INT tmp = Bottom; Bottom = Top; Top = tmp;
    }

    /* Check if the target rect is empty */
    if ((Left == Right) || (Top == Bottom)) return TRUE;

    // FIXME: this needs to be verified
    if ((arctype == GdiTypeChord ) || (arctype == GdiTypePie))
    {
        if ((Right - Left == 1) || (Bottom - Top == 1))
           return TRUE;
    }


    pdcattr = dc->pdcattr;

    pbrPen = PEN_ShareLockPen(pdcattr->hpen);
    if (!pbrPen)
    {
        DPRINT1("Arc Fail 1\n");
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    PenOrigWidth = PenWidth = pbrPen->ptPenWidth.x;
    if (pbrPen->ulPenStyle == PS_NULL) PenWidth = 0;

    if (pbrPen->ulPenStyle == PS_INSIDEFRAME)
    {
       if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
       if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
       Left   += PenWidth / 2;
       Right  -= (PenWidth - 1) / 2;
       Top    += PenWidth / 2;
       Bottom -= (PenWidth - 1) / 2;
    }

    if (!PenWidth) PenWidth = 1;
    pbrPen->ptPenWidth.x = PenWidth;

    RectBounds.left   = Left;
    RectBounds.right  = Right;
    RectBounds.top    = Top;
    RectBounds.bottom = Bottom;

    RectSEpts.left   = XRadialStart;
    RectSEpts.top    = YRadialStart;
    RectSEpts.right  = XRadialEnd;
    RectSEpts.bottom = YRadialEnd;

    IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
    IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2);

    RectBounds.left   += dc->ptlDCOrig.x;
    RectBounds.right  += dc->ptlDCOrig.x;
    RectBounds.top    += dc->ptlDCOrig.y;
    RectBounds.bottom += dc->ptlDCOrig.y;

    RectSEpts.left    += dc->ptlDCOrig.x;
    RectSEpts.top     += dc->ptlDCOrig.y;
    RectSEpts.right   += dc->ptlDCOrig.x;
    RectSEpts.bottom  += dc->ptlDCOrig.y;

    DPRINT("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
               RectSEpts.left,RectSEpts.top,RectSEpts.right,RectSEpts.bottom);

    DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
               RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);

    RadiusX = max((RectBounds.right - RectBounds.left) / 2, 1);
    RadiusY = max((RectBounds.bottom - RectBounds.top) / 2, 1);
    CenterX = (RectBounds.right + RectBounds.left) / 2;
    CenterY = (RectBounds.bottom + RectBounds.top) / 2;
    AngleEnd   = atan2((RectSEpts.bottom - CenterY), RectSEpts.right - CenterX)*(360.0/(M_PI*2));
    AngleStart = atan2((RectSEpts.top - CenterY), RectSEpts.left - CenterX)*(360.0/(M_PI*2));

    /* Edge Case: Check if the start segments overlaps(is equal) the end segment */
    if (AngleEnd == AngleStart)
    {
        AngleStart = AngleEnd + 360.0; // Arc(), ArcTo(), Pie() and Chord() are counterclockwise APIs.
    }

    SfCx = (LONG)(Rcos(AngleStart) * RadiusX);
    SfCy = (LONG)(Rsin(AngleStart) * RadiusY);
    EfCx = (LONG)(Rcos(AngleEnd) * RadiusX);
    EfCy = (LONG)(Rsin(AngleEnd) * RadiusY);

    if ((arctype == GdiTypePie) || (arctype == GdiTypeChord))
    {
        ret = IntFillArc( dc,
              RectBounds.left,
              RectBounds.top,
              abs(RectBounds.right-RectBounds.left), // Width
              abs(RectBounds.bottom-RectBounds.top), // Height
              AngleStart,
              AngleEnd,
              arctype);
    }

    ret = IntDrawArc( dc,
              RectBounds.left,
              RectBounds.top,
              abs(RectBounds.right-RectBounds.left), // Width
              abs(RectBounds.bottom-RectBounds.top), // Height
              AngleStart,
              AngleEnd,
              arctype,
              pbrPen);

    psurf = dc->dclevel.pSurface;
    if (NULL == psurf)
    {
        DPRINT1("Arc Fail 2\n");
        PEN_ShareUnlockPen(pbrPen);
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    if (arctype == GdiTypePie)
    {
       PUTLINE(CenterX, CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);
       PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, dc->eboLine);
    }
    if (arctype == GdiTypeChord)
        PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);

    pbrPen->ptPenWidth.x = PenOrigWidth;
    PEN_ShareUnlockPen(pbrPen);
    DPRINT("IntArc Exit.\n");
    return ret;
}