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

Commit 2dc016ea authored by Yuli Huang's avatar Yuli Huang Committed by Android Git Automerger
Browse files

am 7b62f488: Fix b/5401109.

* commit '7b62f488':
  Fix b/5401109.
parents dba62bd5 7b62f488
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project

     Licensed 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.
-->

<com.android.gallery3d.photoeditor.actions.FlipView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fullscreen_effect_tool"
    style="@style/FullscreenToolView"/>
+24 −1
Original line number Diff line number Diff line
@@ -87,6 +87,13 @@ public class PhotoView extends GLSurfaceView {
        renderer.rotatePhoto(degrees);
    }

    /**
     * Flips displayed photo; this method must be queued for GL thread.
     */
    public void flipPhoto(float horizontalDegrees, float verticalDegrees) {
        renderer.flipPhoto(horizontalDegrees, verticalDegrees);
    }

    /**
     * Renderer that renders the GL surface-view and only be called from the GL thread.
     */
@@ -99,6 +106,8 @@ public class PhotoView extends GLSurfaceView {
        int viewWidth;
        int viewHeight;
        float rotatedDegrees;
        float flippedHorizontalDegrees;
        float flippedVerticalDegrees;

        void setPhoto(Photo photo, boolean clearTransform) {
            int width = (photo != null) ? photo.width() : 0;
@@ -115,18 +124,23 @@ public class PhotoView extends GLSurfaceView {
        }

        void updateSurface(boolean clearTransform, boolean sizeChanged) {
            boolean transformed = (rotatedDegrees != 0);
            boolean flipped = (flippedHorizontalDegrees != 0) || (flippedVerticalDegrees != 0);
            boolean transformed = (rotatedDegrees != 0) || flipped;
            if ((clearTransform && transformed) || (sizeChanged && !transformed)) {
                // Fit photo when clearing existing transforms or changing surface/photo sizes.
                if (photo != null) {
                    RendererUtils.setRenderToFit(renderContext, photo.width(), photo.height(),
                            viewWidth, viewHeight);
                    rotatedDegrees = 0;
                    flippedHorizontalDegrees = 0;
                    flippedVerticalDegrees = 0;
                }
            } else {
                // Restore existing transformations for orientation changes or awaking from sleep.
                if (rotatedDegrees != 0) {
                    rotatePhoto(rotatedDegrees);
                } else if (flipped) {
                    flipPhoto(flippedHorizontalDegrees, flippedVerticalDegrees);
                }
            }
        }
@@ -139,6 +153,15 @@ public class PhotoView extends GLSurfaceView {
            }
        }

        void flipPhoto(float horizontalDegrees, float verticalDegrees) {
            if (photo != null) {
                RendererUtils.setRenderToFlip(renderContext, photo.width(), photo.height(),
                        viewWidth, viewHeight, horizontalDegrees, verticalDegrees);
                flippedHorizontalDegrees = horizontalDegrees;
                flippedVerticalDegrees = verticalDegrees;
            }
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            Runnable r = null;
+73 −6
Original line number Diff line number Diff line
@@ -121,13 +121,13 @@ public class RendererUtils {
        checkGlError("glDeleteTextures");
    }

    public static void setRenderToFit(RenderContext context, int srcWidth, int srcHeight,
            int dstWidth, int dstHeight) {
    private static float[] getFitVertices(int srcWidth, int srcHeight, int dstWidth,
            int dstHeight) {
        float srcAspectRatio = ((float) srcWidth) / srcHeight;
        float dstAspectRatio = ((float) dstWidth) / dstHeight;
        float relativeAspectRatio = dstAspectRatio / srcAspectRatio;

        float vertices[] = new float[8];
        float[] vertices = new float[8];
        System.arraycopy(POS_VERTICES, 0, vertices, 0, vertices.length);
        if (relativeAspectRatio > 1.0f) {
            // Screen is wider than the camera, scale down X
@@ -141,13 +141,20 @@ public class RendererUtils {
            vertices[5] *= relativeAspectRatio;
            vertices[7] *= relativeAspectRatio;
        }
        context.posVertices = createVerticesBuffer(vertices);
        return vertices;
    }

    public static void setRenderToFit(RenderContext context, int srcWidth, int srcHeight,
            int dstWidth, int dstHeight) {
        context.posVertices = createVerticesBuffer(
                getFitVertices(srcWidth, srcHeight, dstWidth, dstHeight));
    }

    public static void setRenderToRotate(RenderContext context, int srcWidth, int srcHeight,
            int dstWidth, int dstHeight, float degrees) {
        float cosTheta = (float) Math.cos(-degrees * DEGREE_TO_RADIAN);
        float sinTheta = (float) Math.sin(-degrees * DEGREE_TO_RADIAN);
        float radian = -degrees * DEGREE_TO_RADIAN;
        float cosTheta = (float) Math.cos(radian);
        float sinTheta = (float) Math.sin(radian);
        float cosWidth = cosTheta * srcWidth;
        float sinWidth = sinTheta * srcWidth;
        float cosHeight = cosTheta * srcHeight;
@@ -174,6 +181,66 @@ public class RendererUtils {
        context.posVertices = createVerticesBuffer(vertices);
    }

    public static void setRenderToFlip(RenderContext context, int srcWidth, int srcHeight,
            int dstWidth, int dstHeight, float horizontalDegrees, float verticalDegrees) {
        // Calculate the base flip coordinates.
        float[] base = getFitVertices(srcWidth, srcHeight, dstWidth, dstHeight);
        int horizontalRounds = (int) horizontalDegrees / 180;
        if (horizontalRounds % 2 != 0) {
            base[0] = -base[0];
            base[4] = base[0];
            base[2] = -base[2];
            base[6] = base[2];
        }
        int verticalRounds = (int) verticalDegrees / 180;
        if (verticalRounds % 2 != 0) {
            base[1] = -base[1];
            base[3] = base[1];
            base[5] = -base[5];
            base[7] = base[5];
        }

        float length = 5;
        float[] vertices = new float[8];
        System.arraycopy(base, 0, vertices, 0, vertices.length);
        if (horizontalDegrees % 180f != 0) {
            float radian = (horizontalDegrees - horizontalRounds * 180) * DEGREE_TO_RADIAN;
            float cosTheta = (float) Math.cos(radian);
            float sinTheta = (float) Math.sin(radian);

            float scale = length / (length + sinTheta * base[0]);
            vertices[0] = cosTheta * base[0] * scale;
            vertices[1] = base[1] * scale;
            vertices[4] = vertices[0];
            vertices[5] = base[5] * scale;

            scale = length / (length + sinTheta * base[2]);
            vertices[2] = cosTheta * base[2] * scale;
            vertices[3] = base[3] * scale;
            vertices[6] = vertices[2];
            vertices[7] = base[7] * scale;
        }

        if (verticalDegrees % 180f != 0) {
            float radian = (verticalDegrees - verticalRounds * 180) * DEGREE_TO_RADIAN;
            float cosTheta = (float) Math.cos(radian);
            float sinTheta = (float) Math.sin(radian);

            float scale = length / (length + sinTheta * base[1]);
            vertices[0] = base[0] * scale;
            vertices[1] = cosTheta * base[1] * scale;
            vertices[2] = base[2] * scale;
            vertices[3] = vertices[1];

            scale = length / (length + sinTheta * base[5]);
            vertices[4] = base[4] * scale;
            vertices[5] = cosTheta * base[5] * scale;
            vertices[6] = base[6] * scale;
            vertices[7] = vertices[5];
        }
        context.posVertices = createVerticesBuffer(vertices);
    }

    public static void renderBackground() {
        GLES20.glClearColor(0, 0, 0, 1);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+4 −0
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ public class EffectToolFactory {
        return (TouchView) createFullscreenTool(R.layout.photoeditor_touch_view);
    }

    public FlipView createFlipView() {
        return (FlipView) createFullscreenTool(R.layout.photoeditor_flip_view);
    }

    public RotateView createRotateView() {
        return (RotateView) createFullscreenTool(R.layout.photoeditor_rotate_view);
    }
+70 −28
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.gallery3d.photoeditor.actions;
import android.content.Context;
import android.util.AttributeSet;

import com.android.gallery3d.R;
import com.android.gallery3d.photoeditor.PhotoView;
import com.android.gallery3d.photoeditor.filters.FlipFilter;

/**
@@ -26,9 +28,14 @@ import com.android.gallery3d.photoeditor.filters.FlipFilter;
 */
public class FlipAction extends EffectAction {

    private boolean flipHorizontal;
    private boolean flipVertical;
    private TouchView touchView;
    private static final float DEFAULT_ANGLE = 0.0f;
    private static final float DEFAULT_FLIP_SPAN = 180.0f;

    private FlipFilter filter;
    private float horizontalFlipDegrees;
    private float verticalFlipDegrees;
    private Runnable queuedFlipChange;
    private FlipView flipView;

    public FlipAction(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -36,51 +43,86 @@ public class FlipAction extends EffectAction {

    @Override
    public void doBegin() {
        final FlipFilter filter = new FlipFilter();
        filter = new FlipFilter();

        flipView = factory.createFlipView();
        flipView.setOnFlipChangeListener(new FlipView.OnFlipChangeListener() {

        touchView = factory.createTouchView();
        touchView.setSwipeListener(new TouchView.SwipeListener() {
            // Directly transform photo-view because running the flip filter isn't fast enough.
            PhotoView photoView = (PhotoView) flipView.getRootView().findViewById(
                    R.id.photo_view);

            @Override
            public void onSwipeDown() {
                flipFilterVertically(filter);
            public void onAngleChanged(float horizontalDegrees, float verticalDegrees,
                    boolean fromUser) {
                if (fromUser) {
                    horizontalFlipDegrees = horizontalDegrees;
                    verticalFlipDegrees = verticalDegrees;
                    updateFlipFilter(false);
                    transformPhotoView(horizontalDegrees, verticalDegrees);
                }
            }

            @Override
            public void onSwipeLeft() {
                flipFilterHorizontally(filter);
            public void onStartTrackingTouch() {
                // no-op
            }

            @Override
            public void onSwipeRight() {
                flipFilterHorizontally(filter);
            public void onStopTrackingTouch() {
                roundFlipDegrees();
                updateFlipFilter(false);
                transformPhotoView(horizontalFlipDegrees, verticalFlipDegrees);
                flipView.setFlippedAngles(horizontalFlipDegrees, verticalFlipDegrees);
            }

            private void transformPhotoView(final float horizontalDegrees,
                    final float verticalDegrees) {
                // Remove the outdated flip change before queuing a new one.
                if (queuedFlipChange != null) {
                    photoView.remove(queuedFlipChange);
                }
                queuedFlipChange = new Runnable() {

                    @Override
            public void onSwipeUp() {
                flipFilterVertically(filter);
                    public void run() {
                        photoView.flipPhoto(horizontalDegrees, verticalDegrees);
                    }
                };
                photoView.queue(queuedFlipChange);
            }
        });

        flipHorizontal = false;
        flipVertical = false;
        flipFilterHorizontally(filter);
        flipView.setFlippedAngles(DEFAULT_ANGLE, DEFAULT_ANGLE);
        flipView.setFlipSpan(DEFAULT_FLIP_SPAN);
        horizontalFlipDegrees = 0;
        verticalFlipDegrees = 0;
        queuedFlipChange = null;
    }

    @Override
    public void doEnd() {
        touchView.setSwipeListener(null);
        flipView.setOnFlipChangeListener(null);
        // Round the current flip degrees in case flip tracking has not stopped yet.
        roundFlipDegrees();
        updateFlipFilter(true);
    }

    private void flipFilterHorizontally(final FlipFilter filter) {
        flipHorizontal = !flipHorizontal;
        filter.setFlip(flipHorizontal, flipVertical);
        notifyFilterChanged(filter, true);
    /**
     * Rounds flip degrees to multiples of 180 degrees.
     */
    private void roundFlipDegrees() {
        if (horizontalFlipDegrees % 180 != 0) {
            horizontalFlipDegrees = Math.round(horizontalFlipDegrees / 180) * 180;
        }
        if (verticalFlipDegrees % 180 != 0) {
            verticalFlipDegrees = Math.round(verticalFlipDegrees / 180) * 180;
        }
    }

    private void flipFilterVertically(final FlipFilter filter) {
        flipVertical = !flipVertical;
        filter.setFlip(flipHorizontal, flipVertical);
        notifyFilterChanged(filter, true);
    private void updateFlipFilter(boolean outputFilter) {
        // Flip the filter if the flipped degrees are at the opposite directions.
        filter.setFlip(((int) horizontalFlipDegrees / 180) % 2 != 0,
                ((int) verticalFlipDegrees / 180) % 2 != 0);
        notifyFilterChanged(filter, outputFilter);
    }
}
Loading