summaryrefslogtreecommitdiff
path: root/Build/source/texk/lcdf-typetools/lcdf-typetools-2.98/include/lcdf/transform.hh
blob: 496658a49114bfed6d6498f65f3cca749ffc9b97 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// -*- related-file-name: "../../liblcdf/transform.cc" -*-
#ifndef LCDF_TRANSFORM_HH
#define LCDF_TRANSFORM_HH
#include <lcdf/bezier.hh>
#include <lcdf/string.hh>
#include <assert.h>

class Transform { public:

    Transform();
    Transform(const double[6]);
    Transform(double scalex, double sheary, double shearx, double scaley, double shiftx, double shifty);
    // Transform(const Transform &)	generated by compiler
    // ~Transform()			generated by compiler

    double operator[](int i) const	{ assert(i>=0&&i<6); return _m[i]; }
    bool null() const			{ return _null; }
    void check_null(double tolerance);

    void scale(double, double);
    void scale(const Point &p)			{ scale(p.x, p.y); }
    void scale(double d)			{ scale(d, d); }
    void rotate(double);
    void translate(double, double);
    void translate(const Point &p)		{ translate(p.x, p.y); }
    void shear(double);
    inline void transform(const Transform &);

    inline Transform scaled(double, double) const;
    Transform scaled(const Point &p) const	{ return scaled(p.x, p.y); }
    Transform scaled(double d) const		{ return scaled(d, d); }
    inline Transform rotated(double) const;
    inline Transform translated(double, double) const;
    inline Transform translated(const Point &p) const;
    inline Transform sheared(double) const;
    Transform transformed(const Transform &) const;

    // Transform operator+(Transform, const Point &);
    // Transform &operator+=(Transform &, const Point &);
    // Transform operator*(Transform, double);
    // Transform &operator*=(Transform &, double);
    // Transform operator*(Transform, const Transform &);
    // Transform &operator*=(Transform &, const Transform &);
    friend Point operator*(const Point &, const Transform &);
    friend Point &operator*=(Point &, const Transform &);
    friend Bezier operator*(const Bezier &, const Transform &);
    friend Bezier &operator*=(Bezier &, const Transform &);

    String unparse() const;

  private:

    // stored in PostScript order (along columns)
    double _m[6];
    bool _null;

    void real_apply_to(Point &) const;
    Point real_apply(const Point &) const;

};


inline Transform
Transform::scaled(double x, double y) const
{
    Transform t(*this);
    t.scale(x, y);
    return t;
}

inline Transform
Transform::rotated(double r) const
{
    Transform t(*this);
    t.rotate(r);
    return t;
}

inline Transform
Transform::translated(double x, double y) const
{
    Transform t(*this);
    t.translate(x, y);
    return t;
}

inline Transform
Transform::translated(const Point &p) const
{
    return translated(p.x, p.y);
}

inline Transform
Transform::sheared(double s) const
{
    Transform t(*this);
    t.shear(s);
    return t;
}


inline Transform &
operator+=(Transform &t, const Point &p)
{
    t.translate(p);
    return t;
}

inline Transform
operator+(Transform t, const Point &p)
{
    return t += p;
}

inline Transform &
operator*=(Transform &t, double scale)
{
    t.scale(scale);
    return t;
}

inline Transform
operator*(Transform t, double scale)
{
    return t *= scale;
}

inline Transform
operator*(const Transform &t, const Transform &tt)
{
    return t.transformed(tt);
}

inline Transform &
operator*=(Transform &t, const Transform &tt)
{
    t = t.transformed(tt);
    return t;
}

inline void
Transform::transform(const Transform &t)
{
    *this *= t;
}


inline Point &
operator*=(Point &p, const Transform &t)
{
    if (!t.null())
	t.real_apply_to(p);
    return p;
}

inline Point
operator*(const Point &p, const Transform &t)
{
    return (t.null() ? p : t.real_apply(p));
}

#endif