Home | History | Annotate | Download | only in hwuicompare
      1 /*
      2  * Copyright (C) 2012 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 com.android.test.hwuicompare;
     18 
     19 import java.util.LinkedHashMap;
     20 import java.util.Map.Entry;
     21 
     22 import android.graphics.Canvas;
     23 import android.graphics.Paint;
     24 import android.graphics.RectF;
     25 import android.util.Log;
     26 
     27 public abstract class DisplayModifier {
     28 
     29     // automated tests ignore any combination of operations that don't together return TOTAL_MASK
     30     protected final static int TOTAL_MASK = 0x1F;
     31 
     32     // if we're filling, ensure we're not also sweeping over stroke parameters
     33     protected final static int SWEEP_STROKE_WIDTH_BIT = 0x1 << 0;
     34     protected final static int SWEEP_STROKE_CAP_BIT = 0x1 << 1;
     35     protected final static int SWEEP_STROKE_JOIN_BIT = 0x1 << 2;
     36 
     37     protected final static int SWEEP_SHADER_BIT = 0x1 << 3; // only allow non-simple shaders to use rectangle drawing
     38     protected final static int SWEEP_TRANSFORM_BIT = 0x1 << 4; // only sweep over specified transforms
     39 
     40     abstract public void modifyDrawing(Paint paint, Canvas canvas);
     41     protected int mask() { return 0x0; };
     42 
     43     private static final RectF gRect = new RectF(0, 0, 200, 175);
     44     private static final float[] gPts = new float[] {
     45             0, 100, 100, 0, 100, 200, 200, 100
     46     };
     47 
     48     private static final int NUM_PARALLEL_LINES = 24;
     49     private static final float[] gTriPts = new float[] {
     50         75, 0, 130, 130, 130, 130, 0, 130, 0, 130, 75, 0
     51     };
     52     private static final float[] gLinePts = new float[NUM_PARALLEL_LINES * 8 + gTriPts.length];
     53     static {
     54         int index;
     55         for (index = 0; index < gTriPts.length; index++) {
     56             gLinePts[index] = gTriPts[index];
     57         }
     58         float val = 0;
     59         for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
     60             gLinePts[index + 0] = 150;
     61             gLinePts[index + 1] = val;
     62             gLinePts[index + 2] = 300;
     63             gLinePts[index + 3] = val;
     64             index += 4;
     65             val += 8 + (2.0f/NUM_PARALLEL_LINES);
     66         }
     67         val = 0;
     68         for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
     69             gLinePts[index + 0] = val;
     70             gLinePts[index + 1] = 150;
     71             gLinePts[index + 2] = val;
     72             gLinePts[index + 3] = 300;
     73             index += 4;
     74             val += 8 + (2.0f/NUM_PARALLEL_LINES);
     75         }
     76     };
     77 
     78     @SuppressWarnings("serial")
     79     private static final LinkedHashMap<String, LinkedHashMap<String, DisplayModifier>> gMaps = new LinkedHashMap<String, LinkedHashMap<String, DisplayModifier>>() {
     80         {
     81             put("aa", new LinkedHashMap<String, DisplayModifier>() {
     82                 {
     83                     put("true", new DisplayModifier() {
     84                         @Override
     85                         public void modifyDrawing(Paint paint, Canvas canvas) {
     86                             paint.setAntiAlias(true);
     87                         }
     88                     });
     89                     put("false", new DisplayModifier() {
     90                         @Override
     91                         public void modifyDrawing(Paint paint, Canvas canvas) {
     92                             paint.setAntiAlias(false);
     93                         }
     94                     });
     95                 }
     96             });
     97             put("style", new LinkedHashMap<String, DisplayModifier>() {
     98                 {
     99                     put("fill", new DisplayModifier() {
    100                         @Override
    101                         public void modifyDrawing(Paint paint, Canvas canvas) {
    102                             paint.setStyle(Paint.Style.FILL);
    103                         }
    104                     });
    105                     put("stroke", new DisplayModifier() {
    106                         @Override
    107                         public void modifyDrawing(Paint paint, Canvas canvas) {
    108                             paint.setStyle(Paint.Style.STROKE);
    109                         }
    110                         @Override
    111                         protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
    112                     });
    113                     put("fillAndStroke", new DisplayModifier() {
    114                         @Override
    115                         public void modifyDrawing(Paint paint, Canvas canvas) {
    116                             paint.setStyle(Paint.Style.FILL_AND_STROKE);
    117                         }
    118 
    119                         @Override
    120                         protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
    121                     });
    122                 }
    123             });
    124             put("strokeWidth", new LinkedHashMap<String, DisplayModifier>() {
    125                 {
    126                     put("hair", new DisplayModifier() {
    127                         @Override
    128                         public void modifyDrawing(Paint paint, Canvas canvas) {
    129                             paint.setStrokeWidth(0);
    130                         }
    131                         @Override
    132                         protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
    133                     });
    134                     put("0.3", new DisplayModifier() {
    135                         @Override
    136                         public void modifyDrawing(Paint paint, Canvas canvas) {
    137                             paint.setStrokeWidth(0.3f);
    138                         }
    139                     });
    140                     put("1", new DisplayModifier() {
    141                         @Override
    142                         public void modifyDrawing(Paint paint, Canvas canvas) {
    143                             paint.setStrokeWidth(1);
    144                         }
    145                     });
    146                     put("5", new DisplayModifier() {
    147                         @Override
    148                         public void modifyDrawing(Paint paint, Canvas canvas) {
    149                             paint.setStrokeWidth(5);
    150                         }
    151                     });
    152                     put("30", new DisplayModifier() {
    153                         @Override
    154                         public void modifyDrawing(Paint paint, Canvas canvas) {
    155                             paint.setStrokeWidth(30);
    156                         }
    157                     });
    158                 }
    159             });
    160             put("strokeCap", new LinkedHashMap<String, DisplayModifier>() {
    161                 {
    162                     put("butt", new DisplayModifier() {
    163                         @Override
    164                         public void modifyDrawing(Paint paint, Canvas canvas) {
    165                             paint.setStrokeCap(Paint.Cap.BUTT);
    166                         }
    167                         @Override
    168                         protected int mask() { return SWEEP_STROKE_CAP_BIT; }
    169                     });
    170                     put("round", new DisplayModifier() {
    171                         @Override
    172                         public void modifyDrawing(Paint paint, Canvas canvas) {
    173                             paint.setStrokeCap(Paint.Cap.ROUND);
    174                         }
    175                     });
    176                     put("square", new DisplayModifier() {
    177                         @Override
    178                         public void modifyDrawing(Paint paint, Canvas canvas) {
    179                             paint.setStrokeCap(Paint.Cap.SQUARE);
    180                         }
    181                     });
    182                 }
    183             });
    184             put("strokeJoin", new LinkedHashMap<String, DisplayModifier>() {
    185                 {
    186                     put("bevel", new DisplayModifier() {
    187                         @Override
    188                         public void modifyDrawing(Paint paint, Canvas canvas) {
    189                             paint.setStrokeJoin(Paint.Join.BEVEL);
    190                         }
    191                         @Override
    192                         protected int mask() { return SWEEP_STROKE_JOIN_BIT; }
    193                     });
    194                     put("round", new DisplayModifier() {
    195                         @Override
    196                         public void modifyDrawing(Paint paint, Canvas canvas) {
    197                             paint.setStrokeJoin(Paint.Join.ROUND);
    198                         }
    199                     });
    200                     put("miter", new DisplayModifier() {
    201                         @Override
    202                         public void modifyDrawing(Paint paint, Canvas canvas) {
    203                             paint.setStrokeJoin(Paint.Join.MITER);
    204                         }
    205                     });
    206                     // TODO: add miter0, miter1 etc to test miter distances
    207                 }
    208             });
    209 
    210             put("transform", new LinkedHashMap<String, DisplayModifier>() {
    211                 {
    212                     put("noTransform", new DisplayModifier() {
    213                         @Override
    214                         public void modifyDrawing(Paint paint, Canvas canvas) {}
    215                         @Override
    216                         protected int mask() { return SWEEP_TRANSFORM_BIT; };
    217                     });
    218                     put("rotate5", new DisplayModifier() {
    219                         @Override
    220                         public void modifyDrawing(Paint paint, Canvas canvas) {
    221                             canvas.rotate(5);
    222                         }
    223                     });
    224                     put("rotate45", new DisplayModifier() {
    225                         @Override
    226                         public void modifyDrawing(Paint paint, Canvas canvas) {
    227                             canvas.rotate(45);
    228                         }
    229                     });
    230                     put("rotate90", new DisplayModifier() {
    231                         @Override
    232                         public void modifyDrawing(Paint paint, Canvas canvas) {
    233                             canvas.rotate(90);
    234                             canvas.translate(0, -200);
    235                         }
    236                     });
    237                     put("scale2x2", new DisplayModifier() {
    238                         @Override
    239                         public void modifyDrawing(Paint paint, Canvas canvas) {
    240                             canvas.scale(2, 2);
    241                         }
    242                         @Override
    243                         protected int mask() { return SWEEP_TRANSFORM_BIT; };
    244                     });
    245                     put("rot20scl1x4", new DisplayModifier() {
    246                         @Override
    247                         public void modifyDrawing(Paint paint, Canvas canvas) {
    248                             canvas.rotate(20);
    249                             canvas.scale(1, 4);
    250                         }
    251                         @Override
    252                         protected int mask() { return SWEEP_TRANSFORM_BIT; };
    253                     });
    254                 }
    255             });
    256 
    257             put("shader", new LinkedHashMap<String, DisplayModifier>() {
    258                 {
    259                     put("noShader", new DisplayModifier() {
    260                         @Override
    261                         public void modifyDrawing(Paint paint, Canvas canvas) {}
    262                         @Override
    263                         protected int mask() { return SWEEP_SHADER_BIT; };
    264                     });
    265                     put("repeatShader", new DisplayModifier() {
    266                         @Override
    267                         public void modifyDrawing(Paint paint, Canvas canvas) {
    268                             paint.setShader(ResourceModifiers.instance().mRepeatShader);
    269                         }
    270                         @Override
    271                         protected int mask() { return SWEEP_SHADER_BIT; };
    272                     });
    273                     put("translatedShader", new DisplayModifier() {
    274                         @Override
    275                         public void modifyDrawing(Paint paint, Canvas canvas) {
    276                             paint.setShader(ResourceModifiers.instance().mTranslatedShader);
    277                         }
    278                     });
    279                     put("scaledShader", new DisplayModifier() {
    280                         @Override
    281                         public void modifyDrawing(Paint paint, Canvas canvas) {
    282                             paint.setShader(ResourceModifiers.instance().mScaledShader);
    283                         }
    284                     });
    285                     put("horGradient", new DisplayModifier() {
    286                         @Override
    287                         public void modifyDrawing(Paint paint, Canvas canvas) {
    288                             paint.setShader(ResourceModifiers.instance().mHorGradient);
    289                         }
    290                     });
    291                     put("diagGradient", new DisplayModifier() {
    292                         @Override
    293                         public void modifyDrawing(Paint paint, Canvas canvas) {
    294                             paint.setShader(ResourceModifiers.instance().mDiagGradient);
    295                         }
    296                         @Override
    297                         protected int mask() { return SWEEP_SHADER_BIT; };
    298                     });
    299                     put("vertGradient", new DisplayModifier() {
    300                         @Override
    301                         public void modifyDrawing(Paint paint, Canvas canvas) {
    302                             paint.setShader(ResourceModifiers.instance().mVertGradient);
    303                         }
    304                     });
    305                 }
    306             });
    307 
    308             // FINAL MAP: DOES ACTUAL DRAWING
    309             put("drawing", new LinkedHashMap<String, DisplayModifier>() {
    310                 {
    311                     put("roundRect", new DisplayModifier() {
    312                         @Override
    313                         public void modifyDrawing(Paint paint, Canvas canvas) {
    314                             canvas.drawRoundRect(gRect, 20, 20, paint);
    315                         }
    316                     });
    317                     put("rect", new DisplayModifier() {
    318                         @Override
    319                         public void modifyDrawing(Paint paint, Canvas canvas) {
    320                             canvas.drawRect(gRect, paint);
    321                         }
    322                         @Override
    323                         protected int mask() { return SWEEP_SHADER_BIT | SWEEP_STROKE_CAP_BIT; };
    324                     });
    325                     put("circle", new DisplayModifier() {
    326                         @Override
    327                         public void modifyDrawing(Paint paint, Canvas canvas) {
    328                             canvas.drawCircle(100, 100, 75, paint);
    329                         }
    330                     });
    331                     put("oval", new DisplayModifier() {
    332                         @Override
    333                         public void modifyDrawing(Paint paint, Canvas canvas) {
    334                             canvas.drawOval(gRect, paint);
    335                         }
    336                     });
    337                     put("lines", new DisplayModifier() {
    338                         @Override
    339                         public void modifyDrawing(Paint paint, Canvas canvas) {
    340                             canvas.drawLines(gLinePts, paint);
    341                         }
    342                         @Override
    343                         protected int mask() { return SWEEP_STROKE_CAP_BIT; };
    344                     });
    345                     put("plusPoints", new DisplayModifier() {
    346                         @Override
    347                         public void modifyDrawing(Paint paint, Canvas canvas) {
    348                             canvas.drawPoints(gPts, paint);
    349                         }
    350                     });
    351                     put("text", new DisplayModifier() {
    352                         @Override
    353                         public void modifyDrawing(Paint paint, Canvas canvas) {
    354                             paint.setTextSize(36);
    355                             canvas.drawText("TEXTTEST", 0, 50, paint);
    356                         }
    357                     });
    358                     put("shadowtext", new DisplayModifier() {
    359                         @Override
    360                         public void modifyDrawing(Paint paint, Canvas canvas) {
    361                             paint.setTextSize(36);
    362                             paint.setShadowLayer(3.0f, 0.0f, 3.0f, 0xffff00ff);
    363                             canvas.drawText("TEXTTEST", 0, 50, paint);
    364                         }
    365                     });
    366                     put("bitmapMesh", new DisplayModifier() {
    367                         @Override
    368                         public void modifyDrawing(Paint paint, Canvas canvas) {
    369                             canvas.drawBitmapMesh(ResourceModifiers.instance().mBitmap, 3, 3,
    370                                     ResourceModifiers.instance().mBitmapVertices, 0, null, 0, null);
    371                         }
    372                     });
    373                     put("arc", new DisplayModifier() {
    374                         @Override
    375                         public void modifyDrawing(Paint paint, Canvas canvas) {
    376                             canvas.drawArc(gRect, 260, 285, false, paint);
    377                         }
    378                         @Override
    379                         protected int mask() { return SWEEP_STROKE_CAP_BIT; };
    380                     });
    381                     put("arcFromCenter", new DisplayModifier() {
    382                         @Override
    383                         public void modifyDrawing(Paint paint, Canvas canvas) {
    384                             canvas.drawArc(gRect, 260, 285, true, paint);
    385                         }
    386                         @Override
    387                         protected int mask() { return SWEEP_STROKE_JOIN_BIT; };
    388                     });
    389                 }
    390             });
    391             // WARNING: DON'T PUT MORE MAPS BELOW THIS
    392         }
    393     };
    394 
    395     private static LinkedHashMap<String, DisplayModifier> getMapAtIndex(int index) {
    396         for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) {
    397             if (index == 0) {
    398                 return map;
    399             }
    400             index--;
    401         }
    402         return null;
    403     }
    404 
    405     // indices instead of iterators for easier bidirectional traversal
    406     private static final int mIndices[] = new int[gMaps.size()];
    407     private static final String[] mLastAppliedModifications = new String[gMaps.size()];
    408 
    409     private static boolean stepInternal(boolean forward) {
    410         int modifierMapIndex = gMaps.size() - 1;
    411         while (modifierMapIndex >= 0) {
    412             LinkedHashMap<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex);
    413             mIndices[modifierMapIndex] += (forward ? 1 : -1);
    414 
    415             if (mIndices[modifierMapIndex] >= 0 && mIndices[modifierMapIndex] < map.size()) {
    416                 break;
    417             }
    418 
    419             mIndices[modifierMapIndex] = (forward ? 0 : map.size() - 1);
    420             modifierMapIndex--;
    421         }
    422         return modifierMapIndex < 0; // true if resetting
    423     }
    424 
    425     public static boolean step() {
    426         boolean ret = false;
    427         do {
    428             ret |= stepInternal(true);
    429         } while (!checkModificationStateMask());
    430         return ret;
    431     }
    432 
    433     public static boolean stepBack() {
    434         boolean ret = false;
    435         do {
    436             ret |= stepInternal(false);
    437         } while (!checkModificationStateMask());
    438         return ret;
    439     }
    440 
    441     private static boolean checkModificationStateMask() {
    442         int operatorMask = 0x0;
    443         int mapIndex = 0;
    444         for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) {
    445             int displayModifierIndex = mIndices[mapIndex];
    446             for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
    447                 if (displayModifierIndex == 0) {
    448                     mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
    449                     operatorMask |= modifierEntry.getValue().mask();
    450                     break;
    451                 }
    452                 displayModifierIndex--;
    453             }
    454             mapIndex++;
    455         }
    456         return operatorMask == TOTAL_MASK;
    457     }
    458 
    459     public static void apply(Paint paint, Canvas canvas) {
    460         int mapIndex = 0;
    461         for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) {
    462             int displayModifierIndex = mIndices[mapIndex];
    463             for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
    464                 if (displayModifierIndex == 0) {
    465                     mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
    466                     modifierEntry.getValue().modifyDrawing(paint, canvas);
    467                     break;
    468                 }
    469                 displayModifierIndex--;
    470             }
    471             mapIndex++;
    472         }
    473     }
    474 
    475     public static String[] getLastAppliedModifications() {
    476         return mLastAppliedModifications.clone();
    477     }
    478 
    479     public static String[][] getStrings() {
    480         String[][] keys = new String[gMaps.size()][];
    481 
    482         int i = 0;
    483         for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) {
    484             keys[i] = new String[map.size()];
    485             int j = 0;
    486             for (String key : map.keySet()) {
    487                 keys[i][j++] = key;
    488             }
    489             i++;
    490         }
    491 
    492         return keys;
    493     }
    494 
    495     public static void setIndex(int mapIndex, int newIndexValue) {
    496         mIndices[mapIndex] = newIndexValue;
    497     }
    498 
    499     public static int[] getIndices() {
    500         return mIndices;
    501     }
    502 }
    503