~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/2geom/path.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Ted Gould, Kees Cook
  • Date: 2009-06-24 14:00:43 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090624140043-07stp20mry48hqup
Tags: 0.47~pre0-0ubuntu1
* New upstream release

[ Ted Gould ]
* debian/control: Adding libgsl0 and removing version specifics on boost

[ Kees Cook ]
* debian/watch: updated to run uupdate and mangle pre-release versions.
* Dropped patches that have been taken upstream:
  - 01_mips
  - 02-poppler-0.8.3
  - 03-chinese-inkscape
  - 05_fix_latex_patch
  - 06_gcc-4.4
  - 07_cdr2svg
  - 08_skip-bad-utf-on-pdf-import
  - 09_gtk-clist
  - 10_belarussian
  - 11_libpng
  - 12_desktop
  - 13_slider
  - 100_svg_import_improvements
  - 102_sp_pattern_painter_free
  - 103_bitmap_type_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Path - Series of continuous curves
3
 
 *   
4
 
 * Copyright 2007  MenTaLguY <mental@rydia.net>
5
 
 *     
6
 
 * This library is free software; you can redistribute it and/or 
 
3
 *
 
4
 * Authors:
 
5
 *              MenTaLguY <mental@rydia.net>
 
6
 *              Marco Cecchetti <mrcekets at gmail.com>
 
7
 *
 
8
 * Copyright 2007-2008  authors
 
9
 *
 
10
 * This library is free software; you can redistribute it and/or
7
11
 * modify it either under the terms of the GNU Lesser General Public
8
12
 * License version 2.1 as published by the Free Software Foundation
9
13
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 
 * Public License Version 1.1 (the "MPL"). If you do not alter this 
 
14
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
15
 * notice, a recipient may use your version of this file under either
12
16
 * the MPL or the LGPL.
13
 
 *            
 
17
 *
14
18
 * You should have received a copy of the LGPL along with this library
15
 
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software 
 
19
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
 
 * You should have received a copy of the MPL along with this library 
 
21
 * You should have received a copy of the MPL along with this library
18
22
 * in the file COPYING-MPL-1.1
19
 
 *                
 
23
 *
20
24
 * The contents of this file are subject to the Mozilla Public License
21
25
 * Version 1.1 (the "License"); you may not use this file except in
22
26
 * compliance with the License. You may obtain a copy of the License at
23
27
 * http://www.mozilla.org/MPL/
24
 
 *                   
 
28
 *
25
29
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
30
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
31
 * the specific language governing rights and limitations.
28
32
 */
29
33
 
30
 
#include "path.h"
31
 
 
32
 
#include "ord.h"
33
 
 
34
 
namespace Geom {
35
 
 
36
 
int CurveHelpers::root_winding(Curve const &c, Point p) {
37
 
    std::vector<double> ts = c.roots(p[Y], Y);
38
 
 
39
 
    if(ts.empty()) return 0;
40
 
 
41
 
    double const fudge = 0.01; //fudge factor used on first and last
42
 
 
43
 
    std::sort(ts.begin(), ts.end());
44
 
 
45
 
    // winding determined by crossings at roots
46
 
    int wind=0;
47
 
    // previous time
48
 
    double pt = ts.front() - fudge;
49
 
    for ( std::vector<double>::iterator ti = ts.begin()
50
 
        ; ti != ts.end()
51
 
        ; ++ti )
52
 
    {
53
 
        double t = *ti;
54
 
        if ( t <= 0. || t >= 1. ) continue; //skip endpoint roots 
55
 
        if ( c.valueAt(t, X) > p[X] ) { // root is ray intersection
56
 
            // Get t of next:
57
 
            std::vector<double>::iterator next = ti;
58
 
            next++;
59
 
            double nt;
60
 
            if(next == ts.end()) nt = t + fudge; else nt = *next;
61
 
            
62
 
            // Check before in time and after in time for positions
63
 
            // Currently we're using the average times between next and previous segs
64
 
            Cmp after_to_ray =  cmp(c.valueAt((t + nt) / 2, Y), p[Y]);
65
 
            Cmp before_to_ray = cmp(c.valueAt((t + pt) / 2, Y), p[Y]);
66
 
            // if y is included, these will have opposite values, giving order.
67
 
            Cmp dt = cmp(after_to_ray, before_to_ray);
68
 
            if(dt != EQUAL_TO) //Should always be true, but yah never know..
69
 
                wind += dt;
70
 
            pt = t;
71
 
        }
 
34
 
 
35
 
 
36
 
 
37
#include <2geom/path.h>
 
38
#include <algorithm>
 
39
 
 
40
 
 
41
using namespace Geom::PathInternal;
 
42
 
 
43
namespace Geom
 
44
{
 
45
 
 
46
OptRect Path::boundsFast() const {
 
47
  OptRect bounds;
 
48
  if (empty()) return bounds;
 
49
  bounds=front().boundsFast();
 
50
  const_iterator iter = begin();
 
51
  if ( iter != end() ) {
 
52
    for ( ++iter; iter != end() ; ++iter ) {
 
53
      bounds.unionWith(iter->boundsFast());
72
54
    }
73
 
    
74
 
    return wind;
75
 
}
76
 
 
77
 
void Path::swap(Path &other) {
78
 
  std::swap(curves_, other.curves_);
79
 
  std::swap(closed_, other.closed_);
80
 
  std::swap(*final_, *other.final_);
81
 
  curves_[curves_.size()-1] = final_;
82
 
  other.curves_[other.curves_.size()-1] = other.final_;
83
 
}
84
 
 
85
 
Rect Path::boundsFast() const {
86
 
  Rect bounds=front().boundsFast();
87
 
  for ( const_iterator iter=++begin(); iter != end() ; ++iter ) {
88
 
    bounds.unionWith(iter->boundsFast());
89
55
  }
90
56
  return bounds;
91
57
}
92
58
 
93
 
Rect Path::boundsExact() const {
94
 
  Rect bounds=front().boundsExact();
95
 
  for ( const_iterator iter=++begin(); iter != end() ; ++iter ) {
96
 
    bounds.unionWith(iter->boundsExact());
 
59
OptRect Path::boundsExact() const {
 
60
  OptRect bounds;
 
61
  if (empty()) return bounds;
 
62
  bounds=front().boundsExact();
 
63
  const_iterator iter = begin();
 
64
  if ( iter != end() ) {
 
65
    for ( ++iter; iter != end() ; ++iter ) {
 
66
      bounds.unionWith(iter->boundsExact());
 
67
    }
97
68
  }
98
69
  return bounds;
99
70
}
106
77
  return ret;
107
78
}
108
79
 
109
 
//This assumes that you can't be perfect in your t-vals, and as such, tweaks the start
 
80
Path &Path::operator*=(Matrix const &m) {
 
81
  unshare();
 
82
  Sequence::iterator last = get_curves().end() - 1;
 
83
  Sequence::iterator it;
 
84
  Point prev;
 
85
  for (it = get_curves().begin() ; it != last ; ++it) {
 
86
    *it = boost::shared_ptr<Curve>((*it)->transformed(m));
 
87
    if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) {
 
88
      THROW_CONTINUITYERROR();
 
89
    }
 
90
    prev = (*it)->finalPoint();
 
91
  }
 
92
  for ( int i = 0 ; i < 2 ; ++i ) {
 
93
    final_->setPoint(i, (*final_)[i] * m);
 
94
  }
 
95
  if (get_curves().size() > 1) {
 
96
    if ( front().initialPoint() != initialPoint() || back().finalPoint() != finalPoint() ) {
 
97
      THROW_CONTINUITYERROR();
 
98
    }
 
99
  }
 
100
  return *this;
 
101
}
 
102
 
 
103
std::vector<double>
 
104
Path::allNearestPoints(Point const& _point, double from, double to) const
 
105
{
 
106
        if ( from > to ) std::swap(from, to);
 
107
        const Path& _path = *this;
 
108
        unsigned int sz = _path.size();
 
109
        if ( _path.closed() ) ++sz;
 
110
        if ( from < 0 || to > sz )
 
111
        {
 
112
                THROW_RANGEERROR("[from,to] interval out of bounds");
 
113
        }
 
114
        double sif, st = modf(from, &sif);
 
115
        double eif, et = modf(to, &eif);
 
116
        unsigned int si = static_cast<unsigned int>(sif);
 
117
        unsigned int ei = static_cast<unsigned int>(eif);
 
118
        if ( si == sz )
 
119
        {
 
120
                --si;
 
121
                st = 1;
 
122
        }
 
123
        if ( ei == sz )
 
124
        {
 
125
                --ei;
 
126
                et = 1;
 
127
        }
 
128
        if ( si == ei )
 
129
        {
 
130
                std::vector<double>     all_nearest =
 
131
                        _path[si].allNearestPoints(_point, st, et);
 
132
                for ( unsigned int i = 0; i < all_nearest.size(); ++i )
 
133
                {
 
134
                        all_nearest[i] = si + all_nearest[i];
 
135
                }
 
136
                return all_nearest;
 
137
        }
 
138
        std::vector<double> all_t;
 
139
        std::vector< std::vector<double> > all_np;
 
140
        all_np.push_back( _path[si].allNearestPoints(_point, st) );
 
141
        std::vector<unsigned int> ni;
 
142
        ni.push_back(si);
 
143
        double dsq;
 
144
        double mindistsq
 
145
                = distanceSq( _point, _path[si].pointAt( all_np.front().front() ) );
 
146
        Rect bb(Geom::Point(0,0),Geom::Point(0,0));
 
147
        for ( unsigned int i = si + 1; i < ei; ++i )
 
148
        {
 
149
                bb = *(_path[i].boundsFast());
 
150
                dsq = distanceSq(_point, bb);
 
151
                if ( mindistsq < dsq ) continue;
 
152
                all_t = _path[i].allNearestPoints(_point);
 
153
                dsq = distanceSq( _point, _path[i].pointAt( all_t.front() ) );
 
154
                if ( mindistsq > dsq )
 
155
                {
 
156
                        all_np.clear();
 
157
                        all_np.push_back(all_t);
 
158
                        ni.clear();
 
159
                        ni.push_back(i);
 
160
                        mindistsq = dsq;
 
161
                }
 
162
                else if ( mindistsq == dsq )
 
163
                {
 
164
                        all_np.push_back(all_t);
 
165
                        ni.push_back(i);
 
166
                }
 
167
        }
 
168
        bb = *(_path[ei].boundsFast());
 
169
        dsq = distanceSq(_point, bb);
 
170
        if ( mindistsq >= dsq )
 
171
        {
 
172
                all_t = _path[ei].allNearestPoints(_point, 0, et);
 
173
                dsq = distanceSq( _point, _path[ei].pointAt( all_t.front() ) );
 
174
                if ( mindistsq > dsq )
 
175
                {
 
176
                        for ( unsigned int i = 0; i < all_t.size(); ++i )
 
177
                        {
 
178
                                all_t[i] = ei + all_t[i];
 
179
                        }
 
180
                        return all_t;
 
181
                }
 
182
                else if ( mindistsq == dsq )
 
183
                {
 
184
                        all_np.push_back(all_t);
 
185
                        ni.push_back(ei);
 
186
                }
 
187
        }
 
188
        std::vector<double> all_nearest;
 
189
        for ( unsigned int i = 0; i < all_np.size(); ++i )
 
190
        {
 
191
                for ( unsigned int j = 0; j < all_np[i].size(); ++j )
 
192
                {
 
193
                        all_nearest.push_back( ni[i] + all_np[i][j] );
 
194
                }
 
195
        }
 
196
        all_nearest.erase(std::unique(all_nearest.begin(), all_nearest.end()),
 
197
                          all_nearest.end());
 
198
        return all_nearest;
 
199
}
 
200
 
 
201
std::vector<double>
 
202
Path::nearestPointPerCurve(Point const& _point) const
 
203
{
 
204
        //return a single nearest point for each curve in this path
 
205
        std::vector<double> np;
 
206
        const Path& _path = *this;
 
207
        for (Sequence::const_iterator it = _path.get_curves().begin() ; it != _path.get_curves().end()-1 ; ++it)
 
208
        //for (std::vector<Path>::const_iterator it = _path.begin(); it != _path.end(), ++it){
 
209
        {
 
210
            np.push_back((*it)->nearestPoint(_point));
 
211
    }
 
212
        return np;
 
213
}  
 
214
 
 
215
double Path::nearestPoint(Point const &_point, double from, double to, double *distance_squared) const
 
216
{
 
217
        if ( from > to ) std::swap(from, to);
 
218
        const Path& _path = *this;
 
219
        unsigned int sz = _path.size();
 
220
        if ( _path.closed() ) ++sz;
 
221
        if ( from < 0 || to > sz )
 
222
        {
 
223
                THROW_RANGEERROR("[from,to] interval out of bounds");
 
224
        }
 
225
        double sif, st = modf(from, &sif);
 
226
        double eif, et = modf(to, &eif);
 
227
        unsigned int si = static_cast<unsigned int>(sif);
 
228
        unsigned int ei = static_cast<unsigned int>(eif);
 
229
        if(sz == 0) {// naked moveto
 
230
            if (distance_squared != NULL)
 
231
                *distance_squared = distanceSq(_point, _path.initialPoint());
 
232
            return 0;
 
233
        }
 
234
        if ( si == sz )
 
235
        {
 
236
                --si;
 
237
                st = 1;
 
238
        }
 
239
        if ( ei == sz )
 
240
        {
 
241
                --ei;
 
242
                et = 1;
 
243
        }
 
244
        if ( si == ei )
 
245
        {
 
246
                double nearest = _path[si].nearestPoint(_point, st, et);
 
247
                if (distance_squared != NULL)
 
248
                    *distance_squared = distanceSq(_point, _path[si].pointAt(nearest));
 
249
                return si + nearest;
 
250
        }
 
251
 
 
252
        double t;
 
253
        double nearest = _path[si].nearestPoint(_point, st);
 
254
        unsigned int ni = si;
 
255
        double dsq;
 
256
        double mindistsq = distanceSq(_point, _path[si].pointAt(nearest));
 
257
        Rect bb(Geom::Point(0,0),Geom::Point(0,0));
 
258
        for ( unsigned int i = si + 1; i < ei; ++i )
 
259
        {
 
260
                bb = *(_path[i].boundsFast());
 
261
                dsq = distanceSq(_point, bb);
 
262
                if ( mindistsq <= dsq ) continue;
 
263
                t = _path[i].nearestPoint(_point);
 
264
                dsq = distanceSq(_point, _path[i].pointAt(t));
 
265
                if ( mindistsq > dsq )
 
266
                {
 
267
                        nearest = t;
 
268
                        ni = i;
 
269
                        mindistsq = dsq;
 
270
                }
 
271
        }
 
272
        bb = *(_path[ei].boundsFast());
 
273
        dsq = distanceSq(_point, bb);
 
274
        if ( mindistsq > dsq )
 
275
        {
 
276
                t = _path[ei].nearestPoint(_point, 0, et);
 
277
                dsq = distanceSq(_point, _path[ei].pointAt(t));
 
278
                if ( mindistsq > dsq )
 
279
                {
 
280
                        nearest = t;
 
281
                        ni = ei;
 
282
                        mindistsq = dsq;
 
283
                }
 
284
        }
 
285
 
 
286
    if (distance_squared != NULL)
 
287
        *distance_squared = mindistsq;
 
288
 
 
289
        return ni + nearest;
 
290
}
 
291
 
110
292
void Path::appendPortionTo(Path &ret, double from, double to) const {
111
 
  assert(from >= 0 && to >= 0);
 
293
  if (!(from >= 0 && to >= 0)) {
 
294
    THROW_RANGEERROR("from and to must be >=0 in Path::appendPortionTo");
 
295
  }
112
296
  if(to == 0) to = size()+0.999999;
113
297
  if(from == to) { return; }
114
298
  double fi, ti;
117
301
  const_iterator fromi = inc(begin(), (unsigned)fi);
118
302
  if(fi == ti && from < to) {
119
303
    Curve *v = fromi->portion(ff, tf);
120
 
    ret.append(*v);
 
304
    ret.append(*v, STITCH_DISCONTINUOUS);
121
305
    delete v;
122
306
    return;
123
307
  }
125
309
  if(ff != 1.) {
126
310
    Curve *fromv = fromi->portion(ff, 1.);
127
311
    //fromv->setInitial(ret.finalPoint());
128
 
    ret.append(*fromv);
 
312
    ret.append(*fromv, STITCH_DISCONTINUOUS);
129
313
    delete fromv;
130
314
  }
131
315
  if(from >= to) {
132
316
    const_iterator ender = end();
133
317
    if(ender->initialPoint() == ender->finalPoint()) ender++;
134
 
    ret.insert(ret.end(), ++fromi, ender);
135
 
    ret.insert(ret.end(), begin(), toi);
 
318
    ret.insert(ret.end(), ++fromi, ender, STITCH_DISCONTINUOUS);
 
319
    ret.insert(ret.end(), begin(), toi, STITCH_DISCONTINUOUS);
136
320
  } else {
137
 
    ret.insert(ret.end(), ++fromi, toi);
 
321
    ret.insert(ret.end(), ++fromi, toi, STITCH_DISCONTINUOUS);
138
322
  }
139
323
  Curve *tov = toi->portion(0., tf);
140
 
  ret.append(*tov);
 
324
  ret.append(*tov, STITCH_DISCONTINUOUS);
141
325
  delete tov;
142
326
}
143
327
 
144
 
const double eps = .1;
145
 
 
146
 
void Path::append(Curve const &curve) {
147
 
  if ( curves_.front() != final_ && !are_near(curve.initialPoint(), (*final_)[0], eps) ) {
148
 
    throwContinuityError();
149
 
  }
150
 
  do_append(curve.duplicate());
151
 
}
152
 
 
153
 
void Path::append(D2<SBasis> const &curve) {
154
 
  if ( curves_.front() != final_ ) {
155
 
    for ( int i = 0 ; i < 2 ; ++i ) {
156
 
      if ( !are_near(curve[i][0][0], (*final_)[0][i], eps) ) {
157
 
        throwContinuityError();
158
 
      }
159
 
    }
160
 
  }
161
 
  do_append(new SBasisCurve(curve));
162
 
}
163
 
 
164
328
void Path::do_update(Sequence::iterator first_replaced,
165
329
                     Sequence::iterator last_replaced,
166
330
                     Sequence::iterator first,
167
 
                    Sequence::iterator last)
 
331
                     Sequence::iterator last)
168
332
{
169
333
  // note: modifies the contents of [first,last)
170
 
 
171
334
  check_continuity(first_replaced, last_replaced, first, last);
172
 
  delete_range(first_replaced, last_replaced);
173
335
  if ( ( last - first ) == ( last_replaced - first_replaced ) ) {
174
336
    std::copy(first, last, first_replaced);
175
337
  } else {
176
338
    // this approach depends on std::vector's behavior WRT iterator stability
177
 
    curves_.erase(first_replaced, last_replaced);
178
 
    curves_.insert(first_replaced, first, last);
 
339
    get_curves().erase(first_replaced, last_replaced);
 
340
    get_curves().insert(first_replaced, first, last);
179
341
  }
180
342
 
181
 
  if ( curves_.front() != final_ ) {
 
343
  if ( get_curves().front().get() != final_ ) {
182
344
    final_->setPoint(0, back().finalPoint());
183
345
    final_->setPoint(1, front().initialPoint());
184
346
  }
185
347
}
186
348
 
187
 
void Path::do_append(Curve *curve) {
188
 
  if ( curves_.front() == final_ ) {
 
349
void Path::do_append(Curve *c) {
 
350
  boost::shared_ptr<Curve> curve(c);
 
351
  if ( get_curves().front().get() == final_ ) {
189
352
    final_->setPoint(1, curve->initialPoint());
 
353
  } else {
 
354
    if (curve->initialPoint() != finalPoint()) {
 
355
      THROW_CONTINUITYERROR();
 
356
    }
190
357
  }
191
 
  curves_.insert(curves_.end()-1, curve);
 
358
  get_curves().insert(get_curves().end()-1, curve);
192
359
  final_->setPoint(0, curve->finalPoint());
193
360
}
194
361
 
195
 
void Path::delete_range(Sequence::iterator first, Sequence::iterator last) {
196
 
  for ( Sequence::iterator iter=first ; iter != last ; ++iter ) {
197
 
    delete *iter;
 
362
void Path::stitch(Sequence::iterator first_replaced,
 
363
                  Sequence::iterator last_replaced,
 
364
                  Sequence &source)
 
365
{
 
366
  if (!source.empty()) {
 
367
    if ( first_replaced != get_curves().begin() ) {
 
368
      if ( (*first_replaced)->initialPoint() != source.front()->initialPoint() ) {
 
369
        Curve *stitch = new StitchSegment((*first_replaced)->initialPoint(),
 
370
                                          source.front()->initialPoint());
 
371
        source.insert(source.begin(), boost::shared_ptr<Curve>(stitch));
 
372
      }
 
373
    }
 
374
    if ( last_replaced != (get_curves().end()-1) ) {
 
375
      if ( (*last_replaced)->finalPoint() != source.back()->finalPoint() ) {
 
376
        Curve *stitch = new StitchSegment(source.back()->finalPoint(),
 
377
                                          (*last_replaced)->finalPoint());
 
378
        source.insert(source.end(), boost::shared_ptr<Curve>(stitch));
 
379
      }
 
380
    }
 
381
  } else if ( first_replaced != last_replaced && first_replaced != get_curves().begin() && last_replaced != get_curves().end()-1) {
 
382
    if ( (*first_replaced)->initialPoint() != (*(last_replaced-1))->finalPoint() ) {
 
383
      Curve *stitch = new StitchSegment((*(last_replaced-1))->finalPoint(),
 
384
                                        (*first_replaced)->initialPoint());
 
385
      source.insert(source.begin(), boost::shared_ptr<Curve>(stitch));
 
386
    }
198
387
  }
199
388
}
200
389
 
204
393
                            Sequence::iterator last)
205
394
{
206
395
  if ( first != last ) {
207
 
    if ( first_replaced != curves_.begin() ) {
208
 
      if ( !are_near( (*first_replaced)->initialPoint(), (*first)->initialPoint(), eps ) ) {
209
 
        throwContinuityError();
210
 
      }
211
 
    }
212
 
    if ( last_replaced != (curves_.end()-1) ) {
213
 
      if ( !are_near( (*(last_replaced-1))->finalPoint(), (*(last-1))->finalPoint(), eps ) ) {
214
 
        throwContinuityError();
215
 
      }
216
 
    }
217
 
  } else if ( first_replaced != last_replaced && first_replaced != curves_.begin() && last_replaced != curves_.end()-1) {
218
 
    if ( !are_near((*first_replaced)->initialPoint(), (*(last_replaced-1))->finalPoint(), eps ) ) {
219
 
      throwContinuityError();
 
396
    if ( first_replaced != get_curves().begin() ) {
 
397
      if ( (*first_replaced)->initialPoint() != (*first)->initialPoint() ) {
 
398
        THROW_CONTINUITYERROR();
 
399
      }
 
400
    }
 
401
    if ( last_replaced != (get_curves().end()-1) ) {
 
402
      if ( (*(last_replaced-1))->finalPoint() != (*(last-1))->finalPoint() ) {
 
403
        THROW_CONTINUITYERROR();
 
404
      }
 
405
    }
 
406
  } else if ( first_replaced != last_replaced && first_replaced != get_curves().begin() && last_replaced != get_curves().end()-1) {
 
407
    if ( (*first_replaced)->initialPoint() != (*(last_replaced-1))->finalPoint() ) {
 
408
      THROW_CONTINUITYERROR();
220
409
    }
221
410
  }
222
411
}
223
412
 
224
 
Rect SVGEllipticalArc::boundsFast() const {
225
 
    throwNotImplemented();
226
 
}
227
 
Rect SVGEllipticalArc::boundsExact() const {
228
 
    throwNotImplemented();
229
 
}
230
 
Rect SVGEllipticalArc::boundsLocal(Interval i, unsigned deg) const {
231
 
    throwNotImplemented();
232
 
}
233
 
 
234
 
std::vector<Point> SVGEllipticalArc::pointAndDerivatives(Coord t, unsigned n) const {
235
 
    throwNotImplemented();
236
 
}
237
 
 
238
 
std::vector<double> SVGEllipticalArc::roots(double v, Dim2 d) const {
239
 
    throwNotImplemented();
240
 
}
241
 
 
242
 
D2<SBasis> SVGEllipticalArc::toSBasis() const {
243
 
    return D2<SBasis>(Linear(initial_[X], final_[X]), Linear(initial_[Y], final_[Y]));
244
 
}
245
 
 
246
 
}
 
413
} // end namespace Geom
247
414
 
248
415
/*
249
416
  Local Variables:
250
417
  mode:c++
251
418
  c-file-style:"stroustrup"
252
 
  c-file-offsets:((innamespace . 0)(substatement-open . 0))
 
419
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
253
420
  indent-tabs-mode:nil
254
 
  c-brace-offset:0
255
421
  fill-column:99
256
422
  End:
257
 
  vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2 :
258
423
*/
 
424
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :