13b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/*
23b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Copyright (C) 2013 The Android Open Source Project
33b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
43b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
53b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * you may not use this file except in compliance with the License.
63b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * You may obtain a copy of the License at
73b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
83b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
93b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Unless required by applicable law or agreed to in writing, software
113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * See the License for the specific language governing permissions and
143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * limitations under the License.
153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#ifndef ANDROID_HWUI_UV_MAPPER_H
183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define ANDROID_HWUI_UV_MAPPER_H
193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "Rect.h"
213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android {
233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace uirenderer {
243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/**
263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * This class can be used to map UV coordinates from the [0..1]
273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * range to other arbitrary ranges. All the methods below assume
283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * that the input values lie in the [0..1] range already.
293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass UvMapper {
313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypublic:
323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Using this constructor is equivalent to not using any mapping at all.
343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * UV coordinates in the [0..1] range remain in the [0..1] range.
353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
361bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    UvMapper() : mIdentity(true), mMinU(0.0f), mMaxU(1.0f), mMinV(0.0f), mMaxV(1.0f) {}
373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Creates a new mapper with the specified ranges for U and V coordinates.
403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * The parameter minU must be < maxU and minV must be < maxV.
413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
421bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    UvMapper(float minU, float maxU, float minV, float maxV)
431bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            : mMinU(minU), mMaxU(maxU), mMinV(minV), mMaxV(maxV) {
443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        checkIdentity();
453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns true if calling the map*() methods has no effect (that is,
493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * texture coordinates remain in the 0..1 range.)
503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
511bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    bool isIdentity() const { return mIdentity; }
523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Changes the U and V mapping ranges.
553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * The parameter minU must be < maxU and minV must be < maxV.
563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void setMapping(float minU, float maxU, float minV, float maxV) {
583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mMinU = minU;
593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mMaxU = maxU;
603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mMinV = minV;
613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mMaxV = maxV;
623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        checkIdentity();
633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Maps a single value in the U range.
673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void mapU(float& u) const {
693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (!mIdentity) u = lerp(mMinU, mMaxU, u);
703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Maps a single value in the V range.
743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void mapV(float& v) const {
763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (!mIdentity) v = lerp(mMinV, mMaxV, v);
773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Maps the specified rectangle in place. This method assumes:
813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * - left = min. U
823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * - top = min. V
833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * - right = max. U
843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * - bottom = max. V
853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void map(Rect& texCoords) const {
873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (!mIdentity) {
883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            texCoords.left = lerp(mMinU, mMaxU, texCoords.left);
893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            texCoords.right = lerp(mMinU, mMaxU, texCoords.right);
903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            texCoords.top = lerp(mMinV, mMaxV, texCoords.top);
913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            texCoords.bottom = lerp(mMinV, mMaxV, texCoords.bottom);
923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Maps the specified UV coordinates in place.
973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void map(float& u1, float& v1, float& u2, float& v2) const {
993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (!mIdentity) {
1003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            u1 = lerp(mMinU, mMaxU, u1);
1013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            u2 = lerp(mMinU, mMaxU, u2);
1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            v1 = lerp(mMinV, mMaxV, v1);
1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            v2 = lerp(mMinV, mMaxV, v2);
1043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void dump() const {
1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        ALOGD("mapper[minU=%.2f maxU=%.2f minV=%.2f maxV=%.2f]", mMinU, mMaxU, mMinV, mMaxV);
1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyprivate:
1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    static float lerp(float start, float stop, float amount) {
1133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return start + (stop - start) * amount;
1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    void checkIdentity() {
1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mIdentity = mMinU == 0.0f && mMaxU == 1.0f && mMinV == 0.0f && mMaxV == 1.0f;
1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    bool mIdentity;
1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    float mMinU;
1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    float mMaxU;
1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    float mMinV;
1243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    float mMaxV;
1253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy};
1263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1271bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace uirenderer
1281bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace android
1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1301bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#endif  // ANDROID_HWUI_UV_MAPPER_H
131