<commit_before>/********************************************************/
/*                       Regions                        */
/********************************************************/

#ifndef wxPI
# define wxPI 3.141592653589793
#endif

#define CAIRO_DEV ((cairo_t *)target)

#ifdef wx_mac
typedef struct {
  CGContextRef cg;
  CGMutablePathRef path;
} PathTarget;
# define CGPATH ((PathTarget *)target)->path
# define CGCG ((PathTarget *)target)->cg
# define PathTargetPath_t CGMutablePathRef
# define CGXFORM (&current_xform)
# define PATHPATH ((CGMutablePathRef)target)
#endif

#ifdef wx_msw
typedef struct {
  Graphics *g;
  GraphicsPath *path;
  int did_one;
} PathTarget;
# define GP ((PathTarget *)target)->path
# define GP_G ((PathTarget *)target)->g
# define GP_DID_ONE ((PathTarget *)target)->did_one
# define PathTargetPath_t GraphicsPath*
# define CURRENT_GP current_path
# define PATH_GP ((GraphicsPath *)target)
#endif

#ifndef WX_USE_CAIRO
typedef int cairo_matrix_p;
#endif

/**************************************************************************/

wxRegion::wxRegion(wxDC *_dc, wxRegion *r, Bool _no_prgn)
{
  dc = _dc;
  is_ps = wxSubType(dc->__type, wxTYPE_DC_POSTSCRIPT);
  locked = 0;
 
#ifdef wx_msw
  lazy_rgn = NULL;
#endif
#ifdef wx_x
  rgn = NULL;
#endif
#ifdef wx_mac
  rgn = NULL;
#endif
  prgn = NULL;
  no_prgn = _no_prgn;
  if (r) Union(r);
}

wxRegion::~wxRegion()
{
  Cleanup();
}

void wxRegion::Cleanup()
{  
#ifdef wx_msw
  if (lazy_rgn) {
    if (real_rgn)
      lazy_rgn->DoneRgn(real_rgn);
    lazy_rgn = NULL;
  }
#endif
#ifdef wx_x
  if (rgn) {
    XDestroyRegion(rgn);
    rgn = NULL;
  }
#endif
#ifdef wx_mac
  if (rgn) {
    DisposeRgn(rgn);
    rgn = NULL;
  }
#endif
  if (!no_prgn) {
    prgn = NULL;
  }
}

void wxRegion::Lock(int delta)
{
#ifdef wx_msw
  if (!locked) {
    if (lazy_rgn) {
      real_rgn = lazy_rgn->GetRgn();
    }
  }
#endif  

  locked += delta;

#ifdef wx_msw
  if (!locked) {
    if (lazy_rgn) {
      lazy_rgn->DoneRgn(real_rgn);
      real_rgn = NULL;
    }
  }
#endif
}

#ifdef wx_msw
HRGN wxRegion::GetRgn()
{
  return real_rgn;
}
#endif

void wxRegion::SetRectangle(double x, double y, double width, double height)
{
  double xw, yh;
  int ix, iy, iw, ih;

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxRectanglePathRgn(dc, x, y, width, height);
  }

  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  xw = dc->FLogicalToUnscrolledDeviceX(xw);
  width = xw - x;
  yh = dc->FLogicalToUnscrolledDeviceY(yh);
  height = yh - y;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y  = -y;
  }

  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;

#ifdef wx_msw
  lazy_rgn = new RectLazyRgn(ix, iy, iw, ih);
#endif
#ifdef wx_x
  {
    XRectangle r;
    rgn = XCreateRegion();
    r.x = ix;
    r.y = iy;
    r.width = iw;
    r.height = ih;
    XUnionRectWithRegion(&r, rgn, rgn);
  }
#endif
#ifdef wx_mac
  rgn = NewRgn();
  SetRectRgn(rgn, ix, iy, ix + iw, iy + ih);
#endif
}

void wxRegion::SetRoundedRectangle(double x, double y, double width, double height, double radius)
{
#ifdef wx_xt
  wxRegion *lt, *rt, *lb, *rb, *w, *h, *r;
#endif
#if defined(wx_msw) || defined(wx_mac)
  double xw, yh;
  int ix, iy, iw, ih;
  int xradius, yradius;
#endif

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxRoundedRectanglePathRgn(dc, x, y, width, height, radius);
  }

  // A negative radius value is interpreted to mean
  // 'the proportion of the smallest X or Y dimension'
  if (radius < 0.0) {
    double smallest = 0.0;
    if (width < height)
      smallest = width;
    else
      smallest = height;
    radius = (double)(- radius * smallest);
  } else
    radius = dc->FLogicalToDeviceXRel(radius);

#ifdef wx_x
  lt = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  rt = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  lb = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  rb = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  w = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  h = new WXGC_PTRS wxRegion(dc, NULL, TRUE);

  lt->SetEllipse(x, y, 2 * radius, 2 * radius);
  rt->SetEllipse(x + width - 2 * radius, y, 2 * radius, 2 * radius);
  rb->SetEllipse(x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius);
  lb->SetEllipse(x, y + height - 2 * radius, 2 * radius, 2 * radius);

  w->SetRectangle(x, y + radius, width, height - 2 * radius);
  h->SetRectangle(x + radius, y, width - 2 * radius, height);

  r = lt;
  r->Union(rt);
  r->Union(lb);
  r->Union(rb);
  r->Union(w);
  r->Union(h);

  /* A little hack: steal rgn from r: */
  rgn = r->rgn;
  r->rgn = NULL;
#else
  /* Windows and Mac */
  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  width = dc->FLogicalToUnscrolledDeviceX(xw) - x;
  height = dc->FLogicalToUnscrolledDeviceY(yh) - y;
  xradius = (int)(dc->FLogicalToDeviceXRel(radius));
  yradius = (int)(dc->FLogicalToDeviceYRel(radius));

  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y = -y;
  }

# ifdef wx_msw
  lazy_rgn = new RoundRectLazyRgn(ix, iy, iw, ih, xradius, yradius);
# endif
# ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    {
      Rect r2;
      SetRect(&r2, ix, iy, ix + iw, iy + ih);
      FrameRoundRect(&r2, xradius, yradius);
      CloseRgn(rgn);
    }

    ::SetGWorld(savep, savegd);
  }    
# endif
#endif
}

void wxRegion::SetEllipse(double x, double y, double width, double height)
{
  double xw, yh;
#if defined(wx_msw) || defined(wx_mac)
  int ix, iy, iw, ih;
#endif

  Cleanup();

  if (!no_prgn) {
#ifdef WX_USE_CAIRO
    /* cairo_arc() went bad for clipping, so we avoid it. */
    {
      wxPath *p;
      p = new WXGC_PTRS wxPath();
      p->Arc(x, y, width, height, 0, 2 * wxPI, FALSE);
      p->Close();
      prgn = new WXGC_PTRS wxPathPathRgn(dc, p, 0, 0, wxWINDING_RULE);
    }
#else
    prgn = new WXGC_PTRS wxArcPathRgn(dc, x, y, width, height, 0, 2 * wxPI);
#endif
  }

  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  width = dc->FLogicalToUnscrolledDeviceX(xw) - x;
  height = dc->FLogicalToUnscrolledDeviceY(yh) - y;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y = -y;
  }

#if defined(wx_msw) || defined(wx_mac)
  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;
#endif

#ifdef wx_msw
  lazy_rgn = new EllipticLazyRgn(ix, iy, iw, ih);
#endif
#ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    {
      Rect r;
      SetRect(&r, ix, iy, ix + iw, iy + ih);
      FrameOval(&r);
      CloseRgn(rgn);
    }

    ::SetGWorld(savep, savegd);
  }
#endif

#ifdef wx_x
  {
    int npoints;
    XPoint *p;
    p = wxEllipseToPolygon(width, height, x, y, &npoints);
    rgn = XPolygonRegion(p, npoints - 1, WindingRule);
  }
#endif
}

#ifdef wx_x
# define POINT XPoint
#endif
#ifdef wx_mac
# define POINT MyPoint
  typedef struct { int x, y; } MyPoint;
#endif

typedef struct { double x, y; } FPoint;

void wxRegion::SetPolygon(int n, wxPoint points[], double xoffset, double yoffset, int fillStyle, int delta)
{
  POINT *cpoints;
  FPoint *fpoints;
  int i, v;
  double vf;

  Cleanup();

  if (n < 2)
    return;

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxPolygonPathRgn(dc, n, points, xoffset, yoffset, fillStyle);
  }

  cpoints = new WXGC_ATOMIC POINT[n];
  fpoints = (is_ps ? new WXGC_ATOMIC FPoint[n] : (FPoint *)NULL);
  for (i = 0; i < n; i++) {
    v = dc->LogicalToUnscrolledDeviceX(points[i+delta].x + xoffset);
    cpoints[i].x = v;
    v = dc->LogicalToUnscrolledDeviceY(points[i+delta].y + yoffset);
    cpoints[i].y = v;
    if (fpoints) {
      vf = dc->FLogicalToUnscrolledDeviceX(points[i+delta].x + xoffset);
      fpoints[i].x = vf;
      vf = dc->FLogicalToUnscrolledDeviceY(points[i+delta].y + yoffset);
      fpoints[i].y = vf;
    }
  }

  if (is_ps) {
    /* So bitmap-based region is right */
    for (i = 0; i < n; i++) {
      cpoints[i].y = -cpoints[i].y;
    }
  }

#ifdef wx_msw
  lazy_rgn = new PolygonLazyRgn(cpoints, n, (fillStyle == wxODDEVEN_RULE) ? ALTERNATE : WINDING);
#endif
#ifdef wx_x
  rgn = XPolygonRegion(cpoints, n, (fillStyle == wxODDEVEN_RULE) ? EvenOddRule : WindingRule);
#endif
#ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    MoveTo(cpoints[0].x, cpoints[0].y);
    for (i = 0; i < n; i++) {
      LineTo(cpoints[i].x, cpoints[i].y);
    }
    LineTo(cpoints[0].x, cpoints[0].y);
    CloseRgn(rgn);

    ::SetGWorld(savep, savegd);
  }
#endif
}

void wxRegion::SetPath(wxPath *p, double xoffset, double yoffset, int fillStyle)
{
  double **ptss, xs, ys;
  int *lens, cnt, i, total_cnt, j, k;
  wxPoint *a;

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxPathPathRgn(dc, p, xoffset, yoffset, fillStyle);
    no_prgn = 1;
  }

  dc->GetUserScale(&xs, &ys);
  cnt = p->ToPolygons(&lens, &ptss, xs, ys);

  if (!cnt)
    return;
  
  total_cnt = 0;
  for (i = 0; i < cnt; i++) {
    total_cnt += (lens[i] / 2);
  }

#ifdef MZ_PRECISE_GC
  a = (wxPoint *)GC_malloc_atomic(sizeof(wxPoint) * total_cnt);
#else
  a = new WXGC_ATOMIC wxPoint[total_cnt];
#endif

  for (i = 0, k = 0; i < cnt; i++) {
    for (j = 0; j < lens[i]; j += 2) {
      a[k].x = ptss[i][j] + xoffset;
      a[k].y = ptss[i][j+1] + yoffset;
      k++;
    }
  }

  if (cnt == 1) {
    SetPolygon(total_cnt, a, xoffset, yoffset, fillStyle, 0);
  } else {
    for (i = 0, k = 0; i < cnt; i++) {
      j = (lens[i] / 2);
      if (i == 0)
	SetPolygon(j, a, xoffset, yoffset, fillStyle, k);
      else {
	wxRegion *r;
	r = new WXGC_PTRS wxRegion(dc, NULL, 1);
	r->SetPolygon(j, a, xoffset, yoffset, fillStyle, k);
	Xor(r);
	DELETE_OBJ r;
      }
      k += j;
    }
  }      
  
  no_prgn = 0;
}<commit_msg>fix region<%> set-path for 'aligned mode<commit_after>/********************************************************/
/*                       Regions                        */
/********************************************************/

#ifndef wxPI
# define wxPI 3.141592653589793
#endif

#define CAIRO_DEV ((cairo_t *)target)

#ifdef wx_mac
typedef struct {
  CGContextRef cg;
  CGMutablePathRef path;
} PathTarget;
# define CGPATH ((PathTarget *)target)->path
# define CGCG ((PathTarget *)target)->cg
# define PathTargetPath_t CGMutablePathRef
# define CGXFORM (&current_xform)
# define PATHPATH ((CGMutablePathRef)target)
#endif

#ifdef wx_msw
typedef struct {
  Graphics *g;
  GraphicsPath *path;
  int did_one;
} PathTarget;
# define GP ((PathTarget *)target)->path
# define GP_G ((PathTarget *)target)->g
# define GP_DID_ONE ((PathTarget *)target)->did_one
# define PathTargetPath_t GraphicsPath*
# define CURRENT_GP current_path
# define PATH_GP ((GraphicsPath *)target)
#endif

#ifndef WX_USE_CAIRO
typedef int cairo_matrix_p;
#endif

/**************************************************************************/

wxRegion::wxRegion(wxDC *_dc, wxRegion *r, Bool _no_prgn)
{
  dc = _dc;
  is_ps = wxSubType(dc->__type, wxTYPE_DC_POSTSCRIPT);
  locked = 0;
 
#ifdef wx_msw
  lazy_rgn = NULL;
#endif
#ifdef wx_x
  rgn = NULL;
#endif
#ifdef wx_mac
  rgn = NULL;
#endif
  prgn = NULL;
  no_prgn = _no_prgn;
  if (r) Union(r);
}

wxRegion::~wxRegion()
{
  Cleanup();
}

void wxRegion::Cleanup()
{  
#ifdef wx_msw
  if (lazy_rgn) {
    if (real_rgn)
      lazy_rgn->DoneRgn(real_rgn);
    lazy_rgn = NULL;
  }
#endif
#ifdef wx_x
  if (rgn) {
    XDestroyRegion(rgn);
    rgn = NULL;
  }
#endif
#ifdef wx_mac
  if (rgn) {
    DisposeRgn(rgn);
    rgn = NULL;
  }
#endif
  if (!no_prgn) {
    prgn = NULL;
  }
}

void wxRegion::Lock(int delta)
{
#ifdef wx_msw
  if (!locked) {
    if (lazy_rgn) {
      real_rgn = lazy_rgn->GetRgn();
    }
  }
#endif  

  locked += delta;

#ifdef wx_msw
  if (!locked) {
    if (lazy_rgn) {
      lazy_rgn->DoneRgn(real_rgn);
      real_rgn = NULL;
    }
  }
#endif
}

#ifdef wx_msw
HRGN wxRegion::GetRgn()
{
  return real_rgn;
}
#endif

void wxRegion::SetRectangle(double x, double y, double width, double height)
{
  double xw, yh;
  int ix, iy, iw, ih;

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxRectanglePathRgn(dc, x, y, width, height);
  }

  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  xw = dc->FLogicalToUnscrolledDeviceX(xw);
  width = xw - x;
  yh = dc->FLogicalToUnscrolledDeviceY(yh);
  height = yh - y;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y  = -y;
  }

  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;

#ifdef wx_msw
  lazy_rgn = new RectLazyRgn(ix, iy, iw, ih);
#endif
#ifdef wx_x
  {
    XRectangle r;
    rgn = XCreateRegion();
    r.x = ix;
    r.y = iy;
    r.width = iw;
    r.height = ih;
    XUnionRectWithRegion(&r, rgn, rgn);
  }
#endif
#ifdef wx_mac
  rgn = NewRgn();
  SetRectRgn(rgn, ix, iy, ix + iw, iy + ih);
#endif
}

void wxRegion::SetRoundedRectangle(double x, double y, double width, double height, double radius)
{
#ifdef wx_xt
  wxRegion *lt, *rt, *lb, *rb, *w, *h, *r;
#endif
#if defined(wx_msw) || defined(wx_mac)
  double xw, yh;
  int ix, iy, iw, ih;
  int xradius, yradius;
#endif

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxRoundedRectanglePathRgn(dc, x, y, width, height, radius);
  }

  // A negative radius value is interpreted to mean
  // 'the proportion of the smallest X or Y dimension'
  if (radius < 0.0) {
    double smallest = 0.0;
    if (width < height)
      smallest = width;
    else
      smallest = height;
    radius = (double)(- radius * smallest);
  } else
    radius = dc->FLogicalToDeviceXRel(radius);

#ifdef wx_x
  lt = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  rt = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  lb = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  rb = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  w = new WXGC_PTRS wxRegion(dc, NULL, TRUE);
  h = new WXGC_PTRS wxRegion(dc, NULL, TRUE);

  lt->SetEllipse(x, y, 2 * radius, 2 * radius);
  rt->SetEllipse(x + width - 2 * radius, y, 2 * radius, 2 * radius);
  rb->SetEllipse(x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius);
  lb->SetEllipse(x, y + height - 2 * radius, 2 * radius, 2 * radius);

  w->SetRectangle(x, y + radius, width, height - 2 * radius);
  h->SetRectangle(x + radius, y, width - 2 * radius, height);

  r = lt;
  r->Union(rt);
  r->Union(lb);
  r->Union(rb);
  r->Union(w);
  r->Union(h);

  /* A little hack: steal rgn from r: */
  rgn = r->rgn;
  r->rgn = NULL;
#else
  /* Windows and Mac */
  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  width = dc->FLogicalToUnscrolledDeviceX(xw) - x;
  height = dc->FLogicalToUnscrolledDeviceY(yh) - y;
  xradius = (int)(dc->FLogicalToDeviceXRel(radius));
  yradius = (int)(dc->FLogicalToDeviceYRel(radius));

  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y = -y;
  }

# ifdef wx_msw
  lazy_rgn = new RoundRectLazyRgn(ix, iy, iw, ih, xradius, yradius);
# endif
# ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    {
      Rect r2;
      SetRect(&r2, ix, iy, ix + iw, iy + ih);
      FrameRoundRect(&r2, xradius, yradius);
      CloseRgn(rgn);
    }

    ::SetGWorld(savep, savegd);
  }    
# endif
#endif
}

void wxRegion::SetEllipse(double x, double y, double width, double height)
{
  double xw, yh;
#if defined(wx_msw) || defined(wx_mac)
  int ix, iy, iw, ih;
#endif

  Cleanup();

  if (!no_prgn) {
#ifdef WX_USE_CAIRO
    /* cairo_arc() went bad for clipping, so we avoid it. */
    {
      wxPath *p;
      p = new WXGC_PTRS wxPath();
      p->Arc(x, y, width, height, 0, 2 * wxPI, FALSE);
      p->Close();
      prgn = new WXGC_PTRS wxPathPathRgn(dc, p, 0, 0, wxWINDING_RULE);
    }
#else
    prgn = new WXGC_PTRS wxArcPathRgn(dc, x, y, width, height, 0, 2 * wxPI);
#endif
  }

  xw = x + width;
  yh = y + height;
  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  width = dc->FLogicalToUnscrolledDeviceX(xw) - x;
  height = dc->FLogicalToUnscrolledDeviceY(yh) - y;

  if (is_ps) {
    /* So bitmap-based region is right */
    height = -height;
    y = -y;
  }

#if defined(wx_msw) || defined(wx_mac)
  ix = (int)floor(x);
  iy = (int)floor(y);
  iw = ((int)floor(x + width)) - ix;
  ih = ((int)floor(y + height)) - iy;
#endif

#ifdef wx_msw
  lazy_rgn = new EllipticLazyRgn(ix, iy, iw, ih);
#endif
#ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    {
      Rect r;
      SetRect(&r, ix, iy, ix + iw, iy + ih);
      FrameOval(&r);
      CloseRgn(rgn);
    }

    ::SetGWorld(savep, savegd);
  }
#endif

#ifdef wx_x
  {
    int npoints;
    XPoint *p;
    p = wxEllipseToPolygon(width, height, x, y, &npoints);
    rgn = XPolygonRegion(p, npoints - 1, WindingRule);
  }
#endif
}

#ifdef wx_x
# define POINT XPoint
#endif
#ifdef wx_mac
# define POINT MyPoint
  typedef struct { int x, y; } MyPoint;
#endif

typedef struct { double x, y; } FPoint;

void wxRegion::SetPolygon(int n, wxPoint points[], double xoffset, double yoffset, int fillStyle, int delta)
{
  POINT *cpoints;
  FPoint *fpoints;
  int i, v;
  double vf;

  Cleanup();

  if (n < 2)
    return;

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxPolygonPathRgn(dc, n, points, xoffset, yoffset, fillStyle);
  }

  cpoints = new WXGC_ATOMIC POINT[n];
  fpoints = (is_ps ? new WXGC_ATOMIC FPoint[n] : (FPoint *)NULL);
  for (i = 0; i < n; i++) {
    v = dc->LogicalToUnscrolledDeviceX(points[i+delta].x + xoffset);
    cpoints[i].x = v;
    v = dc->LogicalToUnscrolledDeviceY(points[i+delta].y + yoffset);
    cpoints[i].y = v;
    if (fpoints) {
      vf = dc->FLogicalToUnscrolledDeviceX(points[i+delta].x + xoffset);
      fpoints[i].x = vf;
      vf = dc->FLogicalToUnscrolledDeviceY(points[i+delta].y + yoffset);
      fpoints[i].y = vf;
    }
  }

  if (is_ps) {
    /* So bitmap-based region is right */
    for (i = 0; i < n; i++) {
      cpoints[i].y = -cpoints[i].y;
    }
  }

#ifdef wx_msw
  lazy_rgn = new PolygonLazyRgn(cpoints, n, (fillStyle == wxODDEVEN_RULE) ? ALTERNATE : WINDING);
#endif
#ifdef wx_x
  rgn = XPolygonRegion(cpoints, n, (fillStyle == wxODDEVEN_RULE) ? EvenOddRule : WindingRule);
#endif
#ifdef wx_mac
  /* This code uses the current port. We don't know what the current
     port might be, so we have to pick one to be sure that QuickDraw
     is allowed. */
  {
    CGrafPtr savep;
    GDHandle savegd;
    
    ::GetGWorld(&savep, &savegd);  
    ::SetGWorld(wxGetGrafPtr(), GetMainDevice());

    rgn = NewRgn();
    OpenRgn();
    MoveTo(cpoints[0].x, cpoints[0].y);
    for (i = 0; i < n; i++) {
      LineTo(cpoints[i].x, cpoints[i].y);
    }
    LineTo(cpoints[0].x, cpoints[0].y);
    CloseRgn(rgn);

    ::SetGWorld(savep, savegd);
  }
#endif
}

void wxRegion::SetPath(wxPath *p, double xoffset, double yoffset, int fillStyle)
{
  double **ptss;
  int *lens, cnt, i, total_cnt, j, k;
  wxPoint *a;

  Cleanup();

  if (!no_prgn) {
    prgn = new WXGC_PTRS wxPathPathRgn(dc, p, xoffset, yoffset, fillStyle);
    no_prgn = 1;
  }

  cnt = p->ToPolygons(&lens, &ptss, 1.0, 1.0);

  if (!cnt)
    return;
  
  total_cnt = 0;
  for (i = 0; i < cnt; i++) {
    total_cnt += (lens[i] / 2);
  }

#ifdef MZ_PRECISE_GC
  a = (wxPoint *)GC_malloc_atomic(sizeof(wxPoint) * total_cnt);
#else
  a = new WXGC_ATOMIC wxPoint[total_cnt];
#endif

  for (i = 0, k = 0; i < cnt; i++) {
    for (j = 0; j < lens[i]; j += 2) {
      a[k].x = ptss[i][j];
      a[k].y = ptss[i][j+1];
      k++;
    }
  }

  if (cnt == 1) {
    SetPolygon(total_cnt, a, xoffset, yoffset, fillStyle, 0);
  } else {
    for (i = 0, k = 0; i < cnt; i++) {
      j = (lens[i] / 2);
      if (i == 0)
	SetPolygon(j, a, xoffset, yoffset, fillStyle, k);
      else {
	wxRegion *r;
	r = new WXGC_PTRS wxRegion(dc, NULL, 1);
	r->SetPolygon(j, a, xoffset, yoffset, fillStyle, k);
	Xor(r);
	DELETE_OBJ r;
      }
      k += j;
    }
  }      
  
  no_prgn = 0;
}
{'fraction_non_alphanumeric': 0.16665905874834527, 'fraction_numerical': 0.006573241429680011, 'mean_word_length': 3.0242468772961058, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2191834', 'n_tokens_mistral': 9261, 'n_tokens_neox': 8910, 'n_words': 2259}