1 /*
2  * Copyright (C) 2007 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.example.android.apis.graphics;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.BitmapShader;
22 import android.graphics.Canvas;
23 import android.graphics.Color;
24 import android.graphics.Matrix;
25 import android.graphics.Paint;
26 import android.graphics.PorterDuff;
27 import android.graphics.PorterDuffXfermode;
28 import android.graphics.RectF;
29 import android.graphics.Shader;
30 import android.graphics.Xfermode;
31 import android.os.Bundle;
32 import android.view.View;
33 
34 public class Xfermodes extends GraphicsActivity {
35 
36     // create a bitmap with a circle, used for the "dst" image
makeDst(int w, int h)37     static Bitmap makeDst(int w, int h) {
38         Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
39         Canvas c = new Canvas(bm);
40         Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
41 
42         p.setColor(0xFFFFCC44);
43         c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
44         return bm;
45     }
46 
47     // create a bitmap with a rect, used for the "src" image
makeSrc(int w, int h)48     static Bitmap makeSrc(int w, int h) {
49         Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
50         Canvas c = new Canvas(bm);
51         Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
52 
53         p.setColor(0xFF66AAFF);
54         c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
55         return bm;
56     }
57 
58     @Override
onCreate(Bundle savedInstanceState)59     protected void onCreate(Bundle savedInstanceState) {
60         super.onCreate(savedInstanceState);
61         setContentView(new SampleView(this));
62     }
63 
64     private static class SampleView extends View {
65         private static final int W = 64;
66         private static final int H = 64;
67         private static final int ROW_MAX = 4;   // number of samples per row
68 
69         private Bitmap mSrcB;
70         private Bitmap mDstB;
71         private Shader mBG;     // background checker-board pattern
72 
73         private static final Xfermode[] sModes = {
74             new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
75             new PorterDuffXfermode(PorterDuff.Mode.SRC),
76             new PorterDuffXfermode(PorterDuff.Mode.DST),
77             new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
78             new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
79             new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
80             new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
81             new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
82             new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
83             new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
84             new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
85             new PorterDuffXfermode(PorterDuff.Mode.XOR),
86             new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
87             new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
88             new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
89             new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
90         };
91 
92         private static final String[] sLabels = {
93             "Clear", "Src", "Dst", "SrcOver",
94             "DstOver", "SrcIn", "DstIn", "SrcOut",
95             "DstOut", "SrcATop", "DstATop", "Xor",
96             "Darken", "Lighten", "Multiply", "Screen"
97         };
98 
SampleView(Context context)99         public SampleView(Context context) {
100             super(context);
101 
102             mSrcB = makeSrc(W, H);
103             mDstB = makeDst(W, H);
104 
105             // make a ckeckerboard pattern
106             Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
107                                             0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,
108                                             Bitmap.Config.RGB_565);
109             mBG = new BitmapShader(bm,
110                                    Shader.TileMode.REPEAT,
111                                    Shader.TileMode.REPEAT);
112             Matrix m = new Matrix();
113             m.setScale(6, 6);
114             mBG.setLocalMatrix(m);
115         }
116 
onDraw(Canvas canvas)117         @Override protected void onDraw(Canvas canvas) {
118             canvas.drawColor(Color.WHITE);
119 
120             Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
121             labelP.setTextAlign(Paint.Align.CENTER);
122 
123             Paint paint = new Paint();
124             paint.setFilterBitmap(false);
125 
126             canvas.translate(15, 35);
127 
128             int x = 0;
129             int y = 0;
130             for (int i = 0; i < sModes.length; i++) {
131                 // draw the border
132                 paint.setStyle(Paint.Style.STROKE);
133                 paint.setShader(null);
134                 canvas.drawRect(x - 0.5f, y - 0.5f,
135                                 x + W + 0.5f, y + H + 0.5f, paint);
136 
137                 // draw the checker-board pattern
138                 paint.setStyle(Paint.Style.FILL);
139                 paint.setShader(mBG);
140                 canvas.drawRect(x, y, x + W, y + H, paint);
141 
142                 // draw the src/dst example into our offscreen bitmap
143                 int sc = canvas.saveLayer(x, y, x + W, y + H, null);
144                 canvas.translate(x, y);
145                 canvas.drawBitmap(mDstB, 0, 0, paint);
146                 paint.setXfermode(sModes[i]);
147                 canvas.drawBitmap(mSrcB, 0, 0, paint);
148                 paint.setXfermode(null);
149                 canvas.restoreToCount(sc);
150 
151                 // draw the label
152                 canvas.drawText(sLabels[i],
153                                 x + W/2, y - labelP.getTextSize()/2, labelP);
154 
155                 x += W + 10;
156 
157                 // wrap around when we've drawn enough for one row
158                 if ((i % ROW_MAX) == ROW_MAX - 1) {
159                     x = 0;
160                     y += H + 30;
161                 }
162             }
163         }
164     }
165 }
166 
167