Home | History | Annotate | Download | only in testclasses
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.uirendering.cts.testclasses;
     18 
     19 import static org.junit.Assert.assertNotNull;
     20 
     21 import android.content.pm.PackageManager;
     22 import android.graphics.Color;
     23 import android.graphics.Paint;
     24 import android.graphics.Path;
     25 import android.graphics.Point;
     26 import android.graphics.Typeface;
     27 import android.support.test.filters.LargeTest;
     28 import android.support.test.filters.MediumTest;
     29 import android.support.test.runner.AndroidJUnit4;
     30 import android.uirendering.cts.R;
     31 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
     32 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
     33 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
     34 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
     35 import android.uirendering.cts.testinfrastructure.CanvasClient;
     36 import android.uirendering.cts.testinfrastructure.CanvasClientDrawable;
     37 import android.uirendering.cts.testinfrastructure.ViewInitializer;
     38 import android.uirendering.cts.util.WebViewReadyHelper;
     39 import android.view.View;
     40 import android.view.ViewGroup;
     41 import android.webkit.WebView;
     42 
     43 import org.junit.Test;
     44 import org.junit.runner.RunWith;
     45 
     46 import java.util.concurrent.CountDownLatch;
     47 
     48 @MediumTest
     49 @RunWith(AndroidJUnit4.class)
     50 public class PathClippingTests extends ActivityTestBase {
     51     // draw circle with hole in it, with stroked circle
     52     static final CanvasClient sTorusDrawCanvasClient = (canvas, width, height) -> {
     53         Paint paint = new Paint();
     54         paint.setAntiAlias(false);
     55         paint.setColor(Color.BLUE);
     56         paint.setStyle(Paint.Style.STROKE);
     57         paint.setStrokeWidth(20);
     58         canvas.drawCircle(30, 30, 40, paint);
     59     };
     60 
     61     // draw circle with hole in it, by path operations + path clipping
     62     static final CanvasClient sTorusClipCanvasClient = (canvas, width, height) -> {
     63         canvas.save();
     64 
     65         Path path = new Path();
     66         path.addCircle(30, 30, 50, Path.Direction.CW);
     67         path.addCircle(30, 30, 30, Path.Direction.CCW);
     68 
     69         canvas.clipPath(path);
     70         canvas.drawColor(Color.BLUE);
     71 
     72         canvas.restore();
     73     };
     74 
     75     // draw circle with hole in it, by path operations + path clipping
     76     static final CanvasClient sTorusClipOutCanvasClient = (canvas, width, height) -> {
     77         canvas.save();
     78 
     79         Path path1 = new Path();
     80         path1.addCircle(30, 30, 50, Path.Direction.CW);
     81 
     82         Path path2 = new Path();
     83         path2.addCircle(30, 30, 30, Path.Direction.CW);
     84 
     85         canvas.clipPath(path1);
     86         canvas.clipOutPath(path2);
     87         canvas.drawColor(Color.BLUE);
     88 
     89         canvas.restore();
     90     };
     91 
     92     @Test
     93     public void testCircleWithCircle() {
     94         createTest()
     95                 .addCanvasClient("TorusDraw", sTorusDrawCanvasClient, false)
     96                 .addCanvasClient("TorusClip", sTorusClipCanvasClient)
     97                 .addCanvasClient("TorusClipOut", sTorusClipOutCanvasClient)
     98                 .runWithVerifier(new GoldenImageVerifier(getActivity(),
     99                         R.drawable.pathclippingtest_torus, new MSSIMComparer(0.95)));
    100     }
    101 
    102     @Test
    103     public void testCircleWithPoints() {
    104         createTest()
    105                 .addCanvasClient("TorusClip", sTorusClipCanvasClient)
    106                 .addCanvasClient("TorusClipOut", sTorusClipOutCanvasClient)
    107                 .runWithVerifier(new SamplePointVerifier(
    108                         new Point[] {
    109                                 // inside of circle
    110                                 new Point(30, 50),
    111                                 // on circle
    112                                 new Point(30 + 32, 30 + 32),
    113                                 // outside of circle
    114                                 new Point(30 + 38, 30 + 38),
    115                                 new Point(80, 80)
    116                         },
    117                         new int[] {
    118                                 Color.WHITE,
    119                                 Color.BLUE,
    120                                 Color.WHITE,
    121                                 Color.WHITE,
    122                         }));
    123     }
    124 
    125     @Test
    126     public void testViewRotate() {
    127         createTest()
    128                 .addLayout(R.layout.blue_padded_layout, view -> {
    129                     ViewGroup rootView = (ViewGroup) view;
    130                     rootView.setClipChildren(true);
    131                     View childView = rootView.getChildAt(0);
    132                     childView.setPivotX(40);
    133                     childView.setPivotY(40);
    134                     childView.setRotation(45f);
    135                 })
    136                 .runWithVerifier(new SamplePointVerifier(
    137                         new Point[] {
    138                                 // inside of rotated rect
    139                                 new Point(40, 40),
    140                                 new Point(40 + 25, 40 + 25),
    141                                 // outside of rotated rect
    142                                 new Point(40 + 31, 40 + 31),
    143                                 new Point(80, 80)
    144                         },
    145                         new int[] {
    146                                 Color.BLUE,
    147                                 Color.BLUE,
    148                                 Color.WHITE,
    149                                 Color.WHITE,
    150                         }));
    151     }
    152 
    153     @Test
    154     public void testPathScale() {
    155         createTest()
    156                 .addLayout(R.layout.frame_layout, view -> {
    157                     Path path = new Path();
    158                     path.addCircle(TEST_WIDTH / 2, TEST_HEIGHT / 2,
    159                             TEST_WIDTH / 4, Path.Direction.CW);
    160                     view.setBackground(new CanvasClientDrawable((canvas, width, height) -> {
    161                         canvas.clipPath(path);
    162                         canvas.drawColor(Color.BLUE);
    163                     }));
    164                     view.setScaleX(2);
    165                     view.setScaleY(2);
    166                 })
    167                 .runWithComparer(new MSSIMComparer(0.90));
    168     }
    169 
    170     @Test
    171     public void testTextClip() {
    172         createTest()
    173                 .addCanvasClient((canvas, width, height) -> {
    174                     canvas.save();
    175 
    176                     Path path = new Path();
    177                     path.addCircle(0, 45, 45, Path.Direction.CW);
    178                     path.addCircle(90, 45, 45, Path.Direction.CW);
    179                     canvas.clipPath(path);
    180 
    181                     Paint paint = new Paint();
    182                     paint.setAntiAlias(true);
    183                     paint.setTextSize(90);
    184                     paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
    185                     canvas.drawText("STRING", 0, 90, paint);
    186 
    187                     canvas.restore();
    188                 })
    189                 .runWithComparer(new MSSIMComparer(0.90));
    190     }
    191 
    192     private ViewInitializer initBlueWebView(final CountDownLatch fence) {
    193         return view -> {
    194             WebView webview = (WebView)view.findViewById(R.id.webview);
    195             assertNotNull(webview);
    196             WebViewReadyHelper helper = new WebViewReadyHelper(webview, fence);
    197             helper.loadData("<body style=\"background-color:blue\">");
    198         };
    199     }
    200 
    201     @LargeTest
    202     @Test
    203     public void testWebViewClipWithCircle() {
    204         if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
    205             return; // no WebView to run test on
    206         }
    207         CountDownLatch hwFence = new CountDownLatch(1);
    208         CountDownLatch swFence = new CountDownLatch(1);
    209         createTest()
    210                 // golden client - draw a simple non-AA circle
    211                 .addCanvasClient((canvas, width, height) -> {
    212                     Paint paint = new Paint();
    213                     paint.setAntiAlias(false);
    214                     paint.setColor(Color.BLUE);
    215                     canvas.drawOval(0, 0, width, height, paint);
    216                 }, false)
    217                 // verify against solid color webview, clipped to its parent oval
    218                 .addLayout(R.layout.circle_clipped_webview,
    219                         initBlueWebView(hwFence), true, hwFence)
    220                 .addLayout(R.layout.circle_clipped_webview,
    221                         initBlueWebView(swFence), false, swFence)
    222                 .runWithComparer(new MSSIMComparer(0.95));
    223     }
    224 }
    225