File: bounds.h

package info (click to toggle)
contextfree 3.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,260 kB
  • sloc: cpp: 37,992; lex: 414; makefile: 123; sh: 43; python: 34
file content (135 lines) | stat: -rw-r--r-- 5,201 bytes parent folder | download | duplicates (2)
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