1 // bounds.h 2 // this file is part of Context Free 3 // --------------------- 4 // Copyright (C) 2006-2007 Mark Lentczner - markl@glyphic.com 5 // Copyright (C) 2006-2013 John Horigan - john@glyphic.com 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; either version 2 10 // of the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 // 21 // John Horigan can be contacted at john@glyphic.com or at 22 // John Horigan, 1209 Villa St., Mountain View, CA 94041-1123, USA 23 // 24 // Mark Lentczner can be contacted at markl@glyphic.com or at 25 // Mark Lentczner, 1209 Villa St., Mountain View, CA 94041-1123, USA 26 // 27 // 28 29 30 #ifndef INCLUDE_BOUNDS_H 31 #define INCLUDE_BOUNDS_H 32 33 #include "agg2/agg_path_storage.h" 34 #include <limits> 35 #include <cmath> 36 37 namespace agg { struct trans_affine; } 38 namespace AST { 39 class ASTpathCommand; 40 struct CommandInfo; 41 } 42 class pathIterator; 43 44 class Bounds { 45 public: Bounds()46 Bounds() : mMin_X(std::numeric_limits<double>::infinity()) {} 47 48 Bounds(const agg::trans_affine& trans, pathIterator& helper, 49 double scale, const AST::CommandInfo& attr); 50 // set bounds to be the bounds of this shape, transformed 51 valid()52 bool valid() const { return std::isfinite(mMin_X) && std::isfinite(mMax_X) && 53 std::isfinite(mMin_Y) && std::isfinite(mMax_Y); } invalidate()54 void invalidate() { mMin_X = std::numeric_limits<double>::infinity(); } 55 56 Bounds dilate(double dilation) const; 57 merge(const Bounds & b)58 void merge(const Bounds& b) 59 // merge the other bounds into this bounds 60 { 61 if (valid() && b.valid()) { 62 if (b.mMin_X < mMin_X) mMin_X = b.mMin_X; 63 if (b.mMax_X > mMax_X) mMax_X = b.mMax_X; 64 if (b.mMin_Y < mMin_Y) mMin_Y = b.mMin_Y; 65 if (b.mMax_Y > mMax_Y) mMax_Y = b.mMax_Y; 66 } else if (b.valid()) { 67 *this = b; 68 } 69 } 70 merge(double x,double y)71 void merge(double x, double y) 72 // merge a point into this bounds 73 { 74 if (valid()) { 75 if (x < mMin_X) mMin_X = x; 76 if (x > mMax_X) mMax_X = x; 77 if (y < mMin_Y) mMin_Y = y; 78 if (y > mMax_Y) mMax_Y = y; 79 } else { 80 mMin_X = mMax_X = x; 81 mMin_Y = mMax_Y = y; 82 } 83 } 84 merge(const agg::point_d & p)85 void merge(const agg::point_d& p) { merge(p.x, p.y); } 86 // merge a point into this bounds 87 88 Bounds operator+(const Bounds& other) const 89 { Bounds t(*this); t.merge(other); return t; } 90 91 Bounds& operator+=(const Bounds& other) 92 { merge(other); return *this; } 93 94 Bounds operator+(const agg::point_d& p) const 95 { Bounds t(*this); t.merge(p); return t; } 96 97 Bounds& operator+=(const agg::point_d& p) 98 { merge(p); return *this; } 99 100 Bounds interpolate(const Bounds& other, double alpha) const; 101 // compute the interpolation between this bounds and the other 102 // an alpha of 0.0 has no effect, an alpha of 1.0 give the other 103 Bounds slewCenter(const Bounds& other, double alpha) const; 104 // compute a new bounds who's center is slewed alpha of the way 105 // toward the other center, yet incorporates all of the current 106 // bounds 107 108 double computeScale(int& width, int& height, double borderX, double borderY, 109 bool modify = false, agg::trans_affine* trans = nullptr, 110 bool exact = false) const; 111 // Computes the scale factor of fitting this bounds into a canvas 112 // of the given width and height, with the provided fixed border. 113 // If modify is true, width and height are reset to the scaled size. 114 // If trans isn't null, it is set to the needed transformation. 115 // If exact is true then the diensions are not bumped to preserve parity. 116 117 void gather(const Bounds& other, double weight); 118 119 void update(const agg::trans_affine& trns, pathIterator& helper, 120 double scale, const AST::CommandInfo& attr); 121 overlaps(const Bounds & other)122 bool overlaps(const Bounds& other) const 123 { 124 return !(other.mMin_X > mMax_X || other.mMax_X < mMin_X || 125 other.mMin_Y > mMax_Y || other.mMax_Y < mMin_Y); 126 127 } 128 129 double mMin_X, mMin_Y, mMax_X, mMax_Y; 130 }; 131 132 #endif // INCLUDE_BOUNDS_H 133