14b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet/* 24b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 34b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 44b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 54b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * you may not use this file except in compliance with the License. 64b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * You may obtain a copy of the License at 74b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 84b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 94b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 104b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Unless required by applicable law or agreed to in writing, software 114b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 124b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * See the License for the specific language governing permissions and 144b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * limitations under the License. 154b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet */ 164b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 174b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohetpackage android.graphics; 184b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 19918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog; 20d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 21c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.layoutlib.bridge.impl.DelegateManager; 229a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohetimport com.android.tools.layoutlib.annotations.LayoutlibDelegate; 234b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 24d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.AlphaComposite; 25d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.Composite; 26d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 274b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet/** 284b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Delegate implementing the native methods of android.graphics.PorterDuffXfermode 294b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 304b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Through the layoutlib_create tool, the original native methods of PorterDuffXfermode have been 314b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * replaced by calls to methods of the same name in this delegate class. 324b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 334b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * This class behaves like the original native implementation, but in Java, keeping previously 344b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * native data into its own objects and mapping them to int that are sent back and forth between 354b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * it and the original PorterDuffXfermode class. 364b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 374b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * Because this extends {@link Xfermode_Delegate}, there's no need to use a 384b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by 394b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * {@link Xfermode_Delegate}. 404b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet * 414b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet */ 424b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohetpublic class PorterDuffXfermode_Delegate extends Xfermode_Delegate { 434b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 444b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet // ---- delegate data ---- 454b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 464b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet private final int mMode; 474b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 484b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet // ---- Public Helper methods ---- 494b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 50b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet public PorterDuff.Mode getMode() { 51b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet return getPorterDuffMode(mMode); 52b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet } 53b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet 54d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet @Override 5563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet public Composite getComposite(int alpha) { 5663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return getComposite(getPorterDuffMode(mMode), alpha); 57d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet } 58d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 59d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet @Override 60d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet public boolean isSupported() { 61d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet return true; 62d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet } 63d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 64d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet @Override 65d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet public String getSupportMessage() { 66d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet // no message since isSupported returns true; 67d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet return null; 68d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet } 69d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 7063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet public static PorterDuff.Mode getPorterDuffMode(int mode) { 7163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet for (PorterDuff.Mode m : PorterDuff.Mode.values()) { 7263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet if (m.nativeInt == mode) { 7363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return m; 7463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet } 7563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet } 7663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet 77918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet Bridge.getLog().error(LayoutLog.TAG_BROKEN, 7851a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet String.format("Unknown PorterDuff.Mode: %d", mode), null /*data*/); 7963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet assert false; 8063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return PorterDuff.Mode.SRC_OVER; 8163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet } 8263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet 8363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet public static Composite getComposite(PorterDuff.Mode mode, int alpha) { 8463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet float falpha = alpha != 0xFF ? (float)alpha / 255.f : 1.f; 8563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet switch (mode) { 86d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case CLEAR: 8763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha); 88d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DARKEN: 89d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet break; 90d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DST: 9163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.DST, falpha); 92d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DST_ATOP: 9363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha); 94d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DST_IN: 9563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha); 96d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DST_OUT: 9763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha); 98d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case DST_OVER: 9963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha); 100d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case LIGHTEN: 101d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet break; 102d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case MULTIPLY: 103d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet break; 104d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SCREEN: 105d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet break; 106d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SRC: 10763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC, falpha); 108d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SRC_ATOP: 10963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha); 110d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SRC_IN: 11163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha); 112d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SRC_OUT: 11363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha); 114d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case SRC_OVER: 11563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha); 116d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet case XOR: 11763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.XOR, falpha); 118d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet } 119d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 120918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, 12163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet String.format("Unsupported PorterDuff Mode: %s", mode.name()), 12251a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet null, null /*data*/); 123d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet 12463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha); 1254b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet } 1264b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 1274b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet // ---- native methods ---- 1284b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 1299a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet @LayoutlibDelegate 1304b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet /*package*/ static int nativeCreateXfermode(int mode) { 1314b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet PorterDuffXfermode_Delegate newDelegate = new PorterDuffXfermode_Delegate(mode); 132cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet return sManager.addNewDelegate(newDelegate); 1334b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet } 1344b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 1354b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet // ---- Private delegate/helper methods ---- 1364b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet 1374b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet private PorterDuffXfermode_Delegate(int mode) { 1384b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet mMode = mode; 1394b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet } 1404b606da91d2d76dd90a427cb3e37ea7df655e8e0Xavier Ducrohet} 141