/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" #include "basegfx/tools/keystoplerp.hxx" #include #include static void validateInput(const std::vector& rKeyStops) { (void)rKeyStops; #ifdef DBG_UTIL OSL_ENSURE( rKeyStops.size() > 1, "KeyStopLerp::KeyStopLerp(): key stop vector must have two entries or more" ); // rKeyStops must be sorted in ascending order for( ::std::size_t i=1, len=rKeyStops.size(); i rKeyStops[i] ) OSL_ENSURE( false, "KeyStopLerp::KeyStopLerp(): time vector is not sorted in ascending order!" ); } #endif } namespace basegfx { namespace tools { KeyStopLerp::KeyStopLerp( const std::vector& rKeyStops ) : maKeyStops(rKeyStops), mnLastIndex(0) { validateInput(maKeyStops); } KeyStopLerp::KeyStopLerp( const ::com::sun::star::uno::Sequence& rKeyStops ) : maKeyStops(rKeyStops.getLength()), mnLastIndex(0) { std::copy( rKeyStops.getConstArray(), rKeyStops.getConstArray()+rKeyStops.getLength(), maKeyStops.begin() ); validateInput(maKeyStops); } KeyStopLerp::ResultType KeyStopLerp::lerp(double fAlpha) const { // cached value still okay? if( maKeyStops.at(mnLastIndex) < fAlpha || maKeyStops.at(mnLastIndex+1) >= fAlpha ) { // nope, find new index mnLastIndex = std::min( maKeyStops.size()-2, // range is ensured by max below std::max( 0, std::distance( maKeyStops.begin(), std::lower_bound( maKeyStops.begin(), maKeyStops.end(), fAlpha )) - 1 )); } // lerp between stop and stop+1 const double fRawLerp= (fAlpha-maKeyStops.at(mnLastIndex)) / (maKeyStops.at(mnLastIndex+1) - maKeyStops.at(mnLastIndex)); // clamp to permissible range (input fAlpha might be // everything) return ResultType( mnLastIndex, clamp(fRawLerp,0.0,1.0)); } } }