1766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu/*
2766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Copyright (C) 2016 The Android Open Source Project
3766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu *
4766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
5766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * you may not use this file except in compliance with the License.
6766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * You may obtain a copy of the License at
7766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu *
8766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
9766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu *
10766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Unless required by applicable law or agreed to in writing, software
11766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
12766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * See the License for the specific language governing permissions and
14766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * limitations under the License.
15766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu */
16766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
17766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "PropertyValuesHolder.h"
18766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
19253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy#include "utils/Color.h"
20766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "utils/VectorDrawableUtils.h"
21766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include <utils/Log.h>
23766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
24766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liunamespace android {
25766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liunamespace uirenderer {
26766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
27766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuusing namespace VectorDrawable;
28766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
29253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guyinline constexpr float lerp(float fromValue, float toValue, float fraction) {
30253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    return float (fromValue * (1 - fraction) + toValue * fraction);
31253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy}
32253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy
33253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guyinline constexpr float linearize(U8CPU component) {
34253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    return EOCF_sRGB(component / 255.0f);
35a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu}
36a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu
37a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu// TODO: Add a test for this
38a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liuvoid ColorEvaluator::evaluate(SkColor* outColor,
39a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        const SkColor& fromColor, const SkColor& toColor, float fraction) const {
40253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    float a = lerp(SkColorGetA(fromColor) / 255.0f, SkColorGetA(toColor) / 255.0f, fraction);
41253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    float r = lerp(linearize(SkColorGetR(fromColor)), linearize(SkColorGetR(toColor)), fraction);
42253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    float g = lerp(linearize(SkColorGetG(fromColor)), linearize(SkColorGetG(toColor)), fraction);
43253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    float b = lerp(linearize(SkColorGetB(fromColor)), linearize(SkColorGetB(toColor)), fraction);
44253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    *outColor = SkColorSetARGB(
45253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            (U8CPU) roundf(a * 255.0f),
46253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            (U8CPU) roundf(OECF_sRGB(r) * 255.0f),
47253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            (U8CPU) roundf(OECF_sRGB(g) * 255.0f),
48253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            (U8CPU) roundf(OECF_sRGB(b) * 255.0f));
49a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu}
50a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu
51a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liuvoid PathEvaluator::evaluate(PathData* out,
52a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        const PathData& from, const PathData& to, float fraction) const {
53a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    VectorDrawableUtils::interpolatePaths(out, from, to, fraction);
54a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu}
55a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu
56a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liutemplate<typename T>
57a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liuconst T PropertyValuesHolderImpl<T>::getValueFromData(float fraction) const {
58766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    if (mDataSource.size() == 0) {
59766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu        LOG_ALWAYS_FATAL("No data source is defined");
60766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu        return 0;
61766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    }
62766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    if (fraction <= 0.0f) {
63766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu        return mDataSource.front();
64766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    }
65766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    if (fraction >= 1.0f) {
66766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu        return mDataSource.back();
67766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    }
68766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
69766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    fraction *= mDataSource.size() - 1;
70766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    int lowIndex = floor(fraction);
71766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    fraction -= lowIndex;
72766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
73a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    T value;
74a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    mEvaluator->evaluate(&value, mDataSource[lowIndex], mDataSource[lowIndex + 1], fraction);
75766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    return value;
76766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
77766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
78a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liutemplate<typename T>
79a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liuconst T PropertyValuesHolderImpl<T>::calculateAnimatedValue(float fraction) const {
80766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    if (mDataSource.size() > 0) {
81a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        return getValueFromData(fraction);
82766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    } else {
83a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        T value;
84a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        mEvaluator->evaluate(&value, mStartValue, mEndValue, fraction);
85a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu        return value;
86766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    }
87766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
88766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
89a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liuvoid GroupPropertyValuesHolder::setFraction(float fraction) {
90a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    float animatedValue = calculateAnimatedValue(fraction);
91a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    mGroup->mutateProperties()->setPropertyValue(mPropertyId, animatedValue);
92766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
93766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
94766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid FullPathColorPropertyValuesHolder::setFraction(float fraction) {
95a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    SkColor animatedValue = calculateAnimatedValue(fraction);
961d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    mFullPath->mutateProperties()->setColorPropertyValue(mPropertyId, animatedValue);
97766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
98766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
99766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid FullPathPropertyValuesHolder::setFraction(float fraction) {
100a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    float animatedValue = calculateAnimatedValue(fraction);
1011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    mFullPath->mutateProperties()->setPropertyValue(mPropertyId, animatedValue);
102766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
103766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
104766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PathDataPropertyValuesHolder::setFraction(float fraction) {
105a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    mEvaluator->evaluate(&mPathData, mStartValue, mEndValue, fraction);
1061d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    mPath->mutateProperties()->setData(mPathData);
107766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
108766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
109766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid RootAlphaPropertyValuesHolder::setFraction(float fraction) {
110a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu    float animatedValue = calculateAnimatedValue(fraction);
1111d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    mTree->mutateProperties()->setRootAlpha(animatedValue);
112766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
113766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
114766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} // namepace uirenderer
115766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} // namespace android
116