root/testsuite/libbase.all/Range2dTest.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

// 
//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
//   Foundation, Inc
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// 
// 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 for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
#endif

#include "check.h"
#include "Range2d.h"
#include <iostream>
#include <sstream>
#include <cassert>

using namespace std;
using namespace gnash;
using namespace gnash::geometry;

int
main(int /*argc*/, char** /*argv*/)
{

        //
        // Test NULL range construction
        //

        Range2d<int> nullIntRange1;
        check(   nullIntRange1.isNull() );
        check( ! nullIntRange1.isWorld() );
        check( ! nullIntRange1.isFinite() );

        Range2d<int> nullIntRange2(nullRange);
        check_equals( nullIntRange1, nullIntRange2 );
        check( nullIntRange1 == nullIntRange2 );

        //
        // Test WORLD range construction
        //

        Range2d<int> worldIntRange1(worldRange);
        check( ! worldIntRange1.isNull() );
        check(   worldIntRange1.isWorld() );
        check( ! worldIntRange1.isFinite() );
        check( nullIntRange1 != worldIntRange1 );

        //
        // Test FINITE range construction
        //

        Range2d<int> fIntRange1(0, 0, 10, 10);

        check( ! fIntRange1.isNull() );
        check( ! fIntRange1.isWorld() );
        check(   fIntRange1.isFinite() );
        check( fIntRange1 != worldIntRange1 );
        check( fIntRange1 != nullIntRange1 );

        //
        // Test expandToCircle()
        //
        
        Range2d<float> circleRange;
    circleRange.expandToCircle(50.0, 100.0, 10.0);
    check_equals( circleRange, Range2d<float>(40.0, 90.0, 60.0, 110.0));  


        //
        // Test growBy()
        //

        check_equals(
                Range2d<int>(0, 0, 1, 2).growBy(2),
                Range2d<int>(-2, -2, 3, 4) );

        // hit the numeric limits on each side
        unsigned uupbound = std::numeric_limits<unsigned>::max();
        // overflow xmin
        check_equals(
                Range2d<unsigned>(0, 3, 1, 6).growBy(2),
                Range2d<unsigned>(worldRange) );
        // overflow ymin
        check_equals(
                Range2d<unsigned>(3, 1, 7, 8).growBy(2),
                Range2d<unsigned int>(worldRange) );
        // overflow xmax
        check_equals(
                Range2d<unsigned>(10, 10, uupbound-1, 20).growBy(2),
                Range2d<unsigned int>(worldRange) );
        // overflow ymax
        check_equals(
                Range2d<unsigned>(10, 10, 20, uupbound-1).growBy(2),
                Range2d<unsigned int>(worldRange) );
        // overflow both direction so that min is still < max as a result
        // (this is tricky)
        check_equals(
                Range2d<unsigned>(1, 1,
                        uupbound-1, uupbound-1).growBy(uupbound),
                Range2d<unsigned int>(worldRange) );

        //
        // Test shinkBy()
        //

        check_equals(
                Range2d<int>(0, 0, 10, 20).shrinkBy(2),
                Range2d<int>(2, 2, 8, 18) );

        // Collapse horizontally
        check_equals(
                Range2d<int>(0, 3, 1, 6).shrinkBy(2),
                Range2d<int>(nullRange) );
        // Collapse vertically
        check_equals(
                Range2d<int>(0, 3, 10, 6).shrinkBy(8),
                Range2d<int>(nullRange) );

        //
        // Test scale()
        //

        check_equals(
                Range2d<int>(0, 3, 10, 6).scale(2),
                Range2d<int>(0, 6, 20, 12) );

        check_equals(
                Range2d<int>(0, 3, 10, 6).scale(2, 3),
                Range2d<int>(0, 9, 20, 18) );

        check_equals(
                Range2d<int>(-1, 3, 10, 5).scale(3, .5),
                Range2d<int>(-3, 1, 30, 3) );

        check_equals(
                Range2d<unsigned int>(1, 3, 10, 5).scale(3, .5),
                Range2d<unsigned int>(3, 1, 30, 3) );

        check_equals(
                Range2d<float>(-1, 3, 10, 5).scale(3, .5),
                Range2d<float>(-3, 1.5, 30, 2.5) );

        check_equals( // tolerate 1/1000 floating point drift
                round(Range2d<float>(0, 0, 40, 80).scale(1.2, 1.0/20).width()*1000)/1000,
                48);

        check_equals(
                Range2d<float>(0, 0, 40, 80).scale(1.2, 1.0/20).height(),
                4);

        //
        // Test range Union 
        //

        Range2d<int> uIntNW1 = Union(nullIntRange1, worldIntRange1);
        Range2d<int> uIntNW2 = Union(worldIntRange1, nullIntRange1);

        // union is transitive
        check_equals( uIntNW1, uIntNW2 );

        // union of anything with world is world
        check_equals( uIntNW1, worldIntRange1 );

        Range2d<int> uIntNF1 = Union(nullIntRange1, fIntRange1);
        Range2d<int> uIntNF2 = Union(fIntRange1, nullIntRange1);

        // union is transitive
        check_equals( uIntNF1, uIntNF2 );

        // union of anything with null is no-op
        check_equals( uIntNF1, fIntRange1 );

        Range2d<int> uIntWF1 = Union(worldIntRange1, fIntRange1);
        Range2d<int> uIntWF2 = Union(fIntRange1, worldIntRange1);

        // union is transitive
        check_equals( uIntWF1, uIntWF2 );

        // union of anything with world is world
        check_equals( uIntWF1, worldIntRange1 );

        check_equals(
                Union( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, -5, -5)),
                Range2d<int>(-10, -10, 10, 10)
        );

        // disjoint
        check_equals(
                Union( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, 5, 5)),
                Range2d<int>(-10, -10, 10, 10)
        );

        // overlapping
        check_equals(
                Union( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, 5, 5)),
                Range2d<int>(-10, -10, 10, 10)
        );
        check_equals(
                Union( Range2d<float>(-0.2, -0.3, 0.7, 0.8),
                        Range2d<float>(-0.1, -0.1, 0.8, 0.9)),
                Range2d<float>(-0.2, -0.3, 0.8, 0.9)
        );

        // inscribed
        check_equals(
                Union( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(2, 2, 5, 5)),
                Range2d<int>(0, 0, 10, 10)
        );
        check_equals(
                Union( Range2d<unsigned short>(2, 2, 8, 9),
                        Range2d<unsigned short>(0, 1, 9, 10)),
                Range2d<unsigned short>(0, 1, 9, 10)
        );

        //
        // Test Intersection  / Intersects
        //

        Range2d<int> iIntNW1 = Intersection(nullIntRange1, worldIntRange1);
        Range2d<int> iIntNW2 = Intersection(worldIntRange1, nullIntRange1);

        // intersection is transitive
        check_equals( iIntNW1, iIntNW2 );

        // intersection of anything with null is null
        check_equals( iIntNW1, nullIntRange1 );
        check_equals( Intersect(nullIntRange1, worldIntRange1), false );

        // disjoint ranges
        check_equals(
                Intersection( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, -2, -3)),
                Range2d<int>() // NULL range !
        );
        check_equals(
                Intersection( Range2d<double>(-100.4, 50.5, -60.4, 60),
                        Range2d<double>(-80, -10, -70, -9)),
                Range2d<double>() // NULL range !
        );
        check_equals(
                Intersect( Range2d<double>(-100.4, 50.5, -60.4, 60),
                        Range2d<double>(-80, -10, -70, -9)),
                false
        );

        // overlapping ranges
        check_equals(
                Intersection( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, 5, 5) ),
                Range2d<int>(0, 0, 5, 5) 
        );
        check_equals(
                Intersect( Range2d<int>(0, 0, 10, 10),
                        Range2d<int>(-10, -10, 5, 5)),
                true
        );

        // inscribed ranges
        check_equals(
                Intersection( Range2d<unsigned short>(0, 0, 10, 10),
                        Range2d<unsigned short>(2, 2, 5, 5)),
                Range2d<unsigned short>(2, 2, 5, 5) 
        );
        check_equals(
                Intersect( Range2d<unsigned short>(0, 0, 10, 10),
                        Range2d<unsigned short>(2, 2, 5, 5)),
                true
        );

        //
        // Test Range2d<float> to Range2d<int> cast
        //
        
        check_equals( (Range2d<int>)Range2d<float>(-0.1, 0.1, 10.1, 10.2),
                        Range2d<int>(-1, 0, 11, 11) );


        //
        // Test Contains
        //

        // Null ranges don't contain anything, not even themselves
        check( ! nullIntRange1.contains(10, 10) );
        check( ! nullIntRange1.contains(nullIntRange1) );
        check( ! nullIntRange1.contains(worldIntRange1) );

        // World ranges contain everything except null ranges
        check( worldIntRange1.contains(10, -190) );
        check( worldIntRange1.contains(worldIntRange1) );
        check( ! worldIntRange1.contains(nullIntRange1) );

        // Self-containment
        check( fIntRange1.contains(fIntRange1) );

        cout << "fIntRange1 == " << fIntRange1 << endl;

        // Boundary overlaps
        check( fIntRange1.contains(0, 0) );
        check( fIntRange1.contains(10, 5) );
        check( fIntRange1.contains(5, 10) );
        check( fIntRange1.contains(5, 0) );
        check( fIntRange1.contains(Range2d<int>(0, 0, 2, 2)) );
        check( fIntRange1.contains(Range2d<int>(0, 4, 2, 6)) );
        check( fIntRange1.contains(Range2d<int>(0, 8, 2, 10)) );
        check( fIntRange1.contains(Range2d<int>(4, 8, 6, 10)) );
        check( fIntRange1.contains(Range2d<int>(8, 8, 10, 10)) );
        check( fIntRange1.contains(Range2d<int>(8, 4, 10, 6)) );
        check( fIntRange1.contains(Range2d<int>(8, 0, 10, 2)) );
        check( fIntRange1.contains(Range2d<int>(4, 0, 6, 2)) );

        // Strict containment
        check( fIntRange1.contains(Range2d<int>(2, 2, 4, 4)) );
        check( fIntRange1.contains(5, 5) );

        // Intersection (partial overlap)
        check( ! fIntRange1.contains(Range2d<int>(-2, 0, 2, 2)) );
        check( ! fIntRange1.contains(Range2d<int>(8, 8, 10, 11)) );
        check( ! fIntRange1.contains(Range2d<int>(8, 8, 11, 11)) );
        

}


/* [<][>][^][v][top][bottom][index][help] */