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