Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d406d41b authored by Wu Ahan's avatar Wu Ahan Committed by Android (Google) Code Review
Browse files

Merge "Reset the texture coordinates and also take aspect ratio into account." into qt-dev

parents 5b12743b 7f6519f0
Loading
Loading
Loading
Loading
+55 −38
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import static android.opengl.GLES20.glVertexAttribPointer;

import android.graphics.Bitmap;
import android.opengl.GLUtils;
import android.os.Build;
import android.util.Log;

import java.nio.ByteBuffer;
@@ -196,58 +195,76 @@ class ImageGLWallpaper {
        glUniform1i(mUniTexture, 0);
    }

    /**
     * This method adjust s(x-axis), t(y-axis) texture coordinates
     * to prevent the wallpaper from being stretched.
     * The adjustment happens if either the width or height of the bitmap is larger than
     * corresponding size of the surface.
     * If both width and height are larger than corresponding size of the surface,
     * the adjustment will happen at both s, t side.
     *
     * @param bitmapWidth The width of the bitmap.
     * @param bitmapHeight The height of the bitmap.
     * @param surfaceWidth The width of the surface.
     * @param surfaceHeight The height of the surface.
     * @param xOffset The offset amount along s axis.
     * @param yOffset The offset amount along t axis.
     */
    void adjustTextureCoordinates(int bitmapWidth, int bitmapHeight,
            int surfaceWidth, int surfaceHeight, float xOffset, float yOffset) {
        float ratioW = 1f;
        float ratioH = 1f;
        float rX = 0f;
        float rY = 0f;
        float[] coordinates = null;

        final boolean adjustWidth = bitmapWidth > surfaceWidth;
        final boolean adjustHeight = bitmapHeight > surfaceHeight;

        if (adjustWidth || adjustHeight) {
            coordinates = TEXTURES.clone();
        float[] coordinates = TEXTURES.clone();

        if (bitmapWidth > surfaceWidth) {
            // Calculate the new s pos in pixels.
            float pixelS = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset);
            // Calculate the s pos in texture coordinate.
            float coordinateS = pixelS / bitmapWidth;
            // Calculate the percentage occupied by the surface width in bitmap width.
            float surfacePercentageW = (float) surfaceWidth / bitmapWidth;
            // Need also consider the case if bitmap height is smaller than surface height.
            if (bitmapHeight < surfaceHeight) {
                // We will narrow the surface percentage to keep aspect ratio.
                surfacePercentageW *= (float) bitmapHeight / surfaceHeight;
            }

        if (adjustWidth) {
            float x = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset) / bitmapWidth;
            ratioW = (float) surfaceWidth / bitmapWidth;
            float referenceX = x + ratioW > 1f ? 1f - ratioW : x;
            // Determine the final s pos, also limit the legal s pos to prevent from out of range.
            float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
            // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
            for (int i = 0; i < coordinates.length; i += 2) {
                // indices 2, 4 and 6 are the end of s coordinates.
                if (i == 2 || i == 4 || i == 6) {
                    coordinates[i] = Math.min(1f, referenceX + ratioW);
                    coordinates[i] = Math.min(1f, s + surfacePercentageW);
                } else {
                    coordinates[i] = referenceX;
                    coordinates[i] = s;
                }
            }
            rX = referenceX;
        }


        if (adjustHeight) {
            float y = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset) / bitmapHeight;
            ratioH = (float) surfaceHeight / bitmapHeight;
            float referenceY = y + ratioH > 1f ? 1f - ratioH : y;
        if (bitmapHeight > surfaceHeight) {
            // Calculate the new t pos in pixels.
            float pixelT = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset);
            // Calculate the t pos in texture coordinate.
            float coordinateT = pixelT / bitmapHeight;
            // Calculate the percentage occupied by the surface height in bitmap height.
            float surfacePercentageH = (float) surfaceHeight / bitmapHeight;
            // Need also consider the case if bitmap width is smaller than surface width.
            if (bitmapWidth < surfaceWidth) {
                // We will narrow the surface percentage to keep aspect ratio.
                surfacePercentageH *= (float) bitmapWidth / surfaceWidth;
            }
            // Determine the final t pos, also limit the legal t pos to prevent from out of range.
            float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
            // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
            for (int i = 1; i < coordinates.length; i += 2) {
                // indices 1, 3 and 11 are the end of t coordinates.
                if (i == 1 || i == 3 || i == 11) {
                    coordinates[i] = Math.min(1f, referenceY + ratioH);
                    coordinates[i] = Math.min(1f, t + surfacePercentageH);
                } else {
                    coordinates[i] = referenceY;
                    coordinates[i] = t;
                }
            }
            rY = referenceY;
        }

        if (adjustWidth || adjustHeight) {
            if (Build.IS_DEBUGGABLE) {
                Log.d(TAG, "adjustTextureCoordinates: sW=" + surfaceWidth + ", sH=" + surfaceHeight
                        + ", bW=" + bitmapWidth + ", bH=" + bitmapHeight
                        + ", rW=" + ratioW + ", rH=" + ratioH + ", rX=" + rX + ", rY=" + rY);
            }
        mTextureBuffer.put(coordinates);
        mTextureBuffer.position(0);
    }
}
}