示例#1
0
/*
 * @implemented
 */
BOOL
APIENTRY
EngAlphaBlend(IN SURFOBJ *psoDest,
              IN SURFOBJ *psoSource,
              IN CLIPOBJ *ClipRegion,
              IN XLATEOBJ *ColorTranslation,
              IN PRECTL DestRect,
              IN PRECTL SourceRect,
              IN BLENDOBJ *BlendObj)
{
    RECTL              InputRect;
    RECTL              OutputRect;
    RECTL              ClipRect;
    RECTL              CombinedRect;
    RECTL              Rect;
    POINTL             Translate;
    INTENG_ENTER_LEAVE EnterLeaveSource;
    INTENG_ENTER_LEAVE EnterLeaveDest;
    SURFOBJ*           InputObj;
    SURFOBJ*           OutputObj;
    LONG               ClippingType;
    RECT_ENUM          RectEnum;
    BOOL               EnumMore;
    INT                i;
    BOOLEAN            Ret;

    DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation);
    DPRINT("              DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
           DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
           SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
    DPRINT("              BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp,
           BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha,
           BlendObj->BlendFunction.AlphaFormat);

    /* Validate output */
    OutputRect = *DestRect;
    if (OutputRect.right < OutputRect.left)
    {
        OutputRect.left = DestRect->right;
        OutputRect.right = DestRect->left;
    }
    if (OutputRect.bottom < OutputRect.top)
    {
        OutputRect.left = DestRect->right;
        OutputRect.right = DestRect->left;
    }

    /* Validate input */
    InputRect = *SourceRect;
    if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
         (InputRect.left < 0) || (InputRect.right < 0) ||
         InputRect.right > psoSource->sizlBitmap.cx ||
         InputRect.bottom > psoSource->sizlBitmap.cy )
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (psoDest == psoSource &&
            !(OutputRect.left >= SourceRect->right || InputRect.left >= OutputRect.right ||
              OutputRect.top >= SourceRect->bottom || InputRect.top >= OutputRect.bottom))
    {
        DPRINT1("Source and destination rectangles overlap!\n");
        return FALSE;
    }

    if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
    {
        DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp);
        return FALSE;
    }
    if (BlendObj->BlendFunction.BlendFlags != 0)
    {
        DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags);
        return FALSE;
    }
    if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
    {
        DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat);
        return FALSE;
    }

    /* Check if there is anything to draw */
    if (ClipRegion != NULL &&
            (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
             ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
    {
        /* Nothing to do */
        return TRUE;
    }

    /* Now call the DIB function */
    if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
    {
        return FALSE;
    }
    InputRect.left +=  Translate.x;
    InputRect.right +=  Translate.x;
    InputRect.top +=  Translate.y;
    InputRect.bottom +=  Translate.y;

    if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
    {
        return FALSE;
    }
    OutputRect.left += Translate.x;
    OutputRect.right += Translate.x;
    OutputRect.top += Translate.y;
    OutputRect.bottom += Translate.y;

    Ret = FALSE;
    ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
    switch (ClippingType)
    {
        case DC_TRIVIAL:
            Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                      OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj);
            break;

        case DC_RECT:
            ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
            ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
            ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
            ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
            {
                Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
                Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
                Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
                Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
                Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                          OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj);
            }
            break;

        case DC_COMPLEX:
            Ret = TRUE;
            CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
            do
            {
                EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
                                         (PVOID) &RectEnum);

                for (i = 0; i < RectEnum.c; i++)
                {
                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                    {
                        Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
                        Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
                        Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
                        Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
                        Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                                  OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret;
                    }
                }
            }
            while (EnumMore);
            break;

        default:
            UNIMPLEMENTED;
            ASSERT(FALSE);
            break;
    }

    IntEngLeave(&EnterLeaveDest);
    IntEngLeave(&EnterLeaveSource);

    return Ret;
}
示例#2
0
文件: transblt.c 项目: RPG-7/reactos
BOOL
APIENTRY
EngTransparentBlt(
    SURFOBJ *psoDest,
    SURFOBJ *psoSource,
    CLIPOBJ *Clip,
    XLATEOBJ *ColorTranslation,
    PRECTL DestRect,
    PRECTL SourceRect,
    ULONG iTransColor,
    ULONG Reserved)
{
    BOOL Ret = TRUE;
    BYTE ClippingType;
    INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest;
    SURFOBJ *InputObj, *OutputObj;
    RECTL OutputRect, InputRect;
    POINTL Translate;

    LONG DstHeight;
    LONG DstWidth;
    LONG SrcHeight;
    LONG SrcWidth;

    InputRect = *SourceRect;

    if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
    {
        return FALSE;
    }
    InputRect.left += Translate.x;
    InputRect.right += Translate.x;
    InputRect.top += Translate.y;
    InputRect.bottom += Translate.y;

    OutputRect = *DestRect;
    if (OutputRect.right < OutputRect.left)
    {
        OutputRect.left = DestRect->right;
        OutputRect.right = DestRect->left;
    }
    if (OutputRect.bottom < OutputRect.top)
    {
        OutputRect.top = DestRect->bottom;
        OutputRect.bottom = DestRect->top;
    }

    if (Clip)
    {
        if (OutputRect.left < Clip->rclBounds.left)
        {
            InputRect.left += Clip->rclBounds.left - OutputRect.left;
            OutputRect.left = Clip->rclBounds.left;
        }
        if (Clip->rclBounds.right < OutputRect.right)
        {
            InputRect.right -=  OutputRect.right - Clip->rclBounds.right;
            OutputRect.right = Clip->rclBounds.right;
        }
        if (OutputRect.top < Clip->rclBounds.top)
        {
            InputRect.top += Clip->rclBounds.top - OutputRect.top;
            OutputRect.top = Clip->rclBounds.top;
        }
        if (Clip->rclBounds.bottom < OutputRect.bottom)
        {
            InputRect.bottom -=  OutputRect.bottom - Clip->rclBounds.bottom;
            OutputRect.bottom = Clip->rclBounds.bottom;
        }
    }

    /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
       nothing to do */
    if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
    {
        IntEngLeave(&EnterLeaveSource);
        return TRUE;
    }

    if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
    {
        IntEngLeave(&EnterLeaveSource);
        return FALSE;
    }

    OutputRect.left = DestRect->left + Translate.x;
    OutputRect.right = DestRect->right + Translate.x;
    OutputRect.top = DestRect->top + Translate.y;
    OutputRect.bottom = DestRect->bottom + Translate.y;

    ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL);

    DstHeight = OutputRect.bottom - OutputRect.top;
    DstWidth = OutputRect.right - OutputRect.left;
    SrcHeight = InputRect.bottom - InputRect.top;
    SrcWidth = InputRect.right - InputRect.left;
    switch (ClippingType)
    {
        case DC_TRIVIAL:
        {
            Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
                      OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor);
            break;
        }
        case DC_RECT:
        {
            RECTL ClipRect, CombinedRect;
            RECTL InputToCombinedRect;

            ClipRect.left = Clip->rclBounds.left + Translate.x;
            ClipRect.right = Clip->rclBounds.right + Translate.x;
            ClipRect.top = Clip->rclBounds.top + Translate.y;
            ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
            {
                InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
                InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
                InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
                InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
                Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
                          OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
            }
            break;
        }
        case DC_COMPLEX:
        {
            ULONG Direction, i;
            RECT_ENUM RectEnum;
            BOOL EnumMore;

            if (OutputObj == InputObj)
            {
                if (OutputRect.top < InputRect.top)
                {
                    Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN);
                }
                else
                {
                    Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP);
                }
            }
            else
            {
                Direction = CD_ANY;
            }

            CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0);
            do
            {
                EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID)&RectEnum);
                for (i = 0; i < RectEnum.c; i++)
                {
                    RECTL ClipRect, CombinedRect;
                    RECTL InputToCombinedRect;

                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                    {
                        InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
                        InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
                        InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
                        InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;

                        Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
                                  OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
                        if (!Ret)
                        {
                            break;
                        }
                    }
                }
            }
            while (EnumMore && Ret);
            break;
        }
        default:
        {
            Ret = FALSE;
            break;
        }
    }

    IntEngLeave(&EnterLeaveDest);
    IntEngLeave(&EnterLeaveSource);

    return Ret;
}
示例#3
0
BOOL
FASTCALL
IntEngGradientFillTriangle(
    IN SURFOBJ  *psoDest,
    IN CLIPOBJ  *pco,
    IN XLATEOBJ  *pxlo,
    IN TRIVERTEX  *pVertex,
    IN ULONG  nVertex,
    IN PGRADIENT_TRIANGLE gTriangle,
    IN RECTL  *prclExtents,
    IN POINTL  *pptlDitherOrg)
{
    SURFOBJ *psoOutput;
    PTRIVERTEX v1, v2, v3;
    //RECT_ENUM RectEnum;
    //BOOL EnumMore;
    //ULONG i;
    POINTL Translate;
    INTENG_ENTER_LEAVE EnterLeave;
    RECTL FillRect = { 0, 0, 0, 0 };
    //ULONG Color;

    //BOOL sx[NLINES];
    //LONG x[NLINES], dx[NLINES], dy[NLINES], incx[NLINES], ex[NLINES], destx[NLINES];
    //LONG c[NLINES][3], dc[NLINES][3], ec[NLINES][3], ic[NLINES][3]; /* colors on lines */
    //LONG g, gx, gxi, gc[3], gd[3], ge[3], gi[3]; /* colors in triangle */
    //LONG sy, y, bt;

    v1 = (pVertex + gTriangle->Vertex1);
    v2 = (pVertex + gTriangle->Vertex2);
    v3 = (pVertex + gTriangle->Vertex3);

    /* bubble sort */
    if (SMALLER(v2, v1))
    {
        TRIVERTEX *t;
        SWAP(v1, v2, t);
    }

    if (SMALLER(v3, v2))
    {
        TRIVERTEX *t;
        SWAP(v2, v3, t);
        if (SMALLER(v2, v1))
        {
            SWAP(v1, v2, t);
        }
    }

    DPRINT("Triangle: (%i,%i) (%i,%i) (%i,%i)\n", v1->x, v1->y, v2->x, v2->y, v3->x, v3->y);
    /* FIXME: commented out because of an endless loop - fix triangles first */
    DPRINT("FIXME: IntEngGradientFillTriangle is broken\n");

    if (!IntEngEnter(&EnterLeave, psoDest, &FillRect, FALSE, &Translate, &psoOutput))
    {
        return FALSE;
    }

    //if (VCMPCLRS(v1, v2, v3))
    //{
    //  CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
    //  do
    //  {
    //    EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
    //    for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++)
    //    {
    //      if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents))
    //      {
    //        BOOL InY;

    //        DOINIT(v1, v3, 0);
    //        DOINIT(v1, v2, 1);
    //        DOINIT(v2, v3, 2);

    //        y = v1->y;
    //        sy = v1->y + pptlDitherOrg->y;
    //        bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom);

    //        while (sy < bt)
    //        {
    //          InY = !(sy < FillRect.top || sy >= FillRect.bottom);
    //          GOLINE(v1, v3, 0);
    //          DOLINE(v1, v3, 0);
    //          ENDLINE(v1, v3, 0);

    //          GOLINE(v1, v2, 1);
    //          DOLINE(v1, v2, 1);
    //          FILLLINE(0, 1);
    //          ENDLINE(v1, v2, 1);

    //          GOLINE(v2, v3, 2);
    //          DOLINE(v2, v3, 2);
    //          FILLLINE(0, 2);
    //          ENDLINE(23, v3, 2);

    //          y++;
    //          sy++;
    //        }
    //      }
    //    }
    //  } while (EnumMore);

    //  return IntEngLeave(&EnterLeave);
    //}

    ///* fill triangle with one solid color */

    //Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red >> 8, v1->Green >> 8, v1->Blue >> 8));
    //CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
    //do
    //{
    //  EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
    //  for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++)
    //  {
    //    if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents))
    //    {
    //      S_INITLINE(v1, v3, 0);
    //      S_INITLINE(v1, v2, 1);
    //      S_INITLINE(v2, v3, 2);

    //      y = v1->y;
    //      sy = v1->y + pptlDitherOrg->y;
    //      bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom);

    //      while (sy < bt)
    //      {
    //        S_GOLINE(v1, v3, 0);
    //        S_DOLINE(v1, v3, 0);
    //        S_ENDLINE(v1, v3, 0);

    //        S_GOLINE(v1, v2, 1);
    //        S_DOLINE(v1, v2, 1);
    //        S_FILLLINE(0, 1);
    //        S_ENDLINE(v1, v2, 1);

    //        S_GOLINE(v2, v3, 2);
    //        S_DOLINE(v2, v3, 2);
    //        S_FILLLINE(0, 2);
    //        S_ENDLINE(23, v3, 2);

    //        y++;
    //        sy++;
    //      }
    //    }
    //  }
    //} while (EnumMore);

    return IntEngLeave(&EnterLeave);
}
示例#4
0
BOOL
FASTCALL
IntEngGradientFillRect(
    IN SURFOBJ  *psoDest,
    IN CLIPOBJ  *pco,
    IN XLATEOBJ  *pxlo,
    IN TRIVERTEX  *pVertex,
    IN ULONG  nVertex,
    IN PGRADIENT_RECT gRect,
    IN RECTL  *prclExtents,
    IN POINTL  *pptlDitherOrg,
    IN BOOL Horizontal)
{
    SURFOBJ *psoOutput;
    TRIVERTEX *v1, *v2;
    RECTL rcGradient, rcSG;
    RECT_ENUM RectEnum;
    BOOL EnumMore;
    ULONG i;
    POINTL Translate;
    INTENG_ENTER_LEAVE EnterLeave;
    LONG y, dy, c[3], dc[3], ec[3], ic[3];

    v1 = (pVertex + gRect->UpperLeft);
    v2 = (pVertex + gRect->LowerRight);

    rcGradient.left = min(v1->x, v2->x);
    rcGradient.right = max(v1->x, v2->x);
    rcGradient.top = min(v1->y, v2->y);
    rcGradient.bottom = max(v1->y, v2->y);
    rcSG = rcGradient;
    RECTL_vOffsetRect(&rcSG, pptlDitherOrg->x, pptlDitherOrg->y);

    if(Horizontal)
    {
        dy = abs(rcGradient.right - rcGradient.left);
    }
    else
    {
        dy = abs(rcGradient.bottom - rcGradient.top);
    }

    if(!IntEngEnter(&EnterLeave, psoDest, &rcSG, FALSE, &Translate, &psoOutput))
    {
        return FALSE;
    }

    if((v1->Red != v2->Red || v1->Green != v2->Green || v1->Blue != v2->Blue) && dy > 1)
    {
        CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
        do
        {
            RECTL FillRect;
            ULONG Color;

            if (Horizontal)
            {
                EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
                for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++)
                {
                    if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG))
                    {
                        HVINITCOL(Red, 0);
                        HVINITCOL(Green, 1);
                        HVINITCOL(Blue, 2);

                        for (y = rcSG.left; y < FillRect.right; y++)
                        {
                            if (y >= FillRect.left)
                            {
                                Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2]));
                                DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_VLine(
                                    psoOutput, y + Translate.x, FillRect.top + Translate.y, FillRect.bottom + Translate.y, Color);
                            }
                            HVSTEPCOL(0);
                            HVSTEPCOL(1);
                            HVSTEPCOL(2);
                        }
                    }
                }

                continue;
            }

            /* vertical */
            EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
            for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++)
            {
                if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG))
                {
                    HVINITCOL(Red, 0);
                    HVINITCOL(Green, 1);
                    HVINITCOL(Blue, 2);

                    for (y = rcSG.top; y < FillRect.bottom; y++)
                    {
                        if (y >= FillRect.top)
                        {
                            Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2]));
                            DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput,
                                                                                            FillRect.left + Translate.x,
                                                                                            FillRect.right + Translate.x,
                                                                                            y + Translate.y,
                                                                                            Color);
                        }
                        HVSTEPCOL(0);
                        HVSTEPCOL(1);
                        HVSTEPCOL(2);
                    }
                }
            }

        }
        while (EnumMore);

        return IntEngLeave(&EnterLeave);
    }

    /* rectangle has only one color, no calculation required */
    CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
    do
    {
        RECTL FillRect;
        ULONG Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red, v1->Green, v1->Blue));

        EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
        for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++)
        {
            if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG))
            {
                for (; FillRect.top < FillRect.bottom; FillRect.top++)
                {
                    DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput,
                                                                                    FillRect.left + Translate.x,
                                                                                    FillRect.right + Translate.x,
                                                                                    FillRect.top + Translate.y,
                                                                                    Color);
                }
            }
        }
    }
    while (EnumMore);

    return IntEngLeave(&EnterLeave);
}
示例#5
0
/*
 * @implemented
 */
BOOL
APIENTRY
EngStretchBltROP(
    IN SURFOBJ  *psoDest,
    IN SURFOBJ  *psoSource,
    IN SURFOBJ  *Mask,
    IN CLIPOBJ  *ClipRegion,
    IN XLATEOBJ  *ColorTranslation,
    IN COLORADJUSTMENT  *pca,
    IN POINTL  *BrushOrigin,
    IN RECTL  *prclDest,
    IN RECTL  *prclSrc,
    IN POINTL  *MaskOrigin,
    IN ULONG  Mode,
    IN BRUSHOBJ *pbo,
    IN ROP4 Rop4)
{
    RECTL              InputRect;
    RECTL              OutputRect;
    POINTL             Translate;
    INTENG_ENTER_LEAVE EnterLeaveSource;
    INTENG_ENTER_LEAVE EnterLeaveDest;
    SURFOBJ*           psoInput;
    SURFOBJ*           psoOutput;
    PSTRETCHRECTFUNC   BltRectFunc;
    BOOLEAN            Ret = TRUE;
    POINTL             AdjustedBrushOrigin;
    BOOL               UsesSource = ROP4_USES_SOURCE(Rop4);

    BYTE               clippingType;
    RECTL              ClipRect;
    RECT_ENUM          RectEnum;
    BOOL               EnumMore;
    ULONG              Direction;
    RECTL              CombinedRect;
    RECTL              InputToCombinedRect;
    unsigned           i;

    LONG DstHeight;
    LONG DstWidth;
    LONG SrcHeight;
    LONG SrcWidth;

    if (Rop4 == ROP4_NOOP)
    {
        /* Copy destination onto itself: nop */
        return TRUE;
    }


    /* Determine clipping type */
    if (ClipRegion == (CLIPOBJ *) NULL)
    {
        clippingType = DC_TRIVIAL;
    }
    else
    {
        clippingType = ClipRegion->iDComplexity;
    }

    OutputRect = *prclDest;
    if (OutputRect.right < OutputRect.left)
    {
        OutputRect.left = prclDest->right;
        OutputRect.right = prclDest->left;
    }
    if (OutputRect.bottom < OutputRect.top)
    {
        OutputRect.top = prclDest->bottom;
        OutputRect.bottom = prclDest->top;
    }

    if (UsesSource)
    {
        if (NULL == prclSrc)
        {
            return FALSE;
        }
        InputRect = *prclSrc;

        if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
                          &Translate, &psoInput))
        {
            return FALSE;
        }

        InputRect.left += Translate.x;
        InputRect.right += Translate.x;
        InputRect.top += Translate.y;
        InputRect.bottom += Translate.y;
    }
    else
    {
        InputRect.left = 0;
        InputRect.right = OutputRect.right - OutputRect.left;
        InputRect.top = 0;
        InputRect.bottom = OutputRect.bottom - OutputRect.top;
        psoInput = NULL;
    }

    if (NULL != ClipRegion)
    {
        if (OutputRect.left < ClipRegion->rclBounds.left)
        {
            InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
            OutputRect.left = ClipRegion->rclBounds.left;
        }
        if (ClipRegion->rclBounds.right < OutputRect.right)
        {
            InputRect.right -= OutputRect.right - ClipRegion->rclBounds.right;
            OutputRect.right = ClipRegion->rclBounds.right;
        }
        if (OutputRect.top < ClipRegion->rclBounds.top)
        {
            InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
            OutputRect.top = ClipRegion->rclBounds.top;
        }
        if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
        {
            InputRect.bottom -=  OutputRect.bottom - ClipRegion->rclBounds.bottom;
            OutputRect.bottom = ClipRegion->rclBounds.bottom;
        }
    }

    /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
       nothing to do */
    if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
    {
        if (UsesSource)
        {
            IntEngLeave(&EnterLeaveSource);
        }
        return TRUE;
    }

    if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &psoOutput))
    {
        if (UsesSource)
        {
            IntEngLeave(&EnterLeaveSource);
        }
        return FALSE;
    }

    OutputRect.left += Translate.x;
    OutputRect.right += Translate.x;
    OutputRect.top += Translate.y;
    OutputRect.bottom += Translate.y;

    if (BrushOrigin)
    {
        AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
        AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
    }
    else
    {
        AdjustedBrushOrigin = Translate;
    }

    BltRectFunc = CallDibStretchBlt;

    DstHeight = OutputRect.bottom - OutputRect.top;
    DstWidth = OutputRect.right - OutputRect.left;
    SrcHeight = InputRect.bottom - InputRect.top;
    SrcWidth = InputRect.right - InputRect.left;
    switch (clippingType)
    {
        case DC_TRIVIAL:
            Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
                         ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
                         pbo, &AdjustedBrushOrigin, Rop4);
            break;
        case DC_RECT:
            // Clip the blt to the clip rectangle
            ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
            ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
            ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
            ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
            {
                InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
                InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
                InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
                InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
                Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
                           ColorTranslation,
                           &CombinedRect,
                           &InputToCombinedRect,
                           MaskOrigin,
                           pbo,
                           &AdjustedBrushOrigin,
                           Rop4);
            }
            break;
        case DC_COMPLEX:
            if (psoOutput == psoInput)
            {
                if (OutputRect.top < InputRect.top)
                {
                    Direction = OutputRect.left < InputRect.left ?
                                CD_RIGHTDOWN : CD_LEFTDOWN;
                }
                else
                {
                    Direction = OutputRect.left < InputRect.left ?
                                CD_RIGHTUP : CD_LEFTUP;
                }
            }
            else
            {
                Direction = CD_ANY;
            }
            CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
            do
            {
                EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
                                         (PVOID) &RectEnum);
                for (i = 0; i < RectEnum.c; i++)
                {
                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                    {
                        InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
                        InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
                        InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
                        InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
                        Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
                           ColorTranslation,
                           &CombinedRect,
                           &InputToCombinedRect,
                           MaskOrigin,
                           pbo,
                           &AdjustedBrushOrigin,
                           Rop4);
                    }
                }
            }
            while (EnumMore);
            break;
    }

    IntEngLeave(&EnterLeaveDest);
    if (UsesSource)
    {
        IntEngLeave(&EnterLeaveSource);
    }

    return Ret;
}