• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
modifyDrawing(Paint paint, Canvas canvas)40     abstract public void modifyDrawing(Paint paint, Canvas canvas);
mask()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(5);
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 
getMapAtIndex(int index)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 
stepInternal(boolean forward)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 
step()425     public static boolean step() {
426         boolean ret = false;
427         do {
428             ret |= stepInternal(true);
429         } while (!checkModificationStateMask());
430         return ret;
431     }
432 
stepBack()433     public static boolean stepBack() {
434         boolean ret = false;
435         do {
436             ret |= stepInternal(false);
437         } while (!checkModificationStateMask());
438         return ret;
439     }
440 
checkModificationStateMask()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 
apply(Paint paint, Canvas canvas)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 
getLastAppliedModifications()475     public static String[] getLastAppliedModifications() {
476         return mLastAppliedModifications.clone();
477     }
478 
getStrings()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 
setIndex(int mapIndex, int newIndexValue)495     public static void setIndex(int mapIndex, int newIndexValue) {
496         mIndices[mapIndex] = newIndexValue;
497     }
498 
getIndices()499     public static int[] getIndices() {
500         return mIndices;
501     }
502 }
503