22#include <freerdp/config.h> 
   28#include <winpr/assert.h> 
   30#include <freerdp/freerdp.h> 
   31#include <freerdp/gdi/gdi.h> 
   32#include <freerdp/gdi/pen.h> 
   33#include <freerdp/gdi/bitmap.h> 
   34#include <freerdp/gdi/region.h> 
   40static BOOL gdi_rop_color(INT32 rop, BYTE* pixelPtr, UINT32 pen, UINT32 format)
 
   42  WINPR_ASSERT(pixelPtr);
 
   43  const UINT32 srcPixel = FreeRDPReadColor(pixelPtr, format);
 
   49      dstPixel = FreeRDPGetColor(format, 0, 0, 0, 0xFF);
 
   52    case GDI_R2_NOTMERGEPEN: 
 
   53      dstPixel = ~(srcPixel | pen);
 
   56    case GDI_R2_MASKNOTPEN: 
 
   57      dstPixel = srcPixel & ~pen;
 
   60    case GDI_R2_NOTCOPYPEN: 
 
   64    case GDI_R2_MASKPENNOT: 
 
   65      dstPixel = pen & ~srcPixel;
 
   73      dstPixel = srcPixel ^ pen;
 
   76    case GDI_R2_NOTMASKPEN: 
 
   77      dstPixel = ~(srcPixel & pen);
 
   81      dstPixel = srcPixel & pen;
 
   84    case GDI_R2_NOTXORPEN: 
 
   85      dstPixel = ~(srcPixel ^ pen);
 
   92    case GDI_R2_MERGENOTPEN: 
 
   93      dstPixel = srcPixel | ~pen;
 
  100    case GDI_R2_MERGEPENNOT: 
 
  101      dstPixel = srcPixel | ~pen;
 
  104    case GDI_R2_MERGEPEN: 
 
  105      dstPixel = srcPixel | pen;
 
  109      dstPixel = FreeRDPGetColor(format, 0xFF, 0xFF, 0xFF, 0xFF);
 
  116  return FreeRDPWriteColor(pixelPtr, format, dstPixel);
 
  119BOOL gdi_LineTo(
HGDI_DC hdc, INT32 nXEnd, INT32 nYEnd)
 
  125  const INT32 rop2 = gdi_GetROP2(hdc);
 
  127  const INT32 x1 = hdc->pen->posX;
 
  128  const INT32 y1 = hdc->pen->posY;
 
  129  const INT32 x2 = WINPR_ASSERTING_INT_CAST(int32_t, nXEnd);
 
  130  const INT32 y2 = WINPR_ASSERTING_INT_CAST(int32_t, nYEnd);
 
  131  const INT32 dx = (x1 > x2) ? x1 - x2 : x2 - x1;
 
  132  const INT32 dy = (y1 > y2) ? y1 - y2 : y2 - y1;
 
  133  const INT32 sx = (x1 < x2) ? 1 : -1;
 
  134  const INT32 sy = (y1 < y2) ? 1 : -1;
 
  139  WINPR_ASSERT(hdc->clip);
 
  146    bx1 = (x1 < x2) ? x1 : x2;
 
  147    by1 = (y1 < y2) ? y1 : y2;
 
  148    bx2 = (x1 > x2) ? x1 : x2;
 
  149    by2 = (y1 > y2) ? y1 : y2;
 
  155    bx2 = bx1 + hdc->clip->w - 1;
 
  156    by2 = by1 + hdc->clip->h - 1;
 
  164  bx2 = MIN(bx2, bmp->width - 1);
 
  165  by2 = MIN(by2, bmp->height - 1);
 
  167  if (!gdi_InvalidateRegion(hdc, bx1, by1, bx2 - bx1 + 1, by2 - by1 + 1))
 
  170  pen = gdi_GetPenColor(hdc->pen, bmp->format);
 
  174    if (!(x == x2 && y == y2))
 
  176      if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2))
 
  178        BYTE* pixel = gdi_GetPointer(bmp, WINPR_ASSERTING_INT_CAST(uint32_t, x),
 
  179                                     WINPR_ASSERTING_INT_CAST(uint32_t, y));
 
  181        gdi_rop_color(rop2, pixel, pen, bmp->format);
 
  217  WINPR_ASSERT(lppt || (cCount == 0));
 
  219  for (DWORD i = 0; i < cCount; i++)
 
  221    if (!gdi_LineTo(hdc, lppt[i].x, lppt[i].y))
 
  224    if (!gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL))
 
  241  WINPR_ASSERT(lppt || (cPoints == 0));
 
  247    if (!gdi_MoveToEx(hdc, lppt[0].x, lppt[0].y, &pt))
 
  250    for (UINT32 i = 0; i < cPoints; i++)
 
  252      if (!gdi_LineTo(hdc, lppt[i].x, lppt[i].y))
 
  255      if (!gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL))
 
  259    if (!gdi_MoveToEx(hdc, pt.x, pt.y, NULL))
 
  274BOOL gdi_PolyPolyline(
HGDI_DC hdc, 
GDI_POINT* lppt, 
const UINT32* lpdwPolyPoints, DWORD cCount)
 
  279  WINPR_ASSERT(lppt || (cCount == 0));
 
  280  WINPR_ASSERT(lpdwPolyPoints || (cCount == 0));
 
  282  for (DWORD i = 0; i < cCount; i++)
 
  284    const UINT32 cPoints = lpdwPolyPoints[i];
 
  286    if (!gdi_Polyline(hdc, &lppt[j], cPoints))
 
  309    lpPoint->x = hdc->pen->posX;
 
  310    lpPoint->y = hdc->pen->posY;