1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2008 by Sun Microsystems, Inc. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * $RCSfile: canvastools.hxx,v $ 10 * $Revision: 1.10 $ 11 * 12 * This file is part of OpenOffice.org. 13 * 14 * OpenOffice.org is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License version 3 16 * only, as published by the Free Software Foundation. 17 * 18 * OpenOffice.org is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License version 3 for more details 22 * (a copy is included in the LICENSE file that accompanied this code). 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * version 3 along with OpenOffice.org. If not, see 26 * <http://www.openoffice.org/license.html> 27 * for a copy of the LGPLv3 License. 28 * 29 ************************************************************************/ 30 31 // MARKER(update_precomp.py): autogen include statement, do not remove 32 #include "precompiled_basegfx.hxx" 33 34 #include "basegfx/tools/keystoplerp.hxx" 35 #include <com/sun/star/uno/Sequence.hxx> 36 37 #include <algorithm> 38 39 static void validateInput(const std::vector<double>& rKeyStops) 40 { 41 (void)rKeyStops; 42 #ifdef DBG_UTIL 43 OSL_ENSURE( rKeyStops.size() > 1, 44 "KeyStopLerp::KeyStopLerp(): key stop vector must have two entries or more" ); 45 46 // rKeyStops must be sorted in ascending order 47 for( ::std::size_t i=1, len=rKeyStops.size(); i<len; ++i ) 48 { 49 if( rKeyStops[i-1] > rKeyStops[i] ) 50 OSL_ENSURE( false, 51 "KeyStopLerp::KeyStopLerp(): time vector is not sorted in ascending order!" ); 52 } 53 #endif 54 } 55 56 namespace basegfx 57 { 58 namespace tools 59 { 60 KeyStopLerp::KeyStopLerp( const std::vector<double>& rKeyStops ) : 61 maKeyStops(rKeyStops), 62 mnLastIndex(0) 63 { 64 validateInput(maKeyStops); 65 } 66 67 KeyStopLerp::KeyStopLerp( const ::com::sun::star::uno::Sequence<double>& rKeyStops ) : 68 maKeyStops(rKeyStops.getLength()), 69 mnLastIndex(0) 70 { 71 std::copy( rKeyStops.getConstArray(), 72 rKeyStops.getConstArray()+rKeyStops.getLength(), 73 maKeyStops.begin() ); 74 validateInput(maKeyStops); 75 } 76 77 KeyStopLerp::ResultType KeyStopLerp::lerp(double fAlpha) const 78 { 79 // cached value still okay? 80 if( maKeyStops.at(mnLastIndex) < fAlpha || 81 maKeyStops.at(mnLastIndex+1) >= fAlpha ) 82 { 83 // nope, find new index 84 mnLastIndex = std::min<std::ptrdiff_t>( 85 maKeyStops.size()-2, 86 // range is ensured by max below 87 std::max<std::ptrdiff_t>( 88 0, 89 std::distance( maKeyStops.begin(), 90 std::lower_bound( maKeyStops.begin(), 91 maKeyStops.end(), 92 fAlpha )) - 1 )); 93 } 94 95 // lerp between stop and stop+1 96 const double fRawLerp= 97 (fAlpha-maKeyStops.at(mnLastIndex)) / 98 (maKeyStops.at(mnLastIndex+1) - maKeyStops.at(mnLastIndex)); 99 100 // clamp to permissible range (input fAlpha might be 101 // everything) 102 return ResultType( 103 mnLastIndex, 104 clamp(fRawLerp,0.0,1.0)); 105 } 106 } 107 } 108