/**************************************************************************** ** COPYRIGHT (C): 1997 Cay S. Horstmann. All Rights Reserved. ** PROJECT: Practical OO Development with C++ and Java ** FILE: shapes8.cpp ** PURPOSE: test graphics shapes in chapter 8 ** VERSION 1.0 ** PROGRAMMERS: Cay Horstmann (CSH) ** RELEASE DATE: 3-15-97 (CSH) ** UPDATE HISTORY: ****************************************************************************/ /* Project: GUI Application Add files shapes8.cpp \PracticalOOBook\cpplib\graphics.cpp Additional include directory: \PracticalOOBook\cpplib */ #include "setup.h" #include #include #include "graphics.h" #ifdef PRACTICALOO_MIN_MAX_CONFLICT #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) #endif #endif class Point; class Segment; class Shape { public: virtual void scale(Point center, double s) = 0; virtual void move(int x, int y) = 0; virtual void plot(Graphics& g) const = 0; virtual void print(ostream& os) const = 0; virtual ~Shape() {} }; /*-------------------------------------------------------------*/ class Point : public Shape { public: Point(int xx =0, int yy =0); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; int x() const; int y() const; #ifdef PRACTICALOO_COMPILER_UNREASONABLY_INSISTS_ON_COMPARISON_OPERATORS_FOR_VECTORS bool operator<(const Point& b) const { return _x < b._x || _x == b._x && _y < b._y; } bool operator==(const Point& b) const { return _x == b._x && _y == b._y; } #endif private: int _x; int _y; }; /*-------------------------------------------------------------*/ class Rectangle : public Shape { public: Rectangle(); Rectangle(Point, Point); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; Point topleft() const; Point bottomright() const; private: Point _topleft; Point _bottomright; }; /*-------------------------------------------------------------*/ class FilledRect : public Rectangle { public: FilledRect(); FilledRect(Point, Point, Color); virtual void plot(Graphics& g) const; private: Color _color; }; /*-------------------------------------------------------------*/ class Polygon : public Shape { public: Polygon(); Polygon(int); void set_corner(int, Point); Point corner(int) const; virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; private: #ifndef PRACTICALOO_MUST_USE_ALLOCATOR vector _corners; #else vector > _corners; #endif }; /*-------------------------------------------------------------*/ class Text : public Shape { public: Text() {} Text(Point, string); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; private: Point _start; string _text; }; /*-------------------------------------------------------------*/ class ScalableText : public Text { public: ScalableText(); ScalableText(Point, string, double); virtual void scale(Point center, double s); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; private: double _size; }; /*-------------------------------------------------------------*/ Point::Point(int xx, int yy) : _x(xx), _y(yy) {} /*.............................................................*/ void Point::plot(Graphics& g) const { g.drawOval(_x - 2, _y - 2, 5, 5); } /*.............................................................*/ void Point::print(ostream& os) const { os << "(" << _x << "," << _y << ")"; } /*.............................................................*/ void Point::scale(Point center, double s) { _x = center._x + (int)((_x - center._x) * s); _y = center._y + (int)((_y - center._y) * s); } /*.............................................................*/ void Point::move(int x, int y) { _x += x; _y += y; } /*.............................................................*/ inline int Point::x() const { return _x; } /*.............................................................*/ inline int Point::y() const { return _y; } /*-------------------------------------------------------------*/ Rectangle::Rectangle() {} /*.............................................................*/ Rectangle::Rectangle(Point p, Point q) /* RECEIVES: p, q - two corner points */ : _topleft(min(p.x(), q.x()), min(p.y(), q.y())), _bottomright(max(p.x(), q.x()), max(p.y(), q.y())) {} /*.............................................................*/ void Rectangle::plot(Graphics& g) const { g.drawRect(_topleft.x(), _topleft.y(), _bottomright.x() - _topleft.x(), _bottomright.y() - _topleft.y()); } /*.............................................................*/ void Rectangle::print(ostream& os) const { _topleft.print(os); _bottomright.print(os); } /*.............................................................*/ void Rectangle::scale(Point center, double s) { _topleft.scale(center, s); _bottomright.scale(center, s); } /*.............................................................*/ void Rectangle::move(int x, int y) { _topleft.move(x, y); _bottomright.move(x, y); } /*.............................................................*/ Point Rectangle::topleft() const { return _topleft; } /*.............................................................*/ Point Rectangle::bottomright() const { return _bottomright; } /*-------------------------------------------------------------*/ FilledRect::FilledRect() : _color(Color::black) {} /*.............................................................*/ FilledRect::FilledRect(Point p, Point q, Color b) : _color(b), Rectangle(p, q) {} /*.............................................................*/ void FilledRect::plot(Graphics& g) const { g.setColor(_color); g.fillRect(topleft().x(), topleft().y(), bottomright().x() - topleft().x(), bottomright().y() - topleft().y()); g.setColor(Color::black); } /*-------------------------------------------------------------*/ Polygon::Polygon() /* REMARKS: Makes a useless null polygon */ {} /*.............................................................*/ Polygon::Polygon(int n) /* RECEIVES: n - the number of vertices */ : _corners(n) {} /*.............................................................*/ Point Polygon::corner(int i) const { return _corners[i]; } /*.............................................................*/ void Polygon::set_corner(int i , Point p) { if (0 <= i && i < _corners.size()) _corners[i] = p; } /*.............................................................*/ void Polygon::plot(Graphics& g) const { for (int i = 0; i < _corners.size(); i++) { int j = i + 1; if (j > _corners.size() - 1) j = 0; Point p = _corners[i]; Point q = _corners[j]; g.drawLine(p.x(), p.y(), q.x(), q.y()); } } /*.............................................................*/ void Polygon::print(ostream& os) const { os << _corners.size() << " "; for (int i = 0; i < _corners.size(); i++) { _corners[i].print(os); } } /*.............................................................*/ void Polygon::scale(Point center, double s) { for (int i = 0; i < _corners.size(); i++) _corners[i].scale(center, s); } /*.............................................................*/ void Polygon::move(int x, int y) { for (int i = 0; i < _corners.size(); i++) _corners[i].move(x, y); } /*-------------------------------------------------------------*/ Text::Text(Point s, string t) : _start(s), _text(t) {} /*.............................................................*/ void Text::plot(Graphics& g) const { g.drawString(_text, _start.x(), _start.y()); } /*.............................................................*/ void Text::scale(Point center, double s) { _start.scale(center, s); } /*.............................................................*/ void Text::move(int x, int y) { _start.move(x, y); } /*.............................................................*/ void Text::print(ostream& os) const { _start.print(os); os << " " << _text << endl; } /*-------------------------------------------------------------*/ ScalableText::ScalableText() : _size(1) {} /*.............................................................*/ ScalableText::ScalableText(Point start, string t, double size) : Text(start, t), _size(size) {} /*.............................................................*/ void ScalableText::plot(Graphics& g) const { Font f = g.getFont(); Font newfont(f.getName(), (int)(_size + 0.5), f.getStyle()); g.setFont(newfont); Text::plot(g); g.setFont(f); } /*.............................................................*/ void ScalableText::scale(Point center, double s) { Text::scale(center, s); _size = _size * s; } /*.............................................................*/ void ScalableText::print(ostream& os) const { Text::print(os); os << " " << _size; } /*-------------------------------------------------------------*/ void paint(Graphics& g) { #ifndef PRACTICALOO_MUST_USE_ALLOCATOR vector fig; #else vector > fig; #endif fig.push_back(new Point(150, 150)); #ifndef PRACTICAL_OO_ANONYMOUS_OBJECT_PARAMS_CAUSE_INTERNAL_ERROR fig.push_back(new Rectangle(Point(40, 30), Point(60, 70))); fig.push_back(new FilledRect(Point(80, 40), Point(130, 165), Color::red)); #else // code above causes internal error in BC45 Point p2 = Point(15, 30); fig.push_back(new Rectangle(Point(40, 60), p2)); p2 = Point(20, 40); fig.push_back(new FilledRect(Point(10, 16), p2, Color::green)); p2 = Point(200, 170); #endif Polygon* p = new Polygon(3); p->set_corner(0, Point(350, 100)); p->set_corner(1, Point(400, 140)); p->set_corner(2, Point(350, 180)); fig.push_back(p); fig.push_back(new ScalableText(Point(500, 100), "Hi", 36)); fig.push_back(new Text(Point(160, 150), "Hello")); for (int i = 1; i < 20; i++) { for (int j = 0; j < fig.size(); j++) { fig[j]->plot(g); fig[j]->scale(Point(8, 8), 0.9); } } }