Back to index

plt-scheme  4.2.1
Public Member Functions | Public Attributes
wxRegion Class Reference

#include <Region.h>

Inheritance diagram for wxRegion:
Inheritance graph
[legend]
Collaboration diagram for wxRegion:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 wxRegion (wxDC *dc, wxRegion *r=NULL, Bool no_prgn=FALSE)
 ~wxRegion ()
wxDCGetDC ()
void Lock (int v)
void SetRectangle (double x, double y, double width, double height)
void SetRoundedRectangle (double x, double y, double width, double height, double radius=20.0)
void SetEllipse (double x, double y, double width, double height)
void SetPolygon (int n, wxPoint points[], double xoffset=0, double yoffset=0, int fillStyle=wxODDEVEN_RULE, int delta=0)
void SetPath (wxPath *p, double xoffset=0, double yoffset=0, int fillStyle=wxODDEVEN_RULE)
void SetArc (double x, double y, double w, double h, double start, double end)
void Union (wxRegion *)
void Intersect (wxRegion *)
void Subtract (wxRegion *)
void Xor (wxRegion *r)
void BoundingBox (double *x, double *y, double *w, double *h)
Bool Empty ()
Bool ReallyEmpty ()
Bool IsInRegion (double x, double y)
void Cleanup ()
void Install (long target, Bool align)
void InstallPS (wxPostScriptDC *dc, wxPSStream *s)
void install_cleanup ()
voidoperator new (size_t size)
voidoperator new (size_t size, GCPlacement gcp)
voidoperator new (size_t size, void *p)
voidoperator new (size_t size)
voidoperator new (size_t size, GCPlacement gcp)
void operator delete (void *obj)
void operator delete (void *, void *)
void operator delete (void *obj)
voidoperator new[] (size_t size)
voidoperator new[] (size_t size, GCPlacement gcp)
voidoperator new[] (size_t size, void *p)
void operator delete[] (void *obj)
void operator delete[] (void *, void *)

Public Attributes

wxPathRgnprgn
wxDCdc
char is_ps
char no_prgn
int locked
WXTYPE __type
void__gc_external

Detailed Description

Definition at line 52 of file Region.h.


Constructor & Destructor Documentation

wxRegion::wxRegion ( wxDC dc,
wxRegion r = NULL,
Bool  no_prgn = FALSE 
)

Definition at line 43 of file Region.cxx.

{
  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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 63 of file Region.cxx.

{
  Cleanup();
}

Here is the call graph for this function:


Member Function Documentation

void wxRegion::BoundingBox ( double *  x,
double *  y,
double *  w,
double *  h 
)

Definition at line 860 of file Region.cxx.

{
  if (Empty()) {
    *x = *y = *w = *h = 0;
    return;
  } else {
    double v;
#ifdef wx_msw
    RECT r;
    HRGN rgn;

    if (real_rgn)
      rgn = real_rgn;
    else
      rgn = lazy_rgn->GetRgn();

    if (rgn)
      GetRgnBox(rgn, &r);
    else {
      r.left = r.top = r.right = r.bottom = 0;
    }

    if (!real_rgn)
      lazy_rgn->DoneRgn(rgn);
  
    *x = r.left;
    *y = r.top;
    *w = r.right - r.left;
    *h = r.bottom - r.top;
#endif
#ifdef wx_x
    XRectangle r;
    
    XClipBox(rgn, &r);
    
    *x = r.x;
    *y = r.y;
    *w = r.width;
    *h = r.height;
#endif
#ifdef wx_mac
    {
      Rect r;
      GetRegionBounds(rgn,&r);
      *x = r.left;
      *y = r.top;
      *w = r.right - *x;
      *h = r.bottom - *y;
    }
#endif

    if (is_ps) {
      /* Bitmap-based region is stored upside-down */
      *y = -(*y);
    }
    
    v = dc->UnscrolledDeviceToLogicalX((int)*x);
    *x = v;
    v = dc->UnscrolledDeviceToLogicalY((int)*y);
    *y = v;
    v = dc->DeviceToLogicalXRel((int)*w);
    *w = v;
    v = dc->DeviceToLogicalYRel((int)*h);
    *h = v;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 68 of file Region.cxx.

{  
#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;
  }
}

Here is the caller graph for this function:

Definition at line 927 of file Region.cxx.

{
#ifdef wx_msw
  RECT r;
  HRGN rgn;
  Bool is_empty;

  if (!lazy_rgn) return TRUE;

  if (real_rgn)
    rgn = real_rgn;
  else
    rgn = lazy_rgn->GetRgn();

  if (!rgn)
    is_empty = 1;
  else
    is_empty = (GetRgnBox(rgn, &r) == NULLREGION);

  if (!real_rgn)
    lazy_rgn->DoneRgn(rgn);

  return is_empty;
#endif
#ifdef wx_x
  if (!rgn) return TRUE;
  return XEmptyRegion(rgn);
#endif
#ifdef wx_mac
  if (!rgn) return TRUE;
  return EmptyRgn(rgn);
#endif
}

Here is the caller graph for this function:

wxDC* wxRegion::GetDC ( ) [inline]

Definition at line 74 of file Region.h.

{ return dc; }
void wxRegion::Install ( long  target,
Bool  align 
)

Definition at line 1013 of file Region.cxx.

{
  if (prgn) {
    Bool oe;

#ifdef WX_USE_CAIRO
    cairo_new_path(CAIRO_DEV);
#endif
#ifdef wx_mac
    CGContextRef cg = (CGContextRef)target;
    PathTarget *t;
    CGMutablePathRef path;
    
    path = CGPathCreateMutable();
  
    t = (PathTarget *)malloc(sizeof(PathTarget));
    t->path = path;
    t->cg = cg;
    
    target = (long)t;
#endif
#ifdef wx_msw
    Graphics *g = (Graphics *)target;
    GraphicsPath *gp;
    PathTarget *t;

    gp = wxGPathNew(FillModeAlternate);

    t = (PathTarget *)malloc(sizeof(PathTarget));
    t->path = gp;
    t->g = g;
    t->did_one = 0;

    target = (long)t;
#endif

    oe = prgn->Install(target, 0, align);

#ifdef WX_USE_CAIRO
    if (oe)
      cairo_set_fill_rule(CAIRO_DEV, CAIRO_FILL_RULE_EVEN_ODD);
    cairo_clip(CAIRO_DEV);
    if (oe)
      cairo_set_fill_rule(CAIRO_DEV, CAIRO_FILL_RULE_WINDING);
    cairo_new_path(CAIRO_DEV);
#endif
#ifdef wx_mac
    CGContextBeginPath(cg);
    CGContextAddPath(cg, t->path);
    if (oe)
      CGContextEOClip(cg);
    else
      CGContextClip(cg);
    CGPathRelease(t->path);
    free(t);
#endif
#ifdef wx_msw
    wxGSetClip(g, t->path, t->did_one ? CombineModeIntersect : CombineModeReplace);
    wxGPathRelease(t->path);
    free(t);
#endif
  } else {
    /* Empty region: */
#ifdef WX_USE_CAIRO
    cairo_new_path(CAIRO_DEV);
    /* Empty path confuses some versions of Cairo, so
       clip to two non-overlapping regions */
    cairo_move_to(CAIRO_DEV, 0, 0);
    cairo_line_to(CAIRO_DEV, 1, 0);
    cairo_line_to(CAIRO_DEV, 1, 1);
    cairo_clip(CAIRO_DEV);
    cairo_new_path(CAIRO_DEV);
    cairo_move_to(CAIRO_DEV, 2, 2);
    cairo_line_to(CAIRO_DEV, 3, 2);
    cairo_line_to(CAIRO_DEV, 3, 3);
    cairo_clip(CAIRO_DEV);
#endif
#ifdef wx_mac
    {
      CGContextRef cg = (CGContextRef)target;
      CGRect r;
      r.origin.x = 0;
      r.origin.y = 0;
      r.size.width = 0;
      r.size.height = 0;
      CGContextClipToRect(cg, r);
    }
#endif
#ifdef wx_msw
    {
      GraphicsPath *gp;
      Graphics *g = (Graphics *)target;
      gp = wxGPathNew(FillModeAlternate);
      wxGSetClip(g, gp, CombineModeReplace);
      wxGPathRelease(gp);
    }
#endif
  }
}

Here is the call graph for this function:

Definition at line 99 of file wxGC.cxx.

{
  GC_finalization_proc old_fn;
  void *old_data;

# ifdef MZ_PRECISE_GC
#  define ALLOW_NON_BASE 0
#  define CHECK_BASE 0
# else
#  ifdef wx_xt
#   define ALLOW_NON_BASE 0
#   define CHECK_BASE 0
#  else
#   ifdef WIN32
#    define ALLOW_NON_BASE 0
#    define CHECK_BASE 1
#    define CRASH_ON_NONBASE 1
#   else
#    define ALLOW_NON_BASE 1
#    define CHECK_BASE 0
#   endif
#  endif
# endif

# if CHECK_BASE || ALLOW_NON_BASE
  if (GC_base(this) != (void *)this) {
#  if ALLOW_NON_BASE
    return;
#  else
#   ifdef CRASH_ON_NONBASE
    *(long *)0x0 = 1;
#   else
    printf("Clean-up object is not the base object\n");
    abort();
#   endif
#  endif
  }
# endif

  GC_register_finalizer_ignore_self(gcOBJ_TO_PTR(this), 
                                CAST_GCP GC_cleanup, NULL, 
                                CAST_GCPP &old_fn, &old_data);

# if CHECK_BASE
  if (old_fn) {
#  ifdef CRASH_ON_NONBASE
       *(long *)0x0 = 1;
#  else
    printf("Object already has a clean-up\n");
    abort();
#  endif
  }
# endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wxRegion::InstallPS ( wxPostScriptDC *  dc,
wxPSStream s 
)

Definition at line 1113 of file Region.cxx.

{
  Bool oe;

  if (!prgn) return; /* shouldn't happen */

  s->Out("newpath\n");

  oe = prgn->InstallPS(dc, s);

  if (oe)
    s->Out("eoclip\n");
  else
    s->Out("clip\n");
}

Here is the call graph for this function:

Definition at line 705 of file Region.cxx.

{
  if (r->dc != dc) return;
  if (ReallyEmpty())
    return;
  if (r->ReallyEmpty()) {
    Cleanup();
    return;
  }

  if (!no_prgn) {
    wxPathRgn *rprgn, *pr;
    rprgn = r->prgn;
    if (!rprgn) abort();
    if (prgn->is_rect 
       && rprgn->is_rect
       && (prgn->ox == rprgn->ox)
       && (prgn->oy == rprgn->oy)
       && (prgn->sx == rprgn->sx)
       && (prgn->sy == rprgn->sy)) {
      /* Special case: both are rectangles with the same
        origin and scale. This is a common case, and it 
        can be a lot faster making a rectangle directly. */
      wxRectanglePathRgn *r1 = (wxRectanglePathRgn *)prgn;
      wxRectanglePathRgn *r2 = (wxRectanglePathRgn *)rprgn;
      double px, py, pw, ph;

      if (r1->x < r2->x)
       px = r2->x;
      else
       px = r1->x;
      if (r1->y < r2->y)
       py = r2->y;
      else
       py = r1->y;
      if (r1->x + r1->width < r2->x + r2->width)
       pw = (r1->x + r1->width) - px;
      else
       pw = (r2->x + r2->width) - px;
      if (r1->y + r1->height < r2->y + r2->height)
       ph = (r1->y + r1->height) - py;
      else
       ph = (r2->y + r2->height) - py;
      
      if ((pw > 0) && (ph > 0))
       pr = new WXGC_PTRS wxRectanglePathRgn(dc, px, py, pw, ph);
      else {
       /* empty */
       Cleanup();
       return;
      }
    } else {
      pr = new WXGC_PTRS wxIntersectPathRgn(prgn, r->prgn);
    }
    prgn = pr;
  }

#ifdef wx_msw
  if (!lazy_rgn) return;
  if (!r->lazy_rgn) {
    lazy_rgn = NULL;
    return;
  }
  
  lazy_rgn = new UnionLazyRgn(lazy_rgn, r->lazy_rgn, RGN_AND);
#endif
#ifdef wx_x
  if (!rgn) return;
  XIntersectRegion(rgn, r->rgn, rgn);
#endif
#ifdef wx_mac
  if (!rgn) return;
  SectRgn(rgn, r->rgn, rgn);
#endif

  if (ReallyEmpty()) {
    Cleanup();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Bool wxRegion::IsInRegion ( double  x,
double  y 
)

Definition at line 966 of file Region.cxx.

{
  int ix, iy;

  if (Empty()) return FALSE;

  x = dc->FLogicalToUnscrolledDeviceX(x);
  y = dc->FLogicalToUnscrolledDeviceY(y);
  

  ix = (int)floor(x);
  iy = (int)floor(y);

#ifdef wx_xt
  return XPointInRegion(rgn, ix, iy);
#endif
#ifdef wx_msw
  {
    HRGN rgn;
    Bool in_rgn;

    if (real_rgn)
      rgn = real_rgn;
    else
      rgn = lazy_rgn->GetRgn();
    
    if (rgn)
      in_rgn = PtInRegion(rgn, ix, iy);
    else
      in_rgn = 0;

    if (!real_rgn)
      lazy_rgn->DoneRgn(rgn);

    return in_rgn;
  }
#endif
#ifdef wx_mac
  {
    Point p;
    p.h = ix;
    p.v = iy;
    return PtInRgn(p, rgn);
  }
#endif
}

Here is the call graph for this function:

Definition at line 94 of file Region.cxx.

{
#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
}
void gc::operator delete ( void obj) [inline, inherited]
void gc::operator delete ( void obj) [inline, inherited]

Definition at line 287 of file gc_cpp.h.

                                           {
    GC_FREE( obj );}

Here is the caller graph for this function:

void gc::operator delete ( void ,
void  
) [inline, inherited]

Definition at line 291 of file gc_cpp.h.

{}
void gc::operator delete[] ( void obj) [inline, inherited]

Definition at line 305 of file gc_cpp.h.

                                             {
    gc::operator delete( obj );}

Here is the call graph for this function:

void gc::operator delete[] ( void ,
void  
) [inline, inherited]

Definition at line 309 of file gc_cpp.h.

{}
void* gc::operator new ( size_t  size) [inline, inherited]
void* gc::operator new ( size_t  size,
GCPlacement  gcp 
) [inline, inherited]
void * gc::operator new ( size_t  size) [inline, inherited]

Definition at line 273 of file gc_cpp.h.

                                           {
    return GC_MALLOC( size );}

Here is the caller graph for this function:

void * gc::operator new ( size_t  size,
GCPlacement  gcp 
) [inline, inherited]

Definition at line 276 of file gc_cpp.h.

                                                            {
    if (gcp == UseGC) 
        return GC_MALLOC( size );
    else if (gcp == PointerFreeGC)
       return GC_MALLOC_ATOMIC( size );
    else
        return GC_MALLOC_UNCOLLECTABLE( size );}
void * gc::operator new ( size_t  size,
void p 
) [inline, inherited]

Definition at line 284 of file gc_cpp.h.

                                                    {
    return p;}
void * gc::operator new[] ( size_t  size) [inline, inherited]

Definition at line 296 of file gc_cpp.h.

                                             {
    return gc::operator new( size );}

Here is the call graph for this function:

void * gc::operator new[] ( size_t  size,
GCPlacement  gcp 
) [inline, inherited]

Definition at line 299 of file gc_cpp.h.

                                                              {
    return gc::operator new( size, gcp );}

Here is the call graph for this function:

void * gc::operator new[] ( size_t  size,
void p 
) [inline, inherited]

Definition at line 302 of file gc_cpp.h.

                                                      {
    return p;}

Definition at line 961 of file Region.cxx.

{
  return Empty() && !prgn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wxRegion::SetArc ( double  x,
double  y,
double  w,
double  h,
double  start,
double  end 
)

Definition at line 499 of file Region.cxx.

{
  wxRegion *r;
  static double pi;
  int saw_start = 0, saw_end = 0, closed = 0;
  double cx, cy;
  wxPoint *a;
  int n;
  char save_no_prgn;

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

  save_no_prgn = no_prgn;
  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->MoveTo(x + w / 2, y + h / 2);
      p->Arc(x, y, w, h, end, start, FALSE);
      p->Close();
      prgn = new WXGC_PTRS wxPathPathRgn(dc, p, 0, 0, wxWINDING_RULE);
    }
#else
    prgn = new WXGC_PTRS wxArcPathRgn(dc, x, y, w, h, start, end);
#endif
    no_prgn = 1;
  }

  SetEllipse(x, y, w, h);

  if (start == end) return;

  r = new WXGC_PTRS wxRegion(dc, NULL, TRUE);

  if (!pi)
    pi = 2 * asin((double)1.0);

  start = fmod((double)start, 2*pi);
  end = fmod((double)end, 2*pi);
  if (start < 0)
    start += 2*pi;
  if (end < 0)
    end += 2*pi;

  cx = x + w/2;
  cy = y + h/2;

  a[0].x = ((w+2) / 2) * cos(end) + cx;
  a[0].y = ((h+2) / 2) * (-sin(end)) + cy;

  a[1].x = cx;
  a[1].y = cy;

  a[2].x = ((w+2) / 2) * cos(start) + cx;
  a[2].y = ((h+2) / 2) * (-sin(start)) + cy;

  n = 3;

  if (!saw_start && (start < (pi / 2)))
    saw_start = 1;
  if (!saw_end && (end > start) && (end < (pi / 2)))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x + w + 2;
    a[n++].y = y - 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = cx;
    a[n++].y = y - 2;
  } else
    closed = saw_start;

  if (!saw_start && (start < pi))
    saw_start = 1;
  if (!saw_end && (end > start) && (end < pi))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x - 2;
    a[n++].y = y - 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = x - 2;
    a[n++].y = cy;
  } else
    closed = saw_start;

  if (!saw_start && (start < (1.5 * pi)))
    saw_start = 1;
  if (!saw_end && (end > start) && (end < (1.5 * pi)))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x - 2;
    a[n++].y = y + h + 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = cx;
    a[n++].y = y + h + 2;
  } else
    closed = saw_start;

  saw_start = 1;
  saw_end = (end > start);
  
  if (saw_start && !closed) {
    a[n].x = x + w + 2;
    a[n++].y = y + h + 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = x + w + 2;
    a[n++].y = cy;    
  } else
    closed = saw_start;

  if (!saw_end && (end < (pi / 2)))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x + w + 2;
    a[n++].y = y - 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = cx;
    a[n++].y = y - 2; 
  } else
    closed = saw_start;
  
  if (!saw_end && (end < pi))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x - 2;
    a[n++].y = y - 2;
  }
  if (saw_start && !saw_end) {
    a[n].x = x - 2;
    a[n++].y = cy;    
  } else
    closed = saw_start;

  if (!saw_end && (end < (1.5 * pi)))
    saw_end = 1;
  if (saw_start && !closed) {
    a[n].x = x - 2;
    a[n++].y = y + h + 2;
  } 
  if (saw_start && !saw_end) {
    a[n].x = cx;
    a[n++].y = y + h + 2;
  } else
    closed = saw_start;

  if (!closed) {
    a[n].x = x + w + 2;
    a[n++].y = y + h + 2;
  }

  r->SetPolygon(n, a);

  Intersect(r);

  no_prgn = save_no_prgn;
}

Here is the call graph for this function:

void wxRegion::SetEllipse ( double  x,
double  y,
double  width,
double  height 
)

Definition at line 280 of file Region.cxx.

{
  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
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wxRegion::SetPath ( wxPath p,
double  xoffset = 0,
double  yoffset = 0,
int  fillStyle = wxODDEVEN_RULE 
)

Definition at line 440 of file Region.cxx.

{
  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;
}

Here is the call graph for this function:

void wxRegion::SetPolygon ( int  n,
wxPoint  points[],
double  xoffset = 0,
double  yoffset = 0,
int  fillStyle = wxODDEVEN_RULE,
int  delta = 0 
)

Definition at line 371 of file Region.cxx.

{
  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
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wxRegion::SetRectangle ( double  x,
double  y,
double  width,
double  height 
)

Definition at line 123 of file Region.cxx.

{
  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
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wxRegion::SetRoundedRectangle ( double  x,
double  y,
double  width,
double  height,
double  radius = 20.0 
)

Definition at line 174 of file Region.cxx.

{
#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
}

Here is the call graph for this function:

Definition at line 785 of file Region.cxx.

{
  if (r->dc != dc) return;
  if (r->ReallyEmpty()) return;

  if (!no_prgn) {
    /* wxDiffPathRgn is only half a subtract; the result must be intersected with the first part */
    wxPathRgn *pr;
    if (!r->prgn) abort();
    pr = new WXGC_PTRS wxDiffPathRgn(prgn, r->prgn);
    pr = new WXGC_PTRS wxIntersectPathRgn(prgn, pr);
    prgn = pr;
  }

#ifdef wx_msw
  if (!lazy_rgn) return;
  if (!r->lazy_rgn) {
    /* No change */
    return;
  }
  lazy_rgn = new UnionLazyRgn(lazy_rgn, r->lazy_rgn, RGN_DIFF);
#endif
#ifdef wx_x
  if (!rgn) return;
  XSubtractRegion(rgn, r->rgn, rgn);
#endif
#ifdef wx_mac
  if (!rgn) return;
  DiffRgn(rgn, r->rgn, rgn);
#endif

  if (ReallyEmpty()) {
    Cleanup();
    return;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 666 of file Region.cxx.

{
  if (r->dc != dc) return;
  if (r->ReallyEmpty()) return;

  if (!no_prgn) {
    if (!r->prgn) abort();
    if (!prgn)
      prgn = r->prgn;
    else {
      wxPathRgn *pr;
      pr = new WXGC_PTRS wxUnionPathRgn(prgn, r->prgn);
      prgn = pr;
    }
  }

#ifdef wx_msw
  if (!lazy_rgn) {
    lazy_rgn = r->lazy_rgn;
  } else if (!r->lazy_rgn) {
    /* no change */
  } else {
    lazy_rgn = new UnionLazyRgn(lazy_rgn, r->lazy_rgn, RGN_OR);
  }
#endif
#ifdef wx_x
  if (!rgn) {
    rgn = XCreateRegion();
  }
  XUnionRegion(rgn, r->rgn, rgn);
#endif
#ifdef wx_mac
  if (!rgn) {
    rgn = NewRgn();
  }
  UnionRgn(rgn, r->rgn, rgn);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 822 of file Region.cxx.

{
  if (r->dc != dc) return;
  if (r->ReallyEmpty()) return;

  if (!no_prgn) {
    wxPathRgn *pr;
    if (!r->prgn) abort();
    if (!prgn)
      pr = r->prgn;
    else
      pr = new WXGC_PTRS wxDiffPathRgn(prgn, r->prgn);
    prgn = pr;
  }

#ifdef wx_msw
  if (!lazy_rgn) return;
  if (!r->lazy_rgn) {
    return;
  }
  
  lazy_rgn = new UnionLazyRgn(lazy_rgn, r->lazy_rgn, RGN_XOR);
#endif
#ifdef wx_x
  if (!rgn) return;
  XXorRegion(rgn, r->rgn, rgn);
#endif
#ifdef wx_mac
  if (!rgn) return;
  XorRgn(rgn, r->rgn, rgn);
#endif

  if (ReallyEmpty()) {
    Cleanup();
    return;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 146 of file wxGC.h.

WXTYPE wxObject::__type [inherited]

Definition at line 77 of file Object.h.

Definition at line 67 of file Region.h.

Definition at line 68 of file Region.h.

Definition at line 69 of file Region.h.

Definition at line 68 of file Region.h.

Definition at line 66 of file Region.h.


The documentation for this class was generated from the following files: