Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <basegfx/curve/b2dbeziertools.hxx>
30 : : #include <basegfx/curve/b2dcubicbezier.hxx>
31 : : #include <algorithm>
32 : :
33 : : //////////////////////////////////////////////////////////////////////////////
34 : :
35 : : namespace basegfx
36 : : {
37 : 0 : B2DCubicBezierHelper::B2DCubicBezierHelper(const B2DCubicBezier& rBase, sal_uInt32 nDivisions)
38 : : : maLengthArray(),
39 : 0 : mnEdgeCount(0)
40 : : {
41 [ # # ]: 0 : const bool bIsBezier(rBase.isBezier());
42 : :
43 [ # # ]: 0 : if(bIsBezier)
44 : : {
45 : : // check nDivisions; at least one is needed, but also prevent too big values
46 [ # # ]: 0 : if(nDivisions < 1)
47 : : {
48 : 0 : nDivisions = 1;
49 : : }
50 [ # # ]: 0 : else if(nDivisions > 1000)
51 : : {
52 : 0 : nDivisions = 1000;
53 : : }
54 : :
55 : : // set nEdgeCount
56 : 0 : mnEdgeCount = nDivisions + 1;
57 : :
58 : : // fill in maLengthArray
59 : 0 : maLengthArray.clear();
60 [ # # ]: 0 : maLengthArray.reserve(mnEdgeCount);
61 : 0 : B2DPoint aCurrent(rBase.getStartPoint());
62 : 0 : double fLength(0.0);
63 : :
64 : 0 : for(sal_uInt32 a(1);;)
65 : : {
66 [ # # ]: 0 : const B2DPoint aNext(rBase.interpolatePoint((double)a / (double)mnEdgeCount));
67 : 0 : const B2DVector aEdge(aNext - aCurrent);
68 : :
69 [ # # ]: 0 : fLength += aEdge.getLength();
70 [ # # ]: 0 : maLengthArray.push_back(fLength);
71 : :
72 [ # # ]: 0 : if(++a < mnEdgeCount)
73 : : {
74 : 0 : aCurrent = aNext;
75 : : }
76 : : else
77 : : {
78 : 0 : const B2DPoint aLastNext(rBase.getEndPoint());
79 : 0 : const B2DVector aLastEdge(aLastNext - aNext);
80 : :
81 [ # # ]: 0 : fLength += aLastEdge.getLength();
82 [ # # ]: 0 : maLengthArray.push_back(fLength);
83 : 0 : break;
84 : : }
85 [ # # ][ # # ]: 0 : }
86 : : }
87 : : else
88 : : {
89 : 0 : maLengthArray.clear();
90 [ # # ][ # # ]: 0 : maLengthArray.push_back(rBase.getEdgeLength());
91 : 0 : mnEdgeCount = 1;
92 : : }
93 : 0 : }
94 : :
95 : 0 : double B2DCubicBezierHelper::distanceToRelative(double fDistance) const
96 : : {
97 [ # # ]: 0 : if(fDistance <= 0.0)
98 : : {
99 : 0 : return 0.0;
100 : : }
101 : :
102 [ # # ]: 0 : const double fLength(getLength());
103 : :
104 [ # # ]: 0 : if(fTools::moreOrEqual(fDistance, fLength))
105 : : {
106 : 0 : return 1.0;
107 : : }
108 : :
109 : : // fDistance is in ]0.0 .. fLength[
110 : :
111 [ # # ]: 0 : if(1 == mnEdgeCount)
112 : : {
113 : : // not a bezier, linear edge
114 : 0 : return fDistance / fLength;
115 : : }
116 : :
117 : : // it is a bezier
118 [ # # ]: 0 : ::std::vector< double >::const_iterator aIter = ::std::lower_bound(maLengthArray.begin(), maLengthArray.end(), fDistance);
119 [ # # ]: 0 : const sal_uInt32 nIndex(aIter - maLengthArray.begin());
120 [ # # ]: 0 : const double fHighBound(maLengthArray[nIndex]);
121 [ # # ][ # # ]: 0 : const double fLowBound(nIndex ? maLengthArray[nIndex - 1] : 0.0);
122 : 0 : const double fLinearInterpolatedLength((fDistance - fLowBound) / (fHighBound - fLowBound));
123 : :
124 : 0 : return (static_cast< double >(nIndex) + fLinearInterpolatedLength) / static_cast< double >(mnEdgeCount);
125 : : }
126 : :
127 : : } // end of namespace basegfx
128 : :
129 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|