1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is IBM Corporation code.
17 * The Initial Developer of the Original Code is IBM Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2007
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
42 gfxPath::gfxPath(cairo_path_t
* aPath
) : mPath(aPath
)
48 cairo_path_destroy(mPath
);
51 gfxFlattenedPath::gfxFlattenedPath(cairo_path_t
* aPath
) : gfxPath(aPath
)
55 gfxFlattenedPath::~gfxFlattenedPath()
60 CalcSubLengthAndAdvance(cairo_path_data_t
*aData
,
61 gfxPoint
&aPathStart
, gfxPoint
&aCurrent
)
65 switch (aData
->header
.type
) {
66 case CAIRO_PATH_MOVE_TO
:
68 aCurrent
= aPathStart
= gfxPoint(aData
[1].point
.x
,
72 case CAIRO_PATH_LINE_TO
:
75 gfxPoint(aData
[1].point
.x
, aData
[1].point
.y
) - aCurrent
;
76 sublength
= sqrt(diff
.x
* diff
.x
+ diff
.y
* diff
.y
);
77 aCurrent
= gfxPoint(aData
[1].point
.x
, aData
[1].point
.y
);
80 case CAIRO_PATH_CURVE_TO
:
81 /* should never happen with a flattened path */
82 NS_WARNING("curve_to in flattened path");
84 case CAIRO_PATH_CLOSE_PATH
:
86 gfxPoint diff
= aPathStart
- aCurrent
;
87 sublength
= sqrt(diff
.x
* diff
.x
+ diff
.y
* diff
.y
);
88 aCurrent
= aPathStart
;
96 gfxFlattenedPath::GetLength()
98 gfxPoint
start(0, 0); // start of current subpath
99 gfxPoint
current(0, 0); // current point
100 gfxFloat length
= 0; // current summed length
104 i
+= mPath
->data
[i
].header
.length
) {
105 length
+= CalcSubLengthAndAdvance(&mPath
->data
[i
], start
, current
);
111 gfxFlattenedPath::FindPoint(gfxPoint aOffset
, gfxFloat
*aAngle
)
113 gfxPoint
start(0, 0); // start of current subpath
114 gfxPoint
current(0, 0); // current point
115 gfxFloat length
= 0; // current summed length
119 i
+= mPath
->data
[i
].header
.length
) {
120 gfxPoint prev
= current
;
122 gfxFloat sublength
= CalcSubLengthAndAdvance(&mPath
->data
[i
],
125 gfxPoint diff
= current
- prev
;
127 *aAngle
= atan2(diff
.y
, diff
.x
);
129 if (sublength
!= 0 && length
+ sublength
>= aOffset
.x
) {
130 gfxFloat ratio
= (aOffset
.x
- length
) / sublength
;
131 gfxFloat normalization
=
132 1.0 / sqrt(diff
.x
* diff
.x
+ diff
.y
* diff
.y
);
134 return prev
* (1.0f
- ratio
) + current
* ratio
+
135 gfxPoint(-diff
.y
, diff
.x
) * aOffset
.y
* normalization
;
140 // requested offset is past the end of the path - return last point