    //------------------------------------------------------------------------------
    // emClipRects.h
    //
    // Copyright (C) 2011-2012,2014 Oliver Hamann.
    //
    // Homepage: http://eaglemode.sourceforge.net/
    //
    // This program is free software: you can redistribute it and/or modify it under
    // the terms of the GNU General Public License version 3 as published by the
    // Free Software Foundation.
    //
    // This program is distributed in the hope that it will be useful, but WITHOUT
    // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
    // more details.
    //
    // You should have received a copy of the GNU General Public License version 3
    // along with this program. If not, see <http://www.gnu.org/licenses/>.
    //------------------------------------------------------------------------------

    #ifndef emClipRects_h
    #define emClipRects_h

    #ifndef emList_h
    #include <emCore/emList.h>
    #endif

    //==============================================================================
    //================================ emClipRects =================================
    //==============================================================================

    template <class NUM> class emClipRects {

    public:

            // Template class for a disjoint set of clip rectangles with
            // copy-on-write behavior. The template parameter NUM is the type of the
            // rectangle coordinates (usually int or double).

            emClipRects();
                    // Construct an empty set of clip rectangles.

            emClipRects(const emClipRects & clipRects);
                    // Construct a copied set of clip rectangles.
                    // Arguments:
                    //   clipRects - The set to be copied.

            emClipRects(NUM x1, NUM y1, NUM x2, NUM y2);
                    // Construct a set of clip rectangles with a single rectangle.
                    // Arguments:
                    //   x1,y1,x2,y2 - Coordinates of the rectangle.

            ~emClipRects();
                    // Destruct a set of clip rectangles.

            emClipRects & operator = (const emClipRects & clipRects);
                    // Copy a set of clip rectangles.

            class Rect {
            public:

                    // Class for one rectangle of a set of clip rectangles.

                    NUM GetX1() const;
                    NUM GetY1() const;
                    NUM GetX2() const;
                    NUM GetY2() const;
                    void Get(NUM * pX1, NUM * pY1, NUM * pX2, NUM * pY2) const;
                            // Get the coordinates of the rectangle.

                    const Rect * GetNext() const;
                            // Get the next rectangle in the list of rectangles.

            private:
                    friend class emClipRects<NUM>;
                    NUM X1,Y1,X2,Y2;
                    Rect * Next;
            };

            const Rect * GetFirst() const;
                    // Get a pointer to the first rectangle. The rectangles are
                    // organized in a single-linked NULL-terminated list. So you can
                    // iterate the rectangles with:
                    //
                    //   for (r=clipRects.GetFirst(); r; r=r->GetNext()) {...}
                    //
                    // The rectangles have no order, except after one has called
                    // Sort().
                    //
                    // At least because of the copy-on-write feature, the pointers
                    // are valid only until calling any non-const method or operator
                    // on this list, or giving this list as a non-const argument to
                    // any call in the world.

            int GetCount() const;
                    // Get the number of rectangles.

            void GetMinMax(NUM * pX1, NUM * pY1, NUM * pX2, NUM * pY2) const;
                    // Calculate the min/max rectangle. That is the smallest
                    // rectangle which encloses the whole set of clip rectangles. If
                    // the set is empty, the rectangle (0,0,0,0) is returned.
                    // Arguments:
                    //   pX1,pY1,pX2,pY2 - Pointers for returning the coordinates of
                    //                     the min/max rectangle.

            void SetToMinMax();
                    // Set this set of clip rectangles to its min/max rectangle.

            void SetToMinMaxOf(const emClipRects & clipRects);
                    // Set this set of clip rectangles to the min/max rectangle of
                    // another set of clip rectangles.

            void Set(NUM x1, NUM y1, NUM x2, NUM y2);
                    // Set this set of clip rectangles to a single rectangle.
                    // Arguments:
                    //   x1,y1,x2,y2 - Coordinates of the rectangle.

            void Set(const emClipRects & clipRects);
                    // Set this set of clip rectangles equal to another set of clip
                    // rectangles.
                    //   clipRects - The set to be copied.

            void Unite(NUM x1, NUM y1, NUM x2, NUM y2);
            void Unite(const emClipRects & clipRects);
            emClipRects & operator += (const emClipRects & clipRects);
            emClipRects operator + (const emClipRects & clipRects) const;
            emClipRects & operator |= (const emClipRects & clipRects);
            emClipRects operator | (const emClipRects & clipRects) const;
                    // Perform the OR operation.

            void Intersect(NUM x1, NUM y1, NUM x2, NUM y2);
            void Intersect(const emClipRects & clipRects);
            emClipRects & operator &= (const emClipRects & clipRects);
            emClipRects operator & (const emClipRects & clipRects) const;
                    // Perform the AND operation.

            void Subtract(NUM x1, NUM y1, NUM x2, NUM y2);
            void Subtract(const emClipRects & clipRects);
            emClipRects & operator -= (const emClipRects & clipRects);
            emClipRects operator - (const emClipRects & clipRects) const;
                    // Perform the AND-NOT operation.

            void Sort();
                    // Sort the list of rectangles primarily by Y1 and secondarily
                    // by X1.

            void Clear();
                    // Empty the set of clip rectangles.

            bool IsEmpty() const;
                    // Ask whether the set of clip rectangles is empty.

            bool IsSubsetOf(NUM x1, NUM y1, NUM x2, NUM y2) const;
            bool IsSubsetOf(const emClipRects & clipRects) const;
                    // Ask whether the set of clip rectangles is contained in
                    // another rectangle or set.

            bool IsSupersetOf(NUM x1, NUM y1, NUM x2, NUM y2) const;
            bool IsSupersetOf(const emClipRects & clipRects) const;
                    // Ask whether the set of clip rectangles is containing
                    // another rectangle or set.

            bool operator == (const emClipRects & clipRects) const;
            bool operator != (const emClipRects & clipRects) const;
                    // Compare sets of clip rectangles.

            unsigned int GetDataRefCount() const;
                    // Get number of references to the data behind this set of clip
                    // rectangles.

            void MakeNonShared();
                    // This must be called before handing the object to another
                    // thread.

    private:

            void PrivUnite(Rect * * list, NUM x1, NUM y1, NUM x2, NUM y2);
            void DeleteData();
            Rect * AllocRect();
            void FreeRect(Rect * rect);
            void AllocBlock();
            static int CompareRects(void * r1, void * r2, void * context);

            struct MemBlock {
                    Rect Rects[16];
                    MemBlock * Next;
            };

            struct SharedData {
                    Rect * List;
                    Rect * FreeList;
                    MemBlock * BlockList;
                    unsigned int Count;
                    unsigned int RefCount;
                    bool IsStaticEmpty;
            };

            SharedData * Data;
            static SharedData EmptyData;
    };

    //==============================================================================
    //============================== Implementations ===============================
    //==============================================================================

    //--------------------------- Inline implementations ---------------------------

    template <class NUM> inline emClipRects<NUM>::emClipRects()
    {
            Data=&EmptyData;
    }

    template <class NUM> inline
    emClipRects<NUM>::emClipRects(const emClipRects & clipRects)
    {
            Data=clipRects.Data;
            Data->RefCount++;
    }

    template <class NUM> inline emClipRects<NUM>::~emClipRects()
    {
            if (!--Data->RefCount) DeleteData();
    }

    template <class NUM> inline
    emClipRects<NUM> & emClipRects<NUM>::operator = (const emClipRects & clipRects)
    {
            clipRects.Data->RefCount++;
            if (!--Data->RefCount) DeleteData();
            Data=clipRects.Data;
            return *this;
    }

    template <class NUM> inline NUM emClipRects<NUM>::Rect::GetX1() const
    {
            return X1;
    }

    template <class NUM> inline NUM emClipRects<NUM>::Rect::GetY1() const
    {
            return Y1;
    }

    template <class NUM> inline NUM emClipRects<NUM>::Rect::GetX2() const
    {
            return X2;
    }

    template <class NUM> inline NUM emClipRects<NUM>::Rect::GetY2() const
    {
            return Y2;
    }

    template <class NUM> inline
    void emClipRects<NUM>::Rect::Get(NUM * pX1, NUM * pY1, NUM * pX2, NUM * pY2) const
    {
            *pX1=X1;
            *pY1=Y1;
            *pX2=X2;
            *pY2=Y2;
    }

    template <class NUM> inline
    const typename emClipRects<NUM>::Rect * emClipRects<NUM>::Rect::GetNext() const
    {
            return Next;
    }

    template <class NUM> inline
    const typename emClipRects<NUM>::Rect * emClipRects<NUM>::GetFirst() const
    {
            return Data->List;
    }

    template <class NUM> inline int emClipRects<NUM>::GetCount() const
    {
            return Data->Count;
    }

    template <class NUM> inline void emClipRects<NUM>::SetToMinMax()
    {
            SetToMinMaxOf(*this);
    }

    template <class NUM> inline
    void emClipRects<NUM>::Set(const emClipRects & clipRects)
    {
            clipRects.Data->RefCount++;
            if (!--Data->RefCount) DeleteData();
            Data=clipRects.Data;
    }

    template <class NUM> inline
    emClipRects<NUM> & emClipRects<NUM>::operator += (const emClipRects & clipRects)
    {
            Unite(clipRects);
            return *this;
    }

    template <class NUM> inline
    emClipRects<NUM> & emClipRects<NUM>::operator |= (const emClipRects & clipRects)
    {
            return *this+=clipRects;
    }

    template <class NUM> inline
    emClipRects<NUM> emClipRects<NUM>::operator | (const emClipRects & clipRects) const
    {
            return *this+clipRects;
    }

    template <class NUM> inline
    emClipRects<NUM> & emClipRects<NUM>::operator &= (const emClipRects & clipRects)
    {
            Intersect(clipRects);
            return *this;
    }

    template <class NUM> inline
    emClipRects<NUM> & emClipRects<NUM>::operator -= (const emClipRects & clipRects)
    {
            Subtract(clipRects);
            return *this;
    }

    template <class NUM> inline void emClipRects<NUM>::Clear()
    {
            if (!--Data->RefCount) DeleteData();
            Data=&EmptyData;
    }

    template <class NUM> inline bool emClipRects<NUM>::IsEmpty() const
    {
            return !Data->Count;
    }

    template <class NUM> inline
    bool emClipRects<NUM>::IsSupersetOf(const emClipRects & clipRects) const
    {
            return clipRects.IsSubsetOf(*this);
    }

    template <class NUM> inline
    bool emClipRects<NUM>::operator != (const emClipRects & clipRects) const
    {
            return !(*this == clipRects);
    }

    template <class NUM> inline unsigned int emClipRects<NUM>::GetDataRefCount() const
    {
            return Data->IsStaticEmpty ? UINT_MAX/2 : Data->RefCount;
    }

    template <class NUM> inline
    typename emClipRects<NUM>::Rect * emClipRects<NUM>::AllocRect()
    {
            Rect * r;

            r=Data->FreeList;
            if (!r) {
                    AllocBlock();
                    r=Data->FreeList;
            }
            Data->FreeList=r->Next;
            Data->Count++;
            return r;
    }

    template <class NUM> inline void emClipRects<NUM>::FreeRect(Rect * rect)
    {
            Data->Count--;
            rect->Next=Data->FreeList;
            Data->FreeList=rect;
    }

    //------------------------- Non-inline implementations -------------------------

    template <class NUM>
    emClipRects<NUM>::emClipRects(NUM x1, NUM y1, NUM x2, NUM y2)
    {
            Rect * r;

            Data=new SharedData;
            Data->List=NULL;
            Data->FreeList=NULL;
            Data->BlockList=NULL;
            Data->Count=0;
            Data->RefCount=1;
            Data->IsStaticEmpty=false;
            r=AllocRect();
            r->X1=x1;
            r->Y1=y1;
            r->X2=x2;
            r->Y2=y2;
            r->Next=NULL;
            Data->List=r;
    }

    template <class NUM>
    void emClipRects<NUM>::GetMinMax(NUM * pX1, NUM * pY1, NUM * pX2, NUM * pY2) const
    {
            NUM x1,y1,x2,y2;
            Rect * r;

            r=Data->List;
            if (!r) {
                    x1=0;
                    y1=0;
                    x2=0;
                    y2=0;
            }
            else {
                    x1=r->X1;
                    y1=r->Y1;
                    x2=r->X2;
                    y2=r->Y2;
                    for (r=r->Next; r; r=r->Next) {
                            if (x1>r->X1) x1=r->X1;
                            if (y1>r->Y1) y1=r->Y1;
                            if (x2<r->X2) x2=r->X2;
                            if (y2<r->Y2) y2=r->Y2;
                    }
            }
            *pX1=x1;
            *pY1=y1;
            *pX2=x2;
            *pY2=y2;
    }

    template <class NUM>
    void emClipRects<NUM>::SetToMinMaxOf(const emClipRects & clipRects)
    {
            NUM x1,y1,x2,y2;

            if (clipRects.Data->Count<=1) {
                    clipRects.Data->RefCount++;
                    if (!--Data->RefCount) DeleteData();
                    Data=clipRects.Data;
            }
            else {
                    GetMinMax(&x1,&y1,&x2,&y2);
                    Set(x1,y1,x2,y2);
            }
    }

    template <class NUM>
    void emClipRects<NUM>::Set(NUM x1, NUM y1, NUM x2, NUM y2)
    {
            Rect * r;

            if (!--Data->RefCount) DeleteData();
            Data=new SharedData;
            Data->List=NULL;
            Data->FreeList=NULL;
            Data->BlockList=NULL;
            Data->Count=0;
            Data->RefCount=1;
            Data->IsStaticEmpty=false;
            r=AllocRect();
            r->X1=x1;
            r->Y1=y1;
            r->X2=x2;
            r->Y2=y2;
            r->Next=NULL;
            Data->List=r;
    }

    template <class NUM>
    void emClipRects<NUM>::Unite(NUM x1, NUM y1, NUM x2, NUM y2)
    {
            if (x1>=x2 || y1>=y2) return;
            MakeNonShared();
            PrivUnite(&Data->List,x1,y1,x2,y2);
    }

    template <class NUM>
    void emClipRects<NUM>::Unite(const emClipRects & clipRects)
    {
            const Rect * r;

            if (Data==clipRects.Data || !clipRects.Data) return;
            MakeNonShared();
            for (r=clipRects.Data->List; r; r=r->Next) {
                    PrivUnite(&Data->List,r->X1,r->Y1,r->X2,r->Y2);
            }
    }

    template <class NUM>
    emClipRects<NUM> emClipRects<NUM>::operator + (const emClipRects & clipRects) const
    {
            emClipRects cr(*this);
            cr.Unite(clipRects);
            return cr;
    }

    template <class NUM>
    void emClipRects<NUM>::Intersect(NUM x1, NUM y1, NUM x2, NUM y2)
    {
            Rect * * pr;
            Rect * r;

            if (x1>=x2 || y1>=y2) {
                    Clear();
                    return;
            }
            MakeNonShared();
            pr=&Data->List;
            for (;;) {
                    r=*pr;
                    if (!r) break;
                    if (r->X1<x1) r->X1=x1;
                    if (r->X2>x2) r->X2=x2;
                    if (r->X1<r->X2) {
                            if (r->Y1<y1) r->Y1=y1;
                            if (r->Y2>y2) r->Y2=y2;
                            if (r->Y1<r->Y2) {
                                    pr=&r->Next;
                                    continue;
                            }
                    }
                    *pr=r->Next;
                    FreeRect(r);
            }
    }

    template <class NUM>
    void emClipRects<NUM>::Intersect(const emClipRects & clipRects)
    {
            Rect * r1, * r2;

            if (Data!=clipRects.Data) {
                    r1=Data->List;
                    if (r1) {
                            r2=clipRects.Data->List;
                            if (!r2) {
                                    Clear();
                            }
                            else if (!r2->Next) {
                                    Intersect(r2->X1,r2->Y1,r2->X2,r2->Y2);
                            }
                            else if (!r1->Next) {
                                    emClipRects cr(clipRects);
                                    cr.Intersect(r1->X1,r1->Y1,r1->X2,r1->Y2);
                                    Set(cr);
                            }
                            else {
                                    emClipRects cr;
                                    cr.SetToMinMaxOf(*this);
                                    cr.Subtract(clipRects);
                                    Subtract(cr);
                            }
                    }
            }
    }

    template <class NUM>
    emClipRects<NUM> emClipRects<NUM>::operator & (const emClipRects & clipRects) const
    {
            emClipRects cr(*this);
            cr.Intersect(clipRects);
            return cr;
    }

    template <class NUM>
    void emClipRects<NUM>::Subtract(NUM x1, NUM y1, NUM x2, NUM y2)
    {
            NUM rx1,ry1,rx2,ry2,sy1,sy2;
            Rect * * pr;
            Rect * r;

            if (!Data->List || x1>=x2 || y1>=y2) return;
            MakeNonShared();
            pr=&Data->List;
            for (;;) {
                    r=*pr;
                    if (!r) break;
                    if (
                            (rx1=r->X1)<x2 &&
                            (rx2=r->X2)>x1 &&
                            (ry1=r->Y1)<y2 &&
                            (ry2=r->Y2)>y1
                    ) {
                            if (ry2>y2) sy2=y2;
                            else sy2=ry2;
                            if (ry1<y1) {
                                    r->Y2=y1;
                                    sy1=y1;
                                    pr=&r->Next;
                            }
                            else {
                                    sy1=ry1;
                                    *pr=r->Next;
                                    FreeRect(r);
                            }
                            if (rx1<x1) {
                                    r=AllocRect();
                                    r->X1=rx1;
                                    r->Y1=sy1;
                                    r->X2=x1;
                                    r->Y2=sy2;
                                    r->Next=*pr;
                                    *pr=r;
                                    pr=&r->Next;
                            }
                            if (rx2>x2) {
                                    r=AllocRect();
                                    r->X1=x2;
                                    r->Y1=sy1;
                                    r->X2=rx2;
                                    r->Y2=sy2;
                                    r->Next=*pr;
                                    *pr=r;
                                    pr=&r->Next;
                            }
                            if (ry2>y2) {
                                    r=AllocRect();
                                    r->X1=rx1;
                                    r->Y1=y2;
                                    r->X2=rx2;
                                    r->Y2=ry2;
                                    r->Next=*pr;
                                    *pr=r;
                                    pr=&r->Next;
                            }
                    }
                    else {
                            pr=&r->Next;
                    }
            }
    }

    template <class NUM>
    void emClipRects<NUM>::Subtract(const emClipRects & clipRects)
    {
            const Rect * r;

            if (Data==clipRects.Data) {
                    Clear();
                    return;
            }
            for (r=clipRects.Data->List; r; r=r->Next) {
                    if (!Data->List) break;
                    Subtract(r->X1,r->Y1,r->X2,r->Y2);
            }
    }

    template <class NUM>
    emClipRects<NUM> emClipRects<NUM>::operator - (const emClipRects & clipRects) const
    {
            emClipRects cr(*this);
            cr.Subtract(clipRects);
            return cr;
    }

    template <class NUM> void emClipRects<NUM>::Sort()
    {
            if (Data->Count>1) {
                    MakeNonShared();
                    emSortSingleLinkedList(
                            (void**)&Data->List,
                            offsetof(Rect,Next),
                            CompareRects,
                            NULL
                    );
            }
    }

    template <class NUM>
    bool emClipRects<NUM>::IsSubsetOf(NUM x1, NUM y1, NUM x2, NUM y2) const
    {
            Rect * r;

            for (r=Data->List; r; r=r->Next) {
                    if (r->X1<x1 || r->Y1<y1 || r->X2>x2 || r->Y2>y2) return false;
            }
            return true;
    }

    template <class NUM>
    bool emClipRects<NUM>::IsSubsetOf(const emClipRects & clipRects) const
    {
            Rect * r;

            if (Data==clipRects.Data) return true;
            if (!Data->List) return true;
            r=clipRects.Data->List;
            if (!r) return false;
            if (!r->Next) return IsSubsetOf(r->X1,r->Y1,r->X2,r->Y2);
            return (*this - clipRects).IsEmpty();
    }

    template <class NUM>
    bool emClipRects<NUM>::IsSupersetOf(NUM x1, NUM y1, NUM x2, NUM y2) const
    {
            return emClipRects(x1,y1,x2,y2).IsSubsetOf(*this);
    }

    template <class NUM>
    bool emClipRects<NUM>::operator == (const emClipRects & clipRects) const
    {
            if (Data==clipRects.Data) return true;
            return IsSubsetOf(clipRects) && clipRects.IsSubsetOf(*this);
    }

    template <class NUM> void emClipRects<NUM>::MakeNonShared()
    {
            SharedData * d1, * d2;
            Rect * r1, *r2;
            Rect * * pr;

            d1=Data;
            if (d1->RefCount>1 || d1->IsStaticEmpty) {
                    d2=new SharedData;
                    d2->List=NULL;
                    d2->FreeList=NULL;
                    d2->BlockList=NULL;
                    d2->Count=0;
                    d2->RefCount=1;
                    d2->IsStaticEmpty=false;
                    d1->RefCount--;
                    Data=d2;
                    r1=d1->List;
                    if (r1) {
                            pr=&d2->List;
                            do {
                                    r2=AllocRect();
                                    r2->X1=r1->X1;
                                    r2->Y1=r1->Y1;
                                    r2->X2=r1->X2;
                                    r2->Y2=r1->Y2;
                                    *pr=r2;
                                    pr=&r2->Next;
                                    r1=r1->Next;
                            } while (r1);
                            *pr=NULL;
                    }
            }
    }

    template <class NUM>
    void emClipRects<NUM>::PrivUnite(Rect * * list, NUM x1, NUM y1, NUM x2, NUM y2)
    {
            NUM rx1,ry1,rx2,ry2;
            Rect * r;

            for (;;) {
                    r=*list;
                    if (!r) break;
                    if (
                            (ry1=r->Y1)>y2 || (ry2=r->Y2)<y1 ||
                            (rx1=r->X1)>x2 || (rx2=r->X2)<x1
                    ) {
                            list=&r->Next;
                    }
                    else if (rx1<=x1 && rx2>=x2 && ry1<=y1 && ry2>=y2) {
                            return;
                    }
                    else if (rx1>=x1 && rx2<=x2 && ry1>=y1 && ry2<=y2) {
                            *list=r->Next;
                            FreeRect(r);
                    }
                    else if (rx1==x1 && rx2==x2) {
                            if (y1>ry1) y1=ry1;
                            if (y2<ry2) y2=ry2;
                            *list=r->Next;
                            FreeRect(r);
                    }
                    else if (ry1<y2 && ry2>y1) {
                            if (ry2>y2) {
                                    r->Y1=y2;
                                    if (ry1<y1) {
                                            r=AllocRect();
                                            r->X1=rx1;
                                            r->Y1=ry1;
                                            r->X2=rx2;
                                            r->Y2=y1;
                                            r->Next=*list;
                                            *list=r;
                                    }
                            }
                            else if (ry1<y1) {
                                    r->Y2=y1;
                            }
                            else {
                                    *list=r->Next;
                                    FreeRect(r);
                            }
                            if (y1<ry1) {
                                    PrivUnite(list,x1,y1,x2,ry1);
                                    y1=ry1;
                            }
                            if (y2>ry2) {
                                    PrivUnite(list,x1,ry2,x2,y2);
                                    y2=ry2;
                            }
                            if (x1>rx1) x1=rx1;
                            if (x2<rx2) x2=rx2;
                    }
                    else {
                            list=&r->Next;
                    }
            }
            r=AllocRect();
            r->X1=x1;
            r->Y1=y1;
            r->X2=x2;
            r->Y2=y2;
            r->Next=NULL;
            *list=r;
    }

    template <class NUM> void emClipRects<NUM>::DeleteData()
    {
            MemBlock * b;

            EmptyData.RefCount=UINT_MAX/2;

            // Never do a
            //  if (Data!=&EmptyData)...
            // instead of
            //  if (!Data->IsStaticEmpty)...
            // because static member variables of template classes could exist
            // multiple times for the same final type (e.g. with Windows DLLs).
            if (!Data->IsStaticEmpty) {
                    while ((b=Data->BlockList)!=NULL) {
                            Data->BlockList=b->Next;
                            delete b;
                    }
                    delete Data;
            }
    }

    template <class NUM> void emClipRects<NUM>::AllocBlock()
    {
            MemBlock * b;
            Rect * r, * e;
            int n;

            b=new MemBlock;
            b->Next=Data->BlockList;
            Data->BlockList=b;
            n=sizeof(b->Rects)/sizeof(Rect);
            e=b->Rects+n-1;
            for (r=b->Rects; r<e; r++) r->Next=r+1;
            e->Next=Data->FreeList;
            Data->FreeList=b->Rects;
    }

    template <class NUM>
    int emClipRects<NUM>::CompareRects(void * r1, void * r2, void * context)
    {
            if (((const Rect*)r1)->Y1<((const Rect*)r2)->Y1) return -1;
            if (((const Rect*)r1)->Y1>((const Rect*)r2)->Y1) return 1;
            if (((const Rect*)r1)->X1<((const Rect*)r2)->X1) return -1;
            if (((const Rect*)r1)->X1>((const Rect*)r2)->X1) return 1;
            return 0;
    }

    template <class NUM>
    typename emClipRects<NUM>::SharedData emClipRects<NUM>::EmptyData=
    {
            NULL,NULL,NULL,0,UINT_MAX/2,true
    };

    #endif